Bleeding edgy refresh (#303)

* not code stuff

* other things

* global vars, defines, helpers

* onclick hud stuff, orphans, world.dm

* controllers and datums

* game folder

* everything not client/mobs in modules

* client folder

* stage 1 mob stuff

* simple animal things

* silicons

* carbon things

* ayylmaos and monkeys

* hyoomahn

* icons n shit

* sprite fixes

* compile fixes

* some fixes I cherrypicked.

* qdel fixes

* forgot brain refractors
This commit is contained in:
Poojawa
2017-03-21 11:44:10 -05:00
committed by GitHub
parent 099a6c8764
commit f67e9f6d87
1476 changed files with 344416 additions and 40694 deletions
+2 -1
View File
@@ -15,8 +15,9 @@
#define DIAG_MECH_HUD "11"// Mech health bar
#define DIAG_BOT_HUD "12"// Bot HUDs
#define DIAG_TRACK_HUD "13"// Mech tracking beacon
#define DIAG_AIRLOCK_HUD "14"//Airlock shock overlay
//for antag huds. these are used at the /mob level
#define ANTAG_HUD "14"
#define ANTAG_HUD "15"
//data HUD (medhud, sechud) defines
//Don't forget to update human/New() if you change these!
+4 -1
View File
@@ -75,4 +75,7 @@
#define TICKET_UNREPLIED "No"
#define TICKET_INACTIVE "No"
#define TICKET_ACTIVE "Yes"
#define TICKET_ACTIVE "Yes"
//Individual logging define
#define INDIVIDUAL_LOOC_LOG "LOOC log"
+10 -1
View File
@@ -9,7 +9,6 @@
#define GIRDER_DISPLACED 3
#define GIRDER_DISASSEMBLED 4
//rwall construction states
#define INTACT 0
#define SUPPORT_LINES 1
@@ -19,6 +18,11 @@
#define SUPPORT_RODS 5
#define SHEATH 6
//window construction states
#define WINDOW_OUT_OF_FRAME 0
#define WINDOW_IN_FRAME 1
#define WINDOW_SCREWED_TO_FRAME 2
//plastic flaps construction states
#define PLASTIC_FLAPS_NORMAL 0
#define PLASTIC_FLAPS_DETACHED 1
@@ -103,3 +107,8 @@
#define CAT_SANDWICH "Sandwiches"
#define CAT_SOUP "Soups"
#define CAT_SPAGHETTI "Spaghettis"
#define RCD_FLOORWALL 1
#define RCD_AIRLOCK 2
#define RCD_DECONSTRUCT 3
#define RCD_WINDOWGRILLE 4
+4
View File
@@ -2,3 +2,7 @@
#define NOT_ENOUGH_PLAYERS 3
#define MAP_ERROR 4
#define WAITING_FOR_SOMETHING 5
#define EVENT_CANT_RUN 0
#define EVENT_READY 1
#define EVENT_CANCELLED 2
+20 -7
View File
@@ -12,24 +12,28 @@
#define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message in the default attackby()
#define MASKINTERNALS 8 // mask allows internals
#define HEAR 16 // This flag is what recursive_hear_check() uses to determine wether to add an item to the hearer list or not.
#define HANDSLOW 32 // If an item has this flag, it will slow you to carry it
#define CONDUCT 64 // conducts electricity (metal etc.)
#define ABSTRACT 128 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way
#define NODECONSTRUCT 128 // For machines and structures that should not break into parts, eg, holodeck stuff
#define OVERLAY_QUEUED 256 //atom queued to SSoverlay
#define ON_BORDER 512 // item has priority to check when entering or leaving
#define EARBANGPROTECT 1024
#define NOSLIP 1024 //prevents from slipping on wet floors, in space etc (NOTE: flag shared with THICKMATERIAL for external suits and helmet)
#define HEADBANGPROTECT 4096
#define NOSLIP 1024 //prevents from slipping on wet floors, in space etc
// BLOCK_GAS_SMOKE_EFFECT only used in masks at the moment.
#define BLOCK_GAS_SMOKE_EFFECT 8192 // blocks the effect that chemical clouds would have on a mob --glasses, mask and helmets ONLY! (NOTE: flag shared with THICKMATERIAL)
#define THICKMATERIAL 8192 //prevents syringes, parapens and hypos if the external suit or helmet (if targeting head) has this flag. Example: space suits, biosuit, bombsuits, thick suits that cover your body. (NOTE: flag shared with BLOCK_GAS_SMOKE_EFFECT)
#define DROPDEL 16384 // When dropped, it calls qdel on itself
#define HOLOGRAM 32768 // HOlodeck shit should not be used in any fucking things
/* Secondary atom flags, access using the SECONDARY_FLAG macros */
#define SLOWS_WHILE_IN_HAND "slows_while_in_hand"
#define NO_EMP_WIRES "no_emp_wires"
#define HOLOGRAM "hologram"
#define FROZEN "frozen"
#define STATIONLOVING "stationloving"
#define INFORM_ADMINS_ON_RELOCATE "inform_admins_on_relocate"
#define BANG_PROTECT "bang_protect"
//turf-only flags
#define NOJAUNT 1
@@ -71,3 +75,12 @@
// Flags for reagents
#define REAGENT_NOREACT 1
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF 1
#define FIRE_PROOF 2 //100% immune to fire damage (but not necessarily to lava or heat)
#define FLAMMABLE 4
#define ON_FIRE 8
#define UNACIDABLE 16 //acid can't even appear on it, let alone melt it.
#define ACID_PROOF 32 //acid stuck on it doesn't melt it.
#define INDESTRUCTIBLE 64 //doesn't take damage
+1 -1
View File
@@ -107,7 +107,7 @@
//Misc mobs
#define isobserver(A) (istype(A, /mob/dead/observer))
#define isnewplayer(A) (istype(A, /mob/new_player))
#define isnewplayer(A) (istype(A, /mob/dead/new_player))
#define isovermind(A) (istype(A, /mob/camera/blob))
+66 -14
View File
@@ -1,17 +1,69 @@
//Arbitrary lighting related stuff
//Bay lighting engine shit, not in /code/modules/lighting because BYOND is being shit about it
#define LIGHTING_INTERVAL 5 // frequency, in 1/10ths of a second, of the lighting process
#define LIGHTING_CIRCULAR 1 //Comment this out to use old square lighting effects.
#define LIGHTING_CAP 10 //The lumcount level at which alpha is 0 and we're fully lit.
#define LIGHTING_CAP_FRAC (255/LIGHTING_CAP) //A precal'd variable we'll use in turf/redraw_lighting()
#define LIGHTING_ICON 'icons/effects/alphacolors.dmi'
#define LIGHTING_ICON_STATE ""
#define LIGHTING_ANIMATE_TIME 2 //Time to animate() any lighting change. Actual number pulled out of my ass
#define LIGHTING_MIN_ALPHA_DELTA_TO_ANIMATE 20 //How much does the alpha have to change to warrent an animation.
#define LIGHTING_DARKEST_VISIBLE_ALPHA 250 //Anything darker than this is so dark, we'll just consider the whole tile unlit
#define LIGHTING_LUM_FOR_FULL_BRIGHT 6 //Anything who's lum is lower then this starts off less bright.
#define LIGHTING_MIN_RADIUS 4 //Lowest radius a light source can effect.
#define LIGHTING_FALLOFF 1 // type of falloff to use for lighting; 1 for circular, 2 for square
#define LIGHTING_LAMBERTIAN 0 // use lambertian shading for light sources
#define LIGHTING_HEIGHT 1 // height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone
#define LIGHTING_ROUND_VALUE 1 / 128 //Value used to round lumcounts, values smaller than 1/255 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY.
#define LIGHTING_ICON 'icons/effects/lighting_object.png' // icon used for lighting shading effects
//different modes that lights can operate in
#define LIGHTING_REGULAR 1 //Apply all effects additively
#define LIGHTING_STARLIGHT 2 //Track all starlight but only apply brightest
// If the max of the lighting lumcounts of each spectrum drops below this, disable luminosity on the lighting objects.
// Set to zero to disable soft lighting. Luminosity changes then work if it's lit at all.
#define LIGHTING_SOFT_THRESHOLD 0
// If I were you I'd leave this alone.
#define LIGHTING_BASE_MATRIX \
list \
( \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, LIGHTING_SOFT_THRESHOLD, 0, \
0, 0, 0, 1 \
) \
// Helpers so we can (more easily) control the colour matrices.
#define CL_MATRIX_RR 1
#define CL_MATRIX_RG 2
#define CL_MATRIX_RB 3
#define CL_MATRIX_RA 4
#define CL_MATRIX_GR 5
#define CL_MATRIX_GG 6
#define CL_MATRIX_GB 7
#define CL_MATRIX_GA 8
#define CL_MATRIX_BR 9
#define CL_MATRIX_BG 10
#define CL_MATRIX_BB 11
#define CL_MATRIX_BA 12
#define CL_MATRIX_AR 13
#define CL_MATRIX_AG 14
#define CL_MATRIX_AB 15
#define CL_MATRIX_AA 16
#define CL_MATRIX_CR 17
#define CL_MATRIX_CG 18
#define CL_MATRIX_CB 19
#define CL_MATRIX_CA 20
//Some defines to generalise colours used in lighting.
//Important note on colors. Colors can end up significantly different from the basic html picture, especially when saturated
#define LIGHT_COLOR_RED "#FA8282" //Warm but extremely diluted red. rgb(250, 130, 130)
#define LIGHT_COLOR_GREEN "#64C864" //Bright but quickly dissipating neon green. rgb(100, 200, 100)
#define LIGHT_COLOR_BLUE "#6496FA" //Cold, diluted blue. rgb(100, 150, 250)
#define LIGHT_COLOR_CYAN "#7DE1E1" //Diluted cyan. rgb(125, 225, 225)
#define LIGHT_COLOR_LIGHT_CYAN "#40CEFF" //More-saturated cyan. rgb(64, 206, 255)
#define LIGHT_COLOR_PINK "#E17DE1" //Diluted, mid-warmth pink. rgb(225, 125, 225)
#define LIGHT_COLOR_YELLOW "#E1E17D" //Dimmed yellow, leaning kaki. rgb(225, 225, 125)
#define LIGHT_COLOR_BROWN "#966432" //Clear brown, mostly dim. rgb(150, 100, 50)
#define LIGHT_COLOR_ORANGE "#FA9632" //Mostly pure orange. rgb(250, 150, 50)
#define LIGHT_COLOR_PURPLE "#952CF4" //Light Purple. rgb(149, 44, 244)
#define LIGHT_COLOR_LAVENDER "#9B51FF" //Less-saturated light purple. rgb(155, 81, 255)
//These ones aren't a direct colour like the ones above, because nothing would fit
#define LIGHT_COLOR_FIRE "#FAA019" //Warm orange color, leaning strongly towards yellow. rgb(250, 160, 25)
#define LIGHT_COLOR_LAVA "#C48A18" //Very warm yellow, leaning slightly towards orange. rgb(196, 138, 24)
#define LIGHT_COLOR_FLARE "#FA644B" //Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75)
#define LIGHT_COLOR_SLIME_LAMP "#AFC84B" //Weird color, between yellow and green, very slimy. rgb(175, 200, 75)
#define LIGHT_COLOR_TUNGSTEN "#FAE1AF" //Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175)
#define LIGHT_COLOR_HALOGEN "#F0FAFA" //Barely visible cyan-ish hue, as the doctor prescribed. rgb(240, 250, 250)
+44
View File
@@ -0,0 +1,44 @@
/*
The /tg/ codebase currently requires you to have 11 z-levels of the same size dimensions.
z-level order is important, the order you put them in inside the map config.dm will determine what z level number they are assigned ingame.
Names of z-level do not matter, but order does greatly, for instances such as checking alive status of revheads on z1
current as of 2016/6/2
z1 = station
z2 = centcomm
z5 = mining
Everything else = randomized space
Last space-z level = empty
*/
#define CROSSLINKED 2
#define SELFLOOPING 1
#define UNAFFECTED 0
#define MAIN_STATION "Main Station"
#define CENTCOMM "CentComm"
#define EMPTY_AREA_1 "Empty Area 1"
#define EMPTY_AREA_2 "Empty Area 2"
#define MINING "Mining Asteroid"
#define EMPTY_AREA_3 "Empty Area 3"
#define EMPTY_AREA_4 "Empty Area 4"
#define EMPTY_AREA_5 "Empty Area 5"
#define EMPTY_AREA_6 "Empty Area 6"
#define EMPTY_AREA_7 "Empty Area 7"
#define EMPTY_AREA_8 "Empty Area 8"
#define AWAY_MISSION "Away Mission"
//for modifying jobs
#define MAP_JOB_CHECK if(SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) { return; }
#define MAP_JOB_CHECK_BASE if(SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) { return ..(); }
#define MAP_REMOVE_JOB(jobpath) /datum/job/##jobpath/map_check() { return (SSmapping.config.map_name != JOB_MODIFICATION_MAP_NAME) && ..() }
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
#define ZLEVEL_STATION 1
#define ZLEVEL_CENTCOM 2
#define ZLEVEL_MINING 5
#define ZLEVEL_LAVALAND 5
#define ZLEVEL_EMPTY_SPACE 11
#define ZLEVEL_SPACEMIN 3
#define ZLEVEL_SPACEMAX 11
+1
View File
@@ -17,6 +17,7 @@
#define TICK_USAGE_TO_MS(starting_tickusage) (TICK_DELTA_TO_MS(world.tick_usage-starting_tickusage))
#define PERCENT(val) (round(val*100, 0.1))
#define CLAMP01(x) (Clamp(x, 0, 1))
//time of day but automatically adjusts to the server going into the next day within the same round.
//for when you need a reliable time number that doesn't depend on byond time.
+7 -25
View File
@@ -63,7 +63,7 @@
#define HANDS_LAYER 3
#define BODY_FRONT_LAYER 2
#define FIRE_LAYER 1 //If you're on fire
#define TOTAL_LAYERS 31 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
#define TOTAL_LAYERS 26 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
@@ -149,16 +149,6 @@
#define STAGE_FIVE 9
#define STAGE_SIX 11 //From supermatter shard
//zlevel defines, can be overridden for different maps in the appropriate _maps file.
#define ZLEVEL_STATION 1
#define ZLEVEL_CENTCOM 2
#define ZLEVEL_MINING 5
#define ZLEVEL_LAVALAND 5
#define ZLEVEL_EMPTY_SPACE 11
#define ZLEVEL_SPACEMIN 3
#define ZLEVEL_SPACEMAX 11
//ticker.current_state values
#define GAME_STATE_STARTUP 0
#define GAME_STATE_PREGAME 1
@@ -235,8 +225,9 @@ var/list/bloody_footprints_cache = list()
//lighting area defines
#define DYNAMIC_LIGHTING_DISABLED 0 //dynamic lighting disabled (area stays at full brightness)
#define DYNAMIC_LIGHTING_ENABLED 1 //dynamic lighting enabled
#define DYNAMIC_LIGHTING_IFSTARLIGHT 2 //dynamic lighting enabled only if starlight is.
#define IS_DYNAMIC_LIGHTING(A) ( A.lighting_use_dynamic == DYNAMIC_LIGHTING_IFSTARLIGHT ? config.starlight : A.lighting_use_dynamic )
#define DYNAMIC_LIGHTING_FORCED 2 //dynamic lighting enabled even if the area doesn't require power
#define DYNAMIC_LIGHTING_IFSTARLIGHT 3 //dynamic lighting enabled only if starlight is.
#define IS_DYNAMIC_LIGHTING(A) ( A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT ? config.starlight : A.dynamic_lighting )
//subtypesof(), typesof() without the parent path
#define subtypesof(typepath) ( typesof(typepath) - typepath )
@@ -244,15 +235,6 @@ var/list/bloody_footprints_cache = list()
//Gets the turf this atom inhabits
#define get_turf(A) (get_step(A, 0))
//Fire and Acid stuff, for resistance_flags
#define LAVA_PROOF 1
#define FIRE_PROOF 2 //100% immune to fire damage (but not necessarily to lava or heat)
#define FLAMMABLE 4
#define ON_FIRE 8
#define UNACIDABLE 16 //acid can't even appear on it, let alone melt it.
#define ACID_PROOF 32 //acid stuck on it doesn't melt it.
#define INDESTRUCTIBLE 64 //doesn't take damage
//Ghost orbit types:
#define GHOST_ORBIT_CIRCLE "circle"
#define GHOST_ORBIT_TRIANGLE "triangle"
@@ -350,8 +332,8 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define SHELTER_DEPLOY_ANCHORED_OBJECTS "anchored objects"
//debug printing macros
#define debug_world(msg) if (Debug2) world << "DEBUG: [msg]"
#define debug_admins(msg) if (Debug2) admins << "DEBUG: [msg]"
#define debug_world(msg) if (Debug2) to_chat(world, "DEBUG: [msg]")
#define debug_admins(msg) if (Debug2) to_chat(admins, "DEBUG: [msg]")
#define debug_world_log(msg) if (Debug2) log_world("DEBUG: [msg]")
#define COORD(A) "([A.x],[A.y],[A.z])"
@@ -417,4 +399,4 @@ var/global/list/ghost_others_options = list(GHOST_OTHERS_SIMPLE, GHOST_OTHERS_DE
#define TURF_DECAL_DIRT "dirt"
//Error handler defines
#define ERROR_USEFUL_LEN 2
#define ERROR_USEFUL_LEN 2
+7
View File
@@ -101,3 +101,10 @@
#define SNPC_STEALTH 2
#define SNPC_MARTYR 3
#define SNPC_PSYCHO 4
//Individual logging defines
#define INDIVIDUAL_ATTACK_LOG "Attack log"
#define INDIVIDUAL_SAY_LOG "Say log"
#define INDIVIDUAL_EMOTE_LOG "Emote log"
#define INDIVIDUAL_OOC_LOG "OOC log"
#define INDIVIDUAL_SHOW_ALL_LOG "All logs"
+2
View File
@@ -34,3 +34,5 @@
// A link given to ghost alice to follow bob
#define FOLLOW_LINK(alice, bob) "<a href=?src=\ref[alice];follow=\ref[bob]>(F)</a>"
#define TURF_LINK(alice, turfy) "<a href=?src=\ref[alice];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(T)</a>"
#define FOLLOW_OR_TURF_LINK(alice, bob, turfy) "<a href=?src=\ref[alice];follow=\ref[bob];x=[turfy.x];y=[turfy.y];z=[turfy.z]>(F)</a>"
+6 -1
View File
@@ -38,4 +38,9 @@
#define SHUTTLE_TRANSIT_BORDER 8
#define PARALLAX_LOOP_TIME 25
#define PARALLAX_LOOP_TIME 25
#define HYPERSPACE_END_TIME 5
#define HYPERSPACE_WARMUP 1
#define HYPERSPACE_LAUNCH 2
#define HYPERSPACE_END 3
+2
View File
@@ -18,6 +18,8 @@
#define STATUS_EFFECT_HISGRACE /datum/status_effect/his_grace //His Grace.
#define STATUS_EFFECT_WISH_GRANTERS_GIFT /datum/status_effect/wish_granters_gift //If you're currently resurrecting with the Wish Granter
/////////////
// DEBUFFS //
/////////////
+5 -1
View File
@@ -12,7 +12,7 @@
//print a testing-mode debug message to world.log and world
#ifdef TESTING
#define testing(msg) log_world("## TESTING: [msg]"); world << "## TESTING: [msg]"
#define testing(msg) log_world("## TESTING: [msg]"); to_chat(world, "## TESTING: [msg]")
#else
#define testing(msg)
#endif
@@ -89,6 +89,10 @@
if (config.log_pda)
diary << "\[[time_stamp()]]CHAT: [text]"
/proc/log_sql(text)
if(config.sql_enabled)
diary << "\[[time_stamp()]]SQL: [text]"
//This replaces world.log so it displays both in DD and the file
/proc/log_world(text)
if(config && config.log_runtimes)
+4 -5
View File
@@ -2,14 +2,13 @@
/client/proc/join_date_check(y,m,d)
var/DBQuery/query = dbcon.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
var/DBQuery/query_datediff = dbcon.NewQuery("SELECT DATEDIFF(Now(),'[y]-[m]-[d]')")
if(!query.Execute())
log_world("SQL ERROR doing datediff. Error : \[[query.ErrorMsg()]\]\n")
if(!query_datediff.Execute())
return FALSE
if(query.NextRow())
var/diff = text2num(query.item[1])
if(query_datediff.NextRow())
var/diff = text2num(query_datediff.item[1])
if(config.use_account_age_for_jobs)
player_age = max(0,diff) //So job code soesn't freak out if they are time traveling.
if(diff < YOUNG)
+4 -6
View File
@@ -29,15 +29,13 @@ var/cmp_field = "name"
/proc/cmp_ckey_dsc(client/a, client/b)
return sorttext(a.ckey, b.ckey)
/proc/cmp_subsystem_init(datum/subsystem/a, datum/subsystem/b)
/proc/cmp_subsystem_init(datum/controller/subsystem/a, datum/controller/subsystem/b)
return b.init_order - a.init_order
/proc/cmp_subsystem_display(datum/subsystem/a, datum/subsystem/b)
if(a.display_order == b.display_order)
return sorttext(b.name, a.name)
return a.display_order - b.display_order
/proc/cmp_subsystem_display(datum/controller/subsystem/a, datum/controller/subsystem/b)
return sorttext(b.name, a.name)
/proc/cmp_subsystem_priority(datum/subsystem/a, datum/subsystem/b)
/proc/cmp_subsystem_priority(datum/controller/subsystem/a, datum/controller/subsystem/b)
return a.priority - b.priority
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
+2 -2
View File
@@ -39,7 +39,7 @@
var/extension = copytext(path,-4,0)
if( !fexists(path) || !(extension in valid_extensions) )
src << "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>"
to_chat(src, "<font color='red'>Error: browse_files(): File not found/Invalid file([path]).</font>")
return
return path
@@ -53,7 +53,7 @@
/client/proc/file_spam_check()
var/time_to_wait = fileaccess_timer - world.time
if(time_to_wait > 0)
src << "<font color='red'>Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.</font>"
to_chat(src, "<font color='red'>Error: file_spam_check(): Spam. Please wait [round(time_to_wait/10)] seconds.</font>")
return 1
fileaccess_timer = world.time + FTPDELAY
return 0
+3
View File
@@ -0,0 +1,3 @@
#define HAS_SECONDARY_FLAG(atom, sflag) (atom.secondary_flags ? atom.secondary_flags[sflag] : FALSE)
#define SET_SECONDARY_FLAG(atom, sflag) if(!atom.secondary_flags) { atom.secondary_flags = list(); } atom.secondary_flags[sflag] = TRUE;
#define CLEAR_SECONDARY_FLAG(atom, sflag) if(atom.secondary_flags) atom.secondary_flags[sflag] = null
+31 -6
View File
@@ -422,20 +422,20 @@
window_flash(G.client)
switch(ignore_category ? askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
if(1)
G << "<span class='notice'>Choice registered: Yes.</span>"
to_chat(G, "<span class='notice'>Choice registered: Yes.</span>")
if((world.time-time_passed)>poll_time)
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
to_chat(G, "<span class='danger'>Sorry, you were too late for the consideration!</span>")
G << 'sound/machines/buzz-sigh.ogg'
else
candidates += G
if(2)
G << "<span class='danger'>Choice registered: No.</span>"
to_chat(G, "<span class='danger'>Choice registered: No.</span>")
if(3)
var/list/L = poll_ignore[ignore_category]
if(!L)
poll_ignore[ignore_category] = list()
poll_ignore[ignore_category] += G.ckey
G << "<span class='danger'>Choice registered: Never for this round.</span>"
to_chat(G, "<span class='danger'>Choice registered: Never for this round.</span>")
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null, flashwindow = TRUE)
var/list/mob/dead/observer/candidates = list()
@@ -498,10 +498,10 @@
return new_character
/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of world << where needed
/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of to_chat(world, where needed)
for(var/M in player_list)
if(M && !isnewplayer(M))
M << thing
to_chat(M, thing)
/proc/window_flash(client/C, ignorepref = FALSE)
if(ismob(C))
@@ -511,3 +511,28 @@
if(!C || (!C.prefs.windowflashing && !ignorepref))
return
winset(C, "mainwindow", "flash=5")
/proc/AnnounceArrival(var/mob/living/carbon/human/character, var/rank)
if(ticker.current_state != GAME_STATE_PLAYING || !character)
return
var/area/A = get_area(character)
var/message = "<span class='game deadsay'><span class='name'>\
[character.real_name]</span> ([rank]) has arrived at the station at \
<span class='name'>[A.name]</span>.</span>"
deadchat_broadcast(message, follow_target = character, message_type=DEADCHAT_ARRIVALRATTLE)
if((!announcement_systems.len) || (!character.mind))
return
if((character.mind.assigned_role == "Cyborg") || (character.mind.assigned_role == character.mind.special_role))
return
var/obj/machinery/announcement_system/announcer = pick(announcement_systems)
announcer.announce("ARRIVAL", character.real_name, rank, list()) //make the list empty to make it announce it in common
/proc/GetRedPart(const/hexa)
return hex2num(copytext(hexa, 2, 4))
/proc/GetGreenPart(const/hexa)
return hex2num(copytext(hexa, 4, 6))
/proc/GetBluePart(const/hexa)
return hex2num(copytext(hexa, 6, 8))
+1 -1
View File
@@ -94,7 +94,7 @@
var/list/L = chemical_reactions_list[reaction]
for(var/t in L)
. += " has: [t]\n"
world << .
to_chat(world, .)
*/
//creates every subtype of prototype (excluding prototype) and adds it to list L.
+7 -5
View File
@@ -167,7 +167,7 @@ mob
Output_Icon()
set name = "2. Output Icon"
src<<"Icon is: \icon[getFlatIcon(src)]"
to_chat(src, "Icon is: \icon[getFlatIcon(src)]")
Label_Icon()
set name = "3. Label Icon"
@@ -869,7 +869,7 @@ The _flatIcons list is a cache for generated icon files.
text_image.color = AverageColour(atom_icon)
text_image.pixel_x = 7
text_image.pixel_y = 5
del(atom_icon)
qdel(atom_icon)
return text_image
var/global/list/friendly_animal_types = list()
@@ -954,6 +954,8 @@ var/global/list/humanoid_icon_cache = list()
if(outfit)
body.equipOutfit(outfit, TRUE)
SSoverlays.Flush()
var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
body.setDir(NORTH)
@@ -993,7 +995,7 @@ var/list/freeze_item_icons = list()
return "\ref[initial(icon)]-[initial(icon_state)]"
/obj/proc/make_frozen_visual()
if(!is_frozen && (initial(icon) && initial(icon_state)))
if(!HAS_SECONDARY_FLAG(src, FROZEN) && (initial(icon) && initial(icon_state)))
var/index = freeze_icon_index()
var/icon/IC
var/icon/P = freeze_item_icons[index]
@@ -1007,10 +1009,10 @@ var/list/freeze_item_icons = list()
freeze_item_icons[index] = P
icon = P
name = "frozen [name]"
is_frozen = TRUE
SET_SECONDARY_FLAG(src, FROZEN)
//Assumes already frozed
obj/proc/make_unfrozen()
icon = initial(icon)
name = replacetext(name, "frozen ", "")
is_frozen = FALSE
CLEAR_SECONDARY_FLAG(src, FROZEN)
+1 -1
View File
@@ -139,7 +139,7 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
var/size_factor = ((-cos(inputToDegrees) +1) /2) //returns a value from 0 to 1
return size_factor + scaling_modifier //scale mod of 0 results in a number from 0 to 1. A scale modifier of +0.5 returns 0.5 to 1.5
//world<< "Transform multiplier of [src] is [size_factor + scaling_modifer]"
//to_chat(world, "Transform multiplier of [src] is [size_factor + scaling_modifer]")
+21 -13
View File
@@ -259,16 +259,12 @@ Proc for attack log creation, because really why not
living_target = target
if(is_mob_user)
var/message = "\[[time_stamp()]\] <font color='red'>[user ? "[user.name][(user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
user.attack_log += message
if(user.mind)
user.mind.attack_log += message
var/message = "<font color='red'>has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
user.log_message(message, INDIVIDUAL_ATTACK_LOG)
if(is_mob_target)
var/message = "\[[time_stamp()]\] <font color='orange'>[target ? "[target.name][(target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
target.attack_log += message
if(target.mind)
target.mind.attack_log += message
var/message = "<font color='orange'>has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
target.log_message(message, INDIVIDUAL_ATTACK_LOG)
log_attack("[user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(is_mob_target && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]")
@@ -450,7 +446,7 @@ Proc for attack log creation, because really why not
for(var/i in 1 to step_count)
step(X, pick(NORTH, SOUTH, EAST, WEST))
/proc/deadchat_broadcast(message, mob/follow_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
/proc/deadchat_broadcast(message, mob/follow_target=null, turf/turf_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
for(var/mob/M in player_list)
var/datum/preferences/prefs
if(M.client && M.client.prefs)
@@ -476,8 +472,20 @@ Proc for attack log creation, because really why not
if(prefs.toggles & DISABLE_ARRIVALRATTLE)
continue
if(isobserver(M) && follow_target)
var/link = FOLLOW_LINK(M, follow_target)
M << "[link] [message]"
if(isobserver(M))
var/rendered_message = message
if(follow_target)
var/F
if(turf_target)
F = FOLLOW_OR_TURF_LINK(M, follow_target, turf_target)
else
F = FOLLOW_LINK(M, follow_target)
rendered_message = "[F] [message]"
else if(turf_target)
var/turf_link = TURF_LINK(M, turf_target)
rendered_message = "[turf_link] [message]"
to_chat(M, rendered_message)
else
M << "[message]"
to_chat(M, message)
+28 -11
View File
@@ -1,3 +1,5 @@
#define ION_FILE "ion_laws.json"
/proc/lizard_name(gender)
if(gender == MALE)
return "[pick(lizard_names_male)]-[pick(lizard_names_male)]"
@@ -170,12 +172,16 @@ var/syndicate_code_response//Code response for traitors.
25; 5
)
var/safety[] = list(1,2,3)//Tells the proc which options to remove later on.
var/nouns[] = list("love","hate","anger","peace","pride","sympathy","bravery","loyalty","honesty","integrity","compassion","charity","success","courage","deceit","skill","beauty","brilliance","pain","misery","beliefs","dreams","justice","truth","faith","liberty","knowledge","thought","information","culture","trust","dedication","progress","education","hospitality","leisure","trouble","friendships", "relaxation")
var/drinks[] = list("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island iced tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequila sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
var/locations[] = teleportlocs.len ? teleportlocs : drinks//if null, defaults to drinks instead.
var/list/safety = list(1,2,3)//Tells the proc which options to remove later on.
var/nouns = strings(ION_FILE, "ionabstract")
var/objects = strings(ION_FILE, "ionobjects")
var/adjectives = strings(ION_FILE, "ionadjectives")
var/threats = strings(ION_FILE, "ionthreats")
var/foods = strings(ION_FILE, "ionfood")
var/drinks = strings(ION_FILE, "iondrinks")
var/list/locations = teleportlocs.len ? teleportlocs : drinks //if null, defaults to drinks instead.
var/names[] = list()
var/list/names = list()
for(var/datum/data/record/t in data_core.general)//Picks from crew manifest.
names += t.fields["name"]
@@ -205,23 +211,34 @@ var/syndicate_code_response//Code response for traitors.
code_phrase += pick(get_all_jobs())//Returns a job.
safety -= 1
if(2)
switch(rand(1,2))//Places or things.
switch(rand(1,3))//Food, drinks, or things. Only selectable once.
if(1)
code_phrase += pick(drinks)
code_phrase += lowertext(pick(drinks))
if(2)
code_phrase += lowertext(pick(foods))
if(3)
code_phrase += pick(locations)
safety -= 2
if(3)
switch(rand(1,3))//Nouns, adjectives, verbs. Can be selected more than once.
switch(rand(1,4))//Abstract nouns, objects, adjectives, threats. Can be selected more than once.
if(1)
code_phrase += pick(nouns)
code_phrase += lowertext(pick(nouns))
if(2)
code_phrase += pick(adjectives)
code_phrase += lowertext(pick(objects))
if(3)
code_phrase += pick(verbs)
code_phrase += lowertext(pick(adjectives))
if(4)
code_phrase += lowertext(pick(threats))
if(words==1)
code_phrase += "."
else
code_phrase += ", "
return code_phrase
/proc/change_station_name(designation)
if(config && config.server_name)
world.name = "[config.server_name]: [designation]"
else
world.name = designation
station_name = designation
+59 -3
View File
@@ -14,8 +14,8 @@
*/
// Run all strings to be used in an SQL query through this proc first to properly escape out injection attempts.
/proc/sanitizeSQL(t as text)
var/sqltext = dbcon.Quote(t);
/proc/sanitizeSQL(t)
var/sqltext = dbcon.Quote("[t]");
return copytext(sqltext, 2, lentext(sqltext));//Quote() adds quotes around input, we already do that
/proc/format_table_name(table as text)
@@ -553,4 +553,60 @@ var/list/binary = list("0","1")
var/list/tosend = list()
tosend["data"] = finalized
log << json_encode(tosend)
log << json_encode(tosend)
//Used for applying byonds text macros to strings that are loaded at runtime
/proc/apply_text_macros(string)
var/next_backslash = findtext(string, "\\")
if(!next_backslash)
return string
var/leng = length(string)
var/next_space = findtext(string, " ", next_backslash + 1)
if(!next_space)
next_space = leng - next_backslash
if(!next_space) //trailing bs
return string
var/base = next_backslash == 1 ? "" : copytext(string, 1, next_backslash)
var/macro = lowertext(copytext(string, next_backslash + 1, next_space))
var/rest = next_backslash > leng ? "" : copytext(string, next_space + 1)
//See http://www.byond.com/docs/ref/info.html#/DM/text/macros
switch(macro)
//prefixes/agnostic
if("the")
rest = text("\the []", rest)
if("a")
rest = text("\a []", rest)
if("an")
rest = text("\an []", rest)
if("proper")
rest = text("\proper []", rest)
if("improper")
rest = text("\improper []", rest)
if("roman")
rest = text("\roman []", rest)
//postfixes
if("th")
base = text("[]\th", rest)
if("s")
base = text("[]\s", rest)
if("he")
base = text("[]\he", rest)
if("she")
base = text("[]\she", rest)
if("his")
base = text("[]\his", rest)
if("himself")
base = text("[]\himself", rest)
if("herself")
base = text("[]\herself", rest)
if("hers")
base = text("[]\hers", rest)
. = base
if(rest)
. += .(rest)
+3 -2
View File
@@ -2,8 +2,9 @@
/proc/worldtime2text()
return gameTimestamp("hh:mm:ss")
/proc/time_stamp(format = "hh:mm:ss")
return time2text(world.timeofday, format)
/proc/time_stamp(format = "hh:mm:ss", show_ds)
var/time_string = time2text(world.timeofday, format)
return show_ds ? "[time_string]:[world.timeofday % 10]" : time_string
/proc/gameTimestamp(format = "hh:mm:ss") // Get the game time in text
return time2text(world.time - timezoneOffset + 432000 - round_start_time, format)
+61 -28
View File
@@ -186,15 +186,17 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 1
//Generalised helper proc for letting mobs rename themselves. Used to be clname() and ainame()
/mob/proc/rename_self(role)
/mob/proc/rename_self(role, client/C)
if(!C)
C = client
var/oldname = real_name
var/newname
var/loop = 1
var/safety = 0
while(loop && safety < 5)
if(client && client.prefs.custom_names[role] && !safety)
newname = client.prefs.custom_names[role]
if(C && C.prefs.custom_names[role] && !safety)
newname = C.prefs.custom_names[role]
else
switch(role)
if("clown")
@@ -329,7 +331,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
for(var/mob/dead/observer/M in sortmob)
moblist.Add(M)
for(var/mob/new_player/M in sortmob)
for(var/mob/dead/new_player/M in sortmob)
moblist.Add(M)
for(var/mob/living/carbon/monkey/M in sortmob)
moblist.Add(M)
@@ -719,11 +721,12 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/pixel_y_offset = AM.pixel_y + M.get_y_shift()
//Irregular objects
if(AM.bound_height != world.icon_size || AM.bound_width != world.icon_size)
var/icon/AMicon = icon(AM.icon, AM.icon_state)
var/icon/AMicon = icon(AM.icon, AM.icon_state)
var/icon/AMiconheight = AMicon.Height()
var/icon/AMiconwidth = AMicon.Width()
if(AMiconheight != world.icon_size || AMiconwidth != world.icon_size)
pixel_x_offset += ((AMicon.Width()/world.icon_size)-1)*(world.icon_size*0.5)
pixel_y_offset += ((AMicon.Height()/world.icon_size)-1)*(world.icon_size*0.5)
qdel(AMicon)
//DY and DX
var/rough_x = round(round(pixel_x_offset,world.icon_size)/world.icon_size)
@@ -731,6 +734,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Find coordinates
var/turf/T = get_turf(AM) //use AM's turfs, as it's coords are the same as AM's AND AM's coords are lost if it is inside another atom
if(!T)
return null
var/final_x = T.x + rough_x
var/final_y = T.y + rough_y
@@ -832,20 +837,20 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
var/pressure = air_contents.return_pressure()
var/total_moles = air_contents.total_moles()
user << "<span class='notice'>Results of analysis of \icon[icon] [target].</span>"
to_chat(user, "<span class='notice'>Results of analysis of \icon[icon] [target].</span>")
if(total_moles>0)
user << "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>"
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.1)] kPa</span>")
var/list/cached_gases = air_contents.gases
for(var/id in cached_gases)
var/gas_concentration = cached_gases[id][MOLES]/total_moles
if(id in hardcoded_gases || gas_concentration > 0.001) //ensures the four primary gases are always shown.
user << "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>"
to_chat(user, "<span class='notice'>[cached_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_concentration*100, 0.01)] %</span>")
user << "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] &deg;C</span>"
to_chat(user, "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] &deg;C</span>")
else
user << "<span class='notice'>[target] is empty!</span>"
to_chat(user, "<span class='notice'>[target] is empty!</span>")
return
/proc/check_target_facings(mob/living/initator, mob/living/target)
@@ -919,19 +924,6 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
return !QDELETED(D)
return 0
//Get the dir to the RIGHT of dir if they were on a clock
//NORTH --> NORTHEAST
/proc/get_clockwise_dir(dir)
. = angle2dir(dir2angle(dir)+45)
//Get the dir to the LEFT of dir if they were on a clock
//NORTH --> NORTHWEST
/proc/get_anticlockwise_dir(dir)
. = angle2dir(dir2angle(dir)-45)
//Compare A's dir, the clockwise dir of A and the anticlockwise dir of A
//To the opposite dir of the dir returned by get_dir(B,A)
//If one of them is a match, then A is facing B
@@ -943,8 +935,8 @@ var/list/WALLITEMS_INVERSE = typecacheof(list(
if(LA.lying)
return 0
var/goal_dir = angle2dir(dir2angle(get_dir(B,A)+180))
var/clockwise_A_dir = get_clockwise_dir(A.dir)
var/anticlockwise_A_dir = get_anticlockwise_dir(B.dir)
var/clockwise_A_dir = turn(A.dir, -45)
var/anticlockwise_A_dir = turn(B.dir, 45)
if(A.dir == goal_dir || clockwise_A_dir == goal_dir || anticlockwise_A_dir == goal_dir)
return 1
@@ -1321,6 +1313,42 @@ proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
else
. = ""
/var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant).
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
dview_mob.loc = center
dview_mob.see_invisible = invis_flags
. = view(range, dview_mob)
dview_mob.loc = null
/mob/dview
invisibility = 101
density = 0
see_in_dark = 1e6
anchored = 1
/mob/dview/Destroy(force=0)
stack_trace("ALRIGHT WHICH FUCKER TRIED TO DELETE *MY* DVIEW?")
if (!force)
return QDEL_HINT_LETMELIVE
world.log << "EVACUATE THE SHITCODE IS TRYING TO STEAL MUH JOBS"
global.dview_mob = new
return QDEL_HINT_QUEUE
#define FOR_DVIEW(type, range, center, invis_flags) \
dview_mob.loc = center; \
dview_mob.see_invisible = invis_flags; \
for(type in view(range, dview_mob))
//can a window be here, or is there a window blocking it?
/proc/valid_window_location(turf/T, dir_to_check)
if(!T)
@@ -1371,7 +1399,7 @@ var/valid_HTTPSGet = FALSE
\______(_______;;; __;;;
*/
var/temp_file = "HTTPSGetOutput.txt"
var/command
var/command
if(world.system_type == MS_WINDOWS)
command = "powershell -Command \"wget [url] -OutFile [temp_file]\""
else if(world.system_type == UNIX)
@@ -1393,3 +1421,8 @@ var/valid_HTTPSGet = FALSE
. = file2text(f)
f = null
fdel(temp_file)
#define UNTIL(X) while(!(X)) stoplag()
/proc/to_chat(target, message)
target << message
-5
View File
@@ -1,5 +1,4 @@
var/datum/configuration/config = null
var/datum/protected_configuration/protected_config = null
var/host = null
var/join_motd = null
@@ -26,10 +25,6 @@ var/Debug2 = 0
var/global/comms_key = "default_pwd"
var/global/comms_allowed = 0 //By default, the server does not allow messages to be sent to it, unless the key is strong enough (this is to prevent misconfigured servers from becoming vulnerable)
//Cross server communications
var/global/cross_address = "byond://" //This needs to be global as the message sent contains the comms key.
var/global/cross_allowed = 0 //Don't bother attempting to send if the address wasn't set.
var/global/medal_hub = null
var/global/medal_pass = " "
var/global/medals_enabled = TRUE //will be auto set to false if the game fails contacting the medal hub to prevent unneeded calls.
+3 -3
View File
@@ -7,10 +7,10 @@ var/list/stealthminID = list() //reference list with IDs that store ckeys,
//Since it didn't really belong in any other category, I'm putting this here
//This is for procs to replace all the goddamn 'in world's that are chilling around the code
var/global/list/player_list = list() //all mobs **with clients attached**. Excludes /mob/new_player
var/global/list/player_list = list() //all mobs **with clients attached**. Excludes /mob/dead/new_player
var/global/list/mob_list = list() //all mobs, including clientless
var/global/list/living_mob_list = list() //all alive mobs, including clientless. Excludes /mob/new_player
var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/new_player
var/global/list/living_mob_list = list() //all alive mobs, including clientless. Excludes /mob/dead/new_player
var/global/list/dead_mob_list = list() //all dead mobs, including clientless. Excludes /mob/dead/new_player
var/global/list/joined_player_list = list() //all clients that have joined the game at round-start or as a latejoin.
var/global/list/silicon_mobs = list() //all silicon mobs
var/global/list/pai_list = list()
+1
View File
@@ -27,3 +27,4 @@ var/global/list/poi_list = list() //list of points of interest for observe/f
var/global/list/pinpointer_list = list() //list of all pinpointers. Used to change stuff they are pointing to all at once.
var/global/list/zombie_infection_list = list() // A list of all zombie_infection organs, for any mass "animation"
var/global/list/meteor_list = list() // List of all meteors.
var/global/list/active_jammers = list() // List of active radio jammers
+2 -1
View File
@@ -3,5 +3,6 @@
#define POLL_IGNORE_PAI "pai"
#define POLL_IGNORE_SENTIENCE_POTION "sentience_potion"
#define POLL_IGNORE_POSSESSED_BLADE "possessed_blade"
#define POLL_IGNORE_ALIEN_LARVA "alien_larva"
var/list/poll_ignore = list()
var/list/poll_ignore = list()
+1 -14
View File
@@ -6,17 +6,4 @@ var/timezoneOffset = 0 // The difference betwen midnight (of the host computer)
// However it'd be ok to use for accessing attack logs and such too, which are even laggier.
var/fileaccess_timer = 0
var/TAB = "&nbsp;&nbsp;&nbsp;&nbsp;"
var/map_ready = 0
/*
basically, this will be used to avoid initialize() being called twice for objects
initialize() is necessary because the map is instanced on a turf-by-turf basis
i.e. all obj on a turf are instanced, then all mobs on that turf, before moving to the next turf (starting bottom-left)
This means if we want to say, get any neighbouring objects in New(), only objects to the south and west will exist yet.
Therefore, we'd need to use spawn inside New() to wait for the surrounding turf contents to be instanced
However, using lots of spawn has a severe performance impact, and often results in spaghetti-code
map_ready will be set to 1 when world/New() is called (which happens just after the map is instanced)
*/
var/TAB = "&nbsp;&nbsp;&nbsp;&nbsp;"
+1 -3
View File
@@ -5,6 +5,4 @@ var/global/datum/datacore/data_core = null
var/CELLRATE = 0.002 // multiplier for watts per tick <> cell storage (eg: .002 means if there is a load of 1000 watts, 20 units will be taken from a cell per second)
var/CHARGELEVEL = 0.001 // Cap for how fast cells charge, as a percentage-per-tick (.001 means cellcharge is capped to 1% per second)
var/list/powernets = list()
var/map_name = "Unknown" //The name of the map that is loaded. Assigned in world/New()
var/list/powernets = list()
+10 -7
View File
@@ -37,7 +37,7 @@
// Non diagonal case
if(T0.x == x || T0.y == y)
// Check for border blockages
return T0.ClickCross(get_dir(T0,src), border_only = 1) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target)
return T0.ClickCross(get_dir(T0,src), border_only = 1, target_atom = target) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target)
// Diagonal case
var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001)
@@ -45,11 +45,11 @@
var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000)
for(var/d in list(d1,d2))
if(!T0.ClickCross(d, border_only = 1))
if(!T0.ClickCross(d, border_only = 1, target_atom = target))
continue // could not leave T0 in that direction
var/turf/T1 = get_step(T0,d)
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0) | get_dir(T1,src), border_only = 0)) //let's check both directions at once
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0) | get_dir(T1,src), border_only = 0, target_atom = target)) //let's check both directions at once
continue // couldn't enter or couldn't leave T1
if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target))
@@ -64,10 +64,13 @@
* Must be on a turf
*/
/atom/movable/Adjacent(var/atom/neighbor)
if(neighbor == loc) return 1
if(!isturf(loc)) return 0
if(loc.Adjacent(neighbor,src)) return 1
return 0
if(neighbor == loc)
return TRUE
if(!isturf(loc))
return FALSE
if(loc.Adjacent(neighbor,target = neighbor))
return TRUE
return FALSE
// This is necessary for storage items not on your person.
/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1)
+25 -2
View File
@@ -129,7 +129,7 @@
// Allows you to click on a box's contents, if that box is on the ground, but no deeper than that
if(isturf(A) || isturf(A.loc) || (A.loc && isturf(A.loc.loc)))
if(A.Adjacent(src)) // see adjacent.dm
if(Adjacent(A) || (W && CheckReach(src, A, W.reach))) //Adjacent or reaching attacks
if(W)
if(W.pre_attackby(A,src,params))
// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
@@ -147,6 +147,29 @@
else
RangedAttack(A, params)
/proc/CheckReach(atom/movable/here, atom/movable/there, reach)
if(!here || !there)
return
switch(reach)
if(0)
return here.loc == there.loc
if(1)
return here.Adjacent(there)
if(2 to INFINITY)
var/obj/dummy = new(get_turf(here)) //We'll try to move this every tick, failing if we can't
dummy.pass_flags |= PASSTABLE
for(var/i in 1 to reach) //Limit it to that many tries
var/turf/T = get_step(dummy, get_dir(dummy, there))
if(dummy.loc == there.loc)
qdel(dummy)
return 1
if(there.density && dummy in range(1, there)) //For windows and
qdel(dummy)
return 1
if(!dummy.Move(T)) //we're blocked!
qdel(dummy)
return
// Default behavior: ignore double clicks (the second click that makes the doubleclick call already calls for a normal click)
/mob/proc/DblClickOn(atom/A, params)
return
@@ -391,4 +414,4 @@
view = -1
else
view = 1
add_view_range(view)
add_view_range(view)
+15 -4
View File
@@ -3,7 +3,7 @@
//PUBLIC - call these wherever you want
/mob/proc/throw_alert(category, type, severity, obj/new_master)
/mob/proc/throw_alert(category, type, severity, obj/new_master, override = FALSE)
/* Proc to create or update an alert. Returns the alert if the alert is new or updated, 0 if it was thrown already
category is a text string. Each mob may only have one alert per category; the previous one will be replaced
@@ -11,7 +11,9 @@
severity is an optional number that will be placed at the end of the icon_state for this alert
For example, high pressure's icon_state is "highpressure" and can be serverity 1 or 2 to get "highpressure1" or "highpressure2"
new_master is optional and sets the alert's icon state to "template" in the ui_style icons with the master as an overlay.
Clicks are forwarded to master */
Clicks are forwarded to master
Override makes it so the alert is not replaced until cleared by a clear_alert with clear_override, and it's used for hallucinations.
*/
if(!category)
return
@@ -19,8 +21,11 @@
var/obj/screen/alert/thealert
if(alerts[category])
thealert = alerts[category]
if(thealert.override_alerts)
return 0
if(new_master && new_master != thealert.master)
WARNING("[src] threw alert [category] with new_master [new_master] while already having that alert with master [thealert.master]")
clear_alert(category)
return .()
else if(thealert.type != type)
@@ -34,6 +39,9 @@
return 0
else
thealert = new type()
thealert.override_alerts = override
if(override)
thealert.timeout = null
if(new_master)
var/old_layer = new_master.layer
@@ -65,10 +73,12 @@
clear_alert(category)
// Proc to clear an existing alert.
/mob/proc/clear_alert(category)
/mob/proc/clear_alert(category, clear_override = FALSE)
var/obj/screen/alert/alert = alerts[category]
if(!alert)
return 0
if(alert.override_alerts && !clear_override)
return 0
alerts -= category
if(client && hud_used)
@@ -85,6 +95,7 @@
var/timeout = 0 //If set to a number, this alert will clear itself after that many deciseconds
var/severity = 0
var/alerttooltipstyle = ""
var/override_alerts = FALSE //If it is overriding other alerts of the same type
/obj/screen/alert/MouseEntered(location,control,params)
@@ -586,7 +597,7 @@ so as to remain in compliance with the most up-to-date laws."
return
var/paramslist = params2list(params)
if(paramslist["shift"]) // screen objects don't do the normal Click() stuff so we'll cheat
usr << "<span class='boldnotice'>[name]</span> - <span class='info'>[desc]</span>"
to_chat(usr, "<span class='boldnotice'>[name]</span> - <span class='info'>[desc]</span>")
return
if(master)
return usr.client.Click(master, location, control, params)
+42 -4
View File
@@ -18,7 +18,7 @@
screen.severity = severity
screens[category] = screen
if(client && stat != DEAD)
if(client && screen.should_show_to(src))
client.screen += screen
return screen
@@ -52,9 +52,14 @@
client.screen -= screens[category]
/mob/proc/reload_fullscreen()
if(client && stat != DEAD) //dead mob do not see any of the fullscreen overlays that he has.
if(client)
var/obj/screen/fullscreen/screen
for(var/category in screens)
client.screen |= screens[category]
screen = screens[category]
if(screen.should_show_to(src))
client.screen |= screen
else
client.screen -= screen
/obj/screen/fullscreen
icon = 'icons/mob/screen_full.dmi'
@@ -64,6 +69,12 @@
plane = FULLSCREEN_PLANE
mouse_opacity = 0
var/severity = 0
var/show_when_dead = FALSE
/obj/screen/fullscreen/proc/should_show_to(mob/mymob)
if(!show_when_dead && mymob.stat == DEAD)
return FALSE
return TRUE
/obj/screen/fullscreen/Destroy()
severity = 0
@@ -125,4 +136,31 @@
color = "#ff0000"
/obj/screen/fullscreen/color_vision/blue
color = "#0000ff"
color = "#0000ff"
/obj/screen/fullscreen/lighting_backdrop
icon = 'icons/mob/screen_gen.dmi'
icon_state = "flash"
transform = matrix(200, 0, 0, 0, 200, 0)
plane = LIGHTING_PLANE
blend_mode = BLEND_OVERLAY
show_when_dead = TRUE
//Provides darkness to the back of the lighting plane
/obj/screen/fullscreen/lighting_backdrop/lit
invisibility = INVISIBILITY_LIGHTING
layer = BACKGROUND_LAYER+21
color = "#000"
show_when_dead = TRUE
//Provides whiteness in case you don't see lights so everything is still visible
/obj/screen/fullscreen/lighting_backdrop/unlit
layer = BACKGROUND_LAYER+20
show_when_dead = TRUE
/obj/screen/fullscreen/see_through_darkness
icon_state = "nightvision"
plane = LIGHTING_PLANE
layer = LIGHTING_LAYER
blend_mode = BLEND_ADD
show_when_dead = TRUE
+5 -14
View File
@@ -46,11 +46,6 @@
/datum/hud/ghost/New(mob/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
var/mob/dead/observer/G = mymob
if(!G.client.prefs.ghost_hud)
mymob.client.screen = null
return
var/obj/screen/using
using = new /obj/screen/ghost/jumptomob()
@@ -73,17 +68,13 @@
using.screen_loc = ui_ghost_pai
static_inventory += using
/datum/hud/ghost/show_hud()
var/mob/dead/observer/G = mymob
mymob.client.screen = list()
for(var/thing in plane_masters)
mymob.client.screen += plane_masters[thing]
create_parallax()
if(G.client.prefs.ghost_hud)
/datum/hud/ghost/show_hud(version = 0, mob/viewmob)
..()
if(!mymob.client.prefs.ghost_hud)
mymob.client.screen -= static_inventory
else
mymob.client.screen += static_inventory
/mob/dead/observer/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/ghost(src, ui_style2icon(client.prefs.UI_style))
+7 -6
View File
@@ -50,8 +50,6 @@
var/obj/screen/healths
var/obj/screen/healthdoll
var/obj/screen/internals
//citadel code
var/obj/screen/arousal
var/ui_style_icon = 'icons/mob/screen_midnight.dmi'
@@ -68,6 +66,7 @@
for(var/mytype in subtypesof(/obj/screen/plane_master))
var/obj/screen/plane_master/instance = new mytype()
plane_masters["[instance.plane]"] = instance
instance.backdrop(mymob)
/datum/hud/Destroy()
if(mymob.hud_used == src)
@@ -131,6 +130,7 @@
qdel(thing)
screenoverlays.Cut()
mymob = null
return ..()
/mob/proc/create_mob_hud()
@@ -204,6 +204,7 @@
for(var/thing in plane_masters)
screenmob.client.screen += plane_masters[thing]
hud_version = display_hud_version
persistent_inventory_update(screenmob)
mymob.update_action_buttons(1)
@@ -216,7 +217,7 @@
..()
hidden_inventory_update(viewmob)
/datum/hud/robot/show_hud(version = 0)
/datum/hud/robot/show_hud(version = 0, mob/viewmob)
..()
update_robot_modules_display()
@@ -244,9 +245,9 @@
if(hud_used && client)
hud_used.show_hud() //Shows the next hud preset
usr << "<span class ='info'>Switched HUD mode. Press F12 to toggle.</span>"
to_chat(usr, "<span class ='info'>Switched HUD mode. Press F12 to toggle.</span>")
else
usr << "<span class ='warning'>This mob type does not use a HUD.</span>"
to_chat(usr, "<span class ='warning'>This mob type does not use a HUD.</span>")
//(re)builds the hand ui slots, throwing away old ones
@@ -278,4 +279,4 @@
for(var/obj/screen/human/equip/E in static_inventory)
E.screen_loc = ui_equip_position(mymob)
if(mymob.hud_used)
show_hud(HUD_STYLE_STANDARD,mymob)
show_hud(HUD_STYLE_STANDARD,mymob)
+2
View File
@@ -0,0 +1,2 @@
/datum/hud
var/obj/screen/arousal
+2
View File
@@ -87,6 +87,8 @@
/datum/hud/human/New(mob/living/carbon/human/owner, ui_style = 'icons/mob/screen_midnight.dmi')
..()
owner.overlay_fullscreen("see_through_darkness", /obj/screen/fullscreen/see_through_darkness)
var/obj/screen/using
var/obj/screen/inventory/inv_box
+38 -38
View File
@@ -2,7 +2,6 @@
/client
var/list/parallax_layers
var/list/parallax_layers_cached
var/static/list/parallax_static_layers_tail = newlist(/obj/screen/parallax_pmaster, /obj/screen/parallax_space_whitifier)
var/atom/movable/movingmob
var/turf/previous_turf
var/dont_animate_parallax //world.time of when we can state animate()ing parallax again
@@ -27,11 +26,22 @@
if (length(C.parallax_layers) > C.parallax_layers_max)
C.parallax_layers.len = C.parallax_layers_max
C.screen |= (C.parallax_layers + C.parallax_static_layers_tail)
C.screen |= (C.parallax_layers)
var/obj/screen/plane_master/PM = plane_masters["[PLANE_SPACE]"]
PM.color = list(
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 1,
0, 0, 0, 0
)
/datum/hud/proc/remove_parallax()
var/client/C = mymob.client
C.screen -= (C.parallax_layers_cached + C.parallax_static_layers_tail)
C.screen -= (C.parallax_layers_cached)
var/obj/screen/plane_master/PM = plane_masters["[PLANE_SPACE]"]
PM.color = initial(PM.color)
C.parallax_layers = null
/datum/hud/proc/apply_parallax_pref()
@@ -70,7 +80,7 @@
create_parallax()
// This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation)
/datum/hud/proc/set_parallax_movedir(new_parallax_movedir)
/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups)
. = FALSE
var/client/C = mymob.client
if(new_parallax_movedir == C.parallax_movedir)
@@ -100,24 +110,29 @@
newtransform = matrix(1, 0,-480, 0, 1, 0)
var/shortesttimer
for(var/thing in C.parallax_layers)
var/obj/screen/parallax_layer/L = thing
if(!skip_windups)
for(var/thing in C.parallax_layers)
var/obj/screen/parallax_layer/L = thing
var/T = PARALLAX_LOOP_TIME / L.speed
if (isnull(shortesttimer))
shortesttimer = T
if (T < shortesttimer)
shortesttimer = T
L.transform = newtransform
animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW)
if (new_parallax_movedir)
var/T = PARALLAX_LOOP_TIME / L.speed
if (isnull(shortesttimer))
shortesttimer = T
if (T < shortesttimer)
shortesttimer = T
L.transform = newtransform
animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter
animate(L, transform = matrix(), time = T, easing = QUAD_EASING | (new_parallax_movedir ? EASE_IN : EASE_OUT), flags = ANIMATION_END_NOW)
if (new_parallax_movedir)
L.transform = newtransform
animate(transform = matrix(), time = T) //queue up another animate so lag doesn't create a shutter
C.parallax_movedir = new_parallax_movedir
if (C.parallax_animate_timer)
deltimer(C.parallax_animate_timer)
C.parallax_animate_timer = addtimer(CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform), min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE)
var/datum/callback/CB = CALLBACK(src, .proc/update_parallax_motionblur, C, animatedir, new_parallax_movedir, newtransform)
if(skip_windups)
CB.Invoke()
else
C.parallax_animate_timer = addtimer(CB, min(shortesttimer, PARALLAX_LOOP_TIME), TIMER_CLIENT_TIME|TIMER_STOPPABLE)
/datum/hud/proc/update_parallax_motionblur(client/C, animatedir, new_parallax_movedir, matrix/newtransform)
@@ -151,7 +166,7 @@
var/area/areaobj = posobj.loc
// Update the movement direction of the parallax if necessary (for shuttles)
set_parallax_movedir(areaobj.parallax_movedir)
set_parallax_movedir(areaobj.parallax_movedir, FALSE)
var/force
if(!C.previous_turf || (C.previous_turf.z != posobj.z))
@@ -204,6 +219,11 @@
if(M && M.client && M.hud_used && length(M.client.parallax_layers))
M.hud_used.update_parallax()
/mob/proc/update_parallax_teleport() //used for arrivals shuttle
if(client && client.eye && hud_used && length(client.parallax_layers))
var/area/areaobj = get_area(client.eye)
hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE)
/obj/screen/parallax_layer
icon = 'icons/effects/parallax.dmi'
var/speed = 1
@@ -216,7 +236,7 @@
mouse_opacity = 0
/obj/screen/parallax_layer/New(view)
/obj/screen/parallax_layer/Initialize(mapload, view)
..()
if (!view)
view = world.view
@@ -249,26 +269,6 @@
speed = 1
layer = 2
/obj/screen/parallax_pmaster
appearance_flags = PLANE_MASTER
plane = PLANE_SPACE_PARALLAX
blend_mode = BLEND_MULTIPLY
mouse_opacity = FALSE
screen_loc = "CENTER-7,CENTER-7"
/obj/screen/parallax_space_whitifier
appearance_flags = PLANE_MASTER
plane = PLANE_SPACE
color = list(
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 1,
0, 0, 0, 0
)
screen_loc = "CENTER-7,CENTER-7"
#undef LOOP_NONE
#undef LOOP_NORMAL
#undef LOOP_REVERSE
+23 -12
View File
@@ -4,15 +4,9 @@
appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR
blend_mode = BLEND_OVERLAY
/obj/screen/plane_master/New()
if(blend_mode == BLEND_MULTIPLY)
//What is this? Read http://www.byond.com/forum/?post=2141928
var/image/backdrop = image('icons/mob/screen_gen.dmi', "black")
backdrop.transform = matrix(200, 0, 0, 0, 200, 0)
backdrop.layer = BACKGROUND_LAYER
backdrop.blend_mode = BLEND_OVERLAY
add_overlay(backdrop)
..()
//Why do plane masters need a backdrop sometimes? Read http://www.byond.com/forum/?post=2141928
//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong.
/obj/screen/plane_master/proc/backdrop(mob/mymob)
/obj/screen/plane_master/game_world
name = "game world plane master"
@@ -22,7 +16,24 @@
/obj/screen/plane_master/lighting
name = "lighting plane master"
plane = LIGHTING_PLANE
blend_mode = BLEND_OVERLAY
// blend_mode = BLEND_MULTIPLY
// color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,0, 0.1,0.1,0.1,0)
blend_mode = BLEND_MULTIPLY
mouse_opacity = 0
/obj/screen/plane_master/lighting/proc/params2color(params)
color = params2list(params)
/obj/screen/plane_master/lighting/proc/basecolor()
color = LIGHTING_BASE_MATRIX
/obj/screen/plane_master/parallax
name = "parallax plane master"
plane = PLANE_SPACE_PARALLAX
blend_mode = BLEND_MULTIPLY
mouse_opacity = FALSE
/obj/screen/plane_master/parallax_white
name = "parallax whitifier plane master"
plane = PLANE_SPACE
/obj/screen/plane_master/lighting/backdrop(mob/mymob)
mymob.overlay_fullscreen("lighting_backdrop_lit", /obj/screen/fullscreen/lighting_backdrop/lit)
mymob.overlay_fullscreen("lighting_backdrop_unlit", /obj/screen/fullscreen/lighting_backdrop/unlit)
+1 -1
View File
@@ -206,7 +206,7 @@
screenmob.client.screen += module_store_icon //"store" icon
if(!R.module.modules)
usr << "<span class='danger'>Selected module has no modules to select</span>"
to_chat(usr, "<span class='danger'>Selected module has no modules to select</span>")
return
if(!R.robot_modules_background)
+28 -20
View File
@@ -80,7 +80,7 @@
return 1
var/area/A = get_area(usr)
if(!A.outdoors)
usr << "<span class='warning'>There is already a defined structure here.</span>"
to_chat(usr, "<span class='warning'>There is already a defined structure here.</span>")
return 1
create_area(usr)
@@ -159,7 +159,7 @@
// We don't even know if it's a middle click
if(world.time <= usr.next_move)
return 1
if(usr.incapacitated())
if(usr.incapacitated() || isobserver(usr))
return 1
if (istype(usr.loc,/obj/mecha)) // stops inventory actions in a mech
return 1
@@ -241,49 +241,49 @@
if(C.internal)
C.internal = null
C << "<span class='notice'>You are no longer running on internals.</span>"
to_chat(C, "<span class='notice'>You are no longer running on internals.</span>")
icon_state = "internal0"
else
if(!C.getorganslot("breathing_tube"))
if(!istype(C.wear_mask, /obj/item/clothing/mask))
C << "<span class='warning'>You are not wearing an internals mask!</span>"
to_chat(C, "<span class='warning'>You are not wearing an internals mask!</span>")
return 1
else
var/obj/item/clothing/mask/M = C.wear_mask
if(M.mask_adjusted) // if mask on face but pushed down
M.adjustmask(C) // adjust it back
if( !(M.flags & MASKINTERNALS) )
C << "<span class='warning'>You are not wearing an internals mask!</span>"
to_chat(C, "<span class='warning'>You are not wearing an internals mask!</span>")
return
var/obj/item/I = C.is_holding_item_of_type(/obj/item/weapon/tank)
if(I)
C << "<span class='notice'>You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))].</span>"
to_chat(C, "<span class='notice'>You are now running on internals from the [I] on your [C.get_held_index_name(C.get_held_index_of_item(I))].</span>")
C.internal = I
else if(ishuman(C))
var/mob/living/carbon/human/H = C
if(istype(H.s_store, /obj/item/weapon/tank))
H << "<span class='notice'>You are now running on internals from the [H.s_store] on your [H.wear_suit].</span>"
to_chat(H, "<span class='notice'>You are now running on internals from the [H.s_store] on your [H.wear_suit].</span>")
H.internal = H.s_store
else if(istype(H.belt, /obj/item/weapon/tank))
H << "<span class='notice'>You are now running on internals from the [H.belt] on your belt.</span>"
to_chat(H, "<span class='notice'>You are now running on internals from the [H.belt] on your belt.</span>")
H.internal = H.belt
else if(istype(H.l_store, /obj/item/weapon/tank))
H << "<span class='notice'>You are now running on internals from the [H.l_store] in your left pocket.</span>"
to_chat(H, "<span class='notice'>You are now running on internals from the [H.l_store] in your left pocket.</span>")
H.internal = H.l_store
else if(istype(H.r_store, /obj/item/weapon/tank))
H << "<span class='notice'>You are now running on internals from the [H.r_store] in your right pocket.</span>"
to_chat(H, "<span class='notice'>You are now running on internals from the [H.r_store] in your right pocket.</span>")
H.internal = H.r_store
//Seperate so CO2 jetpacks are a little less cumbersome.
if(!C.internal && istype(C.back, /obj/item/weapon/tank))
C << "<span class='notice'>You are now running on internals from the [C.back] on your back.</span>"
to_chat(C, "<span class='notice'>You are now running on internals from the [C.back] on your back.</span>")
C.internal = C.back
if(C.internal)
icon_state = "internal1"
else
C << "<span class='warning'>You don't have an oxygen tank!</span>"
to_chat(C, "<span class='warning'>You don't have an oxygen tank!</span>")
return
C.update_action_buttons_icon()
@@ -667,21 +667,29 @@
L.say(pick(word_messages))
/obj/screen/splash
icon = 'icons/misc/fullscreen.dmi'
icon_state = "title"
icon = 'config/title_screens/images/blank.png'
icon_state = ""
screen_loc = "1,1"
layer = SPLASHSCREEN_LAYER
plane = SPLASHSCREEN_PLANE
var/client/holder
/obj/screen/splash/New(client/C, fadeout, qdel_after = TRUE)
..()
/obj/screen/splash/New(client/C, visible, use_previous_title)
holder = C
if(!visible)
alpha = 0
if(SStitle.title_screen)
icon = SStitle.title_screen.icon
holder.screen += src
var/titlescreen = TITLESCREEN
if(titlescreen)
icon_state = titlescreen
if(fadeout)
if(use_previous_title && !SSmapping.previous_map_config.defaulted)
holder.screen -= src //Yell at Cyberboss to finish this
..()
/obj/screen/splash/proc/Fade(out, qdel_after = TRUE)
if(out)
animate(src, alpha = 0, time = 30)
else
alpha = 0
+2 -5
View File
@@ -11,17 +11,14 @@
return
/obj/attackby(obj/item/I, mob/living/user, params)
if(unique_rename && istype(I, /obj/item/weapon/pen))
rewrite(user)
else
return I.attack_obj(src, user)
return I.attack_obj(src, user)
/mob/living/attackby(obj/item/I, mob/user, params)
user.changeNext_move(CLICK_CD_MELEE)
if(user.a_intent == INTENT_HARM && stat == DEAD && butcher_results) //can we butcher it?
var/sharpness = I.is_sharp()
if(sharpness)
user << "<span class='notice'>You begin to butcher [src]...</span>"
to_chat(user, "<span class='notice'>You begin to butcher [src]...</span>")
playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
if(do_mob(user, src, 80/sharpness))
harvest(user)
+2 -2
View File
@@ -71,13 +71,13 @@
if(awaygate)
user.forceMove(awaygate.loc)
else
user << "[src] has no destination."
to_chat(user, "[src] has no destination.")
/obj/machinery/gateway/centeraway/attack_ghost(mob/user)
if(stationgate)
user.forceMove(stationgate.loc)
else
user << "[src] has no destination."
to_chat(user, "[src] has no destination.")
/obj/item/weapon/storage/attack_ghost(mob/user)
orient2hud(user)
+2 -2
View File
@@ -7,7 +7,7 @@
/mob/living/carbon/human/UnarmedAttack(atom/A, proximity)
if(!has_active_hand()) //can't attack without a hand.
src << "<span class='notice'>You look at your arm and sigh.</span>"
to_chat(src, "<span class='notice'>You look at your arm and sigh.</span>")
return
// Special glove functions:
@@ -200,5 +200,5 @@
New Players:
Have no reason to click on anything at all.
*/
/mob/new_player/ClickOn()
/mob/dead/new_player/ClickOn()
return
+1 -1
View File
@@ -152,7 +152,7 @@ var/const/tk_maxrange = 15
if(focus)
d = max(d,get_dist(user,focus)) // whichever is further
if(d > tk_maxrange)
user << "<span class ='warning'>Your mind won't reach that far.</span>"
to_chat(user, "<span class ='warning'>Your mind won't reach that far.</span>")
return 0
return 1
+6 -5
View File
@@ -1,8 +1,10 @@
// Clickable stat() button.
/obj/effect/statclick
name = "Initializing..."
var/target
/obj/effect/statclick/New(text, target)
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
..()
name = text
src.target = target
@@ -14,10 +16,10 @@
var/class
/obj/effect/statclick/debug/Click()
if(!usr.client.holder)
if(!usr.client.holder || !target)
return
if(!class)
if(istype(target, /datum/subsystem))
if(istype(target, /datum/controller/subsystem))
class = "subsystem"
else if(istype(target, /datum/controller))
class = "controller"
@@ -40,8 +42,7 @@
return
switch(controller)
if("Master")
new/datum/controller/master()
Master.process()
Recreate_MC()
feedback_add_details("admin_verb","RMC")
if("Failsafe")
new /datum/controller/failsafe()
+42 -37
View File
@@ -5,23 +5,24 @@
#define SECURITY_HAS_MAINT_ACCESS 2
#define EVERYONE_HAS_MAINT_ACCESS 4
//Not accessible from usual debug controller verb
/datum/protected_configuration
var/autoadmin = 0
var/autoadmin_rank = "Game Admin"
/datum/configuration/vv_get_var(var_name)
var/static/list/banned_views = list("autoadmin", "autoadmin_rank")
if(var_name in banned_views)
return debug_variable(var_name, "SECRET", 0, src)
return ..()
/datum/protected_configuration/SDQL_update()
return FALSE
/datum/protected_configuration/vv_get_var(var_name)
return debug_variable(var_name, "SECRET", 0, src)
/datum/protected_configuration/vv_edit_var(var_name, var_value)
return FALSE
/datum/configuration/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank")
if(var_name in banned_edits)
return FALSE
return ..()
/datum/configuration
var/name = "Configuration" // datum name
var/autoadmin = 0
var/autoadmin_rank = "Game Admin"
var/server_name = null // server name (the name of the game window)
var/server_sql_name = null // short form server name used for the DB
var/station_name = null // station name (the name of the station in-game)
@@ -218,10 +219,11 @@
var/announce_admin_logout = 0
var/announce_admin_login = 0
var/list/datum/votablemap/maplist = list()
var/datum/votablemap/defaultmap = null
var/list/datum/map_config/maplist = list()
var/datum/map_config/defaultmap = null
var/maprotation = 1
var/maprotatechancedelta = 0.75
var/allow_map_voting = TRUE
// Enables random events mid-round when set to 1
var/allow_random_events = 0
@@ -239,6 +241,8 @@
var/client_error_message = "Your version of byond is too old, may have issues, and is blocked from accessing this server."
var/cross_name = "Other server"
var/cross_address = "byond://"
var/cross_allowed = FALSE
var/showircname = 0
var/list/gamemode_cache = null
@@ -251,6 +255,9 @@
var/error_silence_time = 6000 // How long a unique error will be silenced for
var/error_msg_delay = 50 // How long to wait between messaging admins about occurrences of a unique error
var/arrivals_shuttle_dock_window = 55 //Time from when a player late joins on the arrivals shuttle to when the shuttle docks on the station
var/arrivals_shuttle_require_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join
/datum/configuration/New()
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
for(var/T in gamemode_cache)
@@ -418,9 +425,9 @@
if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
global.comms_allowed = 1
if("cross_server_address")
global.cross_address = value
cross_address = value
if(value != "byond:\\address:port")
global.cross_allowed = 1
cross_allowed = 1
if("cross_comms_name")
cross_name = value
if("panic_server_name")
@@ -488,12 +495,14 @@
config.announce_admin_login = 1
if("maprotation")
config.maprotation = 1
if("allow_map_voting")
config.allow_map_voting = text2num(value)
if("maprotationchancedelta")
config.maprotatechancedelta = text2num(value)
if("autoadmin")
protected_config.autoadmin = 1
config.autoadmin = 1
if(value)
protected_config.autoadmin_rank = ckeyEx(value)
config.autoadmin_rank = ckeyEx(value)
if("generate_minimaps")
config.generate_minimaps = 1
if("client_warn_version")
@@ -516,12 +525,6 @@
error_silence_time = text2num(value)
if("error_msg_delay")
error_msg_delay = text2num(value)
if("announce_adminhelps")
config.announce_adminhelps = 1
if("discord_url")
config.discord_url = value
if("discord_password")
config.discord_password = value
else
diary << "Unknown setting in configuration: '[name]'"
@@ -749,6 +752,10 @@
MAX_EX_LIGHT_RANGE = BombCap
MAX_EX_FLASH_RANGE = BombCap
MAX_EX_FLAME_RANGE = BombCap
if("arrivals_shuttle_dock_window")
config.arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value))
if("arrivals_shuttle_require_safe_latejoin")
config.arrivals_shuttle_require_safe_latejoin = text2num(value)
else
diary << "Unknown setting in configuration: '[name]'"
@@ -760,7 +767,7 @@
/datum/configuration/proc/loadmaplist(filename)
var/list/Lines = file2list(filename)
var/datum/votablemap/currentmap = null
var/datum/map_config/currentmap = null
for(var/t in Lines)
if(!t)
continue
@@ -789,21 +796,19 @@
switch (command)
if ("map")
currentmap = new (data)
if ("friendlyname")
currentmap.friendlyname = data
currentmap = new ("_maps/[data].json")
if(currentmap.defaulted)
log_world("Failed to load map config for [data]!")
if ("minplayers","minplayer")
currentmap.minusers = text2num(data)
currentmap.config_min_users = text2num(data)
if ("maxplayers","maxplayer")
currentmap.maxusers = text2num(data)
if ("friendlyname")
currentmap.friendlyname = data
currentmap.config_max_users = text2num(data)
if ("weight","voteweight")
currentmap.voteweight = text2num(data)
if ("default","defaultmap")
config.defaultmap = currentmap
if ("endmap")
config.maplist[currentmap.name] = currentmap
config.maplist[currentmap.map_name] = currentmap
currentmap = null
else
diary << "Unknown command in map vote config: '[command]'"
@@ -866,7 +871,7 @@
var/list/datum/game_mode/runnable_modes = new
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
//world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]"
//to_chat(world, "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]")
if(!(M.config_tag in modes))
qdel(M)
continue
@@ -879,7 +884,7 @@
M.maximum_players = max_pop[M.config_tag]
if(M.can_start())
runnable_modes[M] = probabilities[M.config_tag]
//world << "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]"
//to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]")
return runnable_modes
/datum/configuration/proc/get_runnable_midround_modes(crew)
@@ -904,6 +909,6 @@
/datum/configuration/proc/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Edit", src)
statclick = new/obj/effect/statclick/debug(null, "Edit", src)
stat("[name]:", statclick)
stat("[name]:", statclick)
+16 -1
View File
@@ -1,4 +1,19 @@
/datum/controller
var/name
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
var/obj/effect/statclick/statclick
/datum/controller/proc/Initialize()
//cleanup actions
/datum/controller/proc/Shutdown()
//when we enter dmm_suite.load_map
/datum/controller/proc/StartLoadingMap()
//when we exit dmm_suite.load_map
/datum/controller/proc/StopLoadingMap()
/datum/controller/proc/Recover()
/datum/controller/proc/stat_entry()
+15 -12
View File
@@ -20,6 +20,7 @@ var/datum/controller/failsafe/Failsafe
// Track the MC iteration to make sure its still on track.
var/master_iteration = 0
var/running = TRUE
/datum/controller/failsafe/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
@@ -27,19 +28,21 @@ var/datum/controller/failsafe/Failsafe
if(istype(Failsafe))
qdel(Failsafe)
Failsafe = src
LaunchLoop()
Initialize()
/datum/controller/failsafe/proc/LaunchLoop()
/datum/controller/failsafe/Initialize()
set waitfor = 0
Failsafe.Loop()
qdel(Failsafe) //when Loop() returns, we delete ourselves and let the mc recreate us
if(!QDELETED(src))
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
/datum/controller/failsafe/Destroy()
running = FALSE
..()
return QDEL_HINT_HARDDEL_NOW
/datum/controller/failsafe/proc/Loop()
while(1)
while(running)
lasttick = world.time
if(!Master)
// Replace the missing Master! This should never, ever happen.
@@ -53,23 +56,23 @@ var/datum/controller/failsafe/Failsafe
if(4,5)
--defcon
if(3)
admins << "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks."
to_chat(admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.")
--defcon
if(2)
admins << "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>"
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
--defcon
if(1)
admins << "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>"
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
--defcon
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
admins << "<span class='adminnotice'>MC restarted successfully</span>"
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
else if(rtn < 0)
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
admins << "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>"
to_chat(admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
//no need to handle that specially when defcon 0 can handle it
if(0) //DEFCON 0! (mc failed to restart)
@@ -77,7 +80,7 @@ var/datum/controller/failsafe/Failsafe
if(rtn > 0)
defcon = 4
master_iteration = 0
admins << "<span class='adminnotice'>MC restarted successfully</span>"
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
else
defcon = min(defcon + 1,5)
master_iteration = Master.iteration
@@ -92,8 +95,8 @@ var/datum/controller/failsafe/Failsafe
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/proc/stat_entry()
/datum/controller/failsafe/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
+26 -26
View File
@@ -46,8 +46,8 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// The type of the last subsystem to be process()'d.
var/last_type_processed
var/datum/subsystem/queue_head //Start of queue linked list
var/datum/subsystem/queue_tail //End of queue linked list (used for appending to the list)
var/datum/controller/subsystem/queue_head //Start of queue linked list
var/datum/controller/subsystem/queue_tail //End of queue linked list (used for appending to the list)
var/queue_priority_count = 0 //Running total so that we don't have to loop thru the queue each run to split up the tick
var/queue_priority_count_bg = 0 //Same, but for background subsystems
var/map_loading = FALSE //Are we loading in a new map?
@@ -60,7 +60,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
Recover()
qdel(Master)
else
init_subtypes(/datum/subsystem, subsystems)
init_subtypes(/datum/controller/subsystem, subsystems)
Master = src
/datum/controller/master/Destroy()
@@ -68,9 +68,9 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// Tell qdel() to Del() this object.
return QDEL_HINT_HARDDEL_NOW
/datum/controller/master/proc/Shutdown()
/datum/controller/master/Shutdown()
processing = FALSE
for(var/datum/subsystem/ss in subsystems)
for(var/datum/controller/subsystem/ss in subsystems)
ss.Shutdown()
// Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart,
@@ -93,7 +93,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
return 1
/datum/controller/master/proc/Recover()
/datum/controller/master/Recover()
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for (var/varname in Master.vars)
switch (varname)
@@ -111,22 +111,22 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
subsystems = Master.subsystems
StartProcessing(10)
else
world << "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>"
Setup(20, TRUE)
to_chat(world, "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
Initialize(20, TRUE)
// Please don't stuff random bullshit here,
// Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize()
/datum/controller/master/proc/Setup(delay, init_sss)
/datum/controller/master/Initialize(delay, init_sss)
set waitfor = 0
if(delay)
sleep(delay)
if(init_sss)
init_subtypes(/datum/subsystem, subsystems)
init_subtypes(/datum/controller/subsystem, subsystems)
world << "<span class='boldannounce'>Initializing subsystems...</span>"
to_chat(world, "<span class='boldannounce'>Initializing subsystems...</span>")
// Sort subsystems by init_order, so they initialize in the correct order.
sortTim(subsystems, /proc/cmp_subsystem_init)
@@ -134,7 +134,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems.
CURRENT_TICKLIMIT = config.tick_limit_mc_init
for (var/datum/subsystem/SS in subsystems)
for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_NO_INIT)
continue
SS.Initialize(REALTIMEOFDAY)
@@ -143,7 +143,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
// Sort subsystems by display setting for easy access.
@@ -161,7 +161,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
/datum/controller/master/proc/RoundStart()
round_started = 1
var/timer = world.time
for (var/datum/subsystem/SS in subsystems)
for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_FIRE_IN_LOBBY || SS.flags & SS_TICKER)
continue //already firing
// Stagger subsystems.
@@ -199,7 +199,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/list/lobbysubsystems = list()
var/timer = world.time
for (var/thing in subsystems)
var/datum/subsystem/SS = thing
var/datum/controller/subsystem/SS = thing
if (SS.flags & SS_NO_FIRE)
continue
SS.queued_time = 0
@@ -261,7 +261,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
sleep_delta += 1
if (make_runtime)
var/datum/subsystem/SS
var/datum/controller/subsystem/SS
SS.can_fire = 0
if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time))
new/datum/controller/failsafe() // (re)Start the failsafe.
@@ -313,7 +313,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
. = 0 //so the mc knows if we runtimed
//we create our variables outside of the loops to save on overhead
var/datum/subsystem/SS
var/datum/controller/subsystem/SS
var/SS_flags
for (var/thing in subsystemstocheck)
@@ -339,7 +339,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// Run thru the queue of subsystems to run, running them while balancing out their allocated tick precentage
/datum/controller/master/proc/RunQueue()
. = 0
var/datum/subsystem/queue_node
var/datum/controller/subsystem/queue_node
var/queue_node_flags
var/queue_node_priority
var/queue_node_paused
@@ -465,7 +465,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/subsystemstocheck = subsystems + ticker_SS + normal_SS + lobby_SS
for (var/thing in subsystemstocheck)
var/datum/subsystem/SS = thing
var/datum/controller/subsystem/SS = thing
if (!SS || !istype(SS))
//list(SS) is so if a list makes it in the subsystem list, we remove the list, not the contents
subsystems -= list(SS)
@@ -496,24 +496,24 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
/datum/controller/master/proc/stat_entry()
/datum/controller/master/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
/datum/controller/master/proc/StartLoadingMap()
/datum/controller/master/StartLoadingMap()
//disallow more than one map to load at once, multithreading it will just cause race conditions
while(map_loading)
stoplag()
for(var/S in subsystems)
var/datum/subsystem/SS = S
var/datum/controller/subsystem/SS = S
SS.StartLoadingMap()
map_loading = TRUE
/datum/controller/master/proc/StopLoadingMap(bounds = null)
/datum/controller/master/StopLoadingMap(bounds = null)
map_loading = FALSE
for(var/S in subsystems)
var/datum/subsystem/SS = S
SS.StopLoadingMap()
var/datum/controller/subsystem/SS = S
SS.StopLoadingMap()
+22 -37
View File
@@ -1,11 +1,10 @@
/datum/subsystem
/datum/controller/subsystem
// Metadata; you should define these.
var/name = "fire coderbus" //name of the subsystem
name = "fire coderbus" //name of the subsystem
var/init_order = 0 //order of initialization. Higher numbers are initialized first, lower numbers later. Can be decimal and negative values.
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
var/display_order = 100 //display affects the order the subsystem is displayed in the MC tab
var/priority = 50 //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)
@@ -27,22 +26,14 @@
var/queued_time = 0 //time we entered the queue, (for timing and priority reasons)
var/queued_priority //we keep a running total to make the math easier, if priority changes mid-fire that would break our running total, so we store it here
//linked list stuff for the queue
var/datum/subsystem/queue_next
var/datum/subsystem/queue_prev
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
var/datum/controller/subsystem/queue_next
var/datum/controller/subsystem/queue_prev
// Used to initialize the subsystem BEFORE the map has loaded
/datum/subsystem/New()
//cleanup actions
/datum/subsystem/proc/Shutdown()
return
/datum/controller/subsystem/New()
//This is used so the mc knows when the subsystem sleeps. do not override.
/datum/subsystem/proc/ignite(resumed = 0)
/datum/controller/subsystem/proc/ignite(resumed = 0)
set waitfor = 0
. = SS_SLEEPING
fire(resumed)
@@ -58,11 +49,11 @@
//previously, this would have been named 'process()' but that name is used everywhere for different things!
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
//Sleeping in here prevents future fires until returned.
/datum/subsystem/proc/fire(resumed = 0)
/datum/controller/subsystem/proc/fire(resumed = 0)
flags |= SS_NO_FIRE
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
/datum/subsystem/Destroy()
/datum/controller/subsystem/Destroy()
dequeue()
can_fire = 0
flags |= SS_NO_FIRE
@@ -72,10 +63,10 @@
//Queue it to run.
// (we loop thru a linked list until we get to the end or find the right point)
// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
/datum/subsystem/proc/enqueue()
/datum/controller/subsystem/proc/enqueue()
var/SS_priority = priority
var/SS_flags = flags
var/datum/subsystem/queue_node
var/datum/controller/subsystem/queue_node
var/queue_node_priority
var/queue_node_flags
@@ -130,7 +121,7 @@
queue_node.queue_prev = src
/datum/subsystem/proc/dequeue()
/datum/controller/subsystem/proc/dequeue()
if (queue_next)
queue_next.queue_prev = queue_prev
if (queue_prev)
@@ -144,7 +135,7 @@
state = SS_IDLE
/datum/subsystem/proc/pause()
/datum/controller/subsystem/proc/pause()
. = 1
if (state == SS_RUNNING)
state = SS_PAUSED
@@ -153,17 +144,17 @@
//used to initialize the subsystem AFTER the map has loaded
/datum/subsystem/proc/Initialize(start_timeofday)
/datum/controller/subsystem/Initialize(start_timeofday)
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
return time
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/subsystem/proc/stat_entry(msg)
/datum/controller/subsystem/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
@@ -178,7 +169,7 @@
stat(title, statclick.update(msg))
/datum/subsystem/proc/state_letter()
/datum/controller/subsystem/proc/state_letter()
switch (state)
if (SS_RUNNING)
. = "R"
@@ -193,15 +184,15 @@
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/subsystem/proc/postpone(cycles = 1)
/datum/controller/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
//usually called via datum/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//should attempt to salvage what it can from the old instance of subsystem
/datum/subsystem/proc/Recover()
/datum/controller/subsystem/Recover()
/datum/subsystem/vv_edit_var(var_name, var_value)
/datum/controller/subsystem/vv_edit_var(var_name, var_value)
switch (var_name)
if ("can_fire")
//this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag
@@ -209,10 +200,4 @@
next_fire = world.time + wait
if ("queued_priority") //editing this breaks things.
return 0
. = ..()
//when we enter dmm_suite.load_map
/datum/subsystem/proc/StartLoadingMap()
//when we exit dmm_suite.load_map
/datum/subsystem/proc/StopLoadingMap()
. = ..()
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/acid/SSacid
var/datum/controller/subsystem/acid/SSacid
/datum/subsystem/acid
/datum/controller/subsystem/acid
name = "Acid"
priority = 40
flags = SS_NO_INIT|SS_BACKGROUND
@@ -8,15 +8,15 @@ var/datum/subsystem/acid/SSacid
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/acid/New()
/datum/controller/subsystem/acid/New()
NEW_SS_GLOBAL(SSacid)
/datum/subsystem/acid/stat_entry()
/datum/controller/subsystem/acid/stat_entry()
..("P:[processing.len]")
/datum/subsystem/acid/fire(resumed = 0)
/datum/controller/subsystem/acid/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+25 -27
View File
@@ -5,15 +5,14 @@
#define SSAIR_HIGHPRESSURE 5
#define SSAIR_HOTSPOTS 6
#define SSAIR_SUPERCONDUCTIVITY 7
var/datum/subsystem/air/SSair
var/datum/controller/subsystem/air/SSair
/datum/subsystem/air
/datum/controller/subsystem/air
name = "Air"
init_order = -1
priority = 20
wait = 5
flags = SS_BACKGROUND
display_order = 1
var/cost_turfs = 0
var/cost_groups = 0
@@ -42,10 +41,10 @@ var/datum/subsystem/air/SSair
var/map_loading = TRUE
var/list/queued_for_activation
/datum/subsystem/air/New()
/datum/controller/subsystem/air/New()
NEW_SS_GLOBAL(SSair)
/datum/subsystem/air/stat_entry(msg)
/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
msg += "AT:[round(cost_turfs,1)]|"
msg += "EG:[round(cost_groups,1)]|"
@@ -65,7 +64,7 @@ var/datum/subsystem/air/SSair
..(msg)
/datum/subsystem/air/Initialize(timeofday)
/datum/controller/subsystem/air/Initialize(timeofday)
map_loading = FALSE
setup_allturfs()
setup_atmos_machinery()
@@ -73,7 +72,7 @@ var/datum/subsystem/air/SSair
..()
/datum/subsystem/air/fire(resumed = 0)
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = world.tick_usage
if(currentpart == SSAIR_PIPENETS || !resumed)
@@ -140,7 +139,7 @@ var/datum/subsystem/air/SSair
/datum/subsystem/air/proc/process_pipenets(resumed = 0)
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
if (!resumed)
src.currentrun = networks.Copy()
//cache for sanic speed (lists are references anyways)
@@ -156,7 +155,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_atmos_machinery(resumed = 0)
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = atmos_machinery.Copy()
@@ -171,7 +170,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_super_conductivity(resumed = 0)
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
if (!resumed)
src.currentrun = active_super_conductivity.Copy()
//cache for sanic speed (lists are references anyways)
@@ -183,7 +182,7 @@ var/datum/subsystem/air/SSair
if(MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_hotspots(resumed = 0)
/datum/controller/subsystem/air/proc/process_hotspots(resumed = 0)
if (!resumed)
src.currentrun = hotspots.Copy()
//cache for sanic speed (lists are references anyways)
@@ -199,17 +198,16 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
/datum/controller/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
while (high_pressure_delta.len)
var/turf/open/T = high_pressure_delta[high_pressure_delta.len]
high_pressure_delta.len--
if (isturf(T))
T.high_pressure_movements()
T.pressure_difference = 0
T.high_pressure_movements()
T.pressure_difference = 0
if(MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_active_turfs(resumed = 0)
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
//cache for sanic speed
var/fire_count = times_fired
if (!resumed)
@@ -219,12 +217,12 @@ var/datum/subsystem/air/SSair
while(currentrun.len)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if (T && isturf(T))
if (T)
T.process_cell(fire_count)
if (MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_excited_groups(resumed = 0)
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
if (!resumed)
src.currentrun = excited_groups.Copy()
//cache for sanic speed (lists are references anyways)
@@ -242,7 +240,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/remove_from_active(turf/open/T)
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
active_turfs -= T
if(currentpart == SSAIR_ACTIVETURFS)
currentrun -= T
@@ -251,7 +249,7 @@ var/datum/subsystem/air/SSair
if(T.excited_group)
T.excited_group.garbage_collect()
/datum/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
if(istype(T) && T.air)
T.excited = 1
active_turfs |= T
@@ -269,17 +267,17 @@ var/datum/subsystem/air/SSair
else
T.requires_activation = TRUE
/datum/subsystem/air/StartLoadingMap()
/datum/controller/subsystem/air/StartLoadingMap()
LAZYINITLIST(queued_for_activation)
map_loading = TRUE
/datum/subsystem/air/StopLoadingMap()
/datum/controller/subsystem/air/StopLoadingMap()
map_loading = FALSE
for(var/T in queued_for_activation)
add_to_active(T)
queued_for_activation.Cut()
/datum/subsystem/air/proc/setup_allturfs()
/datum/controller/subsystem/air/proc/setup_allturfs()
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
var/list/active_turfs = src.active_turfs
var/times_fired = ++src.times_fired
@@ -320,7 +318,7 @@ var/datum/subsystem/air/SSair
CHECK_TICK
var/msg = "HEY! LISTEN! [(world.timeofday - timer)/10] Seconds were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
warning(msg)
/turf/open/proc/resolve_active_graph()
@@ -349,7 +347,7 @@ var/datum/subsystem/air/SSair
/turf/open/space/resolve_active_graph()
return list()
/datum/subsystem/air/proc/setup_atmos_machinery()
/datum/controller/subsystem/air/proc/setup_atmos_machinery()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
AM.atmosinit()
CHECK_TICK
@@ -357,12 +355,12 @@ var/datum/subsystem/air/SSair
//this can't be done with setup_atmos_machinery() because
// all atmos machinery has to initalize before the first
// pipenet can be built.
/datum/subsystem/air/proc/setup_pipenets()
/datum/controller/subsystem/air/proc/setup_pipenets()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
AM.build_network()
CHECK_TICK
/datum/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
/datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
for(var/A in atmos_machines)
var/obj/machinery/atmospherics/AM = A
AM.atmosinit()
+4 -4
View File
@@ -1,15 +1,15 @@
var/datum/subsystem/assets/SSasset
var/datum/controller/subsystem/assets/SSasset
/datum/subsystem/assets
/datum/controller/subsystem/assets
name = "Assets"
init_order = -3
flags = SS_NO_FIRE
var/list/cache = list()
/datum/subsystem/assets/New()
/datum/controller/subsystem/assets/New()
NEW_SS_GLOBAL(SSasset)
/datum/subsystem/assets/Initialize(timeofday)
/datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()
+21 -9
View File
@@ -1,10 +1,10 @@
var/datum/subsystem/atoms/SSatoms
var/datum/controller/subsystem/atoms/SSatoms
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
/datum/subsystem/atoms
/datum/controller/subsystem/atoms
name = "Atoms"
init_order = 11
flags = SS_NO_FIRE
@@ -12,17 +12,17 @@ var/datum/subsystem/atoms/SSatoms
var/initialized = INITIALIZATION_INSSATOMS
var/old_initialized
/datum/subsystem/atoms/New()
/datum/controller/subsystem/atoms/New()
NEW_SS_GLOBAL(SSatoms)
/datum/subsystem/atoms/Initialize(timeofday)
/datum/controller/subsystem/atoms/Initialize(timeofday)
fire_overlay.appearance_flags = RESET_COLOR
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
initialized = INITIALIZATION_INNEW_MAPLOAD
InitializeAtoms()
return ..()
/datum/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
if(initialized == INITIALIZATION_INSSATOMS)
return
@@ -30,10 +30,17 @@ var/datum/subsystem/atoms/SSatoms
initialized = INITIALIZATION_INNEW_MAPLOAD
var/static/list/NewQdelList = list()
if(atoms)
for(var/I in atoms)
var/atom/A = I
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
if(QDELETED(A))
if(!(NewQdelList[A.type]))
stack_trace("Found new qdeletion in type [A.type]!")
NewQdelList[A.type] = TRUE
continue
var/start_tick = world.time
if(A.Initialize(TRUE))
LAZYADD(late_loaders, A)
@@ -47,6 +54,11 @@ var/datum/subsystem/atoms/SSatoms
#endif
for(var/atom/A in world)
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
if(QDELETED(A))
if(!(NewQdelList[A.type]))
stack_trace("Found new qdeletion in type [A.type]!")
NewQdelList[A.type] = TRUE
continue
var/start_tick = world.time
if(A.Initialize(TRUE))
LAZYADD(late_loaders, A)
@@ -71,20 +83,20 @@ var/datum/subsystem/atoms/SSatoms
CHECK_TICK
testing("Late-initialized [late_loaders.len] atoms")
/datum/subsystem/atoms/proc/map_loader_begin()
/datum/controller/subsystem/atoms/proc/map_loader_begin()
old_initialized = initialized
initialized = INITIALIZATION_INSSATOMS
/datum/subsystem/atoms/proc/map_loader_stop()
/datum/controller/subsystem/atoms/proc/map_loader_stop()
initialized = old_initialized
/datum/subsystem/atoms/Recover()
/datum/controller/subsystem/atoms/Recover()
initialized = SSatoms.initialized
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
InitializeAtoms()
old_initialized = SSatoms.old_initialized
/datum/subsystem/atoms/proc/setupGenetics()
/datum/controller/subsystem/atoms/proc/setupGenetics()
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
avnums[i] = i
+8 -8
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/augury/SSaugury
var/datum/controller/subsystem/augury/SSaugury
/datum/subsystem/augury
/datum/controller/subsystem/augury
name = "Augury"
flags = SS_NO_INIT
@@ -9,16 +9,16 @@ var/datum/subsystem/augury/SSaugury
var/list/observers_given_action = list()
/datum/subsystem/augury/New()
/datum/controller/subsystem/augury/New()
NEW_SS_GLOBAL(SSaugury)
/datum/subsystem/augury/stat_entry(msg)
/datum/controller/subsystem/augury/stat_entry(msg)
..("W:[watchers.len]|D:[doombringers.len]")
/datum/subsystem/augury/proc/register_doom(atom/A, severity)
/datum/controller/subsystem/augury/proc/register_doom(atom/A, severity)
doombringers[A] = severity
/datum/subsystem/augury/fire()
/datum/controller/subsystem/augury/fire()
var/biggest_doom = null
var/biggest_threat = null
@@ -67,13 +67,13 @@ var/datum/subsystem/augury/SSaugury
/datum/action/innate/augury/Activate()
SSaugury.watchers += owner
owner << "<span class='notice'>You are now auto-following debris.</span>"
to_chat(owner, "<span class='notice'>You are now auto-following debris.</span>")
active = TRUE
UpdateButtonIcon()
/datum/action/innate/augury/Deactivate()
SSaugury.watchers -= owner
owner << "<span class='notice'>You are no longer auto-following debris.</span>"
to_chat(owner, "<span class='notice'>You are no longer auto-following debris.</span>")
active = FALSE
UpdateButtonIcon()
+5 -5
View File
@@ -1,19 +1,19 @@
#define COMMUNICATION_COOLDOWN 600
#define COMMUNICATION_COOLDOWN_AI 600
var/datum/subsystem/communications/SScommunications
var/datum/controller/subsystem/communications/SScommunications
/datum/subsystem/communications
/datum/controller/subsystem/communications
name = "Communications"
flags = SS_NO_INIT | SS_NO_FIRE
var/silicon_message_cooldown
var/nonsilicon_message_cooldown
/datum/subsystem/communications/New()
/datum/controller/subsystem/communications/New()
NEW_SS_GLOBAL(SScommunications)
/datum/subsystem/communications/proc/can_announce(mob/living/user, is_silicon)
/datum/controller/subsystem/communications/proc/can_announce(mob/living/user, is_silicon)
if(is_silicon && silicon_message_cooldown > world.time)
. = FALSE
else if(!is_silicon && nonsilicon_message_cooldown > world.time)
@@ -21,7 +21,7 @@ var/datum/subsystem/communications/SScommunications
else
. = TRUE
/datum/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input)
/datum/controller/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input)
if(!can_announce(user, is_silicon))
return FALSE
if(is_silicon)
+5 -5
View File
@@ -1,19 +1,19 @@
var/datum/subsystem/diseases/SSdisease
var/datum/controller/subsystem/diseases/SSdisease
/datum/subsystem/diseases
/datum/controller/subsystem/diseases
name = "Diseases"
flags = SS_KEEP_TIMING|SS_NO_INIT
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/diseases/New()
/datum/controller/subsystem/diseases/New()
NEW_SS_GLOBAL(SSdisease)
/datum/subsystem/diseases/stat_entry(msg)
/datum/controller/subsystem/diseases/stat_entry(msg)
..("P:[processing.len]")
/datum/subsystem/diseases/fire(resumed = 0)
/datum/controller/subsystem/diseases/fire(resumed = 0)
if(!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
+23 -32
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/events/SSevent
var/datum/controller/subsystem/events/SSevent
/datum/subsystem/events
/datum/controller/subsystem/events
name = "Events"
init_order = 6
@@ -16,11 +16,11 @@ var/datum/subsystem/events/SSevent
var/wizardmode = 0
/datum/subsystem/events/New()
/datum/controller/subsystem/events/New()
NEW_SS_GLOBAL(SSevent)
/datum/subsystem/events/Initialize(time, zlevel)
/datum/controller/subsystem/events/Initialize(time, zlevel)
for(var/type in typesof(/datum/round_event_control))
var/datum/round_event_control/E = new type()
if(!E.typepath)
@@ -31,7 +31,7 @@ var/datum/subsystem/events/SSevent
..()
/datum/subsystem/events/fire(resumed = 0)
/datum/controller/subsystem/events/fire(resumed = 0)
if(!resumed)
checkEvent() //only check these if we aren't resuming a paused fire
src.currentrun = running.Copy()
@@ -50,23 +50,18 @@ var/datum/subsystem/events/SSevent
return
//checks if we should select a random event yet, and reschedules if necessary
/datum/subsystem/events/proc/checkEvent()
/datum/controller/subsystem/events/proc/checkEvent()
if(scheduled <= world.time)
spawnEvent()
reschedule()
//decides which world.time we should select another random event at.
/datum/subsystem/events/proc/reschedule()
/datum/controller/subsystem/events/proc/reschedule()
scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper))
if(world.time > 108000) //2:45
if(SSshuttle.emergency.mode < SHUTTLE_CALL)
SSshuttle.emergency.request(null, 1.5)
log_game("Round time limit reached. Shuttle has been auto-called.")
message_admins("Round time limit reached. Shuttle called.")
//selects a random event based on whether it can occur and it's 'weight'(probability)
/datum/subsystem/events/proc/spawnEvent()
/datum/controller/subsystem/events/proc/spawnEvent()
set waitfor = FALSE //for the admin prompt
if(!config.allow_random_events)
// var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control
// if(E) E.runEvent()
@@ -81,13 +76,8 @@ var/datum/subsystem/events/SSevent
if(!E.canSpawnEvent(players_amt, gamemode))
continue
if(E.weight < 0) //for round-start events etc.
if(E.runEvent() == PROCESS_KILL)
E.max_occurrences = 0
continue
if (E.alertadmins)
message_admins("Random Event triggering: [E.name] ([E.typepath])")
log_game("Random Event triggering: [E.name] ([E.typepath])")
return
if(TriggerEvent(E))
return
sum_of_weights += E.weight
sum_of_weights = rand(0,sum_of_weights) //reusing this variable. It now represents the 'weight' we want to select
@@ -98,14 +88,15 @@ var/datum/subsystem/events/SSevent
sum_of_weights -= E.weight
if(sum_of_weights <= 0) //we've hit our goal
if(E.runEvent() == PROCESS_KILL)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
continue
if (E.alertadmins)
message_admins("Random Event triggering: [E.name] ([E.typepath])")
deadchat_broadcast("<span class='deadsay'><b>[E.name]</b> has just been randomly triggered!</span>") //STOP ASSUMING IT'S BADMINS!
log_game("Random Event triggering: [E.name] ([E.typepath])")
return
if(TriggerEvent(E))
return
/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/E)
. = E.preRunEvent()
if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
else if(. != EVENT_CANCELLED)
E.runEvent(TRUE)
/datum/round_event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in!
var/list/safe_areas = list(
@@ -180,7 +171,7 @@ var/datum/subsystem/events/SSevent
*/
//sets up the holidays and holidays list
/datum/subsystem/events/proc/getHoliday()
/datum/controller/subsystem/events/proc/getHoliday()
if(!config.allow_holidays)
return // Holiday stuff was not enabled in the config!
@@ -200,12 +191,12 @@ var/datum/subsystem/events/SSevent
holidays = shuffle(holidays)
world.update_status()
/datum/subsystem/events/proc/toggleWizardmode()
/datum/controller/subsystem/events/proc/toggleWizardmode()
wizardmode = !wizardmode
message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [SSevent.frequency_lower / 600] to [SSevent.frequency_upper / 600] minutes" : "disabled"]!")
log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
/datum/subsystem/events/proc/resetFrequency()
/datum/controller/subsystem/events/proc/resetFrequency()
frequency_lower = initial(frequency_lower)
frequency_upper = initial(frequency_upper)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/fire_burning/SSfire_burning
var/datum/controller/subsystem/fire_burning/SSfire_burning
/datum/subsystem/fire_burning
/datum/controller/subsystem/fire_burning
name = "Fire Burning"
priority = 40
flags = SS_NO_INIT|SS_BACKGROUND
@@ -8,15 +8,15 @@ var/datum/subsystem/fire_burning/SSfire_burning
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/fire_burning/New()
/datum/controller/subsystem/fire_burning/New()
NEW_SS_GLOBAL(SSfire_burning)
/datum/subsystem/fire_burning/stat_entry()
/datum/controller/subsystem/fire_burning/stat_entry()
..("P:[processing.len]")
/datum/subsystem/fire_burning/fire(resumed = 0)
/datum/controller/subsystem/fire_burning/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+11 -23
View File
@@ -1,10 +1,9 @@
var/datum/subsystem/garbage_collector/SSgarbage
var/datum/controller/subsystem/garbage_collector/SSgarbage
/datum/subsystem/garbage_collector
/datum/controller/subsystem/garbage_collector
name = "Garbage"
priority = 15
wait = 5
display_order = 2
flags = SS_FIRE_IN_LOBBY|SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
@@ -35,10 +34,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
var/list/qdel_list = list() // list of all types that have been qdel()eted
#endif
/datum/subsystem/garbage_collector/New()
/datum/controller/subsystem/garbage_collector/New()
NEW_SS_GLOBAL(SSgarbage)
/datum/subsystem/garbage_collector/stat_entry(msg)
/datum/controller/subsystem/garbage_collector/stat_entry(msg)
msg += "Q:[queue.len]|D:[delslasttick]|G:[gcedlasttick]|"
msg += "GR:"
if (!(delslasttick+gcedlasttick))
@@ -53,14 +52,14 @@ var/datum/subsystem/garbage_collector/SSgarbage
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
..(msg)
/datum/subsystem/garbage_collector/fire()
/datum/controller/subsystem/garbage_collector/fire()
HandleToBeQueued()
if(state == SS_RUNNING)
HandleQueue()
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
//Don't attempt to optimize, not worth the effort.
/datum/subsystem/garbage_collector/proc/HandleToBeQueued()
/datum/controller/subsystem/garbage_collector/proc/HandleToBeQueued()
var/list/tobequeued = src.tobequeued
var/starttime = world.time
var/starttimeofday = world.timeofday
@@ -71,7 +70,7 @@ var/datum/subsystem/garbage_collector/SSgarbage
Queue(ref)
tobequeued.Cut(1, 2)
/datum/subsystem/garbage_collector/proc/HandleQueue()
/datum/controller/subsystem/garbage_collector/proc/HandleQueue()
delslasttick = 0
gcedlasttick = 0
var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del()
@@ -125,12 +124,12 @@ var/datum/subsystem/garbage_collector/SSgarbage
++gcedlasttick
++totalgcs
/datum/subsystem/garbage_collector/proc/QueueForQueuing(datum/A)
/datum/controller/subsystem/garbage_collector/proc/QueueForQueuing(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_QUEUING
/datum/subsystem/garbage_collector/proc/Queue(datum/A)
/datum/controller/subsystem/garbage_collector/proc/Queue(datum/A)
if (!istype(A) || (!isnull(A.gc_destroyed) && A.gc_destroyed >= 0))
return
if (A.gc_destroyed == GC_QUEUED_FOR_HARD_DEL)
@@ -146,12 +145,12 @@ var/datum/subsystem/garbage_collector/SSgarbage
queue[refid] = gctime
/datum/subsystem/garbage_collector/proc/HardQueue(datum/A)
/datum/controller/subsystem/garbage_collector/proc/HardQueue(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_HARD_DEL
/datum/subsystem/garbage_collector/Recover()
/datum/controller/subsystem/garbage_collector/Recover()
if (istype(SSgarbage.queue))
queue |= SSgarbage.queue
if (istype(SSgarbage.tobequeued))
@@ -351,9 +350,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
//if find_references isn't working for some datum
//update this list using tools/DMTreeToGlobalsList
/datum/proc/find_references_in_globals()
SearchVar(nextmap)
SearchVar(mapchanging)
SearchVar(rebootingpendingmapchange)
SearchVar(clockwork_construction_value)
SearchVar(clockwork_caches)
SearchVar(clockwork_daemons)
@@ -398,7 +394,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(WALLITEMS_INVERSE)
SearchVar(sortInstance)
SearchVar(config)
SearchVar(protected_config)
SearchVar(host)
SearchVar(join_motd)
SearchVar(station_name)
@@ -416,8 +411,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(Debug2)
SearchVar(comms_key)
SearchVar(comms_allowed)
SearchVar(cross_address)
SearchVar(cross_allowed)
SearchVar(medal_hub)
SearchVar(medal_pass)
SearchVar(medals_enabled)
@@ -477,12 +470,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(timezoneOffset)
SearchVar(fileaccess_timer)
SearchVar(TAB)
SearchVar(map_ready)
SearchVar(data_core)
SearchVar(CELLRATE)
SearchVar(CHARGELEVEL)
SearchVar(powernets)
SearchVar(map_name)
SearchVar(hair_styles_list)
SearchVar(hair_styles_male_list)
SearchVar(hair_styles_female_list)
@@ -758,8 +749,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(fire_overlay)
SearchVar(acid_overlay)
SearchVar(BUMP_TELEPORTERS)
SearchVar(contrabandposters)
SearchVar(legitposters)
SearchVar(blacklisted_glowshroom_turfs)
SearchVar(PDAs)
SearchVar(rod_recipes)
@@ -943,7 +932,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(GALOSHES_DONT_HELP)
SearchVar(SLIDE_ICE)
SearchVar(limb_icon_cache)
SearchVar(ALIEN_AFK_BRACKET)
SearchVar(MIN_IMPREGNATION_TIME)
SearchVar(MAX_IMPREGNATION_TIME)
SearchVar(MIN_ACTIVE_TIME)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/icon_smooth/SSicon_smooth
var/datum/controller/subsystem/icon_smooth/SSicon_smooth
/datum/subsystem/icon_smooth
/datum/controller/subsystem/icon_smooth
name = "Icon Smoothing"
init_order = -5
wait = 1
@@ -9,10 +9,10 @@ var/datum/subsystem/icon_smooth/SSicon_smooth
var/list/smooth_queue = list()
/datum/subsystem/icon_smooth/New()
/datum/controller/subsystem/icon_smooth/New()
NEW_SS_GLOBAL(SSicon_smooth)
/datum/subsystem/icon_smooth/fire()
/datum/controller/subsystem/icon_smooth/fire()
while(smooth_queue.len)
var/atom/A = smooth_queue[smooth_queue.len]
smooth_queue.len--
@@ -22,7 +22,7 @@ var/datum/subsystem/icon_smooth/SSicon_smooth
if (!smooth_queue.len)
can_fire = 0
/datum/subsystem/icon_smooth/Initialize()
/datum/controller/subsystem/icon_smooth/Initialize()
smooth_zlevel(1,TRUE)
smooth_zlevel(2,TRUE)
var/queue = smooth_queue
+32
View File
@@ -0,0 +1,32 @@
var/datum/controller/subsystem/inbounds/SSinbounds
/datum/controller/subsystem/inbounds
name = "Inbounds"
priority = 40
flags = SS_NO_INIT
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/inbounds/New()
NEW_SS_GLOBAL(SSinbounds)
/datum/controller/subsystem/inbounds/stat_entry()
..("P:[processing.len]")
/datum/controller/subsystem/inbounds/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/atom/movable/thing = currentrun[currentrun.len]
currentrun.len--
if(thing)
thing.check_in_bounds(wait)
else
SSinbounds.processing -= thing
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/inbounds/Recover()
processing = SSinbounds.processing
+4 -4
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/ipintel/SSipintel
var/datum/controller/subsystem/ipintel/SSipintel
/datum/subsystem/ipintel
/datum/controller/subsystem/ipintel
name = "XKeyScore"
init_order = -10
flags = SS_NO_FIRE
@@ -10,10 +10,10 @@ var/datum/subsystem/ipintel/SSipintel
var/list/cache = list()
/datum/subsystem/ipintel/New()
/datum/controller/subsystem/ipintel/New()
NEW_SS_GLOBAL(SSipintel)
/datum/subsystem/ipintel/Initialize(timeofday, zlevel)
/datum/controller/subsystem/ipintel/Initialize(timeofday, zlevel)
enabled = 1
. = ..()
+74 -55
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/job/SSjob
var/datum/controller/subsystem/job/SSjob
/datum/subsystem/job
/datum/controller/subsystem/job
name = "Jobs"
init_order = 14
flags = SS_NO_FIRE
@@ -12,11 +12,13 @@ var/datum/subsystem/job/SSjob
var/list/job_debug = list() //Debug info
var/initial_players_to_assign = 0 //used for checking against population caps
/datum/subsystem/job/New()
var/list/prioritized_jobs = list()
/datum/controller/subsystem/job/New()
NEW_SS_GLOBAL(SSjob)
/datum/subsystem/job/Initialize(timeofday)
/datum/controller/subsystem/job/Initialize(timeofday)
if(!occupations.len)
SetupOccupations()
if(config.load_jobs_from_txt)
@@ -24,11 +26,11 @@ var/datum/subsystem/job/SSjob
..()
/datum/subsystem/job/proc/SetupOccupations(faction = "Station")
/datum/controller/subsystem/job/proc/SetupOccupations(faction = "Station")
occupations = list()
var/list/all_jobs = subtypesof(/datum/job)
if(!all_jobs.len)
world << "<span class='boldannounce'>Error setting up jobs, no job datums found</span>"
to_chat(world, "<span class='boldannounce'>Error setting up jobs, no job datums found</span>")
return 0
for(var/J in all_jobs)
@@ -39,6 +41,9 @@ var/datum/subsystem/job/SSjob
continue
if(!job.config_check())
continue
if(!job.map_check()) //Even though we initialize before mapping, this is fine because the config is loaded at new
testing("Removed [job.type] due to map config");
continue
occupations += job
name_occupations[job.title] = job
type_occupations[J] = job
@@ -46,25 +51,24 @@ var/datum/subsystem/job/SSjob
return 1
/datum/subsystem/job/proc/Debug(text)
/datum/controller/subsystem/job/proc/Debug(text)
if(!Debug2)
return 0
job_debug.Add(text)
return 1
/datum/subsystem/job/proc/GetJob(rank)
/datum/controller/subsystem/job/proc/GetJob(rank)
if(!occupations.len)
SetupOccupations()
return name_occupations[rank]
/datum/subsystem/job/proc/GetJobType(jobtype)
/datum/controller/subsystem/job/proc/GetJobType(jobtype)
if(!occupations.len)
SetupOccupations()
return type_occupations[jobtype]
/datum/subsystem/job/proc/AssignRole(mob/new_player/player, rank, latejoin=0)
/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, rank, latejoin=0)
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
if(player && player.mind && rank)
var/datum/job/job = GetJob(rank)
@@ -86,10 +90,10 @@ var/datum/subsystem/job/SSjob
return 0
/datum/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag)
/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag)
Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
var/list/candidates = list()
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(jobban_isbanned(player, job.title))
Debug("FOC isbanned failed, Player: [player]")
continue
@@ -110,7 +114,7 @@ var/datum/subsystem/job/SSjob
candidates += player
return candidates
/datum/subsystem/job/proc/GiveRandomJob(mob/new_player/player)
/datum/controller/subsystem/job/proc/GiveRandomJob(mob/dead/new_player/player)
Debug("GRJ Giving random job, Player: [player]")
for(var/datum/job/job in shuffle(occupations))
if(!job)
@@ -145,8 +149,8 @@ var/datum/subsystem/job/SSjob
unassigned -= player
break
/datum/subsystem/job/proc/ResetOccupations()
for(var/mob/new_player/player in player_list)
/datum/controller/subsystem/job/proc/ResetOccupations()
for(var/mob/dead/new_player/player in player_list)
if((player) && (player.mind))
player.mind.assigned_role = null
player.mind.special_role = null
@@ -158,7 +162,7 @@ var/datum/subsystem/job/SSjob
//This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until
//it locates a head or runs out of levels to check
//This is basically to ensure that there's atleast a few heads in the round
/datum/subsystem/job/proc/FillHeadPosition()
/datum/controller/subsystem/job/proc/FillHeadPosition()
for(var/level = 1 to 3)
for(var/command_position in command_positions)
var/datum/job/job = GetJob(command_position)
@@ -169,7 +173,7 @@ var/datum/subsystem/job/SSjob
var/list/candidates = FindOccupationCandidates(job, level)
if(!candidates.len)
continue
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
if(AssignRole(candidate, command_position))
return 1
return 0
@@ -177,7 +181,7 @@ var/datum/subsystem/job/SSjob
//This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
//This is also to ensure we get as many heads as possible
/datum/subsystem/job/proc/CheckHeadPositions(level)
/datum/controller/subsystem/job/proc/CheckHeadPositions(level)
for(var/command_position in command_positions)
var/datum/job/job = GetJob(command_position)
if(!job)
@@ -187,12 +191,12 @@ var/datum/subsystem/job/SSjob
var/list/candidates = FindOccupationCandidates(job, level)
if(!candidates.len)
continue
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
AssignRole(candidate, command_position)
return
/datum/subsystem/job/proc/FillAIPosition()
/datum/controller/subsystem/job/proc/FillAIPosition()
var/ai_selected = 0
var/datum/job/job = GetJob("AI")
if(!job)
@@ -202,7 +206,7 @@ var/datum/subsystem/job/SSjob
var/list/candidates = list()
candidates = FindOccupationCandidates(job, level)
if(candidates.len)
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
if(AssignRole(candidate, "AI"))
ai_selected++
break
@@ -215,7 +219,7 @@ var/datum/subsystem/job/SSjob
* fills var "assigned_role" for all ready players.
* This proc must not have any side effect besides of modifying "assigned_role".
**/
/datum/subsystem/job/proc/DivideOccupations()
/datum/controller/subsystem/job/proc/DivideOccupations()
//Setup new player list and get the jobs list
Debug("Running DO")
@@ -226,7 +230,7 @@ var/datum/subsystem/job/SSjob
A.spawn_positions = 3
//Get the players who are ready
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
if(player.ready && player.mind && !player.mind.assigned_role)
unassigned += player
@@ -256,7 +260,7 @@ var/datum/subsystem/job/SSjob
var/datum/job/assist = new /datum/job/assistant()
var/list/assistant_candidates = FindOccupationCandidates(assist, 3)
Debug("AC1, Candidates: [assistant_candidates.len]")
for(var/mob/new_player/player in assistant_candidates)
for(var/mob/dead/new_player/player in assistant_candidates)
Debug("AC1 pass, Player: [player]")
AssignRole(player, "Assistant")
assistant_candidates -= player
@@ -287,7 +291,7 @@ var/datum/subsystem/job/SSjob
CheckHeadPositions(level)
// Loop through all unassigned players
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
@@ -325,13 +329,13 @@ var/datum/subsystem/job/SSjob
// Hand out random jobs to the people who didn't get any in the last check
// Also makes sure that they got their preference correct
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
else if(jobban_isbanned(player, "Assistant"))
GiveRandomJob(player) //you get to roll for random before everyone else just to be sure you don't get assistant. you're so speshul
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
else if(player.client.prefs.joblessrole == BERANDOMJOB)
@@ -342,7 +346,7 @@ var/datum/subsystem/job/SSjob
Debug("DO, Running AC2")
// For those who wanted to be assistant if their preferences were filled, here you go.
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
if(player.client.prefs.joblessrole == BEASSISTANT)
@@ -351,13 +355,21 @@ var/datum/subsystem/job/SSjob
else // For those who don't want to play if their preference were filled, back you go.
RejectPlayer(player)
for(var/mob/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
GiveRandomJob(player)
return 1
//Gives the player the stuff he should have with his rank
/datum/subsystem/job/proc/EquipRank(mob/living/H, rank, joined_late=0)
/datum/controller/subsystem/job/proc/EquipRank(mob/M, rank, joined_late=0)
var/mob/dead/new_player/N
var/mob/living/H
if(!joined_late)
N = M
H = N.new_character
else
H = M
var/datum/job/job = GetJob(rank)
H.job = rank
@@ -375,7 +387,7 @@ var/datum/subsystem/job/SSjob
break
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
log_world("Couldn't find a round start spawn point for [rank]")
S = pick(latejoin)
S = get_turf(pick(latejoin))
if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to.
log_world("Couldn't find a round start latejoin spawn point.")
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
@@ -398,22 +410,26 @@ var/datum/subsystem/job/SSjob
var/new_mob = job.equip(H)
if(ismob(new_mob))
H = new_mob
if(!joined_late)
N.new_character = H
else
M = H
H << "<b>You are the [rank].</b>"
H << "<b>As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>"
H << "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>"
to_chat(M, "<b>You are the [rank].</b>")
to_chat(M, "<b>As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
to_chat(M, "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>")
if(job.req_admin_notify)
H << "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>"
to_chat(M, "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>")
if(config.minimal_access_threshold)
H << "<FONT color='blue'><B>As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>"
to_chat(M, "<FONT color='blue'><B>As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>")
if(job && H)
job.after_spawn(H)
job.after_spawn(H, M)
return H
/datum/subsystem/job/proc/setup_officer_positions()
/datum/controller/subsystem/job/proc/setup_officer_positions()
var/datum/job/J = SSjob.GetJob("Security Officer")
if(!J)
throw EXCEPTION("setup_officer_positions(): Security officer job is missing")
@@ -438,7 +454,7 @@ var/datum/subsystem/job/SSjob
break
/datum/subsystem/job/proc/LoadJobs()
/datum/controller/subsystem/job/proc/LoadJobs()
var/jobstext = return_file_text("config/jobs.txt")
for(var/datum/job/J in occupations)
var/regex/jobs = new("[J.title]=(-1|\\d+),(-1|\\d+)")
@@ -446,7 +462,7 @@ var/datum/subsystem/job/SSjob
J.total_positions = text2num(jobs.group[1])
J.spawn_positions = text2num(jobs.group[2])
/datum/subsystem/job/proc/HandleFeedbackGathering()
/datum/controller/subsystem/job/proc/HandleFeedbackGathering()
for(var/datum/job/job in occupations)
var/tmp_str = "|[job.title]|"
@@ -456,7 +472,7 @@ var/datum/subsystem/job/SSjob
var/level4 = 0 //never
var/level5 = 0 //banned
var/level6 = 0 //account too young
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
if(!(player.ready && player.mind && !player.mind.assigned_role))
continue //This player is not ready
if(jobban_isbanned(player, job.title))
@@ -476,31 +492,34 @@ var/datum/subsystem/job/SSjob
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
feedback_add_details("job_preferences",tmp_str)
/datum/subsystem/job/proc/PopcapReached()
/datum/controller/subsystem/job/proc/PopcapReached()
if(config.hard_popcap || config.extreme_popcap)
var/relevent_cap = max(config.hard_popcap, config.extreme_popcap)
if((initial_players_to_assign - unassigned.len) >= relevent_cap)
return 1
return 0
/datum/subsystem/job/proc/RejectPlayer(mob/new_player/player)
/datum/controller/subsystem/job/proc/RejectPlayer(mob/dead/new_player/player)
if(player.mind && player.mind.special_role)
return
if(PopcapReached())
Debug("Popcap overflow Check observer located, Player: [player]")
player << "<b>You have failed to qualify for any job you desired.</b>"
to_chat(player, "<b>You have failed to qualify for any job you desired.</b>")
unassigned -= player
player.ready = 0
/datum/subsystem/job/Recover()
/datum/controller/subsystem/job/Recover()
set waitfor = FALSE
var/oldjobs = SSjob.occupations
spawn(20)
for (var/datum/job/J in oldjobs)
spawn(-1)
var/datum/job/newjob = GetJob(J.title)
if (!istype(newjob))
return
newjob.total_positions = J.total_positions
newjob.spawn_positions = J.spawn_positions
newjob.current_positions = J.current_positions
sleep(20)
for (var/datum/job/J in oldjobs)
INVOKE_ASYNC(src, .proc/RecoverJob, J)
/datum/controller/subsystem/job/proc/RecoverJob(datum/job/J)
var/datum/job/newjob = GetJob(J.title)
if (!istype(newjob))
return
newjob.total_positions = J.total_positions
newjob.spawn_positions = J.spawn_positions
newjob.current_positions = J.current_positions
+82 -96
View File
@@ -1,119 +1,105 @@
var/datum/subsystem/lighting/SSlighting
var/datum/controller/subsystem/lighting/SSlighting
#define SSLIGHTING_LIGHTS 1
#define SSLIGHTING_TURFS 2
var/list/lighting_update_lights = list() // List of lighting sources queued for update.
var/list/lighting_update_corners = list() // List of lighting corners queued for update.
var/list/lighting_update_objects = list() // List of lighting objects queued for update.
/datum/subsystem/lighting
/datum/controller/subsystem/lighting
name = "Lighting"
init_order = 1
wait = 1
wait = 2
init_order = -20
flags = SS_TICKER
priority = 25
display_order = 5
var/list/changed_lights = list() //list of all datum/light_source that need updating
var/changed_lights_workload = 0 //stats on the largest number of lights (max changed_lights.len)
var/list/changed_turfs = list() //list of all turfs which may have a different light level
var/changed_turfs_workload = 0 //stats on the largest number of turfs changed (max changed_turfs.len)
var/initialized = FALSE
/datum/subsystem/lighting/New()
/datum/controller/subsystem/lighting/New()
NEW_SS_GLOBAL(SSlighting)
return ..()
/datum/subsystem/lighting/stat_entry()
..("L:[round(changed_lights_workload,1)]|T:[round(changed_turfs_workload,1)]")
/datum/controller/subsystem/lighting/stat_entry()
..("L:[lighting_update_lights.len]|C:[lighting_update_corners.len]|O:[lighting_update_objects.len]")
//Workhorse of lighting. It cycles through each light that needs updating. It updates their
//effects and then processes every turf in the queue, updating their lighting object's appearance
//Any light that returns 1 in check() deletes itself
//By using queues we are ensuring we don't perform more updates than are necessary
/datum/subsystem/lighting/fire(resumed = 0)
var/ticklimit = CURRENT_TICKLIMIT
//split our tick allotment in half so we don't spend it all on lightshift checks
CURRENT_TICKLIMIT = world.tick_usage + ((ticklimit-world.tick_usage)/2)
var/list/changed_lights = src.changed_lights
if (!resumed)
changed_lights_workload = MC_AVERAGE(changed_lights_workload, changed_lights.len)
var/i = 1
while (i <= changed_lights.len)
var/datum/light_source/LS = changed_lights[i++]
LS.check()
if (MC_TICK_CHECK)
break
if (i > 1)
changed_lights.Cut(1,i)
CURRENT_TICKLIMIT = ticklimit
var/list/changed_turfs = src.changed_turfs
if (!resumed)
changed_turfs_workload = MC_AVERAGE(changed_turfs_workload, changed_turfs.len)
i = 1
while (i <= changed_turfs.len)
var/turf/T = changed_turfs[i++]
if(T.lighting_changed)
T.redraw_lighting()
if (MC_TICK_CHECK)
break
if (i > 1)
changed_turfs.Cut(1,i)
//same as above except it attempts to shift ALL turfs in the world regardless of lighting_changed status
/datum/subsystem/lighting/Initialize(timeofday)
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
/datum/controller/subsystem/lighting/Initialize(timeofday)
if (config.starlight)
for(var/area/A in world)
if (A.lighting_use_dynamic == DYNAMIC_LIGHTING_IFSTARLIGHT)
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
A.luminosity = 0
CHECK_TICK
for(var/thing in changed_lights)
var/datum/light_source/LS = thing
LS.check()
CHECK_TICK
changed_lights.Cut()
create_all_lighting_objects()
initialized = TRUE
for(var/thing in turfs_to_init)
var/turf/T = thing
T.init_lighting()
CHECK_TICK
changed_turfs.Cut()
fire(FALSE, TRUE)
..()
//Used to strip valid information from an existing instance and transfer it to the replacement. i.e. when a crash occurs
//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop
//does not crash
/datum/subsystem/lighting/Recover()
if(!istype(SSlighting.changed_turfs))
SSlighting.changed_turfs = list()
if(!istype(SSlighting.changed_lights))
SSlighting.changed_lights = list()
/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks)
var/real_tick_limit
if(!init_tick_checks)
real_tick_limit = CURRENT_TICKLIMIT
CURRENT_TICKLIMIT = ((real_tick_limit - world.tick_usage) / 3) + world.tick_usage
var/i = 0
for (i in 1 to lighting_update_lights.len)
var/datum/light_source/L = lighting_update_lights[i]
for(var/thing in SSlighting.changed_lights)
var/datum/light_source/LS = thing
spawn(-1) //so we don't crash the loop (inefficient)
LS.check()
if (L.check() || L.destroyed || L.force_update)
L.remove_lum()
if (!L.destroyed)
L.apply_lum()
for(var/thing in changed_turfs)
var/turf/T = thing
if(T.lighting_changed)
spawn(-1)
T.redraw_lighting()
else if (L.vis_update) //We smartly update only tiles that became (in) visible to use.
L.smart_vis_update()
var/msg = "## DEBUG: [time2text(world.timeofday)] [name] subsystem restarted. Reports:\n"
for(var/varname in SSlighting.vars)
switch(varname)
if("tag","bestF","type","parent_type","vars")
continue
else
var/varval1 = SSlighting.vars[varname]
var/varval2 = vars[varname]
if(istype(varval1,/list))
varval1 = "/list([length(varval1)])"
varval2 = "/list([length(varval2)])"
msg += "\t [varname] = [varval1] -> [varval2]\n"
log_world(msg)
L.vis_update = FALSE
L.force_update = FALSE
L.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_lights.Cut(1, i+1)
i = 0
if(!init_tick_checks)
CURRENT_TICKLIMIT = ((real_tick_limit - world.tick_usage)/2)+world.tick_usage
for (i in 1 to lighting_update_corners.len)
var/datum/lighting_corner/C = lighting_update_corners[i]
C.update_objects()
C.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_corners.Cut(1, i+1)
i = 0
if(!init_tick_checks)
CURRENT_TICKLIMIT = real_tick_limit
for (i in 1 to lighting_update_objects.len)
var/atom/movable/lighting_object/O = lighting_update_objects[i]
if (QDELETED(O))
continue
O.update()
O.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_objects.Cut(1, i+1)
/datum/controller/subsystem/lighting/Recover()
initialized = SSlighting.initialized
..()
+9 -10
View File
@@ -1,21 +1,20 @@
var/datum/subsystem/machines/SSmachine
var/datum/controller/subsystem/machines/SSmachine
/datum/subsystem/machines
/datum/controller/subsystem/machines
name = "Machines"
init_order = 9
display_order = 3
flags = SS_KEEP_TIMING
var/list/processing = list()
var/list/currentrun = list()
var/list/powernets = list()
/datum/subsystem/machines/Initialize()
/datum/controller/subsystem/machines/Initialize()
makepowernets()
fire()
..()
/datum/subsystem/machines/proc/makepowernets()
/datum/controller/subsystem/machines/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
qdel(PN)
powernets.Cut()
@@ -26,15 +25,15 @@ var/datum/subsystem/machines/SSmachine
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
/datum/subsystem/machines/New()
/datum/controller/subsystem/machines/New()
NEW_SS_GLOBAL(SSmachine)
/datum/subsystem/machines/stat_entry()
/datum/controller/subsystem/machines/stat_entry()
..("M:[processing.len]|PN:[powernets.len]")
/datum/subsystem/machines/fire(resumed = 0)
/datum/controller/subsystem/machines/fire(resumed = 0)
if (!resumed)
for(var/datum/powernet/Powernet in powernets)
Powernet.reset() //reset the power state.
@@ -57,7 +56,7 @@ var/datum/subsystem/machines/SSmachine
if (MC_TICK_CHECK)
return
/datum/subsystem/machines/proc/setup_template_powernets(list/cables)
/datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables)
for(var/A in cables)
var/obj/structure/cable/PC = A
if(!PC.powernet)
@@ -65,7 +64,7 @@ var/datum/subsystem/machines/SSmachine
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
/datum/subsystem/machines/Recover()
/datum/controller/subsystem/machines/Recover()
if (istype(SSmachine.processing))
processing = SSmachine.processing
if (istype(SSmachine.powernets))
+143 -21
View File
@@ -1,14 +1,17 @@
var/datum/subsystem/mapping/SSmapping
var/datum/controller/subsystem/mapping/SSmapping
/datum/subsystem/mapping
/datum/controller/subsystem/mapping
name = "Mapping"
init_order = 12
flags = SS_NO_FIRE
display_order = 50
var/list/nuke_tiles = list()
var/list/nuke_threats = list()
var/datum/map_config/previous_map_config
var/datum/map_config/config
var/datum/map_config/next_map_config
var/list/map_templates = list()
var/list/ruins_templates = list()
@@ -18,20 +21,35 @@ var/datum/subsystem/mapping/SSmapping
var/list/shuttle_templates = list()
var/list/shelter_templates = list()
/datum/subsystem/mapping/New()
/datum/controller/subsystem/mapping/New()
NEW_SS_GLOBAL(SSmapping)
if(!previous_map_config)
previous_map_config = new("data/previous_map.json", delete_after = TRUE)
if(previous_map_config.defaulted)
previous_map_config = null
if(!config)
#ifdef FORCE_MAP
config = new(FORCE_MAP)
#else
config = new
#endif
return ..()
/datum/subsystem/mapping/Initialize(timeofday)
/datum/controller/subsystem/mapping/Initialize(timeofday)
if(config.defaulted)
to_chat(world, "<span class='boldannounce'>Unable to load next map config, defaulting to Box Station</span>")
loadWorld()
SortAreas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
// Pick a random away mission.
createRandomZlevel()
// Generate mining.
var/mining_type = MINETYPE
var/mining_type = config.minetype
if (mining_type == "lavaland")
seedRuins(list(5), config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
spawn_rivers()
// deep space ruins
@@ -43,7 +61,7 @@ var/datum/subsystem/mapping/SSmapping
else
space_zlevels += i
seedRuins(space_zlevels, config.space_budget, /area/space, space_ruins_templates)
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
// Set up Z-level transistions.
setup_map_transitions()
@@ -53,26 +71,24 @@ var/datum/subsystem/mapping/SSmapping
Used by the AI doomsday and the self destruct nuke.
*/
/datum/subsystem/mapping/proc/add_nuke_threat(datum/nuke)
/datum/controller/subsystem/mapping/proc/add_nuke_threat(datum/nuke)
nuke_threats[nuke] = TRUE
check_nuke_threats()
/datum/subsystem/mapping/proc/remove_nuke_threat(datum/nuke)
/datum/controller/subsystem/mapping/proc/remove_nuke_threat(datum/nuke)
nuke_threats -= nuke
check_nuke_threats()
/datum/subsystem/mapping/proc/check_nuke_threats()
/datum/controller/subsystem/mapping/proc/check_nuke_threats()
for(var/datum/d in nuke_threats)
if(!istype(d) || QDELETED(d))
nuke_threats -= d
var/threats = nuke_threats.len
for(var/N in nuke_tiles)
var/turf/open/floor/T = N
T.icon_state = (threats ? "rcircuitanim" : T.icon_regular_floor)
var/turf/open/floor/circuit/C = N
C.update_icon()
/datum/subsystem/mapping/Recover()
/datum/controller/subsystem/mapping/Recover()
flags |= SS_NO_INIT
map_templates = SSmapping.map_templates
ruins_templates = SSmapping.ruins_templates
@@ -81,7 +97,113 @@ var/datum/subsystem/mapping/SSmapping
shuttle_templates = SSmapping.shuttle_templates
shelter_templates = SSmapping.shelter_templates
/datum/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
previous_map_config = SSmapping.previous_map_config
config = SSmapping.config
next_map_config = SSmapping.next_map_config
/datum/controller/subsystem/mapping/proc/TryLoadZ(filename, errorList, forceLevel, last)
var/static/dmm_suite/loader
if(!loader)
loader = new
if(!loader.load_map(file(filename), 0, 0, forceLevel, no_changeturf = TRUE))
errorList |= filename
if(last)
QDEL_NULL(loader)
/datum/controller/subsystem/mapping/proc/CreateSpace(zlevel)
while(world.maxz < zlevel)
CHECK_TICK
++world.maxz
CHECK_TICK
for(var/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
CHECK_TICK
new /turf/open/space(T)
#define INIT_ANNOUNCE(X) to_chat(world, "<span class='boldannounce'>[X]</span>"); log_world(X)
/datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong
var/list/FailedZs = list()
var/start_time = REALTIMEOFDAY
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
if(config.minetype != "lavaland")
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
for(var/I in (world.maxz + 1) to ZLEVEL_SPACEMAX)
CreateSpace(I)
if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen
var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]"
if(FailedZs.len > 1)
for(var/I in 2 to FailedZs.len)
msg += ", [I]"
msg += ". Yell at your server host!"
INIT_ANNOUNCE(msg)
#undef INIT_ANNOUNCE
/datum/controller/subsystem/mapping/proc/maprotate()
var/players = clients.len
var/list/mapvotes = list()
//count votes
if(global.config.allow_map_voting)
for (var/client/c in clients)
var/vote = c.prefs.preferred_map
if (!vote)
if (global.config.defaultmap)
mapvotes[global.config.defaultmap.map_name] += 1
continue
mapvotes[vote] += 1
//filter votes
for (var/map in mapvotes)
if (!map)
mapvotes.Remove(map)
if (!(map in global.config.maplist))
mapvotes.Remove(map)
continue
var/datum/map_config/VM = global.config.maplist[map]
if (!VM)
mapvotes.Remove(map)
continue
if (VM.voteweight <= 0)
mapvotes.Remove(map)
continue
if (VM.config_min_users > 0 && players < VM.config_min_users)
mapvotes.Remove(map)
continue
if (VM.config_max_users > 0 && players > VM.config_max_users)
mapvotes.Remove(map)
continue
mapvotes[map] = mapvotes[map]*VM.voteweight
var/pickedmap = global.config.allow_map_voting ? pickweight(mapvotes) : pick(global.config.maplist)
if (!pickedmap)
return
var/datum/map_config/VM = global.config.maplist[pickedmap]
message_admins("Randomly rotating map to [VM.map_name]")
. = changemap(VM)
if (. && VM.map_name != config.map_name)
to_chat(world, "<span class='boldannounce'>Map rotation has chosen [VM.map_name] for next round!</span>")
/datum/controller/subsystem/mapping/proc/changemap(var/datum/map_config/VM)
if(!VM.MakeNextMap())
next_map_config = new(default_to_box = TRUE)
message_admins("Failed to set new map with next_map.json for [VM.map_name]! Using default as backup!")
return
next_map_config = VM
return TRUE
/datum/controller/subsystem/mapping/Shutdown()
if(config)
config.MakePreviousMap()
/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
var/list/filelist = flist(path)
for(var/map in filelist)
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
@@ -91,7 +213,7 @@ var/datum/subsystem/mapping/SSmapping
preloadShuttleTemplates()
preloadShelterTemplates()
/datum/subsystem/mapping/proc/preloadRuinTemplates()
/datum/controller/subsystem/mapping/proc/preloadRuinTemplates()
// Still supporting bans by filename
var/list/banned = generateMapList("config/lavaruinblacklist.txt")
banned += generateMapList("config/spaceruinblacklist.txt")
@@ -114,7 +236,7 @@ var/datum/subsystem/mapping/SSmapping
else if(istype(R, /datum/map_template/ruin/space))
space_ruins_templates[R.name] = R
/datum/subsystem/mapping/proc/preloadShuttleTemplates()
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("config/unbuyableshuttles.txt")
for(var/item in subtypesof(/datum/map_template/shuttle))
@@ -129,7 +251,7 @@ var/datum/subsystem/mapping/SSmapping
shuttle_templates[S.shuttle_id] = S
map_templates[S.shuttle_id] = S
/datum/subsystem/mapping/proc/preloadShelterTemplates()
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
for(var/item in subtypesof(/datum/map_template/shelter))
var/datum/map_template/shelter/shelter_type = item
if(!(initial(shelter_type.mappath)))
@@ -137,4 +259,4 @@ var/datum/subsystem/mapping/SSmapping
var/datum/map_template/shelter/S = new shelter_type()
shelter_templates[S.shelter_id] = S
map_templates[S.shelter_id] = S
map_templates[S.shelter_id] = S
+20 -20
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/minimap/SSminimap
var/datum/controller/subsystem/minimap/SSminimap
/datum/subsystem/minimap
/datum/controller/subsystem/minimap
name = "Minimap"
init_order = -2
flags = SS_NO_FIRE
@@ -9,11 +9,11 @@ var/datum/subsystem/minimap/SSminimap
var/list/z_levels = list(ZLEVEL_STATION)
/datum/subsystem/minimap/New()
/datum/controller/subsystem/minimap/New()
NEW_SS_GLOBAL(SSminimap)
/datum/subsystem/minimap/Initialize(timeofday)
var/hash = md5(file2text("_maps/[MAP_PATH]/[MAP_FILE]"))
/datum/controller/subsystem/minimap/Initialize(timeofday)
var/hash = md5(SSmapping.config.GetFullMapPath())
if(config.generate_minimaps)
if(hash == trim(file2text(hash_path())))
for(var/z in z_levels) //We have these files cached, let's register them
@@ -25,48 +25,48 @@ var/datum/subsystem/minimap/SSminimap
fdel(hash_path())
text2file(hash, hash_path())
else
world << "<span class='boldannounce'>Minimap generation disabled. Loading from cache...</span>"
to_chat(world, "<span class='boldannounce'>Minimap generation disabled. Loading from cache...</span>")
var/fileloc = 0
if(check_files(0)) //Let's first check if we have maps cached in the data folder. NOTE: This will override the backup files even if this map is older.
if(hash != trim(file2text(hash_path())))
world << "<span class='boldannounce'>Loaded cached minimap is outdated. There may be minor discrepancies in layout.</span>" //Disclaimer against players saying map is wrong.
to_chat(world, "<span class='boldannounce'>Loaded cached minimap is outdated. There may be minor discrepancies in layout.</span>" )
fileloc = 0
else
if(!check_files(1))
world << "<span class='boldannounce'>Failed to load backup minimap file. Aborting.</span>" //We couldn't find something. Bail to prevent issues with null files
to_chat(world, "<span class='boldannounce'>Failed to load backup minimap file. Aborting.</span>" )
return
fileloc = 1 //No map image cached with the current map, and we have a backup. Let's fall back to it.
world << "<span class='boldannounce'>No cached minimaps detected. Backup files loaded.</span>"
to_chat(world, "<span class='boldannounce'>No cached minimaps detected. Backup files loaded.</span>")
for(var/z in z_levels)
register_asset("minimap_[z].png", fcopy_rsc(map_path(z,fileloc)))
..()
/datum/subsystem/minimap/proc/check_files(backup) // If the backup argument is true, looks in the icons folder. If false looks in the data folder.
/datum/controller/subsystem/minimap/proc/check_files(backup) // If the backup argument is true, looks in the icons folder. If false looks in the data folder.
for(var/z in z_levels)
if(!fexists(file(map_path(z,backup)))) //Let's make sure we have a file for this map
if(backup)
log_world("Failed to find backup file for map [MAP_NAME] on zlevel [z].")
log_world("Failed to find backup file for map [SSmapping.config.map_name] on zlevel [z].")
return FALSE
return TRUE
/datum/subsystem/minimap/proc/hash_path(backup)
/datum/controller/subsystem/minimap/proc/hash_path(backup)
if(backup)
return "icons/minimaps/[MAP_NAME].md5"
return "icons/minimaps/[SSmapping.config.map_name].md5"
else
return "data/minimaps/[MAP_NAME].md5"
return "data/minimaps/[SSmapping.config.map_name].md5"
/datum/subsystem/minimap/proc/map_path(z,backup)
/datum/controller/subsystem/minimap/proc/map_path(z,backup)
if(backup)
return "icons/minimaps/[MAP_NAME]_[z].png"
return "icons/minimaps/[SSmapping.config.map_name]_[z].png"
else
return "data/minimaps/[MAP_NAME]_[z].png"
return "data/minimaps/[SSmapping.config.map_name]_[z].png"
/datum/subsystem/minimap/proc/send(client/client)
/datum/controller/subsystem/minimap/proc/send(client/client)
for(var/z in z_levels)
send_asset(client, "minimap_[z].png")
/datum/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
/datum/controller/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
// Load the background.
var/icon/minimap = new /icon('icons/minimap.dmi')
// Scale it up to our target size.
@@ -81,7 +81,7 @@ var/datum/subsystem/minimap/SSminimap
final.Insert(minimap, "", SOUTH, 1, 0)
fcopy(final, map_path(z))
/datum/subsystem/minimap/proc/generate_tile(turf/tile, icon/minimap)
/datum/controller/subsystem/minimap/proc/generate_tile(turf/tile, icon/minimap)
var/icon/tile_icon
var/obj/obj
var/list/obj_icons
+5 -6
View File
@@ -1,23 +1,22 @@
var/datum/subsystem/mobs/SSmob
var/datum/controller/subsystem/mobs/SSmob
/datum/subsystem/mobs
/datum/controller/subsystem/mobs
name = "Mobs"
init_order = 4
display_order = 4
priority = 100
flags = SS_KEEP_TIMING|SS_NO_INIT
var/list/currentrun = list()
/datum/subsystem/mobs/New()
/datum/controller/subsystem/mobs/New()
NEW_SS_GLOBAL(SSmob)
/datum/subsystem/mobs/stat_entry()
/datum/controller/subsystem/mobs/stat_entry()
..("P:[mob_list.len]")
/datum/subsystem/mobs/fire(resumed = 0)
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = mob_list.Copy()
+8 -9
View File
@@ -1,9 +1,8 @@
var/datum/subsystem/npcpool/SSnpc
var/datum/controller/subsystem/npcpool/SSnpc
/datum/subsystem/npcpool
/datum/controller/subsystem/npcpool
name = "NPC Pool"
init_order = 17
display_order = 6
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_NO_TICK_CHECK
priority = 25
@@ -15,18 +14,18 @@ var/datum/subsystem/npcpool/SSnpc
var/list/botPool_l = list() //list of all npcs using the pool
var/list/botPool_l_non = list() //list of all non SNPC mobs using the pool
/datum/subsystem/npcpool/proc/insertBot(toInsert)
/datum/controller/subsystem/npcpool/proc/insertBot(toInsert)
if(istype(toInsert,/mob/living/carbon/human/interactive))
botPool_l |= toInsert
/datum/subsystem/npcpool/New()
/datum/controller/subsystem/npcpool/New()
NEW_SS_GLOBAL(SSnpc)
/datum/subsystem/npcpool/stat_entry()
/datum/controller/subsystem/npcpool/stat_entry()
..("T:[botPool_l.len + botPool_l_non.len]|D:[needsDelegate.len]|A:[needsAssistant.len + needsHelp_non.len]|U:[canBeUsed.len + canBeUsed_non.len]")
/datum/subsystem/npcpool/proc/cleanNull()
/datum/controller/subsystem/npcpool/proc/cleanNull()
//cleanup nulled bots
listclearnulls(botPool_l)
listclearnulls(needsDelegate)
@@ -34,7 +33,7 @@ var/datum/subsystem/npcpool/SSnpc
listclearnulls(needsAssistant)
/datum/subsystem/npcpool/fire()
/datum/controller/subsystem/npcpool/fire()
//bot delegation and coordination systems
//General checklist/Tasks for delegating a task or coordinating it (for SNPCs)
// 1. Bot proximity to task target: if too far, delegate, if close, coordinate
@@ -121,7 +120,7 @@ var/datum/subsystem/npcpool/SSnpc
candidate.update_icons()
npcCount++
/datum/subsystem/npcpool/Recover()
/datum/controller/subsystem/npcpool/Recover()
if (istype(SSnpc.botPool_l))
botPool_l = SSnpc.botPool_l
if (istype(SSnpc.botPool_l_non))
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/orbit/SSorbit
var/datum/controller/subsystem/orbit/SSorbit
/datum/subsystem/orbit
/datum/controller/subsystem/orbit
name = "Orbits"
priority = 35
wait = 2
@@ -9,15 +9,15 @@ var/datum/subsystem/orbit/SSorbit
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/orbit/New()
/datum/controller/subsystem/orbit/New()
NEW_SS_GLOBAL(SSorbit)
/datum/subsystem/orbit/stat_entry()
/datum/controller/subsystem/orbit/stat_entry()
..("P:[processing.len]")
/datum/subsystem/orbit/fire(resumed = 0)
/datum/controller/subsystem/orbit/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+9 -9
View File
@@ -1,7 +1,7 @@
var/datum/subsystem/pai/SSpai
var/datum/controller/subsystem/pai/SSpai
var/list/obj/item/device/paicard/pai_card_list = list()
/datum/subsystem/pai
/datum/controller/subsystem/pai
name = "pAI"
flags = SS_NO_INIT|SS_NO_FIRE
@@ -10,10 +10,10 @@ var/list/obj/item/device/paicard/pai_card_list = list()
var/ghost_spam = FALSE
var/spam_delay = 100
/datum/subsystem/pai/New()
/datum/controller/subsystem/pai/New()
NEW_SS_GLOBAL(SSpai)
/datum/subsystem/pai/Topic(href, href_list[])
/datum/controller/subsystem/pai/Topic(href, href_list[])
if(href_list["download"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
var/obj/item/device/paicard/card = locate(href_list["device"])
@@ -84,7 +84,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
return
recruitWindow(usr)
/datum/subsystem/pai/proc/recruitWindow(mob/M)
/datum/controller/subsystem/pai/proc/recruitWindow(mob/M)
var/datum/paiCandidate/candidate
for(var/datum/paiCandidate/c in candidates)
if(c.key == M.key)
@@ -135,10 +135,10 @@ var/list/obj/item/device/paicard/pai_card_list = list()
M << browse(dat, "window=paiRecruit")
/datum/subsystem/pai/proc/spam_again()
/datum/controller/subsystem/pai/proc/spam_again()
ghost_spam = FALSE
/datum/subsystem/pai/proc/check_ready(var/datum/paiCandidate/C)
/datum/controller/subsystem/pai/proc/check_ready(var/datum/paiCandidate/C)
if(!C.ready)
return FALSE
for(var/mob/dead/observer/O in player_list)
@@ -146,7 +146,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
return C
return FALSE
/datum/subsystem/pai/proc/findPAI(obj/item/device/paicard/p, mob/user)
/datum/controller/subsystem/pai/proc/findPAI(obj/item/device/paicard/p, mob/user)
if(!ghost_spam)
ghost_spam = TRUE
for(var/mob/dead/observer/G in player_list)
@@ -155,7 +155,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
if(!(ROLE_PAI in G.client.prefs.be_special))
continue
//G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
G << "<span class='ghostalert'>Someone is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>"
to_chat(G, "<span class='ghostalert'>Someone is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
addtimer(CALLBACK(src, .proc/spam_again), spam_delay)
var/list/available = list()
for(var/datum/paiCandidate/c in SSpai.candidates)
+6 -6
View File
@@ -1,17 +1,17 @@
var/datum/subsystem/parallax/SSparallax
var/datum/controller/subsystem/parallax/SSparallax
/datum/subsystem/parallax
name = "parallax"
/datum/controller/subsystem/parallax
name = "Parallax"
wait = 2
flags = SS_POST_FIRE_TIMING | SS_FIRE_IN_LOBBY | SS_BACKGROUND | SS_NO_INIT
priority = 65
var/list/currentrun
/datum/subsystem/parallax/New()
/datum/controller/subsystem/parallax/New()
NEW_SS_GLOBAL(SSparallax)
return ..()
/datum/subsystem/parallax/fire(resumed = 0)
/datum/controller/subsystem/parallax/fire(resumed = 0)
if (!resumed)
src.currentrun = clients.Copy()
@@ -39,4 +39,4 @@ var/datum/subsystem/parallax/SSparallax
C.movingmob = A
if (MC_TICK_CHECK)
return
currentrun = null
currentrun = null
+17 -17
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/persistence/SSpersistence
var/datum/controller/subsystem/persistence/SSpersistence
/datum/subsystem/persistence
/datum/controller/subsystem/persistence
name = "Persistence"
init_order = -100
flags = SS_NO_FIRE
@@ -13,19 +13,19 @@ var/datum/subsystem/persistence/SSpersistence
var/list/saved_messages = list()
var/savefile/chisel_messages_sav
/datum/subsystem/persistence/New()
/datum/controller/subsystem/persistence/New()
NEW_SS_GLOBAL(SSpersistence)
/datum/subsystem/persistence/Initialize()
/datum/controller/subsystem/persistence/Initialize()
LoadSatchels()
LoadPoly()
LoadChiselMessages()
..()
/datum/subsystem/persistence/proc/LoadSatchels()
/datum/controller/subsystem/persistence/proc/LoadSatchels()
secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/weapon/crowbar))
secret_satchels[MAP_NAME] >> old_secret_satchels
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
var/list/expanded_old_satchels = list()
var/placed_satchels = 0
@@ -44,14 +44,14 @@ var/datum/subsystem/persistence/SSpersistence
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchels) >= (50 - expanded_old_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
break
/datum/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
/datum/controller/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
var/satchel_string
if(expanded_old_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
satchel_string = pick_n_take(expanded_old_satchels)
old_secret_satchels = jointext(expanded_old_satchels,"#")
secret_satchels[MAP_NAME] << old_secret_satchels
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
var/list/chosen_satchel = splittext(satchel_string,"|")
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
@@ -70,15 +70,15 @@ var/datum/subsystem/persistence/SSpersistence
new path(F)
return 1
/datum/subsystem/persistence/proc/LoadPoly()
/datum/controller/subsystem/persistence/proc/LoadPoly()
for(var/mob/living/simple_animal/parrot/Poly/P in living_mob_list)
twitterize(P.speech_buffer, "polytalk")
break //Who's been duping the bird?!
/datum/subsystem/persistence/proc/LoadChiselMessages()
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
var/saved_json
chisel_messages_sav[MAP_NAME] >> saved_json
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
if(!saved_json)
return
@@ -98,11 +98,11 @@ var/datum/subsystem/persistence/SSpersistence
qdel(M)
/datum/subsystem/persistence/proc/CollectData()
/datum/controller/subsystem/persistence/proc/CollectData()
CollectChiselMessages()
CollectSecretSatchels()
/datum/subsystem/persistence/proc/CollectSecretSatchels()
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
for(var/A in new_secret_satchels)
var/obj/item/weapon/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM)
@@ -118,13 +118,13 @@ var/datum/subsystem/persistence/SSpersistence
if(isemptylist(savable_obj))
continue
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
secret_satchels[MAP_NAME] << old_secret_satchels
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
/datum/subsystem/persistence/proc/CollectChiselMessages()
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
for(var/obj/structure/chisel_message/M in chisel_messages)
saved_messages += list(M.pack())
chisel_messages_sav[MAP_NAME] << json_encode(saved_messages)
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
/datum/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
saved_messages += list(M.pack()) // dm eats one list.
+4 -4
View File
@@ -1,18 +1,18 @@
#define PING_BUFFER_TIME 25
var/datum/subsystem/ping/SSping
var/datum/controller/subsystem/ping/SSping
/datum/subsystem/ping
/datum/controller/subsystem/ping
name = "Ping"
wait = 6
flags = SS_NO_INIT|SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
priority = 10
var/list/currentrun
/datum/subsystem/ping/New()
/datum/controller/subsystem/ping/New()
NEW_SS_GLOBAL(SSping)
/datum/subsystem/ping/fire(resumed = FALSE)
/datum/controller/subsystem/ping/fire(resumed = FALSE)
if (!resumed)
src.currentrun = clients.Copy()
@@ -1,10 +1,10 @@
//Fires five times every second.
var/datum/subsystem/processing/fastprocess/SSfastprocess
/datum/subsystem/processing/fastprocess
var/datum/controller/subsystem/processing/fastprocess/SSfastprocess
/datum/controller/subsystem/processing/fastprocess
name = "Fast Processing"
wait = 2
stat_tag = "FP"
/datum/subsystem/processing/fastprocess/New()
/datum/controller/subsystem/processing/fastprocess/New()
NEW_SS_GLOBAL(SSfastprocess)
@@ -1,11 +1,11 @@
var/datum/subsystem/processing/flightpacks/SSflightpacks
/datum/subsystem/processing/flightpacks
var/datum/controller/subsystem/processing/flightpacks/SSflightpacks
/datum/controller/subsystem/processing/flightpacks
name = "Flightpack Movement"
priority = 30
wait = 2
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
/datum/subsystem/processing/flightpacks/New()
/datum/controller/subsystem/processing/flightpacks/New()
NEW_SS_GLOBAL(SSflightpacks)
@@ -1,5 +1,5 @@
var/datum/subsystem/objects/SSobj
/datum/subsystem/objects
var/datum/controller/subsystem/objects/SSobj
/datum/controller/subsystem/objects
name = "Objects"
priority = 40
flags = SS_NO_INIT
@@ -7,12 +7,12 @@ var/datum/subsystem/objects/SSobj
var/list/processing = list()
var/list/currentrun = list()
/datum/subsystem/objects/New()
/datum/controller/subsystem/objects/New()
NEW_SS_GLOBAL(SSobj)
/datum/subsystem/objects/stat_entry()
/datum/controller/subsystem/objects/stat_entry()
..("P:[processing.len]")
/datum/subsystem/objects/fire(resumed = 0)
/datum/controller/subsystem/objects/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
@@ -28,5 +28,5 @@ var/datum/subsystem/objects/SSobj
if (MC_TICK_CHECK)
return
/datum/subsystem/objects/Recover()
/datum/controller/subsystem/objects/Recover()
processing = SSobj.processing
@@ -1,6 +1,6 @@
var/datum/subsystem/processing/overlays/SSoverlays
var/datum/controller/subsystem/processing/overlays/SSoverlays
/datum/subsystem/processing/overlays
/datum/controller/subsystem/processing/overlays
name = "Overlay"
flags = SS_TICKER|SS_FIRE_IN_LOBBY
wait = 1
@@ -13,33 +13,37 @@ var/datum/subsystem/processing/overlays/SSoverlays
var/list/overlay_icon_cache
var/initialized = FALSE
/datum/subsystem/processing/overlays/New()
/datum/controller/subsystem/processing/overlays/New()
NEW_SS_GLOBAL(SSoverlays)
LAZYINITLIST(overlay_icon_state_caches)
LAZYINITLIST(overlay_icon_cache)
/datum/subsystem/processing/overlays/Initialize()
/datum/controller/subsystem/processing/overlays/Initialize()
initialized = TRUE
for(var/I in processing)
var/atom/A = I
A.compile_overlays()
CHECK_TICK
processing.Cut()
Flush()
..()
/datum/subsystem/processing/overlays/Recover()
/datum/controller/subsystem/processing/overlays/Recover()
overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches
overlay_icon_cache = SSoverlays.overlay_icon_cache
processing = SSoverlays.processing
/datum/subsystem/processing/overlays/fire()
/datum/controller/subsystem/processing/overlays/fire(resumed = FALSE, mc_check = TRUE)
while(processing.len)
var/atom/thing = processing[processing.len]
processing.len--
if(thing)
thing.compile_overlays(FALSE)
if(MC_TICK_CHECK)
break
if(mc_check)
if(MC_TICK_CHECK)
break
else
CHECK_TICK
/datum/controller/subsystem/processing/overlays/proc/Flush()
if(processing.len)
testing("Flushing [processing.len] overlays")
fire(mc_check = FALSE) //pair this thread up with the MC to get extra compile time
/atom/proc/compile_overlays()
if(LAZYLEN(priority_overlays) && LAZYLEN(our_overlays))
@@ -54,7 +58,7 @@ var/datum/subsystem/processing/overlays/SSoverlays
/proc/iconstate2appearance(icon, iconstate)
var/static/image/stringbro = new()
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
var/list/cached_icon = icon_states_cache[icon]
if (cached_icon)
var/cached_appearance = cached_icon["[iconstate]"]
@@ -92,16 +96,17 @@ var/datum/subsystem/processing/overlays/SSoverlays
new_overlays[i] = icon2appearance(cached_overlay)
else //image probable
appearance_bro.appearance = cached_overlay
appearance_bro.dir = cached_overlay.dir
if(!ispath(cached_overlay))
appearance_bro.dir = cached_overlay.dir
new_overlays[i] = appearance_bro.appearance
return new_overlays
#define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED))
#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src;
#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src;
/atom/proc/cut_overlays(priority = FALSE)
var/list/cached_overlays = our_overlays
var/list/cached_priority = priority_overlays
var/need_compile = FALSE
if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays
@@ -116,7 +121,6 @@ var/datum/subsystem/processing/overlays/SSoverlays
QUEUE_FOR_COMPILE
/atom/proc/cut_overlay(list/overlays, priority)
var/static/image/appearance_bro = new()
if(!overlays)
return
@@ -135,7 +139,6 @@ var/datum/subsystem/processing/overlays/SSoverlays
QUEUE_FOR_COMPILE
/atom/proc/add_overlay(list/overlays, priority = FALSE)
var/static/image/appearance_bro = new()
if(!overlays)
return
@@ -165,7 +168,7 @@ var/datum/subsystem/processing/overlays/SSoverlays
if(cut_old)
cut_overlays()
return
var/list/cached_other = other.our_overlays
if(cached_other)
if(cut_old)
@@ -188,4 +191,4 @@ var/datum/subsystem/processing/overlays/SSoverlays
overlays -= x
/image/proc/cut_overlays(x)
overlays.Cut()
overlays.Cut()
@@ -1,7 +1,7 @@
//Used to process objects. Fires once every second.
var/datum/subsystem/processing/SSprocessing
/datum/subsystem/processing
var/datum/controller/subsystem/processing/SSprocessing
/datum/controller/subsystem/processing
name = "Processing"
priority = 25
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
@@ -11,13 +11,13 @@ var/datum/subsystem/processing/SSprocessing
var/list/processing = list()
var/list/currentrun = list()
/datum/subsystem/processing/New()
/datum/controller/subsystem/processing/New()
NEW_SS_GLOBAL(SSprocessing)
/datum/subsystem/processing/stat_entry()
/datum/controller/subsystem/processing/stat_entry()
..("[stat_tag]:[processing.len]")
/datum/subsystem/processing/fire(resumed = 0)
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
+6 -6
View File
@@ -1,16 +1,16 @@
var/datum/subsystem/radio/SSradio
var/datum/controller/subsystem/radio/SSradio
/datum/subsystem/radio
/datum/controller/subsystem/radio
name = "Radio"
init_order = 18
flags = SS_NO_FIRE|SS_NO_INIT
var/list/datum/radio_frequency/frequencies = list()
/datum/subsystem/radio/New()
/datum/controller/subsystem/radio/New()
NEW_SS_GLOBAL(SSradio)
/datum/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
/datum/controller/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
@@ -22,7 +22,7 @@ var/datum/subsystem/radio/SSradio
frequency.add_listener(device, filter)
return frequency
/datum/subsystem/radio/proc/remove_object(obj/device, old_frequency)
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
var/f_text = num2text(old_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
@@ -35,7 +35,7 @@ var/datum/subsystem/radio/SSradio
return 1
/datum/subsystem/radio/proc/return_frequency(new_frequency as num)
/datum/controller/subsystem/radio/proc/return_frequency(new_frequency as num)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
+3 -3
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/religion/SSreligion
var/datum/controller/subsystem/religion/SSreligion
/datum/subsystem/religion
/datum/controller/subsystem/religion
name = "Religion"
init_order = 19
flags = SS_NO_FIRE|SS_NO_INIT
@@ -13,5 +13,5 @@ var/datum/subsystem/religion/SSreligion
var/holy_weapon
/datum/subsystem/religion/New()
/datum/controller/subsystem/religion/New()
NEW_SS_GLOBAL(SSreligion)
@@ -1,28 +1,27 @@
var/datum/subsystem/server_maint/SSserver
var/datum/controller/subsystem/server_maint/SSserver
/datum/subsystem/server_maint
/datum/controller/subsystem/server_maint
name = "Server Tasks"
wait = 6000
flags = SS_NO_TICK_CHECK
/datum/subsystem/server_maint/New()
/datum/controller/subsystem/server_maint/New()
NEW_SS_GLOBAL(SSserver)
/datum/subsystem/server_maint/Initialize(timeofday)
/datum/controller/subsystem/server_maint/Initialize(timeofday)
if (config.hub)
world.visibility = 1
..()
/datum/subsystem/server_maint/fire()
/datum/controller/subsystem/server_maint/fire()
//handle kicking inactive players
if(config.kick_inactive > 0)
for(var/client/C in clients)
if(C.is_afk(INACTIVITY_KICK))
if(!istype(C.mob, /mob/dead))
log_access("AFK: [key_name(C)]")
C << "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>"
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
qdel(C)
if(config.sql_enabled)
sql_poll_players()
sql_poll_admins()
sql_poll_population()
+45 -42
View File
@@ -1,8 +1,8 @@
#define HIGHLIGHT_DYNAMIC_TRANSIT 1
var/datum/subsystem/shuttle/SSshuttle
var/datum/controller/subsystem/shuttle/SSshuttle
/datum/subsystem/shuttle
/datum/controller/subsystem/shuttle
name = "Shuttles"
wait = 10
init_order = 3
@@ -18,6 +18,7 @@ var/datum/subsystem/shuttle/SSshuttle
//emergency shuttle stuff
var/obj/docking_port/mobile/emergency/emergency
var/obj/docking_port/mobile/arrivals/arrivals
var/obj/docking_port/mobile/emergency/backup/backup_shuttle
var/emergencyCallTime = 6000 //time taken for emergency shuttle to reach the station when called (in deciseconds)
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
@@ -46,10 +47,12 @@ var/datum/subsystem/shuttle/SSshuttle
var/lockdown = FALSE //disallow transit after nuke goes off
/datum/subsystem/shuttle/New()
/datum/controller/subsystem/shuttle/New()
NEW_SS_GLOBAL(SSshuttle)
/datum/subsystem/shuttle/Initialize(timeofday)
/datum/controller/subsystem/shuttle/Initialize(timeofday)
if(!emergency)
WARNING("No /obj/docking_port/mobile/arrivals placed on the map!")
if(!emergency)
WARNING("No /obj/docking_port/mobile/emergency placed on the map!")
if(!backup_shuttle)
@@ -65,13 +68,14 @@ var/datum/subsystem/shuttle/SSshuttle
continue
supply_packs[P.type] = P
initial_move()
setup_transit_zone()
initial_move()
#ifdef HIGHLIGHT_DYNAMIC_TRANSIT
color_space()
#endif
..()
/datum/subsystem/shuttle/proc/setup_transit_zone()
/datum/controller/subsystem/shuttle/proc/setup_transit_zone()
if(transit_markers.len == 0)
WARNING("No /obj/effect/landmark/transit placed on the map!")
return
@@ -85,7 +89,7 @@ var/datum/subsystem/shuttle/SSshuttle
T.flags |= UNUSED_TRANSIT_TURF
#ifdef HIGHLIGHT_DYNAMIC_TRANSIT
/datum/subsystem/shuttle/proc/color_space()
/datum/controller/subsystem/shuttle/proc/color_space()
if(transit_markers.len == 0)
WARNING("No /obj/effect/landmark/transit placed on the map!")
return
@@ -104,7 +108,7 @@ var/datum/subsystem/shuttle/SSshuttle
//world.log << "[transit_turfs.len] transit turfs registered"
/datum/subsystem/shuttle/fire()
/datum/controller/subsystem/shuttle/fire()
for(var/thing in mobile)
if(!thing)
mobile.Remove(thing)
@@ -148,19 +152,19 @@ var/datum/subsystem/shuttle/SSshuttle
if(MC_TICK_CHECK)
return
/datum/subsystem/shuttle/proc/getShuttle(id)
/datum/controller/subsystem/shuttle/proc/getShuttle(id)
for(var/obj/docking_port/mobile/M in mobile)
if(M.id == id)
return M
WARNING("couldn't find shuttle with id: [id]")
/datum/subsystem/shuttle/proc/getDock(id)
/datum/controller/subsystem/shuttle/proc/getDock(id)
for(var/obj/docking_port/stationary/S in stationary)
if(S.id == id)
return S
WARNING("couldn't find dock with id: [id]")
/datum/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
/datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
if(!emergency)
WARNING("requestEvac(): There is no emergency shuttle, but the \
shuttle was called. Using the backup shuttle instead.")
@@ -176,33 +180,33 @@ var/datum/subsystem/shuttle/SSshuttle
emergency = backup_shuttle
if(world.time - round_start_time < config.shuttle_refuel_delay)
user << "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again."
to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.")
return
switch(emergency.mode)
if(SHUTTLE_RECALL)
user << "The emergency shuttle may not be called while returning to Centcom."
to_chat(user, "The emergency shuttle may not be called while returning to Centcom.")
return
if(SHUTTLE_CALL)
user << "The emergency shuttle is already on its way."
to_chat(user, "The emergency shuttle is already on its way.")
return
if(SHUTTLE_DOCKED)
user << "The emergency shuttle is already here."
to_chat(user, "The emergency shuttle is already here.")
return
if(SHUTTLE_IGNITING)
user << "The emergency shuttle is firing its engines to leave."
to_chat(user, "The emergency shuttle is firing its engines to leave.")
return
if(SHUTTLE_ESCAPE)
user << "The emergency shuttle is moving away to a safe distance."
to_chat(user, "The emergency shuttle is moving away to a safe distance.")
return
if(SHUTTLE_STRANDED)
user << "The emergency shuttle has been disabled by Centcom."
to_chat(user, "The emergency shuttle has been disabled by Centcom.")
return
call_reason = trim(html_encode(call_reason))
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && seclevel2num(get_security_level()) > SEC_LEVEL_GREEN)
user << "You must provide a reason."
to_chat(user, "You must provide a reason.")
return
var/area/signal_origin = get_area(user)
@@ -221,20 +225,20 @@ var/datum/subsystem/shuttle/SSshuttle
// Called when an emergency shuttle mobile docking port is
// destroyed, which will only happen with admin intervention
/datum/subsystem/shuttle/proc/emergencyDeregister()
/datum/controller/subsystem/shuttle/proc/emergencyDeregister()
// When a new emergency shuttle is created, it will override the
// backup shuttle.
src.emergency = src.backup_shuttle
/datum/subsystem/shuttle/proc/cancelEvac(mob/user)
/datum/controller/subsystem/shuttle/proc/cancelEvac(mob/user)
if(canRecall())
emergency.cancel(get_area(user))
log_game("[key_name(user)] has recalled the shuttle.")
message_admins("[key_name_admin(user)] has recalled the shuttle.")
return 1
/datum/subsystem/shuttle/proc/canRecall()
if(emergency.mode != SHUTTLE_CALL)
/datum/controller/subsystem/shuttle/proc/canRecall()
if(!emergency || emergency.mode != SHUTTLE_CALL)
return
if(ticker.mode.name == "meteor")
return
@@ -251,7 +255,7 @@ var/datum/subsystem/shuttle/SSshuttle
return
return 1
/datum/subsystem/shuttle/proc/autoEvac()
/datum/controller/subsystem/shuttle/proc/autoEvac()
var/callShuttle = 1
for(var/thing in shuttle_caller_list)
@@ -275,15 +279,15 @@ var/datum/subsystem/shuttle/SSshuttle
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
/datum/subsystem/shuttle/proc/registerHostileEnvironment(datum/bad)
/datum/controller/subsystem/shuttle/proc/registerHostileEnvironment(datum/bad)
hostileEnvironments[bad] = TRUE
checkHostileEnvironment()
/datum/subsystem/shuttle/proc/clearHostileEnvironment(datum/bad)
/datum/controller/subsystem/shuttle/proc/clearHostileEnvironment(datum/bad)
hostileEnvironments -= bad
checkHostileEnvironment()
/datum/subsystem/shuttle/proc/checkHostileEnvironment()
/datum/controller/subsystem/shuttle/proc/checkHostileEnvironment()
for(var/datum/d in hostileEnvironments)
if(!istype(d) || QDELETED(d))
hostileEnvironments -= d
@@ -304,7 +308,7 @@ var/datum/subsystem/shuttle/SSshuttle
null, 'sound/AI/shuttledock.ogg', "Priority")
//try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons
/datum/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
/datum/controller/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
if(!M)
return 1
@@ -321,7 +325,7 @@ var/datum/subsystem/shuttle/SSshuttle
return 0 //dock successful
/datum/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
/datum/controller/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
var/obj/docking_port/stationary/D = getDock(dockId)
@@ -335,7 +339,7 @@ var/datum/subsystem/shuttle/SSshuttle
return 2
return 0 //dock successful
/datum/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
/datum/controller/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
if(!istype(M))
throw EXCEPTION("[M] is not a mobile docking port")
@@ -345,7 +349,7 @@ var/datum/subsystem/shuttle/SSshuttle
if(!(M in transit_requesters))
transit_requesters += M
/datum/subsystem/shuttle/proc/generate_transit_dock(obj/docking_port/mobile/M)
/datum/controller/subsystem/shuttle/proc/generate_transit_dock(obj/docking_port/mobile/M)
// First, determine the size of the needed zone
// Because of shuttle rotation, the "width" of the shuttle is not
// always x.
@@ -368,7 +372,7 @@ var/datum/subsystem/shuttle/SSshuttle
transit_width += M.height
transit_height += M.width
/*
world << "The attempted transit dock will be [transit_width] width, and \
to_chat(world, "The attempted transit dock will be [transit_width] width, and \)
[transit_height] in height. The travel dir is [travel_dir]."
*/
@@ -398,17 +402,17 @@ var/datum/subsystem/shuttle/SSshuttle
continue base
if(!(T.flags & UNUSED_TRANSIT_TURF))
continue base
//world << "[COORD(topleft)] and [COORD(bottomright)]"
//to_chat(world, "[COORD(topleft)] and [COORD(bottomright)]")
break base
if((!proposed_zone) || (!proposed_zone.len))
return FALSE
var/turf/topleft = proposed_zone[1]
//world << "[COORD(topleft)] is TOPLEFT"
//to_chat(world, "[COORD(topleft)] is TOPLEFT")
// Then create a transit docking port in the middle
var/coords = M.return_coords(0, 0, dock_dir)
//world << json_encode(coords)
//to_chat(world, json_encode(coords))
/* 0------2
| |
| |
@@ -429,7 +433,7 @@ var/datum/subsystem/shuttle/SSshuttle
var/turf/low_point = locate(lowx, lowy, topleft.z)
new /obj/effect/landmark/stationary(low_point)
world << "Starting at the low point, we go [x2],[y2]"
to_chat(world, "Starting at the low point, we go [x2],[y2]")
*/
// Then invert the numbers
var/transit_x = topleft.x + SHUTTLE_TRANSIT_BORDER + abs(x2)
@@ -446,11 +450,11 @@ var/datum/subsystem/shuttle/SSshuttle
if(WEST)
transit_path = /turf/open/space/transit/west
//world << "Docking port at [transit_x], [transit_y], [topleft.z]"
//to_chat(world, "Docking port at [transit_x], [transit_y], [topleft.z]")
var/turf/midpoint = locate(transit_x, transit_y, topleft.z)
if(!midpoint)
return FALSE
//world << "Making transit dock at [COORD(midpoint)]"
//to_chat(world, "Making transit dock at [COORD(midpoint)]")
var/area/shuttle/transit/A = new()
A.parallax_movedir = travel_dir
var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint)
@@ -473,14 +477,14 @@ var/datum/subsystem/shuttle/SSshuttle
M.assigned_transit = new_transit_dock
return TRUE
/datum/subsystem/shuttle/proc/initial_move()
/datum/controller/subsystem/shuttle/proc/initial_move()
for(var/obj/docking_port/mobile/M in mobile)
if(!M.roundstart_move)
continue
M.dockRoundstart()
CHECK_TICK
/datum/subsystem/shuttle/Recover()
/datum/controller/subsystem/shuttle/Recover()
if (istype(SSshuttle.mobile))
mobile = SSshuttle.mobile
if (istype(SSshuttle.stationary))
@@ -504,5 +508,4 @@ var/datum/subsystem/shuttle/SSshuttle
centcom_message = SSshuttle.centcom_message
ordernum = SSshuttle.ordernum
points = SSshuttle.points
points = SSshuttle.points
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/spacedrift/SSspacedrift
var/datum/controller/subsystem/spacedrift/SSspacedrift
/datum/subsystem/spacedrift
/datum/controller/subsystem/spacedrift
name = "Space Drift"
priority = 30
wait = 5
@@ -9,15 +9,15 @@ var/datum/subsystem/spacedrift/SSspacedrift
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/spacedrift/New()
/datum/controller/subsystem/spacedrift/New()
NEW_SS_GLOBAL(SSspacedrift)
/datum/subsystem/spacedrift/stat_entry()
/datum/controller/subsystem/spacedrift/stat_entry()
..("P:[processing.len]")
/datum/subsystem/spacedrift/fire(resumed = 0)
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+6 -6
View File
@@ -1,23 +1,23 @@
var/datum/subsystem/squeak/SSsqueak
var/datum/controller/subsystem/squeak/SSsqueak
// The Squeak
// because this is about placement of mice mobs, and nothing to do with
// mice - the computer peripheral
/datum/subsystem/squeak
/datum/controller/subsystem/squeak
name = "Squeak"
priority = 40
flags = SS_NO_FIRE
var/list/exposed_wires = list()
/datum/subsystem/squeak/New()
/datum/controller/subsystem/squeak/New()
NEW_SS_GLOBAL(SSsqueak)
/datum/subsystem/squeak/Initialize(timeofday)
/datum/controller/subsystem/squeak/Initialize(timeofday)
trigger_migration()
/datum/subsystem/squeak/proc/trigger_migration(num_mice=10)
/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10)
find_exposed_wires()
var/mob/living/simple_animal/mouse/M
@@ -33,7 +33,7 @@ var/datum/subsystem/squeak/SSsqueak
num_mice -= 1
M = null
/datum/subsystem/squeak/proc/find_exposed_wires()
/datum/controller/subsystem/squeak/proc/find_exposed_wires()
exposed_wires.Cut()
var/list/all_turfs = block(locate(1,1,1), locate(world.maxx,world.maxy,1))
+4 -4
View File
@@ -1,16 +1,16 @@
var/datum/subsystem/stickyban/SSstickyban
var/datum/controller/subsystem/stickyban/SSstickyban
/datum/subsystem/stickyban
/datum/controller/subsystem/stickyban
name = "Sticky Ban"
init_order = -10
flags = SS_NO_FIRE
var/list/cache = list()
/datum/subsystem/stickyban/New()
/datum/controller/subsystem/stickyban/New()
NEW_SS_GLOBAL(SSstickyban)
/datum/subsystem/stickyban/Initialize(timeofday)
/datum/controller/subsystem/stickyban/Initialize(timeofday)
var/list/bannedkeys = world.GetConfig("ban")
//sanitize the sticky ban list
for (var/bannedkey in bannedkeys)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/sun/SSsun
var/datum/controller/subsystem/sun/SSsun
/datum/subsystem/sun
/datum/controller/subsystem/sun
name = "Sun"
wait = 600
init_order = 2
@@ -11,7 +11,7 @@ var/datum/subsystem/sun/SSsun
var/rate
var/list/solars = list()
/datum/subsystem/sun/New()
/datum/controller/subsystem/sun/New()
NEW_SS_GLOBAL(SSsun)
angle = rand (0,360) // the station position to the sun is randomised at round start
@@ -19,10 +19,10 @@ var/datum/subsystem/sun/SSsun
if(prob(50)) // same chance to rotate clockwise than counter-clockwise
rate = -rate
/datum/subsystem/sun/stat_entry(msg)
/datum/controller/subsystem/sun/stat_entry(msg)
..("P:[solars.len]")
/datum/subsystem/sun/fire()
/datum/controller/subsystem/sun/fire()
angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate
// now calculate and cache the (dx,dy) increments for line drawing
+6 -7
View File
@@ -1,10 +1,9 @@
var/datum/subsystem/tgui/SStgui
var/datum/controller/subsystem/tgui/SStgui
/datum/subsystem/tgui
/datum/controller/subsystem/tgui
name = "tgui"
wait = 9
init_order = 16
display_order = 6
flags = SS_NO_INIT|SS_FIRE_IN_LOBBY
priority = 110
@@ -13,18 +12,18 @@ var/datum/subsystem/tgui/SStgui
var/list/processing_uis = list() // A list of processing UIs, ungrouped.
var/basehtml // The HTML base used for all UIs.
/datum/subsystem/tgui/New()
/datum/controller/subsystem/tgui/New()
basehtml = file2text('tgui/tgui.html') // Read the HTML from disk.
NEW_SS_GLOBAL(SStgui)
/datum/subsystem/tgui/Shutdown()
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
/datum/subsystem/tgui/stat_entry()
/datum/controller/subsystem/tgui/stat_entry()
..("P:[processing_uis.len]")
/datum/subsystem/tgui/fire(resumed = 0)
/datum/controller/subsystem/tgui/fire(resumed = 0)
if (!resumed)
src.currentrun = processing_uis.Copy()
//cache for sanic speed (lists are references anyways)
+5 -5
View File
@@ -1,8 +1,8 @@
#define MAX_THROWING_DIST 512 // 2 z-levels on default width
#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
var/datum/subsystem/throwing/SSthrowing
var/datum/controller/subsystem/throwing/SSthrowing
/datum/subsystem/throwing
/datum/controller/subsystem/throwing
name = "Throwing"
priority = 25
wait = 1
@@ -11,16 +11,16 @@ var/datum/subsystem/throwing/SSthrowing
var/list/currentrun
var/list/processing
/datum/subsystem/throwing/New()
/datum/controller/subsystem/throwing/New()
NEW_SS_GLOBAL(SSthrowing)
processing = list()
/datum/subsystem/throwing/stat_entry()
/datum/controller/subsystem/throwing/stat_entry()
..("P:[processing.len]")
/datum/subsystem/throwing/fire(resumed = 0)
/datum/controller/subsystem/throwing/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+124 -98
View File
@@ -2,9 +2,9 @@
var/round_start_time = 0
var/datum/subsystem/ticker/ticker
var/datum/controller/subsystem/ticker/ticker
/datum/subsystem/ticker
/datum/controller/subsystem/ticker
name = "Ticker"
init_order = 13
@@ -56,19 +56,17 @@ var/datum/subsystem/ticker/ticker
var/news_report
var/modevoted = 0 //Have we sent a vote for the gamemode?
var/late_join_disabled
/datum/subsystem/ticker/New()
var/modevoted = FALSE //Have we sent a vote for the gamemode?
/datum/controller/subsystem/ticker/New()
NEW_SS_GLOBAL(ticker)
if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS])
login_music = 'sound/ambience/clown.ogg'
else
var/list/music = file2list(ROUND_START_MUSIC_LIST, "\n")
login_music = pick(music)
/datum/subsystem/ticker/Initialize(timeofday)
/datum/controller/subsystem/ticker/Initialize(timeofday)
var/list/music = file2list(ROUND_START_MUSIC_LIST, "\n")
login_music = pick(music)
if(!syndicate_code_phrase)
syndicate_code_phrase = generate_code_phrase()
if(!syndicate_code_response)
@@ -76,14 +74,14 @@ var/datum/subsystem/ticker/ticker
..()
start_at = world.time + (config.lobby_countdown * 10)
/datum/subsystem/ticker/fire()
/datum/controller/subsystem/ticker/fire()
switch(current_state)
if(GAME_STATE_STARTUP)
if(Master.initializations_finished_with_no_players_logged_in)
start_at = world.time + (config.lobby_countdown * 10)
for(var/client/C in clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
world << "<span class='boldnotice'>Welcome to [station_name()]!</span>"
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
current_state = GAME_STATE_PREGAME
if(!modevoted)
send_gamemode_vote()
@@ -95,7 +93,7 @@ var/datum/subsystem/ticker/ticker
timeLeft = max(0,start_at - world.time)
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
++totalPlayers
if(player.ready)
++totalPlayersReady
@@ -133,7 +131,9 @@ var/datum/subsystem/ticker/ticker
toggle_ooc(1) // Turn it on
declare_completion(force_ending)
/datum/subsystem/ticker/proc/setup()
/datum/controller/subsystem/ticker/proc/setup()
to_chat(world, "<span class='boldannounce'>Starting game...</span>")
var/init_start = world.timeofday
//Create and announce mode
var/list/datum/game_mode/runnable_modes
if(master_mode == "random" || master_mode == "secret")
@@ -150,71 +150,83 @@ var/datum/subsystem/ticker/ticker
if(!mode)
if(!runnable_modes.len)
world << "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby."
to_chat(world, "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby.")
return 0
mode = pickweight(runnable_modes)
else
mode = config.pick_mode(master_mode)
if(!mode.can_start())
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby."
to_chat(world, "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.")
qdel(mode)
mode = null
SSjob.ResetOccupations()
return 0
CHECK_TICK
//Configure mode and assign player to special mode stuff
var/can_continue = 0
can_continue = src.mode.pre_setup() //Choose antagonists
CHECK_TICK
SSjob.DivideOccupations() //Distribute jobs
CHECK_TICK
if(!Debug2)
if(!can_continue)
qdel(mode)
mode = null
world << "<B>Error setting up [master_mode].</B> Reverting to pre-game lobby."
to_chat(world, "<B>Error setting up [master_mode].</B> Reverting to pre-game lobby.")
SSjob.ResetOccupations()
return 0
else
message_admins("<span class='notice'>DEBUG: Bypassing prestart checks...</span>")
CHECK_TICK
if(hide_mode)
var/list/modes = new
for (var/datum/game_mode/M in runnable_modes)
modes += M.name
modes = sortList(modes)
world << "<b>The gamemode is: secret!\n\
Possibilities:</B> [english_list(modes)]"
to_chat(world, "<b>The gamemode is: secret!\nPossibilities:</B> [english_list(modes)]")
else
mode.announce()
current_state = GAME_STATE_PLAYING
if(!config.ooc_during_round)
toggle_ooc(0) // Turn it off
round_start_time = world.time
CHECK_TICK
start_landmarks_list = shuffle(start_landmarks_list) //Shuffle the order of spawn points so they dont always predictably spawn bottom-up and right-to-left
create_characters() //Create player characters and transfer them
create_characters() //Create player characters
collect_minds()
equip_characters()
SSoverlays.Flush() //Flush the majority of the shit
data_core.manifest()
Master.RoundStart()
transfer_characters() //transfer keys to the new mobs
world << "<FONT color='blue'><B>Welcome to [station_name()], enjoy your stay!</B></FONT>"
Master.RoundStart() //let the party begin...
log_world("Game start took [(world.timeofday - init_start)/10]s")
round_start_time = world.time
to_chat(world, "<FONT color='blue'><B>Welcome to [station_name()], enjoy your stay!</B></FONT>")
world << sound('sound/AI/welcome.ogg')
current_state = GAME_STATE_PLAYING
if(SSevent.holidays)
world << "<font color='blue'>and...</font>"
to_chat(world, "<font color='blue'>and...</font>")
for(var/holidayname in SSevent.holidays)
var/datum/holiday/holiday = SSevent.holidays[holidayname]
world << "<h4>[holiday.greet()]</h4>"
to_chat(world, "<h4>[holiday.greet()]</h4>")
PostSetup()
return 1
/datum/subsystem/ticker/proc/PostSetup()
/datum/controller/subsystem/ticker/proc/PostSetup()
set waitfor = 0
mode.post_setup()
//Cleanup some stuff
@@ -227,7 +239,7 @@ var/datum/subsystem/ticker/ticker
var/list/allmins = adm["present"]
send2irc("Server", "Round of [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]")
/datum/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
/datum/controller/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
if(bomb) //BOOM
var/turf/epi = bomb.loc
qdel(bomb)
@@ -235,7 +247,7 @@ var/datum/subsystem/ticker/ticker
explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
/datum/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
if( cinematic )
return //already a cinematic in progress!
@@ -344,12 +356,12 @@ var/datum/subsystem/ticker/ticker
if(mode)
mode.explosion_in_progress = 0
world << "<B>The station was destoyed by the nuclear blast!</B>"
to_chat(world, "<B>The station was destoyed by the nuclear blast!</B>")
mode.station_was_nuked = (station_missed<2) //station_missed==1 is a draw. the station becomes irradiated and needs to be evacuated.
addtimer(CALLBACK(src, .proc/finish_cinematic, bombloc, actually_blew_up), 300)
/datum/subsystem/ticker/proc/finish_cinematic(killz, actually_blew_up)
/datum/controller/subsystem/ticker/proc/finish_cinematic(killz, actually_blew_up)
if(cinematic)
qdel(cinematic) //end the cinematic
cinematic = null
@@ -358,49 +370,65 @@ var/datum/subsystem/ticker/ticker
if(actually_blew_up && !isnull(killz) && M.stat != DEAD && M.z == killz)
M.gib()
/datum/subsystem/ticker/proc/create_characters()
for(var/mob/new_player/player in player_list)
/datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/dead/new_player/player in player_list)
if(player.ready && player.mind)
joined_player_list += player.ckey
if(player.mind.assigned_role=="AI")
player.close_spawn_windows()
player.AIize()
else
player.create_character()
qdel(player)
player.create_character(FALSE)
else
player.new_player_panel()
CHECK_TICK
/datum/controller/subsystem/ticker/proc/collect_minds()
for(var/mob/dead/new_player/P in player_list)
if(P.new_character && P.new_character.mind)
ticker.minds += P.new_character.mind
CHECK_TICK
/datum/subsystem/ticker/proc/collect_minds()
for(var/mob/living/player in player_list)
if(player.mind)
ticker.minds += player.mind
/datum/subsystem/ticker/proc/equip_characters()
/datum/controller/subsystem/ticker/proc/equip_characters()
var/captainless=1
for(var/mob/living/carbon/human/player in player_list)
if(player && player.mind && player.mind.assigned_role)
for(var/mob/dead/new_player/N in player_list)
var/mob/living/carbon/human/player = N.new_character
if(istype(player) && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain")
captainless=0
if(player.mind.assigned_role != player.mind.special_role)
SSjob.EquipRank(player, player.mind.assigned_role, 0)
SSjob.EquipRank(N, player.mind.assigned_role, 0)
CHECK_TICK
if(captainless)
for(var/mob/M in player_list)
if(!isnewplayer(M))
M << "Captainship not forced on anyone."
for(var/mob/dead/new_player/N in player_list)
if(N.new_character)
to_chat(N, "Captainship not forced on anyone.")
CHECK_TICK
/datum/controller/subsystem/ticker/proc/transfer_characters()
var/list/livings = list()
for(var/mob/dead/new_player/player in player_list)
var/mob/living = player.transfer_character()
if(living)
qdel(player)
living.notransform = TRUE
if(living.client)
var/obj/screen/splash/S = new(living.client, TRUE)
S.Fade(TRUE)
livings += living
if(livings.len)
addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME)
/datum/controller/subsystem/ticker/proc/release_characters(list/livings)
for(var/I in livings)
var/mob/living/L = I
L.notransform = FALSE
/datum/subsystem/ticker/proc/declare_completion()
/datum/controller/subsystem/ticker/proc/declare_completion()
set waitfor = FALSE
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
var/num_survivors = 0
var/num_escapees = 0
var/num_shuttle_escapees = 0
world << "<BR><BR><BR><FONT size=3><B>The round has ended.</B></FONT>"
to_chat(world, "<BR><BR><BR><FONT size=3><B>The round has ended.</B></FONT>")
//Player status report
for(var/mob/Player in mob_list)
@@ -412,16 +440,16 @@ var/datum/subsystem/ticker/ticker
if(SSshuttle && SSshuttle.emergency)
shuttle_area = SSshuttle.emergency.areaInstance
if(!Player.onCentcom() && !Player.onSyndieBase())
Player << "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>"
to_chat(Player, "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>")
else
num_escapees++
Player << "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>"
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
if(get_area(Player) == shuttle_area)
num_shuttle_escapees++
else
Player << "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>"
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
else
Player << "<font color='red'><b>You did not survive the events on [station_name()]...</b></FONT>"
to_chat(Player, "<font color='red'><b>You did not survive the events on [station_name()]...</b></FONT>")
CHECK_TICK
@@ -430,50 +458,50 @@ var/datum/subsystem/ticker/ticker
end_state.count()
var/station_integrity = min(PERCENT(start_state.score(end_state)), 100)
world << "<BR>[TAB]Shift Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B>"
world << "<BR>[TAB]Station Integrity: <B>[mode.station_was_nuked ? "<font color='red'>Destroyed</font>" : "[station_integrity]%"]</B>"
to_chat(world, "<BR>[TAB]Shift Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B>")
to_chat(world, "<BR>[TAB]Station Integrity: <B>[mode.station_was_nuked ? "<font color='red'>Destroyed</font>" : "[station_integrity]%"]</B>")
if(mode.station_was_nuked)
ticker.news_report = STATION_DESTROYED_NUKE
var/total_players = joined_player_list.len
if(joined_player_list.len)
world << "<BR>[TAB]Total Population: <B>[total_players]</B>"
to_chat(world, "<BR>[TAB]Total Population: <B>[total_players]</B>")
if(station_evacuated)
world << "<BR>[TAB]Evacuation Rate: <B>[num_escapees] ([PERCENT(num_escapees/total_players)]%)</B>"
world << "<BR>[TAB](on emergency shuttle): <B>[num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)</B>"
to_chat(world, "<BR>[TAB]Evacuation Rate: <B>[num_escapees] ([PERCENT(num_escapees/total_players)]%)</B>")
to_chat(world, "<BR>[TAB](on emergency shuttle): <B>[num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)</B>")
news_report = STATION_EVACUATED
if(SSshuttle.emergency.is_hijacked())
news_report = SHUTTLE_HIJACK
world << "<BR>[TAB]Survival Rate: <B>[num_survivors] ([PERCENT(num_survivors/total_players)]%)</B>"
world << "<BR>"
to_chat(world, "<BR>[TAB]Survival Rate: <B>[num_survivors] ([PERCENT(num_survivors/total_players)]%)</B>")
to_chat(world, "<BR>")
CHECK_TICK
//Silicon laws report
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
if (aiPlayer.stat != 2 && aiPlayer.mind)
world << "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:</b>"
to_chat(world, "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:</b>")
aiPlayer.show_laws(1)
else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead
world << "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:</b>"
to_chat(world, "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:</b>")
aiPlayer.show_laws(1)
world << "<b>Total law changes: [aiPlayer.law_change_counter]</b>"
to_chat(world, "<b>Total law changes: [aiPlayer.law_change_counter]</b>")
if (aiPlayer.connected_robots.len)
var/robolist = "<b>[aiPlayer.real_name]'s minions were:</b> "
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
if(robo.mind)
robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]"
world << "[robolist]"
to_chat(world, "[robolist]")
CHECK_TICK
for (var/mob/living/silicon/robot/robo in mob_list)
if (!robo.connected_ai && robo.mind)
if (robo.stat != 2)
world << "<b>[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:</b>"
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:</b>")
else
world << "<b>[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>"
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>")
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
robo.laws.show_laws(world)
@@ -491,7 +519,7 @@ var/datum/subsystem/ticker/ticker
CHECK_TICK
if(cross_allowed)
if(config.cross_allowed)
send_news_report()
CHECK_TICK
@@ -530,7 +558,7 @@ var/datum/subsystem/ticker/ticker
else
borertext += "failed"
borertext += ")"
world << borertext
to_chat(world, borertext)
var/total_borers = 0
for(var/mob/living/simple_animal/borer/B in borers)
@@ -545,12 +573,12 @@ var/datum/subsystem/ticker/ticker
total_borer_hosts++
if(total_borer_hosts_needed <= total_borer_hosts)
borerwin = TRUE
world << "<b>There were [total_borers] borers alive at round end!</b>"
world << "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [total_borer_hosts_needed] hosts to escape.</b>"
to_chat(world, "<b>There were [total_borers] borers alive at round end!</b>")
to_chat(world, "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [total_borer_hosts_needed] hosts to escape.</b>")
if(borerwin)
world << "<b><font color='green'>The borers were successful!</font></b>"
to_chat(world, "<b><font color='green'>The borers were successful!</font></b>")
else
world << "<b><font color='red'>The borers have failed!</font></b>"
to_chat(world, "<b><font color='red'>The borers have failed!</font></b>")
CHECK_TICK
@@ -583,7 +611,7 @@ var/datum/subsystem/ticker/ticker
else
world.Reboot("Round ended.", "end_proper", "proper completion")
/datum/subsystem/ticker/proc/send_tip_of_the_round()
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
var/m
if(selected_tip)
m = selected_tip
@@ -596,35 +624,34 @@ var/datum/subsystem/ticker/ticker
m = pick(memetips)
if(m)
world << "<font color='purple'><b>Tip of the round: \
</b>[html_encode(m)]</font>"
to_chat(world, "<font color='purple'><b>Tip of the round: </b>[html_encode(m)]</font>")
/datum/subsystem/ticker/proc/check_queue()
/datum/controller/subsystem/ticker/proc/check_queue()
if(!queued_players.len || !config.hard_popcap)
return
queue_delay++
var/mob/new_player/next_in_line = queued_players[1]
var/mob/dead/new_player/next_in_line = queued_players[1]
switch(queue_delay)
if(5) //every 5 ticks check if there is a slot available
if(living_player_count() < config.hard_popcap)
if(next_in_line && next_in_line.client)
next_in_line << "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>"
to_chat(next_in_line, "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>")
next_in_line << sound('sound/misc/notice1.ogg')
next_in_line.LateChoices()
return
queued_players -= next_in_line //Client disconnected, remove he
queue_delay = 0 //No vacancy: restart timer
if(25 to INFINITY) //No response from the next in line when a vacancy exists, remove he
next_in_line << "<span class='danger'>No response recieved. You have been removed from the line.</span>"
to_chat(next_in_line, "<span class='danger'>No response recieved. You have been removed from the line.</span>")
queued_players -= next_in_line
queue_delay = 0
/datum/subsystem/ticker/proc/check_maprotate()
if (!config.maprotation || !SERVERTOOLS)
/datum/controller/subsystem/ticker/proc/check_maprotate()
if (!config.maprotation)
return
if (SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
return
if (maprotatechecked)
return
@@ -634,9 +661,9 @@ var/datum/subsystem/ticker/ticker
//map rotate chance defaults to 75% of the length of the round (in minutes)
if (!prob((world.time/600)*config.maprotatechancedelta))
return
INVOKE_ASYNC(GLOBAL_PROC, /.proc/maprotate)
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
/datum/subsystem/ticker/proc/send_gamemode_vote(var/)
/datum/controller/subsystem/ticker/proc/send_gamemode_vote(var/)
SSvote.initiate_vote("roundtype","server")
/world/proc/has_round_started()
@@ -644,7 +671,7 @@ var/datum/subsystem/ticker/ticker
return TRUE
return FALSE
/datum/subsystem/ticker/Recover()
/datum/controller/subsystem/ticker/Recover()
current_state = ticker.current_state
force_ending = ticker.force_ending
hide_mode = ticker.hide_mode
@@ -676,10 +703,9 @@ var/datum/subsystem/ticker/ticker
queued_players = ticker.queued_players
cinematic = ticker.cinematic
maprotatechecked = ticker.maprotatechecked
modevoted = ticker.modevoted
/datum/subsystem/ticker/proc/send_news_report()
/datum/controller/subsystem/ticker/proc/send_news_report()
var/news_message
var/news_source = "Nanotrasen News Network"
switch(news_report)
@@ -706,19 +732,19 @@ var/datum/subsystem/ticker/ticker
if(CULT_SUMMON)
news_message = "Company officials would like to clarify that [station_name()] was scheduled to be decommissioned following meteor damage earlier this year. Earlier reports of an unknowable eldritch horror were made in error."
if(NUKE_MISS)
news_message = "The Syndicate have bungled a terrorist attack [station_name()], detonating a nuclear weapon in empty space near by."
news_message = "The Syndicate have bungled a terrorist attack [station_name()], detonating a nuclear weapon in empty space nearby."
if(OPERATIVES_KILLED)
news_message = "Repairs to [station_name()] are underway after an elite Syndicate death squad was wiped out by the crew."
if(OPERATIVE_SKIRMISH)
news_message = "A skirmish between security forces and Syndicate agents aboard [station_name()] ended with both sides bloodied but intact."
if(REVS_WIN)
news_message = "Company officials have reassured investors that despite a union led revolt aboard [station_name()] that there will be no wage increases for workers."
news_message = "Company officials have reassured investors that despite a union led revolt aboard [station_name()] there will be no wage increases for workers."
if(REVS_LOSE)
news_message = "[station_name()] quickly put down a misguided attempt at mutiny. Remember, unionizing is illegal!"
if(WIZARD_KILLED)
news_message = "Tensions have flared with the Wizard's Federation following the death of one of their members aboard [station_name()]."
news_message = "Tensions have flared with the Space Wizard Federation following the death of one of their members aboard [station_name()]."
if(STATION_NUKED)
news_message = "[station_name()] activated its self destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are under way."
news_message = "[station_name()] activated its self destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are underway."
if(CLOCK_SUMMON)
news_message = "The garbled messages about hailing a mouse and strange energy readings from [station_name()] have been discovered to be an ill-advised, if thorough, prank by a clown."
if(CLOCK_SILICONS)
@@ -731,12 +757,12 @@ var/datum/subsystem/ticker/ticker
if(news_message)
send2otherserver(news_source, news_message,"News_Report")
/datum/subsystem/ticker/proc/GetTimeLeft()
/datum/controller/subsystem/ticker/proc/GetTimeLeft()
if(isnull(ticker.timeLeft))
return max(0, start_at - world.time)
return timeLeft
/datum/subsystem/ticker/proc/SetTimeLeft(newtime)
/datum/controller/subsystem/ticker/proc/SetTimeLeft(newtime)
if(newtime >= 0 && isnull(timeLeft)) //remember, negative means delayed
start_at = world.time + newtime
else
+4 -4
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/time_track/SStime_track
var/datum/controller/subsystem/time_track/SStime_track
/datum/subsystem/time_track
/datum/controller/subsystem/time_track
name = "Time Tracking"
wait = 600
flags = SS_NO_INIT|SS_FIRE_IN_LOBBY
@@ -17,10 +17,10 @@ var/datum/subsystem/time_track/SStime_track
var/last_tick_byond_time = 0
var/last_tick_tickcount = 0
/datum/subsystem/time_track/New()
/datum/controller/subsystem/time_track/New()
NEW_SS_GLOBAL(SStime_track)
/datum/subsystem/time_track/fire()
/datum/controller/subsystem/time_track/fire()
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time
+7 -8
View File
@@ -1,12 +1,11 @@
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
#define BUCKET_POS(timer) (round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) + 1)
var/datum/subsystem/timer/SStimer
var/datum/controller/subsystem/timer/SStimer
/datum/subsystem/timer
/datum/controller/subsystem/timer
name = "Timer"
wait = 1 //SS_TICKER subsystem, so wait is in ticks
init_order = 1
display_order = 3
flags = SS_FIRE_IN_LOBBY|SS_TICKER|SS_NO_INIT
@@ -25,7 +24,7 @@ var/datum/subsystem/timer/SStimer
var/list/clienttime_timers //special snowflake timers that run on fancy pansy "client time"
/datum/subsystem/timer/New()
/datum/controller/subsystem/timer/New()
processing = list()
hashes = list()
bucket_list = list()
@@ -36,10 +35,10 @@ var/datum/subsystem/timer/SStimer
NEW_SS_GLOBAL(SStimer)
/datum/subsystem/timer/stat_entry(msg)
/datum/controller/subsystem/timer/stat_entry(msg)
..("B:[bucket_count] P:[length(processing)] H:[length(hashes)] C:[length(clienttime_timers)]")
/datum/subsystem/timer/fire(resumed = FALSE)
/datum/controller/subsystem/timer/fire(resumed = FALSE)
while(length(clienttime_timers))
var/datum/timedevent/ctime_timer = clienttime_timers[clienttime_timers.len]
if (ctime_timer.timeToRun <= REALTIMEOFDAY)
@@ -107,7 +106,7 @@ var/datum/subsystem/timer/SStimer
spent.len = 0
/datum/subsystem/timer/proc/shift_buckets()
/datum/controller/subsystem/timer/proc/shift_buckets()
var/list/bucket_list = src.bucket_list
var/list/alltimers = list()
//collect the timers currently in the bucket
@@ -172,7 +171,7 @@ var/datum/subsystem/timer/SStimer
processing = (alltimers - timers_to_remove)
/datum/subsystem/timer/Recover()
/datum/controller/subsystem/timer/Recover()
processing |= SStimer.processing
hashes |= SStimer.hashes
timer_id_dict |= SStimer.timer_id_dict
@@ -0,0 +1,39 @@
var/datum/controller/subsystem/title/SStitle
/datum/controller/subsystem/title
name = "Title Screen"
init_order = 15
flags = SS_NO_FIRE
var/turf/closed/indestructible/splashscreen/title_screen
/datum/controller/subsystem/title/New()
NEW_SS_GLOBAL(SStitle)
/datum/controller/subsystem/title/Initialize()
var/list/provisional_title_screens = flist("config/title_screens/images/")
var/list/title_screens = list()
var/use_rare_screens = FALSE
if(title_screen)
if(prob(1))
use_rare_screens = TRUE
for(var/S in provisional_title_screens)
var/list/L = splittext(S,"+")
if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name)))))
title_screens += S
if(!isemptylist(title_screens))
if(length(title_screens) > 1)
for(var/S in title_screens)
var/list/L = splittext(S,".")
if(L.len != 2 || L[1] != "default")
continue
title_screens -= S
break
var/path_string = "config/title_screens/images/[pick(title_screens)]"
var/icon/screen_to_use = new(path_string)
title_screen.icon = screen_to_use
..()

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