mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
498 lines
18 KiB
Plaintext
498 lines
18 KiB
Plaintext
GLOBAL_VAR_INIT(pocket_dim, 1)
|
|
GLOBAL_LIST_EMPTY(pocket_corners)
|
|
GLOBAL_LIST_EMPTY(pocket_mirrors)
|
|
|
|
/proc/get_final_z(atom/A)
|
|
var/turf/T = get_turf(A)
|
|
if (T)
|
|
return T.z
|
|
return A.z
|
|
|
|
/area/yogstation/pocket_dimension
|
|
name = "Pocket Dimension"
|
|
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
|
has_gravity = STANDARD_GRAVITY
|
|
noteleport = TRUE
|
|
unique = FALSE
|
|
requires_power = FALSE
|
|
show_on_sensors = FALSE
|
|
ambience_index = AMBIENCE_SPACE
|
|
parallax_movedir = EAST
|
|
|
|
/obj/effect/landmark/pocket_dimension_corner
|
|
name = "pocket dimension corner (bottom left)"
|
|
|
|
/obj/effect/landmark/pocket_dimension_corner/Initialize(mapload)
|
|
. = ..()
|
|
var/datum/space_level/level = SSmapping.get_level(z)
|
|
if (!level)
|
|
debug_admins("uh oh, stinky!!")
|
|
return INITIALIZE_HINT_QDEL
|
|
GLOB.pocket_corners[level.name] = list(
|
|
"bl-corner" = get_turf(src), // Bottom left corner
|
|
"center" = locate(x + 4, y + 4, z),
|
|
"tr-corner" = locate(x + 8, y + 8, z), // Top right corner
|
|
)
|
|
return INITIALIZE_HINT_QDEL
|
|
|
|
/obj/effect/interdimsional_wall
|
|
name = "interdimensional wall"
|
|
desc = "YOU SHALL NOT PASS"
|
|
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
|
opacity = FALSE
|
|
anchored = TRUE
|
|
density = TRUE
|
|
|
|
/datum/guardian_ability/major/special/pocket
|
|
name = "Dimensional Manifestation"
|
|
desc = "The guardian has access to a pocket dimension, which it can manifest in realspace at will."
|
|
cost = 5
|
|
var/list/pocket_dim
|
|
var/manifested_at_x
|
|
var/manifested_at_y
|
|
var/manifested_at_z
|
|
var/mob/camera/aiEye/remote/pocket/eye
|
|
var/manifesting = FALSE
|
|
var/list/manifestations = list()
|
|
var/datum/action/cooldown/spell/pocket_dim/manifest_spell
|
|
var/datum/action/cooldown/spell/pocket_dim_move/move_spell
|
|
|
|
/datum/guardian_ability/major/special/pocket/Apply()
|
|
manifest_spell = new(guardian)
|
|
manifest_spell.guardian = guardian
|
|
move_spell = new(guardian)
|
|
move_spell.guardian = guardian
|
|
manifest_spell.Grant(guardian)
|
|
move_spell.Grant(guardian)
|
|
RegisterSignal(guardian, COMSIG_MOVABLE_MOVED, PROC_REF(auto_demanifest))
|
|
if (!LAZYLEN(pocket_dim))
|
|
var/list/errorList = list()
|
|
SSmapping.LoadGroup(errorList, "Pocket Dimension [GLOB.pocket_dim]", "templates", "pocket_dimension.dmm", default_traits = list("Pocket Dimension" = TRUE, "Pocket Dimension [GLOB.pocket_dim]" = TRUE, ZTRAIT_BOMBCAP_MULTIPLIER = 0), silent = TRUE)
|
|
if (errorList.len)
|
|
message_admins("A pocket dimension failed to load!")
|
|
log_game("A pocket dimension failed to load!")
|
|
return FALSE
|
|
pocket_dim = "Pocket Dimension [GLOB.pocket_dim++]"
|
|
GLOB.pocket_mirrors[pocket_dim] = list()
|
|
var/pz = get_pocket_z()
|
|
for (var/turf/open/indestructible/pocketspace/pocketspace in world)
|
|
if (pocketspace.z == pz)
|
|
GLOB.pocket_mirrors[pocket_dim] += pocketspace
|
|
eye = new
|
|
eye.guardian = guardian
|
|
eye.guardian_ability = src
|
|
eye.name = "Inactive Guardian Eye ([guardian])"
|
|
eye.forceMove(get_turf(guardian))
|
|
|
|
/datum/guardian_ability/major/special/pocket/Remove()
|
|
manifest_spell.Remove(guardian)
|
|
move_spell.Remove(guardian)
|
|
UnregisterSignal(guardian, COMSIG_MOVABLE_MOVED)
|
|
if (LAZYLEN(manifestations))
|
|
demanifest_dimension()
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/get_pocket_z()
|
|
if (!pocket_dim)
|
|
return
|
|
var/list/zs = SSmapping.levels_by_trait(pocket_dim)
|
|
if (!LAZYLEN(zs))
|
|
return null
|
|
return zs[1]
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/auto_demanifest()
|
|
if (!pocket_dim || manifesting || !LAZYLEN(manifestations) || !(manifested_at_x && manifested_at_y && manifested_at_z))
|
|
return
|
|
var/turf/center = locate(manifested_at_x, manifested_at_y, manifested_at_z)
|
|
if (!center)
|
|
return
|
|
var/turf/guardian_loc = get_turf(guardian)
|
|
if (guardian_loc.z != center.z)
|
|
to_chat(guardian, span_warning("Your pocket dimension demanifests, as you can't keep it manifested from so far away!"))
|
|
demanifest_dimension()
|
|
return
|
|
var/list/screen_size = getviewsize(world.view)
|
|
var/max_dist = max(screen_size[1], screen_size[2]) + 1
|
|
var/dist_from_manifestation = get_dist_euclidian(center, guardian_loc) - 4
|
|
if (dist_from_manifestation > max_dist)
|
|
to_chat(guardian, span_warning("Your pocket dimension demanifests, as you can't keep it manifested from so far away!"))
|
|
demanifest_dimension()
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/get_targets(require_neck_grab = FALSE)
|
|
. = list()
|
|
if (guardian.summoner?.current)
|
|
var/mob/living/summoner = guardian.summoner.current
|
|
. += summoner
|
|
var/bring_pull_in = FALSE
|
|
if (summoner.pulling && !summoner.pulling.anchored)
|
|
if (isobj(summoner.pulling))
|
|
bring_pull_in = TRUE
|
|
else if (isliving(summoner.pulling))
|
|
var/mob/living/pulling = summoner.pulling
|
|
bring_pull_in = !require_neck_grab || pulling.stat >= UNCONSCIOUS || summoner.grab_state >= GRAB_NECK
|
|
if(bring_pull_in)
|
|
. += summoner.pulling
|
|
for (var/G in guardian.summoner.hasparasites())
|
|
var/mob/living/simple_animal/hostile/guardian/guardian = G
|
|
if (guardian.is_deployed())
|
|
. += guardian
|
|
else if (guardian.is_deployed())
|
|
. |= guardian
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/manifest_dimension(pos_already_set = FALSE)
|
|
destroy_pocket_mirror(pocket_dim)
|
|
manifesting = TRUE
|
|
if (LAZYLEN(GLOB.pocket_mirrors[pocket_dim]))
|
|
for (var/turf/open/indestructible/pocketspace/PS in GLOB.pocket_mirrors[pocket_dim])
|
|
PS.vis_contents.Cut()
|
|
var/corrected_max = manifested_at_x
|
|
var/corrected_may = manifested_at_y
|
|
if (!pos_already_set) // don't subtract 4 if the pos is set, because we will have already subtracted by 4.
|
|
manifested_at_x = clamp(guardian.x - 4, 1, world.maxx)
|
|
corrected_max = manifested_at_x
|
|
manifested_at_y = clamp(guardian.y - 4, 1, world.maxy)
|
|
corrected_may = manifested_at_y
|
|
manifested_at_z = get_final_z(guardian)
|
|
|
|
var/list/us = block(locate(corrected_max, corrected_may, manifested_at_z), locate(min(corrected_max + 8, world.maxx), min(corrected_may + 8, world.maxy), manifested_at_z))
|
|
var/list/them = block(GLOB.pocket_corners[pocket_dim]["bl-corner"], GLOB.pocket_corners[pocket_dim]["tr-corner"])
|
|
for (var/idx in 1 to min(LAZYLEN(us), LAZYLEN(them)))
|
|
var/turf/manifestation_turf = us[idx]
|
|
var/turf/dimension_turf = them[idx]
|
|
if (manifestation_turf && dimension_turf)
|
|
var/obj/effect/manifestation/manifestation = new(manifestation_turf)
|
|
manifestation.vis_contents += dimension_turf
|
|
manifestations += manifestation
|
|
|
|
var/matrix/normally_scaled_matrix = new
|
|
normally_scaled_matrix.Scale(1)
|
|
var/matrix/downscaled_matrix = new
|
|
downscaled_matrix.Scale(0.1)
|
|
manifestation.transform = downscaled_matrix
|
|
var/manifestation_relative_x = manifested_at_x - manifestation_turf.x + 4
|
|
var/manifestation_relative_y = manifested_at_y - manifestation_turf.y + 4
|
|
var/pixel_x_shift = manifestation_relative_x * world.icon_size
|
|
var/pixel_y_shift = manifestation_relative_y * world.icon_size
|
|
manifestation.pixel_x = pixel_x_shift
|
|
manifestation.pixel_y = pixel_y_shift
|
|
|
|
animate(manifestation, alpha = 127, transform = normally_scaled_matrix, pixel_x = 0, pixel_y = 0, time = 3 SECONDS, easing = LINEAR_EASING)
|
|
|
|
addtimer(VARSET_CALLBACK(src, manifesting, FALSE), 3 SECONDS)
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/manifest_mobs_into_real_world()
|
|
var/list/targets = get_targets()
|
|
var/turf/corner = GLOB.pocket_corners[pocket_dim]["bl-corner"]
|
|
var/mob/living/pull_target
|
|
var/mob/living/summoner
|
|
for (var/M in targets)
|
|
var/mob/living/target = M
|
|
var/target_x = manifested_at_x + (target.x - corner.x)
|
|
var/target_y = manifested_at_y + (target.y - corner.y)
|
|
var/turf/target_turf = locate(target_x, target_y, manifested_at_z)
|
|
if (!target_turf)
|
|
continue
|
|
if (target == guardian.summoner?.current?.pulling)
|
|
pull_target = target
|
|
else if (target == guardian.summoner?.current)
|
|
summoner = target
|
|
take_effects(target)
|
|
if (target.alpha == 255)
|
|
target.alpha = 0
|
|
animate(target, alpha = 255, time = 3 SECONDS, easing = LINEAR_EASING)
|
|
target.forceMove(target_turf)
|
|
if (pull_target)
|
|
to_chat(pull_target, span_danger("All of existence fades out for a moment..."))
|
|
summoner.start_pulling(pull_target)
|
|
pull_target.Paralyze(5 SECONDS)
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/bring_mobs_into_pocket_dimension()
|
|
var/turf/corner = GLOB.pocket_corners[pocket_dim]["bl-corner"]
|
|
var/bl_safe_x = manifested_at_x + 1
|
|
var/bl_safe_y = manifested_at_y + 1
|
|
var/tr_safe_x = min(world.maxx, manifested_at_x + 7)
|
|
var/tr_safe_y = min(world.maxy, manifested_at_y + 7)
|
|
var/list/safe_locations = block(locate(bl_safe_x, bl_safe_y, manifested_at_z), locate(tr_safe_x, tr_safe_y, manifested_at_z))
|
|
var/pocket_z = get_pocket_z()
|
|
var/list/targets = get_targets(TRUE)
|
|
var/mob/living/pull_target
|
|
var/mob/living/summoner
|
|
for (var/M in targets)
|
|
var/mob/living/target = M
|
|
if (!(target.loc in safe_locations))
|
|
continue
|
|
var/target_x = corner.x + (target.x - manifested_at_x)
|
|
var/target_y = corner.y + (target.y - manifested_at_y)
|
|
var/turf/target_turf = locate(target_x, target_y, pocket_z)
|
|
if (!target_turf)
|
|
continue
|
|
if (target == guardian.summoner?.current?.pulling)
|
|
pull_target = target
|
|
else if (target == guardian.summoner?.current)
|
|
summoner = target
|
|
if (target != pull_target)
|
|
add_effects(target)
|
|
target.forceMove(target_turf)
|
|
if (pull_target)
|
|
to_chat(pull_target, span_danger("All of existence fades out for a moment..."))
|
|
summoner.start_pulling(pull_target)
|
|
pull_target.Paralyze(5 SECONDS)
|
|
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/demanifest_dimension()
|
|
manifesting = TRUE
|
|
for (var/obj/effect/manifestation/manifestation in manifestations)
|
|
// FANCY ANIMATION TIME!
|
|
// Create a new matrix, with a scale of 10%
|
|
var/matrix/downscaled_matrix = new
|
|
downscaled_matrix.Scale(0.1)
|
|
// Calculate the relative x and y of this manifestation
|
|
var/manifestation_relative_x = manifested_at_x - manifestation.x + 4
|
|
var/manifestation_relative_y = manifested_at_y - manifestation.y + 4
|
|
// Calculate the pixel_x and y shift needed to have this effect converge to the center
|
|
var/pixel_x_shift = manifestation_relative_x * world.icon_size
|
|
var/pixel_y_shift = manifestation_relative_y * world.icon_size
|
|
// Animate all this!
|
|
animate(manifestation, alpha = 0, transform = downscaled_matrix, pixel_x = pixel_x_shift, pixel_y = pixel_y_shift, time = 3 SECONDS, easing = LINEAR_EASING)
|
|
manifestations -= manifestation
|
|
QDEL_IN(manifestation, 3 SECONDS)
|
|
|
|
if (pocket_dim)
|
|
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(update_pocket_mirror), pocket_dim, manifested_at_x, manifested_at_y, manifested_at_z), 3.5 SECONDS)
|
|
|
|
addtimer(VARSET_CALLBACK(src, manifesting, FALSE), 3 SECONDS)
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/check_if_teleport(mob/living/L)
|
|
var/list/pocket_z = get_pocket_z()
|
|
if (!pocket_z)
|
|
return
|
|
if (get_final_z(L) != pocket_z)
|
|
take_effects(L)
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/add_effects(mob/living/L)
|
|
L.status_flags |= GODMODE
|
|
ADD_TRAIT(L, TRAIT_NOHARDCRIT, GUARDIAN_TRAIT)
|
|
ADD_TRAIT(L, TRAIT_NOSOFTCRIT, GUARDIAN_TRAIT)
|
|
ADD_TRAIT(L, TRAIT_NODEATH, GUARDIAN_TRAIT)
|
|
if (!isguardian(L))
|
|
RegisterSignal(L, COMSIG_MOVABLE_MOVED, PROC_REF(check_if_teleport))
|
|
for (var/mob/living/simple_animal/hostile/guardian/G in L.hasparasites())
|
|
G.status_flags |= GODMODE
|
|
|
|
/datum/guardian_ability/major/special/pocket/proc/take_effects(mob/living/L)
|
|
L.status_flags &= ~GODMODE
|
|
REMOVE_TRAIT(L, TRAIT_NOHARDCRIT, GUARDIAN_TRAIT)
|
|
REMOVE_TRAIT(L, TRAIT_NOSOFTCRIT, GUARDIAN_TRAIT)
|
|
REMOVE_TRAIT(L, TRAIT_NODEATH, GUARDIAN_TRAIT)
|
|
UnregisterSignal(L, COMSIG_MOVABLE_MOVED)
|
|
for (var/mob/living/simple_animal/hostile/guardian/G in L.hasparasites())
|
|
G.status_flags &= ~GODMODE
|
|
|
|
/obj/effect/manifestation
|
|
layer = ABOVE_LIGHTING_LAYER
|
|
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
|
|
alpha = 0
|
|
mouse_opacity = FALSE
|
|
var/next_animate = 0
|
|
|
|
/obj/effect/manifestation/Initialize(mapload)
|
|
. = ..()
|
|
var/X,Y,i,rsq
|
|
for (i=1, i<=7, ++i)
|
|
do
|
|
X = 60*rand() - 30
|
|
Y = 60*rand() - 30
|
|
rsq = X*X + Y*Y
|
|
while (rsq<100 || rsq>900)
|
|
filters += filter(type="wave", x=X, y=Y, size=rand()*2.5+0.5, offset=rand())
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
/obj/effect/manifestation/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
return ..()
|
|
|
|
/obj/effect/manifestation/process()
|
|
if (next_animate > world.time)
|
|
return
|
|
var/i,f
|
|
for (i=1, i<=7, ++i)
|
|
f = filters[i]
|
|
var/next = rand()*20+(1 SECONDS)
|
|
animate(f, offset=f:offset, time=0 SECONDS, loop=3, flags=ANIMATION_PARALLEL)
|
|
animate(offset=f:offset-1, time=next)
|
|
next_animate = world.time + next
|
|
|
|
/datum/action/cooldown/spell/pocket_dim
|
|
name = "Dimensional Intersection"
|
|
desc = "(De)manifest a pocket dimension."
|
|
button_icon = 'icons/obj/objects.dmi'
|
|
button_icon_state = "anom"
|
|
|
|
cooldown_time = 45 SECONDS
|
|
spell_requirements = NONE
|
|
var/mob/living/simple_animal/hostile/guardian/guardian
|
|
|
|
/datum/action/cooldown/spell/pocket_dim/cast(atom/cast_on)
|
|
. = ..()
|
|
if (!guardian || !istype(guardian))
|
|
return
|
|
if (!guardian.is_deployed())
|
|
to_chat(guardian, span_red(span_bold("You must be manifested to summon the pocket dimension!</span>")))
|
|
return
|
|
var/datum/guardian_ability/major/special/pocket/PD = guardian?.stats?.ability
|
|
if (!PD || !istype(PD))
|
|
return
|
|
var/pocket_z = PD.get_pocket_z()
|
|
if (!pocket_z)
|
|
to_chat(guardian, span_red(span_bold("ERROR: You do not have a pocket dimension generated! Report this bug on Github!</span>")))
|
|
return
|
|
if (PD.manifesting)
|
|
to_chat(guardian, span_red(span_bold("Wait! Your pocket dimension is currently (de)manifesting!</span>")))
|
|
return
|
|
if (guardian.remote_control == PD.eye)
|
|
for (var/V in PD.eye.visibleCameraChunks)
|
|
var/datum/camerachunk/C = V
|
|
C.remove(PD.eye)
|
|
if (guardian.client)
|
|
guardian.reset_perspective(null)
|
|
if (PD.eye.visible_icon)
|
|
guardian.client.images -= PD.eye.user_image
|
|
PD.eye.eye_user = null
|
|
guardian.remote_control = null
|
|
if (LAZYLEN(PD.manifestations))
|
|
guardian.visible_message(span_warning("The distorted space surronding [guardian] is sucked in!"))
|
|
PD.eye.forceMove(get_turf(guardian))
|
|
PD.bring_mobs_into_pocket_dimension()
|
|
PD.demanifest_dimension()
|
|
else
|
|
if (get_final_z(guardian) == pocket_z)
|
|
PD.manifest_dimension(TRUE)
|
|
PD.manifest_mobs_into_real_world()
|
|
PD.eye.forceMove(get_turf(guardian))
|
|
else
|
|
guardian.visible_message(span_warning("[guardian] emits a burst of energy, distorting the space around it!"))
|
|
PD.manifest_dimension()
|
|
PD.eye.forceMove(get_turf(guardian))
|
|
|
|
/datum/action/cooldown/spell/pocket_dim_move
|
|
name = "Dimensional Movement"
|
|
button_icon = 'icons/mob/actions/actions_silicon.dmi'
|
|
button_icon_state = "camera_jump"
|
|
|
|
spell_requirements = NONE
|
|
var/mob/living/simple_animal/hostile/guardian/guardian
|
|
|
|
/datum/action/cooldown/spell/pocket_dim_move/cast(mob/living/user)
|
|
. = ..()
|
|
if (!guardian || !istype(guardian))
|
|
return
|
|
var/datum/guardian_ability/major/special/pocket/PD = guardian?.stats?.ability
|
|
if (!PD || !istype(PD))
|
|
return
|
|
var/pocket_z = PD.get_pocket_z()
|
|
if (!pocket_z)
|
|
to_chat(guardian, span_red(span_bold("ERROR: You do not have a pocket dimension generated! Report this bug on Github!")))
|
|
return
|
|
if (!PD.eye)
|
|
to_chat(guardian, span_red(span_bold("ERROR: You do not have a camera eye generated! Report this bug on Github!</span>")))
|
|
return
|
|
var/turf/T = get_turf(guardian)
|
|
if (T.z != pocket_z)
|
|
to_chat(guardian, span_notice(span_bold("You must be inside a demanifested pocket dimension to move it!")))
|
|
return
|
|
if (PD.manifesting)
|
|
to_chat(guardian, span_red(span_bold("Wait! Your pocket dimension is currently (de)manifesting!</span>")))
|
|
return
|
|
var/mob/camera/aiEye/remote/pocket/eyeobj = PD.eye
|
|
if (eyeobj.eye_user)
|
|
for (var/V in eyeobj.visibleCameraChunks)
|
|
var/datum/camerachunk/C = V
|
|
C.remove(eyeobj)
|
|
if (guardian.client)
|
|
guardian.reset_perspective(null)
|
|
if (eyeobj.visible_icon)
|
|
guardian.client.images -= eyeobj.user_image
|
|
eyeobj.eye_user = null
|
|
guardian.remote_control = null
|
|
else
|
|
give_eye(eyeobj)
|
|
eyeobj.setLoc(locate(PD.manifested_at_x || T.x, PD.manifested_at_y || T.y, PD.manifested_at_z || T.z))
|
|
|
|
return TRUE
|
|
|
|
/datum/action/cooldown/spell/pocket_dim_move/proc/give_eye(mob/camera/aiEye/remote/pocket/eyeobj)
|
|
eyeobj.eye_user = guardian
|
|
eyeobj.name = "Guardian Eye ([guardian.name])"
|
|
guardian.remote_control = eyeobj
|
|
|
|
/turf/open/indestructible/pocketspace
|
|
name = "interdimensional distortion"
|
|
icon = 'icons/turf/space.dmi'
|
|
icon_state = "0"
|
|
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
|
|
planetary_atmos = TRUE
|
|
flags_1 = NOJAUNT_1
|
|
var/next_animate = 0
|
|
|
|
/turf/open/indestructible/pocketspace/Initialize(mapload)
|
|
. = ..()
|
|
var/X,Y,i,rsq
|
|
for (i=1, i<=7, ++i)
|
|
do
|
|
X = 60*rand() - 30
|
|
Y = 60*rand() - 30
|
|
rsq = X*X + Y*Y
|
|
while(rsq<100 || rsq>900)
|
|
filters += filter(type="wave", x=X, y=Y, size=rand()*2.5+0.5, offset=rand())
|
|
START_PROCESSING(SSobj, src)
|
|
|
|
/turf/open/indestructible/pocketspace/Destroy()
|
|
STOP_PROCESSING(SSobj, src)
|
|
return ..()
|
|
|
|
/turf/open/indestructible/pocketspace/process()
|
|
if (next_animate > world.time)
|
|
return
|
|
var/i,f
|
|
for (i=1, i<=7, ++i)
|
|
f = filters[i]
|
|
var/next = rand()*20+(1 SECONDS)
|
|
animate(f, offset=f:offset, time=0 SECONDS, loop=3, flags=ANIMATION_PARALLEL)
|
|
animate(offset=f:offset-1, time=next)
|
|
next_animate = world.time + next
|
|
|
|
/mob/camera/aiEye/remote/pocket
|
|
name = "Inactive Guardian Eye"
|
|
move_on_shuttle = TRUE
|
|
use_static = FALSE
|
|
var/mob/living/simple_animal/hostile/guardian/guardian
|
|
var/datum/guardian_ability/major/special/pocket/guardian_ability
|
|
|
|
/mob/camera/aiEye/remote/pocket/setLoc()
|
|
. = ..()
|
|
var/turf/T = get_turf(src)
|
|
if (T)
|
|
guardian_ability.manifested_at_x = clamp(T.x, 1, world.maxx)
|
|
guardian_ability.manifested_at_y = clamp(T.y, 1, world.maxy)
|
|
guardian_ability.manifested_at_z = T.z
|
|
if (guardian_ability.manifesting || LAZYLEN(guardian_ability.manifestations))
|
|
destroy_pocket_mirror(guardian_ability.pocket_dim)
|
|
else
|
|
update_pocket_mirror(guardian_ability.pocket_dim, T.x, T.y, T.z)
|
|
|
|
/proc/update_pocket_mirror(pocket_dim, sx, sy, sz)
|
|
var/turf/bl_corner = GLOB.pocket_corners[pocket_dim]["bl-corner"]
|
|
var/turf/tr_corner = GLOB.pocket_corners[pocket_dim]["tr-corner"]
|
|
for (var/T in block(bl_corner, tr_corner))
|
|
var/turf/open/indestructible/pocketspace/pocket_space = T
|
|
if (pocket_space && istype(pocket_space))
|
|
pocket_space.vis_contents.Cut()
|
|
pocket_space.vis_contents += locate(sx + (pocket_space.x - bl_corner.x), sy + (pocket_space.y - bl_corner.y), sz)
|
|
|
|
/proc/destroy_pocket_mirror(pocket_dim)
|
|
var/turf/bl_corner = GLOB.pocket_corners[pocket_dim]["bl-corner"]
|
|
var/turf/tr_corner = GLOB.pocket_corners[pocket_dim]["tr-corner"]
|
|
for (var/T in block(bl_corner, tr_corner))
|
|
var/turf/open/indestructible/pocketspace/PS = T
|
|
if (PS && istype(PS))
|
|
PS.vis_contents.Cut()
|