@@ -0,0 +1,328 @@
|
||||
|
||||
//Movable and easily code-modified fields! Allows for custom AOE effects that affect movement and anything inside of them, and can do custom turf effects!
|
||||
//Supports automatic recalculation/reset on movement.
|
||||
//If there's any way to make this less CPU intensive than I've managed, gimme a call or do it yourself! - kevinz000
|
||||
|
||||
//Field shapes
|
||||
#define FIELD_NO_SHAPE 0 //Does not update turfs automatically
|
||||
#define FIELD_SHAPE_RADIUS_SQUARE 1 //Uses current_range and square_depth_up/down
|
||||
#define FIELD_SHAPE_CUSTOM_SQUARE 2 //Uses square_height and square_width and square_depth_up/down
|
||||
|
||||
//Proc to make fields. make_field(field_type, field_params_in_associative_list)
|
||||
/proc/make_field(field_type, list/field_params, override_checks = FALSE, start_field = TRUE)
|
||||
var/datum/proximity_monitor/advanced/F = new field_type()
|
||||
if(!F.assume_params(field_params) && !override_checks)
|
||||
QDEL_NULL(F)
|
||||
if(!F.check_variables() && !override_checks)
|
||||
QDEL_NULL(F)
|
||||
if(start_field && (F || override_checks))
|
||||
F.Initialize()
|
||||
return F
|
||||
|
||||
/datum/proximity_monitor/advanced
|
||||
var/name = "\improper Energy Field"
|
||||
//Field setup specifications
|
||||
var/field_shape = FIELD_NO_SHAPE
|
||||
var/square_height = 0
|
||||
var/square_width = 0
|
||||
var/square_depth_up = 0
|
||||
var/square_depth_down = 0
|
||||
//Processing
|
||||
var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary
|
||||
var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup.
|
||||
var/requires_processing = FALSE
|
||||
var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU.
|
||||
var/setup_field_turfs = FALSE
|
||||
var/use_host_turf = FALSE //For fields from items carried on mobs to check turf instead of loc...
|
||||
|
||||
var/list/turf/field_turfs = list()
|
||||
var/list/turf/edge_turfs = list()
|
||||
var/list/turf/field_turfs_new = list()
|
||||
var/list/turf/edge_turfs_new = list()
|
||||
|
||||
/datum/proximity_monitor/advanced/Destroy()
|
||||
full_cleanup()
|
||||
STOP_PROCESSING(SSfields, src)
|
||||
return ..()
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/assume_params(list/field_params)
|
||||
var/pass_check = TRUE
|
||||
for(var/param in field_params)
|
||||
if(vars[param] || isnull(vars[param]) || (param in vars))
|
||||
vars[param] = field_params[param]
|
||||
else
|
||||
pass_check = FALSE
|
||||
return pass_check
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/check_variables()
|
||||
var/pass = TRUE
|
||||
if(field_shape == FIELD_NO_SHAPE) //If you're going to make a manually updated field you shouldn't be using automatic checks so don't.
|
||||
pass = FALSE
|
||||
if(current_range < 0 || square_height < 0 || square_width < 0 || square_depth_up < 0 || square_depth_down < 0)
|
||||
pass = FALSE
|
||||
if(!istype(host))
|
||||
pass = FALSE
|
||||
return pass
|
||||
|
||||
/datum/proximity_monitor/advanced/process()
|
||||
if(process_inner_turfs)
|
||||
for(var/turf/T in field_turfs)
|
||||
process_inner_turf(T)
|
||||
CHECK_TICK //Really crappy lagchecks, needs improvement once someone starts using processed fields.
|
||||
if(process_edge_turfs)
|
||||
for(var/turf/T in edge_turfs)
|
||||
process_edge_turf(T)
|
||||
CHECK_TICK //Same here.
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T)
|
||||
|
||||
/datum/proximity_monitor/advanced/New()
|
||||
if(requires_processing)
|
||||
START_PROCESSING(SSfields, src)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/Initialize()
|
||||
setup_field()
|
||||
post_setup_field()
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/full_cleanup() //Full cleanup for when you change something that would require complete resetting.
|
||||
for(var/turf/T in edge_turfs)
|
||||
cleanup_edge_turf(T)
|
||||
for(var/turf/T in field_turfs)
|
||||
cleanup_field_turf(T)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/check_movement()
|
||||
if(!use_host_turf)
|
||||
if(host.loc != last_host_loc)
|
||||
last_host_loc = host.loc
|
||||
return TRUE
|
||||
else
|
||||
if(get_turf(host) != last_host_loc)
|
||||
last_host_loc = get_turf(host)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/recalculate_field(ignore_movement_check = FALSE) //Call every time the field moves (done automatically if you use update_center) or a setup specification is changed.
|
||||
if(!(ignore_movement_check || check_movement()) && (field_shape != FIELD_NO_SHAPE))
|
||||
return
|
||||
update_new_turfs()
|
||||
var/list/turf/needs_setup = field_turfs_new.Copy()
|
||||
if(setup_field_turfs)
|
||||
for(var/turf/T in field_turfs)
|
||||
if(!(T in needs_setup))
|
||||
cleanup_field_turf(T)
|
||||
else
|
||||
needs_setup -= T
|
||||
CHECK_TICK
|
||||
for(var/turf/T in needs_setup)
|
||||
setup_field_turf(T)
|
||||
CHECK_TICK
|
||||
if(setup_edge_turfs)
|
||||
for(var/turf/T in edge_turfs)
|
||||
cleanup_edge_turf(T)
|
||||
CHECK_TICK
|
||||
for(var/turf/T in edge_turfs_new)
|
||||
setup_edge_turf(T)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_turf_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F, turf/entering)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_turf_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, turf/entering)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_edge_uncross(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F)
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/HandleMove()
|
||||
var/atom/_host = host
|
||||
var/atom/new_host_loc = _host.loc
|
||||
if(last_host_loc != new_host_loc)
|
||||
recalculate_field()
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/post_setup_field()
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/setup_field()
|
||||
update_new_turfs()
|
||||
if(setup_field_turfs)
|
||||
for(var/turf/T in field_turfs_new)
|
||||
setup_field_turf(T)
|
||||
CHECK_TICK
|
||||
if(setup_edge_turfs)
|
||||
for(var/turf/T in edge_turfs_new)
|
||||
setup_edge_turf(T)
|
||||
CHECK_TICK
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/T)
|
||||
qdel(field_turfs[T])
|
||||
field_turfs -= T
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/T)
|
||||
qdel(edge_turfs[T])
|
||||
edge_turfs -= T
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/T)
|
||||
field_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_turf(T, src)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/T)
|
||||
edge_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_edge(T, src)
|
||||
|
||||
/datum/proximity_monitor/advanced/proc/update_new_turfs()
|
||||
if(!istype(host))
|
||||
return FALSE
|
||||
var/turf/center = get_turf(host)
|
||||
field_turfs_new = list()
|
||||
edge_turfs_new = list()
|
||||
switch(field_shape)
|
||||
if(FIELD_NO_SHAPE)
|
||||
return FALSE
|
||||
if(FIELD_SHAPE_RADIUS_SQUARE)
|
||||
for(var/turf/T in block(locate(center.x-current_range,center.y-current_range,center.z-square_depth_down),locate(center.x+current_range, center.y+current_range,center.z+square_depth_up)))
|
||||
field_turfs_new += T
|
||||
edge_turfs_new = field_turfs_new.Copy()
|
||||
if(current_range >= 1)
|
||||
var/list/turf/center_turfs = list()
|
||||
for(var/turf/T in block(locate(center.x-current_range+1,center.y-current_range+1,center.z-square_depth_down),locate(center.x+current_range-1, center.y+current_range-1,center.z+square_depth_up)))
|
||||
center_turfs += T
|
||||
for(var/turf/T in center_turfs)
|
||||
edge_turfs_new -= T
|
||||
if(FIELD_SHAPE_CUSTOM_SQUARE)
|
||||
for(var/turf/T in block(locate(center.x-square_width,center.y-square_height,center.z-square_depth_down),locate(center.x+square_width, center.y+square_height,center.z+square_depth_up)))
|
||||
field_turfs_new += T
|
||||
edge_turfs_new = field_turfs_new.Copy()
|
||||
if(square_height >= 1 && square_width >= 1)
|
||||
var/list/turf/center_turfs = list()
|
||||
for(var/turf/T in block(locate(center.x-square_width+1,center.y-square_height+1,center.z-square_depth_down),locate(center.x+square_width-1, center.y+square_height-1,center.z+square_depth_up)))
|
||||
center_turfs += T
|
||||
for(var/turf/T in center_turfs)
|
||||
edge_turfs_new -= T
|
||||
|
||||
//Gets edge direction/corner, only works with square radius/WDH fields!
|
||||
/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null)
|
||||
var/turf/checking_from = get_turf(host)
|
||||
if(istype(center_override))
|
||||
checking_from = center_override
|
||||
if(field_shape != FIELD_SHAPE_RADIUS_SQUARE && field_shape != FIELD_SHAPE_CUSTOM_SQUARE)
|
||||
return
|
||||
if(!(T in edge_turfs))
|
||||
return
|
||||
switch(field_shape)
|
||||
if(FIELD_SHAPE_RADIUS_SQUARE)
|
||||
if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range))))
|
||||
return get_dir(checking_from, T)
|
||||
if(T.x == (checking_from.x + current_range))
|
||||
return EAST
|
||||
if(T.x == (checking_from.x - current_range))
|
||||
return WEST
|
||||
if(T.y == (checking_from.y - current_range))
|
||||
return SOUTH
|
||||
if(T.y == (checking_from.y + current_range))
|
||||
return NORTH
|
||||
if(FIELD_SHAPE_CUSTOM_SQUARE)
|
||||
if(((T.x == (checking_from.x + square_width)) || (T.x == (checking_from.x - square_width))) && ((T.y == (checking_from.y + square_height)) || (T.y == (checking_from.y - square_height))))
|
||||
return get_dir(checking_from, T)
|
||||
if(T.x == (checking_from.x + square_width))
|
||||
return EAST
|
||||
if(T.x == (checking_from.x - square_width))
|
||||
return WEST
|
||||
if(T.y == (checking_from.y - square_height))
|
||||
return SOUTH
|
||||
if(T.y == (checking_from.y + square_height))
|
||||
return NORTH
|
||||
|
||||
//DEBUG FIELDS
|
||||
/datum/proximity_monitor/advanced/debug
|
||||
name = "\improper Color Matrix Field"
|
||||
field_shape = FIELD_SHAPE_RADIUS_SQUARE
|
||||
current_range = 5
|
||||
var/set_fieldturf_color = "#aaffff"
|
||||
var/set_edgeturf_color = "#ffaaff"
|
||||
setup_field_turfs = TRUE
|
||||
setup_edge_turfs = TRUE
|
||||
|
||||
|
||||
/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/T)
|
||||
T.color = set_edgeturf_color
|
||||
..()
|
||||
|
||||
/datum/proximity_monitor/advanced/debug/cleanup_edge_turf(turf/T)
|
||||
T.color = initial(T.color)
|
||||
..()
|
||||
if(T in field_turfs)
|
||||
T.color = set_fieldturf_color
|
||||
|
||||
/datum/proximity_monitor/advanced/debug/setup_field_turf(turf/T)
|
||||
T.color = set_fieldturf_color
|
||||
..()
|
||||
|
||||
/datum/proximity_monitor/advanced/debug/cleanup_field_turf(turf/T)
|
||||
T.color = initial(T.color)
|
||||
..()
|
||||
|
||||
//DEBUG FIELD ITEM
|
||||
/obj/item/multitool/field_debug
|
||||
name = "strange multitool"
|
||||
desc = "Seems to project a colored field!"
|
||||
var/list/field_params = list("field_shape" = FIELD_SHAPE_RADIUS_SQUARE, "current_range" = 5, "set_fieldturf_color" = "#aaffff", "set_edgeturf_color" = "#ffaaff")
|
||||
var/field_type = /datum/proximity_monitor/advanced/debug
|
||||
var/operating = FALSE
|
||||
var/datum/proximity_monitor/advanced/current = null
|
||||
var/mob/listeningTo
|
||||
|
||||
/obj/item/multitool/field_debug/Initialize()
|
||||
. = ..()
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/multitool/field_debug/Destroy()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
QDEL_NULL(current)
|
||||
listeningTo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/multitool/field_debug/proc/setup_debug_field()
|
||||
var/list/new_params = field_params.Copy()
|
||||
new_params["host"] = src
|
||||
current = make_field(field_type, new_params)
|
||||
|
||||
/obj/item/multitool/field_debug/attack_self(mob/user)
|
||||
operating = !operating
|
||||
to_chat(user, "You turn [src] [operating? "on":"off"].")
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
if(!istype(current) && operating)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
|
||||
listeningTo = user
|
||||
setup_debug_field()
|
||||
else if(!operating)
|
||||
QDEL_NULL(current)
|
||||
|
||||
/obj/item/multitool/field_debug/dropped()
|
||||
. = ..()
|
||||
if(listeningTo)
|
||||
UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
|
||||
listeningTo = null
|
||||
|
||||
/obj/item/multitool/field_debug/proc/on_mob_move()
|
||||
check_turf(get_turf(src))
|
||||
|
||||
/obj/item/multitool/field_debug/process()
|
||||
check_turf(get_turf(src))
|
||||
|
||||
/obj/item/multitool/field_debug/proc/check_turf(turf/T)
|
||||
current.HandleMove()
|
||||
@@ -0,0 +1,163 @@
|
||||
|
||||
/obj/effect/timestop
|
||||
anchored = TRUE
|
||||
name = "chronofield"
|
||||
desc = "ZA WARUDO"
|
||||
icon = 'icons/effects/160x160.dmi'
|
||||
icon_state = "time"
|
||||
layer = FLY_LAYER
|
||||
pixel_x = -64
|
||||
pixel_y = -64
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
var/list/immune = list() // the one who creates the timestop is immune
|
||||
var/turf/target
|
||||
var/freezerange = 2
|
||||
var/duration = 140
|
||||
var/datum/proximity_monitor/advanced/timestop/chronofield
|
||||
alpha = 125
|
||||
var/check_anti_magic = FALSE
|
||||
var/check_holy = FALSE
|
||||
|
||||
/obj/effect/timestop/Initialize(mapload, radius, time, list/immune_atoms, start = TRUE) //Immune atoms assoc list atom = TRUE
|
||||
. = ..()
|
||||
if(!isnull(time))
|
||||
duration = time
|
||||
if(!isnull(radius))
|
||||
freezerange = radius
|
||||
for(var/A in immune_atoms)
|
||||
immune[A] = TRUE
|
||||
for(var/mob/living/L in GLOB.player_list)
|
||||
if(locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in L.mind.spell_list) //People who can stop time are immune to its effects
|
||||
immune[L] = TRUE
|
||||
for(var/mob/living/simple_animal/hostile/guardian/G in GLOB.parasites)
|
||||
if(G.summoner && locate(/obj/effect/proc_holder/spell/aoe_turf/conjure/timestop) in G.summoner.mind.spell_list) //It would only make sense that a person's stand would also be immune.
|
||||
immune[G] = TRUE
|
||||
if(start)
|
||||
timestop()
|
||||
|
||||
/obj/effect/timestop/Destroy()
|
||||
qdel(chronofield)
|
||||
playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, frequency = -1) //reverse!
|
||||
return ..()
|
||||
|
||||
/obj/effect/timestop/proc/timestop()
|
||||
target = get_turf(src)
|
||||
playsound(src, 'sound/magic/timeparadox2.ogg', 75, 1, -1)
|
||||
chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune, "check_anti_magic" = check_anti_magic, "check_holy" = check_holy))
|
||||
QDEL_IN(src, duration)
|
||||
|
||||
/obj/effect/timestop/wizard
|
||||
check_anti_magic = TRUE
|
||||
duration = 100
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop
|
||||
name = "chronofield"
|
||||
setup_field_turfs = TRUE
|
||||
field_shape = FIELD_SHAPE_RADIUS_SQUARE
|
||||
requires_processing = TRUE
|
||||
var/list/immune = list()
|
||||
var/list/mob/living/frozen_mobs = list()
|
||||
var/list/obj/item/projectile/frozen_projectiles = list()
|
||||
var/list/atom/movable/frozen_throws = list()
|
||||
var/check_anti_magic = FALSE
|
||||
var/check_holy = FALSE
|
||||
|
||||
var/static/list/global_frozen_atoms = list()
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/Destroy()
|
||||
unfreeze_all()
|
||||
return ..()
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/field_turf_crossed(atom/movable/AM)
|
||||
freeze_atom(AM)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_atom(atom/movable/A)
|
||||
if(immune[A] || global_frozen_atoms[A] || !istype(A))
|
||||
return FALSE
|
||||
if(A.throwing)
|
||||
freeze_throwing(A)
|
||||
if(isliving(A))
|
||||
freeze_mob(A)
|
||||
else if(istype(A, /obj/item/projectile))
|
||||
freeze_projectile(A)
|
||||
else
|
||||
return FALSE
|
||||
|
||||
into_the_negative_zone(A)
|
||||
|
||||
return TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_all()
|
||||
for(var/i in frozen_projectiles)
|
||||
unfreeze_projectile(i)
|
||||
for(var/i in frozen_mobs)
|
||||
unfreeze_mob(i)
|
||||
for(var/i in frozen_throws)
|
||||
unfreeze_throw(i)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_throwing(atom/movable/AM)
|
||||
var/datum/thrownthing/T = AM.throwing
|
||||
T.paused = TRUE
|
||||
frozen_throws[AM] = T
|
||||
global_frozen_atoms[AM] = TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_throw(atom/movable/AM)
|
||||
var/datum/thrownthing/T = frozen_throws[AM]
|
||||
T.paused = FALSE
|
||||
frozen_throws -= AM
|
||||
global_frozen_atoms -= AM
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/process()
|
||||
for(var/i in frozen_mobs)
|
||||
var/mob/living/m = i
|
||||
if(get_dist(get_turf(m), get_turf(host)) > current_range)
|
||||
unfreeze_mob(m)
|
||||
else
|
||||
m.Stun(20, 1, 1)
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T)
|
||||
for(var/i in T.contents)
|
||||
freeze_atom(i)
|
||||
return ..()
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_projectile(obj/item/projectile/P)
|
||||
escape_the_negative_zone(P)
|
||||
frozen_projectiles -= P
|
||||
P.paused = FALSE
|
||||
global_frozen_atoms -= P
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/item/projectile/P)
|
||||
frozen_projectiles[P] = TRUE
|
||||
P.paused = TRUE
|
||||
global_frozen_atoms[P] = TRUE
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
|
||||
if(L.anti_magic_check(check_anti_magic, check_holy))
|
||||
immune += L
|
||||
return
|
||||
L.Stun(20, 1, 1)
|
||||
frozen_mobs[L] = L.anchored
|
||||
L.anchored = TRUE
|
||||
global_frozen_atoms[L] = TRUE
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
H.toggle_ai(AI_OFF)
|
||||
H.LoseTarget()
|
||||
|
||||
/datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L)
|
||||
escape_the_negative_zone(L)
|
||||
L.AdjustStun(-20, 1, 1)
|
||||
L.anchored = frozen_mobs[L]
|
||||
frozen_mobs -= L
|
||||
global_frozen_atoms -= L
|
||||
if(ishostile(L))
|
||||
var/mob/living/simple_animal/hostile/H = L
|
||||
H.toggle_ai(initial(H.AIStatus))
|
||||
|
||||
//you don't look quite right, is something the matter?
|
||||
/datum/proximity_monitor/advanced/timestop/proc/into_the_negative_zone(atom/A)
|
||||
A.add_atom_colour(list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0), TEMPORARY_COLOUR_PRIORITY)
|
||||
|
||||
//let's put some colour back into your cheeks
|
||||
/datum/proximity_monitor/advanced/timestop/proc/escape_the_negative_zone(atom/A)
|
||||
A.remove_atom_colour(TEMPORARY_COLOUR_PRIORITY)
|
||||
Reference in New Issue
Block a user