mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
Future Grenades (#13519)
* Adds future grenades. * Fixes conflicts. * Indents see_fall() loops. * Default range argument. * /mob/dview now ignores send_to_future() * AI eyes, observers, and the nuke disk are now timeless. * Blob overminds are now timeless. Objs are now nullspaced upon being sent to the future, just to ensure they're not damaged by anything in the present. * Allows mobs deafened by the grenade's effect to still hear the sound it makes when it ends.
This commit is contained in:
@@ -1318,6 +1318,9 @@ proc/rotate_icon(file, state, step = 1, aa = FALSE)
|
||||
anchored = 1
|
||||
flags = INVULNERABLE
|
||||
|
||||
/mob/dview/send_to_future(var/duration)
|
||||
return
|
||||
|
||||
//Gets the Z level datum for this atom's Z level
|
||||
/proc/get_z_level(var/atom/A)
|
||||
var/z
|
||||
|
||||
@@ -719,3 +719,39 @@
|
||||
|
||||
/atom/movable/proc/can_apply_inertia()
|
||||
return (!src.anchored && !(src.pulledby && src.pulledby.Adjacent(src)))
|
||||
|
||||
/atom/movable/proc/send_to_future(var/duration) //don't override this, only call it
|
||||
spawn()
|
||||
actual_send_to_future(duration)
|
||||
|
||||
/atom/movable/proc/actual_send_to_future(var/duration) //don't call this, only override it
|
||||
var/init_invisibility = invisibility
|
||||
var/init_invuln = flags & INVULNERABLE
|
||||
var/init_density = density
|
||||
var/init_anchored = anchored
|
||||
var/init_timeless = flags & TIMELESS
|
||||
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
flags |= INVULNERABLE
|
||||
density = 0
|
||||
anchored = 1
|
||||
flags |= TIMELESS
|
||||
if(!ignoreinvert)
|
||||
invertcolor(src)
|
||||
timestopped = 1
|
||||
|
||||
for(var/atom/movable/AM in contents)
|
||||
AM.send_to_future(duration)
|
||||
|
||||
sleep(duration)
|
||||
timestopped = 0
|
||||
if(!init_invuln)
|
||||
flags &= ~INVULNERABLE
|
||||
density = init_density
|
||||
anchored = init_anchored
|
||||
if(!init_timeless)
|
||||
flags &= ~TIMELESS
|
||||
appearance = falltempoverlays[src]
|
||||
falltempoverlays -= src
|
||||
ignoreinvert = initial(ignoreinvert)
|
||||
invisibility = init_invisibility
|
||||
@@ -341,6 +341,7 @@ var/obj/item/weapon/disk/nuclear/nukedisk
|
||||
desc = "Better keep this safe."
|
||||
icon_state = "nucleardisk"
|
||||
item_state = "card-id"
|
||||
flags = FPRINT | TIMELESS
|
||||
w_class = W_CLASS_TINY
|
||||
var/respawned = 0
|
||||
|
||||
|
||||
@@ -10,4 +10,48 @@
|
||||
|
||||
/obj/item/weapon/grenade/chronogrenade/prime()
|
||||
timestop(src, duration, radius)
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weapon/grenade/chronogrenade/future
|
||||
desc = "This experimental weapon will send all entities in the local area ten seconds into the future."
|
||||
icon_state = "future_grenade"
|
||||
|
||||
/obj/item/weapon/grenade/chronogrenade/future/prime()
|
||||
future_rift(src, duration, radius)
|
||||
qdel(src)
|
||||
|
||||
/proc/future_rift(atom/A, var/duration, var/range = 7) //Sends all non-timeless atoms in range duration time into the future.
|
||||
if(!A || !duration)
|
||||
return
|
||||
|
||||
var/turf/ourturf = get_turf(A)
|
||||
var/list/targets = circlerangeturfs(A, range)
|
||||
spawn()
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall(ourturf, range)
|
||||
spawn(10)
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall()
|
||||
|
||||
playsound(A, 'sound/effects/fall.ogg', 100, 0, 0, 0, 0)
|
||||
|
||||
for(var/turf/T in targets)
|
||||
for(var/atom/movable/everything in T)
|
||||
if(everything.flags & TIMELESS)
|
||||
continue
|
||||
everything.send_to_future(duration)
|
||||
if(ismob(everything))
|
||||
var/mob/M = everything
|
||||
M.playsound_local(everything, 'sound/effects/fall2.ogg', 100, 0, 0, 0, 0)
|
||||
spawn(duration)
|
||||
spawn(1) //so that mobs deafened by the effect will still hear the sound when it ends
|
||||
playsound(ourturf, 'sound/effects/fall.ogg', 100, 0, 0, 0, 0)
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall(ourturf, range)
|
||||
spawn(10)
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall()
|
||||
@@ -731,3 +731,13 @@
|
||||
..()
|
||||
for(var/i = 1 to 7)
|
||||
new /obj/item/toy/balloon(src)
|
||||
|
||||
/obj/item/weapon/storage/box/chrono_grenades/future
|
||||
icon_state = "future_grenade"
|
||||
|
||||
/obj/item/weapon/storage/box/chrono_grenades/future/New()
|
||||
..()
|
||||
for(var/atom/A in src)
|
||||
qdel(A)
|
||||
for(var/i = 1 to 7)
|
||||
new /obj/item/weapon/grenade/chronogrenade/future(src)
|
||||
|
||||
@@ -546,3 +546,15 @@ a {
|
||||
if(istype(user))
|
||||
return (M_CLUMSY in user.mutations)
|
||||
return 0
|
||||
|
||||
/obj/actual_send_to_future(var/duration)
|
||||
var/turf/current_turf = get_turf(src)
|
||||
var/datum/current_loc = loc
|
||||
forceMove(null)
|
||||
|
||||
..()
|
||||
|
||||
if(!current_loc.gcDestroyed)
|
||||
forceMove(current_loc)
|
||||
else
|
||||
forceMove(current_turf)
|
||||
|
||||
@@ -113,3 +113,6 @@
|
||||
color = LIGHTING_BASE_MATRIX
|
||||
|
||||
return ..("color")
|
||||
|
||||
/atom/movable/lighting_overlay/send_to_future(var/duration)
|
||||
return
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
mouse_opacity = 0
|
||||
see_in_dark = 7
|
||||
invisibility = 101 // No one can see us
|
||||
flags = HEAR | PROXMOVE | TIMELESS
|
||||
|
||||
/mob/camera/can_shuttle_move()
|
||||
return 0
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
canmove = 0
|
||||
blinded = 0
|
||||
anchored = 1 // don't get pushed around
|
||||
flags = HEAR
|
||||
flags = HEAR | TIMELESS
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
universal_understand = 1
|
||||
universal_speak = 1
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
var/high_res = 0
|
||||
flags = HEAR_ALWAYS
|
||||
flags = HEAR_ALWAYS | TIMELESS
|
||||
|
||||
// Use this when setting the aiEye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
|
||||
@@ -1757,5 +1757,21 @@ mob/proc/on_foot()
|
||||
/mob/acidable()
|
||||
return 1
|
||||
|
||||
/mob/actual_send_to_future(var/duration)
|
||||
var/init_blinded = blinded
|
||||
var/init_eye_blind = eye_blind
|
||||
var/init_deaf = ear_deaf
|
||||
overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
|
||||
blinded = 1
|
||||
eye_blind = 1
|
||||
ear_deaf = 1
|
||||
|
||||
..()
|
||||
|
||||
blinded = init_blinded
|
||||
eye_blind = init_eye_blind
|
||||
ear_deaf = init_deaf
|
||||
clear_fullscreen("blind")
|
||||
|
||||
#undef MOB_SPACEDRUGS_HALLUCINATING
|
||||
#undef MOB_MINDBREAKER_HALLUCINATING
|
||||
|
||||
@@ -109,9 +109,9 @@ var/global/list/falltempoverlays = list()
|
||||
if(C.mob)
|
||||
C.mob.see_fall(ourturf, range)
|
||||
spawn(10)
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall()
|
||||
for(var/client/C in clients)
|
||||
if(C.mob)
|
||||
C.mob.see_fall()
|
||||
|
||||
INVOKE_EVENT(user.on_spellcast, list("spell" = src, "target" = targets))
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Reference in New Issue
Block a user