Skip to content

Commit

Permalink
Merge pull request #530 from dwasint/i-can-see-god
Browse files Browse the repository at this point in the history
gods all seeing eye gazes down at me
  • Loading branch information
dwasint authored Nov 7, 2023
2 parents 31f31bd + 5775c4b commit 1198674
Show file tree
Hide file tree
Showing 19 changed files with 346 additions and 2 deletions.
1 change: 1 addition & 0 deletions code/__DEFINES/colors.dm
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
#define DEFAULT_HEX_COLOR_LEN 6

// Color filters
#define CHECK_LIGHT_OCCLUSION(turf) (turf.directional_opacity || turf.opacity)
/// Icon filter that creates ambient occlusion
#define AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA")
/// Icon filter that creates gaussian blur
Expand Down
4 changes: 4 additions & 0 deletions code/__DEFINES/layers.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define FLOOR_PLANE -11

#define WALL_PLANE -10
#define WALL_RENDER_TARGET "*WALL_PLANE" //monkestation edit
#define GAME_PLANE -9
#define GAME_PLANE_FOV_HIDDEN -8
#define GAME_PLANE_UPPER -7
Expand Down Expand Up @@ -85,6 +86,9 @@

///---------------- MISC -----------------------

/// Shadowcasting
#define SHADOWCASTING_PLANE 18 // monkestation edit

///Pipecrawling images
#define PIPECRAWL_IMAGES_PLANE 20

Expand Down
3 changes: 2 additions & 1 deletion code/__DEFINES/subsystems.dm
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@
#define INIT_ORDER_STICKY_BAN -10
#define INIT_ORDER_LIGHTING -20
#define INIT_ORDER_OUTDOOR_EFFECTS -21 //monkestation addition
#define INIT_ORDER_SHUTTLE -22 //monkestation edit -21 > -22
#define INIT_ORDER_SHADOWCASTING -22 // monkestation addition
#define INIT_ORDER_SHUTTLE -23 //monkestation edit -21 > -23
#define INIT_ORDER_MINOR_MAPPING -40
#define INIT_ORDER_PATH -50
#define INIT_ORDER_EXPLOSIONS -69
Expand Down
23 changes: 23 additions & 0 deletions code/__HELPERS/~monkestation-helpers/triangles.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// A list that caches base appearances of triangles for later access.
GLOBAL_LIST_EMPTY(triangle_appearances)

/// Returns a mutable appearance of a triangle of the given points, and caches it for later use
/proc/get_triangle_appearance(x1,y1, x2,y2, x3,y3, icon_size = 32, icon = 'monkestation/code/modules/shadowcasting/icons/geometric.dmi', icon_state = "triangle")
var/key = "[x1]_[y2]_[x2]_[y2]_[x3]_[y3]_[icon_size]_[icon]_[icon_state]"
if(GLOB.triangle_appearances[key])
return GLOB.triangle_appearances[key]
var/mutable_appearance/triangle_appearance = mutable_appearance(icon, icon_state)
triangle_appearance.transform = transform_triangle(x1,y1, x2,y2, x3,y3, icon_size)
GLOB.triangle_appearances[key] = triangle_appearance
return triangle_appearance

/// Returns a matrix which when applied to a proper triangle image, creates an arbitrary triangle
/proc/transform_triangle(x1, y1, x2, y2, x3, y3, icon_size = 32)
var/i = 1/icon_size
var/a = (x3*i)-(x2*i)
var/b = -(x2*i)+(x1*i)
var/c = (x3*0.5)+(x1*0.5)
var/d = (y1*i)-(y2*i)
var/e = -(y2*i)+(y3*i)
var/f = (y1*0.5)+(y3*0.5)
return matrix(a,b,c,e,d,f)
17 changes: 17 additions & 0 deletions code/_onclick/hud/rendering/plane_master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
name = "Wall"
documentation = "Holds all walls. We render this onto the game world. Separate so we can use this + space and floor planes as a guide for where byond blackness is NOT."
plane = WALL_PLANE
render_target = WALL_RENDER_TARGET // monkestation edit
render_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE)

/atom/movable/screen/plane_master/wall/Initialize(mapload, datum/plane_master_group/home, offset)
Expand Down Expand Up @@ -660,3 +661,19 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR
render_relay_planes = list(RENDER_PLANE_MASTER)
allows_offsetting = FALSE

/atom/movable/screen/plane_master/shadowcasting
name = "Shadowcasting"
documentation = "Holds shadowcasting images so you can see fancy shadows where your vision can't reach."
plane = SHADOWCASTING_PLANE
appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
start_hidden = TRUE

/atom/movable/screen/plane_master/shadowcasting/show_to(mob/mymob)
. = ..()
alpha = 96
add_filter("wall_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(WALL_RENDER_TARGET, offset), flags = MASK_INVERSE))
var/blurriness = 3
add_filter("blur", 2, gauss_blur_filter(size = blurriness))

1 change: 1 addition & 0 deletions code/datums/components/chasm.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/// List of refs to falling objects -> how many levels deep we've fallen
var/static/list/falling_atoms = list()
var/static/list/forbidden_types = typecacheof(list(
/atom/movable/shadowcasting_holder,
/obj/singularity,
/obj/energy_ball,
/obj/narsie,
Expand Down
2 changes: 1 addition & 1 deletion code/game/turfs/change_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(

/turf/proc/empty(turf_type=/turf/open/space, baseturf_type, list/ignore_typecache, flags)
// Remove all atoms except observers, landmarks, docking ports
var/static/list/ignored_atoms = typecacheof(list(/mob/dead, /obj/effect/landmark, /obj/docking_port))
var/static/list/ignored_atoms = typecacheof(list(/atom/movable/shadowcasting_holder, /mob/dead, /obj/effect/landmark, /obj/docking_port))
var/list/allowed_contents = typecache_filter_list_reverse(get_all_contents_ignoring(ignore_typecache), ignored_atoms)
allowed_contents -= src
for(var/i in 1 to allowed_contents.len)
Expand Down
3 changes: 3 additions & 0 deletions code/game/turfs/turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ GLOBAL_LIST_EMPTY(station_turfs)
///Lazylist of movable atoms providing opacity sources.
var/list/atom/movable/opacity_sources

///Image used for shadowcasting
var/image/shadowcasting_image

///the holodeck can load onto this turf if TRUE
var/holodeck_compatible = FALSE

Expand Down
5 changes: 5 additions & 0 deletions code/modules/lighting/lighting_turf.dm
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@
if(!new_area.lighting_effects && old_area.lighting_effects && space_lit)
overlays += GLOB.fullbright_overlays[GET_TURF_PLANE_OFFSET(src) + 1]

//This, is also very expensive
for(var/turf/turf in range(world.view, src))
turf.check_shadowcasting_update()


/turf/proc/generate_missing_corners()
if (!lighting_corner_NE)
lighting_corner_NE = new/datum/lighting_corner(src, NORTH|EAST)
Expand Down
2 changes: 2 additions & 0 deletions code/modules/mob/living/living_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD)
pressure_resistance = 10

shadow_caster = TRUE

hud_type = /datum/hud/living

///Badminnery resize
Expand Down
2 changes: 2 additions & 0 deletions code/modules/mob/login.dm
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
SEND_SIGNAL(client, COMSIG_CLIENT_MOB_LOGIN, src)
client.init_verbs()

update_shadowcasting()

AddElement(/datum/element/weather_listener, /datum/weather/ash_storm, ZTRAIT_ASHSTORM, GLOB.ash_storm_sounds)

SEND_GLOBAL_SIGNAL(COMSIG_GLOB_MOB_LOGGED_IN, src)
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/mob.dm
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
initialize_actionspeed()
update_movespeed(TRUE)
become_hearing_sensitive()
update_shadowcasting()
log_mob_tag("CREATED: [key_name(src)] \[[type]\]")

/**
Expand Down
15 changes: 15 additions & 0 deletions monkestation/code/modules/shadowcasting/__shadow_vars.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/mob
///Should the mob use the shadowcasting component when a client is logged to it?
var/shadow_caster = FALSE


/mob/proc/update_shadowcasting()
if(!shadow_caster || !client)
return
for(var/atom/movable/screen/plane_master/plane_master as anything in hud_used.get_true_plane_masters(SHADOWCASTING_PLANE))
plane_master.alpha = 96
for(var/atom/movable/screen/plane_master/plane_master as anything in hud_used.get_true_plane_masters(SHADOWCASTING_PLANE))
plane_master.add_filter("blur", 2, gauss_blur_filter(size = 3))
var/datum/component/shadowcasting = GetComponent(/datum/component/shadowcasting)
if(!shadowcasting)
AddComponent(/datum/component/shadowcasting)
42 changes: 42 additions & 0 deletions monkestation/code/modules/shadowcasting/_shadow_controller.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* This subsystem updates shadowcasting overlays for updates not caused by mob movement.
*/
SUBSYSTEM_DEF(shadowcasting)
name = "Shadowcasting"
wait = 2
init_order = INIT_ORDER_SHADOWCASTING
flags = SS_TICKER
var/static/list/turf/turf_queue = list()

/datum/controller/subsystem/shadowcasting/stat_entry(msg)
msg = "T:[length(turf_queue)]|"
return ..()

/datum/controller/subsystem/shadowcasting/Initialize()
fire(FALSE, TRUE)
initialized = TRUE

return SS_INIT_SUCCESS

/datum/controller/subsystem/shadowcasting/fire(resumed, init_tick_checks)
MC_SPLIT_TICK_INIT(3)
if(!init_tick_checks)
MC_SPLIT_TICK

var/list/queue = turf_queue
var/i = 0
for (i in 1 to length(queue))
var/turf/shadow_source = queue[i]

shadow_source.update_shadowcasting()

if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
queue.Cut(1, i+1)

/datum/controller/subsystem/shadowcasting/Recover()
initialized = SSshadowcasting.initialized
return ..()
Binary file not shown.
95 changes: 95 additions & 0 deletions monkestation/code/modules/shadowcasting/shadow_component.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// lots of ctrl c ctrl v from fov component no fucks given
/datum/component/shadowcasting
/// Whether we are applying the masks now or not
var/applied_shadow = FALSE
/// Atom that shows shadowcasting overlays
var/atom/movable/shadowcasting_holder/visual_shadow

/datum/component/shadowcasting/Initialize()
. = ..()
if(!ismob(parent))
return COMPONENT_INCOMPATIBLE
var/mob/mob_parent = parent
var/client/parent_client = mob_parent.client
if(!parent_client) //Love client volatility!!
qdel(src) //no QDEL hint for components, and we dont want this to print a warning regarding bad component application
return

for(var/atom/movable/screen/plane_master/plane_master as anything in mob_parent.hud_used.get_true_plane_masters(SHADOWCASTING_PLANE))
plane_master.unhide_plane(mob_parent)

visual_shadow = new
update_shadow()

/datum/component/shadowcasting/RegisterWithParent()
. = ..()
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(update_shadow))
RegisterSignal(parent, COMSIG_MOB_RESET_PERSPECTIVE, PROC_REF(update_shadow))
RegisterSignal(parent, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(update_shadow))
RegisterSignal(parent, COMSIG_MOB_LOGOUT, PROC_REF(mob_logout))

/datum/component/shadowcasting/UnregisterFromParent()
. = ..()
UnregisterSignal(parent, list(
COMSIG_MOVABLE_MOVED,
COMSIG_MOB_RESET_PERSPECTIVE,
COMSIG_MOB_SIGHT_CHANGE,
COMSIG_MOB_LOGOUT,
))

/datum/component/shadowcasting/Destroy(force, silent)
var/mob/living/mob_parent = parent
for(var/atom/movable/screen/plane_master/plane_master as anything in mob_parent.hud_used.get_true_plane_masters(SHADOWCASTING_PLANE))
plane_master.hide_plane(mob_parent)

if(applied_shadow)
remove_shadow()
if(visual_shadow)
QDEL_NULL(visual_shadow)
return ..()

/datum/component/shadowcasting/proc/update_shadow()
SIGNAL_HANDLER
var/mob/living/parent_mob = parent
var/client/parent_client = parent_mob.client
if(!parent_client) //Love client volatility!!
return

var/user_turf = get_turf(parent_mob)
var/atom/top_most_atom = get_atom_on_turf(parent_mob)
var/user_extends_eye = parent_client.eye != top_most_atom
var/user_sees_turfs = parent_mob.sight & SEE_TURFS
var/user_blind = parent_mob.sight & BLIND

var/should_apply_mask = user_turf && !user_extends_eye && !user_sees_turfs && !user_blind
if(should_apply_mask)
add_shadow(user_turf)
else
remove_shadow()

/datum/component/shadowcasting/proc/add_shadow(turf/mob_turf)
var/mob/parent_mob = parent
var/client/parent_client = parent_mob.client
if(!parent_client) //Love client volatility!!
return
applied_shadow = TRUE
if(!mob_turf.shadowcasting_image)
mob_turf.update_shadowcasting_image()
visual_shadow.reflector.overlays = null
visual_shadow.reflector.overlays += mob_turf.shadowcasting_image
visual_shadow.loc = get_turf(parent_mob)
parent_client.images |= visual_shadow.reflector

/datum/component/shadowcasting/proc/remove_shadow()
var/mob/parent_mob = parent
var/client/parent_client = parent_mob.client
if(!parent_client) //Love client volatility!!
return
applied_shadow = FALSE
visual_shadow.moveToNullspace()
parent_client.images -= visual_shadow.reflector

/// When a mob logs out, delete the component
/datum/component/shadowcasting/proc/mob_logout(mob/source)
SIGNAL_HANDLER
qdel(src)
18 changes: 18 additions & 0 deletions monkestation/code/modules/shadowcasting/shadow_holder.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/atom/movable/shadowcasting_holder
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
plane = SHADOWCASTING_PLANE
animate_movement = NO_STEPS
invisibility = INVISIBILITY_LIGHTING
anchored = TRUE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
var/image/reflector

/atom/movable/shadowcasting_holder/Initialize(mapload)
. = ..()
reflector = new()
reflector.override = TRUE
reflector.loc = src

/atom/movable/shadowcasting_holder/Destroy(force)
. = ..()
reflector = null
Loading

0 comments on commit 1198674

Please sign in to comment.