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
|
anchored = 1
|
||||||
flags = INVULNERABLE
|
flags = INVULNERABLE
|
||||||
|
|
||||||
|
/mob/dview/send_to_future(var/duration)
|
||||||
|
return
|
||||||
|
|
||||||
//Gets the Z level datum for this atom's Z level
|
//Gets the Z level datum for this atom's Z level
|
||||||
/proc/get_z_level(var/atom/A)
|
/proc/get_z_level(var/atom/A)
|
||||||
var/z
|
var/z
|
||||||
|
|||||||
@@ -719,3 +719,39 @@
|
|||||||
|
|
||||||
/atom/movable/proc/can_apply_inertia()
|
/atom/movable/proc/can_apply_inertia()
|
||||||
return (!src.anchored && !(src.pulledby && src.pulledby.Adjacent(src)))
|
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."
|
desc = "Better keep this safe."
|
||||||
icon_state = "nucleardisk"
|
icon_state = "nucleardisk"
|
||||||
item_state = "card-id"
|
item_state = "card-id"
|
||||||
|
flags = FPRINT | TIMELESS
|
||||||
w_class = W_CLASS_TINY
|
w_class = W_CLASS_TINY
|
||||||
var/respawned = 0
|
var/respawned = 0
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,47 @@
|
|||||||
/obj/item/weapon/grenade/chronogrenade/prime()
|
/obj/item/weapon/grenade/chronogrenade/prime()
|
||||||
timestop(src, duration, radius)
|
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)
|
for(var/i = 1 to 7)
|
||||||
new /obj/item/toy/balloon(src)
|
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))
|
if(istype(user))
|
||||||
return (M_CLUMSY in user.mutations)
|
return (M_CLUMSY in user.mutations)
|
||||||
return 0
|
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
|
color = LIGHTING_BASE_MATRIX
|
||||||
|
|
||||||
return ..("color")
|
return ..("color")
|
||||||
|
|
||||||
|
/atom/movable/lighting_overlay/send_to_future(var/duration)
|
||||||
|
return
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
mouse_opacity = 0
|
mouse_opacity = 0
|
||||||
see_in_dark = 7
|
see_in_dark = 7
|
||||||
invisibility = 101 // No one can see us
|
invisibility = 101 // No one can see us
|
||||||
|
flags = HEAR | PROXMOVE | TIMELESS
|
||||||
|
|
||||||
/mob/camera/can_shuttle_move()
|
/mob/camera/can_shuttle_move()
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
canmove = 0
|
canmove = 0
|
||||||
blinded = 0
|
blinded = 0
|
||||||
anchored = 1 // don't get pushed around
|
anchored = 1 // don't get pushed around
|
||||||
flags = HEAR
|
flags = HEAR | TIMELESS
|
||||||
invisibility = INVISIBILITY_OBSERVER
|
invisibility = INVISIBILITY_OBSERVER
|
||||||
universal_understand = 1
|
universal_understand = 1
|
||||||
universal_speak = 1
|
universal_speak = 1
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
var/list/visibleCameraChunks = list()
|
var/list/visibleCameraChunks = list()
|
||||||
var/mob/living/silicon/ai/ai = null
|
var/mob/living/silicon/ai/ai = null
|
||||||
var/high_res = 0
|
var/high_res = 0
|
||||||
flags = HEAR_ALWAYS
|
flags = HEAR_ALWAYS | TIMELESS
|
||||||
|
|
||||||
// Use this when setting the aiEye's location.
|
// Use this when setting the aiEye's location.
|
||||||
// It will also stream the chunk that the new loc is in.
|
// It will also stream the chunk that the new loc is in.
|
||||||
|
|||||||
@@ -1757,5 +1757,21 @@ mob/proc/on_foot()
|
|||||||
/mob/acidable()
|
/mob/acidable()
|
||||||
return 1
|
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_SPACEDRUGS_HALLUCINATING
|
||||||
#undef MOB_MINDBREAKER_HALLUCINATING
|
#undef MOB_MINDBREAKER_HALLUCINATING
|
||||||
|
|||||||
@@ -109,9 +109,9 @@ var/global/list/falltempoverlays = list()
|
|||||||
if(C.mob)
|
if(C.mob)
|
||||||
C.mob.see_fall(ourturf, range)
|
C.mob.see_fall(ourturf, range)
|
||||||
spawn(10)
|
spawn(10)
|
||||||
for(var/client/C in clients)
|
for(var/client/C in clients)
|
||||||
if(C.mob)
|
if(C.mob)
|
||||||
C.mob.see_fall()
|
C.mob.see_fall()
|
||||||
|
|
||||||
INVOKE_EVENT(user.on_spellcast, list("spell" = src, "target" = targets))
|
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