mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2026-08-29 15:50:10 +01:00
Merge remote-tracking branch 'upstream/master' into cursed
This commit is contained in:
@@ -15,7 +15,9 @@
|
||||
#include "map_files\SpookyStation\SpookyStation.dmm"
|
||||
#include "map_files\CogStation\CogStation.dmm"
|
||||
#include "map_files\TauStation\TauStation.dmm"
|
||||
#include "map_files\SyndicateStation\SyndicateBoxStation.dmm"
|
||||
#include "splurt_maps\map_files\Smexistation\Snaxi_Splurt.dmm"
|
||||
#include "map_files\BoxedInStation\BoxedInStation.dmm"
|
||||
|
||||
#ifdef CIBUILDING
|
||||
#include "templates.dm"
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
#define FORCE_MAP "_maps/boxedinstation.json"
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"map_name": "Boxed In Station",
|
||||
"map_path": "map_files/BoxedInStation",
|
||||
"map_file": "BoxedInStation.dmm",
|
||||
"shuttles": {
|
||||
"cargo": "cargo_box",
|
||||
"ferry": "ferry_fancy",
|
||||
"whiteship": "whiteship_box",
|
||||
"emergency": "emergency_box"
|
||||
}
|
||||
}
|
||||
+18342
-18478
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
#define FORCE_MAP "_maps/syndicatestation.json"
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"map_name": "Syndicate Station",
|
||||
"map_path": "map_files/SyndicateStation",
|
||||
"map_file": "SyndicateBoxStation.dmm",
|
||||
"shuttles": {
|
||||
"cargo": "cargo_box",
|
||||
"ferry": "ferry_fancy",
|
||||
"whiteship": "whiteship_box",
|
||||
"emergency": "emergency_box"
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,12 @@
|
||||
#define COMSIG_GLOB_PLAY_CINEMATIC "!play_cinematic"
|
||||
#define COMPONENT_GLOB_BLOCK_CINEMATIC 1
|
||||
|
||||
/// job subsystem has spawned and equipped a new mob
|
||||
#define COMSIG_GLOB_JOB_AFTER_SPAWN "!job_after_spawn"
|
||||
|
||||
/// job datum has been called to deal with the aftermath of a latejoin spawn
|
||||
#define COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN "!job_after_latejoin_spawn"
|
||||
|
||||
#define COMSIG_GLOB_PRE_RANDOM_EVENT "!pre_random_event"
|
||||
/// Do not allow this random event to continue.
|
||||
#define CANCEL_PRE_RANDOM_EVENT (1<<0)
|
||||
@@ -671,3 +677,6 @@
|
||||
|
||||
// /datum/component/identification signals
|
||||
#define COMSIG_IDENTIFICATION_KNOWLEDGE_CHECK "id_knowledge_check" // (mob/user) - returns a value from ID_COMPONENT_KNOWLEDGE_NONE to ID_COMPONENT_KNOWLEDGE_FULL
|
||||
|
||||
///from base of [/datum/component/multiple_lives/proc/respawn]: (mob/respawned_mob, gibbed, lives_left)
|
||||
#define COMSIG_ON_MULTIPLE_LIVES_RESPAWN "on_multiple_lives_respawn"
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
#define EXOSUIT_MODULE_PHAZON (1<<6)
|
||||
/// Module is compatable with N models
|
||||
#define EXOSUIT_MODULE_GYGAX_MED (1<<7)
|
||||
/// Module is compatible with Savannah Exosuit models - SPLURT ADDITION
|
||||
#define EXOSUIT_MODULE_SAVANNAH (1<<8)
|
||||
|
||||
/// Module is compatible with "Working" Exosuit models - Ripley and Clarke
|
||||
#define EXOSUIT_MODULE_WORKING EXOSUIT_MODULE_RIPLEY | EXOSUIT_MODULE_FIREFIGHTER // | EXOSUIT_MODULE_CLARKE
|
||||
/// Module is compatible with "Combat" Exosuit models - Gygax, H.O.N.K, Durand and Phazon
|
||||
#define EXOSUIT_MODULE_COMBAT EXOSUIT_MODULE_GYGAX | EXOSUIT_MODULE_HONK | EXOSUIT_MODULE_DURAND | EXOSUIT_MODULE_PHAZON
|
||||
#define EXOSUIT_MODULE_COMBAT EXOSUIT_MODULE_GYGAX | EXOSUIT_MODULE_HONK | EXOSUIT_MODULE_DURAND | EXOSUIT_MODULE_PHAZON | EXOSUIT_MODULE_SAVANNAH
|
||||
/// Module is compatible with "Medical" Exosuit modelsm - Odysseus
|
||||
#define EXOSUIT_MODULE_MEDICAL EXOSUIT_MODULE_ODYSSEUS | EXOSUIT_MODULE_GYGAX_MED
|
||||
|
||||
@@ -154,3 +154,43 @@
|
||||
#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 "aimalf"
|
||||
#define ANNOUNCER_ALIENS "aliens"
|
||||
#define ANNOUNCER_ANIMES "animes"
|
||||
#define ANNOUNCER_GRANOMALIES "granomalies"
|
||||
#define ANNOUNCER_INTERCEPT "intercept"
|
||||
#define ANNOUNCER_IONSTORM "ionstorm"
|
||||
#define ANNOUNCER_METEORS "meteors"
|
||||
#define ANNOUNCER_NEWAI "newAI"
|
||||
#define ANNOUNCER_OUTBREAK5 "outbreak5"
|
||||
#define ANNOUNCER_OUTBREAK7 "outbreak7"
|
||||
#define ANNOUNCER_POWEROFF "poweroff"
|
||||
#define ANNOUNCER_POWERON "poweron"
|
||||
#define ANNOUNCER_RADIATION "radiation"
|
||||
#define ANNOUNCER_SHUTTLECALLED "shuttlecalled"
|
||||
#define ANNOUNCER_SHUTTLEDOCK "shuttledock"
|
||||
#define ANNOUNCER_SHUTTLERECALLED "shuttlerecalled"
|
||||
#define ANNOUNCER_SPANOMALIES "spanomalies"
|
||||
|
||||
/// Global list of all of our announcer keys.
|
||||
GLOBAL_LIST_INIT(announcer_keys, list(
|
||||
ANNOUNCER_AIMALF,
|
||||
ANNOUNCER_ALIENS,
|
||||
ANNOUNCER_ANIMES,
|
||||
ANNOUNCER_GRANOMALIES,
|
||||
ANNOUNCER_INTERCEPT,
|
||||
ANNOUNCER_IONSTORM,
|
||||
ANNOUNCER_METEORS,
|
||||
ANNOUNCER_NEWAI,
|
||||
ANNOUNCER_OUTBREAK5,
|
||||
ANNOUNCER_OUTBREAK7,
|
||||
ANNOUNCER_POWEROFF,
|
||||
ANNOUNCER_POWERON,
|
||||
ANNOUNCER_RADIATION,
|
||||
ANNOUNCER_SHUTTLECALLED,
|
||||
ANNOUNCER_SHUTTLEDOCK,
|
||||
ANNOUNCER_SHUTTLERECALLED,
|
||||
ANNOUNCER_SPANOMALIES,
|
||||
))
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#define STATION_TRAIT_POSITIVE 1
|
||||
#define STATION_TRAIT_NEUTRAL 2
|
||||
#define STATION_TRAIT_NEGATIVE 3
|
||||
|
||||
|
||||
#define STATION_TRAIT_ABSTRACT (1<<0)
|
||||
|
||||
/// The data file that future station traits are stored in
|
||||
#define FUTURE_STATION_TRAITS_FILE "data/future_station_traits.json"
|
||||
@@ -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
|
||||
|
||||
@@ -300,6 +300,7 @@
|
||||
#define GLOVE_TRAIT "glove" //inherited by your cool gloves
|
||||
#define BOOK_TRAIT "granter (book)" // knowledge is power
|
||||
#define TURF_TRAIT "turf"
|
||||
#define STATION_TRAIT "station-trait"
|
||||
|
||||
// unique trait sources, still defines
|
||||
#define STATUE_TRAIT "statue"
|
||||
@@ -363,3 +364,16 @@
|
||||
#define MAPPING_HELPER_TRAIT "mapping-helper"
|
||||
/// Trait associated with mafia
|
||||
#define MAFIA_TRAIT "mafia"
|
||||
|
||||
///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_HANGOVER "station_trait_hangover"
|
||||
#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"
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
locate(min(CENTER.x+(RADIUS),world.maxx), min(CENTER.y+(RADIUS),world.maxy), CENTER.z) \
|
||||
)
|
||||
|
||||
/// Returns either the error landmark or the location of the room. Needless to say, if this is used, it means things have gone awry.
|
||||
#define GET_ERROR_ROOM ((locate(/obj/effect/landmark/error) in GLOB.landmarks_list) || locate(4,4,1))
|
||||
|
||||
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
|
||||
#define CULT_POLL_WAIT 2400
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
var/announcement
|
||||
if(!sound)
|
||||
sound = "attention"
|
||||
sound = SSstation.announcer.get_rand_alert_sound()
|
||||
else if(SSstation.announcer.event_sounds[sound])
|
||||
sound = SSstation.announcer.event_sounds[sound]
|
||||
|
||||
if(type == "Priority")
|
||||
announcement += "<h1 class='alert'>Priority Announcement</h1>"
|
||||
@@ -29,110 +31,19 @@
|
||||
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_alert("[html_encode(text)]")]<br>"
|
||||
if(SSstation.announcer.custom_alert_message && !has_important_message)
|
||||
announcement += SSstation.announcer.custom_alert_message
|
||||
else
|
||||
announcement += "<br>[span_alert("[html_encode(text)]")]<br>"
|
||||
announcement += "<br>"
|
||||
|
||||
var/s = sound(get_announcer_sound(sound))
|
||||
var/s = sound(sound)
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(!isnewplayer(M) && M.can_hear())
|
||||
to_chat(M, announcement)
|
||||
if(M.client.prefs.toggles & SOUND_ANNOUNCEMENTS)
|
||||
SEND_SOUND(M, s)
|
||||
|
||||
/proc/get_announcer_sound(soundid)
|
||||
if(isfile(soundid))
|
||||
return soundid
|
||||
else if(!istext(soundid))
|
||||
CRASH("Invalid type passed to get_announcer_sound()")
|
||||
switch(GLOB.announcertype) //These are all individually hardcoded to allow the announcer sounds to be included in the rsc, reducing lag from sending resources midgame.
|
||||
if("classic")
|
||||
switch(soundid)
|
||||
if("aimalf")
|
||||
. = 'sound/announcer/classic/aimalf.ogg'
|
||||
if("aliens")
|
||||
. = 'sound/announcer/classic/aliens.ogg'
|
||||
if("animes")
|
||||
. = 'sound/announcer/classic/animes.ogg'
|
||||
if("attention")
|
||||
. = 'sound/announcer/classic/attention.ogg'
|
||||
if("commandreport")
|
||||
. = 'sound/announcer/classic/commandreport.ogg'
|
||||
if("granomalies")
|
||||
. = 'sound/announcer/classic/granomalies.ogg'
|
||||
if("intercept")
|
||||
. = 'sound/announcer/classic/intercept.ogg'
|
||||
if("ionstorm")
|
||||
. = 'sound/announcer/classic/ionstorm.ogg'
|
||||
if("meteors")
|
||||
. = 'sound/announcer/classic/meteors.ogg'
|
||||
if("newAI")
|
||||
. = 'sound/announcer/classic/newAI.ogg'
|
||||
if("outbreak5")
|
||||
. = 'sound/announcer/classic/outbreak5.ogg'
|
||||
if("outbreak7")
|
||||
. = 'sound/announcer/classic/outbreak7.ogg'
|
||||
if("poweroff")
|
||||
. = 'sound/announcer/classic/poweroff.ogg'
|
||||
if("poweron")
|
||||
. = 'sound/announcer/classic/poweron.ogg'
|
||||
if("radiation")
|
||||
. = 'sound/announcer/classic/radiation.ogg'
|
||||
if("shuttlecalled")
|
||||
. = 'sound/announcer/classic/shuttlecalled.ogg'
|
||||
if("shuttledock")
|
||||
. = 'sound/announcer/classic/shuttledock.ogg'
|
||||
if("shuttlerecalled")
|
||||
. = 'sound/announcer/classic/shuttlerecalled.ogg'
|
||||
if("spanomalies")
|
||||
. = 'sound/announcer/classic/spanomalies.ogg'
|
||||
if("welcome")
|
||||
. = 'sound/announcer/classic/welcome.ogg'
|
||||
if("medibot")
|
||||
switch(soundid)
|
||||
if("aimalf")
|
||||
. = 'sound/announcer/classic/aimalf.ogg'
|
||||
if("aliens")
|
||||
. = 'sound/announcer/medibot/aliens.ogg'
|
||||
if("animes")
|
||||
. = 'sound/announcer/medibot/animes.ogg'
|
||||
if("attention")
|
||||
. = 'sound/announcer/medibot/attention.ogg'
|
||||
if("commandreport")
|
||||
. = 'sound/announcer/medibot/commandreport.ogg'
|
||||
if("granomalies")
|
||||
. = 'sound/announcer/medibot/granomalies.ogg'
|
||||
if("intercept")
|
||||
. = 'sound/announcer/medibot/intercept.ogg'
|
||||
if("ionstorm")
|
||||
. = 'sound/announcer/medibot/ionstorm.ogg'
|
||||
if("meteors")
|
||||
. = 'sound/announcer/medibot/meteors.ogg'
|
||||
if("newAI")
|
||||
. = 'sound/announcer/medibot/newAI.ogg'
|
||||
if("outbreak5")
|
||||
. = 'sound/announcer/medibot/outbreak5.ogg'
|
||||
if("outbreak7")
|
||||
. = 'sound/announcer/medibot/outbreak7.ogg'
|
||||
if("poweroff")
|
||||
. = 'sound/announcer/medibot/poweroff.ogg'
|
||||
if("poweron")
|
||||
. = 'sound/announcer/medibot/poweron.ogg'
|
||||
if("radiation")
|
||||
. = 'sound/announcer/medibot/radiation.ogg'
|
||||
if("shuttlecalled")
|
||||
. = 'sound/announcer/medibot/shuttlecalled.ogg'
|
||||
if("shuttledock")
|
||||
. = 'sound/announcer/medibot/shuttledocked.ogg'
|
||||
if("shuttlerecalled")
|
||||
. = 'sound/announcer/medibot/shuttlerecalled.ogg'
|
||||
if("spanomalies")
|
||||
. = 'sound/announcer/medibot/spanomalies.ogg'
|
||||
if("welcome")
|
||||
. = 'sound/announcer/medibot/welcome.ogg'
|
||||
|
||||
/**
|
||||
* Summon the crew for an emergency meeting
|
||||
*
|
||||
@@ -170,7 +81,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", "commandreport", has_important_message = TRUE)
|
||||
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
|
||||
|
||||
@@ -8,3 +8,8 @@
|
||||
#define COOLDOWN_DOMINANT_SNAP "dominant_snap"
|
||||
#define COOLDOWN_DOMINANT_EXAMINE "dominant_examine"
|
||||
#define COOLDOWN_EMOTE_FART "emote_fart"
|
||||
|
||||
//Mecha cooldowns
|
||||
#define COOLDOWN_MECHA_SKYFALL "mecha_skyfall"
|
||||
#define COOLDOWN_MECHA_MISSILE_STRIKE "mecha_missile_strike"
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ GLOBAL_LIST_EMPTY(emergencyresponseteamspawn)
|
||||
GLOBAL_LIST_EMPTY(servant_spawns) //Servants of Ratvar spawn here
|
||||
GLOBAL_LIST_EMPTY(city_of_cogs_spawns) //Anyone entering the City of Cogs spawns here
|
||||
GLOBAL_LIST_EMPTY(ruin_landmarks)
|
||||
GLOBAL_LIST_EMPTY(bar_areas)
|
||||
|
||||
//away missions
|
||||
GLOBAL_LIST_EMPTY(vr_spawnpoints)
|
||||
|
||||
@@ -6,8 +6,6 @@ GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY"))
|
||||
GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
|
||||
|
||||
|
||||
GLOBAL_VAR_INIT(announcertype, "standard")
|
||||
|
||||
// For FTP requests. (i.e. downloading runtime logs.)
|
||||
// However it'd be ok to use for accessing attack logs and such too, which are even laggier.
|
||||
GLOBAL_VAR_INIT(fileaccess_timer, 0)
|
||||
|
||||
@@ -246,7 +246,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)
|
||||
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_boldannounce("[msg]"))
|
||||
|
||||
@@ -47,6 +47,10 @@ SUBSYSTEM_DEF(economy)
|
||||
"rainbow" = 1000)
|
||||
var/list/bank_accounts = list() //List of normal accounts (not department accounts)
|
||||
var/list/dep_cards = list()
|
||||
///The modifier multiplied to the value of bounties paid out.
|
||||
var/bounty_modifier = 1
|
||||
///The modifier multiplied to the value of cargo pack prices.
|
||||
var/pack_price_modifier = 1
|
||||
|
||||
/datum/controller/subsystem/economy/Initialize(timeofday)
|
||||
var/budget_to_hand_out = round(budget_pool / department_accounts.len)
|
||||
|
||||
@@ -434,20 +434,7 @@ SUBSYSTEM_DEF(job)
|
||||
|
||||
//If we joined at roundstart we should be positioned at our workstation
|
||||
if(!joined_late)
|
||||
var/obj/S = null
|
||||
for(var/obj/effect/landmark/start/sloc in GLOB.start_landmarks_list)
|
||||
if(!sloc.job_spawnpoint)
|
||||
continue
|
||||
if(sloc.name != rank)
|
||||
S = sloc //so we can revert to spawning them on top of eachother if something goes wrong
|
||||
continue
|
||||
if(locate(/mob/living) in sloc.loc)
|
||||
continue
|
||||
S = sloc
|
||||
sloc.used = TRUE
|
||||
break
|
||||
if(length(GLOB.jobspawn_overrides[rank]))
|
||||
S = pick(GLOB.jobspawn_overrides[rank])
|
||||
var/atom/S = job.get_roundstart_spawn_point(H)
|
||||
if(S)
|
||||
S.JoinPlayerHere(H, FALSE)
|
||||
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
|
||||
@@ -499,7 +486,7 @@ SUBSYSTEM_DEF(job)
|
||||
if(job && H)
|
||||
if(job.dresscodecompliant)// CIT CHANGE - dress code compliance
|
||||
equip_loadout(N, H) // CIT CHANGE - allows players to spawn with loadout items
|
||||
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
|
||||
job.after_spawn(H, M.client, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
|
||||
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
|
||||
|
||||
var/list/tcg_cards
|
||||
@@ -773,6 +760,35 @@ SUBSYSTEM_DEF(job)
|
||||
return FALSE
|
||||
job.current_positions = max(0, job.current_positions - 1)
|
||||
|
||||
/datum/controller/subsystem/job/proc/get_last_resort_spawn_points()
|
||||
//bad mojo
|
||||
var/area/shuttle/arrival/arrivals_area = GLOB.areas_by_type[/area/shuttle/arrival]
|
||||
if(arrivals_area)
|
||||
//first check if we can find a chair
|
||||
var/obj/structure/chair/shuttle_chair = locate() in arrivals_area
|
||||
if(shuttle_chair)
|
||||
return shuttle_chair
|
||||
|
||||
//last hurrah
|
||||
var/list/turf/available_turfs = list()
|
||||
for(var/turf/arrivals_turf in arrivals_area)
|
||||
if(!is_blocked_turf(arrivals_turf, TRUE))
|
||||
available_turfs += arrivals_turf
|
||||
if(length(available_turfs))
|
||||
return pick(available_turfs)
|
||||
|
||||
//pick an open spot on arrivals and dump em
|
||||
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
|
||||
if(length(arrivals_turfs))
|
||||
for(var/turf/arrivals_turf in arrivals_turfs)
|
||||
if(!is_blocked_turf(arrivals_turf, TRUE))
|
||||
return arrivals_turf
|
||||
//last chance, pick ANY spot on arrivals and dump em
|
||||
return pick(arrivals_turfs)
|
||||
|
||||
stack_trace("Unable to find last resort spawn point.")
|
||||
return GET_ERROR_ROOM
|
||||
|
||||
///////////////////////////////////
|
||||
//Keeps track of all living heads//
|
||||
///////////////////////////////////
|
||||
|
||||
@@ -81,7 +81,6 @@ SUBSYSTEM_DEF(mapping)
|
||||
to_chat(world, "<span class='boldannounce'>Unable to load next or default map config, defaulting to Box Station</span>")
|
||||
config = old_config
|
||||
GLOB.year_integer += config.year_offset
|
||||
GLOB.announcertype = (config.announcertype == "standard" ? (prob(1) ? "medibot" : "classic") : config.announcertype)
|
||||
initialize_biomes()
|
||||
loadWorld()
|
||||
repopulate_sorted_areas()
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
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()
|
||||
if (fexists(FUTURE_STATION_TRAITS_FILE))
|
||||
var/forced_traits_contents = file2text(FUTURE_STATION_TRAITS_FILE)
|
||||
fdel(FUTURE_STATION_TRAITS_FILE)
|
||||
|
||||
var/list/forced_traits_text_paths = json_decode(forced_traits_contents)
|
||||
forced_traits_text_paths = SANITIZE_LIST(forced_traits_text_paths)
|
||||
|
||||
for (var/trait_text_path in forced_traits_text_paths)
|
||||
var/station_trait_path = text2path(trait_text_path)
|
||||
if (!ispath(station_trait_path, /datum/station_trait) || station_trait_path == /datum/station_trait)
|
||||
var/message = "Invalid station trait path [station_trait_path] was requested in the future station traits!"
|
||||
log_game(message)
|
||||
message_admins(message)
|
||||
continue
|
||||
|
||||
setup_trait(station_trait_path)
|
||||
|
||||
return
|
||||
|
||||
for(var/i in subtypesof(/datum/station_trait))
|
||||
var/datum/station_trait/trait_typepath = i
|
||||
|
||||
// If forced, (probably debugging), just set it up now, keep it out of the pool.
|
||||
if(initial(trait_typepath.force))
|
||||
setup_trait(trait_typepath)
|
||||
continue
|
||||
|
||||
if(initial(trait_typepath.trait_flags) & STATION_TRAIT_ABSTRACT || initial(trait_typepath.weight) == 0)
|
||||
continue //Dont add abstract ones to it
|
||||
selectable_traits_by_types[initial(trait_typepath.trait_type)][trait_typepath] = initial(trait_typepath.weight)
|
||||
|
||||
var/positive_trait_count = pick(20;0, 5;1, 1;2)
|
||||
var/neutral_trait_count = pick(10;0, 10;1, 3;2)
|
||||
var/negative_trait_count = pick(20;0, 5;1, 1;2)
|
||||
can_fire = FALSE
|
||||
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_sign, amount)
|
||||
if(!amount)
|
||||
return
|
||||
for(var/iterator in 1 to amount)
|
||||
var/datum/station_trait/trait_type = pickweight(selectable_traits_by_types[trait_sign]) //Rolls from the table for the specific trait type
|
||||
setup_trait(trait_type)
|
||||
|
||||
///Creates a given trait of a specific type, while also removing any blacklisted ones from the future pool.
|
||||
/datum/controller/subsystem/processing/station/proc/setup_trait(datum/station_trait/trait_type)
|
||||
var/datum/station_trait/trait_instance = new trait_type()
|
||||
can_fire = can_fire || trait_instance.trait_processes
|
||||
station_traits += trait_instance
|
||||
if(!trait_instance.blacklist)
|
||||
return
|
||||
for(var/i in trait_instance.blacklist)
|
||||
var/datum/station_trait/trait_to_remove = i
|
||||
selectable_traits_by_types[initial(trait_to_remove.trait_type)] -= trait_to_remove
|
||||
@@ -308,7 +308,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(get_announcer_sound("welcome")))
|
||||
SEND_SOUND(world, sound(SSstation.announcer.get_rand_welcome_sound()))
|
||||
|
||||
current_state = GAME_STATE_PLAYING
|
||||
Master.SetRunLevel(RUNLEVEL_GAME)
|
||||
|
||||
@@ -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 crewmember 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)
|
||||
@@ -878,9 +878,9 @@ NOTE: there are two lists of areas in the end of this file: centcom and station
|
||||
nightshift_public_area = NIGHTSHIFT_AREA_RECREATION
|
||||
sound_environment = SOUND_AREA_WOODFLOOR
|
||||
|
||||
// /area/service/bar/Initialize(mapload)
|
||||
// . = ..()
|
||||
// GLOB.bar_areas += src
|
||||
/area/service/bar/Initialize(mapload)
|
||||
. = ..()
|
||||
GLOB.bar_areas += src
|
||||
|
||||
/area/service/bar/atrium
|
||||
name = "Atrium"
|
||||
|
||||
@@ -30,4 +30,4 @@
|
||||
/datum/game_mode/extended/announced/send_intercept(report = 0)
|
||||
if(flipseclevel) //CIT CHANGE - allows the sec level to be flipped roundstart
|
||||
return ..()
|
||||
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", "commandreport")
|
||||
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())
|
||||
|
||||
@@ -278,7 +278,7 @@
|
||||
|
||||
/datum/game_mode/proc/send_intercept()
|
||||
if(flipseclevel && !(config_tag == "extended"))//CIT CHANGE - lets the security level be flipped roundstart
|
||||
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", "commandreport")
|
||||
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())
|
||||
return
|
||||
var/intercepttext = "<b><i>Central Command Status Summary</i></b><hr>"
|
||||
intercepttext += "<b>Central Command has intercepted and partially decoded a Syndicate transmission with vital information regarding their movements. The following report outlines the most \
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
nuke_request(reason, usr)
|
||||
to_chat(usr, span_notice("Request sent."))
|
||||
usr.log_message("has requested the nuclear codes from CentCom with reason \"[reason]\"", LOG_SAY)
|
||||
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self-Destruct Codes Requested", "commandreport")
|
||||
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")
|
||||
|
||||
@@ -322,3 +322,9 @@
|
||||
|
||||
/obj/effect/particle_effect/smoke/transparent
|
||||
opaque = FALSE
|
||||
|
||||
/proc/do_smoke(range=0, location=null, smoke_type=/obj/effect/particle_effect/smoke)
|
||||
var/datum/effect_system/smoke_spread/smoke = new
|
||||
smoke.effect_type = smoke_type
|
||||
smoke.set_up(range, location)
|
||||
smoke.start()
|
||||
|
||||
@@ -528,3 +528,70 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
|
||||
name = "portal exit"
|
||||
icon_state = "portal_exit"
|
||||
var/id
|
||||
|
||||
/obj/effect/landmark/start/hangover
|
||||
name = "hangover spawn"
|
||||
icon_state = "hangover_spawn"
|
||||
|
||||
/// A list of everything this hangover spawn created
|
||||
var/list/debris = list()
|
||||
|
||||
/obj/effect/landmark/start/hangover/Initialize(mapload)
|
||||
. = ..()
|
||||
return INITIALIZE_HINT_LATELOAD
|
||||
|
||||
/obj/effect/landmark/start/hangover/Destroy()
|
||||
debris = null
|
||||
return ..()
|
||||
|
||||
/obj/effect/landmark/start/hangover/LateInitialize()
|
||||
. = ..()
|
||||
if(!HAS_TRAIT(SSstation, STATION_TRAIT_HANGOVER))
|
||||
return
|
||||
if(prob(60))
|
||||
debris += new /obj/effect/decal/cleanable/vomit(get_turf(src))
|
||||
if(prob(70))
|
||||
var/bottle_count = rand(1, 3)
|
||||
for(var/index in 1 to bottle_count)
|
||||
var/turf/turf_to_spawn_on = get_step(src, pick(GLOB.alldirs))
|
||||
if(!isopenturf(turf_to_spawn_on))
|
||||
continue
|
||||
var/dense_object = FALSE
|
||||
for(var/atom/content in turf_to_spawn_on.contents)
|
||||
if(content.density)
|
||||
dense_object = TRUE
|
||||
break
|
||||
if(dense_object)
|
||||
continue
|
||||
debris += new /obj/item/reagent_containers/food/drinks/beer/almost_empty(turf_to_spawn_on)
|
||||
|
||||
///Spawns the mob with some drugginess/drunkeness, and some disgust.
|
||||
/obj/effect/landmark/start/hangover/proc/make_hungover(mob/hangover_mob)
|
||||
if(!iscarbon(hangover_mob))
|
||||
return
|
||||
var/mob/living/carbon/spawned_carbon = hangover_mob
|
||||
spawned_carbon.set_resting(TRUE, silent = TRUE)
|
||||
if(prob(50))
|
||||
spawned_carbon.adjust_drugginess(rand(15, 20))
|
||||
else
|
||||
spawned_carbon.drunkenness += rand(15, 25)
|
||||
spawned_carbon.adjust_disgust(rand(5, 55)) //How hungover are you?
|
||||
if(spawned_carbon.head)
|
||||
return
|
||||
|
||||
/obj/effect/landmark/start/hangover/JoinPlayerHere(mob/joining_mob, buckle)
|
||||
. = ..()
|
||||
make_hungover(joining_mob)
|
||||
|
||||
/obj/effect/landmark/start/hangover/closet
|
||||
name = "hangover spawn closet"
|
||||
icon_state = "hangover_spawn_closet"
|
||||
|
||||
/obj/effect/landmark/start/hangover/closet/JoinPlayerHere(mob/joining_mob, buckle)
|
||||
make_hungover(joining_mob)
|
||||
for(var/obj/structure/closet/closet in contents)
|
||||
if(closet.opened)
|
||||
continue
|
||||
joining_mob.forceMove(closet)
|
||||
return
|
||||
return ..() //Call parent as fallback
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
icon = 'icons/effects/landmarks_static.dmi'
|
||||
icon_state = "random_loot"
|
||||
layer = OBJ_LAYER
|
||||
var/spawn_on_init = TRUE
|
||||
var/spawn_on_turf = TRUE
|
||||
var/lootcount = 1 //how many items will be spawned
|
||||
var/lootdoubles = TRUE //if the same item can be spawned twice
|
||||
@@ -10,10 +11,19 @@
|
||||
|
||||
/obj/effect/spawner/lootdrop/Initialize(mapload)
|
||||
..()
|
||||
if(should_spawn_on_init())
|
||||
spawn_loot()
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/spawner/lootdrop/proc/should_spawn_on_init()
|
||||
return spawn_on_init
|
||||
|
||||
/obj/effect/spawner/lootdrop/proc/spawn_loot(lootcount_override)
|
||||
var/lootcount = isnull(lootcount_override) ? src.lootcount : lootcount_override
|
||||
if(loot && loot.len)
|
||||
var/atom/A = spawn_on_turf ? get_turf(src) : loc
|
||||
var/loot_spawned = 0
|
||||
while((lootcount-loot_spawned) && loot.len)
|
||||
while((lootcount-loot_spawned) > 0 && loot.len)
|
||||
var/lootspawn = pickweight(loot)
|
||||
if(!lootdoubles)
|
||||
loot.Remove(lootspawn)
|
||||
@@ -29,7 +39,6 @@
|
||||
if (loot_spawned)
|
||||
spawned_loot.pixel_x = spawned_loot.pixel_y = ((!(loot_spawned%2)*loot_spawned/2)*-1)+((loot_spawned%2)*(loot_spawned+1)/2*1)
|
||||
loot_spawned++
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/spawner/lootdrop/bedsheet
|
||||
icon = 'icons/obj/bedsheets.dmi'
|
||||
@@ -162,6 +171,15 @@
|
||||
loot = GLOB.maintenance_loot
|
||||
. = ..()
|
||||
|
||||
/obj/effect/spawner/lootdrop/maintenance/spawn_loot(lootcount_override)
|
||||
if(isnull(lootcount_override))
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_FILLED_MAINT))
|
||||
lootcount_override = round(lootcount * 1.5)
|
||||
|
||||
else if(HAS_TRAIT(SSstation, STATION_TRAIT_EMPTY_MAINT))
|
||||
lootcount_override = round(lootcount * 0.5)
|
||||
. = ..()
|
||||
|
||||
/obj/effect/spawner/lootdrop/glowstick
|
||||
name = "random colored glowstick"
|
||||
icon = 'icons/obj/lighting.dmi'
|
||||
|
||||
@@ -563,4 +563,4 @@
|
||||
singular_name = "catwalk floor tile"
|
||||
desc = "Flooring that shows its contents underneath. Engineers love it!"
|
||||
icon_state = "catwalk_tile"
|
||||
turf_type = /turf/open/floor/plating/catwalk_floor
|
||||
turf_type = /turf/open/floor/catwalk_floor
|
||||
|
||||
@@ -123,6 +123,10 @@
|
||||
else
|
||||
new /obj/item/tank/internals/plasmaman/belt(src)
|
||||
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
|
||||
new /obj/item/flashlight/flare(src)
|
||||
new /obj/item/radio/off(src)
|
||||
|
||||
/obj/item/storage/box/survival/radio/PopulateContents()
|
||||
..() // we want the survival stuff too.
|
||||
new /obj/item/radio/off(src)
|
||||
@@ -777,6 +781,10 @@
|
||||
else
|
||||
new /obj/item/tank/internals/plasmaman/belt(src)
|
||||
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_PREMIUM_INTERNALS))
|
||||
new /obj/item/flashlight/flare(src)
|
||||
new /obj/item/radio/off(src)
|
||||
|
||||
/obj/item/storage/box/rubbershot
|
||||
name = "box of rubber shots"
|
||||
desc = "A box full of rubber shots, designed for riot shotguns."
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* you can crowbar it to interact with the underneath stuff without destroying the tile...
|
||||
* unless you want to!
|
||||
*/
|
||||
/turf/open/floor/plating/catwalk_floor
|
||||
/turf/open/floor/catwalk_floor
|
||||
icon = 'icons/turf/floors/catwalk_plating.dmi'
|
||||
icon_state = "catwalk_below"
|
||||
floor_tile = /obj/item/stack/tile/catwalk
|
||||
@@ -16,29 +16,35 @@
|
||||
barefootstep = FOOTSTEP_CATWALK
|
||||
clawfootstep = FOOTSTEP_CATWALK
|
||||
heavyfootstep = FOOTSTEP_CATWALK
|
||||
intact = FALSE
|
||||
var/covered = TRUE
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/Initialize(mapload)
|
||||
/turf/open/floor/catwalk_floor/Initialize(mapload)
|
||||
. = ..()
|
||||
layer = CATWALK_LAYER
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/update_overlays()
|
||||
/turf/open/floor/catwalk_floor/update_overlays()
|
||||
. = ..()
|
||||
var/static/catwalk_overlay
|
||||
var/static/image/catwalk_overlay
|
||||
if(isnull(catwalk_overlay))
|
||||
catwalk_overlay = iconstate2appearance(icon, "catwalk_above")
|
||||
catwalk_overlay = new()
|
||||
catwalk_overlay.icon = icon
|
||||
catwalk_overlay.icon_state = "catwalk_above"
|
||||
catwalk_overlay.plane = GAME_PLANE
|
||||
catwalk_overlay.layer = CATWALK_LAYER
|
||||
catwalk_overlay = catwalk_overlay.appearance
|
||||
if(covered)
|
||||
. += catwalk_overlay
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
/turf/open/floor/catwalk_floor/screwdriver_act(mob/living/user, obj/item/tool)
|
||||
. = ..()
|
||||
covered = !covered
|
||||
user.balloon_alert(user, "[!covered ? "cover removed" : "cover added"]")
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/turf/open/floor/plating/catwalk_floor/pry_tile(obj/item/crowbar, mob/user, silent)
|
||||
/turf/open/floor/catwalk_floor/crowbar_act(mob/user, obj/item/I)
|
||||
if(covered)
|
||||
user.balloon_alert(user, "remove cover first!")
|
||||
return FALSE
|
||||
. = ..()
|
||||
return pry_tile(I, user)
|
||||
|
||||
@@ -636,7 +636,7 @@
|
||||
SSticker.start_immediately = FALSE
|
||||
SSticker.SetTimeLeft(1800)
|
||||
to_chat(world, "<b>The game will start in 180 seconds.</b>")
|
||||
SEND_SOUND(world, sound(get_announcer_sound("attention")))
|
||||
SEND_SOUND(world, sound(SSstation.announcer.get_rand_alert_sound()))
|
||||
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
|
||||
@@ -719,7 +719,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(get_announcer_sound("attention")))
|
||||
SEND_SOUND(world, sound(SSstation.announcer.get_rand_alert_sound()))
|
||||
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!
|
||||
|
||||
|
||||
@@ -75,6 +75,7 @@ GLOBAL_PROTECT(admin_verbs_admin)
|
||||
/client/proc/toggle_combo_hud, // toggle display of the combination pizza antag and taco sci/med/eng hud
|
||||
/client/proc/toggle_AI_interact, /*toggle admin ability to interact with machines as an AI*/
|
||||
/datum/admins/proc/open_shuttlepanel, /* Opens shuttle manipulator UI */
|
||||
/datum/admins/proc/station_traits_panel, /* Opens station traits UI */
|
||||
/client/proc/deadchat,
|
||||
/client/proc/toggleprayers,
|
||||
// /client/proc/toggle_prayer_sound,
|
||||
|
||||
@@ -509,7 +509,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, "commandreport")
|
||||
priority_announce(input, null, SSstation.announcer.get_rand_report_sound())
|
||||
announce_command_report = FALSE
|
||||
if("Cancel")
|
||||
return
|
||||
|
||||
@@ -352,7 +352,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, "commandreport")
|
||||
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
|
||||
@@ -360,9 +360,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, "commandreport")
|
||||
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, "commandreport")
|
||||
priority_announce("The NAP has been revoked.", null, SSstation.announcer.get_rand_report_sound())
|
||||
if("blackout")
|
||||
if(!is_funmin)
|
||||
return
|
||||
@@ -528,7 +528,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(get_announcer_sound("animes")))
|
||||
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")
|
||||
|
||||
@@ -53,7 +53,7 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
|
||||
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.")
|
||||
|
||||
|
||||
@@ -135,12 +135,13 @@
|
||||
id = GAS_NITRIC
|
||||
specific_heat = 20
|
||||
name = "Nitric oxide"
|
||||
flags = GAS_FLAG_DANGEROUS
|
||||
odor = "sharp sweetness"
|
||||
odor_strength = 1
|
||||
fusion_power = 15
|
||||
enthalpy = 91290
|
||||
heat_resistance = 2
|
||||
powermix = -1
|
||||
heat_penalty = -1
|
||||
|
||||
/datum/gas/nitryl
|
||||
id = GAS_NITRYL
|
||||
|
||||
@@ -729,11 +729,11 @@
|
||||
/datum/gas_reaction/nitric_oxide/react(datum/gas_mixture/air, datum/holder)
|
||||
var/nitric = air.get_moles(GAS_NITRIC)
|
||||
var/oxygen = air.get_moles(GAS_O2)
|
||||
var/max_amount = max(nitric / 10, MINIMUM_MOLE_COUNT)
|
||||
var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles());
|
||||
var/max_amount = max(nitric / 8, MINIMUM_MOLE_COUNT)
|
||||
var/enthalpy = air.return_temperature() * (air.heat_capacity() + R_IDEAL_GAS_EQUATION * air.total_moles())
|
||||
var/list/enthalpies = GLOB.gas_data.enthalpies
|
||||
if(oxygen > MINIMUM_MOLE_COUNT)
|
||||
var/reaction_amount = min(max_amount, oxygen)
|
||||
var/reaction_amount = min(max_amount, oxygen)/4
|
||||
air.adjust_moles(GAS_NITRIC, -reaction_amount*2)
|
||||
air.adjust_moles(GAS_O2, -reaction_amount)
|
||||
air.adjust_moles(GAS_NITRYL, reaction_amount*2)
|
||||
|
||||
@@ -23,7 +23,7 @@ GLOBAL_LIST_EMPTY(bounties_list)
|
||||
if(can_claim())
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(D)
|
||||
D.adjust_money(reward)
|
||||
D.adjust_money(reward * SSeconomy.bounty_modifier)
|
||||
claimed = TRUE
|
||||
|
||||
// If an item sent in the cargo shuttle can satisfy the bounty.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -81,7 +81,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.
|
||||
))
|
||||
@@ -174,7 +174,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)
|
||||
@@ -191,13 +191,13 @@
|
||||
CHECK_TICK
|
||||
if(empty_turfs && empty_turfs.len)
|
||||
LZ = pick(empty_turfs)
|
||||
if (SO.pack.cost <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
|
||||
D.adjust_money(-SO.pack.cost)
|
||||
if (SO.pack.get_cost() <= points_to_check && LZ)//we need to call the cost check again because of the CHECK_TICK call
|
||||
D.adjust_money(-SO.pack.get_cost())
|
||||
new /obj/effect/pod_landingzone(LZ, podType, SO)
|
||||
. = 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(is_blocked_turf(T))
|
||||
@@ -205,7 +205,7 @@
|
||||
LAZYADD(empty_turfs, T)
|
||||
CHECK_TICK
|
||||
if(empty_turfs && empty_turfs.len)
|
||||
D.adjust_money(-(SO.pack.cost * (0.72*MAX_EMAG_ROCKETS)))
|
||||
D.adjust_money(-(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS)))
|
||||
|
||||
SO.generateRequisition(get_turf(src))
|
||||
for(var/i in 1 to MAX_EMAG_ROCKETS)
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
fill(C)
|
||||
return C
|
||||
|
||||
/datum/supply_pack/proc/get_cost()
|
||||
return cost * SSeconomy.pack_price_modifier
|
||||
|
||||
/datum/supply_pack/proc/fill(obj/structure/closet/crate/C)
|
||||
if (admin_spawned)
|
||||
for(var/item in contains)
|
||||
|
||||
@@ -340,6 +340,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
var/screenshake = 100
|
||||
var/damagescreenshake = 2
|
||||
var/recoil_screenshake = 100
|
||||
var/arousable = TRUE
|
||||
var/autostand = TRUE
|
||||
var/auto_ooc = FALSE
|
||||
@@ -1162,6 +1163,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Screen Shake:</b> <a href='?_src_=prefs;preference=screenshake'>[(screenshake==100) ? "Full" : ((screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
||||
if (user && user.client && !user.client.prefs.screenshake==0)
|
||||
dat += "<b>Damage Screen Shake:</b> <a href='?_src_=prefs;preference=damagescreenshake'>[(damagescreenshake==1) ? "On" : ((damagescreenshake==0) ? "Off" : "Only when down")]</a><br>"
|
||||
dat += "<b>Recoil Screen Push:</b> <a href='?_src_=prefs;preference=recoil_screenshake'>[(recoil_screenshake==100) ? "Full" : ((recoil_screenshake==0) ? "None" : "[screenshake]")]</a><br>"
|
||||
var/p_chaos
|
||||
if (!preferred_chaos)
|
||||
p_chaos = "No preference"
|
||||
@@ -3244,7 +3246,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("no_tetris_storage")
|
||||
no_tetris_storage = !no_tetris_storage
|
||||
if ("screenshake")
|
||||
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, 200 = maximum.)", "Character Preference", screenshake) as null|num
|
||||
var/desiredshake = input(user, "Set the amount of screenshake you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
||||
if (!isnull(desiredshake))
|
||||
screenshake = desiredshake
|
||||
if("damagescreenshake")
|
||||
@@ -3257,6 +3259,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
damagescreenshake = 0
|
||||
else
|
||||
damagescreenshake = 1
|
||||
if ("recoil_screenshake")
|
||||
var/desiredshake = input(user, "Set the amount of recoil screenshake/push you want. \n(0 = disabled, 100 = full, no maximum (at your own risk).)", "Character Preference", screenshake) as null|num
|
||||
if (!isnull(desiredshake))
|
||||
recoil_screenshake = desiredshake
|
||||
if("nameless")
|
||||
nameless = !nameless
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
earliest_start = 10 MINUTES
|
||||
max_occurrences = 6
|
||||
|
||||
/datum/round_event_control/carp_migration/New()
|
||||
. = ..()
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_CARP_INFESTATION))
|
||||
weight *= 3
|
||||
max_occurrences *= 2
|
||||
earliest_start *= 0.5
|
||||
|
||||
/datum/round_event/carp_migration
|
||||
announceWhen = 3
|
||||
startWhen = 50
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
// if(PIRATES_DUTCHMAN)
|
||||
// ship_name = "Flying Dutchman"
|
||||
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", "commandreport")
|
||||
priority_announce("Incoming subspace communication. Secure channel opened at all communication consoles.", "Incoming Message", SSstation.announcer.get_rand_report_sound())
|
||||
var/datum/bank_account/D = SSeconomy.get_dep_account(ACCOUNT_CAR)
|
||||
if(D)
|
||||
payoff = max(payoff_min, FLOOR(D.account_balance * 0.80, 1000))
|
||||
|
||||
@@ -889,7 +889,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, get_announcer_sound("outbreak5"))
|
||||
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)
|
||||
@@ -898,15 +898,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, get_announcer_sound("shuttledock"))
|
||||
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, get_announcer_sound("aimalf"))
|
||||
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'>[generateMeteorString(rand(60, 90),FALSE,pick(GLOB.cardinals))]</span><br><br>")
|
||||
SEND_SOUND(target, get_announcer_sound("meteors"))
|
||||
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>")
|
||||
|
||||
@@ -347,6 +347,9 @@
|
||||
foodtype = GRAIN | ALCOHOL
|
||||
custom_price = PRICE_PRETTY_CHEAP
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/beer/almost_empty
|
||||
list_reagents = list(/datum/reagent/consumable/ethanol/beer = 1)
|
||||
|
||||
/obj/item/reagent_containers/food/drinks/beer/light
|
||||
name = "Carp Lite"
|
||||
desc = "Brewed with \"Pure Ice Asteroid Spring Water\"."
|
||||
|
||||
@@ -66,6 +66,9 @@
|
||||
/// Should this job be allowed to be picked for the bureaucratic error event?
|
||||
var/allow_bureaucratic_error = TRUE
|
||||
|
||||
///Is this job affected by weird spawns like the ones from station traits
|
||||
var/random_spawns_possible = TRUE
|
||||
|
||||
var/display_order = JOB_DISPLAY_ORDER_DEFAULT
|
||||
|
||||
//If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack.
|
||||
@@ -109,14 +112,16 @@
|
||||
|
||||
//Only override this proc
|
||||
//H is usually a human unless an /equip override transformed it
|
||||
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
|
||||
/datum/job/proc/after_spawn(mob/living/spawned, client/player_client, latejoin = FALSE)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_SPAWN, src, spawned, player_client)
|
||||
//do actions on H but send messages to M as the key may not have been transferred_yet
|
||||
if(mind_traits)
|
||||
for(var/t in mind_traits)
|
||||
ADD_TRAIT(H.mind, t, JOB_TRAIT)
|
||||
ADD_TRAIT(spawned.mind, t, JOB_TRAIT)
|
||||
if(/datum/quirk/paraplegic in blacklisted_quirks)
|
||||
H.regenerate_limbs() //if you can't be a paraplegic, attempt to regenerate limbs to stop amputated limb selection
|
||||
H.set_resting(FALSE, TRUE) //they probably shouldn't be on the floor because they had no legs then suddenly had legs
|
||||
spawned.regenerate_limbs() //if you can't be a paraplegic, attempt to regenerate limbs to stop amputated limb selection
|
||||
spawned.set_resting(FALSE, TRUE) //they probably shouldn't be on the floor because they had no legs then suddenly had legs
|
||||
|
||||
/datum/job/proc/announce(mob/living/carbon/human/H)
|
||||
if(head_announce)
|
||||
@@ -333,3 +338,66 @@
|
||||
if(CONFIG_GET(flag/security_has_maint_access))
|
||||
return list(ACCESS_MAINT_TUNNELS)
|
||||
return list()
|
||||
|
||||
/// Handles finding and picking a valid roundstart effect landmark spawn point, in case no uncommon different spawning events occur.
|
||||
/datum/job/proc/get_default_roundstart_spawn_point()
|
||||
for(var/obj/effect/landmark/start/spawn_point as anything in GLOB.start_landmarks_list)
|
||||
if(spawn_point.name != title)
|
||||
continue
|
||||
. = spawn_point
|
||||
if(spawn_point.used) //so we can revert to spawning them on top of eachother if something goes wrong
|
||||
continue
|
||||
spawn_point.used = TRUE
|
||||
break
|
||||
if(!.)
|
||||
log_world("Couldn't find a round start spawn point for [title]")
|
||||
|
||||
/// Finds a valid latejoin spawn point, checking for events and special conditions.
|
||||
/datum/job/proc/get_latejoin_spawn_point()
|
||||
if(length(GLOB.jobspawn_overrides[title])) //We're doing something special today.
|
||||
return pick(GLOB.jobspawn_overrides[title])
|
||||
if(length(SSjob.latejoin_trackers))
|
||||
return pick(SSjob.latejoin_trackers)
|
||||
return SSjob.get_last_resort_spawn_points()
|
||||
|
||||
/// Returns an atom where the mob should spawn in.
|
||||
/datum/job/proc/get_roundstart_spawn_point(var/mob/M)
|
||||
if(random_spawns_possible)
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_LATE_ARRIVALS))
|
||||
return get_latejoin_spawn_point()
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_RANDOM_ARRIVALS))
|
||||
return get_safe_random_station_turf(typesof(/area/hallway)) || get_latejoin_spawn_point()
|
||||
if(HAS_TRAIT(SSstation, STATION_TRAIT_HANGOVER))
|
||||
if(!M || (!HAS_TRAIT(M, TRAIT_TOXIC_ALCOHOL) && !(HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE) && prob(70))))
|
||||
var/obj/effect/landmark/start/hangover_spawn_point
|
||||
for(var/obj/effect/landmark/start/hangover/hangover_landmark in GLOB.start_landmarks_list)
|
||||
hangover_spawn_point = hangover_landmark
|
||||
if(hangover_landmark.used) //so we can revert to spawning them on top of eachother if something goes wrong
|
||||
continue
|
||||
hangover_landmark.used = TRUE
|
||||
break
|
||||
return hangover_spawn_point || get_latejoin_spawn_point()
|
||||
if(length(GLOB.jobspawn_overrides[title]))
|
||||
return pick(GLOB.jobspawn_overrides[title])
|
||||
var/obj/effect/landmark/start/spawn_point = get_default_roundstart_spawn_point()
|
||||
if(!spawn_point) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
|
||||
return get_latejoin_spawn_point()
|
||||
return spawn_point
|
||||
|
||||
/**
|
||||
* Called after a successful roundstart spawn.
|
||||
* Client is not yet in the mob.
|
||||
* This happens after after_spawn()
|
||||
*/
|
||||
/datum/job/proc/after_roundstart_spawn(mob/living/spawning, client/player_client)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
|
||||
|
||||
/**
|
||||
* Called after a successful latejoin spawn.
|
||||
* Client is in the mob.
|
||||
* This happens after after_spawn()
|
||||
*/
|
||||
/datum/job/proc/after_latejoin_spawn(mob/living/spawning)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_JOB_AFTER_LATEJOIN_SPAWN, src, spawning)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
exp_type_department = EXP_TYPE_SILICON
|
||||
display_order = JOB_DISPLAY_ORDER_AI
|
||||
allow_bureaucratic_error = FALSE
|
||||
random_spawns_possible = FALSE
|
||||
var/do_special_check = TRUE
|
||||
threat = 5
|
||||
considered_combat_role = TRUE
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
exp_type = EXP_TYPE_COMMAND
|
||||
exp_type_department = EXP_TYPE_COMMAND
|
||||
considered_combat_role = TRUE
|
||||
custom_spawn_text = "<font color='red' size='4'><b> Do NOT rename the station something Sexual.</b></font>"
|
||||
|
||||
|
||||
outfit = /datum/outfit/job/captain
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_ENGINEERING
|
||||
considered_combat_role = TRUE
|
||||
custom_spawn_text = "<font color='red'>Do your best to keep the station fully powered, the lights on, and the hull's breaches repaired. Keep the atmosphere breathable and habitable for all Humans and Anthromorphs alike. If you don't know how to work the engine, the Solar Panels must be wired at a bare minimum. You are second in line to be Acting Captain.</font>"
|
||||
|
||||
outfit = /datum/outfit/job/ce
|
||||
plasma_outfit = /datum/outfit/plasmaman/ce
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_MEDICAL
|
||||
considered_combat_role = TRUE
|
||||
custom_spawn_text = "<font color='red'>Keep the Fridge stocked with Medicine. Have SOME competency at performing surgeries. Ensure that if a Virus breaks out, that you or the Virologist handles creating a vaccine. You are Fourth in line to be Acting Captain.</font>"
|
||||
|
||||
outfit = /datum/outfit/job/cmo
|
||||
plasma_outfit = /datum/outfit/plasmaman/cmo
|
||||
|
||||
|
||||
@@ -49,6 +49,11 @@
|
||||
|
||||
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] = 5
|
||||
|
||||
/datum/outfit/job/clown/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
|
||||
..()
|
||||
if(visualsOnly)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
exp_requirements = 120
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
|
||||
random_spawns_possible = FALSE
|
||||
starting_modifiers = list(/datum/skill_modifier/job/level/wiring/basic)
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_CYBORG
|
||||
@@ -22,8 +22,11 @@
|
||||
CRASH("dynamic preview is unsupported")
|
||||
return H.Robotize(FALSE, latejoin)
|
||||
|
||||
/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, mob/M)
|
||||
R.updatename(M.client)
|
||||
/datum/job/cyborg/after_spawn(mob/living/silicon/robot/R, client/player_client)
|
||||
. = ..()
|
||||
if(!istype(R))
|
||||
return
|
||||
R.updatename(player_client)
|
||||
R.gender = NEUTER
|
||||
|
||||
/datum/job/cyborg/radio_help_message(mob/M)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
considered_combat_role = TRUE
|
||||
outfit = /datum/outfit/job/hop
|
||||
plasma_outfit = /datum/outfit/plasmaman/hop
|
||||
custom_spawn_text = "<font color='red'> Head of Personnel: DO NOT LEAVE YOUR FUCKING ID CONSOLE SIGNED IN. Open and close Job Slots as necessary, ensure priority Jobs are marked for what is needed, and work within the other Departments to settle interpersonal disputes as a Liasion. ALWAYS ask other department heads before assigning crew to new jobs or granting access. Do not act as HoP-curity by chasing criminals outside of your Office. You are first in line to be Acting Captain.</font>"
|
||||
|
||||
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
|
||||
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
|
||||
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
exp_type_department = EXP_TYPE_SECURITY
|
||||
custom_spawn_text = "<font color='red'>Discipline Security Officers that are being Shitcurity. Grant Off-Duty to the Slutcurity on Green/Blue Alert. You may demote the Warden only with Central Command approval, however bad Security Officers should be taken with a Case-by-Case Basis, Demotions being the absolute final straw. By Default, the Detective is NOT a part of the Security Force, but may perform arrests. You are Seventh and Final in the True Chain of Command for a reason. Should the entire Chain of Command have been disposed or be non-existent, it falls to -you- to maintain any semblance of order. This doesn't mean 'Be a Tyrant', it means 'Do your Best'.</font>"
|
||||
|
||||
outfit = /datum/outfit/job/hos
|
||||
plasma_outfit = /datum/outfit/plasmaman/hos
|
||||
|
||||
@@ -7,13 +7,18 @@
|
||||
total_positions = 0
|
||||
spawn_positions = 0
|
||||
supervisors = "the security team"
|
||||
custom_spawn_text = "<font color='red' size='4'><b>If you join the shift as a Prisoner, you MUST go directly to Security to be allowed into the Permabrig, and you may NOT attempt a break out without ahelping unless your life is in immediate danger.</b></font>"
|
||||
random_spawns_possible = FALSE
|
||||
|
||||
outfit = /datum/outfit/job/prisoner
|
||||
plasma_outfit = /datum/outfit/plasmaman/prisoner
|
||||
|
||||
display_order = JOB_DISPLAY_ORDER_PRISONER
|
||||
|
||||
/datum/job/prisoner/get_latejoin_spawn_point()
|
||||
return get_roundstart_spawn_point()
|
||||
|
||||
/datum/job/prisoner/after_spawn(mob/living/carbon/human/H, mob/M)
|
||||
. = ..()
|
||||
var/list/policies = CONFIG_GET(keyed_list/policy)
|
||||
var/policy = policies[POLICYCONFIG_JOB_PRISONER]
|
||||
if(policy)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
exp_type = EXP_TYPE_CREW
|
||||
exp_type_department = EXP_TYPE_SUPPLY
|
||||
considered_combat_role = TRUE
|
||||
custom_spawn_text = "<font color='red'> No Cargonia without Admin Permission. Work with other departments to fulfill orders. Sell off excess amounts of metals and various empty crates as necessary. Keep track of your Shaft Miners by occasionally checking in with them via comms. Don't be stupid and try collecting taxes. You are fifth in line to be Acting Captain.</font>"
|
||||
|
||||
|
||||
outfit = /datum/outfit/job/quartermaster
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
exp_requirements = 180
|
||||
exp_type = EXP_TYPE_CREW
|
||||
considered_combat_role = TRUE
|
||||
custom_spawn_text = "<font color='red'> Allocate research points efficiently. Keep track of your Mechs, ensuring that any and all Combat Mechs do not leave the Robotics bay OR the Security Wing outside of Amber/Red Alert. Do Toxins if you're bored need points. Assist the station in performing upgrades. Don't let the slimes get loose from Xenobiology. You are third in line to be Acting Captain.</font>"
|
||||
|
||||
outfit = /datum/outfit/job/rd
|
||||
plasma_outfit = /datum/outfit/plasmaman/rd
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
|
||||
var/maptype = MAP_TYPE_STATION //This should be used to adjust ingame behavior depending on the specific type of map being played. For instance, if an overmap were added, it'd be appropriate for it to only generate with a MAP_TYPE_SHIP
|
||||
|
||||
var/announcertype = "standard" //Determines the announcer the map uses. standard uses the default announcer, classic, but has a random chance to use other similarly-themed announcers, like medibot
|
||||
|
||||
var/allow_custom_shuttles = TRUE
|
||||
var/shuttles = list(
|
||||
"cargo" = "cargo_box",
|
||||
@@ -178,9 +176,6 @@
|
||||
if ("maptype" in json)
|
||||
maptype = json["maptype"]
|
||||
|
||||
if ("announcertype" in json)
|
||||
announcertype = json["announcertype"]
|
||||
|
||||
if ("orientation" in json)
|
||||
orientation = json["orientation"]
|
||||
if(!(orientation in GLOB.cardinals))
|
||||
@@ -277,7 +272,6 @@
|
||||
jsonlist["year_offset"] = year_offset
|
||||
jsonlist["minetype"] = minetype
|
||||
jsonlist["maptype"] = maptype
|
||||
jsonlist["announcertype"] = announcertype
|
||||
jsonlist["orientation"] = orientation
|
||||
jsonlist["allow_custom_shuttles"] = allow_custom_shuttles
|
||||
jsonlist["job_whitelist"] = job_whitelist
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
|
||||
sharpness = SHARP_EDGED
|
||||
actions_types = list(/datum/action/item_action/toggle_light)
|
||||
obj_flags = UNIQUE_RENAME
|
||||
var/list/trophies = list()
|
||||
var/charged = TRUE
|
||||
var/charge_time = 15
|
||||
|
||||
@@ -473,12 +473,14 @@
|
||||
SSjob.AssignRole(src, rank, 1)
|
||||
|
||||
var/mob/living/character = create_character(TRUE) //creates the human and transfers vars and mind
|
||||
var/datum/job/job = SSjob.GetJob(rank)
|
||||
|
||||
var/equip = SSjob.EquipRank(character, rank, TRUE)
|
||||
job.after_latejoin_spawn(character)
|
||||
|
||||
if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob.
|
||||
character = equip
|
||||
|
||||
var/datum/job/job = SSjob.GetJob(rank)
|
||||
|
||||
if(job && !job.override_latejoin_spawn(character))
|
||||
SSjob.SendToLateJoin(character)
|
||||
if(!arrivals_docked)
|
||||
|
||||
@@ -836,13 +836,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/left_state = DEFAULT_LEFT_EYE_STATE
|
||||
var/right_state = DEFAULT_RIGHT_EYE_STATE
|
||||
if(eye_type in GLOB.eye_types)
|
||||
left_state = eye_type + "_left_eye"
|
||||
right_state = eye_type + "_right_eye"
|
||||
left_state = "[eye_type]_left_eye"
|
||||
right_state = "[eye_type]_right_eye"
|
||||
var/mutable_appearance/left_eye = mutable_appearance('icons/mob/eyes.dmi', left_state, -BODY_LAYER)
|
||||
var/mutable_appearance/right_eye = mutable_appearance('icons/mob/eyes.dmi', right_state, -BODY_LAYER)
|
||||
if((EYECOLOR in species_traits) && has_eyes)
|
||||
left_eye.color = "#" + H.left_eye_color
|
||||
right_eye.color = "#" + H.right_eye_color
|
||||
left_eye.color = "#[H.left_eye_color]"
|
||||
right_eye.color = "#[H.right_eye_color]"
|
||||
if(OFFSET_EYES in offset_features)
|
||||
left_eye.pixel_x += offset_features[OFFSET_EYES][1]
|
||||
left_eye.pixel_y += offset_features[OFFSET_EYES][2]
|
||||
|
||||
@@ -366,6 +366,8 @@ GLOBAL_LIST_INIT(strippable_corgi_items, create_strippable_list(list(
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff()
|
||||
// First, change back to defaults
|
||||
name = real_name
|
||||
|
||||
@@ -433,7 +433,7 @@ Difficulty: Very Hard
|
||||
H.dropItemToGround(W)
|
||||
var/datum/job/clown/C = new /datum/job/clown()
|
||||
C.equip(H)
|
||||
C.after_spawn(H, H, TRUE)
|
||||
C.after_spawn(H, H.client, TRUE)
|
||||
qdel(C)
|
||||
affected_targets.Add(H)
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -250,7 +250,17 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
animate(pixel_x=rand(min,max), pixel_y=rand(min,max), time=1)
|
||||
animate(pixel_x=oldx, pixel_y=oldy, time=1)
|
||||
|
||||
|
||||
/proc/directional_recoil(mob/M, strength=1, angle = 0)
|
||||
if(!M || !M.client)
|
||||
return
|
||||
var/client/C = M.client
|
||||
var/client_screenshake = (C.prefs.recoil_screenshake * 0.01)
|
||||
strength *= client_screenshake
|
||||
var/recoil_x = -sin(angle)*4*strength + rand(-strength, strength)
|
||||
var/recoil_y = -cos(angle)*4*strength + rand(-strength, strength)
|
||||
animate(C, pixel_x=recoil_x, pixel_y=recoil_y, time=1, easing=SINE_EASING|EASE_OUT, flags=ANIMATION_PARALLEL|ANIMATION_RELATIVE)
|
||||
animate(pixel_x=0, pixel_y=0, time=3, easing=SINE_EASING|EASE_IN) // according to bhjin this works on more recent byond versions
|
||||
// if you havent updated uuh sucks to be you then
|
||||
|
||||
/proc/findname(msg)
|
||||
if(!istext(msg))
|
||||
|
||||
@@ -104,7 +104,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,
|
||||
@@ -131,7 +131,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
|
||||
@@ -141,7 +141,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
|
||||
|
||||
@@ -15,40 +15,29 @@
|
||||
/// Radio connection datum used by signalers.
|
||||
var/datum/radio_frequency/radio_connection
|
||||
|
||||
/datum/computer_file/program/signaler/run_program(mob/living/user)
|
||||
. = ..()
|
||||
if (!.)
|
||||
return
|
||||
if(!computer?.get_modular_computer_part(MC_SIGNALER)) //Giving a clue to users why the program is spitting out zeros.
|
||||
to_chat(user, span_warning("\The [computer] flashes an error: \"hardware\\signal_hardware\\startup.bin -- file not found\"."))
|
||||
|
||||
/datum/computer_file/program/signaler/New()
|
||||
set_frequency(signal_frequency)
|
||||
return ..()
|
||||
|
||||
/datum/computer_file/program/signaler/ui_data(mob/user)
|
||||
var/list/data = get_header_data()
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(sensor?.check_functionality())
|
||||
data["frequency"] = signal_frequency
|
||||
data["code"] = signal_code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
data["maxFrequency"] = MAX_FREE_FREQ
|
||||
data["frequency"] = signal_frequency
|
||||
data["code"] = signal_code
|
||||
data["minFrequency"] = MIN_FREE_FREQ
|
||||
data["maxFrequency"] = MAX_FREE_FREQ
|
||||
return data
|
||||
|
||||
/datum/computer_file/program/signaler/ui_act(action, list/params)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/obj/item/computer_hardware/radio_card/sensor = computer?.get_modular_computer_part(MC_SIGNALER)
|
||||
if(!(sensor?.check_functionality()))
|
||||
playsound(src, 'sound/machines/scanbuzz.ogg', 100, FALSE)
|
||||
return
|
||||
switch(action)
|
||||
if("signal")
|
||||
INVOKE_ASYNC(src, .proc/signal)
|
||||
. = TRUE
|
||||
if("freq")
|
||||
signal_frequency = unformat_frequency(params["freq"])
|
||||
signal_frequency = sanitize_frequency(signal_frequency, TRUE)
|
||||
set_frequency(signal_frequency)
|
||||
var/new_signal_frequency = sanitize_frequency(unformat_frequency(params["freq"]), TRUE)
|
||||
set_frequency(new_signal_frequency)
|
||||
. = TRUE
|
||||
if("code")
|
||||
signal_code = text2num(params["code"])
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
SEND_SIGNAL(O, COMSIG_OBJ_WRITTEN_ON, O.name) //SPLURT EDIT - EGG NAMING
|
||||
|
||||
if(penchoice == "Change description")
|
||||
var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 140)
|
||||
var/input = stripped_input(user,"Describe [O] here:", ,"[O.desc]", 350)
|
||||
var/olddesc = O.desc
|
||||
if(QDELETED(O) || !user.canUseTopic(O, BE_CLOSE))
|
||||
return
|
||||
|
||||
@@ -94,6 +94,9 @@
|
||||
|
||||
var/automatic = 0 //can gun use it, 0 is no, anything above 0 is the delay between clicks in ds
|
||||
|
||||
/// directional recoil multiplier
|
||||
var/dir_recoil_amp = 10
|
||||
|
||||
/obj/item/gun/Initialize(mapload)
|
||||
. = ..()
|
||||
if(no_pin_required)
|
||||
@@ -159,7 +162,7 @@
|
||||
|
||||
/obj/item/gun/proc/shoot_live_shot(mob/living/user, pointblank = FALSE, mob/pbtarget, message = 1, stam_cost = 0)
|
||||
if(recoil)
|
||||
shake_camera(user, recoil + 1, recoil)
|
||||
directional_recoil(user, recoil*dir_recoil_amp, Get_Angle(user, pbtarget))
|
||||
|
||||
if(stam_cost) //CIT CHANGE - makes gun recoil cause staminaloss
|
||||
var/safe_cost = clamp(stam_cost, 0, user.stamina_buffer)*(firing && burst_size >= 2 ? 1/burst_size : 1)
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
icon_state = "goldrevolver"
|
||||
fire_sound = 'sound/weapons/resonator_blast.ogg'
|
||||
recoil = 8
|
||||
dir_recoil_amp = 5 // 40 directional recoil is already really funny
|
||||
pin = /obj/item/firing_pin
|
||||
|
||||
/obj/item/gun/ballistic/revolver/nagant
|
||||
|
||||
@@ -131,7 +131,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, 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)
|
||||
|
||||
@@ -163,8 +163,8 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, 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)
|
||||
@@ -172,7 +172,7 @@ GLOBAL_LIST_INIT(cargo_shuttle_leave_behind_typecache, typecacheof(list(
|
||||
if(!SO.pack.goody && !ispath(SO.pack.crate_type, /obj/structure/closet/secure_closet/cargo)) //we handle goody crates and material closets 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.")
|
||||
|
||||
@@ -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", "commandreport")
|
||||
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()
|
||||
|
||||
|
||||
@@ -169,7 +169,8 @@
|
||||
category_override += "H.O.N.K"
|
||||
if(mech_types & EXOSUIT_MODULE_PHAZON)
|
||||
category_override += "Phazon"
|
||||
|
||||
if(mech_types & EXOSUIT_MODULE_SAVANNAH)
|
||||
category_override += "Savannah-Ivanov"
|
||||
|
||||
var/list/part = list(
|
||||
"name" = D.name,
|
||||
|
||||
@@ -313,7 +313,6 @@
|
||||
desc="Phazon armor plates. They are layered with plasma to protect the pilot from the stress of phasing and have unusual properties."
|
||||
icon_state = "phazon_armor"
|
||||
|
||||
|
||||
///////// Circuitboards
|
||||
|
||||
/obj/item/circuitboard/mecha
|
||||
|
||||
@@ -326,6 +326,7 @@ ROUNDSTART_RACES shadekin
|
||||
ROUNDSTART_RACES undead_mammal
|
||||
ROUNDSTART_RACES undead_insect
|
||||
ROUNDSTART_RACES ghoul_lizard
|
||||
ROUNDSTART_RACES podweak
|
||||
|
||||
##-------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -68,3 +68,9 @@ endmap
|
||||
|
||||
map cogstation
|
||||
endmap
|
||||
|
||||
map syndicatestation
|
||||
endmap
|
||||
|
||||
map boxedinstation
|
||||
endmap
|
||||
|
||||
@@ -39,3 +39,49 @@
|
||||
- tweak: Dumb4cum no longer makes you a pacifist
|
||||
catrock31:
|
||||
- imageadd: added boner sprite for largest knotted cock
|
||||
2022-08-08:
|
||||
Hatterhat:
|
||||
- tweak: Proto-kinetic crushers and variants can now be renamed via pen.
|
||||
- tweak: Custom descriptions on items tagged with UNIQUE_RENAME can now go to 350
|
||||
characters, up from 140.
|
||||
- tweak: Recoil now pushes your screen in the opposite direction of where you're
|
||||
shooting. It makes sense in context, I swear. Adjust the setting for this in
|
||||
your client prefs, because it defaults to on.
|
||||
Linzolle:
|
||||
- bugfix: catwalk overlays behave properly, appearing on top of cables and such
|
||||
Putnam3145:
|
||||
- tweak: Various gases now have shortened names for filters
|
||||
- balance: Nitric oxide now removes from the power mix like nitrogen/pluoxium do
|
||||
- balance: Nitric oxide now becomes, at most, 20% nitrogen dioxide instead of 50%
|
||||
- rscadd: 'Adds station traits: Small modifiers that can randomly be chosen each
|
||||
round. They are usually logged in the intercept the station receives early in
|
||||
the round'
|
||||
- refactor: Announcement audio is now stored in a datum to make it easy to add different
|
||||
announcers
|
||||
SandPoot:
|
||||
- bugfix: Fixed the lack of eyes making ERROR appear on people.
|
||||
- qol: Set up for the dmi editor extension, very helpful as you can see the existant
|
||||
states and their names opposed to only images in a huge spritesheet.
|
||||
2022-08-09:
|
||||
Putnam3145:
|
||||
- rscadd: 'Adds station traits: Small modifiers that can randomly be chosen each
|
||||
round. They are usually logged in the intercept the station receives early in
|
||||
the round'
|
||||
- refactor: Announcement audio is now stored in a datum to make it easy to add different
|
||||
announcers
|
||||
2022-08-11:
|
||||
BongaTheProto:
|
||||
- rscadd: ported Savannah Ivanov from tg
|
||||
2022-08-14:
|
||||
BongaTheProto:
|
||||
- rscadd: Adds new donator lewd medipens with different rewards for each tier
|
||||
- tweak: Now social anxiety works like in tg
|
||||
- tweak: Now podpeople can have hair (you'll want to check your character species
|
||||
config if you're a pod person)
|
||||
- imageadd: Ports podpeople hairs from TG
|
||||
- imageadd: Adds a new binary cloak you can get from the autodrobe (Sprites credit
|
||||
to The Immovable Saint#0001)
|
||||
- soundadd: new *mewo emote
|
||||
- code_imp: changes our modular sprite accessory paths to avoid nulls and bugs in
|
||||
the character creation
|
||||
- code_imp: Fixes a typo in our modular file for underwear
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 78 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user