diff --git a/code/__DEFINES/components.dm b/code/__DEFINES/components.dm
index 9d9fa209adfb..18a39d9b7ff8 100644
--- a/code/__DEFINES/components.dm
+++ b/code/__DEFINES/components.dm
@@ -383,3 +383,10 @@
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
+
+/// job subsystem has spawned and equipped a new mob
+#define COMSIG_GLOB_JOB_AFTER_SPAWN "!job_after_spawn"
+
+///Subsystem signals
+///From base of datum/controller/subsystem/Initialize: (start_timeofday)
+#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"
diff --git a/code/__DEFINES/sound.dm b/code/__DEFINES/sound.dm
index 0c43b208b2da..0a10f8c3a6d1 100644
--- a/code/__DEFINES/sound.dm
+++ b/code/__DEFINES/sound.dm
@@ -75,3 +75,21 @@
'sound/hallucinations/growl3.ogg', 'sound/hallucinations/im_here1.ogg', 'sound/hallucinations/im_here2.ogg', 'sound/hallucinations/i_see_you1.ogg', 'sound/hallucinations/i_see_you2.ogg',\
'sound/hallucinations/look_up1.ogg', 'sound/hallucinations/look_up2.ogg', 'sound/hallucinations/over_here1.ogg', 'sound/hallucinations/over_here2.ogg', 'sound/hallucinations/over_here3.ogg',\
'sound/hallucinations/turn_around1.ogg', 'sound/hallucinations/turn_around2.ogg', 'sound/hallucinations/veryfar_noise.ogg', 'sound/hallucinations/wail.ogg')
+
+///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_intercept"
+#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 000000000000..56cb4f69c6cf
--- /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
\ No newline at end of file
diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm
index 6057bd7b7d04..f774dcb0acc5 100644
--- a/code/__DEFINES/subsystems.dm
+++ b/code/__DEFINES/subsystems.dm
@@ -110,6 +110,7 @@
#define INIT_ORDER_VIS 80
#define INIT_ORDER_MATERIALS 76
#define INIT_ORDER_RESEARCH 75
+#define INIT_ORDER_STATION 74
#define INIT_ORDER_EVENTS 70
#define INIT_ORDER_MAPPING 65
#define INIT_ORDER_JOBS 60
diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm
index 35b7397610e1..e4b1b8096377 100644
--- a/code/__DEFINES/traits.dm
+++ b/code/__DEFINES/traits.dm
@@ -210,6 +210,7 @@
#define CLOTHING_TRAIT "clothing"
#define VEHICLE_TRAIT "vehicle" // inherited from riding vehicles
#define INNATE_TRAIT "innate"
+#define STATION_TRAIT "station-trait"
// unique trait sources, still defines
#define CLONING_POD_TRAIT "cloning-pod"
@@ -252,3 +253,12 @@
#define GUARDIAN_TRAIT "guardian_trait"
#define RANDOM_BLACKOUTS "random_blackouts"
#define MADE_UNCLONEABLE "made-uncloneable"
+
+///Traits given by station traits
+#define STATION_TRAIT_BANANIUM_SHIPMENTS "station_trait_bananium_shipments"
+#define STATION_TRAIT_CARP_INFESTATION "station_trait_carp_infestation"
+#define STATION_TRAIT_PREMIUM_INTERNALS "station_trait_premium_internals"
+#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 cf49bda1f1b0..6194f481333c 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)
@@ -46,7 +52,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 dc65690ce75f..895f1dd14714 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1115,6 +1115,27 @@ B --><-- A
/proc/get_random_station_turf()
return safepick(get_area_turfs(pick(GLOB.the_station_areas)))
+/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(areas_to_pick_from))
+ var/turf/target
+ while (L.len && !target)
+ var/I = rand(1, L.len)
+ var/turf/T = L[I]
+ var/area/X = get_area(T)
+ if(!T.density && X.valid_territory)
+ var/clear = TRUE
+ for(var/obj/O in T)
+ if(O.density)
+ clear = FALSE
+ break
+ if(clear)
+ target = T
+ if (!target)
+ L.Cut(I,I+1)
+ if (target)
+ return target
+
/proc/get_closest_atom(type, list, source)
var/closest_atom
var/closest_distance
diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm
index e736e3a0ed38..1e6f1a57383f 100644
--- a/code/_globalvars/lists/mapping.dm
+++ b/code/_globalvars/lists/mapping.dm
@@ -40,6 +40,7 @@ GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here
GLOBAL_LIST_EMPTY(servant_spawns_scarabs) //Servants of Ratvar spawn here
GLOBAL_LIST_EMPTY(city_of_cogs_spawns) //Anyone entering the City of Cogs spawns here
GLOBAL_LIST_EMPTY(ruin_landmarks)
+GLOBAL_LIST_EMPTY(bar_areas)
//away missions
GLOBAL_LIST_EMPTY(awaydestinations) //a list of landmarks that the warpgate can take you to
diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm
index 20e4c5386f0c..cbeb56cb4c58 100644
--- a/code/controllers/subsystem.dm
+++ b/code/controllers/subsystem.dm
@@ -162,6 +162,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 718357b8bb9c..894e8844db5c 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 8e25e929158e..73e67865de3a 100644
--- a/code/controllers/subsystem/economy.dm
+++ b/code/controllers/subsystem/economy.dm
@@ -50,6 +50,10 @@ SUBSYSTEM_DEF(economy)
var/list/dep_cards = list()
///ref to moneysink. Only one should exist on the map. Has its payout() proc called every budget cycle
var/obj/item/energy_harvester/moneysink = null
+ ///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
/datum/controller/subsystem/economy/Initialize(timeofday)
var/budget_to_hand_out = round(budget_pool / department_accounts.len)
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 82599d1c94d8..027153866c45 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -441,21 +441,26 @@ 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
- for(var/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list)
- if(sloc.name != rank)
- S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
- continue
- if(locate(/mob/living) in sloc.loc)
- continue
- S = sloc
- sloc.used = TRUE
- break
- if(length(GLOB.jobspawn_overrides[rank]))
+ 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/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list)
+ if(sloc.name != rank)
+ S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
+ continue
+ if(locate(/mob/living) in sloc.loc)
+ continue
+ S = sloc
+ sloc.used = TRUE
+ 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]")
SendToLateJoin(living_mob)
@@ -679,6 +684,14 @@ 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/DPtarget(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 000000000000..44a5f312e885
--- /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 6582312479be..b913c7322268 100644
--- a/code/controllers/subsystem/shuttle.dm
+++ b/code/controllers/subsystem/shuttle.dm
@@ -394,7 +394,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 264a8fffb4b9..02de620e7a7b 100755
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -293,7 +293,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
webhook_send_roundstatus("ingame") //yogs - webhook support
diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm
index 9a098a17c56e..801ba80767d6 100644
--- a/code/datums/ai_laws.dm
+++ b/code/datums/ai_laws.dm
@@ -248,6 +248,7 @@
/datum/ai_laws/proc/set_laws_config()
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
+
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 000000000000..4ddf68558110
--- /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)
\ No newline at end of file
diff --git a/code/datums/announcers/default_announcer.dm b/code/datums/announcers/default_announcer.dm
new file mode 100644
index 000000000000..35174457622f
--- /dev/null
+++ b/code/datums/announcers/default_announcer.dm
@@ -0,0 +1,20 @@
+/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_METEORS = 'sound/ai/default/meteors.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')
\ No newline at end of file
diff --git a/code/datums/announcers/intern_announcer.dm b/code/datums/announcers/intern_announcer.dm
new file mode 100644
index 000000000000..11d016eeddb0
--- /dev/null
+++ b/code/datums/announcers/intern_announcer.dm
@@ -0,0 +1,44 @@
+/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/default/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_METEORS = 'sound/ai/intern/meteors.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')
diff --git a/code/datums/announcers/medbot_announcer.dm b/code/datums/announcers/medbot_announcer.dm
new file mode 100644
index 000000000000..11cd12db16dd
--- /dev/null
+++ b/code/datums/announcers/medbot_announcer.dm
@@ -0,0 +1,20 @@
+/datum/centcom_announcer/medbot
+ welcome_sounds = list('sound/ai/medbot/welcome.ogg')
+ alert_sounds = list('sound/ai/medbot/attention.ogg')
+ command_report_sounds = list('sound/ai/medbot/commandreport.ogg')
+ event_sounds = list(ANNOUNCER_AIMALF = 'sound/ai/default/aimalf.ogg',
+ ANNOUNCER_ALIENS = 'sound/ai/medbot/aliens.ogg',
+ ANNOUNCER_ANIMES = 'sound/ai/medbot/animes.ogg',
+ ANNOUNCER_GRANOMALIES = 'sound/ai/medbot/granomalies.ogg',
+ ANNOUNCER_INTERCEPT = 'sound/ai/medbot/intercept.ogg',
+ ANNOUNCER_IONSTORM = 'sound/ai/medbot/ionstorm.ogg',
+ ANNOUNCER_METEORS = 'sound/ai/medbot/meteors.ogg',
+ ANNOUNCER_OUTBREAK5 = 'sound/ai/medbot/outbreak5.ogg',
+ ANNOUNCER_OUTBREAK7 = 'sound/ai/medbot/outbreak7.ogg',
+ ANNOUNCER_POWEROFF = 'sound/ai/medbot/poweroff.ogg',
+ ANNOUNCER_POWERON = 'sound/ai/medbot/poweron.ogg',
+ ANNOUNCER_RADIATION = 'sound/ai/medbot/radiation.ogg',
+ ANNOUNCER_SHUTTLECALLED = 'sound/ai/medbot/shuttlecalled.ogg',
+ ANNOUNCER_SHUTTLEDOCK = 'sound/ai/medbot/shuttledock.ogg',
+ ANNOUNCER_SHUTTLERECALLED = 'sound/ai/medbot/shuttlerecalled.ogg',
+ ANNOUNCER_SPANOMALIES = 'sound/ai/medbot/spanomalies.ogg')
diff --git a/code/datums/helper_datums/teleport.dm b/code/datums/helper_datums/teleport.dm
index 160f40e46689..79c2fd65eef0 100644
--- a/code/datums/helper_datums/teleport.dm
+++ b/code/datums/helper_datums/teleport.dm
@@ -120,7 +120,7 @@
* * zlevels - list of z-levels to check for a safe turf
* * extended_safety_checks - check for lava
*/
-/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)
@@ -172,6 +172,16 @@
var/turf/open/lava/L = F
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 000000000000..87fbe76a32c1
--- /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]"
\ No newline at end of file
diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm
new file mode 100644
index 000000000000..5a986dab07ae
--- /dev/null
+++ b/code/datums/station_traits/negative_traits.dm
@@ -0,0 +1,102 @@
+/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/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
+
+/datum/station_trait/blackout
+ name = "Blackout"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 3
+ 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)
+ SSjob.set_overflow_role(chosen_job)
+
+/datum/station_trait/slow_shuttle
+ name = "Slow Shuttle"
+ trait_type = STATION_TRAIT_NEGATIVE
+ 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
+
+/datum/station_trait/bot_languages
+ name = "Bot Language Matrix Malfunction"
+ trait_type = STATION_TRAIT_NEGATIVE
+ weight = 3
+ show_in_report = TRUE
+ report_message = "Your station's friendly bots have had their language matrix fried due to an event, resulting in some strange and unfamiliar speech patterns."
+
+/datum/station_trait/bot_languages/New()
+ . = ..()
+ /// What "caused" our robots to go haywire (fluff)
+ var/event_source = pick(list("an ion storm", "a syndicate hacking attempt", "a malfunction", "issues with your onboard AI", "an intern's mistakes", "budget cuts"))
+ report_message = "Your station's friendly bots have had their language matrix fried due to [event_source], resulting in some strange and unfamiliar speech patterns."
+
+/datum/station_trait/bot_languages/on_round_start()
+ . = ..()
+ //All bots that exist round start have their set language randomized.
+ for(var/mob/living/simple_animal/bot/found_bot in GLOB.alive_mob_list)
+ /// The bot's language holder - so we can randomize and change their language
+ var/datum/language_holder/bot_languages = found_bot.get_language_holder()
+ bot_languages.selected_language = bot_languages.get_random_spoken_language()
diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm
new file mode 100644
index 000000000000..a134a5e55910
--- /dev/null
+++ b/code/datums/station_traits/neutral_traits.dm
@@ -0,0 +1,61 @@
+/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/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 = 15
+ show_in_report = TRUE
+ report_message = "Something seems to be wrong with the PDAs issued 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 = 1
+ show_in_report = TRUE
+ report_message = "Please be nice to him."
+ blacklist = list(/datum/station_trait/announcement_medbot)
+
+/datum/station_trait/announcement_intern/New()
+ . = ..()
+ SSstation.announcer = /datum/centcom_announcer/intern
+
+/datum/station_trait/announcement_medbot
+ name = "Announcement \"System\""
+ trait_type = STATION_TRAIT_NEUTRAL
+ weight = 1
+ show_in_report = TRUE
+ report_message = "Our announcement system is under scheduled maintenance at the moment. Thankfully, we have a backup."
+ blacklist = list(/datum/station_trait/announcement_intern)
+
+/datum/station_trait/announcement_medbot/New()
+ . = ..()
+ SSstation.announcer = /datum/centcom_announcer/medbot
diff --git a/code/datums/station_traits/positive_traits.dm b/code/datums/station_traits/positive_traits.dm
new file mode 100644
index 000000000000..a49e5a6f5c0d
--- /dev/null
+++ b/code/datums/station_traits/positive_traits.dm
@@ -0,0 +1,124 @@
+#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/DPtarget(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 providing 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)
+ var/scarf_type = pick(scarves)
+
+ living_mob.equip_to_slot_or_del(new scarf_type(living_mob), ITEM_SLOT_NECK)
+
+/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 60473e242ddf..07cc78a54a7b 100644
--- a/code/game/area/Space_Station_13_areas.dm
+++ b/code/game/area/Space_Station_13_areas.dm
@@ -447,6 +447,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
mood_message = "I love being in the bar!\n"
airlock_wires = /datum/wires/airlock/service
+/area/crew_quarters/bar/Initialize(mapload)
+ . = ..()
+ GLOB.bar_areas += src
+
/area/crew_quarters/bar/atrium
name = "Atrium"
icon_state = "bar"
diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm
index 528722d28220..205d73f1aed0 100644
--- a/code/game/gamemodes/dynamic/dynamic.dm
+++ b/code/game/gamemodes/dynamic/dynamic.dm
@@ -262,14 +262,13 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
. += "[title]
"
. += desc
- if(station_goals.len)
- . += "
Special Orders for [station_name()]:"
- for(var/datum/station_goal/G in station_goals)
- G.on_report()
- . += G.get_report()
+ . += generate_station_goal_report()
+ . += generate_station_trait_report()
+
+ desc += "\n\n[generate_station_trait_announcement()]"
print_command_report(., "Central Command Status Summary", announce=FALSE)
- priority_announce(desc, title, 'sound/ai/intercept.ogg')
+ priority_announce(desc, title, ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
@@ -834,7 +833,7 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
return RULE_OF_THREE(40, 20, x) + 50
if (20 to INFINITY)
return rand(90, 100)
-
+
/datum/game_mode/dynamic/proc/configure_ruleset(datum/dynamic_ruleset/ruleset)
if(configuration)
if(!configuration[ruleset.ruletype])
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
index 8d80fff93fea..7f13b1cc6296 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_latejoin.dm
@@ -147,7 +147,7 @@
var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
R.remove_revolutionary(FALSE, "gamemode")
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")
return RULESET_STOP_PROCESSING
diff --git a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
index 9bff678b47d9..19c9c9d2f671 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_midround.dm
@@ -259,7 +259,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/dynamic/dynamic_rulesets_roundstart.dm b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
index 007b89551e72..cebcc6d256d4 100644
--- a/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
+++ b/code/game/gamemodes/dynamic/dynamic_rulesets_roundstart.dm
@@ -439,7 +439,7 @@
var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
R.remove_revolutionary(FALSE, "gamemode")
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")
return RULESET_STOP_PROCESSING
/// Checks for revhead loss conditions and other antag datums.
diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm
index 8a7181aaa3dd..4503462051ec 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_POWERON)
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 29b206724b78..2f5d8009104d 100644
--- a/code/game/gamemodes/extended/extended.dm
+++ b/code/game/gamemodes/extended/extended.dm
@@ -26,5 +26,11 @@
station_goals += G
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')
+/datum/game_mode/extended/announced/send_intercept()
+ var/greenshift_message = "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!\n\n[generate_station_trait_announcement()]"
+ . += "Central Command Status Summary
"
+ . += greenshift_message
+ . += generate_station_trait_report()
+
+ print_command_report(., "Central Command Status Summary", announce = FALSE)
+ priority_announce(greenshift_message, "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 c35e06340963..8752ea1bc443 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -300,17 +300,52 @@
intercepttext += "
"
intercepttext += report
- if(station_goals.len)
- intercepttext += "
Special Orders for [station_name()]:"
- for(var/datum/station_goal/G in station_goals)
- G.on_report()
- intercepttext += G.get_report()
+ intercepttext += generate_station_goal_report()
+ intercepttext += generate_station_trait_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.\n\n[generate_station_trait_announcement()]", "Enemy communication intercepted. Security level elevated.", ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)
-
+
+/*
+ * Generate a list of station goals available to purchase to report to the crew.
+ *
+ * Returns a formatted string all station goals that are available to the station.
+ */
+/datum/game_mode/proc/generate_station_goal_report()
+ if(!station_goals.len)
+ return
+ . = "
Special Orders for [station_name()]:
"
+ for(var/datum/station_goal/station_goal in station_goals)
+ station_goal.on_report()
+ . += station_goal.get_report()
+ return
+
+/*
+ * Generate a list of active station traits to report to the crew.
+ *
+ * Returns a formatted string of all station traits (that are shown) affecting the station.
+ */
+/datum/game_mode/proc/generate_station_trait_report()
+ if(!SSstation.station_traits.len)
+ return
+ . = "
Identified shift divergencies:
"
+ for(var/datum/station_trait/station_trait as anything in SSstation.station_traits)
+ if(!station_trait.show_in_report)
+ continue
+ . += "[station_trait.get_report()]
"
+ return
+
+/datum/game_mode/proc/generate_station_trait_announcement()
+ if(!SSstation.station_traits.len)
+ return
+ . = "Identified shift divergencies:\n"
+ for(var/datum/station_trait/station_trait as anything in SSstation.station_traits)
+ if(!station_trait.show_in_report)
+ continue
+ . += "[station_trait.get_report()]\n"
+ return
// This is a frequency selection system. You may imagine it like a raffle where each player can have some number of tickets. The more tickets you have the more likely you are to
// "win". The default is 100 tickets. If no players use any extra tickets (earned with the antagonist rep system) calling this function should be equivalent to calling the normal
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 8fde898e6379..fbcf30e78554 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -225,7 +225,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 ed1f4264093d..f7a15cdfdebb 100644
--- a/code/game/objects/effects/spawners/lootdrop.dm
+++ b/code/game/objects/effects/spawners/lootdrop.dm
@@ -122,6 +122,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 49c9d6a0392c..d443e011ab82 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -771,7 +771,10 @@ GLOBAL_LIST_EMPTY(PDAs)
tnote += signal
if (!silent)
- playsound(src, 'sound/machines/twobeep_high.ogg', 50, 1)
+ 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/plushes.dm b/code/game/objects/items/plushes.dm
index df6f6acd8dd2..d8a4b8e4f2d7 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -558,7 +558,7 @@
icon_state = "pkplush"
item_state = "pkplush"
attack_verb = list("hugged", "squeezed", "protected", "pacified")
- squeak_override = list('sound/ai/harmalarm.ogg'= 1)
+ squeak_override = list('sound/ai/default/harmalarm.ogg'= 1)
/obj/item/toy/plush/foxplushie
name = "fox plushie"
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 72155c836424..c52bc0ccaf9c 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -309,7 +309,7 @@
if(M.get_ear_protection() == FALSE)
M.confused += 6
audible_message("HUMAN HARM")
- playsound(get_turf(src), 'sound/ai/harmalarm.ogg', 70, 3)
+ playsound(get_turf(src), 'sound/ai/default/harmalarm.ogg', 70, 3)
cooldown = world.time + 200
log_game("[key_name(user)] used a Cyborg Harm Alarm in [AREACOORD(user)]")
if(iscyborg(user))
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 13944292df66..d0727a13cedd 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -292,6 +292,9 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
/obj/item/stack/sheet/mineral/bananium/Initialize(mapload, new_amount, merge = TRUE)
recipes = 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 25ec1e0216a0..bbc847cdf3a9 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -126,6 +126,10 @@
new /obj/item/clothing/mask/breath(src)
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
+
+ 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.
@@ -777,6 +781,10 @@
new /obj/item/clothing/mask/breath(src)
new /obj/item/tank/internals/emergency_oxygen(src)
new /obj/item/reagent_containers/hypospray/medipen(src)
+
+ 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"
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index ee4cc49c8672..64eee39b3510 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -657,7 +657,7 @@
message_admins("[key_name(usr)] delayed the round start.")
else
to_chat(world, "The game will start in [DisplayTimeText(newtime)].")
- SEND_SOUND(world, sound('sound/ai/attention.ogg'))
+ SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
message_admins("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
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/secrets.dm b/code/modules/admin/secrets.dm
index 13053f48009c..28a04cf31a12 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -427,7 +427,7 @@
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Chinese Cartoons"))
message_admins("[key_name_admin(usr)] made everything kawaii.")
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
- 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")
@@ -496,7 +496,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(usr)] 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(!check_rights(R_FUN))
@@ -505,9 +505,9 @@
SSeconomy.full_ancap = !SSeconomy.full_ancap
message_admins("[key_name_admin(usr)] 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("dorf")
if(!check_rights(R_FUN))
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index c999fff7f876..8bbe9a66a279 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -570,7 +570,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/senderOverride = input(src, "Please input the sender of the report", "Sender", "[command_name()] Update")
switch(confirm)
if("Yes")
- priority_announce(input, null, 'sound/ai/commandreport.ogg', sender_override = senderOverride)
+ priority_announce(input, null, SSstation.announcer.get_rand_report_sound(), sender_override = senderOverride)
announce_command_report = FALSE
if("Cancel")
return
diff --git a/code/modules/antagonists/blob/structures/core.dm b/code/modules/antagonists/blob/structures/core.dm
index 92f6b8cd3422..dd2d7815b7fd 100644
--- a/code/modules/antagonists/blob/structures/core.dm
+++ b/code/modules/antagonists/blob/structures/core.dm
@@ -9,7 +9,7 @@
point_return = -1
health_regen = 0 //we regen in Life() instead of when pulsed
resistance_flags = LAVA_PROOF
-
+
/obj/structure/blob/core/Initialize(mapload, client/new_overmind = null, placed = 0)
GLOB.blob_cores += src
START_PROCESSING(SSobj, src)
@@ -23,7 +23,7 @@
. = ..()
/obj/structure/blob/core/proc/generate_announcement()
- 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)
/obj/structure/blob/core/scannerreport()
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index 4d53a0efbc4b..a5534c52bb5c 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -495,7 +495,7 @@ structure_check() searches for nearby cultist structures required for the invoca
. = ..()
GLOB.poi_list |= src
var/area/A = get_area(src)
- priority_announce("An anomaly in veil physics has appeared in your station according to our scanners, the source being in [A.map_name]. It appears the anomaly is being stabilized by the cult of Nar-Sie!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
+ priority_announce("An anomaly in veil physics has appeared in your station according to our scanners, the source being in [A.map_name]. It appears the anomaly is being stabilized by the cult of Nar-Sie!","Central Command Higher Dimensional Affairs", ANNOUNCER_SPANOMALIES)
/obj/effect/rune/narsie/Destroy()
diff --git a/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
index 2d0987def0fc..1e346a867687 100644
--- a/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
+++ b/code/modules/antagonists/eldritch_cult/transmutations/ash_transmutations.dm
@@ -63,7 +63,7 @@
required_shit_list = "Three dead bodies."
/datum/eldritch_transmutation/final/ash_final/on_finished_recipe(mob/living/user, list/atoms, loc)
- priority_announce("$^@*$^@(#&$(@^$^@# Fear The Blaze, for Ashbringer [user.real_name] has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear The Blaze, for Ashbringer [user.real_name] has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 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/transmutations/flesh_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm
index 990317d921e9..0f0972782d9c 100644
--- a/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm
+++ b/code/modules/antagonists/eldritch_cult/transmutations/flesh_transmutations.dm
@@ -108,7 +108,7 @@
var/datum/eldritch_transmutation/voiceless_dead/ghoul2 = heretic.get_transmutation(/datum/eldritch_transmutation/voiceless_dead)
ghoul2.max_amt *= 3
var/mob/dead/observer/ghost_candidate = pick(candidates)
- priority_announce("$^@*$^@(#&$(@^$^@# Fear the dark, for Vassal of Arms has ascended! The Terror of the Night has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear the dark, for Vassal of Arms has ascended! The Terror of the Night has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
log_game("[key_name_admin(ghost_candidate)] has taken control of ([key_name_admin(summoned)]).")
summoned.ghostize(FALSE)
summoned.key = ghost_candidate.key
@@ -125,7 +125,7 @@
if(istype(S, /obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/ash)) //vitally important since ashen passage breaks the shit out of armsy
user.mind.spell_list.Remove(S)
qdel(S)
- priority_announce("$^@*$^@(#&$(@^$^@# Fear the dark, for King of Arms has ascended! Our Lord of the Night has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear the dark, for King of Arms has ascended! Our Lord of the Night has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
log_game("[user.real_name] ascended as [summoned.real_name]")
var/mob/living/carbon/carbon_user = user
var/datum/antagonist/heretic/ascension = carbon_user.mind.has_antag_datum(/datum/antagonist/heretic)
diff --git a/code/modules/antagonists/eldritch_cult/transmutations/rust_transmutations.dm b/code/modules/antagonists/eldritch_cult/transmutations/rust_transmutations.dm
index 3852021633b2..f72af4593509 100644
--- a/code/modules/antagonists/eldritch_cult/transmutations/rust_transmutations.dm
+++ b/code/modules/antagonists/eldritch_cult/transmutations/rust_transmutations.dm
@@ -27,7 +27,7 @@
H.physiology.burn_mod *= 0.5
H.physiology.stamina_mod = 0
H.physiology.stun_mod = 0
- priority_announce("$^@*$^@(#&$(@^$^@# Fear the decay, for Rustbringer [user.real_name] has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", 'sound/ai/spanomalies.ogg')
+ priority_announce("$^@*$^@(#&$(@^$^@# Fear the decay, for Rustbringer [user.real_name] has come! $^@*$^@(#&$(@^$^@#","#$^@*$^@(#&$(@^$^@#", ANNOUNCER_SPANOMALIES)
new /datum/rust_spread(loc)
var/datum/antagonist/heretic/ascension = H.mind.has_antag_datum(/datum/antagonist/heretic)
ascension.ascended = TRUE
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
index f30ae46a4e54..8f8c8ebec1ab 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.")
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index 88a407ebb6b3..4cc6c76247b1 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -240,7 +240,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/AI_Module))
sleep(30)
if(!owner || QDELETED(owner))
return
- 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 6a09200a1f0b..4f1b840dc2d1 100644
--- a/code/modules/antagonists/traitor/equipment/contractor.dm
+++ b/code/modules/antagonists/traitor/equipment/contractor.dm
@@ -243,7 +243,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(var/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 7f42f1d719b8..09970a6ab181 100644
--- a/code/modules/antagonists/traitor/syndicate_contract.dm
+++ b/code/modules/antagonists/traitor/syndicate_contract.dm
@@ -130,7 +130,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 c692b6e803e0..9dd343f5eb3e 100644
--- a/code/modules/cargo/bounty.dm
+++ b/code/modules/cargo/bounty.dm
@@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
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)
D.bounties_claimed += 1
if(D.bounties_claimed == 10)
SSachievements.unlock_achievement(/datum/achievement/cargo/bounties, user.client)
diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm
index 1032a668426a..f8b1161d3ada 100644
--- a/code/modules/cargo/console.dm
+++ b/code/modules/cargo/console.dm
@@ -77,7 +77,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
@@ -87,7 +87,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
@@ -110,7 +110,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.
"small_item" = P.small_item,
diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm
index 1e27b96a37fd..6f936391f22d 100644
--- a/code/modules/cargo/expressconsole.dm
+++ b/code/modules/cargo/expressconsole.dm
@@ -79,7 +79,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.
))
@@ -170,7 +170,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)
if (istype(beacon) && usingBeacon)//prioritize beacons over landing in cargobay
LZ = get_turf(beacon)
beacon.update_status(SP_LAUNCH)
@@ -186,15 +186,15 @@
CHECK_TICK
if(empty_turfs && 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
- D.adjust_money(-SO.pack.cost)
+ if (SO.pack.get_cost() <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
+ D.adjust_money(-SO.pack.get_cost())
new /obj/effect/DPtarget(LZ, podType, SO)
. = TRUE
message_admins("[ADMIN_LOOKUPFLW(usr)] has ordered a [SO.pack.name] pod at location [ADMIN_VERBOSEJMP(LZ)]")
investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO)
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(is_blocked_turf(T))
@@ -202,7 +202,7 @@
LAZYADD(empty_turfs, T)
CHECK_TICK
if(empty_turfs && empty_turfs.len)
- 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))
var/amountordered = 0
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index b82f473b3b1d..d55587dc3345 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -32,6 +32,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)
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 99d9a266bc03..c4bb158d1df0 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -37,7 +37,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 efeb6d19ed39..ddfc740ace98 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -14,7 +14,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 eed7ad853a07..d4d7791bf402 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -5,6 +5,14 @@
min_players = 2
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
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index b75187b29e7b..ed31a3960fd5 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 6fe14d6b77c0..eaef2e0d1101 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 aae319a3f77c..b84ccc9f7db3 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -26,7 +26,7 @@
/datum/round_event/ion_storm/announce(fake)
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || 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 bd1444c6fda9..9dc9ae8293b3 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 3943c6c256ce..812585ca7b33 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -47,7 +47,7 @@
kill()
/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')
+ priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", ANNOUNCER_METEORS)
/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 27e3f96c9e4e..843aa6a6364b 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -29,7 +29,7 @@
beacon = new(ship_name)
/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())
play_intro_music()
if(fake)
return
diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm
index c9142e20173b..c61ea9c85c59 100644
--- a/code/modules/events/radiation_storm.dm
+++ b/code/modules/events/radiation_storm.dm
@@ -12,7 +12,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 7afe14aeb0ed..3cab9cf9339b 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -16,7 +16,7 @@
spawncount = rand(5, 8)
/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()
diff --git a/code/modules/events/wizard/departmentrevolt.dm b/code/modules/events/wizard/departmentrevolt.dm
index 27fd6420a079..00ac9cb114fc 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)
\ No newline at end of file
+ qdel(nation)
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index 58389a925cee..beb43797ed0d 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, null, 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/events/zombie_infection.dm b/code/modules/events/zombie_infection.dm
index 8a8497ca5b0b..a6f7de2add4e 100644
--- a/code/modules/events/zombie_infection.dm
+++ b/code/modules/events/zombie_infection.dm
@@ -10,7 +10,7 @@
fakeable = TRUE
/datum/round_event/ghost_role/zombie/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', 'sound/hallucinations/growl1.ogg')
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS, 'sound/hallucinations/growl1.ogg')
/datum/round_event/ghost_role/zombie/spawn_role()
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 3d8a76a04b65..8eac4c4bd67e 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -882,7 +882,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)
@@ -891,15 +891,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/goals/station_goals/station_goal.dm b/code/modules/goals/station_goals/station_goal.dm
index 82f37ecc5e02..9c9c972eebb3 100644
--- a/code/modules/goals/station_goals/station_goal.dm
+++ b/code/modules/goals/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/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm
index 84e48ab1888a..09b246fbcd93 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 7722a1e23197..f6c008a6135a 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -102,6 +102,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 2116367ac7cd..a8b362cd9df4 100644
--- a/code/modules/jobs/job_types/clown.dm
+++ b/code/modules/jobs/job_types/clown.dm
@@ -49,6 +49,11 @@
box = /obj/item/storage/box/hug/survival
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)
..()
diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm
index d88dfc31a679..56143ddd4f0a 100644
--- a/code/modules/mob/living/simple_animal/friendly/dog.dm
+++ b/code/modules/mob/living/simple_animal/friendly/dog.dm
@@ -397,11 +397,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)
@@ -623,6 +619,11 @@
return
..()
+/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 edbbbd0c0b99..992c7ee0f8c4 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -33,7 +33,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/effects/hyperspace_begin.ogg', 'sound/effects/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/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-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/gunshot_silenced.ogg', 'sound/weapons/gunshot.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/effects/hyperspace_begin.ogg', 'sound/effects/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/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-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/gunshot_silenced.ogg', 'sound/weapons/gunshot.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, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
..()
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 85295b9244f3..830253029107 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -247,7 +247,7 @@
else
SSshuttle.emergencyLastCallLoc = null
- 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." : "" ]", 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." : "" ]", null, ANNOUNCER_SHUTTLECALLED, "Priority")
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
if(mode != SHUTTLE_CALL)
@@ -262,7 +262,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")
/obj/docking_port/mobile/emergency/proc/is_hijacked()
var/has_people = FALSE
@@ -353,7 +353,7 @@
mode = SHUTTLE_DOCKED
setTimer(SSshuttle.emergencyDockTime)
send2irc("Server", "The Emergency Shuttle ([name]) has docked with the station.") // yogs - make it say the name of the shuttle
- 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 b8d1d301cdc5..0bbb448febba 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -98,7 +98,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()
var/datum/bank_account/D
if(SO.paying_account) //Someone paid out of pocket
D = SO.paying_account
@@ -114,8 +114,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
if(SO.paying_account)
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
@@ -143,7 +143,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
else
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/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/harmalarm.ogg b/sound/ai/default/harmalarm.ogg
similarity index 100%
rename from sound/ai/harmalarm.ogg
rename to sound/ai/default/harmalarm.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/newai.ogg b/sound/ai/default/newai.ogg
similarity index 100%
rename from sound/ai/newai.ogg
rename to sound/ai/default/newai.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/alerts/1.ogg b/sound/ai/intern/alerts/1.ogg
new file mode 100644
index 000000000000..c4d182bc8c95
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 000000000000..7380ccdeefdb
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 000000000000..ca548dcc20a0
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 000000000000..8d71419798fc
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 000000000000..128c7aa424d1
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 000000000000..81d54101be5c
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 000000000000..a2ef615d56c5
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 000000000000..51613ff03679
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 000000000000..874536ca72fd
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 000000000000..0af0d28ce189
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 000000000000..a65006a8c013
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 000000000000..4a1d3f013aea
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 000000000000..83ca80f4939b
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 000000000000..3c0c45b25d04
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 000000000000..9dd3c0769785
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 000000000000..36102c3e60ec
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 000000000000..e3108b13d176
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 000000000000..cd67500426c2
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 000000000000..94241c5ba52b
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 000000000000..88944b63b2e6
Binary files /dev/null and b/sound/ai/intern/granomalies.ogg differ
diff --git a/sound/ai/intern/intercept.ogg b/sound/ai/intern/intercept.ogg
new file mode 100644
index 000000000000..a87274abd975
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 000000000000..9e7b5c6b23eb
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 000000000000..c68c4bd8cc4c
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 000000000000..cf98b95fd7ba
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 000000000000..297a1bbe8db6
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 000000000000..4b71053653f6
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 000000000000..509cd398e6ed
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 000000000000..08db53ebfd24
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 000000000000..c903367cdffb
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 000000000000..9f6ccd1a9378
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 000000000000..e259a79f35e4
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 000000000000..9bed8eae3aa0
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 000000000000..758f1967e099
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 000000000000..c2e72be510ed
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 000000000000..004f57371de1
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 000000000000..c4e1f7667cd0
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 000000000000..641b8208a4eb
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 000000000000..b0fc38237f88
Binary files /dev/null and b/sound/ai/intern/welcome/6.ogg differ
diff --git a/sound/ai/medbot/aliens.ogg b/sound/ai/medbot/aliens.ogg
new file mode 100644
index 000000000000..57fa70c3caec
Binary files /dev/null and b/sound/ai/medbot/aliens.ogg differ
diff --git a/sound/ai/medbot/animes.ogg b/sound/ai/medbot/animes.ogg
new file mode 100644
index 000000000000..7615a744a66e
Binary files /dev/null and b/sound/ai/medbot/animes.ogg differ
diff --git a/sound/ai/medbot/attention.ogg b/sound/ai/medbot/attention.ogg
new file mode 100644
index 000000000000..d4d5a2708527
Binary files /dev/null and b/sound/ai/medbot/attention.ogg differ
diff --git a/sound/ai/medbot/commandreport.ogg b/sound/ai/medbot/commandreport.ogg
new file mode 100644
index 000000000000..4e5c2e1d1ff2
Binary files /dev/null and b/sound/ai/medbot/commandreport.ogg differ
diff --git a/sound/ai/medbot/granomalies.ogg b/sound/ai/medbot/granomalies.ogg
new file mode 100644
index 000000000000..2713a3cb1942
Binary files /dev/null and b/sound/ai/medbot/granomalies.ogg differ
diff --git a/sound/ai/medbot/intercept.ogg b/sound/ai/medbot/intercept.ogg
new file mode 100644
index 000000000000..c59d0455c1ca
Binary files /dev/null and b/sound/ai/medbot/intercept.ogg differ
diff --git a/sound/ai/medbot/ionstorm.ogg b/sound/ai/medbot/ionstorm.ogg
new file mode 100644
index 000000000000..15aeac9f7ff9
Binary files /dev/null and b/sound/ai/medbot/ionstorm.ogg differ
diff --git a/sound/ai/medbot/meteors.ogg b/sound/ai/medbot/meteors.ogg
new file mode 100644
index 000000000000..91208cae1223
Binary files /dev/null and b/sound/ai/medbot/meteors.ogg differ
diff --git a/sound/ai/medbot/newAI.ogg b/sound/ai/medbot/newAI.ogg
new file mode 100644
index 000000000000..c40b0990206c
Binary files /dev/null and b/sound/ai/medbot/newAI.ogg differ
diff --git a/sound/ai/medbot/outbreak5.ogg b/sound/ai/medbot/outbreak5.ogg
new file mode 100644
index 000000000000..7118af444924
Binary files /dev/null and b/sound/ai/medbot/outbreak5.ogg differ
diff --git a/sound/ai/medbot/outbreak7.ogg b/sound/ai/medbot/outbreak7.ogg
new file mode 100644
index 000000000000..1fc542534dba
Binary files /dev/null and b/sound/ai/medbot/outbreak7.ogg differ
diff --git a/sound/ai/medbot/poweroff.ogg b/sound/ai/medbot/poweroff.ogg
new file mode 100644
index 000000000000..875df350025e
Binary files /dev/null and b/sound/ai/medbot/poweroff.ogg differ
diff --git a/sound/ai/medbot/poweron.ogg b/sound/ai/medbot/poweron.ogg
new file mode 100644
index 000000000000..4b1605b1c74d
Binary files /dev/null and b/sound/ai/medbot/poweron.ogg differ
diff --git a/sound/ai/medbot/radiation.ogg b/sound/ai/medbot/radiation.ogg
new file mode 100644
index 000000000000..5c48830b5f2f
Binary files /dev/null and b/sound/ai/medbot/radiation.ogg differ
diff --git a/sound/ai/medbot/shuttlecalled.ogg b/sound/ai/medbot/shuttlecalled.ogg
new file mode 100644
index 000000000000..a775567abed6
Binary files /dev/null and b/sound/ai/medbot/shuttlecalled.ogg differ
diff --git a/sound/ai/medbot/shuttledock.ogg b/sound/ai/medbot/shuttledock.ogg
new file mode 100644
index 000000000000..933928db067a
Binary files /dev/null and b/sound/ai/medbot/shuttledock.ogg differ
diff --git a/sound/ai/medbot/shuttlerecalled.ogg b/sound/ai/medbot/shuttlerecalled.ogg
new file mode 100644
index 000000000000..53b622576d4b
Binary files /dev/null and b/sound/ai/medbot/shuttlerecalled.ogg differ
diff --git a/sound/ai/medbot/spanomalies.ogg b/sound/ai/medbot/spanomalies.ogg
new file mode 100644
index 000000000000..d710999e1e15
Binary files /dev/null and b/sound/ai/medbot/spanomalies.ogg differ
diff --git a/sound/ai/medbot/welcome.ogg b/sound/ai/medbot/welcome.ogg
new file mode 100644
index 000000000000..f9a698fd0805
Binary files /dev/null and b/sound/ai/medbot/welcome.ogg differ
diff --git a/sound/machines/twobeep_voice1.ogg b/sound/machines/twobeep_voice1.ogg
new file mode 100644
index 000000000000..1dcaebf7f907
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 000000000000..e8a6c3be58c2
Binary files /dev/null and b/sound/machines/twobeep_voice2.ogg differ
diff --git a/yogstation.dme b/yogstation.dme
index ccc92e603fdb..3b769802480a 100644
--- a/yogstation.dme
+++ b/yogstation.dme
@@ -101,6 +101,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\status_effects.dm"
#include "code\__DEFINES\subsystems.dm"
#include "code\__DEFINES\tgs.config.dm"
@@ -323,6 +324,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"
@@ -371,6 +373,10 @@
#include "code\datums\achievements\viewer.dm"
#include "code\datums\actions\beam_rifle.dm"
#include "code\datums\actions\ninja.dm"
+#include "code\datums\announcers\_announcer.dm"
+#include "code\datums\announcers\default_announcer.dm"
+#include "code\datums\announcers\intern_announcer.dm"
+#include "code\datums\announcers\medbot_announcer.dm"
#include "code\datums\brain_damage\brain_trauma.dm"
#include "code\datums\brain_damage\creepy_trauma.dm"
#include "code\datums\brain_damage\hypnosis.dm"
@@ -565,6 +571,10 @@
#include "code\datums\ruins\icemoon.dm"
#include "code\datums\ruins\lavaland.dm"
#include "code\datums\ruins\space.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"
diff --git a/yogstation/code/controllers/subsystem/yogs.dm b/yogstation/code/controllers/subsystem/yogs.dm
index c6d59af6e54a..c17e12ec8081 100644
--- a/yogstation/code/controllers/subsystem/yogs.dm
+++ b/yogstation/code/controllers/subsystem/yogs.dm
@@ -14,13 +14,13 @@ SUBSYSTEM_DEF(Yogs)
/datum/controller/subsystem/Yogs/Initialize()
mentortickets = list()
-
+
//PRIZEPOOL MODIFIER THING
GLOB.arcade_prize_pool[/obj/item/grenade/plastic/glitterbomb/pink] = 1
GLOB.arcade_prize_pool[/obj/item/toy/plush/goatplushie/angry] = 2
GLOB.arcade_prize_pool[/obj/item/toy/plush/goatplushie/angry/realgoat] = 2
GLOB.arcade_prize_pool[/obj/item/stack/tile/ballpit] = 2
-
+
//MULTI-PORTAL HANDLER
var/list/enters = list()
var/list/exits_by_id = list()
@@ -64,7 +64,7 @@ SUBSYSTEM_DEF(Yogs)
// Picking department goals
// Engineering first
generateGoalsFromSubtypes(/datum/department_goal/eng)
-
+
// Then security
generateGoalsFromSubtypes(/datum/department_goal/sec)
@@ -87,25 +87,25 @@ SUBSYSTEM_DEF(Yogs)
if(istype(C, /obj/machinery/computer/card/minor/ce))
account = ACCOUNT_ENG
-
+
else if(istype(C, /obj/machinery/computer/cargo))
account = ACCOUNT_CAR
-
+
else if(istype(C, /obj/machinery/computer/card/minor/cmo))
account = ACCOUNT_MED
-
+
else if(istype(C, /obj/machinery/computer/card/minor/rd))
account = ACCOUNT_SCI
-
+
else if(istype(C, /obj/machinery/computer/card) && !istype(C, /obj/machinery/computer/card/minor))
account = ACCOUNT_SRV
-
+
else if(istype(C, /obj/machinery/computer/card/minor/hos))
account = ACCOUNT_SEC
-
+
else if(istype(C, /obj/machinery/computer/communications))
account = "all" // Special case, we'll give em all the objectives
-
+
if(account)
if(!is_station_level(C.z))
continue
@@ -135,7 +135,7 @@ SUBSYSTEM_DEF(Yogs)
P.info += ""
P.update_icon()
-
+
for(var/path in subtypesof(/datum/corporation))
new path
@@ -144,16 +144,16 @@ SUBSYSTEM_DEF(Yogs)
/datum/controller/subsystem/Yogs/fire(resumed = 0)
//END OF SHIFT ANNOUNCER
if(world.time > (ROUND_END_ANNOUNCEMENT_TIME*600) && !endedshift && !(EMERGENCY_AT_LEAST_DOCKED))
- priority_announce("Crew, your shift has come to an end. [SSshuttle.emergency.mode != SHUTTLE_IDLE ? "\n You may call the shuttle whenever you find it appropriate." : ""]", "End of shift announcement", 'sound/ai/commandreport.ogg')
+ priority_announce("Crew, your shift has come to an end. [SSshuttle.emergency.mode != SHUTTLE_IDLE ? "\n You may call the shuttle whenever you find it appropriate." : ""]", "End of shift announcement", SSstation.announcer.get_rand_report_sound())
endedshift = TRUE
-
+
//UNCLAIMED TICKET BWOINKER
if(world.time - last_rebwoink > REBWOINK_TIME*10)
last_rebwoink = world.time
for(var/datum/admin_help/bwoink in GLOB.unclaimed_tickets)
if(bwoink.check_owner())
GLOB.unclaimed_tickets -= bwoink
-
+
// Department goal checker
if(department_goals.len && SSticker.current_state == GAME_STATE_PLAYING)
for(var/datum/department_goal/dg in department_goals)
@@ -165,7 +165,7 @@ SUBSYSTEM_DEF(Yogs)
dg.continuing()
/**
- * Generates up to 5 department goals of the given type.
+ * Generates up to 5 department goals of the given type.
*
* Arguments:
* * d - the given datum that we're getting the subtypes of.
@@ -178,7 +178,7 @@ SUBSYSTEM_DEF(Yogs)
var/datum/department_goal/goal = new typepath
if(goal.is_available())
goalsSoFar++
- else
+ else
qdel(goal)
/**