diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm
index 5272496230f..57d32fcff45 100644
--- a/code/__DEFINES/dcs/signals.dm
+++ b/code/__DEFINES/dcs/signals.dm
@@ -23,6 +23,8 @@
#define COMPONENT_GLOB_BLOCK_CINEMATIC (1<<0)
/// ingame button pressed (/obj/machinery/button/button)
#define COMSIG_GLOB_BUTTON_PRESSED "!button_pressed"
+/// job subsystem has spawned and equipped a new mob
+#define COMSIG_GLOB_JOB_AFTER_SPAWN "!job_after_spawn"
/// crewmember joined the game (mob/living, rank)
#define COMSIG_GLOB_CREWMEMBER_JOINED "!crewmember_joined"
@@ -53,6 +55,10 @@
/// fires on the target datum when an element is attached to it (/datum/element)
#define COMSIG_ELEMENT_DETACH "element_detach"
+///Subsystem signals
+///From base of datum/controller/subsystem/Initialize: (start_timeofday)
+#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"
+
// /atom signals
///from base of atom/proc/Initialize(): sent any time a new atom is created
#define COMSIG_ATOM_CREATED "atom_created"
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 3938fdf3ad0..8f607b4c7b0 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -55,7 +55,7 @@
#define AMBIENCE_AWAY "away"
#define AMBIENCE_REEBE "reebe" //unused
#define AMBIENCE_CREEPY "creepy" //not to be confused with spooky
-
+
//default byond sound environments
#define SOUND_ENVIRONMENT_NONE -1
#define SOUND_ENVIRONMENT_GENERIC 0
@@ -99,3 +99,22 @@
#define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS
#define SOUND_AREA_ICEMOON SOUND_ENVIRONMENT_CAVE
#define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY
+
+
+///Announcer audio keys
+#define ANNOUNCER_AIMALF "announcer_aimalf"
+#define ANNOUNCER_ALIENS "announcer_aliens"
+#define ANNOUNCER_ANIMES "announcer_animes"
+#define ANNOUNCER_GRANOMALIES "announcer_granomalies"
+#define ANNOUNCER_INTERCEPT "announcer_animes"
+#define ANNOUNCER_IONSTORM "announcer_ionstorm"
+#define ANNOUNCER_METEORS "announcer_meteors"
+#define ANNOUNCER_OUTBREAK5 "announcer_outbreak5"
+#define ANNOUNCER_OUTBREAK7 "announcer_outbreak7"
+#define ANNOUNCER_POWEROFF "announcer_poweroff"
+#define ANNOUNCER_POWERON "announcer_poweron"
+#define ANNOUNCER_RADIATION "announcer_radiation"
+#define ANNOUNCER_SHUTTLECALLED "announcer_shuttlecalled"
+#define ANNOUNCER_SHUTTLEDOCK "announcer_shuttledock"
+#define ANNOUNCER_SHUTTLERECALLED "announcer_shuttlerecalled"
+#define ANNOUNCER_SPANOMALIES "announcer_spanomalies"
diff --git a/code/__DEFINES/station.dm b/code/__DEFINES/station.dm
new file mode 100644
index 00000000000..1f22593ba3f
--- /dev/null
+++ b/code/__DEFINES/station.dm
@@ -0,0 +1,3 @@
+#define STATION_TRAIT_POSITIVE 1
+#define STATION_TRAIT_NEUTRAL 2
+#define STATION_TRAIT_NEGATIVE 3
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 6b512314c76..d5ca5eba8c6 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -113,6 +113,7 @@
#define INIT_ORDER_VIS 80
#define INIT_ORDER_ACHIEVEMENTS 77
#define INIT_ORDER_RESEARCH 75
+#define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it.
#define INIT_ORDER_EVENTS 70
#define INIT_ORDER_JOBS 65
#define INIT_ORDER_QUIRKS 60
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 33d1612e237..eebbe742302 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -402,6 +402,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define CHOKEHOLD_TRAIT "chokehold" //trait associated to being held in a chokehold
#define RESTING_TRAIT "resting" //trait associated to resting
#define STAT_TRAIT "stat" //trait associated to a stat value or range of
+#define STATION_TRAIT "station-trait"
#define MAPPING_HELPER_TRAIT "mapping-helper" //obtained from mapping helper
/// Trait associated to wearing a suit
#define SUIT_TRAIT "suit"
@@ -499,3 +500,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait from [/datum/antagonist/nukeop/clownop]
#define CLOWNOP_TRAIT "clownop"
+
+///Traits given by station traits
+#define STATION_TRAIT_BANANIUM_SHIPMENTS "station_trait_bananium_shipments"
+#define STATION_TRAIT_UNNATURAL_ATMOSPHERE "station_trait_unnatural_atmosphere"
+#define STATION_TRAIT_UNIQUE_AI "station_trait_unique_ai"
+#define STATION_TRAIT_CARP_INFESTATION "station_trait_carp_infestation"
+#define STATION_TRAIT_PREMIUM_INTERNALS "station_trait_premium_internals"
+#define STATION_TRAIT_LATE_ARRIVALS "station_trait_late_arrivals"
+#define STATION_TRAIT_RANDOM_ARRIVALS "station_trait_random_arrivals"
+#define STATION_TRAIT_FILLED_MAINT "station_trait_filled_maint"
+#define STATION_TRAIT_EMPTY_MAINT "station_trait_empty_maint"
+#define STATION_TRAIT_PDA_GLITCHED "station_trait_pda_glitched"
diff --git a/code/__HELPERS/priority_announce.dm b/code/__HELPERS/priority_announce.dm
index 94c6dc6724a..3d10644a336 100644
--- a/code/__HELPERS/priority_announce.dm
+++ b/code/__HELPERS/priority_announce.dm
@@ -1,8 +1,10 @@
-/proc/priority_announce(text, title = "", sound = 'sound/ai/attention.ogg', type , sender_override)
+/proc/priority_announce(text, title = "", sound, type , sender_override, has_important_message)
if(!text)
return
var/announcement
+ if(!istype(sound, /sound))
+ sound = SSstation.announcer.event_sounds[sound] || SSstation.announcer.get_rand_alert_sound()
if(type == "Priority")
announcement += "
Priority Announcement
"
@@ -26,7 +28,11 @@
else
GLOB.news_network.SubmitArticle(title + "
" + text, "Central Command", "Station Announcements", null)
- announcement += "
[html_encode(text)]
"
+ ///If the announcer overrides alert messages, use that message.
+ if(SSstation.announcer.custom_alert_message && !has_important_message)
+ announcement += SSstation.announcer.custom_alert_message
+ else
+ announcement += "
[html_encode(text)]
"
announcement += "
"
var/s = sound(sound)
@@ -41,7 +47,7 @@
title = "Classified [command_name()] Update"
if(announce)
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg')
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", SSstation.announcer.get_rand_report_sound(), has_important_message = TRUE)
var/datum/comm_message/M = new
M.title = title
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index d07636a8b0e..4e8c5f57945 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -988,9 +988,9 @@ rough example of the "cone" made by the 3 dirs checked
if (length(turfs))
return pick(turfs)
-/proc/get_safe_random_station_turf() //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
+/proc/get_safe_random_station_turf(list/areas_to_pick_from = GLOB.the_station_areas) //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
for (var/i in 1 to 5)
- var/list/L = get_area_turfs(pick(GLOB.the_station_areas))
+ var/list/L = get_area_turfs(pick(areas_to_pick_from))
var/turf/target
while (L.len && !target)
var/I = rand(1, L.len)
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index c7163289db1..03c0540b0fe 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -35,6 +35,7 @@ GLOBAL_LIST_EMPTY(secequipment) //sec equipment lockers that scale with the numb
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(ruin_landmarks)
+GLOBAL_LIST_EMPTY(bar_areas)
//away missions
GLOBAL_LIST_EMPTY(vr_spawnpoints)
diff --git a/code/controllers/master.dm b/code/controllers/master.dm
index de016fd8486..920dcd231ff 100644
--- a/code/controllers/master.dm
+++ b/code/controllers/master.dm
@@ -309,7 +309,7 @@ GLOBAL_REAL(Master, /datum/controller/master) = new
var/error_level = 0
var/sleep_delta = 1
var/list/subsystems_to_check
-
+
//setup the stack overflow detector
stack_end_detector = new()
var/datum/stack_canary/canary = stack_end_detector.prime_canary()
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index be9c8a88032..7b70b5e1eb9 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -214,6 +214,7 @@
//used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday)
initialized = TRUE
+ SEND_SIGNAL(src, COMSIG_SUBSYSTEM_POST_INITIALIZE, start_timeofday)
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
to_chat(world, "[msg]")
diff --git a/code/controllers/subsystem/communications.dm b/code/controllers/subsystem/communications.dm
index e5bda7148a0..39cebb1f671 100644
--- a/code/controllers/subsystem/communications.dm
+++ b/code/controllers/subsystem/communications.dm
@@ -23,7 +23,7 @@ SUBSYSTEM_DEF(communications)
minor_announce(html_decode(input),"[user.name] Announces:")
silicon_message_cooldown = world.time + COMMUNICATION_COOLDOWN_AI
else
- priority_announce(html_decode(user.treat_message(input)), null, 'sound/misc/announce.ogg', "Captain")
+ priority_announce(html_decode(user.treat_message(input)), null, 'sound/misc/announce.ogg', "Captain", has_important_message = TRUE)
nonsilicon_message_cooldown = world.time + COMMUNICATION_COOLDOWN
user.log_talk(input, LOG_SAY, tag="priority announcement")
message_admins("[ADMIN_LOOKUPFLW(user)] has made a priority announcement.")
diff --git a/code/controllers/subsystem/economy.dm b/code/controllers/subsystem/economy.dm
index 0e884ebd71a..a8a0176a125 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -35,6 +35,10 @@ SUBSYSTEM_DEF(economy)
var/civ_bounty_tracker = 0
/// Contains the message to send to newscasters about price inflation and earnings, updated on price_update()
var/earning_report
+ ///The modifier multiplied to the value of bounties paid out.
+ var/bounty_modifier = 1
+ ///The modifier multiplied to the value of cargo pack prices.
+ var/pack_price_modifier = 1
var/market_crashing = FALSE
var/fire_counter_for_paycheck = 0 //SKYRAT EDIT ADDITION
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 5567cd7179c..c0aa6ddce5d 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -454,8 +454,15 @@ SUBSYSTEM_DEF(job)
//If we joined at roundstart we should be positioned at our workstation
if(!joined_late)
+ var/spawning_handled = FALSE
var/obj/S = null
- if(length(GLOB.jobspawn_overrides[rank]))
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_LATE_ARRIVALS))
+ SendToLateJoin(living_mob)
+ spawning_handled = TRUE
+ else if(HAS_TRAIT(SSstation, STATION_TRAIT_RANDOM_ARRIVALS))
+ DropLandAtRandomHallwayPoint(living_mob)
+ spawning_handled = TRUE
+ else if(length(GLOB.jobspawn_overrides[rank]))
S = pick(GLOB.jobspawn_overrides[rank])
else
for(var/_sloc in GLOB.start_landmarks_list)
@@ -469,7 +476,7 @@ SUBSYSTEM_DEF(job)
break
if(S)
S.JoinPlayerHere(living_mob, FALSE)
- if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
+ if(!S && !spawning_handled) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
log_world("Couldn't find a round start spawn point for [rank]")
if(!SendToLateJoin(living_mob))
living_mob.move_to_error_room()
@@ -515,7 +522,7 @@ SUBSYSTEM_DEF(job)
var/mob/living/carbon/human/wageslave = living_mob
living_mob.add_memory("Your account ID is [wageslave.account_id].")
if(job && living_mob)
- job.after_spawn(living_mob, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
+ job.after_spawn(living_mob, M, joined_late) // note: this happens before the mob has a key! M will always have a client, living_mob might not.
//SKYRAT CHANGE ADDITION BEGIN - CUSTOMIZATION
if(!job.no_dresscode && job.loadout)
if(M.client)
@@ -709,6 +716,13 @@ SUBSYSTEM_DEF(job)
message_admins(msg)
CRASH(msg)
+///Lands specified mob at a random spot in the hallways
+/datum/controller/subsystem/job/proc/DropLandAtRandomHallwayPoint(mob/living/living_mob)
+ var/turf/spawn_turf = get_safe_random_station_turf(typesof(/area/hallway))
+
+ var/obj/structure/closet/supplypod/centcompod/toLaunch = new()
+ living_mob.forceMove(toLaunch)
+ new /obj/effect/pod_landingzone(spawn_turf, toLaunch)
///////////////////////////////////
//Keeps track of all living heads//
diff --git a/code/controllers/subsystem/processing/station.dm b/code/controllers/subsystem/processing/station.dm
new file mode 100644
index 00000000000..44a5f312e88
--- /dev/null
+++ b/code/controllers/subsystem/processing/station.dm
@@ -0,0 +1,52 @@
+PROCESSING_SUBSYSTEM_DEF(station)
+ name = "Station"
+ init_order = INIT_ORDER_STATION
+ flags = SS_BACKGROUND
+ runlevels = RUNLEVEL_GAME
+ wait = 5 SECONDS
+
+ ///A list of currently active station traits
+ var/list/station_traits = list()
+ ///Assoc list of trait type || assoc list of traits with weighted value. Used for picking traits from a specific category.
+ var/list/selectable_traits_by_types = list(STATION_TRAIT_POSITIVE = list(), STATION_TRAIT_NEUTRAL = list(), STATION_TRAIT_NEGATIVE = list())
+ ///Currently active announcer. Starts as a type but gets initialized after traits are selected
+ var/datum/centcom_announcer/announcer = /datum/centcom_announcer/default
+
+/datum/controller/subsystem/processing/station/Initialize(timeofday)
+
+ //If doing unit tests we don't do none of that trait shit ya know?
+ #ifndef UNIT_TESTS
+ SetupTraits()
+ #endif
+
+ announcer = new announcer() //Initialize the station's announcer datum
+
+ return ..()
+
+///Rolls for the amount of traits and adds them to the traits list
+/datum/controller/subsystem/processing/station/proc/SetupTraits()
+ for(var/i in subtypesof(/datum/station_trait))
+ var/datum/station_trait/trait_typepath = i
+ selectable_traits_by_types[initial(trait_typepath.trait_type)][trait_typepath] = initial(trait_typepath.weight)
+
+ var/positive_trait_count = pick(12;0, 5;1, 1;2)
+ var/neutral_trait_count = pick(5;0, 10;1, 3;2)
+ var/negative_trait_count = pick(12;0, 5;1, 1;2)
+
+ pick_traits(STATION_TRAIT_POSITIVE, positive_trait_count)
+ pick_traits(STATION_TRAIT_NEUTRAL, neutral_trait_count)
+ pick_traits(STATION_TRAIT_NEGATIVE, negative_trait_count)
+
+///Picks traits of a specific category (e.g. bad or good) and a specified amount, then initializes them and adds them to the list of traits.
+/datum/controller/subsystem/processing/station/proc/pick_traits(trait_type, amount)
+ if(!amount)
+ return
+ for(var/iterator in 1 to amount)
+ var/datum/station_trait/picked_trait = pickweight(selectable_traits_by_types[trait_type]) //Rolls from the table for the specific trait type
+ picked_trait = new picked_trait()
+ station_traits += picked_trait
+ if(!picked_trait.blacklist)
+ continue
+ for(var/i in picked_trait.blacklist)
+ var/datum/station_trait/trait_to_remove = i
+ selectable_traits_by_types[initial(trait_to_remove.trait_type)] -= trait_to_remove
diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm
index 2110c57cabf..0846b430523 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -404,7 +404,7 @@ SUBSYSTEM_DEF(shuttle)
emergency.setTimer(emergencyDockTime)
priority_announce("Hostile environment resolved. \
You have 3 minutes to board the Emergency Shuttle.",
- null, 'sound/ai/shuttledock.ogg', "Priority")
+ null, ANNOUNCER_SHUTTLEDOCK, "Priority")
//try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons
/datum/controller/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index e08f15c97b1..f73b973a21a 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -299,7 +299,7 @@ SUBSYSTEM_DEF(ticker)
SSdbcore.SetRoundStart()
to_chat(world, "Welcome to [station_name()], enjoy your stay!")
- SEND_SOUND(world, sound('sound/ai/welcome.ogg'))
+ SEND_SOUND(world, sound(SSstation.announcer.get_rand_welcome_sound()))
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index c4e5af8931f..c0d1c989a58 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -223,6 +223,11 @@
/datum/ai_laws/proc/set_laws_config()
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
+
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI))
+ pick_weighted_lawset()
+ return
+
switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
diff --git a/code/datums/announcers/_announcer.dm b/code/datums/announcers/_announcer.dm
new file mode 100644
index 00000000000..dab790438c1
--- /dev/null
+++ b/code/datums/announcers/_announcer.dm
@@ -0,0 +1,23 @@
+///Data holder for the announcers that can be used in a game, this can be used to have alternative announcements outside of the default e.g.the intern
+/datum/centcom_announcer
+ ///Roundshift start audio
+ var/welcome_sounds = list()
+ ///Sounds made when announcement is receivedc
+ var/alert_sounds = list()
+ ///Sounds made when command report is received
+ var/command_report_sounds = list()
+ ///Event audio, can be used for specific event announcements and is assoc key - sound. If no sound is found the default is used.area
+ var/event_sounds = list()
+ ///Override this to have a custom message to show instead of the normal priority announcement
+ var/custom_alert_message
+
+
+/datum/centcom_announcer/proc/get_rand_welcome_sound()
+ return pick(welcome_sounds)
+
+
+/datum/centcom_announcer/proc/get_rand_alert_sound()
+ return pick(alert_sounds)
+
+/datum/centcom_announcer/proc/get_rand_report_sound()
+ return pick(command_report_sounds)
diff --git a/code/datums/announcers/default_announcer.dm b/code/datums/announcers/default_announcer.dm
new file mode 100644
index 00000000000..d6d62ec65db
--- /dev/null
+++ b/code/datums/announcers/default_announcer.dm
@@ -0,0 +1,19 @@
+/datum/centcom_announcer/default
+ welcome_sounds = list('sound/ai/default/welcome.ogg')
+ alert_sounds = list('sound/ai/default/attention.ogg')
+ command_report_sounds = list('sound/ai/default/commandreport.ogg')
+ event_sounds = list(ANNOUNCER_AIMALF = 'sound/ai/default/aimalf.ogg',
+ ANNOUNCER_ALIENS = 'sound/ai/default/aliens.ogg',
+ ANNOUNCER_ANIMES = 'sound/ai/default/animes.ogg',
+ ANNOUNCER_GRANOMALIES = 'sound/ai/default/granomalies.ogg',
+ ANNOUNCER_INTERCEPT = 'sound/ai/default/intercept.ogg',
+ ANNOUNCER_IONSTORM = 'sound/ai/default/ionstorm.ogg',
+ ANNOUNCER_OUTBREAK5 = 'sound/ai/default/outbreak5.ogg',
+ ANNOUNCER_OUTBREAK7 = 'sound/ai/default/outbreak7.ogg',
+ ANNOUNCER_POWEROFF = 'sound/ai/default/poweroff.ogg',
+ ANNOUNCER_POWERON = 'sound/ai/default/poweron.ogg',
+ ANNOUNCER_RADIATION = 'sound/ai/default/radiation.ogg',
+ ANNOUNCER_SHUTTLECALLED = 'sound/ai/default/shuttlecalled.ogg',
+ ANNOUNCER_SHUTTLEDOCK = 'sound/ai/default/shuttledock.ogg',
+ ANNOUNCER_SHUTTLERECALLED = 'sound/ai/default/shuttlerecalled.ogg',
+ ANNOUNCER_SPANOMALIES = 'sound/ai/default/spanomalies.ogg')
diff --git a/code/datums/announcers/intern_announcer.dm b/code/datums/announcers/intern_announcer.dm
new file mode 100644
index 00000000000..415eee595e6
--- /dev/null
+++ b/code/datums/announcers/intern_announcer.dm
@@ -0,0 +1,45 @@
+/datum/centcom_announcer/intern
+ welcome_sounds = list('sound/ai/intern/welcome/1.ogg',
+ 'sound/ai/intern/welcome/2.ogg',
+ 'sound/ai/intern/welcome/3.ogg',
+ 'sound/ai/intern/welcome/4.ogg',
+ 'sound/ai/intern/welcome/5.ogg',
+ 'sound/ai/intern/welcome/6.ogg')
+
+ alert_sounds = list('sound/ai/intern/alerts/1.ogg',
+ 'sound/ai/intern/alerts/2.ogg',
+ 'sound/ai/intern/alerts/3.ogg',
+ 'sound/ai/intern/alerts/4.ogg',
+ 'sound/ai/intern/alerts/5.ogg',
+ 'sound/ai/intern/alerts/6.ogg',
+ 'sound/ai/intern/alerts/7.ogg',
+ 'sound/ai/intern/alerts/8.ogg',
+ 'sound/ai/intern/alerts/9.ogg',
+ 'sound/ai/intern/alerts/10.ogg',
+ 'sound/ai/intern/alerts/11.ogg',
+ 'sound/ai/intern/alerts/12.ogg',
+ 'sound/ai/intern/alerts/13.ogg',
+ 'sound/ai/intern/alerts/14.ogg')
+
+
+ command_report_sounds = list('sound/ai/intern/commandreport/1.ogg',
+ 'sound/ai/intern/commandreport/2.ogg',
+ 'sound/ai/intern/commandreport/3.ogg')
+
+ event_sounds = list(ANNOUNCER_AIMALF = 'sound/ai/intern/aimalf.ogg',
+ ANNOUNCER_ALIENS = 'sound/ai/intern/aliens.ogg',
+ ANNOUNCER_ANIMES = 'sound/ai/intern/animes.ogg',
+ ANNOUNCER_GRANOMALIES = 'sound/ai/intern/granomalies.ogg',
+ ANNOUNCER_INTERCEPT = 'sound/ai/intern/intercept.ogg',
+ ANNOUNCER_IONSTORM = 'sound/ai/intern/ionstorm.ogg',
+ ANNOUNCER_OUTBREAK5 = 'sound/ai/intern/outbreak5.ogg',
+ ANNOUNCER_OUTBREAK7 = 'sound/ai/intern/outbreak7.ogg',
+ ANNOUNCER_POWEROFF = 'sound/ai/intern/poweroff.ogg',
+ ANNOUNCER_POWERON = 'sound/ai/intern/poweron.ogg',
+ ANNOUNCER_RADIATION = 'sound/ai/intern/radiation.ogg',
+ ANNOUNCER_SHUTTLECALLED = 'sound/ai/intern/shuttlecalled.ogg',
+ ANNOUNCER_SHUTTLEDOCK = 'sound/ai/intern/shuttledock.ogg',
+ ANNOUNCER_SHUTTLERECALLED = 'sound/ai/intern/shuttlerecalled.ogg',
+ ANNOUNCER_SPANOMALIES = 'sound/ai/intern/spanomalies.ogg')
+
+ custom_alert_message = "
Please stand by for an important message from our new intern.
"
diff --git a/code/datums/atmosphere/_atmosphere.dm b/code/datums/atmosphere/_atmosphere.dm
index bd4227f2f59..fb1dcbb8345 100644
--- a/code/datums/atmosphere/_atmosphere.dm
+++ b/code/datums/atmosphere/_atmosphere.dm
@@ -19,7 +19,10 @@
/datum/atmosphere/proc/generate_gas_string()
var/target_pressure = rand(minimum_pressure, maximum_pressure)
var/pressure_scalar = target_pressure / maximum_pressure
-
+
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE))
+ restricted_chance = restricted_chance + 30
+
// First let's set up the gasmix and base gases for this template
// We make the string from a gasmix in this proc because gases need to calculate their pressure
var/datum/gas_mixture/gasmix = new
@@ -39,13 +42,13 @@
else
gastype = pick(restricted_gases)
amount = restricted_gases[gastype]
- if(gaslist[gastype])
+ if(!HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE) && gaslist[gastype])
continue
-
+
amount *= rand(50, 200) / 100 // Randomly modifes the amount from half to double the base for some variety
amount *= pressure_scalar // If we pick a really small target pressure we want roughly the same mix but less of it all
amount = CEILING(amount, 0.1)
-
+
ASSERT_GAS(gastype, gasmix)
gaslist[gastype][MOLES] += amount
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index bd6b846b1d6..37f4c176bce 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -93,7 +93,7 @@
effect.start()
// Safe location finder
-/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
+/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE, dense_atoms = TRUE)
if(!zlevels)
if (zlevel)
zlevels = list(zlevel)
@@ -149,6 +149,16 @@
if(!L.is_safe())
continue
+ // Check that we're not warping onto a table or window
+ if(!dense_atoms)
+ var/density_found = FALSE
+ for(var/atom/movable/found_movable in F)
+ if(found_movable.density)
+ density_found = TRUE
+ break
+ if(density_found)
+ continue
+
// DING! You have passed the gauntlet, and are "probably" safe.
return F
diff --git a/code/datums/station_traits/_station_trait.dm b/code/datums/station_traits/_station_trait.dm
new file mode 100644
index 00000000000..76fb3fa8ad4
--- /dev/null
+++ b/code/datums/station_traits/_station_trait.dm
@@ -0,0 +1,35 @@
+///Base class of station traits. These are used to influence rounds in one way or the other by influencing the levers of the station.
+/datum/station_trait
+ ///Name of the trait
+ var/name = "unnamed station trait"
+ ///The type of this trait. Used to classify how this trait influences the station
+ var/trait_type = STATION_TRAIT_NEUTRAL
+ ///Whether or not this trait uses process()
+ var/trait_processes = FALSE
+ ///Chance relative to other traits of its type to be picked
+ var/weight = 10
+ ///Does this trait show in the centcom report?
+ var/show_in_report = FALSE
+ ///What message to show in the centcom report?
+ var/report_message
+ ///What code-trait does this station trait give? gives none if null
+ var/trait_to_give
+ ///What traits are incompatible with this one?
+ var/blacklist
+
+
+/datum/station_trait/New()
+ . = ..()
+ SSticker.OnRoundstart(CALLBACK(src, .proc/on_round_start))
+ if(trait_processes)
+ START_PROCESSING(SSstation, src)
+ if(trait_to_give)
+ ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT)
+
+///Proc ran when round starts. Use this for roundstart effects.
+/datum/station_trait/proc/on_round_start()
+ return
+
+///type of info the centcom report has on this trait, if any.
+/datum/station_trait/proc/get_report()
+ return "[name] - [report_message]"
diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm
new file mode 100644
index 00000000000..ec97e1a8884
--- /dev/null
+++ b/code/datums/station_traits/negative_traits.dm
@@ -0,0 +1,92 @@
+/datum/station_trait/carp_infestation
+ name = "Carp infestation"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Dangerous fauna is present in the area of this station"
+ trait_to_give = STATION_TRAIT_CARP_INFESTATION
+
+/datum/station_trait/distant_supply_lines
+ name = "Distant supply lines"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 3
+ show_in_report = TRUE
+ report_message = "Due to the distance to our normal supply lines, cargo orders are more expensive."
+ blacklist = list(/datum/station_trait/strong_supply_lines)
+
+/datum/station_trait/distant_supply_lines/on_round_start()
+ SSeconomy.pack_price_modifier *= 1.2
+
+/datum/station_trait/late_arrivals
+ name = "Late Arrivals"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 2
+ show_in_report = TRUE
+ report_message = "Sorry for that, we didn't expect to fly into that vomiting goose while bringing you to your new station."
+ trait_to_give = STATION_TRAIT_LATE_ARRIVALS
+ blacklist = list(/datum/station_trait/random_spawns)
+
+/datum/station_trait/random_spawns
+ name = "Drive-by landing"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 2
+ show_in_report = TRUE
+ report_message = "Sorry for that, we missed your station by a few miles, so we just launched you towards your station in pods. Hope you don't mind!"
+ trait_to_give = STATION_TRAIT_RANDOM_ARRIVALS
+ blacklist = list(/datum/station_trait/late_arrivals)
+
+/datum/station_trait/blackout
+ name = "Blackout"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Station lights seem to be damaged, be safe when starting your shift today."
+
+/datum/station_trait/blackout/on_round_start()
+ . = ..()
+ for(var/a in GLOB.apcs_list)
+ var/obj/machinery/power/apc/current_apc = a
+ if(prob(60))
+ current_apc.overload_lighting()
+
+/datum/station_trait/empty_maint
+ name = "Cleaned out maintenance"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Our workers cleaned out most of the junk in the maintenace areas."
+ blacklist = list(/datum/station_trait/filled_maint)
+ trait_to_give = STATION_TRAIT_EMPTY_MAINT
+
+
+/datum/station_trait/overflow_job_bureacracy
+ name = "Overflow bureacracy mistake"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 5
+ show_in_report = TRUE
+ var/list/jobs_to_use = list("Clown", "Bartender", "Cook", "Botanist", "Cargo Technician", "Mime", "Janitor", "Prisoner")
+ var/chosen_job
+
+/datum/station_trait/overflow_job_bureacracy/New()
+ . = ..()
+ chosen_job = pick(jobs_to_use)
+ RegisterSignal(SSjob, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/set_overflow_job_override)
+
+/datum/station_trait/overflow_job_bureacracy/get_report()
+ return "[name] - It seems for some reason we put out the wrong job-listing for the overflow role this shift...I hope you like [chosen_job]s."
+
+/datum/station_trait/overflow_job_bureacracy/proc/set_overflow_job_override(datum/source, new_overflow_role)
+ SIGNAL_HANDLER
+ SSjob.set_overflow_role(chosen_job)
+
+/datum/station_trait/slow_shuttle
+ name = "Slow Shuttle"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Due to distance to our supply station, the cargo shuttle will have a slower flight time to your cargo department."
+ blacklist = list(/datum/station_trait/quick_shuttle)
+
+/datum/station_trait/slow_shuttle/on_round_start()
+ . = ..()
+ SSshuttle.supply.callTime *= 1.5
diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm
new file mode 100644
index 00000000000..ef6b654663b
--- /dev/null
+++ b/code/datums/station_traits/neutral_traits.dm
@@ -0,0 +1,64 @@
+/datum/station_trait/bananium_shipment
+ name = "Bananium Shipment"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ report_message = "Rumors has it that the clown planet has been sending support packages to clowns in this system"
+ trait_to_give = STATION_TRAIT_BANANIUM_SHIPMENTS
+
+/datum/station_trait/unnatural_atmosphere
+ name = "Unnatural atmospherical properties"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = TRUE
+ report_message = "System's local planet has irregular atmospherical properties"
+ trait_to_give = STATION_TRAIT_UNNATURAL_ATMOSPHERE
+
+/datum/station_trait/unique_ai
+ name = "Unique AI"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = TRUE
+ report_message = "For experimental purposes, this station AI might show divergence from default lawset. Do not meddle with this experiment."
+ trait_to_give = STATION_TRAIT_UNIQUE_AI
+
+/datum/station_trait/ian_adventure
+ name = "Ian's Adventure"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = FALSE
+ report_message = "Ian has gone exploring somewhere in the station."
+
+/datum/station_trait/ian_adventure/on_round_start()
+ for(var/mob/living/simple_animal/pet/dog/corgi/dog in GLOB.mob_list)
+ if(!(istype(dog, /mob/living/simple_animal/pet/dog/corgi/ian) || istype(dog, /mob/living/simple_animal/pet/dog/corgi/puppy/ian)))
+ continue
+
+ // The extended safety checks at time of writing are about chasms and lava
+ // if there are any chasms and lava on stations in the future, woah
+ var/turf/current_turf = get_turf(dog)
+ var/turf/adventure_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE)
+
+ // Poof!
+ do_smoke(location=current_turf)
+ dog.forceMove(adventure_turf)
+ do_smoke(location=adventure_turf)
+
+
+/datum/station_trait/glitched_pdas
+ name = "PDA glitch"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 8
+ show_in_report = TRUE
+ report_message = "Something seems to be wrong with the PDAs issues to you all this shift. Nothing too bad though."
+ trait_to_give = STATION_TRAIT_PDA_GLITCHED
+
+/datum/station_trait/announcement_intern
+ name = "Announcement Intern"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Please be nice to him."
+
+/datum/station_trait/announcement_intern/New()
+ . = ..()
+ SSstation.announcer = /datum/centcom_announcer/intern
diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm
new file mode 100644
index 00000000000..2c7dcc1de64
--- /dev/null
+++ b/code/datums/station_traits/positive_traits.dm
@@ -0,0 +1,125 @@
+#define PARTY_COOLDOWN_LENGTH_MIN 6 MINUTES
+#define PARTY_COOLDOWN_LENGTH_MAX 12 MINUTES
+
+
+/datum/station_trait/lucky_winner
+ name = "Lucky winner"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 1
+ show_in_report = TRUE
+ report_message = "Your station has won the grand prize of the annual station charity event. Free snacks will be delivered to the bar every now and then."
+ trait_processes = TRUE
+ COOLDOWN_DECLARE(party_cooldown)
+
+/datum/station_trait/lucky_winner/on_round_start()
+ . = ..()
+ COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX))
+
+/datum/station_trait/lucky_winner/process(delta_time)
+ if(!COOLDOWN_FINISHED(src, party_cooldown))
+ return
+
+ COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX))
+
+ var/area/area_to_spawn_in = pick(GLOB.bar_areas)
+ var/turf/T = pick(area_to_spawn_in.contents)
+
+ var/obj/structure/closet/supplypod/centcompod/toLaunch = new()
+ var/obj/item/pizzabox/pizza_to_spawn = pick(list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/mushroom, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable, /obj/item/pizzabox/pineapple))
+ new pizza_to_spawn(toLaunch)
+ for(var/i in 1 to 6)
+ new /obj/item/reagent_containers/food/drinks/beer(toLaunch)
+ new /obj/effect/pod_landingzone(T, toLaunch)
+
+/datum/station_trait/galactic_grant
+ name = "Galactic grant"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Your station has been selected for a special grant. Some extra funds has been made available to your cargo department."
+
+/datum/station_trait/galactic_grant/on_round_start()
+ var/datum/bank_account/cargo_bank = SSeconomy.get_dep_account(ACCOUNT_CAR)
+ cargo_bank.adjust_money(rand(2000, 5000))
+
+/datum/station_trait/premium_internals_box
+ name = "Premium internals boxes"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 10
+ show_in_report = TRUE
+ report_message = "The internals boxes for your crew have been filled with bonus equipment."
+ trait_to_give = STATION_TRAIT_PREMIUM_INTERNALS
+
+/datum/station_trait/bountiful_bounties
+ name = "Bountiful bounties"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "It seems collectors in this system are extra keen to on bounties, and will pay more to see their completion."
+
+/datum/station_trait/bountiful_bounties/on_round_start()
+ SSeconomy.bounty_modifier *= 1.2
+
+/datum/station_trait/strong_supply_lines
+ name = "Strong supply lines"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Prices are low in this system, BUY BUY BUY!"
+ blacklist = list(/datum/station_trait/distant_supply_lines)
+
+
+/datum/station_trait/strong_supply_lines/on_round_start()
+ SSeconomy.pack_price_modifier *= 0.8
+
+/datum/station_trait/scarves
+ name = "Scarves"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ var/list/scarves
+
+/datum/station_trait/scarves/New()
+ . = ..()
+ report_message = pick(
+ "Nanotrasen is experimenting with seeing if neck warmth improves employee morale.",
+ "After Space Fashion Week, scarves are the hot new accessory.",
+ "Everyone was simultaneously a little bit cold when they packed to go to the station.",
+ "The station is definitely not under attack by neck grappling aliens masquerading as wool. Definitely not.",
+ "You all get free scarves. Don't ask why.",
+ "A shipment of scarves was delivered to the station.",
+ )
+ scarves = typesof(/obj/item/clothing/neck/scarf) + list(
+ /obj/item/clothing/neck/stripedredscarf,
+ /obj/item/clothing/neck/stripedgreenscarf,
+ /obj/item/clothing/neck/stripedbluescarf,
+ )
+
+ RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn)
+
+/datum/station_trait/scarves/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/living_mob, mob/M, joined_late)
+ SIGNAL_HANDLER
+ var/scarf_type = pick(scarves)
+
+ living_mob.equip_to_slot_or_del(new scarf_type(living_mob), ITEM_SLOT_NECK, initial = FALSE)
+
+/datum/station_trait/filled_maint
+ name = "Filled up maintenance"
+ trait_type = STATION_TRAIT_POSITIVE
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Our workers accidentaly forgot more of their personal belongings in the maintenace areas."
+ blacklist = list(/datum/station_trait/empty_maint)
+ trait_to_give = STATION_TRAIT_FILLED_MAINT
+
+/datum/station_trait/quick_shuttle
+ name = "Quick Shuttle"
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 5
+ show_in_report = TRUE
+ report_message = "Due to proximity to our supply station, the cargo shuttle will have a quicker flight time to your cargo department/"
+ blacklist = list(/datum/station_trait/slow_shuttle)
+
+/datum/station_trait/quick_shuttle/on_round_start()
+ . = ..()
+ SSshuttle.supply.callTime *= 0.5
diff --git a/code/game/area/space_station_13_areas.dm b/code/game/area/space_station_13_areas.dm
index a1819a2b65e..237049c9aae 100644
--- a/code/game/area/space_station_13_areas.dm
+++ b/code/game/area/space_station_13_areas.dm
@@ -611,6 +611,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_WOODFLOOR
+/area/service/bar/Initialize(mapload)
+ . = ..()
+ GLOB.bar_areas += src
+
/area/service/bar/atrium
name = "Atrium"
icon_state = "bar"
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index e3bd3457cae..cce06c086f7 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -264,8 +264,17 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
G.on_report()
. += G.get_report()
+ if(SSstation.station_traits.len)
+ . += "
Identified shift divergencies:
"
+ for(var/i in SSstation.station_traits)
+ var/datum/station_trait/station_trait_iterator = i
+ if(!station_trait_iterator.show_in_report)
+ return
+ . += "[station_trait_iterator.get_report()]
"
+
+
print_command_report(., "Central Command Status Summary", announce=FALSE)
- priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", 'sound/ai/intercept.ogg')
+ priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 242c9c146e4..ccd12bd34b9 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -322,7 +322,7 @@
M.mind.special_role = antag_flag
M.mind.add_antag_datum(AI)
if(prob(ion_announce))
- priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
+ priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", ANNOUNCER_IONSTORM)
if(prob(removeDontImproveChance))
M.replace_random_law(generate_ion_law(), list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
else
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 8a7181aaa3d..a512523b1b6 100644
--- a/code/game/gamemodes/events.dm
+++ b/code/game/gamemodes/events.dm
@@ -1,5 +1,5 @@
/proc/power_failure()
- priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
+ priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", ANNOUNCER_POWEROFF)
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z))
continue
@@ -30,7 +30,7 @@
/proc/power_restore()
- priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
+ priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWEROFF)
for(var/obj/machinery/power/apc/C in GLOB.machines)
if(C.cell && is_station_level(C.z))
C.cell.charge = C.cell.maxcharge
@@ -54,7 +54,7 @@
/proc/power_restore_quick()
- priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
+ priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWERON)
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(!is_station_level(S.z))
continue
diff --git a/code/game/gamemodes/extended/extended.dm b/code/game/gamemodes/extended/extended.dm
index d1b90b50b54..b3e198012ae 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -26,4 +26,4 @@
G.on_report()
/datum/game_mode/extended/announced/send_intercept(report = 0)
- priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/ai/commandreport.ogg')
+ priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound())
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index eca0b9c22a6..69a10fc9ff4 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -299,8 +299,16 @@
G.on_report()
intercepttext += G.get_report()
+ if(SSstation.station_traits.len)
+ intercepttext += "
Identified shift divergencies:"
+ for(var/i in SSstation.station_traits)
+ var/datum/station_trait/station_trait_iterator = i
+ if(!station_trait_iterator.show_in_report)
+ return
+ intercepttext += station_trait_iterator.get_report()
+
print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE)
- priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/ai/intercept.ogg')
+ priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 4bf4825e7a7..efa616ad46f 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -227,7 +227,7 @@
nuke_request(reason, usr)
to_chat(usr, "Request sent.")
usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
- priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", 'sound/ai/commandreport.ogg')
+ priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", SSstation.announcer.get_rand_report_sound())
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
COOLDOWN_START(src, important_action_cooldown, IMPORTANT_ACTION_COOLDOWN)
if ("restoreBackupRoutingData")
diff --git a/code/game/objects/effects/spawners/lootdrop.dm b/code/game/objects/effects/spawners/lootdrop.dm
index d624c8ac564..f354b2ee66a 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -245,6 +245,13 @@
/obj/effect/spawner/lootdrop/maintenance/Initialize(mapload)
loot = GLOB.maintenance_loot
+
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_FILLED_MAINT))
+ lootcount = FLOOR(lootcount * 1.5, 1)
+
+ else if(HAS_TRAIT(SSstation, STATION_TRAIT_EMPTY_MAINT))
+ lootcount = FLOOR(lootcount * 0.5, 1)
+
. = ..()
/obj/effect/spawner/lootdrop/maintenance/two
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index 999fbb88253..bfeb93e8d4c 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -785,7 +785,10 @@ GLOBAL_LIST_EMPTY(PDAs)
tnote += "← From [signal.data["name"]] ([signal.data["job"]]):
[signal.format_message()]
"
if (!silent)
- playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_PDA_GLITCHED))
+ playsound(src, pick('sound/machines/twobeep_voice1.ogg', 'sound/machines/twobeep_voice2.ogg'), 50, TRUE)
+ else
+ playsound(src, 'sound/machines/twobeep_high.ogg', 50, TRUE)
audible_message("[icon2html(src, hearers(src))] *[ttone]*", null, 3)
//Search for holder of the PDA.
var/mob/living/L = null
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 577a2695b4e..f6a8f00e1d0 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -263,6 +263,9 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
. = ..()
. += GLOB.bananium_recipes
+/obj/item/stack/sheet/mineral/bananium/five
+ amount = 5
+
/*
* Titanium
*/
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index 082caf18022..9b5dc6e2b70 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -138,6 +138,10 @@
//SKYRAT EDIT END
new /obj/item/oxygen_candle(src) //SKYRAT EDIT ADDITION
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
+ new /obj/item/flashlight/flare(src)
+ new /obj/item/radio/off(src)
+
/obj/item/storage/box/survival/radio/PopulateContents()
..() // we want the survival stuff too.
new /obj/item/radio/off(src)
@@ -851,6 +855,9 @@
//SKYRAT EDIT END
new /obj/item/oxygen_candle(src) //SKYRAT EDIT ADDITION
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
+ new /obj/item/flashlight/flare(src)
+ new /obj/item/radio/off(src)
/obj/item/storage/box/rubbershot
name = "box of rubber shots"
desc = "A box full of rubber shots, designed for riot shotguns."
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 99037b17091..da28b8552ff 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -589,7 +589,7 @@
SSticker.start_immediately = FALSE
SSticker.SetTimeLeft(1800)
to_chat(world, "The game will start in 180 seconds.")
- SEND_SOUND(world, sound('sound/ai/attention.ogg'))
+ SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
message_admins("[usr.key] has cancelled immediate game start. Game will start in 180 seconds.")
log_admin("[usr.key] has cancelled immediate game start.")
else
@@ -656,7 +656,7 @@
log_admin("[key_name(usr)] delayed the round start.")
else
to_chat(world, "The game will start in [DisplayTimeText(newtime)].", confidential = TRUE)
- SEND_SOUND(world, sound('sound/ai/attention.ogg'))
+ SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/verbs/anonymousnames.dm b/code/modules/admin/verbs/anonymousnames.dm
index 595396224a0..6857a8fa7d9 100644
--- a/code/modules/admin/verbs/anonymousnames.dm
+++ b/code/modules/admin/verbs/anonymousnames.dm
@@ -16,7 +16,7 @@
message_admins("[key_name_admin(usr)] has disabled anonymous names.")
if(SSticker.current_state < GAME_STATE_PREGAME)
return
- priority_announce("Names and Identities have been restored.", "Identity Restoration", 'sound/ai/attention.ogg')
+ priority_announce("Names and Identities have been restored.", "Identity Restoration", SSstation.announcer.get_rand_alert_sound())
for(var/mob/living/player in GLOB.player_list)
if(!player.mind || (!ishuman(player) && !issilicon(player)) || !SSjob.GetJob(player.mind.assigned_role))
continue
@@ -41,7 +41,7 @@
alert_players = alert(usr, "Alert crew? These are IC Themed FROM centcom.", "2016 admins didn't miss roundstart", "Yes", "No")
SSticker.anonymousnames = new result()
if(alert_players == "Yes")
- priority_announce(SSticker.anonymousnames.announcement_alert, "Identity Loss", 'sound/ai/attention.ogg')
+ priority_announce(SSticker.anonymousnames.announcement_alert, "Identity Loss", SSstation.announcer.get_rand_alert_sound())
anonymous_all_players()
message_admins("[key_name_admin(usr)] has enabled anonymous names. THEME: [SSticker.anonymousnames].")
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index 380edb01af8..94cbf67d4c7 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -561,7 +561,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/announce_command_report = TRUE
switch(confirm)
if("Yes")
- priority_announce(input, null, 'sound/ai/commandreport.ogg')
+ priority_announce(input, null, SSstation.announcer.get_rand_report_sound())
announce_command_report = FALSE
if("Cancel")
return
diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm
index e6f6532599f..3c8ae9439fc 100644
--- a/code/modules/admin/verbs/secrets.dm
+++ b/code/modules/admin/verbs/secrets.dm
@@ -336,7 +336,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(holder)] activated Egalitarian Station mode")
- priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/ai/commandreport.ogg')
+ priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, SSstation.announcer.get_rand_report_sound())
if("ancap")
if(!is_funmin)
return
@@ -344,9 +344,9 @@
SSeconomy.full_ancap = !SSeconomy.full_ancap
message_admins("[key_name_admin(holder)] toggled Anarcho-capitalist mode")
if(SSeconomy.full_ancap)
- priority_announce("The NAP is now in full effect.", null, 'sound/ai/commandreport.ogg')
+ priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound())
else
- priority_announce("The NAP has been revoked.", null, 'sound/ai/commandreport.ogg')
+ priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound())
if("blackout")
if(!is_funmin)
return
@@ -502,7 +502,7 @@
message_admins("[key_name_admin(holder)] made everything kawaii.")
for(var/i in GLOB.human_list)
var/mob/living/carbon/human/H = i
- SEND_SOUND(H, sound('sound/ai/animes.ogg'))
+ SEND_SOUND(H, sound(SSstation.announcer.event_sounds[ANNOUNCER_ANIMES]))
if(H.dna.species.id == "human")
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm
index 629bc3d2a2b..33e1b66e85b 100644
--- a/code/modules/antagonists/blob/overmind.dm
+++ b/code/modules/antagonists/blob/overmind.dm
@@ -129,7 +129,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
max_count = blobs_legit.len
if(announcement_time && (world.time >= announcement_time || blobs_legit.len >= announcement_size) && !has_announced)
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK5)
has_announced = TRUE
/mob/camera/blob/proc/victory()
diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm
index 2c05b544e3b..8313862c9f9 100644
--- a/code/modules/antagonists/cult/ritual.dm
+++ b/code/modules/antagonists/cult/ritual.dm
@@ -120,7 +120,7 @@ This file contains the cult dagger and rune list code
if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move
to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!")
return
- priority_announce("Figments from an eldritch god are being summoned by [user] into [initial(A.name)] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
+ priority_announce("Figments from an eldritch god are being summoned by [user] into [initial(A.name)] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", ANNOUNCER_SPANOMALIES)
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/cult/narsie/N = new(B)
shields += N
diff --git a/code/modules/antagonists/eldritch_cult/eldritch_effects.dm b/code/modules/antagonists/eldritch_cult/eldritch_effects.dm
index 9cbfe139ea2..a8dd718f758 100644
--- a/code/modules/antagonists/eldritch_cult/eldritch_effects.dm
+++ b/code/modules/antagonists/eldritch_cult/eldritch_effects.dm
@@ -154,6 +154,7 @@
for(var/i in 0 to number)
var/turf/chosen_location = get_safe_random_station_turf()
+
//we also dont want them close to each other, at least 1 tile of seperation
var/obj/effect/reality_smash/what_if_i_have_one = locate() in range(1, chosen_location)
var/obj/effect/broken_illusion/what_if_i_had_one_but_got_used = locate() in range(1, chosen_location)
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
index 7045627ec55..19fa86e4497 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/ash_lore.dm
@@ -167,7 +167,7 @@
var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE)
/datum/eldritch_knowledge/final/ash_final/on_finished_recipe(mob/living/user, list/atoms, loc)
- priority_announce("$^@*$^@(#&$(@^$^@# Fear the blaze, for the Ashlord, [user.real_name] has ascended! The flames shall consume all! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear the blaze, for the Ashlord, [user.real_name] has ascended! The flames shall consume all! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/fire_cascade/big)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/fire_sworn)
var/mob/living/carbon/human/H = user
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
index b0f0bf1e581..7c8240f0861 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/flesh_lore.dm
@@ -222,7 +222,7 @@
/datum/eldritch_knowledge/final/flesh_final/on_finished_recipe(mob/living/user, list/atoms, loc)
. = ..()
- priority_announce("$^@*$^@(#&$(@^$^@# Ever coiling vortex. Reality unfolded. THE LORD OF ARMS, [user.real_name] has ascended! Fear the ever twisting hand! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Ever coiling vortex. Reality unfolded. THE LORD OF ARMS, [user.real_name] has ascended! Fear the ever twisting hand! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shed_human_form)
if(!ishuman(user))
return
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
index d4d37d382bc..e6600e16f0c 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/rust_lore.dm
@@ -142,7 +142,7 @@
H.physiology.brute_mod *= 0.5
H.physiology.burn_mod *= 0.5
H.client?.give_award(/datum/award/achievement/misc/rust_ascension, H)
- priority_announce("$^@*$^@(#&$(@^$^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
new /datum/rust_spread(loc)
return ..()
diff --git a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
index 9c9f544606a..eb098ae5bd9 100644
--- a/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
+++ b/code/modules/antagonists/eldritch_cult/knowledge/void_lore.dm
@@ -166,7 +166,7 @@
H.physiology.burn_mod *= 0.5
ADD_TRAIT(H, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
H.client?.give_award(/datum/award/achievement/misc/void_ascension, H)
- priority_announce("$^@*$^@(#&$(@^$^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
sound_loop = new(list(user),TRUE,TRUE)
return ..()
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
index 0b9cb25c6ba..a74e111fad2 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
@@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
if(!check_allowed(user) || !war_declaration)
return
- priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg')
+ priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE)
to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.")
@@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
to_chat(usr, "Invalid war declaration.")
return
- priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg')
+ priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE)
for(var/V in GLOB.syndicate_shuttle_boards)
var/obj/item/circuitboard/computer/syndicate_shuttle/board = V
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index 32bbceb8abe..0b636d34843 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -400,7 +400,7 @@
rev_head_body.makeUncloneable()
priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
- We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
+ We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
else
for (var/_player in GLOB.player_list)
var/mob/player = _player
@@ -436,7 +436,7 @@
priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \
For the safety of our staff, we have blacklisted your station for new employment of security and command. \
- [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
+ [pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, null, null, "Central Command Loyalty Monitoring Division")
/// Mutates the ticker to report that the revs have won
/datum/team/revolution/proc/round_result(finished)
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index 114442e26ee..f21b7d4b5e9 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -243,7 +243,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
if(!owner || QDELETED(owner))
return
if (owner_AI.stat != DEAD)
- priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
+ priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", ANNOUNCER_AIMALF)
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
diff --git a/code/modules/antagonists/traitor/equipment/contractor.dm b/code/modules/antagonists/traitor/equipment/contractor.dm
index a22211863e3..9553bd04a10 100644
--- a/code/modules/antagonists/traitor/equipment/contractor.dm
+++ b/code/modules/antagonists/traitor/equipment/contractor.dm
@@ -241,7 +241,7 @@
if (.)
power_fail(35, 50)
- priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
+ priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", ANNOUNCER_POWEROFF)
// Subtract cost, and spawn if it's an item.
/datum/contractor_item/proc/handle_purchase(datum/contractor_hub/hub, mob/living/user)
diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm
index 480c6772a72..8e381042f5e 100644
--- a/code/modules/antagonists/traitor/syndicate_contract.dm
+++ b/code/modules/antagonists/traitor/syndicate_contract.dm
@@ -134,7 +134,7 @@
D.adjust_money(-points_to_check)
priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \
- As is policy we've taken a portion of the station's funds to offset the overall cost.", null, 'sound/ai/attention.ogg', null, "Nanotrasen Asset Protection")
+ As is policy we've taken a portion of the station's funds to offset the overall cost.", null, null, null, "Nanotrasen Asset Protection")
sleep(30)
diff --git a/code/modules/cargo/bounty.dm b/code/modules/cargo/bounty.dm
index 712cf05f205..339686c13a4 100644
--- a/code/modules/cargo/bounty.dm
+++ b/code/modules/cargo/bounty.dm
@@ -13,7 +13,7 @@
if(can_claim())
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
- D.adjust_money(reward)
+ D.adjust_money(reward * SSeconomy.bounty_modifier)
claimed = TRUE
/// If an item sent in the cargo shuttle can satisfy the bounty.
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
index fa18ab87a46..539175c58c1 100644
--- a/code/modules/cargo/expressconsole.dm
+++ b/code/modules/cargo/expressconsole.dm
@@ -88,7 +88,7 @@
continue // i'd be right happy to
meme_pack_data[P.group]["packs"] += list(list(
"name" = P.name,
- "cost" = P.cost,
+ "cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
))
@@ -185,7 +185,7 @@
if(D)
points_to_check = D.account_balance
if(!(obj_flags & EMAGGED))
- if(SO.pack.cost <= points_to_check)
+ if(SO.pack.get_cost() <= points_to_check)
var/LZ
if (istype(beacon) && usingBeacon)//prioritize beacons over landing in cargobay
LZ = get_turf(beacon)
@@ -202,9 +202,9 @@
CHECK_TICK
if(empty_turfs?.len)
LZ = pick(empty_turfs)
- if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
+ if (SO.pack.get_cost() <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
TIMER_COOLDOWN_START(src, COOLDOWN_EXPRESSPOD_CONSOLE, 5 SECONDS)
- D.adjust_money(-SO.pack.cost)
+ D.adjust_money(-SO.pack.get_cost())
if(pack.special_pod)
new /obj/effect/pod_landingzone(LZ, pack.special_pod, SO)
else
@@ -212,7 +212,7 @@
. = TRUE
update_icon()
else
- if(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^)
+ if(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^)
landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone
for(var/turf/open/floor/T in landingzone.contents)
if(T.is_blocked_turf())
@@ -221,7 +221,7 @@
CHECK_TICK
if(empty_turfs?.len)
TIMER_COOLDOWN_START(src, COOLDOWN_EXPRESSPOD_CONSOLE, 10 SECONDS)
- D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)))
+ D.adjust_money(-(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS)))
SO.generateRequisition(get_turf(src))
for(var/i in 1 to MAX_EMAG_ROCKETS)
diff --git a/code/modules/cargo/orderconsole.dm b/code/modules/cargo/orderconsole.dm
index 586fbcafa2e..af797c8c72c 100644
--- a/code/modules/cargo/orderconsole.dm
+++ b/code/modules/cargo/orderconsole.dm
@@ -99,7 +99,7 @@
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
- "cost" = SO.pack.cost,
+ "cost" = SO.pack.get_cost(),
"id" = SO.id,
"orderer" = SO.orderer,
"paid" = !isnull(SO.paying_account) //paid by requester
@@ -109,7 +109,7 @@
for(var/datum/supply_order/SO in SSshuttle.requestlist)
data["requests"] += list(list(
"object" = SO.pack.name,
- "cost" = SO.pack.cost,
+ "cost" = SO.pack.get_cost(),
"orderer" = SO.orderer,
"reason" = SO.reason,
"id" = SO.id
@@ -132,7 +132,7 @@
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
- "cost" = P.cost,
+ "cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 929ebacd510..4ff37f08687 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -36,6 +36,10 @@
fill(C)
return C
+/datum/supply_pack/proc/get_cost()
+ . = cost
+ . *= SSeconomy.pack_price_modifier
+
/datum/supply_pack/proc/fill(obj/structure/closet/crate/C)
if (admin_spawned)
for(var/item in contains)
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 1df3ade178d..bb5484cfdcb 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -42,7 +42,7 @@
living_aliens = TRUE
if(living_aliens || fake)
- priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS)
/datum/round_event/ghost_role/alien_infestation/spawn_role()
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index 7d12e871239..52bf8eabb27 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -20,7 +20,7 @@
fakeable = TRUE
/datum/round_event/ghost_role/blob/announce(fake)
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK5)
/datum/round_event/ghost_role/blob/spawn_role()
if(!GLOB.blobstart.len)
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index 695cd9ec8ff..bbf199498e6 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -6,6 +6,15 @@
earliest_start = 10 MINUTES
max_occurrences = 6
+/datum/round_event_control/carp_migration/New()
+ . = ..()
+ if(!HAS_TRAIT(SSstation, STATION_TRAIT_CARP_INFESTATION))
+ return
+ weight *= 3
+ max_occurrences *= 2
+ earliest_start *= 0.5
+
+
/datum/round_event/carp_migration
announceWhen = 3
startWhen = 50
@@ -28,7 +37,7 @@
fishannounce(fish) //Prefer to announce the megacarps over the regular fishies
fishannounce(fish)
-/datum/round_event/carp_migration/proc/fishannounce(atom/fish)
+/datum/round_event/carp_migration/proc/fishannounce(atom/fish)
if (!hasAnnounced)
announce_to_ghosts(fish) //Only anounce the first fish
hasAnnounced = TRUE
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index 021e1a67c7a..8e68a0b837d 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -14,7 +14,7 @@
/datum/round_event/disease_outbreak/announce(fake)
- priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
+ priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK7)
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm
index 6fe14d6b77c..eaef2e0d110 100644
--- a/code/modules/events/grid_check.dm
+++ b/code/modules/events/grid_check.dm
@@ -9,7 +9,7 @@
startWhen = 1
/datum/round_event/grid_check/announce(fake)
- priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
+ priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", ANNOUNCER_POWEROFF)
/datum/round_event/grid_check/start()
power_fail(30, 120)
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 9fb19177aaf..e4272a6440d 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -23,7 +23,7 @@
/datum/round_event/ion_storm/announce(fake)
if(prob(announceChance) || fake)
- priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
+ priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", ANNOUNCER_IONSTORM)
/datum/round_event/ion_storm/start()
diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm
index 11af56526c8..e6859c51977 100644
--- a/code/modules/events/meateor_wave.dm
+++ b/code/modules/events/meateor_wave.dm
@@ -8,4 +8,4 @@
wave_name = "meaty"
/datum/round_event/meteor_wave/meaty/announce(fake)
- priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/ai/meteors.ogg')
+ priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", ANNOUNCER_METEORS)
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index faaccf186b2..2c30e2a5e99 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -48,7 +48,7 @@
/datum/round_event/meteor_wave/announce(fake)
//priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg') //ORIGINAL
- priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.", "Meteor Alert", 'sound/ai/meteors.ogg') //ORIGINAL
+ priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.", "Meteor Alert", ANNOUNCER_METEORS) //ORIGINAL
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index 6a4f3e16ead..819fdef6193 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -27,7 +27,7 @@
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
/datum/round_event/pirates/announce(fake)
- priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg')
+ priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
if(fake)
return
threat = new
diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm
index 56b53643148..96e400fa67c 100644
--- a/code/modules/events/radiation_storm.dm
+++ b/code/modules/events/radiation_storm.dm
@@ -13,7 +13,7 @@
announceWhen = 1
/datum/round_event/radiation_storm/announce(fake)
- priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/ai/radiation.ogg')
+ priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", ANNOUNCER_RADIATION)
//sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index ae182207abb..700019903e0 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -14,11 +14,11 @@
announceWhen = rand(announceWhen, announceWhen + 50)
/datum/round_event/spider_infestation/announce(fake)
- priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS)
/datum/round_event/spider_infestation/start()
create_midwife_eggs(spawncount)
-
+
/proc/create_midwife_eggs(amount)
var/list/spawn_locs = list()
for(var/x in GLOB.xeno_spawn)
diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm
index d773cca45e0..d21570f8423 100644
--- a/code/modules/events/wizard/departmentrevolt.dm
+++ b/code/modules/events/wizard/departmentrevolt.dm
@@ -110,7 +110,7 @@
var/announce_text = "The new independent state of [nation_name] has formed from the ashes of the [department] department!"
if(department == "Uprising of Assistants") //the text didn't really work otherwise
announce_text = "The assistants of the station have risen to form the new independent state of [nation_name]!"
- priority_announce(announce_text, "Secession from [GLOB.station_name]")
+ priority_announce(announce_text, "Secession from [GLOB.station_name]", has_important_message = TRUE)
else
message_admins("The nation of [nation_name] did not have enough potential members to be created.")
qdel(nation)
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index 8d3955e57df..8172ffd15ff 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to
wormholes += new /obj/effect/portal/wormhole(T, 0, null, FALSE)
/datum/round_event/wormholes/announce(fake)
- priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
+ priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", ANNOUNCER_SPANOMALIES)
/datum/round_event/wormholes/tick()
if(activeFor % shift_frequency == 0)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 6b6593dce06..c9b843265e8 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -1044,7 +1044,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("blob alert")
to_chat(target, "Biohazard Alert
")
to_chat(target, "
Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.
")
- SEND_SOUND(target, 'sound/ai/outbreak5.ogg')
+ SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_OUTBREAK5])
if("ratvar")
target.playsound_local(target, 'sound/machines/clockcult/ark_deathrattle.ogg', 50, FALSE, pressure_affected = FALSE)
target.playsound_local(target, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE)
@@ -1063,15 +1063,15 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("shuttle dock")
to_chat(target, "Priority Announcement
")
to_chat(target, "
The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.
")
- SEND_SOUND(target, 'sound/ai/shuttledock.ogg')
+ SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_SHUTTLEDOCK])
if("malf ai") //AI is doomsdaying!
to_chat(target, "Anomaly Alert
")
to_chat(target, "
Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.
")
- SEND_SOUND(target, 'sound/ai/aimalf.ogg')
+ SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_AIMALF])
if("meteors") //Meteors inbound!
to_chat(target, "Meteor Alert
")
to_chat(target, "
Meteors have been detected on collision course with the station.
")
- SEND_SOUND(target, 'sound/ai/meteors.ogg')
+ SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_METEORS])
if("supermatter")
SEND_SOUND(target, 'sound/magic/charge.ogg')
to_chat(target, "You feel reality distort for a moment...")
diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm
index d4beb308bbb..ecdd6d9a419 100644
--- a/code/modules/holiday/easter.dm
+++ b/code/modules/holiday/easter.dm
@@ -18,7 +18,7 @@
max_occurrences = 10
/datum/round_event/rabbitrelease/announce(fake)
- priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", ANNOUNCER_ALIENS)
/datum/round_event/rabbitrelease/start()
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index f0edac63bb8..76c2558bed8 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -89,6 +89,7 @@
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
//do actions on H but send messages to M as the key may not have been transferred_yet
+ SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_SPAWN, src, H, M, latejoin)
if(mind_traits)
for(var/t in mind_traits)
ADD_TRAIT(H.mind, t, JOB_TRAIT)
diff --git a/code/modules/jobs/job_types/clown.dm b/code/modules/jobs/job_types/clown.dm
index 58931876949..ebc1343728a 100644
--- a/code/modules/jobs/job_types/clown.dm
+++ b/code/modules/jobs/job_types/clown.dm
@@ -50,6 +50,12 @@
chameleon_extras = /obj/item/stamp/clown
+/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly)
+ . = ..()
+ if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS))
+ backpack_contents[/obj/item/stack/sheet/mineral/bananium/five] = 1
+
+
/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(visualsOnly)
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index 682fbe13307..9853b1ef980 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -437,11 +437,7 @@
if(age == 0)
var/turf/target = get_turf(loc)
if(target)
- var/mob/living/simple_animal/pet/dog/corgi/puppy/P = new /mob/living/simple_animal/pet/dog/corgi/puppy(target)
- P.name = "Ian"
- P.real_name = "Ian"
- P.gender = MALE
- P.desc = "It's the HoP's beloved corgi puppy."
+ new /mob/living/simple_animal/pet/dog/corgi/puppy/ian(target)
Write_Memory(FALSE)
return INITIALIZE_HINT_QDEL
else if(age == record_age)
@@ -608,6 +604,13 @@
return
..()
+//PUPPY IAN! SQUEEEEEEEEE~
+/mob/living/simple_animal/pet/dog/corgi/puppy/ian
+ name = "Ian"
+ real_name = "Ian"
+ gender = MALE
+ desc = "It's the HoP's beloved corgi puppy."
+
/mob/living/simple_animal/pet/dog/corgi/puppy/void //Tribute to the corgis born in nullspace
name = "\improper void puppy"
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index ac41afb8ef6..f4f2f9b15a3 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -106,7 +106,7 @@
/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
. = ..()
- migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/runtime/hyperspace/hyperspace_begin.ogg', 'sound/runtime/hyperspace/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desecration-01.ogg', 'sound/misc/desecration-02.ogg', 'sound/misc/desecration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gun/pistol/shot_suppressed.ogg', 'sound/weapons/gun/pistol/shot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
+ migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/runtime/hyperspace/hyperspace_begin.ogg', 'sound/runtime/hyperspace/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desecration-01.ogg', 'sound/misc/desecration-02.ogg', 'sound/misc/desecration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gun/pistol/shot_suppressed.ogg', 'sound/weapons/gun/pistol/shot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/default/outbreak5.ogg', 'sound/ai/default/outbreak7.ogg', 'sound/ai/default/poweroff.ogg', 'sound/ai/default/radiation.ogg', 'sound/ai/default/shuttlecalled.ogg', 'sound/ai/default/shuttledock.ogg', 'sound/ai/default/shuttlerecalled.ogg', 'sound/ai/default/aimalf.ogg') //hahahaha fuck you code divers
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
index d5f60812798..af22c291290 100644
--- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
+++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm
@@ -627,7 +627,7 @@
if(charge_state < CHARGE_FINALWARNING && time_charged >= (max_charge * 0.5))
charge_state = CHARGE_FINALWARNING
var/area/A = get_area(src)
- priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Spatial Corps", 'sound/ai/spanomalies.ogg')
+ priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Spatial Corps", ANNOUNCER_SPANOMALIES)
/**
* Used to create carp controlled by ghosts when the option is available.
diff --git a/code/modules/modular_computers/file_system/programs/budgetordering.dm b/code/modules/modular_computers/file_system/programs/budgetordering.dm
index 0c7dc9c394e..b42c6812938 100644
--- a/code/modules/modular_computers/file_system/programs/budgetordering.dm
+++ b/code/modules/modular_computers/file_system/programs/budgetordering.dm
@@ -90,7 +90,7 @@
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
- "cost" = P.cost,
+ "cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,
@@ -117,7 +117,7 @@
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
- "cost" = SO.pack.cost,
+ "cost" = SO.pack.get_cost(),
"id" = SO.id,
"orderer" = SO.orderer,
"paid" = !isnull(SO.paying_account) //paid by requester
@@ -127,7 +127,7 @@
for(var/datum/supply_order/SO in SSshuttle.requestlist)
data["requests"] += list(list(
"object" = SO.pack.name,
- "cost" = SO.pack.cost,
+ "cost" = SO.pack.get_cost(),
"orderer" = SO.orderer,
"reason" = SO.reason,
"id" = SO.id
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 076dc2aa892..6f238938161 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -347,7 +347,7 @@
//priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, 'sound/ai/shuttlecalled.ogg', "Priority") //ORIGINAL
//SKYRAT EDIT CHANGE BEGIN - AUTOTRANSFER
if(!silent)
- priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, 'sound/ai/shuttlecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, ANNOUNCER_SHUTTLECALLED, "Priority")
//SKYRAT EDIT CHANGE END - AUTOTRANSFER
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
@@ -363,7 +363,7 @@
SSshuttle.emergencyLastCallLoc = signalOrigin
else
SSshuttle.emergencyLastCallLoc = null
- priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlerecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, ANNOUNCER_SHUTTLERECALLED, "Priority")
SSticker.emergency_reason = null
@@ -452,7 +452,7 @@
mode = SHUTTLE_DOCKED
setTimer(SSshuttle.emergencyDockTime)
send2adminchat("Server", "The Emergency Shuttle has docked with the station.")
- priority_announce("[SSshuttle.emergency] has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/ai/shuttledock.ogg', "Priority")
+ priority_announce("[SSshuttle.emergency] has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, ANNOUNCER_SHUTTLEDOCK, "Priority")
ShuttleDBStuff()
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 94e8fdfc8bb..ca05d972e73 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -110,7 +110,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
if(!empty_turfs.len)
break
- var/price = SO.pack.cost
+ var/price = SO.pack.get_cost()
if(SO.applied_coupon)
price *= (1 - SO.applied_coupon.discount_pct_off)
@@ -138,8 +138,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
LAZYADD(goodies_by_buyer[SO.paying_account], SO)
D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.")
var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR)
- cargo.adjust_money(price - SO.pack.cost) //Cargo gets the handling fee
- value += SO.pack.cost
+ cargo.adjust_money(price - SO.pack.get_cost()) //Cargo gets the handling fee
+ value += SO.pack.get_cost()
SSshuttle.shoppinglist -= SO
SSshuttle.orderhistory += SO
QDEL_NULL(SO.applied_coupon)
@@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
if(!SO.pack.goody) //we handle goody crates below
SO.generate(pick_n_take(empty_turfs))
- SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
+ SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.get_cost()]", "[SO.pack.name]"))
investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO)
if(SO.pack.dangerous)
message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.")
diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm
index 88377455c6a..856bf08ff3c 100644
--- a/code/modules/station_goals/station_goal.dm
+++ b/code/modules/station_goals/station_goal.dm
@@ -12,7 +12,7 @@
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
- priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/ai/commandreport.ogg')
+ priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", SSstation.announcer.get_rand_report_sound())
print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE)
on_report()
diff --git a/modular_skyrat/modules/autotransfer/code/shuttle.dm b/modular_skyrat/modules/autotransfer/code/shuttle.dm
index 0cb7525b006..668a58193d3 100644
--- a/modular_skyrat/modules/autotransfer/code/shuttle.dm
+++ b/modular_skyrat/modules/autotransfer/code/shuttle.dm
@@ -4,7 +4,7 @@
/datum/controller/subsystem/shuttle/proc/autoEnd()
if(EMERGENCY_IDLE_OR_RECALLED)
SSshuttle.emergency.request(silent = TRUE)
- priority_announce("The shift has come to an end and the shuttle called. [GLOB.security_level == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority")
+ priority_announce("The shift has come to an end and the shuttle called. [GLOB.security_level == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, ANNOUNCER_SHUTTLECALLED, "Priority")
log_game("Round end vote passed. Shuttle has been auto-called.")
message_admins("Round end vote passed. Shuttle has been auto-called.")
emergencyNoRecall = TRUE
diff --git a/sound/ai/aimalf.ogg b/sound/ai/default/aimalf.ogg
similarity index 100%
rename from sound/ai/aimalf.ogg
rename to sound/ai/default/aimalf.ogg
diff --git a/sound/ai/aliens.ogg b/sound/ai/default/aliens.ogg
similarity index 100%
rename from sound/ai/aliens.ogg
rename to sound/ai/default/aliens.ogg
diff --git a/sound/ai/animes.ogg b/sound/ai/default/animes.ogg
similarity index 100%
rename from sound/ai/animes.ogg
rename to sound/ai/default/animes.ogg
diff --git a/sound/ai/attention.ogg b/sound/ai/default/attention.ogg
similarity index 100%
rename from sound/ai/attention.ogg
rename to sound/ai/default/attention.ogg
diff --git a/sound/ai/commandreport.ogg b/sound/ai/default/commandreport.ogg
similarity index 100%
rename from sound/ai/commandreport.ogg
rename to sound/ai/default/commandreport.ogg
diff --git a/sound/ai/granomalies.ogg b/sound/ai/default/granomalies.ogg
similarity index 100%
rename from sound/ai/granomalies.ogg
rename to sound/ai/default/granomalies.ogg
diff --git a/sound/ai/intercept.ogg b/sound/ai/default/intercept.ogg
similarity index 100%
rename from sound/ai/intercept.ogg
rename to sound/ai/default/intercept.ogg
diff --git a/sound/ai/ionstorm.ogg b/sound/ai/default/ionstorm.ogg
similarity index 100%
rename from sound/ai/ionstorm.ogg
rename to sound/ai/default/ionstorm.ogg
diff --git a/sound/ai/meteors.ogg b/sound/ai/default/meteors.ogg
similarity index 100%
rename from sound/ai/meteors.ogg
rename to sound/ai/default/meteors.ogg
diff --git a/sound/ai/outbreak5.ogg b/sound/ai/default/outbreak5.ogg
similarity index 100%
rename from sound/ai/outbreak5.ogg
rename to sound/ai/default/outbreak5.ogg
diff --git a/sound/ai/outbreak7.ogg b/sound/ai/default/outbreak7.ogg
similarity index 100%
rename from sound/ai/outbreak7.ogg
rename to sound/ai/default/outbreak7.ogg
diff --git a/sound/ai/poweroff.ogg b/sound/ai/default/poweroff.ogg
similarity index 100%
rename from sound/ai/poweroff.ogg
rename to sound/ai/default/poweroff.ogg
diff --git a/sound/ai/poweron.ogg b/sound/ai/default/poweron.ogg
similarity index 100%
rename from sound/ai/poweron.ogg
rename to sound/ai/default/poweron.ogg
diff --git a/sound/ai/radiation.ogg b/sound/ai/default/radiation.ogg
similarity index 100%
rename from sound/ai/radiation.ogg
rename to sound/ai/default/radiation.ogg
diff --git a/sound/ai/shuttlecalled.ogg b/sound/ai/default/shuttlecalled.ogg
similarity index 100%
rename from sound/ai/shuttlecalled.ogg
rename to sound/ai/default/shuttlecalled.ogg
diff --git a/sound/ai/shuttledock.ogg b/sound/ai/default/shuttledock.ogg
similarity index 100%
rename from sound/ai/shuttledock.ogg
rename to sound/ai/default/shuttledock.ogg
diff --git a/sound/ai/shuttlerecalled.ogg b/sound/ai/default/shuttlerecalled.ogg
similarity index 100%
rename from sound/ai/shuttlerecalled.ogg
rename to sound/ai/default/shuttlerecalled.ogg
diff --git a/sound/ai/spanomalies.ogg b/sound/ai/default/spanomalies.ogg
similarity index 100%
rename from sound/ai/spanomalies.ogg
rename to sound/ai/default/spanomalies.ogg
diff --git a/sound/ai/welcome.ogg b/sound/ai/default/welcome.ogg
similarity index 100%
rename from sound/ai/welcome.ogg
rename to sound/ai/default/welcome.ogg
diff --git a/sound/ai/intern/aimalf.ogg b/sound/ai/intern/aimalf.ogg
new file mode 100644
index 00000000000..b7996916b47
Binary files /dev/null and b/sound/ai/intern/aimalf.ogg differ
diff --git a/sound/ai/intern/alerts/1.ogg b/sound/ai/intern/alerts/1.ogg
new file mode 100644
index 00000000000..c4d182bc8c9
Binary files /dev/null and b/sound/ai/intern/alerts/1.ogg differ
diff --git a/sound/ai/intern/alerts/10.ogg b/sound/ai/intern/alerts/10.ogg
new file mode 100644
index 00000000000..7380ccdeefd
Binary files /dev/null and b/sound/ai/intern/alerts/10.ogg differ
diff --git a/sound/ai/intern/alerts/11.ogg b/sound/ai/intern/alerts/11.ogg
new file mode 100644
index 00000000000..ca548dcc20a
Binary files /dev/null and b/sound/ai/intern/alerts/11.ogg differ
diff --git a/sound/ai/intern/alerts/12.ogg b/sound/ai/intern/alerts/12.ogg
new file mode 100644
index 00000000000..8d71419798f
Binary files /dev/null and b/sound/ai/intern/alerts/12.ogg differ
diff --git a/sound/ai/intern/alerts/13.ogg b/sound/ai/intern/alerts/13.ogg
new file mode 100644
index 00000000000..128c7aa424d
Binary files /dev/null and b/sound/ai/intern/alerts/13.ogg differ
diff --git a/sound/ai/intern/alerts/14.ogg b/sound/ai/intern/alerts/14.ogg
new file mode 100644
index 00000000000..81d54101be5
Binary files /dev/null and b/sound/ai/intern/alerts/14.ogg differ
diff --git a/sound/ai/intern/alerts/2.ogg b/sound/ai/intern/alerts/2.ogg
new file mode 100644
index 00000000000..a2ef615d56c
Binary files /dev/null and b/sound/ai/intern/alerts/2.ogg differ
diff --git a/sound/ai/intern/alerts/3.ogg b/sound/ai/intern/alerts/3.ogg
new file mode 100644
index 00000000000..51613ff0367
Binary files /dev/null and b/sound/ai/intern/alerts/3.ogg differ
diff --git a/sound/ai/intern/alerts/4.ogg b/sound/ai/intern/alerts/4.ogg
new file mode 100644
index 00000000000..874536ca72f
Binary files /dev/null and b/sound/ai/intern/alerts/4.ogg differ
diff --git a/sound/ai/intern/alerts/5.ogg b/sound/ai/intern/alerts/5.ogg
new file mode 100644
index 00000000000..0af0d28ce18
Binary files /dev/null and b/sound/ai/intern/alerts/5.ogg differ
diff --git a/sound/ai/intern/alerts/6.ogg b/sound/ai/intern/alerts/6.ogg
new file mode 100644
index 00000000000..a65006a8c01
Binary files /dev/null and b/sound/ai/intern/alerts/6.ogg differ
diff --git a/sound/ai/intern/alerts/7.ogg b/sound/ai/intern/alerts/7.ogg
new file mode 100644
index 00000000000..4a1d3f013ae
Binary files /dev/null and b/sound/ai/intern/alerts/7.ogg differ
diff --git a/sound/ai/intern/alerts/8.ogg b/sound/ai/intern/alerts/8.ogg
new file mode 100644
index 00000000000..83ca80f4939
Binary files /dev/null and b/sound/ai/intern/alerts/8.ogg differ
diff --git a/sound/ai/intern/alerts/9.ogg b/sound/ai/intern/alerts/9.ogg
new file mode 100644
index 00000000000..3c0c45b25d0
Binary files /dev/null and b/sound/ai/intern/alerts/9.ogg differ
diff --git a/sound/ai/intern/aliens.ogg b/sound/ai/intern/aliens.ogg
new file mode 100644
index 00000000000..9dd3c076978
Binary files /dev/null and b/sound/ai/intern/aliens.ogg differ
diff --git a/sound/ai/intern/animes.ogg b/sound/ai/intern/animes.ogg
new file mode 100644
index 00000000000..36102c3e60e
Binary files /dev/null and b/sound/ai/intern/animes.ogg differ
diff --git a/sound/ai/intern/commandreport/1.ogg b/sound/ai/intern/commandreport/1.ogg
new file mode 100644
index 00000000000..e3108b13d17
Binary files /dev/null and b/sound/ai/intern/commandreport/1.ogg differ
diff --git a/sound/ai/intern/commandreport/2.ogg b/sound/ai/intern/commandreport/2.ogg
new file mode 100644
index 00000000000..cd67500426c
Binary files /dev/null and b/sound/ai/intern/commandreport/2.ogg differ
diff --git a/sound/ai/intern/commandreport/3.ogg b/sound/ai/intern/commandreport/3.ogg
new file mode 100644
index 00000000000..94241c5ba52
Binary files /dev/null and b/sound/ai/intern/commandreport/3.ogg differ
diff --git a/sound/ai/intern/granomalies.ogg b/sound/ai/intern/granomalies.ogg
new file mode 100644
index 00000000000..88944b63b2e
Binary files /dev/null and b/sound/ai/intern/granomalies.ogg differ
diff --git a/sound/ai/intern/harmalarm.ogg b/sound/ai/intern/harmalarm.ogg
new file mode 100644
index 00000000000..b9107f6e44d
Binary files /dev/null and b/sound/ai/intern/harmalarm.ogg differ
diff --git a/sound/ai/intern/intercept.ogg b/sound/ai/intern/intercept.ogg
new file mode 100644
index 00000000000..a87274abd97
Binary files /dev/null and b/sound/ai/intern/intercept.ogg differ
diff --git a/sound/ai/intern/ionstorm.ogg b/sound/ai/intern/ionstorm.ogg
new file mode 100644
index 00000000000..9e7b5c6b23e
Binary files /dev/null and b/sound/ai/intern/ionstorm.ogg differ
diff --git a/sound/ai/intern/meteors.ogg b/sound/ai/intern/meteors.ogg
new file mode 100644
index 00000000000..c68c4bd8cc4
Binary files /dev/null and b/sound/ai/intern/meteors.ogg differ
diff --git a/sound/ai/intern/outbreak5.ogg b/sound/ai/intern/outbreak5.ogg
new file mode 100644
index 00000000000..cf98b95fd7b
Binary files /dev/null and b/sound/ai/intern/outbreak5.ogg differ
diff --git a/sound/ai/intern/outbreak7.ogg b/sound/ai/intern/outbreak7.ogg
new file mode 100644
index 00000000000..297a1bbe8db
Binary files /dev/null and b/sound/ai/intern/outbreak7.ogg differ
diff --git a/sound/ai/intern/poweroff.ogg b/sound/ai/intern/poweroff.ogg
new file mode 100644
index 00000000000..4b71053653f
Binary files /dev/null and b/sound/ai/intern/poweroff.ogg differ
diff --git a/sound/ai/intern/poweron.ogg b/sound/ai/intern/poweron.ogg
new file mode 100644
index 00000000000..509cd398e6e
Binary files /dev/null and b/sound/ai/intern/poweron.ogg differ
diff --git a/sound/ai/intern/radiation.ogg b/sound/ai/intern/radiation.ogg
new file mode 100644
index 00000000000..08db53ebfd2
Binary files /dev/null and b/sound/ai/intern/radiation.ogg differ
diff --git a/sound/ai/intern/shuttlecalled.ogg b/sound/ai/intern/shuttlecalled.ogg
new file mode 100644
index 00000000000..c903367cdff
Binary files /dev/null and b/sound/ai/intern/shuttlecalled.ogg differ
diff --git a/sound/ai/intern/shuttledock.ogg b/sound/ai/intern/shuttledock.ogg
new file mode 100644
index 00000000000..9f6ccd1a937
Binary files /dev/null and b/sound/ai/intern/shuttledock.ogg differ
diff --git a/sound/ai/intern/shuttlerecalled.ogg b/sound/ai/intern/shuttlerecalled.ogg
new file mode 100644
index 00000000000..e259a79f35e
Binary files /dev/null and b/sound/ai/intern/shuttlerecalled.ogg differ
diff --git a/sound/ai/intern/spanomalies.ogg b/sound/ai/intern/spanomalies.ogg
new file mode 100644
index 00000000000..9bed8eae3aa
Binary files /dev/null and b/sound/ai/intern/spanomalies.ogg differ
diff --git a/sound/ai/intern/welcome/1.ogg b/sound/ai/intern/welcome/1.ogg
new file mode 100644
index 00000000000..758f1967e09
Binary files /dev/null and b/sound/ai/intern/welcome/1.ogg differ
diff --git a/sound/ai/intern/welcome/2.ogg b/sound/ai/intern/welcome/2.ogg
new file mode 100644
index 00000000000..c2e72be510e
Binary files /dev/null and b/sound/ai/intern/welcome/2.ogg differ
diff --git a/sound/ai/intern/welcome/3.ogg b/sound/ai/intern/welcome/3.ogg
new file mode 100644
index 00000000000..004f57371de
Binary files /dev/null and b/sound/ai/intern/welcome/3.ogg differ
diff --git a/sound/ai/intern/welcome/4.ogg b/sound/ai/intern/welcome/4.ogg
new file mode 100644
index 00000000000..c4e1f7667cd
Binary files /dev/null and b/sound/ai/intern/welcome/4.ogg differ
diff --git a/sound/ai/intern/welcome/5.ogg b/sound/ai/intern/welcome/5.ogg
new file mode 100644
index 00000000000..641b8208a4e
Binary files /dev/null and b/sound/ai/intern/welcome/5.ogg differ
diff --git a/sound/ai/intern/welcome/6.ogg b/sound/ai/intern/welcome/6.ogg
new file mode 100644
index 00000000000..b0fc38237f8
Binary files /dev/null and b/sound/ai/intern/welcome/6.ogg differ
diff --git a/sound/machines/twobeep_voice1.ogg b/sound/machines/twobeep_voice1.ogg
new file mode 100644
index 00000000000..1dcaebf7f90
Binary files /dev/null and b/sound/machines/twobeep_voice1.ogg differ
diff --git a/sound/machines/twobeep_voice2.ogg b/sound/machines/twobeep_voice2.ogg
new file mode 100644
index 00000000000..e8a6c3be58c
Binary files /dev/null and b/sound/machines/twobeep_voice2.ogg differ
diff --git a/tgstation.dme b/tgstation.dme
index 3a879421b7d..cb55a818214 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -118,6 +118,7 @@
#include "code\__DEFINES\spaceman_dmm.dm"
#include "code\__DEFINES\stat.dm"
#include "code\__DEFINES\stat_tracking.dm"
+#include "code\__DEFINES\station.dm"
#include "code\__DEFINES\statpanel.dm"
#include "code\__DEFINES\status_effects.dm"
#include "code\__DEFINES\storage.dm"
@@ -371,6 +372,7 @@
#include "code\controllers\subsystem\processing\processing.dm"
#include "code\controllers\subsystem\processing\projectiles.dm"
#include "code\controllers\subsystem\processing\quirks.dm"
+#include "code\controllers\subsystem\processing\station.dm"
#include "code\controllers\subsystem\processing\wet_floors.dm"
#include "code\datums\action.dm"
#include "code\datums\ai_laws.dm"
@@ -433,6 +435,9 @@
#include "code\datums\ai\monkey\monkey_controller.dm"
#include "code\datums\ai\objects\vending_machines\vending_machine_behaviors.dm"
#include "code\datums\ai\objects\vending_machines\vending_machine_controller.dm"
+#include "code\datums\announcers\_announcer.dm"
+#include "code\datums\announcers\default_announcer.dm"
+#include "code\datums\announcers\intern_announcer.dm"
#include "code\datums\atmosphere\_atmosphere.dm"
#include "code\datums\atmosphere\planetary.dm"
#include "code\datums\brain_damage\brain_trauma.dm"
@@ -736,6 +741,10 @@
#include "code\datums\skills\cleaning.dm"
#include "code\datums\skills\gaming.dm"
#include "code\datums\skills\mining.dm"
+#include "code\datums\station_traits\_station_trait.dm"
+#include "code\datums\station_traits\negative_traits.dm"
+#include "code\datums\station_traits\neutral_traits.dm"
+#include "code\datums\station_traits\positive_traits.dm"
#include "code\datums\status_effects\buffs.dm"
#include "code\datums\status_effects\debuffs.dm"
#include "code\datums\status_effects\gas.dm"