From f419653c281d3b064cfaeadca5da3cfe5c981c6e Mon Sep 17 00:00:00 2001 From: actioninja Date: Thu, 19 Mar 2020 02:04:22 -0700 Subject: [PATCH] functionality --- code/__DEFINES/layers.dm | 28 ++++++++++ code/__DEFINES/lighting.dm | 5 ++ code/_onclick/hud/plane_master.dm | 51 +++++++++++++++++++ code/game/atoms_movable.dm | 31 +++++++++++ code/game/objects/items.dm | 1 + code/modules/lighting/emissive_blocker.dm | 44 ++++++++++++++++ .../mob/living/carbon/human/human_defines.dm | 2 + .../mob/living/carbon/monkey/monkey.dm | 1 + .../modules/mob/living/silicon/robot/robot.dm | 2 + code/modules/mob/mob_defines.dm | 2 + tgstation.dme | 1 + 11 files changed, 168 insertions(+) create mode 100644 code/modules/lighting/emissive_blocker.dm diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index e0a22667ac..b0c479aa37 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -4,11 +4,16 @@ #define CLICKCATCHER_PLANE -99 #define PLANE_SPACE -95 +#define PLANE_SPACE_RENDER_TARGET "PLANE_SPACE" #define PLANE_SPACE_PARALLAX -90 +#define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX" #define FLOOR_PLANE -2 +#define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE" #define GAME_PLANE -1 +#define GAME_PLANE_RENDER_TARGET "GAME_PLANE" #define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals +#define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE" #define SPACE_LAYER 1.8 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define @@ -78,20 +83,38 @@ #define MASSIVE_OBJ_LAYER 11 #define POINT_LAYER 12 +#define EMISSIVE_BLOCKER_PLANE 12 +#define EMISSIVE_BLOCKER_LAYER 12 +#define EMISSIVE_BLOCKER_RENDER_TARGET "*EMISSIVE_BLOCKER_PLANE" + +#define EMISSIVE_PLANE 13 +#define EMISSIVE_LAYER 13 +#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" + +#define EMISSIVE_UNBLOCKABLE_PLANE 14 +#define EMISSIVE_UNBLOCKABLE_LAYER 14 +#define EMISSIVE_UNBLOCKABLE_RENDER_TARGET "*EMISSIVE_UNBLOCKABLE_PLANE" + #define LIGHTING_PLANE 15 #define LIGHTING_LAYER 15 +#define LIGHTING_RENDER_TARGET "LIGHT_PLANE" #define ABOVE_LIGHTING_PLANE 16 #define ABOVE_LIGHTING_LAYER 16 +#define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE" #define FLOOR_OPENSPACE_PLANE 17 #define OPENSPACE_LAYER 17 +#define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE" #define BYOND_LIGHTING_PLANE 18 #define BYOND_LIGHTING_LAYER 18 +#define BYOND_LIGHTING_RENDER_TARGET "BYOND_LIGHTING_PLANE" #define CAMERA_STATIC_PLANE 19 #define CAMERA_STATIC_LAYER 19 +#define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE" + //HUD layer defines #define FULLSCREEN_PLANE 20 @@ -101,11 +124,16 @@ #define BLIND_LAYER 20.3 #define CRIT_LAYER 20.4 #define CURSE_LAYER 20.5 +#define FULLSCREEN_RENDER_TARGET "FULLSCREEN_PLANE" #define HUD_PLANE 21 #define HUD_LAYER 21 +#define HUD_RENDER_TARGET "HUD_PLANE" #define ABOVE_HUD_PLANE 22 #define ABOVE_HUD_LAYER 22 +#define ABOVE_HUD_RENDER_TARGET "ABOVE_HUD_PLANE" #define SPLASHSCREEN_LAYER 23 #define SPLASHSCREEN_PLANE 23 +#define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" + diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 89c702e605..5ba696b274 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -83,3 +83,8 @@ #define FLASH_LIGHT_DURATION 2 #define FLASH_LIGHT_POWER 3 #define FLASH_LIGHT_RANGE 3.8 + +/// Uses vis_overlays to leverage caching so that very few new items need to be made for the overlay. For anything that doesn't change outline or opaque area much or at all. +#define EMISSIVE_BLOCK_GENERIC 1 +/// Uses a dedicated render_target object to copy the entire appearance in real time to the blocking layer. For things that can change in appearance a lot from the base state, like humans. +#define EMISSIVE_BLOCK_UNIQUE 2 diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index b2bc05924c..7a8cc20d76 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -16,6 +16,7 @@ //Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. /obj/screen/plane_master/proc/backdrop(mob/mymob) +///Things rendered on "openspace"; holes in multi-z /obj/screen/plane_master/openspace name = "open space plane master" plane = FLOOR_OPENSPACE_PLANE @@ -38,12 +39,14 @@ /obj/screen/plane_master/proc/clear_filters() filters = list() +///Contains just the floor /obj/screen/plane_master/floor name = "floor plane master" plane = FLOOR_PLANE appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY +///Contains most things in the game world /obj/screen/plane_master/game_world name = "game world plane master" plane = GAME_PLANE @@ -57,12 +60,60 @@ remove_filter("ambient_occlusion") update_filters() +///Contains all lighting objects /obj/screen/plane_master/lighting name = "lighting plane master" plane = LIGHTING_PLANE blend_mode = BLEND_MULTIPLY mouse_opacity = MOUSE_OPACITY_TRANSPARENT +/obj/screen/plane_master/lighting/Initialize() + . = ..() + filters += filter(type="alpha", render_source=EMISSIVE_RENDER_TARGET, flags=MASK_INVERSE) + filters += filter(type="alpha", render_source=EMISSIVE_UNBLOCKABLE_RENDER_TARGET, flags=MASK_INVERSE) + +/** + * Things placed on this mask the lighting plane. Doesn't render directly. + * + * Gets masked by blocking plane. Use for things that you want blocked by + * mobs, items, etc. + */ +/obj/screen/plane_master/emissive + name = "emissive plane master" + plane = EMISSIVE_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = EMISSIVE_RENDER_TARGET + +/obj/screen/plane_master/emissive/Initialize() + . = ..() + filters += filter(type="alpha", render_source=EMISSIVE_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) + +/** + * Things placed on this always mask the lighting plane. Doesn't render directly. + * + * Always masks the light plane, isn't blocked by anything. Use for on mob glows, + * magic stuff, etc. + */ + +/obj/screen/plane_master/emissive_unblockable + name = "unblockable emissive plane master" + plane = EMISSIVE_UNBLOCKABLE_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = EMISSIVE_UNBLOCKABLE_RENDER_TARGET + +/** + * Things placed on this layer mask the emissive layer. Doesn't render directly + * + * You really shouldn't be directly using this, use atom helpers instead + */ +/obj/screen/plane_master/emissive_unblockable + name = "emissive mob plane master" + plane = EMISSIVE_BLOCKER_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = EMISSIVE_BLOCKER_RENDER_TARGET + +///Contains space parallax + /obj/screen/plane_master/parallax name = "parallax plane master" plane = PLANE_SPACE_PARALLAX diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9f1eb534a9..d8f54e9993 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -39,6 +39,37 @@ var/zfalling = FALSE + /// Either FALSE, [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE] + var/blocks_emissive = FALSE + ///Internal holder for emissive blocker object, do not use directly use blocks_emissive + var/atom/movable/emissive_blocker/em_block + + +/atom/movable/Initialize(mapload) + . = ..() + switch(blocks_emissive) + if(EMISSIVE_BLOCK_GENERIC) + update_emissive_block() + if(EMISSIVE_BLOCK_UNIQUE) + render_target = ref(src) + em_block = new(src, render_target) + vis_contents += em_block + +/atom/movable/Destroy() + QDEL_NULL(em_block) + return ..() + +/atom/movable/proc/update_emissive_block() + if(blocks_emissive != EMISSIVE_BLOCK_GENERIC) + return + if(length(managed_vis_overlays)) + for(var/a in managed_vis_overlays) + var/obj/effect/overlay/vis/vs + if(vs.plane == EMISSIVE_BLOCKER_PLANE) + SSvis_overlays.remove_vis_overlay(src, list(vs)) + break + SSvis_overlays.add_vis_overlay(src, icon, icon_state, EMISSIVE_BLOCKER_LAYER, EMISSIVE_BLOCKER_PLANE) + /atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction) if(!direction) direction = DOWN diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index e1d6101aa5..222b82d134 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -7,6 +7,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) /obj/item name = "item" icon = 'icons/obj/items_and_weapons.dmi' + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/item_state = null var/lefthand_file = 'icons/mob/inhands/items_lefthand.dmi' var/righthand_file = 'icons/mob/inhands/items_righthand.dmi' diff --git a/code/modules/lighting/emissive_blocker.dm b/code/modules/lighting/emissive_blocker.dm new file mode 100644 index 0000000000..b69a474009 --- /dev/null +++ b/code/modules/lighting/emissive_blocker.dm @@ -0,0 +1,44 @@ +/** + * Internal atom that copies an appearance on to the blocker plane + * + * Copies an appearance vis render_target and render_source on to the emissive blocking plane. + * This means that the atom in question will block any emissive sprites. + * This should only be used internally. If you are directly creating more of these, you're + * almost guaranteed to be doing something wrong. + */ +/atom/movable/emissive_blocker + name = "" + plane = EMISSIVE_BLOCKER_PLANE + layer = EMISSIVE_BLOCKER_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + //Why? + //render_targets copy the transform of the target as well, but vis_contents also applies the transform + //to what's in it. Applying RESET_TRANSFORM here makes vis_contents not apply the transform. + //Since only render_target handles transform we don't get any applied transform "stacking" + appearance_flags = RESET_TRANSFORM + +/atom/movable/emissive_blocker/Initialize(mapload, source) + . = ..() + verbs.Cut() //Cargo culting from lighting object, this maybe affects memory usage? + + render_source = source + +/atom/movable/emissive_blocker/ex_act(severity) + return FALSE + +/atom/movable/emissive_blocker/singularity_act() + return + +/atom/movable/emissive_blocker/singularity_pull() + return + +/atom/movable/emissive_blocker/blob_act() + return + +/atom/movable/emissive_blocker/onTransitZ() + return + +//Prevents people from moving these after creation, because they shouldn't be. +/atom/movable/emissive_blocker/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE) + if(harderforce) + return ..() diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm index d20c556c6c..68c312b19c 100644 --- a/code/modules/mob/living/carbon/human/human_defines.dm +++ b/code/modules/mob/living/carbon/human/human_defines.dm @@ -10,6 +10,8 @@ combat_flags = COMBAT_FLAGS_DEFAULT status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER + blocks_emissive = EMISSIVE_BLOCK_UNIQUE + //Hair colour and style var/hair_color = "000" var/hair_style = "Bald" diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 86b9826c12..d3e5941e4e 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -12,6 +12,7 @@ type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey gib_type = /obj/effect/decal/cleanable/blood/gibs unique_name = TRUE + blocks_emissive = EMISSIVE_BLOCK_UNIQUE bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey, /obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey) hud_type = /datum/hud/monkey diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index fd3bcf6598..4ef5993d2d 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -10,6 +10,8 @@ has_limbs = 1 hud_type = /datum/hud/robot + blocks_emissive = EMISSIVE_BLOCK_UNIQUE + var/custom_name = "" var/braintype = "Cyborg" var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of.. diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index fc202b29ad..bf9dad1bc7 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -8,6 +8,8 @@ pressure_resistance = 8 mouse_drag_pointer = MOUSE_ACTIVE_POINTER throwforce = 10 + blocks_emissive = EMISSIVE_BLOCK_GENERIC + var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE var/datum/mind/mind var/list/datum/action/actions = list() diff --git a/tgstation.dme b/tgstation.dme index b212fd39d0..dd25e05460 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2088,6 +2088,7 @@ #include "code\modules\library\lib_machines.dm" #include "code\modules\library\random_books.dm" #include "code\modules\library\soapstone.dm" +#include "code\modules\lighting\emissive_blocker.dm" #include "code\modules\lighting\lighting_area.dm" #include "code\modules\lighting\lighting_atom.dm" #include "code\modules\lighting\lighting_corner.dm"