[MIRROR] [READY] Adds station traits: Small modifiers that can randomly be chosen each round (#3132)

* [READY] Adds station traits: Small modifiers that can randomly be chosen each round

* conflicts

Co-authored-by: Qustinnus <Floydje123@hotmail.com>
Co-authored-by: Gandalf2k15 <jzo123@hotmail.com>
This commit is contained in:
SkyratBot
2021-02-09 00:07:24 +01:00
committed by GitHub
parent 5c55b7b62b
commit cc67a133e5
144 changed files with 712 additions and 97 deletions

View File

@@ -23,6 +23,8 @@
#define COMPONENT_GLOB_BLOCK_CINEMATIC (1<<0)
/// ingame button pressed (/obj/machinery/button/button)
#define COMSIG_GLOB_BUTTON_PRESSED "!button_pressed"
/// job subsystem has spawned and equipped a new mob
#define COMSIG_GLOB_JOB_AFTER_SPAWN "!job_after_spawn"
/// crewmember joined the game (mob/living, rank)
#define COMSIG_GLOB_CREWMEMBER_JOINED "!crewmember_joined"
@@ -53,6 +55,10 @@
/// fires on the target datum when an element is attached to it (/datum/element)
#define COMSIG_ELEMENT_DETACH "element_detach"
///Subsystem signals
///From base of datum/controller/subsystem/Initialize: (start_timeofday)
#define COMSIG_SUBSYSTEM_POST_INITIALIZE "subsystem_post_initialize"
// /atom signals
///from base of atom/proc/Initialize(): sent any time a new atom is created
#define COMSIG_ATOM_CREATED "atom_created"

View File

@@ -99,3 +99,22 @@
#define SOUND_AREA_LAVALAND SOUND_ENVIRONMENT_MOUNTAINS
#define SOUND_AREA_ICEMOON SOUND_ENVIRONMENT_CAVE
#define SOUND_AREA_WOODFLOOR SOUND_ENVIRONMENT_CITY
///Announcer audio keys
#define ANNOUNCER_AIMALF "announcer_aimalf"
#define ANNOUNCER_ALIENS "announcer_aliens"
#define ANNOUNCER_ANIMES "announcer_animes"
#define ANNOUNCER_GRANOMALIES "announcer_granomalies"
#define ANNOUNCER_INTERCEPT "announcer_animes"
#define ANNOUNCER_IONSTORM "announcer_ionstorm"
#define ANNOUNCER_METEORS "announcer_meteors"
#define ANNOUNCER_OUTBREAK5 "announcer_outbreak5"
#define ANNOUNCER_OUTBREAK7 "announcer_outbreak7"
#define ANNOUNCER_POWEROFF "announcer_poweroff"
#define ANNOUNCER_POWERON "announcer_poweron"
#define ANNOUNCER_RADIATION "announcer_radiation"
#define ANNOUNCER_SHUTTLECALLED "announcer_shuttlecalled"
#define ANNOUNCER_SHUTTLEDOCK "announcer_shuttledock"
#define ANNOUNCER_SHUTTLERECALLED "announcer_shuttlerecalled"
#define ANNOUNCER_SPANOMALIES "announcer_spanomalies"

View File

@@ -0,0 +1,3 @@
#define STATION_TRAIT_POSITIVE 1
#define STATION_TRAIT_NEUTRAL 2
#define STATION_TRAIT_NEGATIVE 3

View File

@@ -113,6 +113,7 @@
#define INIT_ORDER_VIS 80
#define INIT_ORDER_ACHIEVEMENTS 77
#define INIT_ORDER_RESEARCH 75
#define INIT_ORDER_STATION 74 //This is high priority because it manipulates a lot of the subsystems that will initialize after it.
#define INIT_ORDER_EVENTS 70
#define INIT_ORDER_JOBS 65
#define INIT_ORDER_QUIRKS 60

View File

@@ -402,6 +402,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define CHOKEHOLD_TRAIT "chokehold" //trait associated to being held in a chokehold
#define RESTING_TRAIT "resting" //trait associated to resting
#define STAT_TRAIT "stat" //trait associated to a stat value or range of
#define STATION_TRAIT "station-trait"
#define MAPPING_HELPER_TRAIT "mapping-helper" //obtained from mapping helper
/// Trait associated to wearing a suit
#define SUIT_TRAIT "suit"
@@ -499,3 +500,15 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Trait from [/datum/antagonist/nukeop/clownop]
#define CLOWNOP_TRAIT "clownop"
///Traits given by station traits
#define STATION_TRAIT_BANANIUM_SHIPMENTS "station_trait_bananium_shipments"
#define STATION_TRAIT_UNNATURAL_ATMOSPHERE "station_trait_unnatural_atmosphere"
#define STATION_TRAIT_UNIQUE_AI "station_trait_unique_ai"
#define STATION_TRAIT_CARP_INFESTATION "station_trait_carp_infestation"
#define STATION_TRAIT_PREMIUM_INTERNALS "station_trait_premium_internals"
#define STATION_TRAIT_LATE_ARRIVALS "station_trait_late_arrivals"
#define STATION_TRAIT_RANDOM_ARRIVALS "station_trait_random_arrivals"
#define STATION_TRAIT_FILLED_MAINT "station_trait_filled_maint"
#define STATION_TRAIT_EMPTY_MAINT "station_trait_empty_maint"
#define STATION_TRAIT_PDA_GLITCHED "station_trait_pda_glitched"

View File

@@ -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 += "<h1 class='alert'>Priority Announcement</h1>"
@@ -26,6 +28,10 @@
else
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
///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 += "<br><span class='alert'>[html_encode(text)]</span><br>"
announcement += "<br>"
@@ -41,7 +47,7 @@
title = "Classified [command_name()] Update"
if(announce)
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg')
priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", SSstation.announcer.get_rand_report_sound(), has_important_message = TRUE)
var/datum/comm_message/M = new
M.title = title

View File

@@ -988,9 +988,9 @@ rough example of the "cone" made by the 3 dirs checked
if (length(turfs))
return pick(turfs)
/proc/get_safe_random_station_turf() //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
/proc/get_safe_random_station_turf(list/areas_to_pick_from = GLOB.the_station_areas) //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
for (var/i in 1 to 5)
var/list/L = get_area_turfs(pick(GLOB.the_station_areas))
var/list/L = get_area_turfs(pick(areas_to_pick_from))
var/turf/target
while (L.len && !target)
var/I = rand(1, L.len)

View File

@@ -35,6 +35,7 @@ GLOBAL_LIST_EMPTY(secequipment) //sec equipment lockers that scale with the numb
GLOBAL_LIST_EMPTY(deathsquadspawn)
GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
GLOBAL_LIST_EMPTY(ruin_landmarks)
GLOBAL_LIST_EMPTY(bar_areas)
//away missions
GLOBAL_LIST_EMPTY(vr_spawnpoints)

View File

@@ -214,6 +214,7 @@
//used to initialize the subsystem AFTER the map has loaded
/datum/controller/subsystem/Initialize(start_timeofday)
initialized = TRUE
SEND_SIGNAL(src, COMSIG_SUBSYSTEM_POST_INITIALIZE, start_timeofday)
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
to_chat(world, "<span class='boldannounce'>[msg]</span>")

View File

@@ -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.")

View File

@@ -35,6 +35,10 @@ SUBSYSTEM_DEF(economy)
var/civ_bounty_tracker = 0
/// Contains the message to send to newscasters about price inflation and earnings, updated on price_update()
var/earning_report
///The modifier multiplied to the value of bounties paid out.
var/bounty_modifier = 1
///The modifier multiplied to the value of cargo pack prices.
var/pack_price_modifier = 1
var/market_crashing = FALSE
var/fire_counter_for_paycheck = 0 //SKYRAT EDIT ADDITION

View File

@@ -454,8 +454,15 @@ SUBSYSTEM_DEF(job)
//If we joined at roundstart we should be positioned at our workstation
if(!joined_late)
var/spawning_handled = FALSE
var/obj/S = null
if(length(GLOB.jobspawn_overrides[rank]))
if(HAS_TRAIT(SSstation, STATION_TRAIT_LATE_ARRIVALS))
SendToLateJoin(living_mob)
spawning_handled = TRUE
else if(HAS_TRAIT(SSstation, STATION_TRAIT_RANDOM_ARRIVALS))
DropLandAtRandomHallwayPoint(living_mob)
spawning_handled = TRUE
else if(length(GLOB.jobspawn_overrides[rank]))
S = pick(GLOB.jobspawn_overrides[rank])
else
for(var/_sloc in GLOB.start_landmarks_list)
@@ -469,7 +476,7 @@ SUBSYSTEM_DEF(job)
break
if(S)
S.JoinPlayerHere(living_mob, FALSE)
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
if(!S && !spawning_handled) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
log_world("Couldn't find a round start spawn point for [rank]")
if(!SendToLateJoin(living_mob))
living_mob.move_to_error_room()
@@ -515,7 +522,7 @@ SUBSYSTEM_DEF(job)
var/mob/living/carbon/human/wageslave = living_mob
living_mob.add_memory("Your account ID is [wageslave.account_id].")
if(job && living_mob)
job.after_spawn(living_mob, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
job.after_spawn(living_mob, M, joined_late) // note: this happens before the mob has a key! M will always have a client, living_mob might not.
//SKYRAT CHANGE ADDITION BEGIN - CUSTOMIZATION
if(!job.no_dresscode && job.loadout)
if(M.client)
@@ -709,6 +716,13 @@ SUBSYSTEM_DEF(job)
message_admins(msg)
CRASH(msg)
///Lands specified mob at a random spot in the hallways
/datum/controller/subsystem/job/proc/DropLandAtRandomHallwayPoint(mob/living/living_mob)
var/turf/spawn_turf = get_safe_random_station_turf(typesof(/area/hallway))
var/obj/structure/closet/supplypod/centcompod/toLaunch = new()
living_mob.forceMove(toLaunch)
new /obj/effect/pod_landingzone(spawn_turf, toLaunch)
///////////////////////////////////
//Keeps track of all living heads//

View File

@@ -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

View File

@@ -404,7 +404,7 @@ SUBSYSTEM_DEF(shuttle)
emergency.setTimer(emergencyDockTime)
priority_announce("Hostile environment resolved. \
You have 3 minutes to board the Emergency Shuttle.",
null, 'sound/ai/shuttledock.ogg', "Priority")
null, ANNOUNCER_SHUTTLEDOCK, "Priority")
//try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons
/datum/controller/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)

View File

@@ -299,7 +299,7 @@ SUBSYSTEM_DEF(ticker)
SSdbcore.SetRoundStart()
to_chat(world, "<span class='notice'><B>Welcome to [station_name()], enjoy your stay!</B></span>")
SEND_SOUND(world, sound('sound/ai/welcome.ogg'))
SEND_SOUND(world, sound(SSstation.announcer.get_rand_welcome_sound()))
current_state = GAME_STATE_PLAYING
Master.SetRunLevel(RUNLEVEL_GAME)

View File

@@ -223,6 +223,11 @@
/datum/ai_laws/proc/set_laws_config()
var/list/law_ids = CONFIG_GET(keyed_list/random_laws)
if(HAS_TRAIT(SSstation, STATION_TRAIT_UNIQUE_AI))
pick_weighted_lawset()
return
switch(CONFIG_GET(number/default_laws))
if(0)
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")

View File

@@ -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)

View File

@@ -0,0 +1,19 @@
/datum/centcom_announcer/default
welcome_sounds = list('sound/ai/default/welcome.ogg')
alert_sounds = list('sound/ai/default/attention.ogg')
command_report_sounds = list('sound/ai/default/commandreport.ogg')
event_sounds = list(ANNOUNCER_AIMALF = 'sound/ai/default/aimalf.ogg',
ANNOUNCER_ALIENS = 'sound/ai/default/aliens.ogg',
ANNOUNCER_ANIMES = 'sound/ai/default/animes.ogg',
ANNOUNCER_GRANOMALIES = 'sound/ai/default/granomalies.ogg',
ANNOUNCER_INTERCEPT = 'sound/ai/default/intercept.ogg',
ANNOUNCER_IONSTORM = 'sound/ai/default/ionstorm.ogg',
ANNOUNCER_OUTBREAK5 = 'sound/ai/default/outbreak5.ogg',
ANNOUNCER_OUTBREAK7 = 'sound/ai/default/outbreak7.ogg',
ANNOUNCER_POWEROFF = 'sound/ai/default/poweroff.ogg',
ANNOUNCER_POWERON = 'sound/ai/default/poweron.ogg',
ANNOUNCER_RADIATION = 'sound/ai/default/radiation.ogg',
ANNOUNCER_SHUTTLECALLED = 'sound/ai/default/shuttlecalled.ogg',
ANNOUNCER_SHUTTLEDOCK = 'sound/ai/default/shuttledock.ogg',
ANNOUNCER_SHUTTLERECALLED = 'sound/ai/default/shuttlerecalled.ogg',
ANNOUNCER_SPANOMALIES = 'sound/ai/default/spanomalies.ogg')

View File

@@ -0,0 +1,45 @@
/datum/centcom_announcer/intern
welcome_sounds = list('sound/ai/intern/welcome/1.ogg',
'sound/ai/intern/welcome/2.ogg',
'sound/ai/intern/welcome/3.ogg',
'sound/ai/intern/welcome/4.ogg',
'sound/ai/intern/welcome/5.ogg',
'sound/ai/intern/welcome/6.ogg')
alert_sounds = list('sound/ai/intern/alerts/1.ogg',
'sound/ai/intern/alerts/2.ogg',
'sound/ai/intern/alerts/3.ogg',
'sound/ai/intern/alerts/4.ogg',
'sound/ai/intern/alerts/5.ogg',
'sound/ai/intern/alerts/6.ogg',
'sound/ai/intern/alerts/7.ogg',
'sound/ai/intern/alerts/8.ogg',
'sound/ai/intern/alerts/9.ogg',
'sound/ai/intern/alerts/10.ogg',
'sound/ai/intern/alerts/11.ogg',
'sound/ai/intern/alerts/12.ogg',
'sound/ai/intern/alerts/13.ogg',
'sound/ai/intern/alerts/14.ogg')
command_report_sounds = list('sound/ai/intern/commandreport/1.ogg',
'sound/ai/intern/commandreport/2.ogg',
'sound/ai/intern/commandreport/3.ogg')
event_sounds = list(ANNOUNCER_AIMALF = 'sound/ai/intern/aimalf.ogg',
ANNOUNCER_ALIENS = 'sound/ai/intern/aliens.ogg',
ANNOUNCER_ANIMES = 'sound/ai/intern/animes.ogg',
ANNOUNCER_GRANOMALIES = 'sound/ai/intern/granomalies.ogg',
ANNOUNCER_INTERCEPT = 'sound/ai/intern/intercept.ogg',
ANNOUNCER_IONSTORM = 'sound/ai/intern/ionstorm.ogg',
ANNOUNCER_OUTBREAK5 = 'sound/ai/intern/outbreak5.ogg',
ANNOUNCER_OUTBREAK7 = 'sound/ai/intern/outbreak7.ogg',
ANNOUNCER_POWEROFF = 'sound/ai/intern/poweroff.ogg',
ANNOUNCER_POWERON = 'sound/ai/intern/poweron.ogg',
ANNOUNCER_RADIATION = 'sound/ai/intern/radiation.ogg',
ANNOUNCER_SHUTTLECALLED = 'sound/ai/intern/shuttlecalled.ogg',
ANNOUNCER_SHUTTLEDOCK = 'sound/ai/intern/shuttledock.ogg',
ANNOUNCER_SHUTTLERECALLED = 'sound/ai/intern/shuttlerecalled.ogg',
ANNOUNCER_SPANOMALIES = 'sound/ai/intern/spanomalies.ogg')
custom_alert_message = "<br><span class='alert'>Please stand by for an important message from our new intern.</span><br>"

View File

@@ -20,6 +20,9 @@
var/target_pressure = rand(minimum_pressure, maximum_pressure)
var/pressure_scalar = target_pressure / maximum_pressure
if(HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE))
restricted_chance = restricted_chance + 30
// First let's set up the gasmix and base gases for this template
// We make the string from a gasmix in this proc because gases need to calculate their pressure
var/datum/gas_mixture/gasmix = new
@@ -39,7 +42,7 @@
else
gastype = pick(restricted_gases)
amount = restricted_gases[gastype]
if(gaslist[gastype])
if(!HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE) && gaslist[gastype])
continue
amount *= rand(50, 200) / 100 // Randomly modifes the amount from half to double the base for some variety

View File

@@ -93,7 +93,7 @@
effect.start()
// Safe location finder
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE, dense_atoms = TRUE)
if(!zlevels)
if (zlevel)
zlevels = list(zlevel)
@@ -149,6 +149,16 @@
if(!L.is_safe())
continue
// Check that we're not warping onto a table or window
if(!dense_atoms)
var/density_found = FALSE
for(var/atom/movable/found_movable in F)
if(found_movable.density)
density_found = TRUE
break
if(density_found)
continue
// DING! You have passed the gauntlet, and are "probably" safe.
return F

View File

@@ -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]"

View File

@@ -0,0 +1,92 @@
/datum/station_trait/carp_infestation
name = "Carp infestation"
trait_type = STATION_TRAIT_NEGATIVE
weight = 5
show_in_report = TRUE
report_message = "Dangerous fauna is present in the area of this station"
trait_to_give = STATION_TRAIT_CARP_INFESTATION
/datum/station_trait/distant_supply_lines
name = "Distant supply lines"
trait_type = STATION_TRAIT_NEGATIVE
weight = 3
show_in_report = TRUE
report_message = "Due to the distance to our normal supply lines, cargo orders are more expensive."
blacklist = list(/datum/station_trait/strong_supply_lines)
/datum/station_trait/distant_supply_lines/on_round_start()
SSeconomy.pack_price_modifier *= 1.2
/datum/station_trait/late_arrivals
name = "Late Arrivals"
trait_type = STATION_TRAIT_NEGATIVE
weight = 2
show_in_report = TRUE
report_message = "Sorry for that, we didn't expect to fly into that vomiting goose while bringing you to your new station."
trait_to_give = STATION_TRAIT_LATE_ARRIVALS
blacklist = list(/datum/station_trait/random_spawns)
/datum/station_trait/random_spawns
name = "Drive-by landing"
trait_type = STATION_TRAIT_NEGATIVE
weight = 2
show_in_report = TRUE
report_message = "Sorry for that, we missed your station by a few miles, so we just launched you towards your station in pods. Hope you don't mind!"
trait_to_give = STATION_TRAIT_RANDOM_ARRIVALS
blacklist = list(/datum/station_trait/late_arrivals)
/datum/station_trait/blackout
name = "Blackout"
trait_type = STATION_TRAIT_NEGATIVE
weight = 5
show_in_report = TRUE
report_message = "Station lights seem to be damaged, be safe when starting your shift today."
/datum/station_trait/blackout/on_round_start()
. = ..()
for(var/a in GLOB.apcs_list)
var/obj/machinery/power/apc/current_apc = a
if(prob(60))
current_apc.overload_lighting()
/datum/station_trait/empty_maint
name = "Cleaned out maintenance"
trait_type = STATION_TRAIT_NEGATIVE
weight = 5
show_in_report = TRUE
report_message = "Our workers cleaned out most of the junk in the maintenace areas."
blacklist = list(/datum/station_trait/filled_maint)
trait_to_give = STATION_TRAIT_EMPTY_MAINT
/datum/station_trait/overflow_job_bureacracy
name = "Overflow bureacracy mistake"
trait_type = STATION_TRAIT_NEGATIVE
weight = 5
show_in_report = TRUE
var/list/jobs_to_use = list("Clown", "Bartender", "Cook", "Botanist", "Cargo Technician", "Mime", "Janitor", "Prisoner")
var/chosen_job
/datum/station_trait/overflow_job_bureacracy/New()
. = ..()
chosen_job = pick(jobs_to_use)
RegisterSignal(SSjob, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/set_overflow_job_override)
/datum/station_trait/overflow_job_bureacracy/get_report()
return "[name] - It seems for some reason we put out the wrong job-listing for the overflow role this shift...I hope you like [chosen_job]s."
/datum/station_trait/overflow_job_bureacracy/proc/set_overflow_job_override(datum/source, new_overflow_role)
SIGNAL_HANDLER
SSjob.set_overflow_role(chosen_job)
/datum/station_trait/slow_shuttle
name = "Slow Shuttle"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = TRUE
report_message = "Due to distance to our supply station, the cargo shuttle will have a slower flight time to your cargo department."
blacklist = list(/datum/station_trait/quick_shuttle)
/datum/station_trait/slow_shuttle/on_round_start()
. = ..()
SSshuttle.supply.callTime *= 1.5

View File

@@ -0,0 +1,64 @@
/datum/station_trait/bananium_shipment
name = "Bananium Shipment"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
report_message = "Rumors has it that the clown planet has been sending support packages to clowns in this system"
trait_to_give = STATION_TRAIT_BANANIUM_SHIPMENTS
/datum/station_trait/unnatural_atmosphere
name = "Unnatural atmospherical properties"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = TRUE
report_message = "System's local planet has irregular atmospherical properties"
trait_to_give = STATION_TRAIT_UNNATURAL_ATMOSPHERE
/datum/station_trait/unique_ai
name = "Unique AI"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = TRUE
report_message = "For experimental purposes, this station AI might show divergence from default lawset. Do not meddle with this experiment."
trait_to_give = STATION_TRAIT_UNIQUE_AI
/datum/station_trait/ian_adventure
name = "Ian's Adventure"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = FALSE
report_message = "Ian has gone exploring somewhere in the station."
/datum/station_trait/ian_adventure/on_round_start()
for(var/mob/living/simple_animal/pet/dog/corgi/dog in GLOB.mob_list)
if(!(istype(dog, /mob/living/simple_animal/pet/dog/corgi/ian) || istype(dog, /mob/living/simple_animal/pet/dog/corgi/puppy/ian)))
continue
// The extended safety checks at time of writing are about chasms and lava
// if there are any chasms and lava on stations in the future, woah
var/turf/current_turf = get_turf(dog)
var/turf/adventure_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE)
// Poof!
do_smoke(location=current_turf)
dog.forceMove(adventure_turf)
do_smoke(location=adventure_turf)
/datum/station_trait/glitched_pdas
name = "PDA glitch"
trait_type = STATION_TRAIT_NEUTRAL
weight = 8
show_in_report = TRUE
report_message = "Something seems to be wrong with the PDAs issues to you all this shift. Nothing too bad though."
trait_to_give = STATION_TRAIT_PDA_GLITCHED
/datum/station_trait/announcement_intern
name = "Announcement Intern"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = TRUE
report_message = "Please be nice to him."
/datum/station_trait/announcement_intern/New()
. = ..()
SSstation.announcer = /datum/centcom_announcer/intern

View File

@@ -0,0 +1,125 @@
#define PARTY_COOLDOWN_LENGTH_MIN 6 MINUTES
#define PARTY_COOLDOWN_LENGTH_MAX 12 MINUTES
/datum/station_trait/lucky_winner
name = "Lucky winner"
trait_type = STATION_TRAIT_POSITIVE
weight = 1
show_in_report = TRUE
report_message = "Your station has won the grand prize of the annual station charity event. Free snacks will be delivered to the bar every now and then."
trait_processes = TRUE
COOLDOWN_DECLARE(party_cooldown)
/datum/station_trait/lucky_winner/on_round_start()
. = ..()
COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX))
/datum/station_trait/lucky_winner/process(delta_time)
if(!COOLDOWN_FINISHED(src, party_cooldown))
return
COOLDOWN_START(src, party_cooldown, rand(PARTY_COOLDOWN_LENGTH_MIN, PARTY_COOLDOWN_LENGTH_MAX))
var/area/area_to_spawn_in = pick(GLOB.bar_areas)
var/turf/T = pick(area_to_spawn_in.contents)
var/obj/structure/closet/supplypod/centcompod/toLaunch = new()
var/obj/item/pizzabox/pizza_to_spawn = pick(list(/obj/item/pizzabox/margherita, /obj/item/pizzabox/mushroom, /obj/item/pizzabox/meat, /obj/item/pizzabox/vegetable, /obj/item/pizzabox/pineapple))
new pizza_to_spawn(toLaunch)
for(var/i in 1 to 6)
new /obj/item/reagent_containers/food/drinks/beer(toLaunch)
new /obj/effect/pod_landingzone(T, toLaunch)
/datum/station_trait/galactic_grant
name = "Galactic grant"
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
report_message = "Your station has been selected for a special grant. Some extra funds has been made available to your cargo department."
/datum/station_trait/galactic_grant/on_round_start()
var/datum/bank_account/cargo_bank = SSeconomy.get_dep_account(ACCOUNT_CAR)
cargo_bank.adjust_money(rand(2000, 5000))
/datum/station_trait/premium_internals_box
name = "Premium internals boxes"
trait_type = STATION_TRAIT_POSITIVE
weight = 10
show_in_report = TRUE
report_message = "The internals boxes for your crew have been filled with bonus equipment."
trait_to_give = STATION_TRAIT_PREMIUM_INTERNALS
/datum/station_trait/bountiful_bounties
name = "Bountiful bounties"
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
report_message = "It seems collectors in this system are extra keen to on bounties, and will pay more to see their completion."
/datum/station_trait/bountiful_bounties/on_round_start()
SSeconomy.bounty_modifier *= 1.2
/datum/station_trait/strong_supply_lines
name = "Strong supply lines"
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
report_message = "Prices are low in this system, BUY BUY BUY!"
blacklist = list(/datum/station_trait/distant_supply_lines)
/datum/station_trait/strong_supply_lines/on_round_start()
SSeconomy.pack_price_modifier *= 0.8
/datum/station_trait/scarves
name = "Scarves"
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
var/list/scarves
/datum/station_trait/scarves/New()
. = ..()
report_message = pick(
"Nanotrasen is experimenting with seeing if neck warmth improves employee morale.",
"After Space Fashion Week, scarves are the hot new accessory.",
"Everyone was simultaneously a little bit cold when they packed to go to the station.",
"The station is definitely not under attack by neck grappling aliens masquerading as wool. Definitely not.",
"You all get free scarves. Don't ask why.",
"A shipment of scarves was delivered to the station.",
)
scarves = typesof(/obj/item/clothing/neck/scarf) + list(
/obj/item/clothing/neck/stripedredscarf,
/obj/item/clothing/neck/stripedgreenscarf,
/obj/item/clothing/neck/stripedbluescarf,
)
RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn)
/datum/station_trait/scarves/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/living_mob, mob/M, joined_late)
SIGNAL_HANDLER
var/scarf_type = pick(scarves)
living_mob.equip_to_slot_or_del(new scarf_type(living_mob), ITEM_SLOT_NECK, initial = FALSE)
/datum/station_trait/filled_maint
name = "Filled up maintenance"
trait_type = STATION_TRAIT_POSITIVE
weight = 5
show_in_report = TRUE
report_message = "Our workers accidentaly forgot more of their personal belongings in the maintenace areas."
blacklist = list(/datum/station_trait/empty_maint)
trait_to_give = STATION_TRAIT_FILLED_MAINT
/datum/station_trait/quick_shuttle
name = "Quick Shuttle"
trait_type = STATION_TRAIT_NEUTRAL
weight = 5
show_in_report = TRUE
report_message = "Due to proximity to our supply station, the cargo shuttle will have a quicker flight time to your cargo department/"
blacklist = list(/datum/station_trait/slow_shuttle)
/datum/station_trait/quick_shuttle/on_round_start()
. = ..()
SSshuttle.supply.callTime *= 0.5

View File

@@ -611,6 +611,10 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
airlock_wires = /datum/wires/airlock/service
sound_environment = SOUND_AREA_WOODFLOOR
/area/service/bar/Initialize(mapload)
. = ..()
GLOB.bar_areas += src
/area/service/bar/atrium
name = "Atrium"
icon_state = "bar"

View File

@@ -264,8 +264,17 @@ GLOBAL_VAR_INIT(dynamic_forced_threat_level, -1)
G.on_report()
. += G.get_report()
if(SSstation.station_traits.len)
. += "<hr><b>Identified shift divergencies:</b><BR>"
for(var/i in SSstation.station_traits)
var/datum/station_trait/station_trait_iterator = i
if(!station_trait_iterator.show_in_report)
return
. += "[station_trait_iterator.get_report()]<BR>"
print_command_report(., "Central Command Status Summary", announce=FALSE)
priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", 'sound/ai/intercept.ogg')
priority_announce("A summary has been copied and printed to all communications consoles.", "Security level elevated.", ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)

View File

@@ -322,7 +322,7 @@
M.mind.special_role = antag_flag
M.mind.add_antag_datum(AI)
if(prob(ion_announce))
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", ANNOUNCER_IONSTORM)
if(prob(removeDontImproveChance))
M.replace_random_law(generate_ion_law(), list(LAW_INHERENT, LAW_SUPPLIED, LAW_ION))
else

View File

@@ -1,5 +1,5 @@
/proc/power_failure()
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", ANNOUNCER_POWEROFF)
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(istype(get_area(S), /area/ai_monitored/turret_protected) || !is_station_level(S.z))
continue
@@ -30,7 +30,7 @@
/proc/power_restore()
priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWEROFF)
for(var/obj/machinery/power/apc/C in GLOB.machines)
if(C.cell && is_station_level(C.z))
C.cell.charge = C.cell.maxcharge
@@ -54,7 +54,7 @@
/proc/power_restore_quick()
priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", 'sound/ai/poweron.ogg')
priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWERON)
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(!is_station_level(S.z))
continue

View File

@@ -26,4 +26,4 @@
G.on_report()
/datum/game_mode/extended/announced/send_intercept(report = 0)
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", 'sound/ai/commandreport.ogg')
priority_announce("Thanks to the tireless efforts of our security and intelligence divisions, there are currently no credible threats to [station_name()]. All station construction projects have been authorized. Have a secure shift!", "Security Report", SSstation.announcer.get_rand_report_sound())

View File

@@ -299,8 +299,16 @@
G.on_report()
intercepttext += G.get_report()
if(SSstation.station_traits.len)
intercepttext += "<hr><b>Identified shift divergencies:</b>"
for(var/i in SSstation.station_traits)
var/datum/station_trait/station_trait_iterator = i
if(!station_trait_iterator.show_in_report)
return
intercepttext += station_trait_iterator.get_report()
print_command_report(intercepttext, "Central Command Status Summary", announce=FALSE)
priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", 'sound/ai/intercept.ogg')
priority_announce("A summary has been copied and printed to all communications consoles.", "Enemy communication intercepted. Security level elevated.", ANNOUNCER_INTERCEPT)
if(GLOB.security_level < SEC_LEVEL_BLUE)
set_security_level(SEC_LEVEL_BLUE)

View File

@@ -227,7 +227,7 @@
nuke_request(reason, usr)
to_chat(usr, "<span class='notice'>Request sent.</span>")
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")

View File

@@ -245,6 +245,13 @@
/obj/effect/spawner/lootdrop/maintenance/Initialize(mapload)
loot = GLOB.maintenance_loot
if(HAS_TRAIT(SSstation, STATION_TRAIT_FILLED_MAINT))
lootcount = FLOOR(lootcount * 1.5, 1)
else if(HAS_TRAIT(SSstation, STATION_TRAIT_EMPTY_MAINT))
lootcount = FLOOR(lootcount * 0.5, 1)
. = ..()
/obj/effect/spawner/lootdrop/maintenance/two

View File

@@ -785,6 +785,9 @@ GLOBAL_LIST_EMPTY(PDAs)
tnote += "<i><b>&larr; From <a href='byond://?src=[REF(src)];choice=Message;target=[REF(signal.source)]'>[signal.data["name"]]</a> ([signal.data["job"]]):</b></i><br>[signal.format_message()]<br>"
if (!silent)
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.

View File

@@ -263,6 +263,9 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \
. = ..()
. += GLOB.bananium_recipes
/obj/item/stack/sheet/mineral/bananium/five
amount = 5
/*
* Titanium
*/

View File

@@ -138,6 +138,10 @@
//SKYRAT EDIT END
new /obj/item/oxygen_candle(src) //SKYRAT EDIT ADDITION
if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
new /obj/item/flashlight/flare(src)
new /obj/item/radio/off(src)
/obj/item/storage/box/survival/radio/PopulateContents()
..() // we want the survival stuff too.
new /obj/item/radio/off(src)
@@ -851,6 +855,9 @@
//SKYRAT EDIT END
new /obj/item/oxygen_candle(src) //SKYRAT EDIT ADDITION
if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
new /obj/item/flashlight/flare(src)
new /obj/item/radio/off(src)
/obj/item/storage/box/rubbershot
name = "box of rubber shots"
desc = "A box full of rubber shots, designed for riot shotguns."

View File

@@ -589,7 +589,7 @@
SSticker.start_immediately = FALSE
SSticker.SetTimeLeft(1800)
to_chat(world, "<b>The game will start in 180 seconds.</b>")
SEND_SOUND(world, sound('sound/ai/attention.ogg'))
SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
message_admins("<font color='blue'>[usr.key] has cancelled immediate game start. Game will start in 180 seconds.</font>")
log_admin("[usr.key] has cancelled immediate game start.")
else
@@ -656,7 +656,7 @@
log_admin("[key_name(usr)] delayed the round start.")
else
to_chat(world, "<b>The game will start in [DisplayTimeText(newtime)].</b>", confidential = TRUE)
SEND_SOUND(world, sound('sound/ai/attention.ogg'))
SEND_SOUND(world, sound('sound/ai/default/attention.ogg'))
log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -16,7 +16,7 @@
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has disabled anonymous names.</span>")
if(SSticker.current_state < GAME_STATE_PREGAME)
return
priority_announce("Names and Identities have been restored.", "Identity Restoration", 'sound/ai/attention.ogg')
priority_announce("Names and Identities have been restored.", "Identity Restoration", SSstation.announcer.get_rand_alert_sound())
for(var/mob/living/player in GLOB.player_list)
if(!player.mind || (!ishuman(player) && !issilicon(player)) || !SSjob.GetJob(player.mind.assigned_role))
continue
@@ -41,7 +41,7 @@
alert_players = alert(usr, "Alert crew? These are IC Themed FROM centcom.", "2016 admins didn't miss roundstart", "Yes", "No")
SSticker.anonymousnames = new result()
if(alert_players == "Yes")
priority_announce(SSticker.anonymousnames.announcement_alert, "Identity Loss", 'sound/ai/attention.ogg')
priority_announce(SSticker.anonymousnames.announcement_alert, "Identity Loss", SSstation.announcer.get_rand_alert_sound())
anonymous_all_players()
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has enabled anonymous names. THEME: [SSticker.anonymousnames].</span>")

View File

@@ -561,7 +561,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/announce_command_report = TRUE
switch(confirm)
if("Yes")
priority_announce(input, null, 'sound/ai/commandreport.ogg')
priority_announce(input, null, SSstation.announcer.get_rand_report_sound())
announce_command_report = FALSE
if("Cancel")
return

View File

@@ -336,7 +336,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/command) && !istype(get_area(W), /area/commons) && !istype(get_area(W), /area/service) && !istype(get_area(W), /area/command/heads_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(holder)] activated Egalitarian Station mode")
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/ai/commandreport.ogg')
priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, SSstation.announcer.get_rand_report_sound())
if("ancap")
if(!is_funmin)
return
@@ -344,9 +344,9 @@
SSeconomy.full_ancap = !SSeconomy.full_ancap
message_admins("[key_name_admin(holder)] toggled Anarcho-capitalist mode")
if(SSeconomy.full_ancap)
priority_announce("The NAP is now in full effect.", null, 'sound/ai/commandreport.ogg')
priority_announce("The NAP is now in full effect.", null, SSstation.announcer.get_rand_report_sound())
else
priority_announce("The NAP has been revoked.", null, 'sound/ai/commandreport.ogg')
priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound())
if("blackout")
if(!is_funmin)
return
@@ -502,7 +502,7 @@
message_admins("[key_name_admin(holder)] made everything kawaii.")
for(var/i in GLOB.human_list)
var/mob/living/carbon/human/H = i
SEND_SOUND(H, sound('sound/ai/animes.ogg'))
SEND_SOUND(H, sound(SSstation.announcer.event_sounds[ANNOUNCER_ANIMES]))
if(H.dna.species.id == "human")
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")

View File

@@ -129,7 +129,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
max_count = blobs_legit.len
if(announcement_time && (world.time >= announcement_time || blobs_legit.len >= announcement_size) && !has_announced)
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK5)
has_announced = TRUE
/mob/camera/blob/proc/victory()

View File

@@ -120,7 +120,7 @@ This file contains the cult dagger and rune list code
if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move
to_chat(user, "<span class='cultlarge'>The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]!</span>")
return
priority_announce("Figments from an eldritch god are being summoned by [user] into [initial(A.name)] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
priority_announce("Figments from an eldritch god are being summoned by [user] into [initial(A.name)] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", ANNOUNCER_SPANOMALIES)
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/cult/narsie/N = new(B)
shields += N

View File

@@ -154,6 +154,7 @@
for(var/i in 0 to number)
var/turf/chosen_location = get_safe_random_station_turf()
//we also dont want them close to each other, at least 1 tile of seperation
var/obj/effect/reality_smash/what_if_i_have_one = locate() in range(1, chosen_location)
var/obj/effect/broken_illusion/what_if_i_had_one_but_got_used = locate() in range(1, chosen_location)

View File

@@ -167,7 +167,7 @@
var/list/trait_list = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE)
/datum/eldritch_knowledge/final/ash_final/on_finished_recipe(mob/living/user, list/atoms, loc)
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the blaze, for the Ashlord, [user.real_name] has ascended! The flames shall consume all! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/ai/spanomalies.ogg')
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the blaze, for the Ashlord, [user.real_name] has ascended! The flames shall consume all! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/fire_cascade/big)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/fire_sworn)
var/mob/living/carbon/human/H = user

View File

@@ -222,7 +222,7 @@
/datum/eldritch_knowledge/final/flesh_final/on_finished_recipe(mob/living/user, list/atoms, loc)
. = ..()
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Ever coiling vortex. Reality unfolded. THE LORD OF ARMS, [user.real_name] has ascended! Fear the ever twisting hand! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/ai/spanomalies.ogg')
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Ever coiling vortex. Reality unfolded. THE LORD OF ARMS, [user.real_name] has ascended! Fear the ever twisting hand! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES)
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shed_human_form)
if(!ishuman(user))
return

View File

@@ -142,7 +142,7 @@
H.physiology.brute_mod *= 0.5
H.physiology.burn_mod *= 0.5
H.client?.give_award(/datum/award/achievement/misc/rust_ascension, H)
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/ai/spanomalies.ogg')
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# Fear the decay, for the Rustbringer, [user.real_name] has ascended! None shall escape the corrosion! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES)
new /datum/rust_spread(loc)
return ..()

View File

@@ -166,7 +166,7 @@
H.physiology.burn_mod *= 0.5
ADD_TRAIT(H, TRAIT_RESISTLOWPRESSURE, MAGIC_TRAIT)
H.client?.give_award(/datum/award/achievement/misc/void_ascension, H)
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", 'sound/ai/spanomalies.ogg')
priority_announce("$^@&#*$^@(#&$(@&#^$&#^@# The nobleman of void [H.real_name] has arrived, step along the Waltz that ends worlds! $^@&#*$^@(#&$(@&#^$&#^@#","#$^@&#*$^@(#&$(@&#^$&#^@#", ANNOUNCER_SPANOMALIES)
sound_loop = new(list(user),TRUE,TRUE)
return ..()

View File

@@ -50,7 +50,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
if(!check_allowed(user) || !war_declaration)
return
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg')
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE)
to_chat(user, "You've attracted the attention of powerful forces within the syndicate. A bonus bundle of telecrystals has been granted to your team. Great things await you if you complete the mission.")
@@ -86,7 +86,7 @@ GLOBAL_LIST_EMPTY(jam_on_wardec)
to_chat(usr, "<span class='warning'>Invalid war declaration.</span>")
return
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg')
priority_announce(war_declaration, title = "Declaration of War", sound = 'sound/machines/alarm.ogg', has_important_message = TRUE)
for(var/V in GLOB.syndicate_shuttle_boards)
var/obj/item/circuitboard/computer/syndicate_shuttle/board = V

View File

@@ -400,7 +400,7 @@
rev_head_body.makeUncloneable()
priority_announce("It appears the mutiny has been quelled. Please return yourself and your incapacitated colleagues to work. \
We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
We have remotely blacklisted the head revolutionaries in your medical records to prevent accidental revival.", null, null, null, "Central Command Loyalty Monitoring Division")
else
for (var/_player in GLOB.player_list)
var/mob/player = _player
@@ -436,7 +436,7 @@
priority_announce("A recent assessment of your station has marked your station as a severe risk area for high ranking Nanotrasen officials. \
For the safety of our staff, we have blacklisted your station for new employment of security and command. \
[pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, 'sound/ai/attention.ogg', null, "Central Command Loyalty Monitoring Division")
[pick(world.file2list("strings/anti_union_propaganda.txt"))]", null, null, null, "Central Command Loyalty Monitoring Division")
/// Mutates the ticker to report that the revs have won
/datum/team/revolution/proc/round_result(finished)

View File

@@ -243,7 +243,7 @@ GLOBAL_LIST_INIT(malf_modules, subtypesof(/datum/ai_module))
if(!owner || QDELETED(owner))
return
if (owner_AI.stat != DEAD)
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", ANNOUNCER_AIMALF)
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE

View File

@@ -241,7 +241,7 @@
if (.)
power_fail(35, 50)
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", ANNOUNCER_POWEROFF)
// Subtract cost, and spawn if it's an item.
/datum/contractor_item/proc/handle_purchase(datum/contractor_hub/hub, mob/living/user)

View File

@@ -134,7 +134,7 @@
D.adjust_money(-points_to_check)
priority_announce("One of your crew was captured by a rival organisation - we've needed to pay their ransom to bring them back. \
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, 'sound/ai/attention.ogg', null, "Nanotrasen Asset Protection")
As is policy we've taken a portion of the station's funds to offset the overall cost.", null, null, null, "Nanotrasen Asset Protection")
sleep(30)

View File

@@ -13,7 +13,7 @@
if(can_claim())
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
if(D)
D.adjust_money(reward)
D.adjust_money(reward * SSeconomy.bounty_modifier)
claimed = TRUE
/// If an item sent in the cargo shuttle can satisfy the bounty.

View File

@@ -88,7 +88,7 @@
continue // i'd be right happy to
meme_pack_data[P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name // If there is a description, use it. Otherwise use the pack's name.
))
@@ -185,7 +185,7 @@
if(D)
points_to_check = D.account_balance
if(!(obj_flags & EMAGGED))
if(SO.pack.cost <= points_to_check)
if(SO.pack.get_cost() <= points_to_check)
var/LZ
if (istype(beacon) && usingBeacon)//prioritize beacons over landing in cargobay
LZ = get_turf(beacon)
@@ -202,9 +202,9 @@
CHECK_TICK
if(empty_turfs?.len)
LZ = pick(empty_turfs)
if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
if (SO.pack.get_cost() <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
TIMER_COOLDOWN_START(src, COOLDOWN_EXPRESSPOD_CONSOLE, 5 SECONDS)
D.adjust_money(-SO.pack.cost)
D.adjust_money(-SO.pack.get_cost())
if(pack.special_pod)
new /obj/effect/pod_landingzone(LZ, pack.special_pod, SO)
else
@@ -212,7 +212,7 @@
. = TRUE
update_icon()
else
if(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^)
if(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^)
landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone
for(var/turf/open/floor/T in landingzone.contents)
if(T.is_blocked_turf())
@@ -221,7 +221,7 @@
CHECK_TICK
if(empty_turfs?.len)
TIMER_COOLDOWN_START(src, COOLDOWN_EXPRESSPOD_CONSOLE, 10 SECONDS)
D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)))
D.adjust_money(-(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS)))
SO.generateRequisition(get_turf(src))
for(var/i in 1 to MAX_EMAG_ROCKETS)

View File

@@ -99,7 +99,7 @@
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"cost" = SO.pack.get_cost(),
"id" = SO.id,
"orderer" = SO.orderer,
"paid" = !isnull(SO.paying_account) //paid by requester
@@ -109,7 +109,7 @@
for(var/datum/supply_order/SO in SSshuttle.requestlist)
data["requests"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"cost" = SO.pack.get_cost(),
"orderer" = SO.orderer,
"reason" = SO.reason,
"id" = SO.id
@@ -132,7 +132,7 @@
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,

View File

@@ -36,6 +36,10 @@
fill(C)
return C
/datum/supply_pack/proc/get_cost()
. = cost
. *= SSeconomy.pack_price_modifier
/datum/supply_pack/proc/fill(obj/structure/closet/crate/C)
if (admin_spawned)
for(var/item in contains)

View File

@@ -42,7 +42,7 @@
living_aliens = TRUE
if(living_aliens || fake)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS)
/datum/round_event/ghost_role/alien_infestation/spawn_role()

View File

@@ -20,7 +20,7 @@
fakeable = TRUE
/datum/round_event/ghost_role/blob/announce(fake)
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", ANNOUNCER_OUTBREAK5)
/datum/round_event/ghost_role/blob/spawn_role()
if(!GLOB.blobstart.len)

View File

@@ -6,6 +6,15 @@
earliest_start = 10 MINUTES
max_occurrences = 6
/datum/round_event_control/carp_migration/New()
. = ..()
if(!HAS_TRAIT(SSstation, STATION_TRAIT_CARP_INFESTATION))
return
weight *= 3
max_occurrences *= 2
earliest_start *= 0.5
/datum/round_event/carp_migration
announceWhen = 3
startWhen = 50

View File

@@ -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)

View File

@@ -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)

View File

@@ -23,7 +23,7 @@
/datum/round_event/ion_storm/announce(fake)
if(prob(announceChance) || fake)
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", ANNOUNCER_IONSTORM)
/datum/round_event/ion_storm/start()

View File

@@ -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)

View File

@@ -48,7 +48,7 @@
/datum/round_event/meteor_wave/announce(fake)
//priority_announce("Meteors have been detected on collision course with the station.", "Meteor Alert", 'sound/ai/meteors.ogg') //ORIGINAL
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.", "Meteor Alert", 'sound/ai/meteors.ogg') //ORIGINAL
priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round((startWhen * SSevents.wait) / 10, 0.1)] seconds.", "Meteor Alert", ANNOUNCER_METEORS) //ORIGINAL
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))

View File

@@ -27,7 +27,7 @@
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
/datum/round_event/pirates/announce(fake)
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", 'sound/ai/commandreport.ogg')
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
if(fake)
return
threat = new

View File

@@ -13,7 +13,7 @@
announceWhen = 1
/datum/round_event/radiation_storm/announce(fake)
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/ai/radiation.ogg')
priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", ANNOUNCER_RADIATION)
//sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()

View File

@@ -14,7 +14,7 @@
announceWhen = rand(announceWhen, announceWhen + 50)
/datum/round_event/spider_infestation/announce(fake)
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", ANNOUNCER_ALIENS)
/datum/round_event/spider_infestation/start()
create_midwife_eggs(spawncount)

View File

@@ -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)

View File

@@ -31,7 +31,7 @@ GLOBAL_LIST_EMPTY(all_wormholes) // So we can pick wormholes to teleport to
wormholes += new /obj/effect/portal/wormhole(T, 0, null, FALSE)
/datum/round_event/wormholes/announce(fake)
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", ANNOUNCER_SPANOMALIES)
/datum/round_event/wormholes/tick()
if(activeFor % shift_frequency == 0)

View File

@@ -1044,7 +1044,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("blob alert")
to_chat(target, "<h1 class='alert'>Biohazard Alert</h1>")
to_chat(target, "<br><br><span class='alert'>Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.</span><br><br>")
SEND_SOUND(target, 'sound/ai/outbreak5.ogg')
SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_OUTBREAK5])
if("ratvar")
target.playsound_local(target, 'sound/machines/clockcult/ark_deathrattle.ogg', 50, FALSE, pressure_affected = FALSE)
target.playsound_local(target, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE)
@@ -1063,15 +1063,15 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("shuttle dock")
to_chat(target, "<h1 class='alert'>Priority Announcement</h1>")
to_chat(target, "<br><br><span class='alert'>The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle.</span><br><br>")
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, "<h1 class='alert'>Anomaly Alert</h1>")
to_chat(target, "<br><br><span class='alert'>Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.</span><br><br>")
SEND_SOUND(target, 'sound/ai/aimalf.ogg')
SEND_SOUND(target, SSstation.announcer.event_sounds[ANNOUNCER_AIMALF])
if("meteors") //Meteors inbound!
to_chat(target, "<h1 class='alert'>Meteor Alert</h1>")
to_chat(target, "<br><br><span class='alert'>Meteors have been detected on collision course with the station.</span><br><br>")
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, "<span class='boldannounce'>You feel reality distort for a moment...</span>")

View File

@@ -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()

View File

@@ -89,6 +89,7 @@
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
//do actions on H but send messages to M as the key may not have been transferred_yet
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_SPAWN, src, H, M, latejoin)
if(mind_traits)
for(var/t in mind_traits)
ADD_TRAIT(H.mind, t, JOB_TRAIT)

View File

@@ -50,6 +50,12 @@
chameleon_extras = /obj/item/stamp/clown
/datum/outfit/job/clown/pre_equip(mob/living/carbon/human/H, visualsOnly)
. = ..()
if(HAS_TRAIT(SSstation, STATION_TRAIT_BANANIUM_SHIPMENTS))
backpack_contents[/obj/item/stack/sheet/mineral/bananium/five] = 1
/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(visualsOnly)

View File

@@ -437,11 +437,7 @@
if(age == 0)
var/turf/target = get_turf(loc)
if(target)
var/mob/living/simple_animal/pet/dog/corgi/puppy/P = new /mob/living/simple_animal/pet/dog/corgi/puppy(target)
P.name = "Ian"
P.real_name = "Ian"
P.gender = MALE
P.desc = "It's the HoP's beloved corgi puppy."
new /mob/living/simple_animal/pet/dog/corgi/puppy/ian(target)
Write_Memory(FALSE)
return INITIALIZE_HINT_QDEL
else if(age == record_age)
@@ -608,6 +604,13 @@
return
..()
//PUPPY IAN! SQUEEEEEEEEE~
/mob/living/simple_animal/pet/dog/corgi/puppy/ian
name = "Ian"
real_name = "Ian"
gender = MALE
desc = "It's the HoP's beloved corgi puppy."
/mob/living/simple_animal/pet/dog/corgi/puppy/void //Tribute to the corgis born in nullspace
name = "\improper void puppy"

View File

@@ -106,7 +106,7 @@
/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
. = ..()
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/runtime/hyperspace/hyperspace_begin.ogg', 'sound/runtime/hyperspace/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desecration-01.ogg', 'sound/misc/desecration-02.ogg', 'sound/misc/desecration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gun/pistol/shot_suppressed.ogg', 'sound/weapons/gun/pistol/shot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/runtime/hyperspace/hyperspace_begin.ogg', 'sound/runtime/hyperspace/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desecration-01.ogg', 'sound/misc/desecration-02.ogg', 'sound/misc/desecration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gun/pistol/shot_suppressed.ogg', 'sound/weapons/gun/pistol/shot.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/ambience/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/default/outbreak5.ogg', 'sound/ai/default/outbreak7.ogg', 'sound/ai/default/poweroff.ogg', 'sound/ai/default/radiation.ogg', 'sound/ai/default/shuttlecalled.ogg', 'sound/ai/default/shuttledock.ogg', 'sound/ai/default/shuttlerecalled.ogg', 'sound/ai/default/aimalf.ogg') //hahahaha fuck you code divers
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
..()

View File

@@ -627,7 +627,7 @@
if(charge_state < CHARGE_FINALWARNING && time_charged >= (max_charge * 0.5))
charge_state = CHARGE_FINALWARNING
var/area/A = get_area(src)
priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Spatial Corps", 'sound/ai/spanomalies.ogg')
priority_announce("A rift is causing an unnaturally large energy flux in [initial(A.name)]. Stop it at all costs!", "Central Command Spatial Corps", ANNOUNCER_SPANOMALIES)
/**
* Used to create carp controlled by ghosts when the option is available.

View File

@@ -90,7 +90,7 @@
continue
data["supplies"][P.group]["packs"] += list(list(
"name" = P.name,
"cost" = P.cost,
"cost" = P.get_cost(),
"id" = pack,
"desc" = P.desc || P.name, // If there is a description, use it. Otherwise use the pack's name.
"goody" = P.goody,
@@ -117,7 +117,7 @@
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
data["cart"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"cost" = SO.pack.get_cost(),
"id" = SO.id,
"orderer" = SO.orderer,
"paid" = !isnull(SO.paying_account) //paid by requester
@@ -127,7 +127,7 @@
for(var/datum/supply_order/SO in SSshuttle.requestlist)
data["requests"] += list(list(
"object" = SO.pack.name,
"cost" = SO.pack.cost,
"cost" = SO.pack.get_cost(),
"orderer" = SO.orderer,
"reason" = SO.reason,
"id" = SO.id

View File

@@ -347,7 +347,7 @@
//priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, 'sound/ai/shuttlecalled.ogg', "Priority") //ORIGINAL
//SKYRAT EDIT CHANGE BEGIN - AUTOTRANSFER
if(!silent)
priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, 'sound/ai/shuttlecalled.ogg', "Priority")
priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ][SSshuttle.adminEmergencyNoRecall ? "\n\nWarning: Shuttle recall subroutines disabled; Recall not possible." : ""]", null, ANNOUNCER_SHUTTLECALLED, "Priority")
//SKYRAT EDIT CHANGE END - AUTOTRANSFER
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
@@ -363,7 +363,7 @@
SSshuttle.emergencyLastCallLoc = signalOrigin
else
SSshuttle.emergencyLastCallLoc = null
priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlerecalled.ogg', "Priority")
priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, ANNOUNCER_SHUTTLERECALLED, "Priority")
SSticker.emergency_reason = null
@@ -452,7 +452,7 @@
mode = SHUTTLE_DOCKED
setTimer(SSshuttle.emergencyDockTime)
send2adminchat("Server", "The Emergency Shuttle has docked with the station.")
priority_announce("[SSshuttle.emergency] has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/ai/shuttledock.ogg', "Priority")
priority_announce("[SSshuttle.emergency] has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, ANNOUNCER_SHUTTLEDOCK, "Priority")
ShuttleDBStuff()

View File

@@ -110,7 +110,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
for(var/datum/supply_order/SO in SSshuttle.shoppinglist)
if(!empty_turfs.len)
break
var/price = SO.pack.cost
var/price = SO.pack.get_cost()
if(SO.applied_coupon)
price *= (1 - SO.applied_coupon.discount_pct_off)
@@ -138,8 +138,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
LAZYADD(goodies_by_buyer[SO.paying_account], SO)
D.bank_card_talk("Cargo order #[SO.id] has shipped. [price] credits have been charged to your bank account.")
var/datum/bank_account/department/cargo = SSeconomy.get_dep_account(ACCOUNT_CAR)
cargo.adjust_money(price - SO.pack.cost) //Cargo gets the handling fee
value += SO.pack.cost
cargo.adjust_money(price - SO.pack.get_cost()) //Cargo gets the handling fee
value += SO.pack.get_cost()
SSshuttle.shoppinglist -= SO
SSshuttle.orderhistory += SO
QDEL_NULL(SO.applied_coupon)
@@ -147,7 +147,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
if(!SO.pack.goody) //we handle goody crates below
SO.generate(pick_n_take(empty_turfs))
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.cost]", "[SO.pack.name]"))
SSblackbox.record_feedback("nested tally", "cargo_imports", 1, list("[SO.pack.get_cost()]", "[SO.pack.name]"))
investigate_log("Order #[SO.id] ([SO.pack.name], placed by [key_name(SO.orderer_ckey)]), paid by [D.account_holder] has shipped.", INVESTIGATE_CARGO)
if(SO.pack.dangerous)
message_admins("\A [SO.pack.name] ordered by [ADMIN_LOOKUPFLW(SO.orderer_ckey)], paid by [D.account_holder] has shipped.")

View File

@@ -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()

View File

@@ -4,7 +4,7 @@
/datum/controller/subsystem/shuttle/proc/autoEnd()
if(EMERGENCY_IDLE_OR_RECALLED)
SSshuttle.emergency.request(silent = TRUE)
priority_announce("The shift has come to an end and the shuttle called. [GLOB.security_level == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority")
priority_announce("The shift has come to an end and the shuttle called. [GLOB.security_level == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, ANNOUNCER_SHUTTLECALLED, "Priority")
log_game("Round end vote passed. Shuttle has been auto-called.")
message_admins("Round end vote passed. Shuttle has been auto-called.")
emergencyNoRecall = TRUE

Some files were not shown because too many files have changed in this diff Show More