Merge branch 'master' into dullahan-2-electric-boogaloo
This commit is contained in:
@@ -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 cause one to come to harm.")
|
||||
|
||||
@@ -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)
|
||||
@@ -0,0 +1,21 @@
|
||||
/datum/centcom_announcer/default
|
||||
welcome_sounds = list('sound/announcer/classic/welcome.ogg')
|
||||
alert_sounds = list('sound/announcer/classic/attention.ogg')
|
||||
command_report_sounds = list('sound/announcer/classic/commandreport.ogg')
|
||||
event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg',
|
||||
ANNOUNCER_ALIENS = 'sound/announcer/classic/aliens.ogg',
|
||||
ANNOUNCER_ANIMES = 'sound/announcer/classic/animes.ogg',
|
||||
ANNOUNCER_GRANOMALIES = 'sound/announcer/classic/granomalies.ogg',
|
||||
ANNOUNCER_INTERCEPT = 'sound/announcer/classic/intercept.ogg',
|
||||
ANNOUNCER_IONSTORM = 'sound/announcer/classic/ionstorm.ogg',
|
||||
ANNOUNCER_METEORS = 'sound/announcer/classic/meteors.ogg',
|
||||
ANNOUNCER_NEWAI = 'sound/announcer/classic/newai.ogg',
|
||||
ANNOUNCER_OUTBREAK5 = 'sound/announcer/classic/outbreak5.ogg',
|
||||
ANNOUNCER_OUTBREAK7 = 'sound/announcer/classic/outbreak7.ogg',
|
||||
ANNOUNCER_POWEROFF = 'sound/announcer/classic/poweroff.ogg',
|
||||
ANNOUNCER_POWERON = 'sound/announcer/classic/poweron.ogg',
|
||||
ANNOUNCER_RADIATION = 'sound/announcer/classic/radiation.ogg',
|
||||
ANNOUNCER_SHUTTLECALLED = 'sound/announcer/classic/shuttlecalled.ogg',
|
||||
ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/classic/shuttledock.ogg',
|
||||
ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/classic/shuttlerecalled.ogg',
|
||||
ANNOUNCER_SPANOMALIES = 'sound/announcer/classic/spanomalies.ogg')
|
||||
@@ -0,0 +1,47 @@
|
||||
/datum/centcom_announcer/intern
|
||||
welcome_sounds = list('sound/announcer/intern/welcome/1.ogg',
|
||||
'sound/announcer/intern/welcome/2.ogg',
|
||||
'sound/announcer/intern/welcome/3.ogg',
|
||||
'sound/announcer/intern/welcome/4.ogg',
|
||||
'sound/announcer/intern/welcome/5.ogg',
|
||||
'sound/announcer/intern/welcome/6.ogg')
|
||||
|
||||
alert_sounds = list('sound/announcer/intern/alerts/1.ogg',
|
||||
'sound/announcer/intern/alerts/2.ogg',
|
||||
'sound/announcer/intern/alerts/3.ogg',
|
||||
'sound/announcer/intern/alerts/4.ogg',
|
||||
'sound/announcer/intern/alerts/5.ogg',
|
||||
'sound/announcer/intern/alerts/6.ogg',
|
||||
'sound/announcer/intern/alerts/7.ogg',
|
||||
'sound/announcer/intern/alerts/8.ogg',
|
||||
'sound/announcer/intern/alerts/9.ogg',
|
||||
'sound/announcer/intern/alerts/10.ogg',
|
||||
'sound/announcer/intern/alerts/11.ogg',
|
||||
'sound/announcer/intern/alerts/12.ogg',
|
||||
'sound/announcer/intern/alerts/13.ogg',
|
||||
'sound/announcer/intern/alerts/14.ogg')
|
||||
|
||||
|
||||
command_report_sounds = list('sound/announcer/intern/commandreport/1.ogg',
|
||||
'sound/announcer/intern/commandreport/2.ogg',
|
||||
'sound/announcer/intern/commandreport/3.ogg')
|
||||
|
||||
event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg',
|
||||
ANNOUNCER_ALIENS = 'sound/announcer/intern/aliens.ogg',
|
||||
ANNOUNCER_ANIMES = 'sound/announcer/intern/animes.ogg',
|
||||
ANNOUNCER_GRANOMALIES = 'sound/announcer/intern/granomalies.ogg',
|
||||
ANNOUNCER_INTERCEPT = 'sound/announcer/intern/intercept.ogg',
|
||||
ANNOUNCER_IONSTORM = 'sound/announcer/intern/ionstorm.ogg',
|
||||
ANNOUNCER_METEORS = 'sound/announcer/intern/meteors.ogg',
|
||||
ANNOUNCER_NEWAI = 'sound/announcer/classic/newai.ogg',
|
||||
ANNOUNCER_OUTBREAK5 = 'sound/announcer/intern/outbreak5.ogg',
|
||||
ANNOUNCER_OUTBREAK7 = 'sound/announcer/intern/outbreak7.ogg',
|
||||
ANNOUNCER_POWEROFF = 'sound/announcer/intern/poweroff.ogg',
|
||||
ANNOUNCER_POWERON = 'sound/announcer/intern/poweron.ogg',
|
||||
ANNOUNCER_RADIATION = 'sound/announcer/intern/radiation.ogg',
|
||||
ANNOUNCER_SHUTTLECALLED = 'sound/announcer/intern/shuttlecalled.ogg',
|
||||
ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/intern/shuttledock.ogg',
|
||||
ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/intern/shuttlerecalled.ogg',
|
||||
ANNOUNCER_SPANOMALIES = 'sound/announcer/intern/spanomalies.ogg')
|
||||
|
||||
custom_alert_message = "<br><span class='alert'>Please stand by for an important message from our new intern.</span><br>"
|
||||
@@ -0,0 +1,22 @@
|
||||
/datum/centcom_announcer/medbot
|
||||
welcome_sounds = list('sound/announcer/medibot/welcome.ogg',
|
||||
'sound/announcer/medibot/newAI.ogg')
|
||||
alert_sounds = list('sound/announcer/medibot/attention.ogg')
|
||||
command_report_sounds = list('sound/announcer/medibot/commandreport.ogg')
|
||||
event_sounds = list(ANNOUNCER_AIMALF = 'sound/announcer/classic/aimalf.ogg',
|
||||
ANNOUNCER_ALIENS = 'sound/announcer/medibot/aliens.ogg',
|
||||
ANNOUNCER_ANIMES = 'sound/announcer/medibot/animes.ogg',
|
||||
ANNOUNCER_GRANOMALIES = 'sound/announcer/medibot/granomalies.ogg',
|
||||
ANNOUNCER_INTERCEPT = 'sound/announcer/medibot/intercept.ogg',
|
||||
ANNOUNCER_IONSTORM = 'sound/announcer/medibot/ionstorm.ogg',
|
||||
ANNOUNCER_METEORS = 'sound/announcer/medibot/meteors.ogg',
|
||||
ANNOUNCER_NEWAI = 'sound/announcer/medibot/newai.ogg',
|
||||
ANNOUNCER_OUTBREAK5 = 'sound/announcer/medibot/outbreak5.ogg',
|
||||
ANNOUNCER_OUTBREAK7 = 'sound/announcer/medibot/outbreak7.ogg',
|
||||
ANNOUNCER_POWEROFF = 'sound/announcer/medibot/poweroff.ogg',
|
||||
ANNOUNCER_POWERON = 'sound/announcer/medibot/poweron.ogg',
|
||||
ANNOUNCER_RADIATION = 'sound/announcer/medibot/radiation.ogg',
|
||||
ANNOUNCER_SHUTTLECALLED = 'sound/announcer/medibot/shuttlecalled.ogg',
|
||||
ANNOUNCER_SHUTTLEDOCK = 'sound/announcer/medibot/shuttledocked.ogg',
|
||||
ANNOUNCER_SHUTTLERECALLED = 'sound/announcer/medibot/shuttlerecalled.ogg',
|
||||
ANNOUNCER_SPANOMALIES = 'sound/announcer/medibot/spanomalies.ogg')
|
||||
@@ -24,6 +24,9 @@
|
||||
var/target_pressure = rand(minimum_pressure, maximum_pressure)
|
||||
var/pressure_scale = target_pressure / maximum_pressure
|
||||
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_UNNATURAL_ATMOSPHERE))
|
||||
restricted_chance = restricted_chance + 40
|
||||
|
||||
// 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
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
GAS_BZ=0.1,
|
||||
GAS_BROMINE=0.1
|
||||
)
|
||||
restricted_chance = 30
|
||||
|
||||
minimum_pressure = HAZARD_LOW_PRESSURE + 10
|
||||
maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1
|
||||
@@ -62,7 +61,7 @@
|
||||
GAS_METHYL_BROMIDE=0.1,
|
||||
GAS_HYDROGEN=0.1
|
||||
)
|
||||
restricted_chance = 10
|
||||
restricted_chance = 5
|
||||
|
||||
minimum_pressure = HAZARD_LOW_PRESSURE + 10
|
||||
maximum_pressure = LAVALAND_EQUIPMENT_EFFECT_PRESSURE - 1
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* A simple component that spawns a mob of the same type and transfers itself to it when parent dies.
|
||||
* For more complex behaviors, use the COMSIG_ON_MULTIPLE_LIVES_RESPAWN comsig.
|
||||
*/
|
||||
/datum/component/multiple_lives
|
||||
can_transfer = TRUE
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
/// The number of respawns the living mob has left.
|
||||
var/lives_left
|
||||
|
||||
/datum/component/multiple_lives/Initialize(lives_left)
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
|
||||
src.lives_left = lives_left
|
||||
|
||||
/datum/component/multiple_lives/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/respawn)
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/on_examine)
|
||||
|
||||
/datum/component/multiple_lives/UnregisterFromParent()
|
||||
UnregisterSignal(parent, list(COMSIG_MOB_DEATH, COMSIG_PARENT_EXAMINE))
|
||||
|
||||
/datum/component/multiple_lives/proc/respawn(mob/living/source, gibbed)
|
||||
SIGNAL_HANDLER
|
||||
if(source.suiciding) //Freed from this mortail coil.
|
||||
qdel(src)
|
||||
return
|
||||
var/mob/living/respawned_mob = new source.type (source.drop_location())
|
||||
source.mind?.transfer_to(respawned_mob)
|
||||
lives_left--
|
||||
if(lives_left <= 0)
|
||||
qdel(src)
|
||||
source.TransferComponents(respawned_mob)
|
||||
SEND_SIGNAL(source, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, respawned_mob, gibbed, lives_left)
|
||||
|
||||
/datum/component/multiple_lives/proc/on_examine(mob/living/source, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER
|
||||
if(isobserver(user) || source == user)
|
||||
examine_list += "[source.p_theyve(TRUE)] [lives_left] extra lives left."
|
||||
|
||||
/datum/component/multiple_lives/InheritComponent(datum/component/multiple_lives/new_comp , lives_left)
|
||||
src.lives_left += new_comp ? new_comp.lives_left : lives_left
|
||||
|
||||
/datum/component/multiple_lives/PostTransfer()
|
||||
if(!isliving(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
@@ -82,12 +82,14 @@
|
||||
var/move_delay = 2
|
||||
var/last_move = 0
|
||||
|
||||
/datum/component/twitch_plays/simple_movement/auto/Initialize(...)
|
||||
/datum/component/twitch_plays/simple_movement/auto/Initialize(move_delay)
|
||||
if(!ismovable(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
. = ..()
|
||||
if(. & COMPONENT_INCOMPATIBLE)
|
||||
return
|
||||
if(!isnull(move_delay))
|
||||
src.move_delay = move_delay
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/datum/component/twitch_plays/simple_movement/auto/Destroy(force, silent)
|
||||
@@ -95,10 +97,10 @@
|
||||
return ..()
|
||||
|
||||
/datum/component/twitch_plays/simple_movement/auto/process()
|
||||
if(world.time < (last_move + move_delay))
|
||||
return
|
||||
var/dir = fetch_data(null, TRUE)
|
||||
if(!dir)
|
||||
return
|
||||
if(world.time < (last_move + move_delay))
|
||||
return
|
||||
last_move = world.time
|
||||
step(parent, dir)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
///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
|
||||
///Whether this trait is always enabled; generally used for debugging
|
||||
var/force = FALSE
|
||||
///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
|
||||
///Extra flags for station traits such as it being abstract
|
||||
var/trait_flags
|
||||
/// Whether or not this trait can be reverted by an admin
|
||||
var/can_revert = TRUE
|
||||
|
||||
/datum/station_trait/New()
|
||||
. = ..()
|
||||
|
||||
RegisterSignal(SSticker, COMSIG_TICKER_ROUND_STARTING, .proc/on_round_start)
|
||||
|
||||
if(trait_processes)
|
||||
START_PROCESSING(SSstation, src)
|
||||
if(trait_to_give)
|
||||
ADD_TRAIT(SSstation, trait_to_give, STATION_TRAIT)
|
||||
|
||||
/datum/station_trait/Destroy()
|
||||
SSstation.station_traits -= src
|
||||
return ..()
|
||||
|
||||
/// Proc ran when round starts. Use this for roundstart effects.
|
||||
/datum/station_trait/proc/on_round_start()
|
||||
SIGNAL_HANDLER
|
||||
return
|
||||
|
||||
///type of info the centcom report has on this trait, if any.
|
||||
/datum/station_trait/proc/get_report()
|
||||
return "[name] - [report_message]"
|
||||
|
||||
/// Will attempt to revert the station trait, used by admins.
|
||||
/datum/station_trait/proc/revert()
|
||||
if (!can_revert)
|
||||
CRASH("revert() was called on [type], which can't be reverted!")
|
||||
|
||||
if (trait_to_give)
|
||||
REMOVE_TRAIT(SSstation, trait_to_give, STATION_TRAIT)
|
||||
|
||||
qdel(src)
|
||||
@@ -0,0 +1,133 @@
|
||||
/// Opens the station traits admin panel
|
||||
/datum/admins/proc/station_traits_panel()
|
||||
set name = "Modify Station Traits"
|
||||
set category = "Admin.Events"
|
||||
|
||||
var/static/datum/station_traits_panel/station_traits_panel = new
|
||||
station_traits_panel.ui_interact(usr)
|
||||
|
||||
/datum/station_traits_panel
|
||||
var/static/list/future_traits
|
||||
|
||||
/datum/station_traits_panel/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
data["too_late_to_revert"] = too_late_to_revert()
|
||||
|
||||
var/list/current_station_traits = list()
|
||||
for (var/datum/station_trait/station_trait as anything in SSstation.station_traits)
|
||||
current_station_traits += list(list(
|
||||
"name" = station_trait.name,
|
||||
"can_revert" = station_trait.can_revert,
|
||||
"ref" = REF(station_trait),
|
||||
))
|
||||
|
||||
data["current_traits"] = current_station_traits
|
||||
data["future_station_traits"] = future_traits
|
||||
|
||||
return data
|
||||
|
||||
/datum/station_traits_panel/ui_static_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/valid_station_traits = list()
|
||||
|
||||
for (var/datum/station_trait/station_trait_path as anything in subtypesof(/datum/station_trait))
|
||||
valid_station_traits += list(list(
|
||||
"name" = initial(station_trait_path.name),
|
||||
"path" = station_trait_path,
|
||||
))
|
||||
|
||||
data["valid_station_traits"] = valid_station_traits
|
||||
|
||||
return data
|
||||
|
||||
/datum/station_traits_panel/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
|
||||
. = ..()
|
||||
if (.)
|
||||
return
|
||||
|
||||
switch (action)
|
||||
if ("revert")
|
||||
var/ref = params["ref"]
|
||||
if (!ref)
|
||||
return TRUE
|
||||
|
||||
var/datum/station_trait/station_trait = locate(ref)
|
||||
|
||||
if (!istype(station_trait))
|
||||
return TRUE
|
||||
|
||||
if (too_late_to_revert())
|
||||
to_chat(usr, span_warning("It's too late to revert station traits, the round has already started!"))
|
||||
return TRUE
|
||||
|
||||
if (!station_trait.can_revert)
|
||||
stack_trace("[station_trait.type] can't be reverted, but was requested anyway.")
|
||||
return TRUE
|
||||
|
||||
var/message = "[key_name(usr)] reverted the station trait [station_trait.name] ([station_trait.type])"
|
||||
log_admin(message)
|
||||
message_admins(message)
|
||||
|
||||
station_trait.revert()
|
||||
|
||||
return TRUE
|
||||
if ("setup_future_traits")
|
||||
if (too_late_for_future_traits())
|
||||
to_chat(usr, span_warning("It's too late to add future station traits, the round is already over!"))
|
||||
return TRUE
|
||||
|
||||
var/list/new_future_traits = list()
|
||||
var/list/station_trait_names = list()
|
||||
|
||||
for (var/station_trait_text in params["station_traits"])
|
||||
var/datum/station_trait/station_trait_path = text2path(station_trait_text)
|
||||
if (!ispath(station_trait_path, /datum/station_trait) || station_trait_path == /datum/station_trait)
|
||||
log_admin("[key_name(usr)] tried to set an invalid future station trait: [station_trait_text]")
|
||||
to_chat(usr, span_warning("Invalid future station trait: [station_trait_text]"))
|
||||
return TRUE
|
||||
|
||||
station_trait_names += initial(station_trait_path.name)
|
||||
|
||||
new_future_traits += list(list(
|
||||
"name" = initial(station_trait_path.name),
|
||||
"path" = station_trait_path,
|
||||
))
|
||||
|
||||
var/message = "[key_name(usr)] has prepared the following station traits for next round: [station_trait_names.Join(", ") || "None"]"
|
||||
log_admin(message)
|
||||
message_admins(message)
|
||||
|
||||
future_traits = new_future_traits
|
||||
rustg_file_write(json_encode(params["station_traits"]), FUTURE_STATION_TRAITS_FILE)
|
||||
|
||||
return TRUE
|
||||
if ("clear_future_traits")
|
||||
if (!future_traits)
|
||||
to_chat(usr, span_warning("There are no future station traits."))
|
||||
return TRUE
|
||||
|
||||
var/message = "[key_name(usr)] has cleared the station traits for next round."
|
||||
log_admin(message)
|
||||
message_admins(message)
|
||||
|
||||
fdel(FUTURE_STATION_TRAITS_FILE)
|
||||
future_traits = null
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/station_traits_panel/proc/too_late_for_future_traits()
|
||||
return SSticker.current_state >= GAME_STATE_FINISHED
|
||||
|
||||
/datum/station_traits_panel/proc/too_late_to_revert()
|
||||
return SSticker.current_state >= GAME_STATE_PLAYING
|
||||
|
||||
/datum/station_traits_panel/ui_status(mob/user, datum/ui_state/state)
|
||||
return check_rights_for(user.client, R_FUN) ? UI_INTERACTIVE : UI_CLOSE
|
||||
|
||||
/datum/station_traits_panel/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "StationTraitsPanel")
|
||||
ui.open()
|
||||
@@ -0,0 +1,287 @@
|
||||
/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/hangover)
|
||||
|
||||
/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/hangover)
|
||||
|
||||
/datum/station_trait/hangover
|
||||
name = "Hangover"
|
||||
trait_type = STATION_TRAIT_NEGATIVE
|
||||
weight = 0
|
||||
show_in_report = TRUE
|
||||
report_message = "Ohh....Man....That mandatory office party from last shift...God that was awesome..I woke up in some random toilet 3 sectors away..."
|
||||
trait_to_give = STATION_TRAIT_HANGOVER
|
||||
blacklist = list(/datum/station_trait/late_arrivals, /datum/station_trait/random_spawns)
|
||||
|
||||
/datum/station_trait/hangover/New()
|
||||
. = ..()
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN, .proc/on_job_after_spawn)
|
||||
|
||||
/datum/station_trait/hangover/revert()
|
||||
for (var/obj/effect/landmark/start/hangover/hangover_spot in GLOB.start_landmarks_list)
|
||||
QDEL_LIST(hangover_spot.debris)
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/station_trait/hangover/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned_mob)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(prob(65)) // most aren't hungover
|
||||
return
|
||||
if(!iscarbon(spawned_mob)) // don't want silicons or similar to be counted here
|
||||
return
|
||||
if(HAS_TRAIT(spawned_mob, TRAIT_ROBOTIC_ORGANISM)) // robots can't get hungover
|
||||
return
|
||||
if(HAS_TRAIT(spawned_mob, TRAIT_TOXIC_ALCOHOL)) // people with alcohol intolerance also can't
|
||||
return
|
||||
var/obj/item/hat = pick(
|
||||
/obj/item/clothing/head/sombrero,
|
||||
/obj/item/clothing/head/fedora,
|
||||
/obj/item/clothing/mask/balaclava,
|
||||
/obj/item/clothing/head/ushanka,
|
||||
/obj/item/clothing/head/cardborg,
|
||||
/obj/item/clothing/head/pirate,
|
||||
/obj/item/clothing/head/cone,
|
||||
)
|
||||
hat = new hat(spawned_mob)
|
||||
spawned_mob.equip_to_slot_or_del(hat, ITEM_SLOT_HEAD)
|
||||
|
||||
|
||||
/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/obj/machinery/power/apc/apc as anything in GLOB.apcs_list)
|
||||
if(is_station_level(apc.z) && prob(60))
|
||||
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
|
||||
|
||||
// This station trait is checked when loot drops initialize, so it's too late
|
||||
can_revert = FALSE
|
||||
|
||||
/datum/station_trait/overflow_job_bureaucracy
|
||||
name = "Overflow bureaucracy mistake"
|
||||
trait_type = STATION_TRAIT_NEGATIVE
|
||||
weight = 4
|
||||
show_in_report = TRUE
|
||||
var/chosen_job_name
|
||||
|
||||
/datum/station_trait/overflow_job_bureaucracy/New()
|
||||
. = ..()
|
||||
RegisterSignal(SSjob, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/set_overflow_job_override)
|
||||
|
||||
/datum/station_trait/overflow_job_bureaucracy/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_name]s."
|
||||
|
||||
/datum/station_trait/overflow_job_bureaucracy/proc/set_overflow_job_override(datum/source)
|
||||
SIGNAL_HANDLER
|
||||
var/datum/job/picked_job = pick(get_all_jobs())
|
||||
chosen_job_name = lowertext(picked_job.title) // like Chief Engineers vs like chief engineers
|
||||
SSjob.set_overflow_role(picked_job.type)
|
||||
|
||||
/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()
|
||||
|
||||
/datum/station_trait/revenge_of_pun_pun
|
||||
name = "Revenge of Pun Pun"
|
||||
trait_type = STATION_TRAIT_NEGATIVE
|
||||
weight = 2
|
||||
|
||||
// Way too much is done on atoms SS to be reverted, and it'd look
|
||||
// kinda clunky on round start. It's not impossible to make this work,
|
||||
// but it's a project for...someone else.
|
||||
can_revert = FALSE
|
||||
|
||||
var/static/list/weapon_types
|
||||
|
||||
/datum/station_trait/revenge_of_pun_pun/New()
|
||||
if(!weapon_types)
|
||||
weapon_types = list(
|
||||
/obj/item/chair = 25,
|
||||
/obj/item/tailclub = 15,
|
||||
/obj/item/melee/baseball_bat = 10,
|
||||
/obj/item/melee/chainofcommand/tailwhip = 15,
|
||||
/obj/item/melee/chainofcommand/tailwhip/kitty = 15,
|
||||
/obj/item/reagent_containers/food/drinks/bottle = 25,
|
||||
/obj/item/gun/ballistic/automatic/pistol = 1,
|
||||
)
|
||||
|
||||
RegisterSignal(SSatoms, COMSIG_SUBSYSTEM_POST_INITIALIZE, .proc/arm_monke)
|
||||
|
||||
/datum/station_trait/revenge_of_pun_pun/proc/arm_monke()
|
||||
SIGNAL_HANDLER
|
||||
var/mob/living/carbon/monkey/punpun = locate()
|
||||
if(!punpun)
|
||||
return
|
||||
var/weapon_type = pickweight(weapon_types)
|
||||
var/obj/item/weapon = new weapon_type
|
||||
if(!punpun.put_in_l_hand(weapon) && !punpun.put_in_r_hand(weapon))
|
||||
// Guess they did all this with whatever they have in their hands already
|
||||
qdel(weapon)
|
||||
weapon = punpun.get_active_held_item() || punpun.get_inactive_held_item()
|
||||
|
||||
weapon?.add_mob_blood(punpun)
|
||||
punpun.add_mob_blood(punpun)
|
||||
|
||||
punpun.aggressive = TRUE
|
||||
|
||||
var/area/place = get_area(punpun)
|
||||
|
||||
var/list/area_open_turfs = list()
|
||||
for(var/turf/location in place)
|
||||
if(location.density)
|
||||
continue
|
||||
area_open_turfs += location
|
||||
|
||||
punpun.forceMove(pick(area_open_turfs))
|
||||
|
||||
for(var/i in 1 to rand(10, 40))
|
||||
new /obj/effect/decal/cleanable/blood(pick(area_open_turfs))
|
||||
|
||||
var/list/blood_path = list()
|
||||
for(var/i in 1 to 10) // Only 10 attempts
|
||||
var/turf/destination = pick(area_open_turfs)
|
||||
var/turf/next_step = get_step_to(punpun, destination)
|
||||
for(var/k in 1 to 30) // Max 30 steps
|
||||
if(!next_step)
|
||||
break
|
||||
blood_path += next_step
|
||||
next_step = get_step_to(next_step, destination)
|
||||
if(length(blood_path))
|
||||
break
|
||||
if(!length(blood_path))
|
||||
CRASH("Unable to make a path from punpun")
|
||||
|
||||
var/turf/last_location
|
||||
for(var/turf/location as anything in blood_path)
|
||||
last_location = location
|
||||
|
||||
if(prob(80))
|
||||
new /obj/effect/decal/cleanable/blood(location)
|
||||
|
||||
if(prob(50))
|
||||
var/static/blood_types = list(
|
||||
/obj/effect/decal/cleanable/blood/splatter,
|
||||
/obj/effect/decal/cleanable/blood/gibs,
|
||||
)
|
||||
var/blood_type = pick(blood_types)
|
||||
new blood_type(get_turf(pick(orange(location, 2))))
|
||||
|
||||
new /obj/effect/decal/cleanable/blood/gibs/torso(last_location)
|
||||
|
||||
// Abstract station trait used for traits that modify a random event in some way (their weight or max occurrences).
|
||||
/datum/station_trait/random_event_weight_modifier
|
||||
name = "Random Event Modifier"
|
||||
report_message = "A random event has been modified this shift! Someone forgot to set this!"
|
||||
show_in_report = TRUE
|
||||
trait_flags = STATION_TRAIT_ABSTRACT
|
||||
weight = 0
|
||||
|
||||
/// The path to the round_event_control that we modify.
|
||||
var/event_control_path
|
||||
/// Multiplier applied to the weight of the event.
|
||||
var/weight_multiplier = 1
|
||||
/// Flat modifier added to the amount of max occurances the random event can have.
|
||||
var/max_occurrences_modifier = 0
|
||||
|
||||
/datum/station_trait/random_event_weight_modifier/on_round_start()
|
||||
. = ..()
|
||||
var/datum/round_event_control/modified_event = locate(event_control_path) in SSevents.control
|
||||
if(!modified_event)
|
||||
CRASH("[type] could not find a round event controller to modify on round start (likely has an invalid event_control_path set)!")
|
||||
|
||||
modified_event.weight *= weight_multiplier
|
||||
modified_event.max_occurrences += max_occurrences_modifier
|
||||
|
||||
/datum/station_trait/random_event_weight_modifier/ion_storms
|
||||
name = "Ionic Stormfront"
|
||||
report_message = "An ionic stormfront is passing over your station's system. Expect an increased likelihood of ion storms afflicting your station's silicon units."
|
||||
trait_type = STATION_TRAIT_NEGATIVE
|
||||
trait_flags = NONE
|
||||
weight = 3
|
||||
event_control_path = /datum/round_event_control/ion_storm
|
||||
weight_multiplier = 2
|
||||
|
||||
/datum/station_trait/random_event_weight_modifier/rad_storms
|
||||
name = "Radiation Stormfront"
|
||||
report_message = "A radioactive stormfront is passing through your station's system. Expect an increased likelihood of radiation storms passing over your station, as well the potential for multiple radiation storms to occur during your shift."
|
||||
trait_type = STATION_TRAIT_NEGATIVE
|
||||
trait_flags = NONE
|
||||
weight = 2
|
||||
event_control_path = /datum/round_event_control/radiation_storm
|
||||
weight_multiplier = 1.5
|
||||
max_occurrences_modifier = 2
|
||||
@@ -0,0 +1,116 @@
|
||||
/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
|
||||
|
||||
// This station trait modifies the atmosphere, which is too far past the time admins are able to revert it
|
||||
can_revert = FALSE
|
||||
|
||||
/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)))
|
||||
continue
|
||||
|
||||
// Makes this station trait more interesting. Ian probably won't go anywhere without a little external help.
|
||||
// Also gives him a couple extra lives to survive eventual tiders.
|
||||
dog.AddComponent(/datum/component/twitch_plays/simple_movement/auto, 3 SECONDS)
|
||||
dog.AddComponent(/datum/component/multiple_lives, 2)
|
||||
RegisterSignal(dog, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, .proc/do_corgi_respawn)
|
||||
|
||||
// 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)
|
||||
|
||||
/// Moves the new dog somewhere safe, equips it with the old one's inventory and makes it deadchat_playable.
|
||||
/datum/station_trait/ian_adventure/proc/do_corgi_respawn(mob/living/simple_animal/pet/dog/corgi/old_dog, mob/living/simple_animal/pet/dog/corgi/new_dog, gibbed, lives_left)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/turf/current_turf = get_turf(new_dog)
|
||||
var/turf/adventure_turf = find_safe_turf(extended_safety_checks = TRUE, dense_atoms = FALSE)
|
||||
|
||||
do_smoke(location=current_turf)
|
||||
new_dog.forceMove(adventure_turf)
|
||||
do_smoke(location=adventure_turf)
|
||||
|
||||
if(old_dog.inventory_back)
|
||||
var/obj/item/old_dog_back = old_dog.inventory_back
|
||||
old_dog.inventory_back = null
|
||||
old_dog_back.forceMove(new_dog)
|
||||
new_dog.inventory_back = old_dog_back
|
||||
|
||||
if(old_dog.inventory_head)
|
||||
var/obj/item/old_dog_hat = old_dog.inventory_head
|
||||
old_dog.inventory_head = null
|
||||
new_dog.place_on_head(old_dog_hat)
|
||||
|
||||
new_dog.update_corgi_fluff()
|
||||
new_dog.regenerate_icons()
|
||||
new_dog.AddComponent(/datum/component/twitch_plays/simple_movement/auto, 3 SECONDS)
|
||||
if(lives_left)
|
||||
RegisterSignal(new_dog, COMSIG_ON_MULTIPLE_LIVES_RESPAWN, .proc/do_corgi_respawn)
|
||||
|
||||
if(!gibbed) //The old dog will now disappear so we won't have more than one Ian at a time.
|
||||
qdel(old_dog)
|
||||
|
||||
/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 maintanance 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
|
||||
@@ -0,0 +1,279 @@
|
||||
#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)
|
||||
if(prob(50))
|
||||
new /obj/item/reagent_containers/food/drinks/beer(toLaunch)
|
||||
else
|
||||
for(var/m in 1 to 2)
|
||||
var/obj/item/soda_to_spawn = pick(list(/obj/item/reagent_containers/food/drinks/soda_cans/sol_dry,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/space_up,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/starkist,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/cola,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/space_mountain_wind,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/dr_gibb,
|
||||
/obj/item/reagent_containers/food/drinks/soda_cans/pwr_game))
|
||||
new soda_to_spawn(toLaunch)
|
||||
new /obj/effect/pod_landingzone(T, toLaunch)
|
||||
|
||||
/datum/station_trait/galactic_grant
|
||||
name = "Galactic grant"
|
||||
trait_type = STATION_TRAIT_POSITIVE
|
||||
weight = 6
|
||||
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,
|
||||
)
|
||||
|
||||
scarves -= /obj/item/clothing/neck/scarf/zomb // donator snowflake code--mayhaps we should make a glob for this or similar
|
||||
|
||||
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/spawned, client/player_client)
|
||||
SIGNAL_HANDLER
|
||||
var/scarf_type = pick(scarves)
|
||||
|
||||
spawned.equip_to_slot_or_del(new scarf_type(spawned), 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
|
||||
|
||||
// This station trait is checked when loot drops initialize, so it's too late
|
||||
can_revert = FALSE
|
||||
|
||||
/datum/station_trait/quick_shuttle
|
||||
name = "Quick Shuttle"
|
||||
trait_type = STATION_TRAIT_POSITIVE
|
||||
weight = 6
|
||||
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
|
||||
|
||||
/datum/station_trait/deathrattle_department
|
||||
name = "deathrattled department"
|
||||
trait_type = STATION_TRAIT_POSITIVE
|
||||
show_in_report = TRUE
|
||||
trait_flags = STATION_TRAIT_ABSTRACT
|
||||
blacklist = list(/datum/station_trait/deathrattle_all)
|
||||
|
||||
var/department_head
|
||||
var/department_name = "department"
|
||||
var/datum/deathrattle_group/deathrattle_group
|
||||
|
||||
/datum/station_trait/deathrattle_department/New()
|
||||
. = ..()
|
||||
deathrattle_group = new("[department_name] group")
|
||||
blacklist += subtypesof(/datum/station_trait/deathrattle_department) - type //All but ourselves
|
||||
report_message = "All members of [department_name] have received an implant to notify each other if one of them dies. This should help improve job-safety!"
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn)
|
||||
|
||||
|
||||
/datum/station_trait/deathrattle_department/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
if(department_head != job.title && !(src.department_head in job.department_head))
|
||||
return
|
||||
|
||||
var/obj/item/implant/deathrattle/implant_to_give = new()
|
||||
deathrattle_group.register(implant_to_give)
|
||||
implant_to_give.implant(spawned, spawned, TRUE, TRUE)
|
||||
|
||||
|
||||
/datum/station_trait/deathrattle_department/service
|
||||
name = "Deathrattled Service"
|
||||
trait_flags = NONE
|
||||
weight = 1
|
||||
department_head = "Head of Personnel"
|
||||
department_name = "Service"
|
||||
|
||||
/datum/station_trait/deathrattle_department/cargo
|
||||
name = "Deathrattled Cargo"
|
||||
trait_flags = NONE
|
||||
weight = 2
|
||||
department_head = "Quartermaster"
|
||||
department_name = "Cargo"
|
||||
|
||||
/datum/station_trait/deathrattle_department/engineering
|
||||
name = "Deathrattled Engineering"
|
||||
trait_flags = NONE
|
||||
weight = 2
|
||||
department_head = "Chief Engineer"
|
||||
department_name = "Engineering"
|
||||
|
||||
/datum/station_trait/deathrattle_department/command
|
||||
name = "Deathrattled Command"
|
||||
trait_flags = NONE
|
||||
weight = 1
|
||||
department_head = "Captain"
|
||||
department_name = "Command"
|
||||
|
||||
/datum/station_trait/deathrattle_department/science
|
||||
name = "Deathrattled Science"
|
||||
trait_flags = NONE
|
||||
weight = 1
|
||||
department_head = "Research Director"
|
||||
department_name = "Science"
|
||||
|
||||
/datum/station_trait/deathrattle_department/security
|
||||
name = "Deathrattled Security"
|
||||
trait_flags = NONE
|
||||
weight = 1
|
||||
department_head = "Head of Security"
|
||||
department_name = "Security"
|
||||
|
||||
/datum/station_trait/deathrattle_department/medical
|
||||
name = "Deathrattled Medical"
|
||||
trait_flags = NONE
|
||||
weight = 1
|
||||
department_head = "Chief Medical Officer"
|
||||
department_name = "Medical"
|
||||
|
||||
/datum/station_trait/deathrattle_all
|
||||
name = "Deathrattled Station"
|
||||
trait_type = STATION_TRAIT_POSITIVE
|
||||
show_in_report = TRUE
|
||||
weight = 1
|
||||
report_message = "All members of the station have received an implant to notify each other if one of them dies. This should help improve job-safety!"
|
||||
var/datum/deathrattle_group/deathrattle_group
|
||||
|
||||
|
||||
/datum/station_trait/deathrattle_all/New()
|
||||
. = ..()
|
||||
deathrattle_group = new("station group")
|
||||
blacklist = subtypesof(/datum/station_trait/deathrattle_department)
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn)
|
||||
|
||||
|
||||
/datum/station_trait/deathrattle_all/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/spawned, client/player_client)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/obj/item/implant/deathrattle/implant_to_give = new()
|
||||
deathrattle_group.register(implant_to_give)
|
||||
implant_to_give.implant(spawned, spawned, TRUE, TRUE)
|
||||
|
||||
|
||||
/datum/station_trait/wallets
|
||||
name = "Wallets!"
|
||||
trait_type = STATION_TRAIT_POSITIVE
|
||||
show_in_report = TRUE
|
||||
weight = 10
|
||||
report_message = "It has become temporarily fashionable to use a wallet, so everyone on the station has been issued one."
|
||||
|
||||
/datum/station_trait/wallets/New()
|
||||
. = ..()
|
||||
RegisterSignal(SSdcs, COMSIG_GLOB_JOB_AFTER_SPAWN, .proc/on_job_after_spawn)
|
||||
|
||||
/datum/station_trait/wallets/proc/on_job_after_spawn(datum/source, datum/job/job, mob/living/living_mob, mob/M, joined_late)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/obj/item/card/id/id_card = living_mob.get_item_by_slot(ITEM_SLOT_ID)
|
||||
if(!istype(id_card))
|
||||
return
|
||||
|
||||
living_mob.temporarilyRemoveItemFromInventory(id_card, force=TRUE)
|
||||
|
||||
// "Doc, what's wrong with me?"
|
||||
var/obj/item/storage/wallet/wallet = new(src)
|
||||
// "You've got a wallet embedded in your chest."
|
||||
wallet.add_fingerprint(living_mob, ignoregloves = TRUE)
|
||||
|
||||
living_mob.equip_to_slot_if_possible(wallet, ITEM_SLOT_ID)
|
||||
|
||||
id_card.forceMove(wallet)
|
||||
|
||||
// Put our filthy fingerprints all over the contents
|
||||
for(var/obj/item/item in wallet)
|
||||
item.add_fingerprint(living_mob, ignoregloves = TRUE)
|
||||
Reference in New Issue
Block a user