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:
@@ -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!
|
||||
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -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>"
|
||||
|
||||
@@ -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
|
||||
@@ -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 //
|
||||
/////////////
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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))
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
@@ -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)] °C</span>"
|
||||
to_chat(user, "<span class='notice'>Temperature: [round(air_contents.temperature-T0C)] °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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 = " "
|
||||
|
||||
|
||||
|
||||
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 = " "
|
||||
@@ -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()
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
/datum/hud
|
||||
var/obj/screen/arousal
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
. = ..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
..()
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user