Skip to content

Commit

Permalink
ghost qol
Browse files Browse the repository at this point in the history
  • Loading branch information
EvilDragonfiend committed Oct 2, 2023
1 parent d6948ad commit bc88a4e
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 7 deletions.
83 changes: 77 additions & 6 deletions code/controllers/subsystem/vis_overlays.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ SUBSYSTEM_DEF(vis_overlays)

var/list/vis_overlay_cache
var/list/unique_vis_overlays
/// vis overlays that is used to project half-transparent mob appearance
var/list/mob_alpha_vis_overlays
var/list/currentrun

/datum/controller/subsystem/vis_overlays/Initialize()
vis_overlay_cache = list()
unique_vis_overlays = list()
mob_alpha_vis_overlays = list()
return ..()

/datum/controller/subsystem/vis_overlays/fire(resumed = FALSE)
Expand All @@ -32,18 +35,18 @@ SUBSYSTEM_DEF(vis_overlays)
return

//the "thing" var can be anything with vis_contents which includes images
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE)
/datum/controller/subsystem/vis_overlays/proc/add_vis_overlay(atom/movable/thing, icon, iconstate, layer, plane, dir, alpha = 255, add_appearance_flags = NONE, unique = FALSE, invisibility = -1)
var/obj/effect/overlay/vis/overlay
if(!unique)
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags]"
. = "[icon]|[iconstate]|[layer]|[plane]|[dir]|[alpha]|[add_appearance_flags][invisibility]"
overlay = vis_overlay_cache[.]
if(!overlay)
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags, invisibility)
vis_overlay_cache[.] = overlay
else
overlay.unused = 0
else
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
overlay = _create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags, invisibility)
overlay.cache_expiration = -1
var/cache_id = "[FAST_REF(overlay)]@{[world.time]}"
unique_vis_overlays += overlay
Expand All @@ -60,7 +63,7 @@ SUBSYSTEM_DEF(vis_overlays)
else
thing.managed_vis_overlays += overlay

/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags)
/datum/controller/subsystem/vis_overlays/proc/_create_new_vis_overlay(icon, iconstate, layer, plane, dir, alpha, add_appearance_flags, invisibility = -1)
var/obj/effect/overlay/vis/overlay = new
overlay.icon = icon
overlay.icon_state = iconstate
Expand All @@ -69,9 +72,10 @@ SUBSYSTEM_DEF(vis_overlays)
overlay.dir = dir
overlay.alpha = alpha
overlay.appearance_flags |= add_appearance_flags
if(invisibility > -1)
overlay.invisibility = invisibility
return overlay


/datum/controller/subsystem/vis_overlays/proc/remove_vis_overlay(atom/movable/thing, list/overlays)
thing.vis_contents -= overlays
if(!isatom(thing))
Expand All @@ -89,10 +93,77 @@ SUBSYSTEM_DEF(vis_overlays)
var/rotation = dir2angle(old_dir) - dir2angle(new_dir)
var/list/overlays_to_remove = list()
for(var/i in thing.managed_vis_overlays - unique_vis_overlays)
if(istype(i, /obj/effect/overlay/vis/mob_alpha))
continue
var/obj/effect/overlay/vis/overlay = i
add_vis_overlay(thing, overlay.icon, overlay.icon_state, overlay.layer, overlay.plane, turn(overlay.dir, rotation), overlay.alpha, overlay.appearance_flags)
overlays_to_remove += overlay
for(var/i in thing.managed_vis_overlays & unique_vis_overlays)
if(istype(i, /obj/effect/overlay/vis/mob_alpha))
continue
var/obj/effect/overlay/vis/overlay = i
overlay.dir = turn(overlay.dir, rotation)
remove_vis_overlay(thing, overlays_to_remove)


/// just add_vis_overlay() but only visible to observers
/datum/controller/subsystem/vis_overlays/proc/add_obj_alpha(atom/movable/thing, icon=null, iconstate=null, alpha=150)
add_vis_overlay(thing, icon || thing.icon, iconstate || thing.icon_state, thing.layer+0.1, thing.plane, thing.dir, alpha=alpha, add_appearance_flags=RESET_ALPHA, invisibility=INVISIBILITY_OBSERVER)

/// identical to procs above, but mob alpha version
/datum/controller/subsystem/vis_overlays/proc/add_mob_alpha(atom/movable/thing, mob/target_mob, alpha=150, invisibility=INVISIBILITY_OBSERVER)
var/obj/effect/overlay/vis/mob_alpha/overlay
var/mob_alpha_id = "[REF(target_mob)][alpha][invisibility]"
overlay = mob_alpha_vis_overlays[mob_alpha_id]
if(!overlay)
overlay = _create_mob_alpha(FLY_LAYER, target_mob.plane, target_mob.dir, alpha, add_appearance_flags=RESET_ALPHA, invisibility=invisibility)
mob_alpha_vis_overlays[mob_alpha_id] = overlay
overlay.mob_alpha_id = mob_alpha_id
overlay.mob_owner_ref = "[REF(target_mob)]"
overlay.cut_overlays()
overlay.add_overlay(target_mob)

if(overlay in thing.vis_contents) // don't do this again
return overlay.mob_owner_ref

thing.vis_contents += overlay

// copy-pasta from the above
if(!isatom(thing))
return overlay.mob_owner_ref

if(!thing.managed_vis_overlays)
thing.managed_vis_overlays = list(overlay)
// RegisterSignal(thing, COMSIG_ATOM_DIR_CHANGE, PROC_REF(rotate_vis_overlay))
// mob alpha overlay doesn't support dir rotation
else
thing.managed_vis_overlays += overlay

return overlay.mob_owner_ref

/datum/controller/subsystem/vis_overlays/proc/remove_mob_alpha(atom/movable/thing, list/exception_mobs=list())
for(var/obj/effect/overlay/vis/mob_alpha/overlay in thing.managed_vis_overlays)
if(overlay.mob_owner_ref in exception_mobs)
continue
thing.vis_contents -= overlay
mob_alpha_vis_overlays -= overlay.mob_alpha_id
if(isatom(thing))
thing.managed_vis_overlays -= overlay
qdel(overlay)

if(isatom(thing) && !length(thing.managed_vis_overlays))
thing.managed_vis_overlays = null
// UnregisterSignal(thing, COMSIG_ATOM_DIR_CHANGE)

/datum/controller/subsystem/vis_overlays/proc/_create_mob_alpha(layer, plane, dir, alpha, add_appearance_flags, invisibility = -1)
var/obj/effect/overlay/vis/mob_alpha/overlay = new
overlay.icon = null
overlay.icon_state = null
overlay.layer = layer
overlay.plane = plane
overlay.dir = dir
overlay.alpha = alpha
overlay.appearance_flags |= add_appearance_flags
if(invisibility > -1)
overlay.invisibility = invisibility
return overlay
4 changes: 4 additions & 0 deletions code/game/objects/effects/forcefields.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@
name = "invisible blockade"
desc = "You're gonna be here awhile."
timeleft = 600

/obj/effect/forcefield/mime/Initialize(mapload, ntimeleft)
. = ..()
SSvis_overlays.add_obj_alpha(src, 'icons/turf/walls/snow_wall.dmi', "snow_wall-0")
5 changes: 5 additions & 0 deletions code/game/objects/effects/overlays.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
var/cache_expiration = 2 MINUTES // overlays which go unused for 2 minutes get cleaned up
vis_flags = VIS_INHERIT_ID|VIS_INHERIT_PLANE

/obj/effect/overlay/vis/mob_alpha
/// this separately exists because "mob_alpha_id" is to reference this single, but "mob_owner_ref" is to reference multiple things to a mob
var/mob_owner_ref
var/mob_alpha_id

/obj/effect/overlay/airlock_part
anchored = TRUE
plane = FLOAT_PLANE
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/implants/implant_stealth.dm
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/obj/structure/closet/cardboard/agent/Initialize(mapload)
. = ..()
go_invisible()

SSvis_overlays.add_obj_alpha(src)

/obj/structure/closet/cardboard/agent/open()
. = ..()
Expand Down
9 changes: 9 additions & 0 deletions code/game/objects/objs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -470,3 +470,12 @@
obj_flags ^= EMAGGED
else
obj_flags |= EMAGGED

/// shows mobs in its contents to ghosts. can be used to update
/obj/proc/update_mob_alpha()
if(!length(contents))
SSvis_overlays.remove_mob_alpha(src)
var/list/exception_mobs = list()
for(var/mob/each_mob in contents)
exception_mobs += SSvis_overlays.add_mob_alpha(src, each_mob)
SSvis_overlays.remove_mob_alpha(src, exception_mobs)
1 change: 1 addition & 0 deletions code/game/objects/structures/crates_lockers/closets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
add_overlay("[icon_door]_open")
else
add_overlay("[icon_state]_open")
update_mob_alpha()

/obj/structure/closet/proc/animate_door(var/closing = FALSE)
if(!door_anim_time)
Expand Down
1 change: 1 addition & 0 deletions code/modules/antagonists/heretic/influences.dm
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
GLOB.reality_smash_track.smashes += src
heretic_image = image(icon, src, real_icon_state, OBJ_LAYER)
generate_name()
SSvis_overlays.add_obj_alpha(src, 'icons/effects/heretic.dmi', "pierced_illusion")

/obj/effect/heretic_influence/Destroy()
GLOB.reality_smash_track.smashes -= src
Expand Down

0 comments on commit bc88a4e

Please sign in to comment.