From c93c5afefaf212e7e2da8f7ccc16f2b83593bf88 Mon Sep 17 00:00:00 2001 From: Aronai Sieyes Date: Mon, 23 Mar 2020 21:31:19 -0400 Subject: [PATCH] Adds atom/movable cloaking framework --- code/__defines/_planes+layers.dm | 3 + code/__defines/mobs.dm | 4 +- code/game/atoms_movable.dm | 93 +++++++++++++++++++ code/game/mecha/mecha.dm | 13 +++ code/modules/artifice/deadringer.dm | 4 +- code/modules/clothing/glasses/glasses.dm | 2 +- code/modules/mob/dead/observer/login.dm | 1 + .../subtypes/animal/giant_spider/lurker.dm | 18 ---- code/modules/mob/login.dm | 5 +- code/modules/mob/mob.dm | 22 +++++ code/modules/mob/mob_planes.dm | 8 ++ 11 files changed, 150 insertions(+), 23 deletions(-) diff --git a/code/__defines/_planes+layers.dm b/code/__defines/_planes+layers.dm index c36e238329..e79511d797 100644 --- a/code/__defines/_planes+layers.dm +++ b/code/__defines/_planes+layers.dm @@ -88,6 +88,9 @@ What is the naming convention for planes or layers? #define BELOW_MOB_LAYER 3.9 // Should be converted to plane swaps #define ABOVE_MOB_LAYER 4.1 // Should be converted to plane swaps +// Invisible things plane +#define CLOAKED_PLANE -15 + // Top plane (in the sense that it's the highest in 'the world' and not a UI element) #define ABOVE_PLANE -10 diff --git a/code/__defines/mobs.dm b/code/__defines/mobs.dm index cfbcfcd1dd..beeda302eb 100644 --- a/code/__defines/mobs.dm +++ b/code/__defines/mobs.dm @@ -396,7 +396,9 @@ #define VIS_BUILDMODE 22 -#define VIS_COUNT 22 //Must be highest number from above. +#define VIS_CLOAKED 23 + +#define VIS_COUNT 23 //Must be highest number from above. //Some mob icon layering defines #define BODY_LAYER -100 diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 37714ea745..af1d53d191 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -24,6 +24,9 @@ var/datum/riding/riding_datum //VOREStation Add - Moved from /obj/vehicle var/does_spin = TRUE // Does the atom spin when thrown (of course it does :P) var/movement_type = NONE + + var/cloaked = FALSE //If we're cloaked or not + var/image/cloaked_selfimage //The image we use for our client to let them see where we are /atom/movable/Destroy() . = ..() @@ -516,3 +519,93 @@ // Called when touching a lava tile. /atom/movable/proc/lava_act() fire_act(null, 10000, 1000) + + +// Procs to cloak/uncloak +/atom/movable/proc/cloak() + if(cloaked) + return FALSE + cloaked = TRUE + . = TRUE // We did work + + var/static/animation_time = 1 SECOND + cloaked_selfimage = get_cloaked_selfimage() + + //Wheeee + cloak_animation(animation_time) + + //Needs to be last so people can actually see the effect before we become invisible + plane = CLOAKED_PLANE + +/atom/movable/proc/uncloak() + if(!cloaked) + return FALSE + cloaked = FALSE + . = TRUE // We did work + + var/static/animation_time = 1 SECOND + QDEL_NULL(cloaked_selfimage) + + //Needs to be first so people can actually see the effect, so become uninvisible first + plane = initial(plane) + + //Oooooo + uncloak_animation(animation_time) + + +// Animations for cloaking/uncloaking +/atom/movable/proc/cloak_animation(var/length = 1 SECOND) + //Save these + var/initial_alpha = alpha + + //Animate alpha fade + animate(src, alpha = 0, time = length) + + //Animate a cloaking effect + var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. + filters += filter(type="wave", x = 0, y = 16, size = 0, offset = 0, flags = WAVE_SIDEWAYS) + animate(filters[our_filter], offset = 1, size = 8, time = length, flags = ANIMATION_PARALLEL) + + //Wait for animations to finish + sleep(length+5) + + //Remove those + filters -= filters[our_filter] + + //Back to original alpha + alpha = initial_alpha + +/atom/movable/proc/uncloak_animation(var/length = 1 SECOND) + //Save these + var/initial_alpha = alpha + + //Put us back to normal, but no alpha + alpha = 0 + + //Animate alpha fade up + animate(src, alpha = initial_alpha, time = length) + + //Animate a cloaking effect + var/our_filter = filters.len+1 //Filters don't appear to have a type that can be stored in a var and accessed. This is how the DM reference does it. + filters += filter(type="wave", x=0, y = 16, size = 8, offset = 1, flags = WAVE_SIDEWAYS) + animate(filters[our_filter], offset = 0, size = 0, time = length, flags = ANIMATION_PARALLEL) + + //Wait for animations to finish + sleep(length+5) + + //Remove those + filters -= filters[our_filter] + + +// So cloaked things can see themselves, if necessary +/atom/movable/proc/get_cloaked_selfimage() + var/icon/selficon = icon(icon, icon_state) + selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White + var/image/selfimage = image(selficon) + selfimage.color = "#0000FF" + selfimage.alpha = 100 + selfimage.layer = initial(layer) + selfimage.plane = initial(plane) + selfimage.loc = src + + return selfimage diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 8eaf406201..71b4bc7491 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -1260,6 +1260,8 @@ src.icon_state = src.reset_icon() set_dir(dir_in) playsound(src, 'sound/machines/windowdoor.ogg', 50, 1) + if(occupant.client && cloaked_selfimage) + occupant.client.images += cloaked_selfimage if(!hasInternalDamage()) //Otherwise it's not nominal! switch(mech_faction) if(MECH_FACTION_NT)//The good guys category @@ -2070,6 +2072,17 @@ ///////////// +/obj/mecha/cloak() + . = ..() + if(occupant && occupant.client && cloaked_selfimage) + occupant.client.images += cloaked_selfimage + +/obj/mecha/uncloak() + if(occupant && occupant.client && cloaked_selfimage) + occupant.client.images -= cloaked_selfimage + return ..() + + //debug /* /obj/mecha/verb/test_int_damage() diff --git a/code/modules/artifice/deadringer.dm b/code/modules/artifice/deadringer.dm index bdac793daf..3e95152528 100644 --- a/code/modules/artifice/deadringer.dm +++ b/code/modules/artifice/deadringer.dm @@ -67,7 +67,7 @@ if(timer > 0) timer-- if(timer == 20) - uncloak() + reveal() if(corpse) new /obj/effect/effect/smoke/chem(corpse.loc) qdel(corpse) @@ -86,7 +86,7 @@ makeacorpse(watchowner) return -/obj/item/weapon/deadringer/proc/uncloak() +/obj/item/weapon/deadringer/proc/reveal() if(watchowner) watchowner.alpha = 255 playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1) diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index d93c866bd3..4b82cbbe25 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -437,7 +437,7 @@ BLIND // can't see anything toggleable = 1 action_button_name = "Toggle Goggles" vision_flags = SEE_MOBS - enables_planes = list(VIS_FULLBRIGHT) + enables_planes = list(VIS_FULLBRIGHT, VIS_CLOAKED) flash_protection = FLASH_PROTECTION_REDUCED emp_act(severity) diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 121a7643ea..5b3f29df8e 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -3,6 +3,7 @@ ..() //Creates the plane_holder lazily plane_holder.set_vis(VIS_GHOSTS, ghostvision) plane_holder.set_vis(VIS_FULLBRIGHT, !seedarkness) + plane_holder.set_vis(VIS_CLOAKED, TRUE) plane_holder.set_vis(VIS_AI_EYE, TRUE) plane_holder.set_vis(VIS_AUGMENTED, TRUE) //VOREStation Add - GHOST VISION IS AUGMENTED plane = PLANE_GHOSTS diff --git a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm index d26ad34992..f5a90f69bc 100644 --- a/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm +++ b/code/modules/mob/living/simple_mob/subtypes/animal/giant_spider/lurker.dm @@ -47,29 +47,12 @@ ai_holder_type = /datum/ai_holder/simple_mob/melee/hit_and_run - var/cloaked = FALSE var/cloaked_alpha = 45 // Lower = Harder to see. var/cloaked_bonus_damage = 30 // This is added on top of the normal melee damage. var/cloaked_weaken_amount = 3 // How long to stun for. var/cloak_cooldown = 10 SECONDS // Amount of time needed to re-cloak after losing it. var/last_uncloak = 0 // world.time - -/mob/living/simple_mob/animal/giant_spider/lurker/proc/cloak() - if(cloaked) - return - animate(src, alpha = cloaked_alpha, time = 1 SECOND) - cloaked = TRUE - - -/mob/living/simple_mob/animal/giant_spider/lurker/proc/uncloak() - last_uncloak = world.time // This is assigned even if it isn't cloaked already, to 'reset' the timer if the spider is continously getting attacked. - if(!cloaked) - return - animate(src, alpha = initial(alpha), time = 1 SECOND) - cloaked = FALSE - - // Check if cloaking if possible. /mob/living/simple_mob/animal/giant_spider/lurker/proc/can_cloak() if(stat) @@ -79,7 +62,6 @@ return TRUE - // Called by things that break cloaks, like Technomancer wards. /mob/living/simple_mob/animal/giant_spider/lurker/break_cloak() uncloak() diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm index 045d9d5f44..8bff62d3f4 100644 --- a/code/modules/mob/login.dm +++ b/code/modules/mob/login.dm @@ -74,4 +74,7 @@ var/turf/T = get_turf(src) if(isturf(T)) - update_client_z(T.z) \ No newline at end of file + update_client_z(T.z) + + if(cloaked && cloaked_selfimage) + client.images += cloaked_selfimage \ No newline at end of file diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 04525d2f9b..88c880e5a2 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1197,3 +1197,25 @@ mob/proc/yank_out_object() /mob/onTransitZ(old_z, new_z) ..() update_client_z(new_z) + +/mob/cloak() + . = ..() + if(client && cloaked_selfimage) + client.images += cloaked_selfimage + +/mob/uncloak() + if(client && cloaked_selfimage) + client.images -= cloaked_selfimage + return ..() + +/mob/get_cloaked_selfimage() + var/icon/selficon = getCompoundIcon(src) + selficon.MapColors(0,0,0, 0,0,0, 0,0,0, 1,1,1) //White + var/image/selfimage = image(selficon) + selfimage.color = "#0000FF" + selfimage.alpha = 100 + selfimage.layer = initial(layer) + selfimage.plane = initial(plane) + selfimage.loc = src + + return selfimage diff --git a/code/modules/mob/mob_planes.dm b/code/modules/mob/mob_planes.dm index 86173ee7fe..e1c33efe72 100644 --- a/code/modules/mob/mob_planes.dm +++ b/code/modules/mob/mob_planes.dm @@ -41,6 +41,7 @@ plane_masters[VIS_TURFS] = new /obj/screen/plane_master/main{plane = TURF_PLANE} plane_masters[VIS_OBJS] = new /obj/screen/plane_master/main{plane = OBJ_PLANE} plane_masters[VIS_MOBS] = new /obj/screen/plane_master/main{plane = MOB_PLANE} + plane_masters[VIS_CLOAKED] = new /obj/screen/plane_master/cloaked //Cloaked atoms! ..() @@ -178,6 +179,13 @@ plane = PLANE_GHOSTS desired_alpha = 127 //When enabled, they're like half-transparent +///////////////// +//Cloaked atoms are visible to ghosts (or for other reasons?) +/obj/screen/plane_master/cloaked + plane = CLOAKED_PLANE + desired_alpha = 80 + color = "#0000FF" + ///////////////// //The main game planes start normal and visible /obj/screen/plane_master/main