mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
TG performance tweaks - oh-god-please-kill-me-edition ASYNC / SLEEP BAD / Profiler (#10207)
* Im sleepy * Reee * oopsie Linter go brrrr * Update code/datums/components/storage/concrete/bag_of_holding.dm Co-authored-by: Nichlas Pihl <nichlas00100@gmail.com> * Update code/controllers/subsystem/air.dm Co-authored-by: Nichlas Pihl <nichlas00100@gmail.com>
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
#define CLEAN_IMPRESSIVE 5
|
#define CLEAN_IMPRESSIVE 5
|
||||||
/// Cleans things spotless down to the atomic structure
|
/// Cleans things spotless down to the atomic structure
|
||||||
#define CLEAN_GOD 6
|
#define CLEAN_GOD 6
|
||||||
|
/// Never cleaned
|
||||||
|
#define CLEAN_NEVER 7
|
||||||
|
|
||||||
//How strong things have to be to wipe forensic evidence...
|
//How strong things have to be to wipe forensic evidence...
|
||||||
#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
|
#define CLEAN_STRENGTH_FINGERPRINTS CLEAN_IMPRESSIVE
|
||||||
|
|||||||
@@ -478,3 +478,5 @@ GLOBAL_LIST_INIT(pda_styles, list(MONO, VT, ORBITRON, SHARE))
|
|||||||
#define ALIGNMENT_NEUT "neutral"
|
#define ALIGNMENT_NEUT "neutral"
|
||||||
#define ALIGNMENT_EVIL "evil"
|
#define ALIGNMENT_EVIL "evil"
|
||||||
|
|
||||||
|
// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
|
||||||
|
#define REF(thing) (istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
|
||||||
@@ -98,6 +98,7 @@
|
|||||||
// Subsystems shutdown in the reverse of the order they initialize in
|
// Subsystems shutdown in the reverse of the order they initialize in
|
||||||
// The numbers just define the ordering, they are meaningless otherwise.
|
// The numbers just define the ordering, they are meaningless otherwise.
|
||||||
|
|
||||||
|
#define INIT_ORDER_PROFILER 101
|
||||||
#define INIT_ORDER_TITLE 100
|
#define INIT_ORDER_TITLE 100
|
||||||
#define INIT_ORDER_GARBAGE 99
|
#define INIT_ORDER_GARBAGE 99
|
||||||
#define INIT_ORDER_STATPANELS 98
|
#define INIT_ORDER_STATPANELS 98
|
||||||
|
|||||||
@@ -174,11 +174,11 @@
|
|||||||
/proc/recursive_hear_check(O)
|
/proc/recursive_hear_check(O)
|
||||||
var/list/processing_list = list(O)
|
var/list/processing_list = list(O)
|
||||||
. = list()
|
. = list()
|
||||||
while(processing_list.len)
|
var/i = 0
|
||||||
var/atom/A = processing_list[1]
|
while(i < length(processing_list))
|
||||||
|
var/atom/A = processing_list[++i]
|
||||||
if(A.flags_1 & HEAR_1)
|
if(A.flags_1 & HEAR_1)
|
||||||
. += A
|
. += A
|
||||||
processing_list.Cut(1, 2)
|
|
||||||
processing_list += A.contents
|
processing_list += A.contents
|
||||||
|
|
||||||
/** recursive_organ_check
|
/** recursive_organ_check
|
||||||
@@ -264,10 +264,8 @@
|
|||||||
// Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
|
// Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
|
||||||
var/turf/T = get_turf(source)
|
var/turf/T = get_turf(source)
|
||||||
. = list()
|
. = list()
|
||||||
|
|
||||||
if(!T)
|
if(!T)
|
||||||
return
|
return
|
||||||
|
|
||||||
var/list/processing_list = list()
|
var/list/processing_list = list()
|
||||||
if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
|
if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
|
||||||
processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
|
processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
|
||||||
@@ -280,11 +278,11 @@
|
|||||||
processing_list += O
|
processing_list += O
|
||||||
T.luminosity = lum
|
T.luminosity = lum
|
||||||
|
|
||||||
while(processing_list.len) // recursive_hear_check inlined here
|
var/i = 0
|
||||||
var/atom/A = processing_list[1]
|
while(i < length(processing_list)) // recursive_hear_check inlined here
|
||||||
|
var/atom/A = processing_list[++i]
|
||||||
if(A.flags_1 & HEAR_1)
|
if(A.flags_1 & HEAR_1)
|
||||||
. += A
|
. += A
|
||||||
processing_list.Cut(1, 2)
|
|
||||||
processing_list += A.contents
|
processing_list += A.contents
|
||||||
|
|
||||||
/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios)
|
/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios)
|
||||||
|
|||||||
@@ -449,38 +449,38 @@ Turf and target are separate in case you want to teleport some distance from a t
|
|||||||
Gets all contents of contents and returns them all in a list.
|
Gets all contents of contents and returns them all in a list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/atom/proc/GetAllContents(var/T)
|
/atom/proc/GetAllContents(T, ignore_flag_1)
|
||||||
var/list/processing_list = list(src)
|
var/list/processing_list = list(src)
|
||||||
var/list/assembled = list()
|
|
||||||
if(T)
|
if(T)
|
||||||
while(processing_list.len)
|
. = list()
|
||||||
var/atom/A = processing_list[1]
|
var/i = 0
|
||||||
processing_list.Cut(1, 2)
|
while(i < length(processing_list))
|
||||||
|
var/atom/A = processing_list[++i]
|
||||||
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
|
//Byond does not allow things to be in multiple contents, or double parent-child hierarchies, so only += is needed
|
||||||
//This is also why we don't need to check against assembled as we go along
|
//This is also why we don't need to check against assembled as we go along
|
||||||
|
if (!(A.flags_1 & ignore_flag_1))
|
||||||
processing_list += A.contents
|
processing_list += A.contents
|
||||||
if(istype(A,T))
|
if(istype(A,T))
|
||||||
assembled += A
|
. += A
|
||||||
else
|
else
|
||||||
while(processing_list.len)
|
var/i = 0
|
||||||
var/atom/A = processing_list[1]
|
while(i < length(processing_list))
|
||||||
processing_list.Cut(1, 2)
|
var/atom/A = processing_list[++i]
|
||||||
|
if (!(A.flags_1 & ignore_flag_1))
|
||||||
processing_list += A.contents
|
processing_list += A.contents
|
||||||
assembled += A
|
return processing_list
|
||||||
return assembled
|
|
||||||
|
|
||||||
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
|
/atom/proc/GetAllContentsIgnoring(list/ignore_typecache)
|
||||||
if(!length(ignore_typecache))
|
if(!length(ignore_typecache))
|
||||||
return GetAllContents()
|
return GetAllContents()
|
||||||
var/list/processing = list(src)
|
var/list/processing = list(src)
|
||||||
var/list/assembled = list()
|
. = list()
|
||||||
while(processing.len)
|
var/i = 0
|
||||||
var/atom/A = processing[1]
|
while(i < length(processing))
|
||||||
processing.Cut(1,2)
|
var/atom/A = processing[++i]
|
||||||
if(!ignore_typecache[A.type])
|
if(!ignore_typecache[A.type])
|
||||||
processing += A.contents
|
processing += A.contents
|
||||||
assembled += A
|
. += A
|
||||||
return assembled
|
|
||||||
|
|
||||||
//Step-towards method of determining whether one atom can see another. Similar to viewers()
|
//Step-towards method of determining whether one atom can see another. Similar to viewers()
|
||||||
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
/proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate.
|
||||||
@@ -1396,20 +1396,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new)
|
|||||||
|
|
||||||
return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}"
|
return "{[time_high]-[time_mid]-[GUID_VERSION][time_low]-[GUID_VARIANT][time_clock]-[node_id]}"
|
||||||
|
|
||||||
// \ref behaviour got changed in 512 so this is necesary to replicate old behaviour.
|
|
||||||
// If it ever becomes necesary to get a more performant REF(), this lies here in wait
|
|
||||||
// #define REF(thing) (thing && istype(thing, /datum) && (thing:datum_flags & DF_USE_TAG) && thing:tag ? "[thing:tag]" : "\ref[thing]")
|
|
||||||
/proc/REF(input)
|
|
||||||
if(istype(input, /datum))
|
|
||||||
var/datum/thing = input
|
|
||||||
if(thing.datum_flags & DF_USE_TAG)
|
|
||||||
if(!thing.tag)
|
|
||||||
stack_trace("A ref was requested of an object with DF_USE_TAG set but no tag: [thing]")
|
|
||||||
thing.datum_flags &= ~DF_USE_TAG
|
|
||||||
else
|
|
||||||
return "\[[url_encode(thing.tag)]\]"
|
|
||||||
return "\ref[input]"
|
|
||||||
|
|
||||||
// Makes a call in the context of a different usr
|
// Makes a call in the context of a different usr
|
||||||
// Use sparingly
|
// Use sparingly
|
||||||
/world/proc/PushUsr(mob/M, datum/callback/CB, ...)
|
/world/proc/PushUsr(mob/M, datum/callback/CB, ...)
|
||||||
|
|||||||
@@ -495,3 +495,5 @@
|
|||||||
/datum/config_entry/flag/everyone_is_donator
|
/datum/config_entry/flag/everyone_is_donator
|
||||||
|
|
||||||
/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API
|
/datum/config_entry/string/centcom_ban_db // URL for the CentCom Galactic Ban DB API
|
||||||
|
|
||||||
|
/datum/config_entry/flag/auto_profile
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
return
|
return
|
||||||
|
|
||||||
//This is used so the mc knows when the subsystem sleeps. do not override.
|
//This is used so the mc knows when the subsystem sleeps. do not override.
|
||||||
/datum/controller/subsystem/proc/ignite(resumed = 0)
|
/datum/controller/subsystem/proc/ignite(resumed = FALSE)
|
||||||
SHOULD_NOT_OVERRIDE(TRUE)
|
SHOULD_NOT_OVERRIDE(TRUE)
|
||||||
set waitfor = 0
|
set waitfor = FALSE
|
||||||
. = SS_SLEEPING
|
. = SS_SLEEPING
|
||||||
fire(resumed)
|
fire(resumed)
|
||||||
. = state
|
. = state
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
//previously, this would have been named 'process()' but that name is used everywhere for different things!
|
//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.
|
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
|
||||||
//Sleeping in here prevents future fires until returned.
|
//Sleeping in here prevents future fires until returned.
|
||||||
/datum/controller/subsystem/proc/fire(resumed = 0)
|
/datum/controller/subsystem/proc/fire(resumed = FALSE)
|
||||||
flags |= SS_NO_FIRE
|
flags |= SS_NO_FIRE
|
||||||
CRASH("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.")
|
CRASH("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.")
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ SUBSYSTEM_DEF(air)
|
|||||||
flags = SS_BACKGROUND
|
flags = SS_BACKGROUND
|
||||||
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME
|
||||||
|
|
||||||
|
var/cached_cost = 0
|
||||||
var/cost_turfs = 0
|
var/cost_turfs = 0
|
||||||
var/cost_groups = 0
|
var/cost_groups = 0
|
||||||
var/cost_highpressure = 0
|
var/cost_highpressure = 0
|
||||||
@@ -85,74 +86,93 @@ SUBSYSTEM_DEF(air)
|
|||||||
resumed = FALSE
|
resumed = FALSE
|
||||||
currentpart = SSAIR_PIPENETS
|
currentpart = SSAIR_PIPENETS
|
||||||
if(currentpart == SSAIR_PIPENETS || !resumed)
|
if(currentpart == SSAIR_PIPENETS || !resumed)
|
||||||
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_pipenets(resumed)
|
process_pipenets(resumed)
|
||||||
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
cached_cost += TICK_USAGE_REAL - timer
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_pipenets = MC_AVERAGE(cost_pipenets, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_ATMOSMACHINERY
|
currentpart = SSAIR_ATMOSMACHINERY
|
||||||
|
|
||||||
if(currentpart == SSAIR_ATMOSMACHINERY)
|
if(currentpart == SSAIR_ATMOSMACHINERY)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_atmos_machinery(resumed)
|
process_atmos_machinery(resumed)
|
||||||
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
cached_cost += TICK_USAGE_REAL - timer
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_atmos_machinery = MC_AVERAGE(cost_atmos_machinery, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_EQUALIZE
|
currentpart = SSAIR_EQUALIZE
|
||||||
|
|
||||||
if(currentpart == SSAIR_EQUALIZE)
|
if(currentpart == SSAIR_EQUALIZE)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_turf_equalize(resumed)
|
process_turf_equalize(resumed)
|
||||||
cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_equalize = MC_AVERAGE(cost_equalize, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_ACTIVETURFS
|
currentpart = SSAIR_ACTIVETURFS
|
||||||
|
|
||||||
if(currentpart == SSAIR_ACTIVETURFS)
|
if(currentpart == SSAIR_ACTIVETURFS)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_active_turfs(resumed)
|
process_active_turfs(resumed)
|
||||||
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_turfs = MC_AVERAGE(cost_turfs, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_EXCITEDGROUPS
|
currentpart = SSAIR_EXCITEDGROUPS
|
||||||
|
|
||||||
if(currentpart == SSAIR_EXCITEDGROUPS)
|
if(currentpart == SSAIR_EXCITEDGROUPS)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_excited_groups(resumed)
|
process_excited_groups(resumed)
|
||||||
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_groups = MC_AVERAGE(cost_groups, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_HIGHPRESSURE
|
currentpart = SSAIR_HIGHPRESSURE
|
||||||
|
|
||||||
if(currentpart == SSAIR_HIGHPRESSURE)
|
if(currentpart == SSAIR_HIGHPRESSURE)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_high_pressure_delta(resumed)
|
process_high_pressure_delta(resumed)
|
||||||
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_highpressure = MC_AVERAGE(cost_highpressure, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_HOTSPOTS
|
currentpart = SSAIR_HOTSPOTS
|
||||||
|
|
||||||
if(currentpart == SSAIR_HOTSPOTS)
|
if(currentpart == SSAIR_HOTSPOTS)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_hotspots(resumed)
|
process_hotspots(resumed)
|
||||||
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_hotspots = MC_AVERAGE(cost_hotspots, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_SUPERCONDUCTIVITY
|
currentpart = SSAIR_SUPERCONDUCTIVITY
|
||||||
|
|
||||||
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
|
if(currentpart == SSAIR_SUPERCONDUCTIVITY)
|
||||||
timer = TICK_USAGE_REAL
|
timer = TICK_USAGE_REAL
|
||||||
|
if(!resumed)
|
||||||
|
cached_cost = 0
|
||||||
process_super_conductivity(resumed)
|
process_super_conductivity(resumed)
|
||||||
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
|
||||||
if(state != SS_RUNNING)
|
if(state != SS_RUNNING)
|
||||||
return
|
return
|
||||||
resumed = 0
|
cost_superconductivity = MC_AVERAGE(cost_superconductivity, TICK_DELTA_TO_MS(cached_cost))
|
||||||
|
resumed = FALSE
|
||||||
currentpart = SSAIR_REBUILD_PIPENETS
|
currentpart = SSAIR_REBUILD_PIPENETS
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
64
code/controllers/subsystem/profiler.dm
Normal file
64
code/controllers/subsystem/profiler.dm
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#define PROFILER_FILENAME "profiler.json"
|
||||||
|
|
||||||
|
SUBSYSTEM_DEF(profiler)
|
||||||
|
name = "Profiler"
|
||||||
|
init_order = INIT_ORDER_PROFILER
|
||||||
|
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
||||||
|
wait = 3000
|
||||||
|
flags = SS_NO_TICK_CHECK
|
||||||
|
var/fetch_cost = 0
|
||||||
|
var/write_cost = 0
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/stat_entry(msg)
|
||||||
|
msg += "F:[round(fetch_cost,1)]ms"
|
||||||
|
msg += "|W:[round(write_cost,1)]ms"
|
||||||
|
..(msg)
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/Initialize()
|
||||||
|
if(CONFIG_GET(flag/auto_profile))
|
||||||
|
StartProfiling()
|
||||||
|
else
|
||||||
|
StopProfiling() //Stop the early start from world/New
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/fire()
|
||||||
|
if(CONFIG_GET(flag/auto_profile))
|
||||||
|
DumpFile()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/Shutdown()
|
||||||
|
if(CONFIG_GET(flag/auto_profile))
|
||||||
|
DumpFile()
|
||||||
|
return ..()
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/proc/StartProfiling()
|
||||||
|
#if DM_BUILD < 1506 || DM_VERSION < 513
|
||||||
|
stack_trace("Auto profiling unsupported on this byond version")
|
||||||
|
CONFIG_SET(flag/auto_profile, FALSE)
|
||||||
|
#else
|
||||||
|
world.Profile(PROFILE_START)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/proc/StopProfiling()
|
||||||
|
#if DM_BUILD >= 1506 && DM_VERSION >= 513
|
||||||
|
world.Profile(PROFILE_STOP)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/datum/controller/subsystem/profiler/proc/DumpFile()
|
||||||
|
#if DM_BUILD < 1506 || DM_VERSION < 513
|
||||||
|
stack_trace("Auto profiling unsupported on this byond version")
|
||||||
|
CONFIG_SET(flag/auto_profile, FALSE)
|
||||||
|
#else
|
||||||
|
var/timer = TICK_USAGE_REAL
|
||||||
|
var/current_profile_data = world.Profile(PROFILE_REFRESH,format="json")
|
||||||
|
fetch_cost = MC_AVERAGE(fetch_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||||
|
CHECK_TICK
|
||||||
|
if(!length(current_profile_data)) //Would be nice to have explicit proc to check this
|
||||||
|
stack_trace("Warning, profiling stopped manually before dump.")
|
||||||
|
var/json_file = file("[GLOB.log_directory]/[PROFILER_FILENAME]")
|
||||||
|
if(fexists(json_file))
|
||||||
|
fdel(json_file)
|
||||||
|
timer = TICK_USAGE_REAL
|
||||||
|
WRITE_FILE(json_file, current_profile_data)
|
||||||
|
write_cost = MC_AVERAGE(write_cost, TICK_DELTA_TO_MS(TICK_USAGE_REAL - timer))
|
||||||
|
WRITE_FILE(json_file, current_profile_data)
|
||||||
|
#endif
|
||||||
@@ -87,7 +87,7 @@
|
|||||||
owner.vomit()
|
owner.vomit()
|
||||||
fail = TRUE
|
fail = TRUE
|
||||||
if(2)
|
if(2)
|
||||||
owner.emote("cough")
|
INVOKE_ASYNC(owner, /mob.proc/emote, "cough")
|
||||||
owner.dizziness += 10
|
owner.dizziness += 10
|
||||||
fail = TRUE
|
fail = TRUE
|
||||||
if(3)
|
if(3)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
var/first_dir // This only stores the dir arg from init
|
var/first_dir // This only stores the dir arg from init
|
||||||
|
|
||||||
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_GOD, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
/datum/component/decal/Initialize(_icon, _icon_state, _dir, _cleanable=CLEAN_NEVER, _color, _layer=TURF_LAYER, _description, _alpha=255)
|
||||||
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
if(!isatom(parent) || !generate_appearance(_icon, _icon_state, _dir, _layer, _color, _alpha))
|
||||||
return COMPONENT_INCOMPATIBLE
|
return COMPONENT_INCOMPATIBLE
|
||||||
first_dir = _dir
|
first_dir = _dir
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
/datum/component/decal/RegisterWithParent()
|
/datum/component/decal/RegisterWithParent()
|
||||||
if(first_dir)
|
if(first_dir)
|
||||||
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
|
RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, .proc/rotate_react)
|
||||||
if(cleanable)
|
if(cleanable != CLEAN_NEVER)
|
||||||
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean_react)
|
||||||
if(description)
|
if(description)
|
||||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, .proc/examine)
|
||||||
|
|||||||
@@ -5,10 +5,16 @@
|
|||||||
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding))
|
var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(W.GetAllContents(), typecacheof(/obj/item/storage/backpack/holding))
|
||||||
matching -= A
|
matching -= A
|
||||||
if(istype(W, /obj/item/storage/backpack/holding) || matching.len)
|
if(istype(W, /obj/item/storage/backpack/holding) || matching.len)
|
||||||
|
INVOKE_ASYNC(src, .proc/recursive_insertion, W, user)
|
||||||
|
return
|
||||||
|
. = ..()
|
||||||
|
|
||||||
|
/datum/component/storage/concrete/bluespace/bag_of_holding/proc/recursive_insertion(obj/item/W, mob/living/user)
|
||||||
|
var/atom/A = parent
|
||||||
var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed")
|
var/safety = alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [A.name]?", "Abort", "Proceed")
|
||||||
if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user)))
|
if(safety != "Proceed" || QDELETED(A) || QDELETED(W) || QDELETED(user) || !user.canUseTopic(A, BE_CLOSE, iscarbon(user)))
|
||||||
return
|
return
|
||||||
var/turf/loccheck = get_turf(A)
|
var/turf/loccheck = get_turf_global(A)
|
||||||
if(is_reebe(loccheck.z))
|
if(is_reebe(loccheck.z))
|
||||||
user.visible_message("<span class='warning'>An unseen force knocks [user] to the ground!</span>", "<span class='big_brass'>\"I think not!\"</span>")
|
user.visible_message("<span class='warning'>An unseen force knocks [user] to the ground!</span>", "<span class='big_brass'>\"I think not!\"</span>")
|
||||||
user.Paralyze(60)
|
user.Paralyze(60)
|
||||||
@@ -43,5 +49,3 @@
|
|||||||
for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
|
for (var/obj/structure/ladder/unbreakable/binary/ladder in GLOB.ladders)
|
||||||
ladder.ActivateAlmonds()
|
ladder.ActivateAlmonds()
|
||||||
qdel(A)
|
qdel(A)
|
||||||
return
|
|
||||||
. = ..()
|
|
||||||
|
|||||||
@@ -78,6 +78,8 @@
|
|||||||
SSticker.minds -= src
|
SSticker.minds -= src
|
||||||
if(islist(antag_datums))
|
if(islist(antag_datums))
|
||||||
QDEL_LIST(antag_datums)
|
QDEL_LIST(antag_datums)
|
||||||
|
current = null
|
||||||
|
soulOwner = null
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
/datum/mind/proc/get_language_holder()
|
/datum/mind/proc/get_language_holder()
|
||||||
|
|||||||
@@ -17,4 +17,4 @@
|
|||||||
return visual_indicators[type][1]
|
return visual_indicators[type][1]
|
||||||
|
|
||||||
/datum/mutation/human/telekinesis/on_ranged_attack(atom/target)
|
/datum/mutation/human/telekinesis/on_ranged_attack(atom/target)
|
||||||
target.attack_tk(owner)
|
INVOKE_ASYNC(target, /atom.proc/attack_tk, owner)
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
|
/datum/status_effect/crusher_damage //tracks the damage dealt to this mob by kinetic crushers
|
||||||
id = "crusher_damage"
|
id = "crusher_damage"
|
||||||
duration = -1
|
duration = -1
|
||||||
|
tick_interval = -1
|
||||||
status_type = STATUS_EFFECT_UNIQUE
|
status_type = STATUS_EFFECT_UNIQUE
|
||||||
alert_type = null
|
alert_type = null
|
||||||
var/total_damage = 0
|
var/total_damage = 0
|
||||||
@@ -202,6 +203,7 @@
|
|||||||
/datum/status_effect/heldup
|
/datum/status_effect/heldup
|
||||||
id = "heldup"
|
id = "heldup"
|
||||||
duration = -1
|
duration = -1
|
||||||
|
tick_interval = -1
|
||||||
status_type = STATUS_EFFECT_MULTIPLE
|
status_type = STATUS_EFFECT_MULTIPLE
|
||||||
alert_type = /obj/screen/alert/status_effect/heldup
|
alert_type = /obj/screen/alert/status_effect/heldup
|
||||||
|
|
||||||
@@ -214,6 +216,7 @@
|
|||||||
/datum/status_effect/holdup
|
/datum/status_effect/holdup
|
||||||
id = "holdup"
|
id = "holdup"
|
||||||
duration = -1
|
duration = -1
|
||||||
|
tick_interval = -1
|
||||||
status_type = STATUS_EFFECT_UNIQUE
|
status_type = STATUS_EFFECT_UNIQUE
|
||||||
alert_type = /obj/screen/alert/status_effect/holdup
|
alert_type = /obj/screen/alert/status_effect/holdup
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
|
var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
|
||||||
A.attached_effect = src //so the alert can reference us, if it needs to
|
A.attached_effect = src //so the alert can reference us, if it needs to
|
||||||
linked_alert = A //so we can reference the alert, if we need to
|
linked_alert = A //so we can reference the alert, if we need to
|
||||||
|
if(duration > 0 || initial(tick_interval) > 0) //don't process if we don't care
|
||||||
START_PROCESSING(SSfastprocess, src)
|
START_PROCESSING(SSfastprocess, src)
|
||||||
return TRUE
|
return TRUE
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
#define AI_WIRE_NORMAL 0
|
||||||
|
#define AI_WIRE_DISABLED 1
|
||||||
|
#define AI_WIRE_HACKED 2
|
||||||
|
#define AI_WIRE_DISABLED_HACKED -1
|
||||||
|
|
||||||
/datum/wires/airlock
|
/datum/wires/airlock
|
||||||
holder_type = /obj/machinery/door/airlock
|
holder_type = /obj/machinery/door/airlock
|
||||||
proper_name = "Generic Airlock"
|
proper_name = "Generic Airlock"
|
||||||
@@ -98,16 +103,11 @@
|
|||||||
A.emergency = FALSE
|
A.emergency = FALSE
|
||||||
A.update_icon()
|
A.update_icon()
|
||||||
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
|
if(WIRE_AI) // Pulse to disable WIRE_AI control for 10 ticks (follows same rules as cutting).
|
||||||
if(A.aiControlDisabled == 0)
|
if(A.aiControlDisabled == AI_WIRE_NORMAL)
|
||||||
A.aiControlDisabled = 1
|
A.aiControlDisabled = AI_WIRE_DISABLED
|
||||||
else if(A.aiControlDisabled == -1)
|
else if(A.aiControlDisabled == AI_WIRE_DISABLED_HACKED)
|
||||||
A.aiControlDisabled = 2
|
A.aiControlDisabled = AI_WIRE_HACKED
|
||||||
sleep(10)
|
addtimer(CALLBACK(A, /obj/machinery/door/airlock.proc/reset_ai_wire), 1 SECONDS)
|
||||||
if(A)
|
|
||||||
if(A.aiControlDisabled == 1)
|
|
||||||
A.aiControlDisabled = 0
|
|
||||||
else if(A.aiControlDisabled == 2)
|
|
||||||
A.aiControlDisabled = -1
|
|
||||||
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
|
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
|
||||||
if(!A.secondsElectrified)
|
if(!A.secondsElectrified)
|
||||||
A.set_electrified(MACHINE_DEFAULT_ELECTRIFY_TIME, usr)
|
A.set_electrified(MACHINE_DEFAULT_ELECTRIFY_TIME, usr)
|
||||||
@@ -121,6 +121,12 @@
|
|||||||
A.lights = !A.lights
|
A.lights = !A.lights
|
||||||
A.update_icon()
|
A.update_icon()
|
||||||
|
|
||||||
|
/obj/machinery/door/airlock/proc/reset_ai_wire()
|
||||||
|
if(aiControlDisabled == AI_WIRE_DISABLED)
|
||||||
|
aiControlDisabled = AI_WIRE_NORMAL
|
||||||
|
else if(aiControlDisabled == AI_WIRE_HACKED)
|
||||||
|
aiControlDisabled = AI_WIRE_DISABLED_HACKED
|
||||||
|
|
||||||
/datum/wires/airlock/on_cut(wire, mend)
|
/datum/wires/airlock/on_cut(wire, mend)
|
||||||
var/obj/machinery/door/airlock/A = holder
|
var/obj/machinery/door/airlock/A = holder
|
||||||
switch(wire)
|
switch(wire)
|
||||||
@@ -147,15 +153,15 @@
|
|||||||
A.bolt()
|
A.bolt()
|
||||||
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
|
if(WIRE_AI) // Cut to disable WIRE_AI control, mend to re-enable.
|
||||||
if(mend)
|
if(mend)
|
||||||
if(A.aiControlDisabled == 1) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
|
if(A.aiControlDisabled == AI_WIRE_DISABLED) // 0 = normal, 1 = locked out, 2 = overridden by WIRE_AI, -1 = previously overridden by WIRE_AI
|
||||||
A.aiControlDisabled = 0
|
A.aiControlDisabled = AI_WIRE_NORMAL
|
||||||
else if(A.aiControlDisabled == 2)
|
else if(A.aiControlDisabled == AI_WIRE_HACKED)
|
||||||
A.aiControlDisabled = -1
|
A.aiControlDisabled = AI_WIRE_DISABLED_HACKED
|
||||||
else
|
else
|
||||||
if(A.aiControlDisabled == 0)
|
if(A.aiControlDisabled == AI_WIRE_NORMAL)
|
||||||
A.aiControlDisabled = 1
|
A.aiControlDisabled = AI_WIRE_DISABLED
|
||||||
else if(A.aiControlDisabled == -1)
|
else if(A.aiControlDisabled == AI_WIRE_DISABLED_HACKED)
|
||||||
A.aiControlDisabled = 2
|
A.aiControlDisabled = AI_WIRE_HACKED
|
||||||
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
|
if(WIRE_SHOCK) // Cut to shock the door, mend to unshock.
|
||||||
if(mend)
|
if(mend)
|
||||||
if(A.secondsElectrified)
|
if(A.secondsElectrified)
|
||||||
|
|||||||
@@ -152,8 +152,7 @@
|
|||||||
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
|
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
|
||||||
slipper.Slip(src, hit_atom)
|
slipper.Slip(src, hit_atom)
|
||||||
if(thrownby && !caught)
|
if(thrownby && !caught)
|
||||||
sleep(1)
|
addtimer(CALLBACK(src, /atom/movable.proc/throw_at, thrownby, throw_range+2, throw_speed, null, TRUE), 1)
|
||||||
throw_at(thrownby, throw_range+2, throw_speed, null, TRUE)
|
|
||||||
else
|
else
|
||||||
return ..()
|
return ..()
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
|
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
|
||||||
|
|
||||||
var/security_level = 0 //How much are wires secured
|
var/security_level = 0 //How much are wires secured
|
||||||
var/aiControlDisabled = 0 //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
|
var/aiControlDisabled = AI_WIRE_NORMAL //If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in.
|
||||||
var/hackProof = FALSE // if true, this door can't be hacked by the AI
|
var/hackProof = FALSE // if true, this door can't be hacked by the AI
|
||||||
var/secondsMainPowerLost = 0 //The number of seconds until power is restored.
|
var/secondsMainPowerLost = 0 //The number of seconds until power is restored.
|
||||||
var/secondsBackupPowerLost = 0 //The number of seconds until power is restored.
|
var/secondsBackupPowerLost = 0 //The number of seconds until power is restored.
|
||||||
@@ -475,10 +475,10 @@
|
|||||||
return FALSE
|
return FALSE
|
||||||
|
|
||||||
/obj/machinery/door/airlock/proc/canAIControl(mob/user)
|
/obj/machinery/door/airlock/proc/canAIControl(mob/user)
|
||||||
return ((aiControlDisabled != 1) && !isAllPowerCut())
|
return ((aiControlDisabled != AI_WIRE_DISABLED) && !isAllPowerCut())
|
||||||
|
|
||||||
/obj/machinery/door/airlock/proc/canAIHack()
|
/obj/machinery/door/airlock/proc/canAIHack()
|
||||||
return ((aiControlDisabled==1) && (!hackProof) && (!isAllPowerCut()));
|
return ((aiControlDisabled==AI_WIRE_DISABLED) && (!hackProof) && (!isAllPowerCut()));
|
||||||
|
|
||||||
/obj/machinery/door/airlock/hasPower()
|
/obj/machinery/door/airlock/hasPower()
|
||||||
return ((!secondsMainPowerLost || !secondsBackupPowerLost) && !(stat & NOPOWER))
|
return ((!secondsMainPowerLost || !secondsBackupPowerLost) && !(stat & NOPOWER))
|
||||||
@@ -835,7 +835,7 @@
|
|||||||
to_chat(user, "Transfer complete. Forcing airlock to execute program.")
|
to_chat(user, "Transfer complete. Forcing airlock to execute program.")
|
||||||
sleep(50)
|
sleep(50)
|
||||||
//disable blocked control
|
//disable blocked control
|
||||||
aiControlDisabled = 2
|
aiControlDisabled = AI_WIRE_HACKED
|
||||||
to_chat(user, "Receiving control information from airlock.")
|
to_chat(user, "Receiving control information from airlock.")
|
||||||
sleep(10)
|
sleep(10)
|
||||||
//bring up airlock dialog
|
//bring up airlock dialog
|
||||||
|
|||||||
@@ -437,7 +437,7 @@
|
|||||||
damage_deflection = 30
|
damage_deflection = 30
|
||||||
explosion_block = 3
|
explosion_block = 3
|
||||||
hackProof = TRUE
|
hackProof = TRUE
|
||||||
aiControlDisabled = 1
|
aiControlDisabled = AI_WIRE_DISABLED
|
||||||
normal_integrity = 700
|
normal_integrity = 700
|
||||||
security_level = 1
|
security_level = 1
|
||||||
|
|
||||||
@@ -452,7 +452,7 @@
|
|||||||
overlays_file = 'icons/obj/doors/airlocks/cult/runed/overlays.dmi'
|
overlays_file = 'icons/obj/doors/airlocks/cult/runed/overlays.dmi'
|
||||||
assemblytype = /obj/structure/door_assembly/door_assembly_cult
|
assemblytype = /obj/structure/door_assembly/door_assembly_cult
|
||||||
hackProof = TRUE
|
hackProof = TRUE
|
||||||
aiControlDisabled = 1
|
aiControlDisabled = AI_WIRE_DISABLED
|
||||||
req_access = list(ACCESS_BLOODCULT)
|
req_access = list(ACCESS_BLOODCULT)
|
||||||
damage_deflection = 10
|
damage_deflection = 10
|
||||||
var/openingoverlaytype = /obj/effect/temp_visual/cult/door
|
var/openingoverlaytype = /obj/effect/temp_visual/cult/door
|
||||||
@@ -557,7 +557,7 @@
|
|||||||
overlays_file = 'icons/obj/doors/airlocks/clockwork/overlays.dmi'
|
overlays_file = 'icons/obj/doors/airlocks/clockwork/overlays.dmi'
|
||||||
anim_parts = "left=-13,0;right=13,0"
|
anim_parts = "left=-13,0;right=13,0"
|
||||||
hackProof = TRUE
|
hackProof = TRUE
|
||||||
aiControlDisabled = 1
|
aiControlDisabled = AI_WIRE_DISABLED
|
||||||
req_access = list(ACCESS_CLOCKCULT)
|
req_access = list(ACCESS_CLOCKCULT)
|
||||||
use_power = FALSE
|
use_power = FALSE
|
||||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||||
|
|||||||
@@ -78,7 +78,9 @@
|
|||||||
controller.cycleClose(door)
|
controller.cycleClose(door)
|
||||||
else
|
else
|
||||||
controller.onlyClose(door)
|
controller.onlyClose(door)
|
||||||
sleep(20)
|
addtimer(CALLBACK(src, .proc/not_busy), 2 SECONDS)
|
||||||
|
|
||||||
|
/obj/machinery/doorButtons/access_button/proc/not_busy()
|
||||||
busy = FALSE
|
busy = FALSE
|
||||||
update_icon()
|
update_icon()
|
||||||
|
|
||||||
|
|||||||
@@ -25,10 +25,11 @@
|
|||||||
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
|
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
|
||||||
mergeable_decal = FALSE
|
mergeable_decal = FALSE
|
||||||
|
|
||||||
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
|
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions, mapload=FALSE)
|
||||||
set waitfor = 0
|
set waitfor = 0
|
||||||
var/direction = pick(directions)
|
var/direction = pick(directions)
|
||||||
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
|
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
|
||||||
|
if (!mapload)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
if(i > 0)
|
if(i > 0)
|
||||||
new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
|
new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
|
||||||
|
|||||||
@@ -77,12 +77,13 @@
|
|||||||
playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, TRUE)
|
playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, TRUE)
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|
||||||
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
|
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions, mapload=FALSE)
|
||||||
set waitfor = FALSE
|
set waitfor = FALSE
|
||||||
var/list/diseases = list()
|
var/list/diseases = list()
|
||||||
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
|
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
|
||||||
var/direction = pick(directions)
|
var/direction = pick(directions)
|
||||||
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
|
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
|
||||||
|
if (!mapload)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
if(i > 0)
|
if(i > 0)
|
||||||
new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
|
new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
|
||||||
|
|||||||
@@ -11,15 +11,16 @@
|
|||||||
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
bloodiness = BLOOD_AMOUNT_PER_DECAL
|
||||||
mergeable_decal = FALSE
|
mergeable_decal = FALSE
|
||||||
|
|
||||||
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
|
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions, mapload=FALSE)
|
||||||
set waitfor = 0
|
set waitfor = 0
|
||||||
var/direction = pick(directions)
|
var/direction = pick(directions)
|
||||||
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
|
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
|
||||||
|
if (!mapload)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
if (prob(40))
|
if (prob(40))
|
||||||
new /obj/effect/decal/cleanable/oil/streak(src.loc)
|
new /obj/effect/decal/cleanable/oil/streak(src.loc)
|
||||||
else if (prob(10))
|
else if (prob(10) && !mapload)
|
||||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||||
s.set_up(3, 1, src)
|
s.set_up(3, 1, src)
|
||||||
s.start()
|
s.start()
|
||||||
|
|||||||
@@ -45,4 +45,4 @@
|
|||||||
var/turf/T = loc
|
var/turf/T = loc
|
||||||
if(!istype(T)) //you know this will happen somehow
|
if(!istype(T)) //you know this will happen somehow
|
||||||
CRASH("Turf decal initialized in an object/nullspace")
|
CRASH("Turf decal initialized in an object/nullspace")
|
||||||
T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_GOD, color, null, null, alpha)
|
T.AddComponent(/datum/component/decal, icon, icon_state, dir, CLEAN_NEVER, color, null, null, alpha)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
var/list/directions = gibdirections[i]
|
var/list/directions = gibdirections[i]
|
||||||
if(isturf(loc))
|
if(isturf(loc))
|
||||||
if(directions.len)
|
if(directions.len)
|
||||||
gib.streak(directions)
|
gib.streak(directions, mapload)
|
||||||
|
|
||||||
return INITIALIZE_HINT_QDEL
|
return INITIALIZE_HINT_QDEL
|
||||||
|
|
||||||
|
|||||||
@@ -133,5 +133,4 @@
|
|||||||
if(trigger_item && istype(AM, specific_item) && !claimed)
|
if(trigger_item && istype(AM, specific_item) && !claimed)
|
||||||
claimed = TRUE
|
claimed = TRUE
|
||||||
flick("laserbox_burn", AM)
|
flick("laserbox_burn", AM)
|
||||||
sleep(15)
|
QDEL_IN(AM, 15)
|
||||||
qdel(AM)
|
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ GLOBAL_VAR(restart_counter)
|
|||||||
*/
|
*/
|
||||||
/world/New()
|
/world/New()
|
||||||
enable_debugger() //This does nothing if you aren't trying to debug
|
enable_debugger() //This does nothing if you aren't trying to debug
|
||||||
|
|
||||||
|
//Early profile for auto-profiler - will be stopped on profiler init if necessary.
|
||||||
|
#if DM_VERSION >= 513 && DM_BUILD >= 1506
|
||||||
|
world.Profile(PROFILE_START)
|
||||||
|
#endif
|
||||||
|
|
||||||
log_world("World loaded at [time_stamp()]!")
|
log_world("World loaded at [time_stamp()]!")
|
||||||
|
|
||||||
SetupExternalRSC()
|
SetupExternalRSC()
|
||||||
|
|||||||
@@ -164,13 +164,9 @@
|
|||||||
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
|
if((temperature < FIRE_MINIMUM_TEMPERATURE_TO_EXIST) || (volume <= 1))
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
|
|
||||||
qdel(src)
|
|
||||||
return
|
|
||||||
|
|
||||||
//Not enough to burn
|
//Not enough / nothing to burn
|
||||||
// god damn it previous coder you made the INSUFFICIENT macro for a fucking reason why didn't you use it here smh
|
if(!location.air || (INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
|
||||||
if((INSUFFICIENT(/datum/gas/plasma) && INSUFFICIENT(/datum/gas/tritium)) || INSUFFICIENT(/datum/gas/oxygen))
|
|
||||||
qdel(src)
|
qdel(src)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,8 @@
|
|||||||
|
|
||||||
/obj/item/twohanded/required/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
|
/obj/item/twohanded/required/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
|
||||||
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||||
|
if(!C)
|
||||||
|
C = target.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||||
var/target_health = target.health
|
var/target_health = target.health
|
||||||
..()
|
..()
|
||||||
for(var/t in trophies)
|
for(var/t in trophies)
|
||||||
@@ -97,6 +99,8 @@
|
|||||||
if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK))
|
if(!CM || CM.hammer_synced != src || !L.remove_status_effect(STATUS_EFFECT_CRUSHERMARK))
|
||||||
return
|
return
|
||||||
var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
var/datum/status_effect/crusher_damage/C = L.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||||
|
if(!C)
|
||||||
|
C = L.apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
||||||
var/target_health = L.health
|
var/target_health = L.health
|
||||||
for(var/t in trophies)
|
for(var/t in trophies)
|
||||||
var/obj/item/crusher_trophy/T = t
|
var/obj/item/crusher_trophy/T = t
|
||||||
|
|||||||
@@ -402,7 +402,7 @@
|
|||||||
|
|
||||||
switch(rand(1,100)+modifier) //91-100=Nothing special happens
|
switch(rand(1,100)+modifier) //91-100=Nothing special happens
|
||||||
if(-INFINITY to 0) //attack yourself
|
if(-INFINITY to 0) //attack yourself
|
||||||
I.attack(src,src)
|
INVOKE_ASYNC(I, /obj/item.proc/attack, src, src)
|
||||||
if(1 to 30) //throw it at yourself
|
if(1 to 30) //throw it at yourself
|
||||||
I.throw_impact(src)
|
I.throw_impact(src)
|
||||||
if(31 to 60) //Throw object in facing direction
|
if(31 to 60) //Throw object in facing direction
|
||||||
|
|||||||
@@ -245,7 +245,7 @@
|
|||||||
if(!illusion && (shock_damage * siemens_coeff >= 1) && prob(25))
|
if(!illusion && (shock_damage * siemens_coeff >= 1) && prob(25))
|
||||||
set_heartattack(FALSE)
|
set_heartattack(FALSE)
|
||||||
revive()
|
revive()
|
||||||
emote("gasp")
|
INVOKE_ASYNC(src, .proc/emote, "gasp")
|
||||||
Jitter(100)
|
Jitter(100)
|
||||||
SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK)
|
SEND_SIGNAL(src, COMSIG_LIVING_MINOR_SHOCK)
|
||||||
adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 199) //yogs end
|
adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 199) //yogs end
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
losebreath = 0
|
losebreath = 0
|
||||||
|
|
||||||
if(!gibbed)
|
if(!gibbed)
|
||||||
emote("deathgasp")
|
INVOKE_ASYNC(src, .proc/emote, "deathgasp")
|
||||||
|
|
||||||
. = ..()
|
. = ..()
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@
|
|||||||
if(losebreath >= 1) //You've missed a breath, take oxy damage
|
if(losebreath >= 1) //You've missed a breath, take oxy damage
|
||||||
losebreath--
|
losebreath--
|
||||||
if(prob(10))
|
if(prob(10))
|
||||||
emote("gasp")
|
INVOKE_ASYNC(src, .proc/emote, "gasp")
|
||||||
if(istype(loc, /obj/))
|
if(istype(loc, /obj/))
|
||||||
var/obj/loc_as_obj = loc
|
var/obj/loc_as_obj = loc
|
||||||
loc_as_obj.handle_internal_lifeform(src,0)
|
loc_as_obj.handle_internal_lifeform(src,0)
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
//OXYGEN
|
//OXYGEN
|
||||||
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
|
if(O2_partialpressure < safe_oxy_min) //Not enough oxygen
|
||||||
if(prob(20))
|
if(prob(20))
|
||||||
emote("gasp")
|
INVOKE_ASYNC(src, .proc/emote, "gasp")
|
||||||
if(O2_partialpressure > 0)
|
if(O2_partialpressure > 0)
|
||||||
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
var/ratio = 1 - O2_partialpressure/safe_oxy_min
|
||||||
adjustOxyLoss(min(5*ratio, 3))
|
adjustOxyLoss(min(5*ratio, 3))
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
if(prob(1))
|
if(prob(1))
|
||||||
to_chat(src, "<span class='danger'>You mutate!</span>")
|
to_chat(src, "<span class='danger'>You mutate!</span>")
|
||||||
easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||||
emote("gasp")
|
INVOKE_ASYNC(src, .proc/emote, "gasp")
|
||||||
domutcheck()
|
domutcheck()
|
||||||
|
|
||||||
if(radiation > RAD_MOB_MUTATE * 2 && prob(50))
|
if(radiation > RAD_MOB_MUTATE * 2 && prob(50))
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
/mob/living/simple_animal/bot/secbot/grievous/Initialize()
|
/mob/living/simple_animal/bot/secbot/grievous/Initialize()
|
||||||
. = ..()
|
. = ..()
|
||||||
weapon = new baton_type(src)
|
weapon = new baton_type(src)
|
||||||
weapon.attack_self(src)
|
INVOKE_ASYNC(weapon, /obj/item.proc/attack_self, src)
|
||||||
|
|
||||||
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
|
/mob/living/simple_animal/bot/secbot/grievous/Destroy()
|
||||||
QDEL_NULL(weapon)
|
QDEL_NULL(weapon)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
var/robot_arm = /obj/item/bodypart/r_arm/robot
|
var/robot_arm = /obj/item/bodypart/r_arm/robot
|
||||||
|
|
||||||
var/commissioned = FALSE // Will other (noncommissioned) bots salute this bot?
|
var/commissioned = FALSE // Will other (noncommissioned) bots salute this bot?
|
||||||
var/can_salute = TRUE
|
COOLDOWN_DECLARE(next_salute_check)
|
||||||
var/salute_delay = 60 SECONDS
|
var/salute_delay = 60 SECONDS
|
||||||
|
|
||||||
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views
|
hud_possible = list(DIAG_STAT_HUD, DIAG_BOT_HUD, DIAG_HUD, DIAG_PATH_HUD = HUD_LIST_LIST) //Diagnostic HUD views
|
||||||
@@ -257,12 +257,11 @@
|
|||||||
if(!on || client)
|
if(!on || client)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(!commissioned && can_salute)
|
if(commissioned && COOLDOWN_FINISHED(src, next_salute_check))
|
||||||
for(var/mob/living/simple_animal/bot/B in get_hearers_in_view(5, get_turf(src)))
|
COOLDOWN_START(src, next_salute_check, salute_delay)
|
||||||
if(B.commissioned)
|
for(var/mob/living/simple_animal/bot/B in view(5, src))
|
||||||
visible_message("<b>[src]</b> performs an elaborate salute for [B]!")
|
if(!B.commissioned && B.on)
|
||||||
can_salute = FALSE
|
visible_message("<b>[B]</b> performs an elaborate salute for [src]!")
|
||||||
addtimer(VARSET_CALLBACK(src, can_salute, TRUE), salute_delay)
|
|
||||||
break
|
break
|
||||||
|
|
||||||
switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
|
switch(mode) //High-priority overrides are processed first. Bots can do nothing else while under direct command.
|
||||||
|
|||||||
@@ -305,7 +305,7 @@
|
|||||||
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
/mob/living/simple_animal/pet/dog/corgi/proc/place_on_head(obj/item/item_to_add, mob/user)
|
||||||
|
|
||||||
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
if(istype(item_to_add, /obj/item/grenade/plastic)) // last thing he ever wears, I guess
|
||||||
item_to_add.afterattack(src,user,1)
|
INVOKE_ASYNC(item_to_add, /obj/item.proc/afterattack, src, user, 1)
|
||||||
return
|
return
|
||||||
|
|
||||||
if(inventory_head)
|
if(inventory_head)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@
|
|||||||
if(spawn_mecha_type)
|
if(spawn_mecha_type)
|
||||||
var/obj/mecha/M = new spawn_mecha_type (get_turf(src))
|
var/obj/mecha/M = new spawn_mecha_type (get_turf(src))
|
||||||
if(istype(M))
|
if(istype(M))
|
||||||
enter_mecha(M)
|
INVOKE_ASYNC(src, .proc/enter_mecha, M)
|
||||||
|
|
||||||
|
|
||||||
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M)
|
/mob/living/simple_animal/hostile/syndicate/mecha_pilot/proc/enter_mecha(obj/mecha/M)
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
. = ..()
|
. = ..()
|
||||||
if(internal_type && true_spawn)
|
if(internal_type && true_spawn)
|
||||||
internal = new internal_type(src)
|
internal = new internal_type(src)
|
||||||
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
|
||||||
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
|
ADD_TRAIT(src, TRAIT_NO_TELEPORT, MEGAFAUNA_TRAIT)
|
||||||
for(var/action_type in attack_action_types)
|
for(var/action_type in attack_action_types)
|
||||||
var/datum/action/innate/megafauna_attack/attack_action = new action_type()
|
var/datum/action/innate/megafauna_attack/attack_action = new action_type()
|
||||||
|
|||||||
@@ -22,10 +22,6 @@
|
|||||||
var/icon_aggro = null
|
var/icon_aggro = null
|
||||||
var/crusher_drop_mod = 25
|
var/crusher_drop_mod = 25
|
||||||
|
|
||||||
/mob/living/simple_animal/hostile/asteroid/Initialize(mapload)
|
|
||||||
. = ..()
|
|
||||||
apply_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
|
|
||||||
|
|
||||||
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
/mob/living/simple_animal/hostile/asteroid/Aggro()
|
||||||
..()
|
..()
|
||||||
if(vision_range == aggro_vision_range && icon_aggro)
|
if(vision_range == aggro_vision_range && icon_aggro)
|
||||||
|
|||||||
@@ -407,7 +407,7 @@
|
|||||||
update()
|
update()
|
||||||
|
|
||||||
/obj/machinery/light/proc/broken_sparks(start_only=FALSE)
|
/obj/machinery/light/proc/broken_sparks(start_only=FALSE)
|
||||||
if(status == LIGHT_BROKEN && has_power())
|
if(status == LIGHT_BROKEN && has_power() && Master.current_runlevel)
|
||||||
if(!start_only)
|
if(!start_only)
|
||||||
do_sparks(3, TRUE, src)
|
do_sparks(3, TRUE, src)
|
||||||
var/delay = rand(BROKEN_SPARKS_MIN, BROKEN_SPARKS_MAX)
|
var/delay = rand(BROKEN_SPARKS_MIN, BROKEN_SPARKS_MAX)
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
var/modifier = 0
|
var/modifier = 0
|
||||||
|
|
||||||
/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume)
|
/datum/chemical_reaction/reagent_explosion/on_reaction(datum/reagents/holder, created_volume)
|
||||||
|
explode(holder, created_volume)
|
||||||
|
|
||||||
|
/datum/chemical_reaction/reagent_explosion/proc/explode(datum/reagents/holder, created_volume)
|
||||||
var/turf/T = get_turf(holder.my_atom)
|
var/turf/T = get_turf(holder.my_atom)
|
||||||
var/inside_msg
|
var/inside_msg
|
||||||
if(ismob(holder.my_atom))
|
if(ismob(holder.my_atom))
|
||||||
@@ -69,15 +72,16 @@
|
|||||||
R.stun(20)
|
R.stun(20)
|
||||||
R.reveal(100)
|
R.reveal(100)
|
||||||
R.adjustHealth(50)
|
R.adjustHealth(50)
|
||||||
sleep(20)
|
addtimer(CALLBACK(src, .proc/divine_explosion, round(created_volume/48,1),get_turf(holder.my_atom)), 2 SECONDS)
|
||||||
for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/20,1),get_turf(holder.my_atom))) //roughly 5 tiles with 100/100 potwat
|
..()
|
||||||
|
|
||||||
|
/datum/chemical_reaction/reagent_explosion/potassium_explosion/holyboom/proc/divine_explosion(size, turf/T)
|
||||||
|
for(var/mob/living/carbon/C in get_hearers_in_view(size,T))
|
||||||
if(iscultist(C))
|
if(iscultist(C))
|
||||||
to_chat(C, "<span class='userdanger'>The divine explosion sears you!</span>")
|
to_chat(C, "<span class='userdanger'>The divine explosion sears you!</span>")
|
||||||
C.Paralyze(40)
|
C.Paralyze(40)
|
||||||
C.adjust_fire_stacks(5)
|
C.adjust_fire_stacks(5)
|
||||||
C.IgniteMob()
|
C.IgniteMob()
|
||||||
..()
|
|
||||||
|
|
||||||
|
|
||||||
/datum/chemical_reaction/blackpowder
|
/datum/chemical_reaction/blackpowder
|
||||||
name = "Black Powder"
|
name = "Black Powder"
|
||||||
@@ -95,8 +99,7 @@
|
|||||||
mix_message = "<span class='boldannounce'>Sparks start flying around the black powder!</span>"
|
mix_message = "<span class='boldannounce'>Sparks start flying around the black powder!</span>"
|
||||||
|
|
||||||
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
|
/datum/chemical_reaction/reagent_explosion/blackpowder_explosion/on_reaction(datum/reagents/holder, created_volume)
|
||||||
sleep(rand(50,100))
|
addtimer(CALLBACK(src, .proc/explode, holder, created_volume), rand(5,10) SECONDS)
|
||||||
..()
|
|
||||||
|
|
||||||
/datum/chemical_reaction/thermite
|
/datum/chemical_reaction/thermite
|
||||||
name = "Thermite"
|
name = "Thermite"
|
||||||
@@ -431,19 +434,22 @@
|
|||||||
var/T1 = created_volume * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison.
|
var/T1 = created_volume * 20 //100 units : Zap 3 times, with powers 2000/5000/12000. Tesla revolvers have a power of 10000 for comparison.
|
||||||
var/T2 = created_volume * 50
|
var/T2 = created_volume * 50
|
||||||
var/T3 = created_volume * 120
|
var/T3 = created_volume * 120
|
||||||
sleep(5)
|
var/added_delay = 0.5 SECONDS
|
||||||
if(created_volume >= 75)
|
if(created_volume >= 75)
|
||||||
tesla_zap(holder.my_atom, 7, T1, tesla_flags)
|
addtimer(CALLBACK(src, .proc/zappy_zappy, holder, T1), added_delay)
|
||||||
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
|
added_delay += 1.5 SECONDS
|
||||||
sleep(15)
|
|
||||||
if(created_volume >= 40)
|
if(created_volume >= 40)
|
||||||
tesla_zap(holder.my_atom, 7, T2, tesla_flags)
|
addtimer(CALLBACK(src, .proc/zappy_zappy, holder, T2), added_delay)
|
||||||
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
|
added_delay += 1.5 SECONDS
|
||||||
sleep(15)
|
|
||||||
if(created_volume >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast.
|
if(created_volume >= 10) //10 units minimum for lightning, 40 units for secondary blast, 75 units for tertiary blast.
|
||||||
tesla_zap(holder.my_atom, 7, T3, tesla_flags)
|
addtimer(CALLBACK(src, .proc/zappy_zappy, holder, T3), added_delay)
|
||||||
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, 1)
|
addtimer(CALLBACK(src, .proc/explode, holder, created_volume), added_delay)
|
||||||
..()
|
|
||||||
|
/datum/chemical_reaction/reagent_explosion/teslium_lightning/proc/zappy_zappy(datum/reagents/holder, power)
|
||||||
|
if(QDELETED(holder.my_atom))
|
||||||
|
return
|
||||||
|
tesla_zap(holder.my_atom, 7, power, tesla_flags)
|
||||||
|
playsound(holder.my_atom, 'sound/machines/defib_zap.ogg', 50, TRUE)
|
||||||
|
|
||||||
/datum/chemical_reaction/reagent_explosion/teslium_lightning/heat
|
/datum/chemical_reaction/reagent_explosion/teslium_lightning/heat
|
||||||
id = "teslium_lightning2"
|
id = "teslium_lightning2"
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
var/deletes_extract = TRUE
|
var/deletes_extract = TRUE
|
||||||
|
|
||||||
/datum/chemical_reaction/slime/on_reaction(datum/reagents/holder)
|
/datum/chemical_reaction/slime/on_reaction(datum/reagents/holder)
|
||||||
|
use_slime_core(holder)
|
||||||
|
|
||||||
|
/datum/chemical_reaction/slime/proc/use_slime_core(datum/reagents/holder)
|
||||||
SSblackbox.record_feedback("tally", "slime_cores_used", 1, "type")
|
SSblackbox.record_feedback("tally", "slime_cores_used", 1, "type")
|
||||||
if(deletes_extract)
|
if(deletes_extract)
|
||||||
delete_extract(holder)
|
delete_extract(holder)
|
||||||
@@ -582,7 +585,9 @@
|
|||||||
required_other = TRUE
|
required_other = TRUE
|
||||||
|
|
||||||
/datum/chemical_reaction/slime/slimestop/on_reaction(datum/reagents/holder)
|
/datum/chemical_reaction/slime/slimestop/on_reaction(datum/reagents/holder)
|
||||||
sleep(50)
|
addtimer(CALLBACK(src, .proc/slime_stop, holder), 5 SECONDS)
|
||||||
|
|
||||||
|
/datum/chemical_reaction/slime/slimestop/proc/slime_stop(datum/reagents/holder)
|
||||||
var/obj/item/slime_extract/sepia/extract = holder.my_atom
|
var/obj/item/slime_extract/sepia/extract = holder.my_atom
|
||||||
var/turf/T = get_turf(holder.my_atom)
|
var/turf/T = get_turf(holder.my_atom)
|
||||||
new /obj/effect/timestop(T, null, null, null)
|
new /obj/effect/timestop(T, null, null, null)
|
||||||
@@ -592,7 +597,7 @@
|
|||||||
if(lastheld && !lastheld.equip_to_slot_if_possible(extract, SLOT_HANDS, disable_warning = TRUE))
|
if(lastheld && !lastheld.equip_to_slot_if_possible(extract, SLOT_HANDS, disable_warning = TRUE))
|
||||||
extract.forceMove(get_turf(lastheld))
|
extract.forceMove(get_turf(lastheld))
|
||||||
|
|
||||||
..()
|
use_slime_core(holder)
|
||||||
|
|
||||||
/datum/chemical_reaction/slime/slimecamera
|
/datum/chemical_reaction/slime/slimecamera
|
||||||
name = "Slime Camera"
|
name = "Slime Camera"
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
/datum/status_effect/slimerecall
|
/datum/status_effect/slimerecall
|
||||||
id = "slime_recall"
|
id = "slime_recall"
|
||||||
duration = -1 //Will be removed by the extract.
|
duration = -1 //Will be removed by the extract.
|
||||||
|
tick_interval = -1
|
||||||
alert_type = null
|
alert_type = null
|
||||||
var/interrupted = FALSE
|
var/interrupted = FALSE
|
||||||
var/mob/target
|
var/mob/target
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
|
var/obj/item/bodypart/affecting = C.get_bodypart(BODY_ZONE_CHEST)
|
||||||
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage
|
affecting.receive_damage(clamp(brute_dam/2 * affecting.body_damage_coeff, 15, 50), clamp(burn_dam/2 * affecting.body_damage_coeff, 0, 50)) //Damage the chest based on limb's existing damage
|
||||||
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
|
C.visible_message("<span class='danger'><B>[C]'s [src.name] has been violently dismembered!</B></span>")
|
||||||
C.emote("scream")
|
INVOKE_ASYNC(C, /mob.proc/emote, "scream")
|
||||||
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
|
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "dismembered", /datum/mood_event/dismembered)
|
||||||
drop_limb()
|
drop_limb()
|
||||||
|
|
||||||
|
|||||||
@@ -434,3 +434,5 @@ DEFAULT_VIEW_SQUARE 15x15
|
|||||||
## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL.
|
## Uncomment to enable global ban DB using the provided URL. The API should expect to receive a ckey at the end of the URL.
|
||||||
## More API details can be found here: https://centcom.melonmesa.com
|
## More API details can be found here: https://centcom.melonmesa.com
|
||||||
CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search
|
CENTCOM_BAN_DB https://centcom.melonmesa.com/ban/search
|
||||||
|
|
||||||
|
AUTO_PROFILE
|
||||||
@@ -289,6 +289,7 @@
|
|||||||
#include "code\controllers\subsystem\pathfinder.dm"
|
#include "code\controllers\subsystem\pathfinder.dm"
|
||||||
#include "code\controllers\subsystem\persistence.dm"
|
#include "code\controllers\subsystem\persistence.dm"
|
||||||
#include "code\controllers\subsystem\ping.dm"
|
#include "code\controllers\subsystem\ping.dm"
|
||||||
|
#include "code\controllers\subsystem\profiler.dm"
|
||||||
#include "code\controllers\subsystem\radiation.dm"
|
#include "code\controllers\subsystem\radiation.dm"
|
||||||
#include "code\controllers\subsystem\radio.dm"
|
#include "code\controllers\subsystem\radio.dm"
|
||||||
#include "code\controllers\subsystem\research.dm"
|
#include "code\controllers\subsystem\research.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user