From bc8bf7c7d7362270ee6a07341a06eeb19ac9417e Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 28 Nov 2023 21:43:54 -0500 Subject: [PATCH 001/144] oh my god my EYES --- code/__DEFINES/dcs/signals/signals_huds.dm | 2 + .../dcs/signals/signals_mob/signals_mob.dm | 3 - code/__DEFINES/hud.dm | 5 + code/__DEFINES/layers.dm | 65 ++- code/__DEFINES/lighting.dm | 45 +- code/__DEFINES/sight.dm | 5 +- code/__DEFINES/traits.dm | 6 + code/__HELPERS/_planes.dm | 49 ++ code/__HELPERS/cmp.dm | 3 + code/__HELPERS/colors.dm | 31 ++ code/__HELPERS/filters.dm | 6 + code/__HELPERS/unsorted.dm | 1 - code/_onclick/hud/fullscreen.dm | 2 +- code/_onclick/hud/hud.dm | 54 +++ code/_onclick/hud/plane_master.dm | 456 ++++++++++++++++++ code/controllers/subsystem/mapping.dm | 24 + code/datums/actions/mobs/adjust_vision.dm | 73 +++ code/datums/brain_damage/imaginary_friend.dm | 2 - code/datums/datum.dm | 63 +++ code/datums/status_effects/debuffs/debuffs.dm | 1 - code/datums/traits/good.dm | 2 +- code/game/atoms.dm | 15 - code/game/machinery/camera/camera.dm | 5 +- .../machinery/computer/camera_advanced.dm | 1 - code/game/objects/items.dm | 11 + code/game/turfs/openspace/openspace.dm | 1 + code/modules/antagonists/blob/blob_mobs.dm | 6 +- code/modules/antagonists/blob/overmind.dm | 6 +- .../antagonists/bloodsuckers/bloodsuckers.dm | 5 +- .../structures/bloodsucker_life.dm | 3 +- .../clock_items/wraith_spectacles.dm | 4 - .../clockcult/clock_mobs/_eminence.dm | 6 +- .../antagonists/demon/general_powers.dm | 5 +- code/modules/antagonists/devil/imp/imp.dm | 6 +- .../antagonists/disease/disease_mob.dm | 7 +- .../eldritch_cult/eldritch_items.dm | 3 +- code/modules/antagonists/horror/horror.dm | 5 +- code/modules/antagonists/morph/morph.dm | 6 +- code/modules/antagonists/revenant/revenant.dm | 10 +- .../revenant/revenant_abilities.dm | 11 +- .../antagonists/slaughter/slaughter.dm | 5 +- code/modules/cargo/bounties/special.dm | 2 +- code/modules/clothing/clothing.dm | 2 +- code/modules/clothing/glasses/_glasses.dm | 44 +- .../clothing/glasses/engine_goggles.dm | 10 +- code/modules/clothing/glasses/hud.dm | 21 +- .../mining/lavaland/necropolis_chests.dm | 6 +- code/modules/mining/minebot.dm | 11 +- code/modules/mob/camera/camera.dm | 5 +- code/modules/mob/dead/observer/observer.dm | 19 +- code/modules/mob/living/carbon/alien/alien.dm | 3 +- code/modules/mob/living/carbon/carbon.dm | 84 ++-- .../mob/living/carbon/human/inventory.dm | 4 +- .../human/species_types/shadowpeople.dm | 4 +- .../carbon/human/species_types/zombies.dm | 2 +- code/modules/mob/living/living.dm | 4 +- code/modules/mob/living/living_defines.dm | 1 - code/modules/mob/living/silicon/ai/ai.dm | 1 - code/modules/mob/living/silicon/ai/life.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 19 +- code/modules/mob/living/silicon/silicon.dm | 1 - .../mob/living/simple_animal/constructs.dm | 6 +- .../living/simple_animal/eldritch_demons.dm | 6 +- .../mob/living/simple_animal/friendly/cat.dm | 2 - .../mob/living/simple_animal/friendly/dog.dm | 6 +- .../simple_animal/friendly/drone/_drone.dm | 6 +- .../simple_animal/friendly/farm_animals.dm | 3 - .../mob/living/simple_animal/friendly/fox.dm | 1 - .../living/simple_animal/friendly/mouse.dm | 2 - .../living/simple_animal/friendly/penguin.dm | 1 - .../simple_animal/guardian/types/ranged.dm | 28 +- .../mob/living/simple_animal/hostile/alien.dm | 6 +- .../mob/living/simple_animal/hostile/bear.dm | 1 - .../living/simple_animal/hostile/eyeballs.dm | 4 + .../simple_animal/hostile/giant_spider.dm | 3 +- .../hostile/jungle/_jungle_mobs.dm | 6 +- .../simple_animal/hostile/killertomato.dm | 1 - .../simple_animal/hostile/megafauna/legion.dm | 4 + .../hostile/mining_mobs/hivelord.dm | 7 +- .../hostile/mining_mobs/mining_mobs.dm | 6 +- .../mob/living/simple_animal/hostile/rat.dm | 2 - .../living/simple_animal/hostile/regalrat.dm | 7 +- .../simple_animal/hostile/retaliate/bat.dm | 2 - .../hostile/retaliate/trianglespider.dm | 2 - .../living/simple_animal/hostile/skeleton.dm | 6 +- .../living/simple_animal/hostile/smspider.dm | 8 +- .../simple_animal/hostile/space_dragon.dm | 2 - .../living/simple_animal/hostile/statue.dm | 8 +- .../simple_animal/hostile/venus_human_trap.dm | 5 +- .../mob/living/simple_animal/simple_animal.dm | 4 +- code/modules/mob/mob.dm | 30 +- code/modules/mob/mob_defines.dm | 20 +- code/modules/mob/mob_helpers.dm | 5 + code/modules/mob/status_procs.dm | 28 ++ .../xenobiology/crossbreeding/_structures.dm | 2 +- code/modules/shuttle/navigation_computer.dm | 5 +- .../shuttle_creation/shuttle_creator_eye.dm | 5 +- .../spells/spell_types/self/night_vision.dm | 39 -- code/modules/surgery/organs/eyes.dm | 88 +++- yogstation.dme | 4 +- .../game/gamemodes/shadowling/shadowling.dm | 2 +- .../game/gamemodes/vampire/vampire_bat.dm | 2 - .../shadowling/shadowling_abilities.dm | 48 +- .../antagonists/slaughter/slaughter.dm | 2 - .../code/modules/clothing/glasses/_glasses.dm | 3 +- yogstation/code/modules/guardian/guardian.dm | 1 - .../carbon/human/species_types/darkspawn.dm | 2 +- .../human/species_types/preternis/organs.dm | 55 ++- .../carbon/human/species_types/szlachta.dm | 2 +- yogstation/code/modules/mob/living/living.dm | 2 +- .../surgery/organs/shadowling_organs.dm | 4 +- 111 files changed, 1337 insertions(+), 423 deletions(-) create mode 100644 code/__DEFINES/dcs/signals/signals_huds.dm create mode 100644 code/__HELPERS/_planes.dm create mode 100644 code/datums/actions/mobs/adjust_vision.dm delete mode 100644 code/modules/spells/spell_types/self/night_vision.dm diff --git a/code/__DEFINES/dcs/signals/signals_huds.dm b/code/__DEFINES/dcs/signals/signals_huds.dm new file mode 100644 index 000000000000..50e3069a6149 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_huds.dm @@ -0,0 +1,2 @@ +/// Sent from /datum/hud/proc/eye_z_changed() : (old_offset, new_offset) +#define COMSIG_HUD_OFFSET_CHANGED "hud_offset_changed" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm index 14d26b0ac454..4423bfff8cc7 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob.dm @@ -80,9 +80,6 @@ #define COMSIG_MOB_SIGHT_CHANGE "mob_sight_changed" ///from base of mob/set_invis_see(): (new_invis, old_invis) #define COMSIG_MOB_SEE_INVIS_CHANGE "mob_see_invis_change" -///from base of mob/set_see_in_dark(): (new_range, old_range) -#define COMSIG_MOB_SEE_IN_DARK_CHANGE "mob_see_in_dark_change" - ///from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone, blocked, wound_bonus, bare_wound_bonus, sharpness, attack_direction) #define COMSIG_MOB_APPLY_DAMAGE "mob_apply_damage" diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index fdcc04a03b8f..900b77f28848 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -233,3 +233,8 @@ #define SCRN_OBJ_INSERT_FIRST "first" /// The filter name for the hover outline #define HOVER_OUTLINE_FILTER "hover_outline" +// Plane group keys, used to group swaths of plane masters that need to appear in subwindows +/// The primary group, holds everything on the main window +#define PLANE_GROUP_MAIN "main" +/// A secondary group, used when a client views a generic window +#define PLANE_GROUP_POPUP_WINDOW(screen) "popup-[REF(screen)]" diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 3ce945e5eecc..c8598014fce9 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -1,6 +1,9 @@ //Defines for atom layers and planes //KEEP THESE IN A NICE ACSCENDING ORDER, PLEASE +//NEVER HAVE ANYTHING BELOW THIS PLANE ADJUST IF YOU NEED MORE SPACE +#define LOWEST_EVER_PLANE -100 + #define CLICKCATCHER_PLANE -99 #define PLANE_SPACE -95 @@ -8,13 +11,20 @@ #define PLANE_SPACE_PARALLAX -90 #define PLANE_SPACE_PARALLAX_RENDER_TARGET "PLANE_SPACE_PARALLAX" +#define GRAVITY_PULSE_PLANE -89 +#define GRAVITY_PULSE_RENDER_TARGET "*GRAVPULSE_RENDER_TARGET" + #define SINGULARITY_EFFECT_PLANE -80 #define SINGULARITY_RENDER_TARGET "*SINGULARITY_EFFECTS_PLANE" -#define FLOOR_PLANE -2 +#define RENDER_PLANE_TRANSPARENT -12 //Transparent plane that shows openspace underneath the floor +#define TRANSPARENT_FLOOR_PLANE -5 +#define FLOOR_PLANE -4 #define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE" -#define GAME_PLANE -1 +#define WALL_PLANE -3 +#define GAME_PLANE -2 #define GAME_PLANE_RENDER_TARGET "GAME_PLANE" +#define WALL_PLANE_UPPER -1 #define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals #define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE" @@ -99,6 +109,16 @@ #define EMISSIVE_LAYER 13 #define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" +/// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas. +#define EMISSIVE_RENDER_PLATE 14 +#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" + +// Ensures all the render targets that point at the emissive plate layer correctly +#define EMISSIVE_Z_BELOW_LAYER 1 +#define EMISSIVE_FLOOR_LAYER 2 +#define EMISSIVE_SPACE_LAYER 3 +#define EMISSIVE_WALL_LAYER 4 + #define EMISSIVE_UNBLOCKABLE_PLANE 14 #define EMISSIVE_UNBLOCKABLE_LAYER 14 #define EMISSIVE_UNBLOCKABLE_RENDER_TARGET "*EMISSIVE_UNBLOCKABLE_PLANE" @@ -109,11 +129,16 @@ #define RAD_TEXT_LAYER 15.1 - #define O_LIGHTING_VISUAL_PLANE 16 #define O_LIGHTING_VISUAL_LAYER 16 #define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" +#define RENDER_PLANE_LIGHTING 15 +/// Masks the lighting plane with turfs, so we never light up the void +/// Failing that, masks emissives and the overlay lighting plane +#define LIGHT_MASK_PLANE 16 +#define LIGHT_MASK_RENDER_TARGET "*LIGHT_MASK_PLANE" + #define ABOVE_LIGHTING_PLANE 200 //things that should render ignoring lightning #define ABOVE_LIGHTING_LAYER 17 #define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE" @@ -156,11 +181,45 @@ #define SPLASHSCREEN_PLANE 23 #define SPLASHSCREEN_RENDER_TARGET "SPLASHSCREEN_PLANE" +/// This plane master will temporarially remove relays to all other planes +/// Allows us to retain the effects of a plane while cutting off the changes it makes +#define PLANE_CRITICAL_NO_RELAY (1<<1) +/// We assume this plane master has a render target starting with *, it'll be removed, forcing it to render in place +#define PLANE_CRITICAL_CUT_RENDER (1<<2) + +#define PLANE_CRITICAL_FUCKO_PARALLAX (PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_RELAY|PLANE_CRITICAL_CUT_RENDER) //-------------------- Rendering --------------------- +//Plane master critical flags +//Describes how different plane masters behave when they are being culled for performance reasons +/// This plane master will not go away if its layer is culled. useful for preserving effects +#define PLANE_CRITICAL_DISPLAY (1<<0) + #define RENDER_PLANE_GAME 100 #define RENDER_PLANE_NON_GAME 101 +///Slightly above the game plane but does not catch mouse clicks. Useful for certain visuals that should be clicked through, like seethrough trees +#define SEETHROUGH_PLANE -3 +#define ABOVE_GAME_PLANE -2 + +#define RENDER_PLANE_GAME_WORLD -1 + +#define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it + +#define AREA_PLANE 2 +#define MASSIVE_OBJ_PLANE 3 +#define GHOST_PLANE 4 +#define POINT_PLANE 5 + +#define RENDER_PLANE_MASTER 110 + +// Lummox I swear to god I will find you +// NOTE! You can only ever have planes greater then -10000, if you add too many with large offsets you will brick multiz +// Same can be said for large multiz maps. Tread carefully mappers +#define HIGHEST_EVER_PLANE RENDER_PLANE_MASTER +/// The range unique planes can be in +#define PLANE_RANGE (HIGHEST_EVER_PLANE - LOWEST_EVER_PLANE) + ///1000 is an unimportant number, it's just to normalize copied layers #define RADIAL_CONTENT_LAYER 1000 diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 57271b6bcdee..a377464d4248 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -56,12 +56,16 @@ ///How many tiles standard fires glow. #define LIGHT_RANGE_FIRE 3 -#define LIGHTING_PLANE_ALPHA_VISIBLE 255 -#define LIGHTING_PLANE_ALPHA_NV_TRAIT 245 -#define LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE 192 -/// For lighting alpha, small amounts lead to big changes. even at 128 its hard to figure out what is dark and what is light, at 64 you almost can't even tell. -#define LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE 128 -#define LIGHTING_PLANE_ALPHA_INVISIBLE 0 +// Lighting cutoff defines +// These are a percentage of how much darkness to cut off (in rgb) +#define LIGHTING_CUTOFF_VISIBLE 0 +#define LIGHTING_CUTOFF_REAL_LOW 4.5 +#define LIGHTING_CUTOFF_MEDIUM 15 +#define LIGHTING_CUTOFF_HIGH 30 +#define LIGHTING_CUTOFF_FULLBRIGHT 100 + +/// What counts as being able to see in the dark +#define LIGHTING_NIGHTVISION_THRESHOLD 10 //lighting area defines /// dynamic lighting disabled (area stays at full brightness) @@ -114,3 +118,32 @@ do { \ source.lum_b = 1; \ }; \ } while (FALSE) + +// Emissive blocking. +/// 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 0 +/// 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 1 +/// Don't block any emissives. Useful for things like, pieces of paper? +#define EMISSIVE_BLOCK_NONE 2 + + +#define _EMISSIVE_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, val,val,val,0) +/// The color matrix applied to all emissive overlays. Should be solely dependent on alpha and not have RGB overlap with [EM_BLOCK_COLOR]. +#define EMISSIVE_COLOR _EMISSIVE_COLOR(1) +/// A globaly cached version of [EMISSIVE_COLOR] for quick access. +GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR) + +#define _EM_BLOCK_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,val, 0,0,0,0) +/// The color matrix applied to all emissive blockers. Should be solely dependent on alpha and not have RGB overlap with [EMISSIVE_COLOR]. +#define EM_BLOCK_COLOR _EM_BLOCK_COLOR(1) +/// A globaly cached version of [EM_BLOCK_COLOR] for quick access. +GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR) + +/// A set of appearance flags applied to all emissive and emissive blocker overlays. +/// KEEP_APART to prevent parent hooking, KEEP_TOGETHER for children, and we reset the color and alpha of our parent so nothing gets overriden +#define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_ALPHA) +/// The color matrix used to mask out emissive blockers on the emissive plane. Alpha should default to zero, be solely dependent on the RGB value of [EMISSIVE_COLOR], and be independant of the RGB value of [EM_BLOCK_COLOR]. +#define EM_MASK_MATRIX list(0,0,0,1/3, 0,0,0,1/3, 0,0,0,1/3, 0,0,0,0, 1,1,1,0) +/// A globaly cached version of [EM_MASK_MATRIX] for quick access. +GLOBAL_LIST_INIT(em_mask_matrix, EM_MASK_MATRIX) diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 862c851f187f..7952d9addd21 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -28,5 +28,8 @@ #define VISOR_TINT (1<<1) #define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses #define VISOR_DARKNESSVIEW (1<<3) -#define VISOR_INVISVIEW (1<<4) +#define VISOR_INVISVIEW (1<<3) +/// Bitfield of sight flags that show THINGS but no lighting +/// Since lighting is an underlay on turfs, this is everything but that +#define SEE_AVOID_TURF_BLACKNESS (SEE_MOBS|SEE_OBJS) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 0cdc86824d08..e812b802fcbd 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -492,3 +492,9 @@ #define TRAIT_BEING_BLADE_SHIELDED "being_blade_shielded" /// things with this trait are treated as having no access in /obj/proc/check_access(obj/item) #define TRAIT_ALWAYS_NO_ACCESS "alwaysnoaccess" +/// Gives us Night vision +#define TRAIT_TRUE_NIGHT_VISION "true_night_vision" +/// Gives us turf vision through walls and slight night vision +#define TRAIT_MESON_VISION "meson_vision" +/// Ignores darkness for hearing +#define TRAIT_HEAR_THROUGH_DARKNESS "hear_through_darkness" diff --git a/code/__HELPERS/_planes.dm b/code/__HELPERS/_planes.dm new file mode 100644 index 000000000000..c9d8c8de21cb --- /dev/null +++ b/code/__HELPERS/_planes.dm @@ -0,0 +1,49 @@ +/// Takes a plane to offset, and the multiplier to use, and well, does the offsetting +/// Respects a blacklist we use to remove redundant plane masters, such as hud objects +#define GET_NEW_PLANE(new_value, multiplier) (SSmapping.plane_offset_blacklist?["[new_value]"] ? new_value : (new_value) - (PLANE_RANGE * (multiplier))) +/// Takes a render target and an offset, returns a canonical render target string for it +#define OFFSET_RENDER_TARGET(render_target, offset) (_OFFSET_RENDER_TARGET(render_target, SSmapping.render_offset_blacklist?["[render_target]"] ? 0 : offset)) +/// Helper macro for the above +/// Honestly just exists to make the pattern of render target strings more readable +#define _OFFSET_RENDER_TARGET(render_target, offset) ("[(render_target)] #[(offset)]") +/// Takes a plane, returns TRUE if it is of critical priority, FALSE otherwise +#define PLANE_IS_CRITICAL(plane) ((SSmapping.plane_to_offset) ? !!SSmapping.critical_planes["[plane]"] : FALSE) +/// Implicit plane set. We take the turf from the object we're changing the plane of, and use ITS z as a spokesperson for our plane value +#define SET_PLANE_IMPLICIT(thing, new_value) SET_PLANE_EXPLICIT(thing, new_value, thing) +/// Takes a plane, returns the canonical, unoffset plane it represents +#define PLANE_TO_TRUE(plane) ((SSmapping.plane_offset_to_true) ? SSmapping.plane_offset_to_true["[plane]"] : plane) +/// Takes a plane, returns the offset it uses +#define PLANE_TO_OFFSET(plane) ((SSmapping.plane_to_offset) ? SSmapping.plane_to_offset["[plane]"] : plane) +/// Takes a z reference that we are unsure of, sanity checks it +/// Returns either its offset, or 0 if it's not a valid ref +/// Will return the reference's PLANE'S offset if we can't get anything out of the z level. We do our best +#define GET_TURF_PLANE_OFFSET(z_reference) ((SSmapping.max_plane_offset && isatom(z_reference)) ? (z_reference.z ? GET_Z_PLANE_OFFSET(z_reference.z) : PLANE_TO_OFFSET(z_reference.plane)) : 0) +/// Essentially just an unsafe version of GET_TURF_PLANE_OFFSET() +/// Takes a z value we returns its offset with a list lookup +/// Will runtime during parts of init. Be careful :) +#define GET_Z_PLANE_OFFSET(z) (SSmapping.z_level_to_plane_offset[z]) +/// Takes a true plane, returns the offset planes that would canonically represent it +#define TRUE_PLANE_TO_OFFSETS(plane) ((SSmapping.true_to_offset_planes) ? SSmapping.true_to_offset_planes["[plane]"] : list(plane)) +// This is an unrolled and optimized version of SET_PLANE, for use anywhere where you are unsure of a source's "turfness" +// We do also try and guess at what the thing's z level is, even if it's not a z +// The plane is cached to allow for fancy stuff to be eval'd once, rather then often +#define SET_PLANE_EXPLICIT(thing, new_value, source) \ + do {\ + if(SSmapping.max_plane_offset) {\ + var/_cached_plane = new_value;\ + var/turf/_our_turf = get_turf(source);\ + if(_our_turf){\ + thing.plane = GET_NEW_PLANE(_cached_plane, GET_Z_PLANE_OFFSET(_our_turf.z));\ + }\ + else if(source) {\ + thing.plane = GET_NEW_PLANE(_cached_plane, PLANE_TO_OFFSET(source.plane));\ + }\ + else {\ + thing.plane = _cached_plane;\ + }\ + }\ + else {\ + thing.plane = new_value;\ + }\ + }\ + while (FALSE) diff --git a/code/__HELPERS/cmp.dm b/code/__HELPERS/cmp.dm index 73118506fcf1..06bca876d4bb 100644 --- a/code/__HELPERS/cmp.dm +++ b/code/__HELPERS/cmp.dm @@ -150,3 +150,6 @@ GLOBAL_VAR_INIT(cmp_field, "name") rhs = ispath(B, /datum/reagent) ? 0 : 1 return lhs - rhs + +/proc/cmp_filter_data_priority(list/A, list/B) + return A["priority"] - B["priority"] diff --git a/code/__HELPERS/colors.dm b/code/__HELPERS/colors.dm index 4a15f36ef6ff..134091a88f88 100644 --- a/code/__HELPERS/colors.dm +++ b/code/__HELPERS/colors.dm @@ -16,3 +16,34 @@ final_color += copytext(color, digit, digit + 1) return final_color + +/// Blends together two colors (passed as 3 or 4 length lists) using the screen blend mode +/// Much like multiply, screen effects the brightness of the resulting color +/// Screen blend will always lighten the resulting color, since before multiplication we invert the colors +/// This makes our resulting output brighter instead of darker +/proc/blend_screen_color(list/first_color, list/second_color) + var/list/output = new /list(4) + + // max out any non existant alphas + if(length(first_color) < 4) + first_color[4] = 255 + if(length(second_color) < 4) + second_color[4] = 255 + + // time to do our blending + for(var/i in 1 to 4) + output[i] = (1 - (1 - first_color[i] / 255) * (1 - second_color[i] / 255)) * 255 + return output + +/// Used to blend together two different color cutoffs +/// Uses the screen blendmode under the hood, essentially just [/proc/blend_screen_color] +/// But paired down and modified to work for our color range +/// Accepts the color cutoffs as two 3 length list(0-100,...) arguments +/proc/blend_cutoff_colors(list/first_color, list/second_color) + var/list/output = new /list(3) + + // Invert the colors, multiply to "darken" (actually lights), then uninvert to get back to what we want + for(var/i in 1 to 3) + output[i] = (1 - (1 - first_color[i] / 100) * (1 - second_color[i] / 100)) * 100 + + return output diff --git a/code/__HELPERS/filters.dm b/code/__HELPERS/filters.dm index 5bc143695e2b..29825367c33e 100644 --- a/code/__HELPERS/filters.dm +++ b/code/__HELPERS/filters.dm @@ -19,3 +19,9 @@ .["color"] = color if(!isnull(flags)) .["flags"] = flags + +/proc/color_matrix_filter(matrix/in_matrix, space) + . = list("type" = "color") + .["color"] = in_matrix + if(!isnull(space)) + .["space"] = space diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 74ec550f4a37..952e2d9d983e 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1206,7 +1206,6 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) name = "INTERNAL DVIEW MOB" invisibility = 101 density = FALSE - see_in_dark = 1e6 move_resist = INFINITY var/ready_to_die = FALSE diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 1162314ce15a..0fe15e009176 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -184,7 +184,7 @@ /atom/movable/screen/fullscreen/lighting_backdrop icon = 'icons/mob/screen_gen.dmi' icon_state = "flash" - transform = matrix(200, 0, 0, 0, 200, 0) + screen_loc = "WEST,SOUTH to EAST,NORTH" plane = LIGHTING_PLANE blend_mode = BLEND_OVERLAY show_when_dead = TRUE diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index f60a5fa86cdc..bc28261dc38e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -63,6 +63,16 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/healths var/atom/movable/screen/healthdoll var/atom/movable/screen/stamina + /// Think of multiz as a stack of z levels. Each index in that stack has its own group of plane masters + /// This variable is the plane offset our mob/client is currently "on" + /// We use it to track what we should show/not show + /// Goes from 0 to the max (z level stack size - 1) + var/current_plane_offset = 0 + /// Assoc list of key => "plane master groups" + /// This is normally just the main window, but it'll occasionally contain things like spyglasses windows + var/list/datum/plane_master_group/master_groups = list() + ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref + var/list/atom/movable/plane_master_controller/plane_master_controllers = list() // subtypes can override this to force a specific UI style var/ui_style @@ -634,3 +644,47 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/action_group/listed/refresh_actions() . = ..() owner.palette_actions.refresh_actions() // We effect them, so we gotta refresh em + +/datum/hud/proc/should_use_scale() + return should_sight_scale(mymob.sight) + +/datum/hud/proc/should_sight_scale(sight_flags) + return (sight_flags & (SEE_TURFS | SEE_OBJS)) != SEE_TURFS + +/datum/hud/proc/eye_z_changed(atom/eye) + SIGNAL_HANDLER + update_parallax_pref() // If your eye changes z level, so should your parallax prefs + var/turf/eye_turf = get_turf(eye) + var/new_offset = GET_TURF_PLANE_OFFSET(eye_turf) + if(current_plane_offset == new_offset) + return + var/old_offset = current_plane_offset + current_plane_offset = new_offset + + SEND_SIGNAL(src, COMSIG_HUD_OFFSET_CHANGED, old_offset, new_offset) + if(should_use_scale()) + for(var/group_key as anything in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.transform_lower_turfs(src, new_offset) + +/// Returns the plane master that matches the input plane from the passed in group +/datum/hud/proc/get_plane_master(plane, group_key = PLANE_GROUP_MAIN) + var/plane_key = "[plane]" + var/datum/plane_master_group/group = master_groups[group_key] + return group.plane_masters[plane_key] + +/// Returns a list of all plane masters that match the input true plane, drawn from the passed in group (ignores z layer offsets) +/datum/hud/proc/get_true_plane_masters(true_plane, group_key = PLANE_GROUP_MAIN) + var/list/atom/movable/screen/plane_master/masters = list() + for(var/plane in TRUE_PLANE_TO_OFFSETS(true_plane)) + masters += get_plane_master(plane, group_key) + return masters + +/// Returns all the planes belonging to the passed in group key +/datum/hud/proc/get_planes_from(group_key) + var/datum/plane_master_group/group = master_groups[group_key] + return group.plane_masters + +/// Returns the corresponding plane group datum if one exists +/datum/hud/proc/get_plane_group(key) + return master_groups[key] diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index 401a350fba1d..fdd372ddbe0f 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -11,6 +11,30 @@ //--rendering relay vars-- /// list of planes we will relay this plane's render to var/list/render_relay_planes = list(RENDER_PLANE_GAME) + /// If this plane master is being forced to hide. + /// Hidden PMs will dump ANYTHING relayed or drawn onto them. Be careful with this + /// Remember: a hidden plane master will dump anything drawn directly to it onto the output render. It does NOT hide its contents + /// Use alpha for that + var/force_hidden = FALSE + /// If this plane master is outside of our visual bounds right now + var/is_outside_bounds = FALSE + /// Our offset from our "true" plane, see below + var/offset + /// list of current relays this plane is utilizing to render + var/list/atom/movable/render_plane_relay/relays = list() + /// if render relays have already be generated + var/relays_generated = FALSE + /// See [code\__DEFINES\layers.dm] for our bitflags + var/critical = NONE + /// The plane master group we're a member of, our "home" + var/datum/plane_master_group/home + /// blend mode to apply to the render relay in case you dont want to use the plane_masters blend_mode + var/blend_mode_override + /// Our real alpha value, so alpha can persist through being hidden/shown + var/true_alpha = 255 + /// Tracks if we're using our true alpha, or being manipulated in some other way + var/alpha_enabled = TRUE + /atom/movable/screen/plane_master/proc/Show(override) alpha = override || show_alpha @@ -30,6 +54,13 @@ blend_mode = BLEND_MULTIPLY alpha = 255 +/atom/movable/screen/plane_master/proc/disable_alpha() + alpha_enabled = FALSE + alpha = 0 + +/atom/movable/screen/plane_master/proc/enable_alpha() + alpha_enabled = TRUE + alpha = true_alpha /atom/movable/screen/plane_master/openspace/backdrop(mob/mymob) filters = list() filters += filter(type="alpha", render_source = LIGHTING_RENDER_TARGET, flags = MASK_INVERSE) @@ -52,6 +83,16 @@ plane = FLOOR_PLANE appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY + render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) + +/atom/movable/screen/plane_master/transparent_floor + name = "Transparent Floor" + // documentation = "Really just openspace, stuff that is a turf but has no color or alpha whatsoever.\ + //
We use this to draw to just the light mask plane, cause if it's not there we get holes of blackness over openspace" + plane = TRANSPARENT_FLOOR_PLANE + render_relay_planes = list(LIGHT_MASK_PLANE) + // Needs to be critical or it uh, it'll look white + critical = PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_RELAY /atom/movable/screen/plane_master/floor/backdrop(mob/mymob) filters = list() @@ -77,6 +118,23 @@ filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) +/atom/movable/screen/plane_master/wall + 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_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) + +/atom/movable/screen/plane_master/wall/Initialize(mapload, datum/plane_master_group/home, offset) + . = ..() + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_WALL_LAYER, relay_color = GLOB.em_block_color) + +/atom/movable/screen/plane_master/wall_upper + name = "Upper wall" + // documentation = "There are some walls that want to render above most things (mostly minerals since they shift over.\ + //
We draw them to their own plane so we can hijack them for our emissive mask stuff" + plane = WALL_PLANE_UPPER + render_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) + ///Contains all lighting objects /atom/movable/screen/plane_master/lighting name = "lighting plane master" @@ -149,6 +207,9 @@ /atom/movable/screen/plane_master/parallax_white name = "parallax whitifier plane master" plane = PLANE_SPACE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) + critical = PLANE_CRITICAL_FUCKO_PARALLAX // goes funny when touched. no idea why I don't trust byond /atom/movable/screen/plane_master/lighting/backdrop(mob/mymob) mymob.overlay_fullscreen("lighting_backdrop_lit", /atom/movable/screen/fullscreen/lighting_backdrop/lit) @@ -185,6 +246,60 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT blend_mode = BLEND_MULTIPLY +/// Gets the relay atom we're using to connect to the target plane, if one exists +/atom/movable/screen/plane_master/proc/get_relay_to(target_plane) + for(var/atom/movable/render_plane_relay/relay in relays) + if(relay.plane == target_plane) + return relay + +/proc/get_plane_master_render_base(name) + return "*[name]: AUTOGENERATED RENDER TGT" + +/atom/movable/screen/plane_master/proc/generate_relay_to(target_plane, relay_loc, client/show_to, blend_override, relay_layer) + if(!length(relays) && !initial(render_target)) + render_target = OFFSET_RENDER_TARGET(get_plane_master_render_base(name), offset) + if(!relay_loc) + relay_loc = "CENTER" + // If we're using a submap (say for a popup window) make sure we draw onto it + if(home?.map) + relay_loc = "[home.map]:[relay_loc]" + var/blend_to_use = blend_override + if(isnull(blend_to_use)) + blend_to_use = blend_mode_override || initial(blend_mode) + + var/atom/movable/render_plane_relay/relay = new() + relay.render_source = render_target + relay.plane = target_plane + relay.screen_loc = relay_loc + // There are two rules here + // 1: layer needs to be positive (negative layers are treated as float layers) + // 2: lower planes (including offset ones) need to be layered below higher ones (because otherwise they'll render fucky) + // By multiplying LOWEST_EVER_PLANE by 30, we give 30 offsets worth of room to planes before they start going negative + // Bet + // We allow for manuel override if requested. careful with this + relay.layer = relay_layer || (plane + abs(LOWEST_EVER_PLANE * 30)) //layer must be positive but can be a decimal + relay.blend_mode = blend_to_use + relay.mouse_opacity = mouse_opacity + relay.name = render_target + relay.critical_target = PLANE_IS_CRITICAL(target_plane) + relays += relay + // Relays are sometimes generated early, before huds have a mob to display stuff to + // That's what this is for + if(show_to) + show_to.screen += relay + return relay + +/// Creates a connection between this plane master and the passed in plane +/// Helper for out of system code, shouldn't be used in this file +/// Build system to differenchiate between generated and non generated render relays +/atom/movable/screen/plane_master/proc/add_relay_to(target_plane, blend_override, relay_layer, relay_color) + if(get_relay_to(target_plane)) + return + render_relay_planes += target_plane + var/client/display_lad = home?.our_hud?.mymob?.canon_client + var/atom/movable/render_plane_relay/relay = generate_relay_to(target_plane, show_to = display_lad, blend_override = blend_override, relay_layer = relay_layer) + relay.color = relay_color + /** * Render relay object assigned to a plane master to be able to relay it's render onto other planes that are not it's own */ @@ -196,6 +311,11 @@ /// If we render into a critical plane master, or not var/critical_target = FALSE +/// Hook to allow planes to work around is_outside_bounds +/// Return false to allow a show, true otherwise +/atom/movable/screen/plane_master/proc/check_outside_bounds() + return is_outside_bounds + /atom/movable/screen/plane_master/fullscreen name = "Fullscreen" plane = FULLSCREEN_PLANE @@ -203,3 +323,339 @@ render_relay_planes = list(RENDER_PLANE_NON_GAME) mouse_opacity = MOUSE_OPACITY_TRANSPARENT allows_offsetting = FALSE + +/atom/movable/screen/plane_master/parallax + name = "Parallax" + // documentation = "Contains parallax, or to be more exact the screen objects that hold parallax.\ + //
Note the BLEND_MULTIPLY. The trick here is how low our plane value is. Because of that, we draw below almost everything in the game.\ + //
We abuse this to ensure we multiply against the Parallax whitifier plane, or space's plane. It's set to full white, so when you do the multiply you just get parallax out where it well, makes sense to be.\ + //
Also notice that the parent parallax plane is mirrored down to all children. We want to support viewing parallax across all z levels at once." + plane = PLANE_SPACE_PARALLAX + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + blend_mode = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + + +/// Hides a plane master from the passeed in mob +/// Do your effect cleanup here +/atom/movable/screen/plane_master/proc/hide_from(mob/oldmob) + SHOULD_CALL_PARENT(TRUE) + var/client/their_client = oldmob?.client + if(!their_client) + return + their_client.screen -= src + their_client.screen -= relays + +/// Shows a plane master to the passed in mob +/// Override this to apply unique effects and such +/// Returns TRUE if the call is allowed, FALSE otherwise +/atom/movable/screen/plane_master/proc/show_to(mob/mymob) + SHOULD_CALL_PARENT(TRUE) + if(force_hidden) + return FALSE + var/client/our_client = mymob?.client + // Alright, let's get this out of the way + // Mobs can move z levels without their client. If this happens, we need to ensure critical display settings are respected + // This is done here. Mild to severe pain but it's nessesary + if(check_outside_bounds()) + if(!(critical & PLANE_CRITICAL_DISPLAY)) + return FALSE + if(!our_client) + return TRUE + our_client.screen += src + + if(!(critical & PLANE_CRITICAL_NO_RELAY)) + our_client.screen += relays + return TRUE + + return TRUE + + if(!our_client) + return TRUE + + our_client.screen += src + our_client.screen += relays + return TRUE + +/atom/movable/screen/plane_master/proc/outside_bounds(mob/relevant) + if(force_hidden || is_outside_bounds) + return + is_outside_bounds = TRUE + // If we're of critical importance, AND we're below the rendering layer + if(critical & PLANE_CRITICAL_DISPLAY) + // We here assume that your render target starts with * + if(critical & PLANE_CRITICAL_CUT_RENDER && render_target) + render_target = copytext_char(render_target, 2) + if(!(critical & PLANE_CRITICAL_NO_RELAY)) + return + var/client/our_client = relevant.client + if(our_client) + for(var/atom/movable/render_plane_relay/relay as anything in relays) + our_client.screen -= relay + + return + hide_from(relevant) + +/// Datum that represents one "group" of plane masters +/// So all the main window planes would be in one, all the spyglass planes in another +/// Etc +/datum/plane_master_group + /// Our key in the group list on /datum/hud + /// Should be unique for any group of plane masters in the world + var/key + /// Our parent hud + var/datum/hud/our_hud + /// List in the form "[plane]" = object, the plane masters we own + var/list/atom/movable/screen/plane_master/plane_masters = list() + /// The visual offset we are currently using + var/active_offset = 0 + /// What, if any, submap we render onto + var/map = "" + +/// Nice wrapper for the "[]"ing +/datum/plane_master_group/proc/get_plane(plane) + return plane_masters["[plane]"] + +///Contains all lighting objects +/atom/movable/screen/plane_master/rendering_plate/lighting + name = "Lighting plate" + // documentation = "Anything on this plane will be multiplied with the plane it's rendered onto (typically the game plane).\ + //
That's how lighting functions at base. Because it uses BLEND_MULTIPLY and occasionally color matrixes, it needs a backdrop of blackness.\ + //
See This byond post\ + //
Lemme see uh, we're masked by the emissive plane so it can actually function (IE: make things glow in the dark).\ + //
We're also masked by the overlay lighting plane, which contains all the movable lights in the game. It draws to us and also the game plane.\ + //
Masks us out so it has the breathing room to apply its effect.\ + //
Oh and we quite often have our alpha changed to achive night vision effects, or things of that sort." + plane = RENDER_PLANE_LIGHTING + blend_mode_override = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + critical = PLANE_CRITICAL_DISPLAY + /// A list of light cutoffs we're actively using, (mass, r, g, b) to avoid filter churn + var/list/light_cutoffs + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/set_light_cutoff(light_cutoff, list/color_cutoffs) + var/list/new_cutoffs = list(light_cutoff) + new_cutoffs += color_cutoffs + if(new_cutoffs ~= light_cutoffs) + return + + remove_filter(list("light_cutdown", "light_cutup")) + + var/ratio = light_cutoff/100 + if(!color_cutoffs) + color_cutoffs = list(0, 0, 0) + + var/red = color_cutoffs[1] / 100 + var/green = color_cutoffs[2] / 100 + var/blue = color_cutoffs[3] / 100 + add_filter("light_cutdown", 3, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, -(ratio + red),-(ratio+green),-(ratio+blue),0))) + add_filter("light_cutup", 4, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, ratio+red,ratio+green,ratio+blue,0))) + +/*! + * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. + * + * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color. + * Emissive blockers are pasted with an atom color that converts them to be entirely some different color. + * Emissive overlays and emissive blockers are put onto the same plane. + * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects. + * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is. + * This is then used to alpha mask the lighting plane. + * + */ +/atom/movable/screen/plane_master/rendering_plate/lighting/Initialize(mapload) + . = ..() + add_filter("emissives", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(EMISSIVE_RENDER_TARGET, offset), flags = MASK_INVERSE)) + add_filter("object_lighting", 2, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(O_LIGHTING_VISUAL_RENDER_TARGET, offset), flags = MASK_INVERSE)) + set_light_cutoff(10) + +/// Breaks a connection between this plane master, and the passed in place +/atom/movable/screen/plane_master/proc/remove_relay_from(target_plane) + render_relay_planes -= target_plane + var/atom/movable/render_plane_relay/existing_relay = get_relay_to(target_plane) + if(!existing_relay) + return + relays -= existing_relay + if(!length(relays) && !initial(render_target)) + render_target = null + var/client/lad = home?.our_hud?.mymob?.canon_client + if(lad) + lad.screen -= existing_relay + +/atom/movable/screen/plane_master/rendering_plate/master/proc/offset_change(new_offset) + if(new_offset == offset) // If we're on our own z layer, relay to nothing, just draw + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) + else // Otherwise, regenerate the relay + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) + +/atom/movable/screen/plane_master/rendering_plate/master/proc/on_offset_change(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_change(new_offset) + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/on_offset_change(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_change(new_offset) + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/offset_change(mob_offset) + // Offsets stack down remember. This implies that we're above the mob's view plane, and shouldn't render + if(offset < mob_offset) + disable_alpha() + else + enable_alpha() + +/atom/movable/screen/plane_master/rendering_plate/lighting/show_to(mob/mymob) + . = ..() + if(!.) + return + // This applies a backdrop to our lighting plane + // Why do plane masters need a backdrop sometimes? Read https://secure.byond.com/forum/?post=2141928 + // Basically, we need something to brighten + // unlit is perhaps less needed rn, it exists to provide a fullbright for things that can't see the lighting plane + // but we don't actually use invisibility to hide the lighting plane anymore, so it's pointless + var/atom/movable/screen/backdrop = mymob.overlay_fullscreen("lighting_backdrop_lit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/lit) + // Need to make sure they're on our plane, ALL the time. We always need a backdrop + SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) + backdrop = mymob.overlay_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) + SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) + // Sorry, this is a bit annoying + // Basically, we only want the lighting plane we can actually see to attempt to render + // If we don't our lower plane gets totally overriden by the black void of the upper plane + var/datum/hud/hud = home.our_hud + // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this + if(hud) + RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) + offset_change(hud?.current_plane_offset || 0) + set_light_cutoff(mymob.lighting_cutoff, mymob.lighting_color_cutoffs) + +/atom/movable/screen/plane_master/rendering_plate/lighting/hide_from(mob/oldmob) + . = ..() + oldmob.clear_fullscreen("lighting_backdrop_lit_[home.key]#[offset]") + oldmob.clear_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]") + var/datum/hud/hud = home.our_hud + if(hud) + UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + +/atom/movable/screen/plane_master/rendering_plate/emissive_slate/Initialize(mapload, datum/plane_master_group/home, offset) + . = ..() + add_filter("em_block_masking", 2, color_matrix_filter(GLOB.em_mask_matrix)) + if(offset != 0) + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset - 1), relay_layer = EMISSIVE_Z_BELOW_LAYER) + +/atom/movable/screen/plane_master/rendering_plate/light_mask + name = "Light Mask" + // documentation = "Any part of this plane that is transparent will be black below it on the game rendering plate.\ + //
This is done to ensure emissives and overlay lights don't light things up \"through\" the darkness that normally sits at the bottom of the lighting plane.\ + //
We relay copies of the space, floor and wall planes to it, so we can use them as masks. Then we just boost any existing alpha to 100% and we're done.\ + //
If we ever switch to a sight setup that shows say, mobs but not floors, we instead mask just overlay lighting and emissives.\ +
This avoids dumb seethrough without breaking stuff like thermals." + plane = LIGHT_MASK_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + // Fullwhite where there's any color, no alpha otherwise + color = list(255,255,255,255, 255,255,255,255, 255,255,255,255, 0,0,0,0, 0,0,0,0) + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = LIGHT_MASK_RENDER_TARGET + // We blend against the game plane, so she's gotta multiply! + blend_mode = BLEND_MULTIPLY + render_relay_planes = list(RENDER_PLANE_GAME) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/show_to(mob/mymob) + . = ..() + if(!.) + return + + RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight)) + handle_sight(mymob, mymob.sight, NONE) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/hide_from(mob/oldmob) + . = ..() + var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) + overlay_lights.remove_filter("lighting_mask") + var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) + emissive.remove_filter("lighting_mask") + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) + UnregisterSignal(oldmob, COMSIG_MOB_SIGHT_CHANGE) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/proc/handle_sight(datum/source, new_sight, old_sight) + // If we can see something that shows "through" blackness, and we can't see turfs, disable our draw to the game plane + // And instead mask JUST the overlay lighting plane, since that will look fuckin wrong + var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) + var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) + if(new_sight & SEE_AVOID_TURF_BLACKNESS && !(new_sight & SEE_TURFS)) + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) + overlay_lights.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) + emissive.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) + // If we CAN'T see through the black, then draw er down brother! + else + overlay_lights.remove_filter("lighting_mask") + emissive.remove_filter("lighting_mask") + // We max alpha here, so our darkness is actually.. dark + // Can't do it before cause it fucks with the filter + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) +// It would be nice to setup parallaxing for stairs and things when doing this +// So they look nicer. if you can't it's all good, if you think you can sanely look at monster's work +// It's hard, and potentially expensive. be careful +/datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) + // Check if this feature is disabled for the client, in which case don't use scale. + // var/mob/our_mob = our_hud?.mymob + + // No offset? piss off + if(!SSmapping.max_plane_offset) + return + + active_offset = new_offset + + // Each time we go "down" a visual z level, we'll reduce the scale by this amount + // Chosen because mothblocks liked it, didn't cause motion sickness while also giving a sense of height + var/scale_by = 0.965 + if(!use_scale) + // This is a workaround for two things + // First of all, if a mob can see objects but not turfs, they will not be shown the holder objects we use for + // What I'd like to do is revert to images if this case throws, but image vis_contents is broken + // https://www.byond.com/forum/post/2821969 + // If that's ever fixed, please just use that. thanks :) + scale_by = 1 + + var/list/offsets = list() + // var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) + + // We accept negatives so going down "zooms" away the drop above as it goes + for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) + // Multiz boundaries disable transforms + // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) + // offsets += null + // continue + + // No transformations if we're landing ON you + if(offset == 0) + offsets += null + continue + + var/scale = scale_by ** (offset) + var/matrix/multiz_shrink = matrix() + multiz_shrink.Scale(scale) + offsets += multiz_shrink + + // So we can talk in 1 -> max_offset * 2 + 1, rather then -max_offset -> max_offset + var/offset_offset = SSmapping.max_plane_offset + 1 + + for(var/plane_key in plane_masters) + var/atom/movable/screen/plane_master/plane = plane_masters[plane_key] + if(!plane.allows_offsetting) + continue + + var/visual_offset = plane.offset - new_offset + + // Basically uh, if we're showing something down X amount of levels, or up any amount of levels + // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) + // plane.outside_bounds(our_mob) + // else if(plane.is_outside_bounds) + // plane.inside_bounds(our_mob) + + // if(!plane.multiz_scaled) + // continue + + if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0) + // We don't animate here because it should be invisble, but we do mark because it'll look nice + plane.transform = offsets[visual_offset + offset_offset] + continue + + animate(plane, transform = offsets[visual_offset + offset_offset], 0.05 SECONDS, easing = LINEAR_EASING) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 697a2fa61a3a..f572a652d1b0 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -26,6 +26,30 @@ SUBSYSTEM_DEF(mapping) var/list/station_minimaps = list() + /// Assoc list of string plane to the plane's offset value + var/list/plane_to_offset + + /// Used to maintain the plane cube + var/list/z_level_to_plane_offset = list() + + /// List of planes that do not allow for offsetting + var/list/plane_offset_blacklist + + /// The largest plane offset we've generated so far + var/max_plane_offset = 0 + + /// Assoc list of true string plane values to a list of all potential offset planess + var/list/true_to_offset_planes + + /// List of render targets that do not allow for offsetting + var/list/render_offset_blacklist + + /// List of plane masters that are of critical priority + var/list/critical_planes + + /// Assoc list of string plane values to their true, non offset representation + var/list/plane_offset_to_true + var/list/areas_in_z = list() var/loading_ruins = FALSE diff --git a/code/datums/actions/mobs/adjust_vision.dm b/code/datums/actions/mobs/adjust_vision.dm new file mode 100644 index 000000000000..906ef33fa73e --- /dev/null +++ b/code/datums/actions/mobs/adjust_vision.dm @@ -0,0 +1,73 @@ +#define VISION_ACTION_LIGHT_OFF 0 +#define VISION_ACTION_LIGHT_LOW 1 +#define VISION_ACTION_LIGHT_MID 2 +#define VISION_ACTION_LIGHT_HIG 3 + +/datum/action/adjust_vision + name = "Adjust Vision" + desc = "See better in the dark. Or don't. Your advanced vision allows either." + button_icon = 'icons/mob/actions/actions_animal.dmi' + button_icon_state = "adjust_vision" + background_icon_state = "bg_default" + overlay_icon_state = "bg_default_border" + + + // These lists are used as the color cutoff for the action + // They need to be filled out for subtypes + var/list/low_light_cutoff + var/list/medium_light_cutoff + var/list/high_light_cutoff + var/light_level = VISION_ACTION_LIGHT_OFF + +/datum/action/adjust_vision/Grant(mob/living/grant_to) + . = ..() + set_light_level(VISION_ACTION_LIGHT_LOW) + RegisterSignal(grant_to, COMSIG_MOB_UPDATE_SIGHT, PROC_REF(on_update_sight)) + +/datum/action/adjust_vision/Remove(mob/living/remove_from) + set_light_level(VISION_ACTION_LIGHT_OFF) + UnregisterSignal(remove_from, COMSIG_MOB_UPDATE_SIGHT) + . = ..() + +/datum/action/adjust_vision/Trigger(trigger_flags) + . = ..() + if(!.) + return + + switch(light_level) + if (VISION_ACTION_LIGHT_OFF) + set_light_level(VISION_ACTION_LIGHT_LOW) + if (VISION_ACTION_LIGHT_LOW) + set_light_level(VISION_ACTION_LIGHT_MID) + if (VISION_ACTION_LIGHT_MID) + set_light_level(VISION_ACTION_LIGHT_HIG) + else + set_light_level(VISION_ACTION_LIGHT_OFF) + +/datum/action/adjust_vision/proc/set_light_level(new_level) + light_level = new_level + owner.update_sight() + +/datum/action/adjust_vision/proc/on_update_sight(datum/source) + SIGNAL_HANDLER + var/list/color_from + switch(light_level) + if (VISION_ACTION_LIGHT_LOW) + color_from = low_light_cutoff + if (VISION_ACTION_LIGHT_MID) + color_from = medium_light_cutoff + if (VISION_ACTION_LIGHT_HIG) + color_from = high_light_cutoff + else // just in case + color_from = list(0, 0, 0) + owner.lighting_color_cutoffs = blend_cutoff_colors(owner.lighting_color_cutoffs, color_from.Copy()) + +/datum/action/adjust_vision/bileworm + low_light_cutoff = list(18, 12, 0) + medium_light_cutoff = list(30, 20, 5) + high_light_cutoff = list(45, 30, 10) + +#undef VISION_ACTION_LIGHT_OFF +#undef VISION_ACTION_LIGHT_LOW +#undef VISION_ACTION_LIGHT_MID +#undef VISION_ACTION_LIGHT_HIG diff --git a/code/datums/brain_damage/imaginary_friend.dm b/code/datums/brain_damage/imaginary_friend.dm index 7d5685af7c03..5a74bb46721e 100644 --- a/code/datums/brain_damage/imaginary_friend.dm +++ b/code/datums/brain_damage/imaginary_friend.dm @@ -58,8 +58,6 @@ real_name = "imaginary friend" move_on_shuttle = TRUE desc = "A wonderful yet fake friend." - see_in_dark = 0 - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE sight = NONE mouse_opacity = MOUSE_OPACITY_OPAQUE see_invisible = SEE_INVISIBLE_LIVING diff --git a/code/datums/datum.dm b/code/datums/datum.dm index a2d370e2ee68..303ca4d21f04 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -46,6 +46,8 @@ * add_timer() returns the truthy value of -1 when not stoppable, and else a truthy numeric index */ var/list/cooldowns + /// List for handling persistent filters. + var/list/filter_data #ifdef TESTING var/running_find_references @@ -250,3 +252,64 @@ return SEND_SIGNAL(source, COMSIG_CD_RESET(index), S_TIMER_COOLDOWN_TIMELEFT(source, index)) TIMER_COOLDOWN_END(source, index) + +/** Update a filter's parameter and animate this change. If the filter doesnt exist we won't do anything. + * Basically a [datum/proc/modify_filter] call but with animations. Unmodified filter parameters are kept. + * + * Arguments: + * * name - Filter name + * * new_params - New parameters of the filter + * * time - time arg of the BYOND animate() proc. + * * easing - easing arg of the BYOND animate() proc. + * * loop - loop arg of the BYOND animate() proc. + */ +/datum/proc/transition_filter(name, list/new_params, time, easing, loop) + var/filter = get_filter(name) + if(!filter) + return + // This can get injected by the filter procs, we want to support them so bye byeeeee + new_params -= "type" + animate(filter, new_params, time = time, easing = easing, loop = loop) + modify_filter(name, new_params) + +/// Returns the filter associated with the passed key +/datum/proc/get_filter(name) + ASSERT(isatom(src) || istype(src, /image)) + if(filter_data && filter_data[name]) + var/atom/atom_cast = src // filters only work with images or atoms. + return atom_cast.filters[filter_data.Find(name)] + +/** Update a filter's parameter to the new one. If the filter doesnt exist we won't do anything. + * + * Arguments: + * * name - Filter name + * * new_params - New parameters of the filter + * * overwrite - TRUE means we replace the parameter list completely. FALSE means we only replace the things on new_params. + */ +/datum/proc/modify_filter(name, list/new_params, overwrite = FALSE) + var/filter = get_filter(name) + if(!filter) + return + if(overwrite) + filter_data[name] = new_params + else + for(var/thing in new_params) + filter_data[name][thing] = new_params[thing] + update_filters() + +/// Reapplies all the filters. +/datum/proc/update_filters() + ASSERT(isatom(src) || istype(src, /image)) + var/atom/atom_cast = src // filters only work with images or atoms. + atom_cast.filters = null + filter_data = sortTim(filter_data, GLOBAL_PROC_REF(cmp_filter_data_priority), TRUE) + for(var/filter_raw in filter_data) + var/list/data = filter_data[filter_raw] + var/list/arguments = data.Copy() + arguments -= "priority" + atom_cast.filters += filter(arglist(arguments)) + UNSETEMPTY(filter_data) + +/obj/item/update_filters() + . = ..() + update_item_action_buttons() diff --git a/code/datums/status_effects/debuffs/debuffs.dm b/code/datums/status_effects/debuffs/debuffs.dm index 13601c2c4123..dbc2f2c6bff0 100644 --- a/code/datums/status_effects/debuffs/debuffs.dm +++ b/code/datums/status_effects/debuffs/debuffs.dm @@ -493,7 +493,6 @@ /datum/status_effect/cultghost/on_apply() owner.see_invisible = SEE_INVISIBLE_OBSERVER - owner.see_in_dark = 2 /datum/status_effect/cultghost/tick() if(owner.reagents) diff --git a/code/datums/traits/good.dm b/code/datums/traits/good.dm index 6c9e33ccef9d..f9844d1661af 100644 --- a/code/datums/traits/good.dm +++ b/code/datums/traits/good.dm @@ -165,7 +165,7 @@ /datum/quirk/night_vision/on_spawn() var/mob/living/carbon/human/H = quirk_holder var/obj/item/organ/eyes/eyes = H.getorgan(/obj/item/organ/eyes) - if(!eyes || eyes.lighting_alpha) + if(!eyes || eyes.lighting_cutoff) return eyes.Insert(H) //refresh their eyesight and vision diff --git a/code/game/atoms.dm b/code/game/atoms.dm index a1def6de5e72..25ee96acc14a 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -85,8 +85,6 @@ ///Last fingerprints to touch this atom var/fingerprintslast - var/list/filter_data //For handling persistent filters - ///Economy cost of item var/custom_price ///Economy cost of item in premium vendor @@ -1502,25 +1500,12 @@ filter_data[name] = p update_filters() -/atom/movable/proc/update_filters() - filters = null - sortTim(filter_data,associative = TRUE) - for(var/f in filter_data) - var/list/data = filter_data[f] - var/list/arguments = data.Copy() - arguments -= "priority" - filters += filter(arglist(arguments)) - /obj/item/update_filters() . = ..() for(var/X in actions) var/datum/action/A = X A.build_all_button_icons() -/atom/movable/proc/get_filter(name) - if(filter_data && filter_data[name]) - return filters[filter_data.Find(name)] - /// Returns the indice in filters of the given filter name. /// If it is not found, returns null. /atom/proc/get_filter_index(name) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 1b20666ac44c..6a22487fe039 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -471,8 +471,5 @@ user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras if(isXRay()) user.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) - user.see_in_dark = max(user.see_in_dark, 8) - else - user.sight = 0 - user.see_in_dark = 2 + return 1 diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 3788a9b0e816..0ddf5f2005c8 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -174,7 +174,6 @@ /mob/camera/aiEye/remote/update_remote_sight(mob/living/user) user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras user.sight = SEE_TURFS | SEE_BLACKNESS - user.see_in_dark = 2 return TRUE /mob/camera/aiEye/remote/Destroy() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 4c40cf4173ec..c7137fc51a82 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -1135,3 +1135,14 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(item_heal_robotic(H, user, brute_heal, burn_heal)) return heal_robo_limb(I, H, user, brute_heal, burn_heal, amount, volume) return TRUE + +/** + * Updates all action buttons associated with this item + * + * Arguments: + * * update_flags - Which flags of the action should we update + * * force - Force buttons update even if the given button icon state has not changed + */ +/obj/item/proc/update_item_action_buttons(update_flags = ALL, force = FALSE) + for(var/datum/action/current_action as anything in actions) + current_action.build_all_button_icons(update_flags, force) diff --git a/code/game/turfs/openspace/openspace.dm b/code/game/turfs/openspace/openspace.dm index 5a06c4bc2234..292707fdebc1 100644 --- a/code/game/turfs/openspace/openspace.dm +++ b/code/game/turfs/openspace/openspace.dm @@ -5,6 +5,7 @@ baseturfs = /turf/open/openspace CanAtmosPassVertical = ATMOS_PASS_YES flags_1 = NO_RUST + plane = TRANSPARENT_FLOOR_PLANE //mouse_opacity = MOUSE_OPACITY_TRANSPARENT var/can_cover_up = TRUE var/can_build_on = TRUE diff --git a/code/modules/antagonists/blob/blob_mobs.dm b/code/modules/antagonists/blob/blob_mobs.dm index 3c9b7fa82a2e..3b9100bf680f 100644 --- a/code/modules/antagonists/blob/blob_mobs.dm +++ b/code/modules/antagonists/blob/blob_mobs.dm @@ -15,8 +15,10 @@ maxbodytemp = 360 unique_name = 1 a_intent = INTENT_HARM - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // ... Blob colored lighting + lighting_cutoff_red = 20 + lighting_cutoff_green = 40 + lighting_cutoff_blue = 30 var/mob/camera/blob/overmind = null var/obj/structure/blob/factory/factory = null var/independent = FALSE diff --git a/code/modules/antagonists/blob/overmind.dm b/code/modules/antagonists/blob/overmind.dm index dacff037b249..3c79ce8c687e 100644 --- a/code/modules/antagonists/blob/overmind.dm +++ b/code/modules/antagonists/blob/overmind.dm @@ -13,13 +13,15 @@ GLOBAL_LIST_EMPTY(blob_nodes) icon_state = "marker" mouse_opacity = MOUSE_OPACITY_ICON move_on_shuttle = 1 - see_in_dark = 8 invisibility = INVISIBILITY_OBSERVER layer = FLY_LAYER + // Vivid blue green, would be cool to make this change with strain + lighting_cutoff_red = 0 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 20 pass_flags = PASSBLOB faction = list(ROLE_BLOB) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE hud_type = /datum/hud/blob_overmind var/obj/structure/blob/core/blob_core = null // The blob overmind's core var/blob_points = 0 diff --git a/code/modules/antagonists/bloodsuckers/bloodsuckers.dm b/code/modules/antagonists/bloodsuckers/bloodsuckers.dm index 58826b125266..4797081ec734 100644 --- a/code/modules/antagonists/bloodsuckers/bloodsuckers.dm +++ b/code/modules/antagonists/bloodsuckers/bloodsuckers.dm @@ -564,8 +564,9 @@ if(user_eyes) user_eyes.flash_protect = initial(user_eyes.flash_protect) user_eyes.sight_flags = initial(user_eyes.sight_flags) - user_eyes.see_in_dark = initial(user_eyes.see_in_dark) - user_eyes.lighting_alpha = initial(user_eyes.lighting_alpha) + user.lighting_cutoff_red += 5 + user.lighting_cutoff_green += 15 + user.lighting_cutoff_blue += 5 user.update_sight() /datum/antagonist/bloodsucker/proc/give_masquerade_infraction() diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm index 718b13382163..2d0673457ffa 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm @@ -215,8 +215,7 @@ if(current_eyes) current_eyes.flash_protect = max(initial(current_eyes.flash_protect) - 1, - 1) current_eyes.sight_flags = SEE_MOBS - current_eyes.see_in_dark = 8 - current_eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + current_eyes.setOrganDamage(0) //making sure if(my_clan?.get_clan() == CLAN_LASOMBRA && ishuman(bloodsuckeruser)) var/mob/living/carbon/human/bloodsucker = bloodsuckeruser diff --git a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm index bac0e1fac941..7a7febba425b 100644 --- a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm +++ b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm @@ -58,15 +58,11 @@ return TRUE /obj/item/clothing/glasses/wraith_spectacles/proc/set_vision_vars(update_vision) - lighting_alpha = null tint = 0 vision_flags = NONE - darkness_view = 2 if(!up) if(is_servant_of_ratvar(loc)) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE vision_flags = SEE_MOBS | SEE_TURFS | SEE_OBJS - darkness_view = 3 else tint = 3 if(update_vision && iscarbon(loc)) diff --git a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm index efcbd6f882ec..8ed7296d9442 100644 --- a/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm +++ b/code/modules/antagonists/clockcult/clock_mobs/_eminence.dm @@ -11,11 +11,13 @@ icon_state = "eminence" mouse_opacity = MOUSE_OPACITY_OPAQUE move_on_shuttle = TRUE - see_in_dark = 8 invisibility = INVISIBILITY_OBSERVER layer = FLY_LAYER faction = list("ratvar") - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // VERY red, to fit the eyes + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 var/turf/last_failed_turf var/static/superheated_walls = 0 var/lastWarning = 0 diff --git a/code/modules/antagonists/demon/general_powers.dm b/code/modules/antagonists/demon/general_powers.dm index 41834bb33b6a..ff8eb520ecd0 100644 --- a/code/modules/antagonists/demon/general_powers.dm +++ b/code/modules/antagonists/demon/general_powers.dm @@ -45,8 +45,9 @@ melee_damage_lower = 20 melee_damage_upper = 20 wound_bonus = -15 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 loot = (/obj/effect/decal/cleanable/blood) del_on_death = TRUE diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm index 7c76013f3401..b4474c51e689 100644 --- a/code/modules/antagonists/devil/imp/imp.dm +++ b/code/modules/antagonists/devil/imp/imp.dm @@ -31,8 +31,10 @@ obj_damage = 40 melee_damage_lower = 10 melee_damage_upper = 15 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // You KNOW we're doing a lightly purple red + lighting_cutoff_red = 30 + lighting_cutoff_green = 10 + lighting_cutoff_blue = 20 var/boost = 0 bloodcrawl = BLOODCRAWL_EAT var/list/consumed_mobs = list() diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm index a9c6d361e279..9ebd36567bdc 100644 --- a/code/modules/antagonists/disease/disease_mob.dm +++ b/code/modules/antagonists/disease/disease_mob.dm @@ -13,14 +13,17 @@ the new instance inside the host to be updated to the template's stats. icon_state = "marker" mouse_opacity = MOUSE_OPACITY_ICON move_on_shuttle = FALSE - see_in_dark = 8 see_invisible = SEE_INVISIBLE_LIVING invisibility = INVISIBILITY_OBSERVER layer = BELOW_MOB_LAYER - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE sight = SEE_SELF|SEE_THRU initial_language_holder = /datum/language_holder/universal + // Pale green, bright enough to have good vision + lighting_cutoff_red = 5 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 20 + var/freemove = TRUE var/freemove_end = 0 var/const/freemove_time = 1200 diff --git a/code/modules/antagonists/eldritch_cult/eldritch_items.dm b/code/modules/antagonists/eldritch_cult/eldritch_items.dm index 693016e600dc..32d16a4ff7ee 100644 --- a/code/modules/antagonists/eldritch_cult/eldritch_items.dm +++ b/code/modules/antagonists/eldritch_cult/eldritch_items.dm @@ -303,7 +303,8 @@ desc = "Allows the user to swap between three hud types, science, medical, and diagnostic" icon_state = "godeye" item_state = "godeye" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Blue, light blue + color_cutoffs = list(15, 30, 40) hud_type = DATA_HUD_SECURITY_BASIC /obj/item/clothing/glasses/hud/toggle/eldritch_eye/equipped(mob/living/user, slot) diff --git a/code/modules/antagonists/horror/horror.dm b/code/modules/antagonists/horror/horror.dm index 03ca12a00b9c..c476f05a1f97 100644 --- a/code/modules/antagonists/horror/horror.dm +++ b/code/modules/antagonists/horror/horror.dm @@ -9,8 +9,9 @@ maxHealth = 50 melee_damage_lower = 10 melee_damage_upper = 10 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 stop_automated_movement = TRUE attacktext = "bites" speak_emote = list("gurgles") diff --git a/code/modules/antagonists/morph/morph.dm b/code/modules/antagonists/morph/morph.dm index 4513e199850e..25f2cf9fff4e 100644 --- a/code/modules/antagonists/morph/morph.dm +++ b/code/modules/antagonists/morph/morph.dm @@ -24,8 +24,10 @@ obj_damage = 50 melee_damage_lower = 20 melee_damage_upper = 20 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Oh you KNOW it's gonna be real green + lighting_cutoff_red = 10 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 15 vision_range = 1 // Only attack when target is close wander = FALSE attack_vis_effect = ATTACK_EFFECT_BITE //nom nom nom diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index b0f30b70856b..f5eaa26713b7 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -27,8 +27,10 @@ sight = SEE_MOBS | SEE_OBJS | SEE_TURFS | SEE_SELF throwforce = 0 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Going for faint purple spoopy ghost + lighting_cutoff_red = 20 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 35 response_help = "passes through" response_disarm = "swings through" response_harm = "punches through" @@ -72,10 +74,6 @@ flags_1 |= RAD_NO_CONTAMINATE_1 ADD_TRAIT(src, TRAIT_SIXTHSENSE, INNATE_TRAIT) - // Starting spells - var/datum/action/cooldown/spell/night_vision/revenant/vision = new(src) - vision.Grant(src) - var/datum/action/cooldown/spell/list_target/telepathy/revenant/telepathy = new(src) telepathy.Grant(src) diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm index 1253d94a738a..dae162f7c257 100644 --- a/code/modules/antagonists/revenant/revenant_abilities.dm +++ b/code/modules/antagonists/revenant/revenant_abilities.dm @@ -96,16 +96,7 @@ to_chat(src, span_revenwarning("You are not close enough to siphon [target ? "[target]'s":"[target.p_their()]"] soul. The link has been broken.")) draining = FALSE essence_drained = 0 - -//Toggle night vision: lets the revenant toggle its night vision -/datum/action/cooldown/spell/night_vision/revenant - name = "Toggle Darkvision" - panel = "Revenant Abilities" - background_icon_state = "bg_revenant" - button_icon = 'icons/mob/actions/actions_revenant.dmi' - button_icon_state = "r_nightvision" - toggle_span = "revennotice" - + //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob /datum/action/cooldown/spell/list_target/telepathy/revenant name = "Revenant Transmit" diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index 5b186f6696c5..adaa1d088467 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -33,8 +33,9 @@ obj_damage = 50 melee_damage_lower = 30 melee_damage_upper = 30 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 bloodcrawl = BLOODCRAWL_EAT var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \ You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \ diff --git a/code/modules/cargo/bounties/special.dm b/code/modules/cargo/bounties/special.dm index 0072cb11f629..fce400e49f20 100644 --- a/code/modules/cargo/bounties/special.dm +++ b/code/modules/cargo/bounties/special.dm @@ -3,7 +3,7 @@ description = "Nanotrasen is interested in studying Xenomorph biology. Ship a set of organs to be thoroughly compensated." reward = 25000 required_count = 3 - wanted_types = list(/obj/item/organ/brain/alien, /obj/item/organ/alien, /obj/item/organ/body_egg/alien_embryo, /obj/item/organ/liver/alien, /obj/item/organ/tongue/alien, /obj/item/organ/eyes/night_vision/alien) + wanted_types = list(/obj/item/organ/brain/alien, /obj/item/organ/alien, /obj/item/organ/body_egg/alien_embryo, /obj/item/organ/liver/alien, /obj/item/organ/tongue/alien, /obj/item/organ/eyes/alien) /datum/bounty/item/syndicate_documents name = "Syndicate Documents" diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm index c2dc8a24625e..eddeb3420196 100644 --- a/code/modules/clothing/clothing.dm +++ b/code/modules/clothing/clothing.dm @@ -12,7 +12,7 @@ var/visor_flags_inv = 0 //same as visor_flags, but for flags_inv var/visor_flags_cover = 0 //same as above, but for flags_cover //what to toggle when toggled with weldingvisortoggle() - var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_DARKNESSVIEW | VISOR_INVISVIEW + var/visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT | VISOR_VISIONFLAGS | VISOR_INVISVIEW lefthand_file = 'icons/mob/inhands/clothing_lefthand.dmi' righthand_file = 'icons/mob/inhands/clothing_righthand.dmi' var/alt_desc = null diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 7c433361c60d..2048bf937375 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -10,14 +10,24 @@ resistance_flags = NONE materials = list(/datum/material/glass = 250) var/vision_flags = 0 - var/darkness_view = 2//Base human is 2 var/invis_view = SEE_INVISIBLE_LIVING //admin only for now var/invis_override = 0 //Override to allow glasses to set higher than normal see_invis - var/lighting_alpha var/list/icon/current = list() //the current hud icons var/vision_correction = 0 //does wearing these glasses correct some of our vision defects? var/glass_colour_type //colors your vision when worn + /// A percentage of how much rgb to "max" on the lighting plane + /// This lets us brighten darkness without washing out bright color + var/lighting_cutoff = null + /// Similar to lighting_cutoff, except it has individual r g and b components in the same 0-100 scale + var/list/color_cutoffs = null +// Potentially replace glass_color_type with a setup that colors lighting by dropping segments of different componets +// Like the current idea, but applied without the mass cutoff (maybe? somehow?) +// That or just a light color to the lighting plane, that'd work too +// Enough to make it visible but not so much that it's a pain + +// That, or just make stuff that uses lighting_cutoff have colored offsets and all, like you were planning + /obj/item/clothing/glasses/suicide_act(mob/living/carbon/user) user.visible_message(span_suicide("[user] is stabbing \the [src] into [user.p_their()] eyes! It looks like [user.p_theyre()] trying to commit suicide!")) return BRUTELOSS @@ -31,8 +41,6 @@ ..() if(visor_vars_to_toggle & VISOR_VISIONFLAGS) vision_flags ^= initial(vision_flags) - if(visor_vars_to_toggle & VISOR_DARKNESSVIEW) - darkness_view ^= initial(darkness_view) if(visor_vars_to_toggle & VISOR_INVISVIEW) invis_view ^= initial(invis_view) @@ -59,9 +67,9 @@ desc = "Used by engineering and mining staff to see basic structural and terrain layouts through walls, regardless of lighting conditions." icon_state = "meson" item_state = "meson" - darkness_view = 2 vision_flags = SEE_TURFS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Mesons get to be lightly green + color_cutoffs = list(5, 15, 5) glass_colour_type = /datum/client_colour/glass_colour/lightgreen clothing_traits = list(TRAIT_MESONS) @@ -74,9 +82,10 @@ desc = "An optical meson scanner fitted with an amplified visible light spectrum overlay, providing greater visual clarity in darkness." icon_state = "nvgmeson" item_state = "nvgmeson" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Night vision mesons get the same but more intense + color_cutoffs = list(10, 30, 10) + lighting_cutoff = LIGHTING_CUTOFF_HIGH glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/meson/gar @@ -137,18 +146,18 @@ desc = "A pair of snazzy goggles used to protect against chemical spills that happen in complete darkness. Fitted with an analyzer for scanning items and reagents." icon_state = "sciencehudnight" item_state = "sciencehudnight" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Real vivid purple + color_cutoffs = list(50, 10, 30) /obj/item/clothing/glasses/night name = "night vision goggles" desc = "You can totally see in the dark now!" icon_state = "night" item_state = "glasses" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Dark green + color_cutoffs = list(10, 30, 10) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/science/suicide_act(mob/living/carbon/user) @@ -164,7 +173,6 @@ /obj/item/clothing/glasses/eyepatch/bigboss name = "faded eyepatch" desc = "Offers night vision and protection from flashes. Another mission, right boss?" - darkness_view = 8 flash_protect = 1 /obj/item/clothing/glasses/monocle @@ -187,7 +195,6 @@ desc = "Used by miners to detect ores deep within the rock." icon_state = "material" item_state = "glasses" - darkness_view = 0 /obj/item/clothing/glasses/material/mining/gar name = "gar material scanner" @@ -234,7 +241,6 @@ desc = "Strangely ancient technology used to help provide rudimentary eye cover. Enhanced shielding blocks flashes." icon_state = "sun" item_state = "sunglasses" - darkness_view = 1 flash_protect = 1 tint = 1 glass_colour_type = /datum/client_colour/glass_colour/gray @@ -317,7 +323,6 @@ item_state = "blindfold" flash_protect = 2 tint = 3 - darkness_view = 1 dog_fashion = /datum/dog_fashion/head /obj/item/clothing/glasses/blindfold/equipped(mob/living/carbon/human/user, slot) @@ -371,7 +376,8 @@ icon_state = "thermal" item_state = "glasses" vision_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Going for an orange color here + color_cutoffs = list(25, 8, 5) flash_protect = -1 glass_colour_type = /datum/client_colour/glass_colour/red @@ -462,8 +468,8 @@ icon_state = "godeye" item_state = "godeye" vision_flags = SEE_TURFS - darkness_view = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Blue, light blue + color_cutoffs = list(15, 30, 40) resistance_flags = LAVA_PROOF | FIRE_PROOF clothing_flags = SCAN_REAGENTS var/datum/action/cooldown/expose/expose_ability diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index 23ac10427b4b..e672db3326c8 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -19,8 +19,8 @@ actions_types = list(/datum/action/item_action/toggle_mode) vision_flags = NONE - darkness_view = 2 invis_view = SEE_INVISIBLE_LIVING + color_cutoffs = null var/list/modes = list(MODE_NONE = MODE_MESON, MODE_MESON = MODE_TRAY, MODE_TRAY = MODE_RAD, MODE_RAD = MODE_NONE) var/mode = MODE_NONE @@ -42,14 +42,12 @@ switch(mode) if(MODE_MESON) vision_flags = SEE_TURFS - darkness_view = 1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + color_cutoffs = list(15, 12, 0) if(MODE_TRAY) //undoes the last mode, meson vision_flags = NONE - darkness_view = 2 - lighting_alpha = null - + color_cutoffs = list() + if(ishuman(user)) var/mob/living/carbon/human/H = user if(H.glasses == src) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 33592b773bf9..b60bfafaa647 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -43,9 +43,9 @@ desc = "An advanced medical heads-up display that allows doctors to find patients in complete darkness." icon_state = "healthhudnight" item_state = "glasses" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Blue green, dark + color_cutoffs = list(5, 15, 30) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/health/meson @@ -54,7 +54,6 @@ icon_state = "mesonhealth" item_state = "mesonhealth" vision_flags = SEE_TURFS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE clothing_traits = list(TRAIT_MESONS) glass_colour_type = /datum/client_colour/glass_colour/lightblue @@ -62,7 +61,6 @@ name = "medical HUDSunglasses" desc = "Sunglasses with a medical HUD." icon_state = "sunhudmed" - darkness_view = 1 flash_protect = 1 tint = 1 glass_colour_type = /datum/client_colour/glass_colour/blue @@ -84,9 +82,9 @@ desc = "A robotics diagnostic HUD fitted with a light amplifier." icon_state = "diagnostichudnight" item_state = "glasses" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Pale yellow + color_cutoffs = list(30, 20, 5) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/diagnostic/sunglasses @@ -143,9 +141,10 @@ name = "security HUDSunglasses" desc = "Sunglasses with a security HUD." icon_state = "sunhudsec" - darkness_view = 1 flash_protect = 1 tint = 1 + // Red with a tint of green + color_cutoffs = list(35, 5, 5) glass_colour_type = /datum/client_colour/glass_colour/darkred /obj/item/clothing/glasses/hud/security/sunglasses/hos @@ -157,9 +156,7 @@ name = "night vision security HUD" desc = "An advanced heads-up display which provides ID data and vision in complete darkness." icon_state = "securityhudnight" - darkness_view = 8 flash_protect = -1 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/security/sunglasses/gars @@ -228,7 +225,7 @@ icon_state = "thermal" hud_type = DATA_HUD_SECURITY_ADVANCED vision_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + color_cutoffs = list(25, 8, 5) glass_colour_type = /datum/client_colour/glass_colour/red /obj/item/clothing/glasses/hud/toggle/thermal/attack_self(mob/user) @@ -236,13 +233,17 @@ switch (hud_type) if (DATA_HUD_MEDICAL_ADVANCED) icon_state = "meson" + color_cutoffs = list(5, 15, 5) change_glass_color(user, /datum/client_colour/glass_colour/green) if (DATA_HUD_SECURITY_ADVANCED) icon_state = "thermal" + color_cutoffs = list(25, 8, 5) change_glass_color(user, /datum/client_colour/glass_colour/red) else icon_state = "purple" + color_cutoffs = list(15, 0, 25) change_glass_color(user, /datum/client_colour/glass_colour/purple) + user.update_sight() user.update_inv_glasses() /obj/item/clothing/glasses/hud/toggle/thermal/emp_act(severity) diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm index faf393415081..843882860b8d 100644 --- a/code/modules/mining/lavaland/necropolis_chests.dm +++ b/code/modules/mining/lavaland/necropolis_chests.dm @@ -299,7 +299,7 @@ GLOBAL_LIST_EMPTY(aide_list) light_flags = LIGHT_ATTACHED layer = ABOVE_ALL_MOB_LAYER var/sight_flags = SEE_MOBS - var/lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + var/list/color_cutoffs = list(10, 25, 25) /obj/effect/wisp/orbit(atom/thing, radius, clockwise, rotation_speed, rotation_segments, pre_rotation, lockinorbit) . = ..() @@ -317,8 +317,8 @@ GLOBAL_LIST_EMPTY(aide_list) /obj/effect/wisp/proc/update_user_sight(mob/user) user.sight |= sight_flags - if(!isnull(lighting_alpha)) - user.lighting_alpha = min(user.lighting_alpha, lighting_alpha) + if(!isnull(color_cutoffs)) + user.lighting_color_cutoffs = blend_cutoff_colors(user.lighting_color_cutoffs, color_cutoffs) //Red/Blue Cubes /obj/item/warp_cube diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 5ccc373a53fb..c1ea6bfafaf4 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -205,12 +205,15 @@ var/mob/living/simple_animal/hostile/mining_drone/user = owner if(user.sight & SEE_TURFS) user.sight &= ~SEE_TURFS - user.lighting_alpha = initial(user.lighting_alpha) + user.lighting_cutoff_red += 5 + user.lighting_cutoff_green += 15 + user.lighting_cutoff_blue += 5 else user.sight |= SEE_TURFS - user.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - - user.sync_lighting_plane_alpha() + user.lighting_cutoff_red -= 5 + user.lighting_cutoff_green -= 15 + user.lighting_cutoff_blue -= 5 + user.sync_lighting_plane_cutoff() to_chat(user, span_notice("You toggle your meson vision [(user.sight & SEE_TURFS) ? "on" : "off"].")) diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index fe06cbf0f341..dbf07aed090f 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -7,11 +7,14 @@ move_resist = INFINITY status_flags = GODMODE // You can't damage it. mouse_opacity = MOUSE_OPACITY_TRANSPARENT - see_in_dark = 7 invisibility = INVISIBILITY_ABSTRACT // No one can see us sight = SEE_SELF move_on_shuttle = FALSE +/mob/camera/update_sight() + lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) + return ..() + /mob/camera/experience_pressure_difference() return diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6f2f8e73ed36..6ae0b1d9039b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -12,8 +12,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) stat = DEAD density = FALSE see_invisible = SEE_INVISIBLE_OBSERVER - see_in_dark = 100 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + lighting_cutoff = LIGHTING_CUTOFF_MEDIUM invisibility = INVISIBILITY_OBSERVER hud_type = /datum/hud/ghost movement_type = GROUND | FLYING @@ -597,15 +596,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp /mob/dead/observer/verb/toggle_darkness() set name = "Toggle Darkness" set category = "Ghost" - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + switch(lighting_cutoff) + if (LIGHTING_CUTOFF_VISIBLE) + lighting_cutoff = LIGHTING_CUTOFF_MEDIUM + if (LIGHTING_CUTOFF_MEDIUM) + lighting_cutoff = LIGHTING_CUTOFF_HIGH + if (LIGHTING_CUTOFF_HIGH) + lighting_cutoff = LIGHTING_CUTOFF_FULLBRIGHT else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + lighting_cutoff = LIGHTING_CUTOFF_VISIBLE update_sight() diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index 995728c0f2ad..b11914cd7329 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -6,7 +6,6 @@ faction = list(ROLE_ALIEN) ventcrawler = VENTCRAWLER_ALWAYS sight = SEE_MOBS - see_in_dark = 4 verb_say = "hisses" initial_language_holder = /datum/language_holder/alien bubble_icon = "alien" @@ -40,7 +39,7 @@ internal_organs += new /obj/item/organ/brain/alien internal_organs += new /obj/item/organ/alien/hivenode internal_organs += new /obj/item/organ/tongue/alien - internal_organs += new /obj/item/organ/eyes/night_vision/alien + internal_organs += new /obj/item/organ/eyes/alien internal_organs += new /obj/item/organ/liver/alien internal_organs += new /obj/item/organ/ears ..() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 243853dafa04..a3eb04ddc2ca 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -562,78 +562,56 @@ return if(stat == DEAD) if(SSmapping.level_trait(z, ZTRAIT_NOXRAY)) - sight = null + set_sight(null) else if(is_secret_level(z)) - sight = initial(sight) + set_sight(initial(sight)) else - sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_in_dark = 8 - see_invisible = SEE_INVISIBLE_OBSERVER + set_sight(SEE_TURFS|SEE_MOBS|SEE_OBJS) + set_invis_see(SEE_INVISIBLE_OBSERVER) return - sight = initial(sight) - see_infrared = initial(see_infrared) - lighting_alpha = initial(lighting_alpha) - var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES) - if(!E) - update_tint() - else - see_invisible = E.see_invisible - see_in_dark = E.see_in_dark - sight |= E.sight_flags - if(!isnull(E.lighting_alpha)) - lighting_alpha = E.lighting_alpha - - for(var/image/I in infra_images) - if(client) - client.images.Remove(I) - infra_images = list() - remove_client_colour(/datum/client_colour/monochrome_infra) - - if(client.eye != src) + var/new_sight = initial(sight) + lighting_cutoff = initial(lighting_cutoff) + lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) + + if(client.eye && client.eye != src) var/atom/A = client.eye if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. return if(glasses) - var/obj/item/clothing/glasses/G = glasses - sight |= G.vision_flags - see_in_dark = max(G.darkness_view, see_in_dark) - if(G.invis_override) - see_invisible = G.invis_override + new_sight |= glasses.vision_flags + if(glasses.invis_override) + set_invis_see(glasses.invis_override) else - see_invisible = min(G.invis_view, see_invisible) - if(!isnull(G.lighting_alpha)) - lighting_alpha = min(lighting_alpha, G.lighting_alpha) - - if(HAS_TRAIT(src, TRAIT_INFRARED_VISION)) - add_client_colour(/datum/client_colour/monochrome_infra) - var/image/A = null - see_infrared = TRUE - lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - - if(client) - for(var/mob/living/carbon/human/H in GLOB.alive_mob_list) - A = image('icons/mob/simple_human.dmi', H, "fullwhite") - A.name = "white haze" - A.override = 1 - infra_images |= A - client.images |= A + set_invis_see(min(glasses.invis_view, see_invisible)) + if(!isnull(glasses.lighting_cutoff)) + lighting_cutoff = max(lighting_cutoff, glasses.lighting_cutoff) + if(!isnull(glasses.color_cutoffs)) + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, glasses.color_cutoffs) + + + if(HAS_TRAIT(src, TRAIT_TRUE_NIGHT_VISION)) + lighting_cutoff = max(lighting_cutoff, LIGHTING_CUTOFF_HIGH) + + if(HAS_TRAIT(src, TRAIT_MESON_VISION)) + new_sight |= SEE_TURFS + lighting_cutoff = max(lighting_cutoff, LIGHTING_CUTOFF_MEDIUM) if(HAS_TRAIT(src, TRAIT_THERMAL_VISION)) - sight |= (SEE_MOBS) - lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) + new_sight |= SEE_MOBS + lighting_cutoff = max(lighting_cutoff, LIGHTING_CUTOFF_MEDIUM) if(HAS_TRAIT(src, TRAIT_XRAY_VISION)) - sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_in_dark = max(see_in_dark, 8) + new_sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS if(see_override) - see_invisible = see_override + set_invis_see(see_override) if(SSmapping.level_trait(z, ZTRAIT_NOXRAY)) - sight = null + new_sight = NONE + set_sight(new_sight) return ..() /mob/living/carbon/update_stamina_hud(shown_stamina_amount) diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index f87e39120139..653d2abc967e 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -132,7 +132,7 @@ if(G.vision_correction) clear_fullscreen("nearsighted") clear_fullscreen("eye_damage") - if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) + if(G.vision_flags || G.invis_override || G.invis_view || !isnull(G.lighting_cutoff)) update_sight() update_inv_glasses() if(ITEM_SLOT_GLOVES) @@ -217,7 +217,7 @@ if(G.vision_correction) if(HAS_TRAIT(src, TRAIT_NEARSIGHT)) overlay_fullscreen("nearsighted", /atom/movable/screen/fullscreen/impaired, 1) - if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha)) + if(G.vision_flags || G.invis_override || G.invis_view || !isnull(G.lighting_cutoff)) update_sight() if(!QDELETED(src)) update_inv_glasses() diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm index c4b8bd0be8d4..4aca5549e3d8 100644 --- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm @@ -13,7 +13,7 @@ inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH,TRAIT_GENELESS,TRAIT_NOHUNGER) changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC - mutanteyes = /obj/item/organ/eyes/night_vision + mutanteyes = /obj/item/organ/eyes/shadow /datum/species/shadow/spec_life(mob/living/carbon/human/H) @@ -89,7 +89,7 @@ no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYESPRITES,NOFLASH) inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER) - mutanteyes = /obj/item/organ/eyes/night_vision/nightmare + mutanteyes = /obj/item/organ/eyes/shadow mutant_organs = list(/obj/item/organ/heart/nightmare) mutantbrain = /obj/item/organ/brain/nightmare diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm index 41ed79f0ff96..4f3a9832fafb 100644 --- a/code/modules/mob/living/carbon/human/species_types/zombies.dm +++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm @@ -51,7 +51,7 @@ mutanthands = /obj/item/zombie_hand armor = 20 // 120 damage to KO a zombie, which kills it speedmod = 1.6 - mutanteyes = /obj/item/organ/eyes/night_vision/zombie + mutanteyes = /obj/item/organ/eyes/zombie var/heal_rate = 1 var/regen_cooldown = 0 changesource_flags = MIRROR_BADMIN | WABBAJACK | ERT_SPAWN diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 120de23ca684..cce17d6775e8 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -1555,8 +1555,8 @@ GLOBAL_LIST_EMPTY(fire_appearances) updatehealth() if("resize") update_transform() - if("lighting_alpha") - sync_lighting_plane_alpha() + if("lighting_cutoff") + sync_lighting_plane_cutoff() /mob/living/vv_get_header() . = ..() diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 4288d6291183..217078bf717a 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -1,7 +1,6 @@ /mob/living see_invisible = SEE_INVISIBLE_LIVING sight = 0 - see_in_dark = 2 hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD) pressure_resistance = 10 infra_luminosity = 10 diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5d890506003f..70783b2399a6 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -23,7 +23,6 @@ status_flags = CANSTUN|CANPUSH a_intent = INTENT_HARM //so we always get pushed instead of trying to swap sight = SEE_TURFS | SEE_MOBS | SEE_OBJS - see_in_dark = 8 hud_type = /datum/hud/ai med_hud = DATA_HUD_MEDICAL_BASIC sec_hud = DATA_HUD_SECURITY_BASIC diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm index 7d9c128e622e..0c0cf4554fdf 100644 --- a/code/modules/mob/living/silicon/ai/life.dm +++ b/code/modules/mob/living/silicon/ai/life.dm @@ -111,17 +111,15 @@ /mob/living/silicon/ai/update_sight() see_invisible = initial(see_invisible) - see_in_dark = initial(see_in_dark) sight = initial(sight) if(aiRestorePowerRoutine && !available_ai_cores()) sight = sight&~SEE_TURFS sight = sight&~SEE_MOBS sight = sight&~SEE_OBJS - see_in_dark = 0 if(see_override) see_invisible = see_override - sync_lighting_plane_alpha() + sync_lighting_plane_cutoff() /mob/living/silicon/ai/proc/start_RestorePowerRoutine() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index ea28cd315e22..c5bc9df32716 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1065,14 +1065,13 @@ sight = initial(sight) else sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_in_dark = 8 see_invisible = SEE_INVISIBLE_OBSERVER return see_invisible = initial(see_invisible) - see_in_dark = initial(see_in_dark) sight = initial(sight) - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + lighting_cutoff = LIGHTING_CUTOFF_VISIBLE + lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) if(client.eye != src) var/atom/A = client.eye @@ -1081,28 +1080,24 @@ if(sight_mode & BORGMESON) sight |= SEE_TURFS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 2 + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(5, 15, 5)) if(sight_mode & BORGMESON_NIGHTVISION) sight |= SEE_TURFS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 8 + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(5, 30, 5)) if(sight_mode & BORGMATERIAL) sight |= SEE_OBJS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 2 + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(20, 25, 40)) if(sight_mode & BORGXRAY) sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) see_invisible = SEE_INVISIBLE_LIVING - see_in_dark = 8 if(sight_mode & BORGTHERM) sight |= SEE_MOBS see_invisible = min(see_invisible, SEE_INVISIBLE_LIVING) - see_in_dark = 8 + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(25, 8, 5)) if(see_override) see_invisible = see_override @@ -1110,7 +1105,7 @@ if(SSmapping.level_trait(z, ZTRAIT_NOXRAY)) sight = null - sync_lighting_plane_alpha() + sync_lighting_plane_cutoff() /mob/living/silicon/robot/update_stat() if(status_flags & GODMODE) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index e8ef8b4249a7..a2743cbf2527 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -6,7 +6,6 @@ verb_exclaim = "declares" verb_yell = "alarms" initial_language_holder = /datum/language_holder/synthetic - see_in_dark = 8 infra_luminosity = 0 bubble_icon = "machine" weather_immunities = list("ash") diff --git a/code/modules/mob/living/simple_animal/constructs.dm b/code/modules/mob/living/simple_animal/constructs.dm index 5334e54e44d1..33539a190172 100644 --- a/code/modules/mob/living/simple_animal/constructs.dm +++ b/code/modules/mob/living/simple_animal/constructs.dm @@ -16,8 +16,10 @@ stop_automated_movement = 1 status_flags = CANPUSH attack_sound = 'sound/weapons/punch1.ogg' - see_in_dark = 7 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Vivid red, cause cult theme + lighting_cutoff_red = 30 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 20 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/eldritch_demons.dm b/code/modules/mob/living/simple_animal/eldritch_demons.dm index a8160ab84822..326c7bebc458 100644 --- a/code/modules/mob/living/simple_animal/eldritch_demons.dm +++ b/code/modules/mob/living/simple_animal/eldritch_demons.dm @@ -15,8 +15,10 @@ stop_automated_movement = 1 AIStatus = AI_OFF attack_sound = 'sound/weapons/punch1.ogg' - see_in_dark = 7 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Sort of greenish brown, to match the vibeTM + lighting_cutoff_red = 20 + lighting_cutoff_green = 25 + lighting_cutoff_blue = 5 damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 925bbe3462b9..f69b10974dd4 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -13,8 +13,6 @@ emote_see = list("shakes its head.", "shivers.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE ventcrawler = VENTCRAWLER_ALWAYS pass_flags = PASSTABLE | PASSCOMPUTER mob_biotypes = MOB_ORGANIC|MOB_BEAST diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 0a967ca90dbe..5e6046c6d1b8 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -15,8 +15,10 @@ emote_hear = list("barks!", "woofs!", "yaps.","pants.") emote_see = list("shakes its head.", "chases its tail.","shivers.") faction = list("neutral") - see_in_dark = 5 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // VERY red, to fit the eyes + lighting_cutoff_red = 22 + lighting_cutoff_green = 5 + lighting_cutoff_blue = 5 speak_chance = 1 turns_per_move = 10 gold_core_spawnable = FRIENDLY_SPAWN diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index fd63fa71afb3..5dcaab702f96 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -48,8 +48,10 @@ faction = list("neutral","silicon","turret") dextrous = TRUE dextrous_hud_type = /datum/hud/dextrous/drone - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - see_in_dark = 7 + // Going for a sort of pale green here + lighting_cutoff_red = 30 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 25 can_be_held = TRUE held_items = list(null, null) ignores_capitalism = TRUE // Yogs -- Lets drones buy a damned smoke for christ's sake diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index ff77a98efdf5..b091a7a0d843 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -11,7 +11,6 @@ emote_see = list("shakes its head.", "stamps a foot.", "glares around.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 4, /obj/item/clothing/head/yogs/goatpelt = 1) response_help = "pets" response_disarm = "gently pushes aside" @@ -127,7 +126,6 @@ emote_see = list("shakes its head.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 6) response_help = "pets" response_disarm = "gently pushes aside" @@ -349,7 +347,6 @@ emote_see = list("nibbles at the ground.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 4) response_help = "pets" response_disarm = "gently pushes aside" diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index efb43b056b3d..91b763b6e3a9 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -12,7 +12,6 @@ emote_see = list("shakes its head.", "shivers.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1) //3 -> 1, foxes aren't Big response_help = "pets" response_disarm = "gently pushes aside" diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 0db366f360e3..453cb5c9fd0f 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -29,7 +29,6 @@ GLOBAL_VAR_INIT(mouse_killed, 0) emote_see = list("runs in a circle.", "shakes.") speak_chance = 1 turns_per_move = 5 - see_in_dark = 8 maxHealth = 5 health = 5 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/mouse = 1) @@ -41,7 +40,6 @@ GLOBAL_VAR_INIT(mouse_killed, 0) pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY mob_biotypes = MOB_ORGANIC|MOB_BEAST - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE can_be_held = TRUE //mouse gaming worn_slot_flags = ITEM_SLOT_HEAD var/body_color //brown, gray and white, leave blank for random diff --git a/code/modules/mob/living/simple_animal/friendly/penguin.dm b/code/modules/mob/living/simple_animal/friendly/penguin.dm index d4042069e51d..e23795675f64 100644 --- a/code/modules/mob/living/simple_animal/friendly/penguin.dm +++ b/code/modules/mob/living/simple_animal/friendly/penguin.dm @@ -10,7 +10,6 @@ emote_see = list("shakes its beak.", "flaps it's wings.","preens itself.") faction = list("penguin") minbodytemp = 0 - see_in_dark = 5 speak_chance = 1 turns_per_move = 10 icon = 'icons/mob/penguins.dmi' diff --git a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm index 9ff6b8827553..dac773498b73 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/ranged.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/ranged.dm @@ -63,23 +63,33 @@ if(namedatum) P.color = namedatum.color -/mob/living/simple_animal/hostile/guardian/ranged/ToggleLight() +/mob/living/simple_animal/hostile/guardian/ranged/toggle_light() var/msg - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + switch(lighting_cutoff) + if (LIGHTING_CUTOFF_VISIBLE) + lighting_cutoff_red = 10 + lighting_cutoff_green = 10 + lighting_cutoff_blue = 15 msg = "You activate your night vision." - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + if (LIGHTING_CUTOFF_MEDIUM) + lighting_cutoff_red = 25 + lighting_cutoff_green = 25 + lighting_cutoff_blue = 35 msg = "You increase your night vision." - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + if (LIGHTING_CUTOFF_HIGH) + lighting_cutoff_red = 35 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 50 msg = "You maximize your night vision." else lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + lighting_cutoff_red = 0 + lighting_cutoff_green = 0 + lighting_cutoff_blue = 0 msg = "You deactivate your night vision." + sync_lighting_plane_cutoff() + to_chat(src, span_notice(msg)) - to_chat(src, span_notice("[msg]")) /mob/living/simple_animal/hostile/guardian/ranged/verb/Snare() diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index ead1ba836cb9..5561f20b757d 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -31,8 +31,10 @@ faction = list(ROLE_ALIEN) status_flags = CANPUSH minbodytemp = 0 - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Going for a dark purple here + lighting_cutoff_red = 30 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 50 unique_name = 1 gold_core_spawnable = NO_SPAWN deathsound = 'sound/voice/hiss6.ogg' diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index b8af2e8da74f..a5588ada87b6 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -14,7 +14,6 @@ speak_chance = 1 taunt_chance = 25 turns_per_move = 5 - see_in_dark = 6 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1) response_help = "pets" response_disarm = "gently pushes aside" diff --git a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm index f14228d72160..f08e6b472af7 100644 --- a/code/modules/mob/living/simple_animal/hostile/eyeballs.dm +++ b/code/modules/mob/living/simple_animal/hostile/eyeballs.dm @@ -26,3 +26,7 @@ faction = list("spooky") del_on_death = 1 random_color = FALSE + // Redish ethereal glow. These lads live on the cult ship + lighting_cutoff_red = 40 + lighting_cutoff_green = 20 + lighting_cutoff_blue = 30 diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index bfc88357e0b8..820234f07f18 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -46,8 +46,7 @@ attack_sound = 'sound/weapons/bite.ogg' unique_name = 1 gold_core_spawnable = HOSTILE_SPAWN - see_in_dark = 4 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + footstep_type = FOOTSTEP_MOB_CLAW var/busy = SPIDER_IDLE var/playable_spider = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm index 959bef634b01..af1afb4bac93 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/_jungle_mobs.dm @@ -12,6 +12,8 @@ response_harm = "strikes" status_flags = NONE a_intent = INTENT_HARM - see_in_dark = 4 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Let's do a blue, since they'll be on green turfs if this shit is ever finished + lighting_cutoff_red = 5 + lighting_cutoff_green = 20 + lighting_cutoff_blue = 25 mob_size = MOB_SIZE_LARGE diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm index 17658cc7c1b4..2a26a7060f8e 100644 --- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm +++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm @@ -9,7 +9,6 @@ turns_per_move = 5 maxHealth = 30 health = 30 - see_in_dark = 3 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/killertomato = 2) response_help = "prods" response_disarm = "pushes aside" diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm index 711b67818090..35c5c617a2b6 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm @@ -52,6 +52,10 @@ Difficulty: Medium attack_action_types = list(/datum/action/innate/megafauna_attack/create_skull, /datum/action/innate/megafauna_attack/charge_target) small_sprite_type = /datum/action/small_sprite/megafauna/legion + // Purple, but bright cause we're gonna need to spot mobs on lavaland + lighting_cutoff_red = 35 + lighting_cutoff_green = 20 + lighting_cutoff_blue = 45 /datum/action/innate/megafauna_attack/create_skull name = "Create Legion Skull" diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm index 5ee206d44c72..611a4a7d5b8a 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/hivelord.dm @@ -279,9 +279,10 @@ weather_immunities = list(WEATHER_LAVA, WEATHER_ASH) obj_damage = 30 environment_smash = ENVIRONMENT_SMASH_STRUCTURES - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - + // Purple, but bright cause we're gonna need to spot mobs on lavaland + lighting_cutoff_red = 35 + lighting_cutoff_green = 20 + lighting_cutoff_blue = 45 /mob/living/simple_animal/hostile/big_legion/Initialize(mapload) .=..() diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm index ff2ab1ed7ed9..4d78888ddba4 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/mining_mobs.dm @@ -16,8 +16,10 @@ var/crusher_loot var/throw_message = "bounces off of" var/fromtendril = FALSE - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Pale purple, should be red enough to see stuff on lavaland + lighting_cutoff_red = 25 + lighting_cutoff_green = 15 + lighting_cutoff_blue = 35 mob_size = MOB_SIZE_LARGE var/icon_aggro = null var/crusher_drop_mod = 25 diff --git a/code/modules/mob/living/simple_animal/hostile/rat.dm b/code/modules/mob/living/simple_animal/hostile/rat.dm index a99c17ffc4eb..518e8210049b 100644 --- a/code/modules/mob/living/simple_animal/hostile/rat.dm +++ b/code/modules/mob/living/simple_animal/hostile/rat.dm @@ -13,8 +13,6 @@ obj_damage = 5 speak_chance = 1 turns_per_move = 5 - see_in_dark = 6 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE maxHealth = 15 health = 15 butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/mouse = 1) diff --git a/code/modules/mob/living/simple_animal/hostile/regalrat.dm b/code/modules/mob/living/simple_animal/hostile/regalrat.dm index c117420b0f4d..b63f5d550833 100644 --- a/code/modules/mob/living/simple_animal/hostile/regalrat.dm +++ b/code/modules/mob/living/simple_animal/hostile/regalrat.dm @@ -9,7 +9,6 @@ turns_per_move = 5 maxHealth = 70 health = 70 - see_in_dark = 15 obj_damage = 10 butcher_results = list(/obj/item/clothing/head/crown = 1,) response_help = "glares at" @@ -24,7 +23,11 @@ ventcrawler = VENTCRAWLER_ALWAYS unique_name = TRUE faction = list("rat") - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Slightly brown red, for the eyes + // Might be a bit too dim + lighting_cutoff_red = 22 + lighting_cutoff_green = 8 + lighting_cutoff_blue = 5 var/datum/action/cooldown/riot var/datum/action/cooldown/domain var/opening_airlock = FALSE diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm index 25567bc1d6aa..cf4fad70e66d 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/bat.dm @@ -14,8 +14,6 @@ maxHealth = 15 health = 15 spacewalk = TRUE - see_in_dark = 10 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE harm_intent_damage = 6 melee_damage_lower = 6 melee_damage_upper = 5 diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/trianglespider.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/trianglespider.dm index 2986111e54b5..f041887315e4 100644 --- a/code/modules/mob/living/simple_animal/hostile/retaliate/trianglespider.dm +++ b/code/modules/mob/living/simple_animal/hostile/retaliate/trianglespider.dm @@ -26,5 +26,3 @@ attack_sound = 'sound/weapons/bite.ogg' unique_name = 1 gold_core_spawnable = HOSTILE_SPAWN - see_in_dark = 4 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE diff --git a/code/modules/mob/living/simple_animal/hostile/skeleton.dm b/code/modules/mob/living/simple_animal/hostile/skeleton.dm index ce1eb05e880d..5f342e06eccd 100644 --- a/code/modules/mob/living/simple_animal/hostile/skeleton.dm +++ b/code/modules/mob/living/simple_animal/hostile/skeleton.dm @@ -29,8 +29,10 @@ stat_attack = UNCONSCIOUS gold_core_spawnable = HOSTILE_SPAWN faction = list("skeleton") - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Going for a sort of pale bluegreen here, shooting for boneish + lighting_cutoff_red = 15 + lighting_cutoff_green = 25 + lighting_cutoff_blue = 35 deathmessage = "collapses into a pile of bones!" del_on_death = 1 loot = list(/obj/effect/decal/remains/human) diff --git a/code/modules/mob/living/simple_animal/hostile/smspider.dm b/code/modules/mob/living/simple_animal/hostile/smspider.dm index 52350aa77c05..ebe30b9a04a2 100644 --- a/code/modules/mob/living/simple_animal/hostile/smspider.dm +++ b/code/modules/mob/living/simple_animal/hostile/smspider.dm @@ -21,8 +21,10 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_plas" = 0, "max_plas" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) robust_searching = 1 faction = list("hostile") - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Gold, supermatter tinted + lighting_cutoff_red = 30 + lighting_cutoff_green = 30 + lighting_cutoff_blue = 10 ventcrawler = VENTCRAWLER_ALWAYS deathmessage = "falls to the ground, its shard dulling to a miserable grey!" var/overcharged = FALSE // if true, spider will not die if it dusts a limb @@ -55,4 +57,4 @@ icon_living = "smspideroc" maxHealth = 25 health = 25 - overcharged = TRUE \ No newline at end of file + overcharged = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm index 6ea19253f06b..3bab5bd24821 100644 --- a/code/modules/mob/living/simple_animal/hostile/space_dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/space_dragon.dm @@ -38,8 +38,6 @@ icon_dead = "spacedragon_dead" health_doll_icon = "spacedragon" obj_damage = 50 - see_in_dark = 7 //yogs - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE //yogs environment_smash = ENVIRONMENT_SMASH_NONE flags_1 = HEAR_1 | PREVENT_CONTENTS_EXPLOSION_1 mob_size = MOB_SIZE_LARGE diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 55c8f67fa8ba..ee396f27c7fa 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -36,8 +36,10 @@ animate_movement = NO_STEPS // Do not animate movement, you jump around as you're a scary statue. hud_possible = list(ANTAG_HUD) - see_in_dark = 13 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // Dim purple, I want it to be possible to miss people in the dark but not easy to + lighting_cutoff_red = 15 + lighting_cutoff_green = 10 + lighting_cutoff_blue = 25 vision_range = 12 aggro_vision_range = 12 @@ -64,8 +66,6 @@ flicker.Grant(src) var/datum/action/cooldown/spell/aoe/blindness/blind = new(src) blind.Grant(src) - var/datum/action/cooldown/spell/night_vision/night_vision = new(src) - night_vision.Grant(src) // Set creator if(creator) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 4ed3901312fe..ae31adfe8284 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -94,7 +94,10 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 sight = SEE_SELF|SEE_MOBS|SEE_OBJS|SEE_TURFS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + // Real green, cause of course + lighting_cutoff_red = 10 + lighting_cutoff_green = 35 + lighting_cutoff_blue = 20 faction = list("hostile","vines","plants") initial_language_holder = /datum/language_holder/venus del_on_death = TRUE diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index f8739d65a3d1..c4885bec37a1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -480,12 +480,10 @@ sight = initial(sight) else sight = (SEE_TURFS|SEE_MOBS|SEE_OBJS) - see_in_dark = 8 see_invisible = SEE_INVISIBLE_OBSERVER return see_invisible = initial(see_invisible) - see_in_dark = initial(see_in_dark) sight = initial(sight) if(SSmapping.level_trait(z, ZTRAIT_NOXRAY)) sight = null @@ -493,7 +491,7 @@ var/atom/A = client.eye if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. return - sync_lighting_plane_alpha() + sync_lighting_plane_cutoff() /mob/living/simple_animal/get_idcard(hand_first) return access_card diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index c93719de7ff2..a1847ad7a880 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -259,19 +259,25 @@ //This entire if/else chain could be in two lines but isn't for readibilties sake. var/msg = message + var/msg_type = MSG_VISUAL + if(M.see_invisible < invisibility)//if src is invisible to M msg = blind_message + msg_type = MSG_AUDIBLE else if(T != loc && T != src) //if src is inside something and not a turf. + if(M != loc) // Only give the blind message to hearers that aren't the location + msg = blind_message + msg_type = MSG_AUDIBLE + else if(!HAS_TRAIT(M, TRAIT_HEAR_THROUGH_DARKNESS) && M.lighting_cutoff < LIGHTING_CUTOFF_HIGH && T.is_softly_lit() && !in_range(T,M)) //if it is too dark, unless we're right next to them. msg = blind_message - else if(M.lighting_alpha > LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE && T.is_softly_lit() && !in_range(T,M)) //if it is too dark. - msg = blind_message + msg_type = MSG_AUDIBLE if(!msg) continue if(visible_message_flags & EMOTE_MESSAGE && runechat_prefs_check(M, visible_message_flags) && !is_blind(M)) M.create_chat_message(src, raw_message = raw_msg, runechat_flags = visible_message_flags) - M.show_message(msg, MSG_VISUAL, blind_message, MSG_AUDIBLE) + M.show_message(msg, msg_type, blind_message, MSG_AUDIBLE) @@ -1240,15 +1246,15 @@ ///Update the lighting plane and sight of this mob (sends COMSIG_MOB_UPDATE_SIGHT) /mob/proc/update_sight() SEND_SIGNAL(src, COMSIG_MOB_UPDATE_SIGHT) - sync_lighting_plane_alpha() + sync_lighting_plane_cutoff() ///Set the lighting plane hud alpha to the mobs lighting_alpha var -/mob/proc/sync_lighting_plane_alpha() - if(hud_used) - var/atom/movable/screen/plane_master/lighting/L = hud_used.plane_masters["[LIGHTING_PLANE]"] - if (L) - L.alpha = lighting_alpha - +/mob/proc/sync_lighting_plane_cutoff() + if(!hud_used) + return + for(var/atom/movable/screen/plane_master/rendering_plate/lighting/light as anything in hud_used.get_true_plane_masters(RENDER_PLANE_LIGHTING)) + light.set_light_cutoff(lighting_cutoff, lighting_color_cutoffs) + ///Update the mouse pointer of the attached client in this mob /mob/proc/update_mouse_pointer() if (!client) @@ -1266,6 +1272,10 @@ if(client.mouse_override_icon) client.mouse_pointer_icon = client.mouse_override_icon +/mob/proc/has_nightvision() + // Somewhat conservative, basically is your lighting plane bright enough that you the user can see stuff + var/light_offset = (lighting_color_cutoffs[1] + lighting_color_cutoffs[2] + lighting_color_cutoffs[3]) / 3 + lighting_cutoff + return light_offset >= LIGHTING_NIGHTVISION_THRESHOLD ///This mob is abile to read books /mob/proc/is_literate() diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 469261640cb2..341dbcafdd13 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -17,8 +17,23 @@ mouse_drag_pointer = MOUSE_ACTIVE_POINTER throwforce = 10 blocks_emissive = EMISSIVE_BLOCK_GENERIC - - var/lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + // we never want to hide a turf because it's not lit + // We can rely on the lighting plane to handle that for us + see_in_dark = 1e6 + + /// Percentage of how much rgb to max the lighting plane at + /// This lets us brighten it without washing out color + /// Scale from 0-100, reset off update_sight() + var/lighting_cutoff = LIGHTING_CUTOFF_VISIBLE + // Individual color max for red, we can use this to color darkness without tinting the light + var/lighting_cutoff_red = 0 + // Individual color max for green, we can use this to color darkness without tinting the light + var/lighting_cutoff_green = 0 + // Individual color max for blue, we can use this to color darkness without tinting the light + var/lighting_cutoff_blue = 0 + /// A list of red, green and blue cutoffs + /// This is what actually gets applied to the mob, it's modified by things like glasses + var/list/lighting_color_cutoffs = null var/datum/mind/mind var/static/next_mob_id = 0 /// The current client inhabiting this mob. Managed by login/logout @@ -234,3 +249,4 @@ var/datum/focus var/fake_client = FALSE // Currently only used for examines + diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index d42751d8181b..e9b5fe3be285 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -612,3 +612,8 @@ if(chosen_bodypart.status < BODYPART_ROBOTIC) amount += chosen_bodypart.burn_dam return amount + +/mob/proc/default_lighting_cutoff() + if(client?.combo_hud_enabled && client?.prefs?.toggles & COMBOHUD_LIGHTING) + return LIGHTING_CUTOFF_FULLBRIGHT + return initial(lighting_cutoff) diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index 345156098958..a94f8efeaa0f 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -122,3 +122,31 @@ // 10C has 3 range (2 tiles) // 0C has 0 range (0 tiles) infra_luminosity = round(max((bodytemperature - T0C)/3, 0)) + +/// Sight here is the mob.sight var, which tells byond what to actually show to our client +/// See [code\__DEFINES\sight.dm] for more details +/mob/proc/set_sight(new_value) + SHOULD_CALL_PARENT(TRUE) + if(sight == new_value) + return + var/old_sight = sight + sight = new_value + + SEND_SIGNAL(src, COMSIG_MOB_SIGHT_CHANGE, new_value, old_sight) + +/mob/proc/add_sight(new_value) + set_sight(sight | new_value) + +/mob/proc/clear_sight(new_value) + set_sight(sight & ~new_value) + +/// see invisibility is the mob's capability to see things that ought to be hidden from it +/// Can think of it as a primitive version of changing the alpha of planes +/// We mostly use it to hide ghosts, no real reason why +/mob/proc/set_invis_see(new_sight) + SHOULD_CALL_PARENT(TRUE) + if(new_sight == see_invisible) + return + var/old_invis = see_invisible + see_invisible = new_sight + SEND_SIGNAL(src, COMSIG_MOB_SEE_INVIS_CHANGE, see_invisible, old_invis) diff --git a/code/modules/research/xenobiology/crossbreeding/_structures.dm b/code/modules/research/xenobiology/crossbreeding/_structures.dm index 32243aeb67a1..9b2584ab207b 100644 --- a/code/modules/research/xenobiology/crossbreeding/_structures.dm +++ b/code/modules/research/xenobiology/crossbreeding/_structures.dm @@ -424,7 +424,7 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals) blood_amt -= 50 to_chat(user, span_notice("You touch the crystal, and see blood transforming into an organ!")) playsound(src, 'sound/magic/demon_consume.ogg', 50, 1) - var/type = pick(/obj/item/reagent_containers/food/snacks/meat/slab,/obj/item/organ/heart,/obj/item/organ/heart/freedom,/obj/item/organ/lungs,/obj/item/organ/lungs/plasmaman,/obj/item/organ/lungs/ethereal,/obj/item/organ/lungs/slime,/obj/item/organ/liver,/obj/item/organ/liver/plasmaman,/obj/item/organ/liver/alien,/obj/item/organ/eyes,/obj/item/organ/eyes/night_vision/alien,/obj/item/organ/eyes/night_vision,/obj/item/organ/eyes/night_vision/mushroom,/obj/item/organ/tongue,/obj/item/organ/stomach,/obj/item/organ/stomach/plasmaman,/obj/item/organ/stomach/cell/ethereal,/obj/item/organ/ears,/obj/item/organ/ears/cat,/obj/item/organ/ears/penguin) + var/type = pick(/obj/item/reagent_containers/food/snacks/meat/slab,/obj/item/organ/heart,/obj/item/organ/heart/freedom,/obj/item/organ/lungs,/obj/item/organ/lungs/plasmaman,/obj/item/organ/lungs/ethereal,/obj/item/organ/lungs/slime,/obj/item/organ/liver,/obj/item/organ/liver/plasmaman,/obj/item/organ/liver/alien,/obj/item/organ/eyes,/obj/item/organ/eyes/alien,/obj/item/organ/eyes/night_vision,/obj/item/organ/eyes/night_vision/mushroom,/obj/item/organ/tongue,/obj/item/organ/stomach,/obj/item/organ/stomach/plasmaman,/obj/item/organ/stomach/cell/ethereal,/obj/item/organ/ears,/obj/item/organ/ears/cat,/obj/item/organ/ears/penguin) new type(get_turf(src)) /obj/structure/slime_crystal/red/attacked_by(obj/item/I, mob/living/user) diff --git a/code/modules/shuttle/navigation_computer.dm b/code/modules/shuttle/navigation_computer.dm index c38dcbb9c178..ab2f851020b4 100644 --- a/code/modules/shuttle/navigation_computer.dm +++ b/code/modules/shuttle/navigation_computer.dm @@ -286,8 +286,9 @@ /mob/camera/aiEye/remote/shuttle_docker/update_remote_sight(mob/living/user) user.sight = BLIND|SEE_TURFS - user.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - user.sync_lighting_plane_alpha() + // Pale blue, should look nice I think + user.lighting_color_cutoffs = list(30, 40, 50) + user.sync_lighting_plane_cutoff() return TRUE /datum/action/innate/shuttledocker_rotate diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm index f8c60e4eb9de..23742a544efe 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm @@ -15,8 +15,9 @@ /mob/camera/aiEye/remote/shuttle_creation/update_remote_sight(mob/living/user) user.sight = BLIND|SEE_TURFS - user.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - user.sync_lighting_plane_alpha() + // Pale blue, should look nice I think + user.lighting_color_cutoffs = list(30, 40, 50) + user.sync_lighting_plane_cutoff() return TRUE /mob/camera/aiEye/remote/shuttle_creation/relaymove(mob/user, direct) diff --git a/code/modules/spells/spell_types/self/night_vision.dm b/code/modules/spells/spell_types/self/night_vision.dm deleted file mode 100644 index c3b3fc9977fa..000000000000 --- a/code/modules/spells/spell_types/self/night_vision.dm +++ /dev/null @@ -1,39 +0,0 @@ -//Toggle Night Vision -/datum/action/cooldown/spell/night_vision - name = "Toggle Nightvision" - desc = "Toggle your nightvision mode." - - cooldown_time = 1 SECONDS - spell_requirements = NONE - - /// The span the "toggle" message uses when sent to the user - var/toggle_span = "notice" - -/datum/action/cooldown/spell/night_vision/New(Target) - . = ..() - name = "[name] \[ON\]" - -/datum/action/cooldown/spell/night_vision/is_valid_target(atom/cast_on) - return isliving(cast_on) - -/datum/action/cooldown/spell/night_vision/cast(mob/living/cast_on) - . = ..() - to_chat(cast_on, "You toggle your night vision.") - - var/next_mode_text = "" - switch(cast_on.lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - cast_on.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - next_mode_text = "More" - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - cast_on.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - next_mode_text = "Full" - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - cast_on.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - next_mode_text = "OFF" - else - cast_on.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - next_mode_text = "ON" - - cast_on.update_sight() - name = "[initial(name)] \[[next_mode_text]\]" \ No newline at end of file diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index dd838e18ccfb..3a1fef1a4bcf 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -20,14 +20,16 @@ low_threshold_cleared = span_info("Your vision is cleared of any ailment.") var/sight_flags = 0 - var/see_in_dark = 2 var/tint = 0 var/eye_color = "" //set to a hex code to override a mob's eye color var/eye_icon_state = "eyes" var/old_eye_color = "fff" var/flash_protect = 0 var/see_invisible = SEE_INVISIBLE_LIVING - var/lighting_alpha + /// How much darkness to cut out of your view (basically, night vision) + var/lighting_cutoff = null + /// List of color cutoffs from eyes, or null if not applicable + var/list/color_cutoffs = null var/no_glasses var/damaged = TRUE //damaged indicates that our eyes are undergoing some level of negative effect,starts as true so it removes the impaired vision overlay if it is replacing damaged eyes @@ -40,8 +42,6 @@ HMN.eye_color = eye_color else eye_color = HMN.eye_color - if(HAS_TRAIT(HMN, TRAIT_NIGHT_VISION) && !lighting_alpha) - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT M.update_tint() owner.update_sight() if(M.has_dna() && ishuman(M)) @@ -117,38 +117,64 @@ #undef OFFSET_X #undef OFFSET_Y +#define NIGHTVISION_LIGHT_OFF 0 +#define NIGHTVISION_LIGHT_LOW 1 +#define NIGHTVISION_LIGHT_MID 2 +#define NIGHTVISION_LIGHT_HIG 3 + /obj/item/organ/eyes/night_vision name = "shadow eyes" desc = "A spooky set of eyes that can see in the dark." - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + actions_types = list(/datum/action/item_action/organ_action/use) - var/night_vision = TRUE + // These lists are used as the color cutoff for the eye + // They need to be filled out for subtypes + var/list/low_light_cutoff + var/list/medium_light_cutoff + var/list/high_light_cutoff + var/light_level = NIGHTVISION_LIGHT_OFF + +/obj/item/organ/eyes/night_vision/Initialize(mapload) + . = ..() + if (PERFORM_ALL_TESTS(focus_only/nightvision_color_cutoffs) && type != /obj/item/organ/eyes/night_vision) + if(length(low_light_cutoff) != 3 || length(medium_light_cutoff) != 3 || length(high_light_cutoff) != 3) + stack_trace("[type] did not have fully filled out color cutoff lists") + if(low_light_cutoff) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW /obj/item/organ/eyes/night_vision/ui_action_click() sight_flags = initial(sight_flags) - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + switch(light_level) + if (NIGHTVISION_LIGHT_OFF) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW + if (NIGHTVISION_LIGHT_LOW) + color_cutoffs = medium_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_MID + if (NIGHTVISION_LIGHT_MID) + color_cutoffs = high_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_HIG else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - sight_flags &= ~SEE_BLACKNESS + color_cutoffs = list() + light_level = NIGHTVISION_LIGHT_OFF owner.update_sight() -/obj/item/organ/eyes/night_vision/alien +#undef NIGHTVISION_LIGHT_OFF +#undef NIGHTVISION_LIGHT_LOW +#undef NIGHTVISION_LIGHT_MID +#undef NIGHTVISION_LIGHT_HIG + +/obj/item/organ/eyes/alien name = "alien eyes" desc = "It turned out they had them after all!" sight_flags = SEE_MOBS -/obj/item/organ/eyes/night_vision/zombie +/obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." -/obj/item/organ/eyes/night_vision/nightmare +/obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" @@ -182,9 +208,10 @@ name = "\improper meson eyes" desc = "These cybernetic eyes will give you meson-vision. Looks like it could withstand seeing a supermatter crystal!." eye_color = "00FF00" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) sight_flags = SEE_TURFS - see_in_dark = 4 + /obj/item/organ/eyes/robotic/xray/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE, initialising) . = ..() @@ -199,16 +226,15 @@ desc = "These cybernetic eyes will give you true X-ray vision. Blinking is futile." eye_color = "000" sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS - see_in_dark = 8 /obj/item/organ/eyes/robotic/thermals name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." eye_color = "FC0" sight_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) flash_protect = -1 - see_in_dark = 8 /obj/item/organ/eyes/robotic/flashlight name = "flashlight eyes" @@ -455,5 +481,15 @@ /obj/item/organ/eyes/polysmorph name = "polysmorph eyes" desc = "Eyes from a polysmorph, capable of retaining slightly more vision in low light environments" - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT - see_in_dark = 5 + color_cutoffs = list(25, 5, 42) + +/obj/item/organ/eyes/zombie + name = "undead eyes" + desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) + +/obj/item/organ/eyes/alien + name = "alien eyes" + desc = "It turned out they had them after all!" + sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) diff --git a/yogstation.dme b/yogstation.dme index 23b33a2472d9..dd062cd59f21 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -152,6 +152,7 @@ #include "code\__DEFINES\dcs\signals\signals_global.dm" #include "code\__DEFINES\dcs\signals\signals_global_object.dm" #include "code\__DEFINES\dcs\signals\signals_heretic.dm" +#include "code\__DEFINES\dcs\signals\signals_huds.dm" #include "code\__DEFINES\dcs\signals\signals_janitor.dm" #include "code\__DEFINES\dcs\signals\signals_mood.dm" #include "code\__DEFINES\dcs\signals\signals_moveloop.dm" @@ -201,6 +202,7 @@ #include "code\__DEFINES\{yogs_defines}\wires.dm" #include "code\__HELPERS\_lists.dm" #include "code\__HELPERS\_logging.dm" +#include "code\__HELPERS\_planes.dm" #include "code\__HELPERS\_string_lists.dm" #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" @@ -475,6 +477,7 @@ #include "code\datums\actions\items\stealth_box.dm" #include "code\datums\actions\items\toggles.dm" #include "code\datums\actions\items\vortex_recall.dm" +#include "code\datums\actions\mobs\adjust_vision.dm" #include "code\datums\actions\mobs\language_menu.dm" #include "code\datums\actions\mobs\ninja.dm" #include "code\datums\actions\mobs\small_sprite.dm" @@ -3601,7 +3604,6 @@ #include "code\modules\spells\spell_types\self\lichdom.dm" #include "code\modules\spells\spell_types\self\mime_vow.dm" #include "code\modules\spells\spell_types\self\mutate.dm" -#include "code\modules\spells\spell_types\self\night_vision.dm" #include "code\modules\spells\spell_types\self\personality_commune.dm" #include "code\modules\spells\spell_types\self\rod_form.dm" #include "code\modules\spells\spell_types\self\smoke.dm" diff --git a/yogstation/code/game/gamemodes/shadowling/shadowling.dm b/yogstation/code/game/gamemodes/shadowling/shadowling.dm index 44b224ba7e78..8c49e5e19ca0 100644 --- a/yogstation/code/game/gamemodes/shadowling/shadowling.dm +++ b/yogstation/code/game/gamemodes/shadowling/shadowling.dm @@ -146,7 +146,7 @@ Made by Xhuis inherent_traits = list(TRAIT_NOGUNS, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_PIERCEIMMUNE) no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_EYES, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE) nojumpsuit = TRUE - mutanteyes = /obj/item/organ/eyes/night_vision/alien/sling + mutanteyes = /obj/item/organ/eyes/alien/sling burnmod = 1.5 //1.5x burn damage, 2x is excessive heatmod = 1.5 var/mutable_appearance/eyes_overlay diff --git a/yogstation/code/game/gamemodes/vampire/vampire_bat.dm b/yogstation/code/game/gamemodes/vampire/vampire_bat.dm index 75fd9ccf8341..80abc4fb8fad 100644 --- a/yogstation/code/game/gamemodes/vampire/vampire_bat.dm +++ b/yogstation/code/game/gamemodes/vampire/vampire_bat.dm @@ -13,8 +13,6 @@ maxHealth = 20 health = 20 speed = 0 - see_in_dark = 10 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE harm_intent_damage = 7 melee_damage_lower = 5 melee_damage_upper = 7 diff --git a/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm b/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm index 4990a34d07d3..d52ee24b9c75 100644 --- a/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm +++ b/yogstation/code/modules/antagonists/shadowling/shadowling_abilities.dm @@ -993,30 +993,30 @@ spell_requirements = NONE -/datum/action/cooldown/spell/thrall_night_vision/cast(mob/living/carbon/human/user) - . = ..() - if(!.) - return FALSE - if(!is_shadow_or_thrall(user)) - return - var/obj/item/organ/eyes/eyes = user.getorganslot(ORGAN_SLOT_EYES) - if(!eyes) - return - eyes.sight_flags = initial(eyes.sight_flags) - switch(eyes.lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - eyes.see_in_dark = 8 - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE - else - eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - eyes.see_in_dark = 2 //default - user.update_sight() - - return TRUE +// /datum/action/cooldown/spell/thrall_night_vision/cast(mob/living/carbon/human/user) +// . = ..() +// if(!.) +// return FALSE +// if(!is_shadow_or_thrall(user)) +// return +// var/obj/item/organ/eyes/eyes = user.getorganslot(ORGAN_SLOT_EYES) +// if(!eyes) +// return +// eyes.sight_flags = initial(eyes.sight_flags) +// switch(eyes.lighting_alpha) +// if (LIGHTING_PLANE_ALPHA_VISIBLE) +// eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE +// eyes.see_in_dark = 8 +// if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) +// eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE +// if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) +// eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE +// else +// eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE +// eyes.see_in_dark = 2 //default +// user.update_sight() + +// return TRUE /datum/action/cooldown/spell/lesser_shadowling_hivemind //Lets a thrall talk with their allies name = "Lesser Commune" diff --git a/yogstation/code/modules/antagonists/slaughter/slaughter.dm b/yogstation/code/modules/antagonists/slaughter/slaughter.dm index ed62fb6cd5ed..75e90ee01660 100644 --- a/yogstation/code/modules/antagonists/slaughter/slaughter.dm +++ b/yogstation/code/modules/antagonists/slaughter/slaughter.dm @@ -32,8 +32,6 @@ wound_bonus = -10 bare_wound_bonus = 0 sharpness = SHARP_EDGED - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \ Alt-click blood pools to travel through them, appearing and disappearing from the station at will. \ diff --git a/yogstation/code/modules/clothing/glasses/_glasses.dm b/yogstation/code/modules/clothing/glasses/_glasses.dm index d79a523f5a98..9070e85df29d 100644 --- a/yogstation/code/modules/clothing/glasses/_glasses.dm +++ b/yogstation/code/modules/clothing/glasses/_glasses.dm @@ -3,7 +3,6 @@ desc = "Made in china" icon_state = "sun" item_state = "sunglasses" - darkness_view = 1 flash_protect = 0 tint = 1 glass_colour_type = /datum/client_colour/glass_colour/gray @@ -25,4 +24,4 @@ name = "eye patch" desc = "Arrrggg now you too can be a real pirate matey." icon_state = "eyepatch" - item_state = "eyepatch" \ No newline at end of file + item_state = "eyepatch" diff --git a/yogstation/code/modules/guardian/guardian.dm b/yogstation/code/modules/guardian/guardian.dm index d2d02ad0f4e6..f4f711438dd3 100644 --- a/yogstation/code/modules/guardian/guardian.dm +++ b/yogstation/code/modules/guardian/guardian.dm @@ -50,7 +50,6 @@ GLOBAL_LIST_INIT(guardian_projectile_damage, list( light_range = 3 light_on = FALSE hud_type = /datum/hud/guardian - see_in_dark = 8 var/list/barrier_images = list() var/custom_name = FALSE var/atk_cooldown = 10 diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/darkspawn.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/darkspawn.dm index 6d9808c035f0..0087efc26d69 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/darkspawn.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/darkspawn.dm @@ -13,7 +13,7 @@ no_equip = list(ITEM_SLOT_MASK, ITEM_SLOT_OCLOTHING, ITEM_SLOT_GLOVES, ITEM_SLOT_FEET, ITEM_SLOT_ICLOTHING, ITEM_SLOT_SUITSTORE, ITEM_SLOT_HEAD) species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYESPRITES,NOFLASH) inherent_traits = list(TRAIT_NOGUNS, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_PIERCEIMMUNE, TRAIT_NODISMEMBER, TRAIT_NOHUNGER) - mutanteyes = /obj/item/organ/eyes/night_vision/alien + mutanteyes = /obj/item/organ/eyes/alien var/list/upgrades = list() COOLDOWN_DECLARE(reflect_cd_1) COOLDOWN_DECLARE(reflect_cd_2) diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 6e47fd34d5c7..037da0f9230a 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -1,8 +1,11 @@ +#define NIGHTVISION_LIGHT_OFF 0 +#define NIGHTVISION_LIGHT_LOW 1 +#define NIGHTVISION_LIGHT_MID 2 +#define NIGHTVISION_LIGHT_HIG 3 + /obj/item/organ/eyes/robotic/preternis name = "preternis eyes" desc = "An experimental upgraded version of eyes that can see in the dark. They are designed to fit preternis" - see_in_dark = PRETERNIS_NV_ON - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE //preternis eyes need to be powered by a preternis to function, in a non preternis they slowly power down to blindness status = ORGAN_ROBOTIC organ_flags = ORGAN_SYNTHETIC @@ -17,22 +20,34 @@ var/powered = TRUE actions_types = list(/datum/action/item_action/organ_action/use) var/night_vision = TRUE + // These lists are used as the color cutoff for the eye + // They need to be filled out for subtypes + var/list/low_light_cutoff + var/list/medium_light_cutoff + var/list/high_light_cutoff + var/light_level = NIGHTVISION_LIGHT_OFF + + + /obj/item/organ/eyes/robotic/preternis/ui_action_click() if(damage > low_threshold) //no nightvision if your eyes are hurt return sight_flags = initial(sight_flags) - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + switch(light_level) + if (NIGHTVISION_LIGHT_OFF) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW + if (NIGHTVISION_LIGHT_LOW) + color_cutoffs = medium_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_MID + if (NIGHTVISION_LIGHT_MID) + color_cutoffs = high_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_HIG else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - sight_flags &= ~SEE_BLACKNESS + color_cutoffs = list() + light_level = NIGHTVISION_LIGHT_OFF owner.update_sight() /obj/item/organ/eyes/robotic/preternis/on_life() @@ -52,19 +67,11 @@ //to simulate running out of power, they take damage owner.adjustOrganLoss(ORGAN_SLOT_EYES,0.5) - if(damage < low_threshold) - if(see_in_dark == PRETERNIS_NV_OFF) - see_in_dark = PRETERNIS_NV_ON - owner.update_sight() - else - //if your eyes start getting hurt no more nightvision - if(see_in_dark == PRETERNIS_NV_ON) - see_in_dark = PRETERNIS_NV_OFF - owner.update_sight() - if(lighting_alpha < LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - sight_flags &= ~SEE_BLACKNESS - owner.update_sight() +#undef NIGHTVISION_LIGHT_OFF +#undef NIGHTVISION_LIGHT_LOW +#undef NIGHTVISION_LIGHT_MID +#undef NIGHTVISION_LIGHT_HIG + /obj/item/organ/eyes/robotic/preternis/examine(mob/user) . = ..() diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/szlachta.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/szlachta.dm index dd1a717f7b14..be23ef61881f 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/szlachta.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/szlachta.dm @@ -17,7 +17,7 @@ inherent_traits = list(TRAIT_NOGUNS, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE, TRAIT_NOBREATH, TRAIT_RADIMMUNE, TRAIT_VIRUSIMMUNE, TRAIT_PIERCEIMMUNE, TRAIT_NODISMEMBER, TRAIT_MONKEYLIKE, TRAIT_NOCRITDAMAGE, TRAIT_GENELESS, TRAIT_NOSOFTCRIT, TRAIT_NOHARDCRIT, TRAIT_HARDLY_WOUNDED, TRAIT_HUSK) - mutanteyes = /obj/item/organ/eyes/night_vision/alien + mutanteyes = /obj/item/organ/eyes/alien /datum/species/szlachta/on_species_gain(mob/living/carbon/C, datum/species/old_species) . = ..() diff --git a/yogstation/code/modules/mob/living/living.dm b/yogstation/code/modules/mob/living/living.dm index 772af13c60b8..5a123f460b41 100644 --- a/yogstation/code/modules/mob/living/living.dm +++ b/yogstation/code/modules/mob/living/living.dm @@ -17,5 +17,5 @@ /mob/living/update_sight() . = ..() for(var/mob/living/simple_animal/hostile/guardian/holopara as anything in hasparasites()) - holopara.lighting_alpha = lighting_alpha + holopara.lighting_cutoff = lighting_cutoff holopara.update_sight() diff --git a/yogstation/code/modules/surgery/organs/shadowling_organs.dm b/yogstation/code/modules/surgery/organs/shadowling_organs.dm index 309ac0e96d12..1182b11f6ed6 100644 --- a/yogstation/code/modules/surgery/organs/shadowling_organs.dm +++ b/yogstation/code/modules/surgery/organs/shadowling_organs.dm @@ -1,5 +1,5 @@ //Snowflake spot for putting sling organ related stuff -/obj/item/organ/eyes/night_vision/alien/sling +/obj/item/organ/eyes/alien/sling name = "shadowling eyes" desc = "The eyes of a spooky shadowling!" @@ -62,7 +62,7 @@ playsound(S, 'sound/effects/bang.ogg', 50, 1) return FALSE var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES) - eyes.lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE + eyes.lighting_cutoff = LIGHTING_CUTOFF_VISIBLE eyes.sight_flags = initial(eyes.sight_flags) M.update_sight() M.remove_thrall() From 37f0215268108f74ea5c2f02379b727facb4bddd Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:01:43 -0500 Subject: [PATCH 002/144] fix this --- code/__DEFINES/lighting.dm | 15 ++++++--------- code/_onclick/hud/plane_master.dm | 32 +++++++++++++++---------------- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index a377464d4248..b1c2408dd2c4 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -90,10 +90,13 @@ #define FLASH_LIGHT_POWER 3 #define FLASH_LIGHT_RANGE 3.8 +// Emissive blocking. /// 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 +#define EMISSIVE_BLOCK_GENERIC 0 /// 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 +#define EMISSIVE_BLOCK_UNIQUE 1 +/// Don't block any emissives. Useful for things like, pieces of paper? +#define EMISSIVE_BLOCK_NONE 2 /// Returns the red part of a #RRGGBB hex sequence as number #define GETREDPART(hexa) hex2num(copytext(hexa, 2, 4)) @@ -119,13 +122,7 @@ do { \ }; \ } while (FALSE) -// Emissive blocking. -/// 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 0 -/// 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 1 -/// Don't block any emissives. Useful for things like, pieces of paper? -#define EMISSIVE_BLOCK_NONE 2 + #define _EMISSIVE_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, val,val,val,0) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index fdd372ddbe0f..50bc5e6d5cbe 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -87,7 +87,7 @@ /atom/movable/screen/plane_master/transparent_floor name = "Transparent Floor" - // documentation = "Really just openspace, stuff that is a turf but has no color or alpha whatsoever.\ + // documentation = "Really just openspace, stuff that is a turf but has no color or alpha whatsoever. //
We use this to draw to just the light mask plane, cause if it's not there we get holes of blackness over openspace" plane = TRANSPARENT_FLOOR_PLANE render_relay_planes = list(LIGHT_MASK_PLANE) @@ -130,7 +130,7 @@ /atom/movable/screen/plane_master/wall_upper name = "Upper wall" - // documentation = "There are some walls that want to render above most things (mostly minerals since they shift over.\ + // documentation = "There are some walls that want to render above most things (mostly minerals since they shift over. //
We draw them to their own plane so we can hijack them for our emissive mask stuff" plane = WALL_PLANE_UPPER render_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) @@ -326,9 +326,9 @@ /atom/movable/screen/plane_master/parallax name = "Parallax" - // documentation = "Contains parallax, or to be more exact the screen objects that hold parallax.\ - //
Note the BLEND_MULTIPLY. The trick here is how low our plane value is. Because of that, we draw below almost everything in the game.\ - //
We abuse this to ensure we multiply against the Parallax whitifier plane, or space's plane. It's set to full white, so when you do the multiply you just get parallax out where it well, makes sense to be.\ + // documentation = "Contains parallax, or to be more exact the screen objects that hold parallax. + //
Note the BLEND_MULTIPLY. The trick here is how low our plane value is. Because of that, we draw below almost everything in the game. + //
We abuse this to ensure we multiply against the Parallax whitifier plane, or space's plane. It's set to full white, so when you do the multiply you just get parallax out where it well, makes sense to be. //
Also notice that the parent parallax plane is mirrored down to all children. We want to support viewing parallax across all z levels at once." plane = PLANE_SPACE_PARALLAX appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR @@ -419,12 +419,12 @@ ///Contains all lighting objects /atom/movable/screen/plane_master/rendering_plate/lighting name = "Lighting plate" - // documentation = "Anything on this plane will be multiplied with the plane it's rendered onto (typically the game plane).\ - //
That's how lighting functions at base. Because it uses BLEND_MULTIPLY and occasionally color matrixes, it needs a backdrop of blackness.\ - //
See This byond post\ - //
Lemme see uh, we're masked by the emissive plane so it can actually function (IE: make things glow in the dark).\ - //
We're also masked by the overlay lighting plane, which contains all the movable lights in the game. It draws to us and also the game plane.\ - //
Masks us out so it has the breathing room to apply its effect.\ + // documentation = "Anything on this plane will be multiplied with the plane it's rendered onto (typically the game plane). + //
That's how lighting functions at base. Because it uses BLEND_MULTIPLY and occasionally color matrixes, it needs a backdrop of blackness. + //
See This byond post + //
Lemme see uh, we're masked by the emissive plane so it can actually function (IE: make things glow in the dark). + //
We're also masked by the overlay lighting plane, which contains all the movable lights in the game. It draws to us and also the game plane. + //
Masks us out so it has the breathing room to apply its effect. //
Oh and we quite often have our alpha changed to achive night vision effects, or things of that sort." plane = RENDER_PLANE_LIGHTING blend_mode_override = BLEND_MULTIPLY @@ -542,11 +542,11 @@ /atom/movable/screen/plane_master/rendering_plate/light_mask name = "Light Mask" - // documentation = "Any part of this plane that is transparent will be black below it on the game rendering plate.\ - //
This is done to ensure emissives and overlay lights don't light things up \"through\" the darkness that normally sits at the bottom of the lighting plane.\ - //
We relay copies of the space, floor and wall planes to it, so we can use them as masks. Then we just boost any existing alpha to 100% and we're done.\ - //
If we ever switch to a sight setup that shows say, mobs but not floors, we instead mask just overlay lighting and emissives.\ -
This avoids dumb seethrough without breaking stuff like thermals." + // documentation = "Any part of this plane that is transparent will be black below it on the game rendering plate. + //
This is done to ensure emissives and overlay lights don't light things up \"through\" the darkness that normally sits at the bottom of the lighting plane. + //
We relay copies of the space, floor and wall planes to it, so we can use them as masks. Then we just boost any existing alpha to 100% and we're done. + //
If we ever switch to a sight setup that shows say, mobs but not floors, we instead mask just overlay lighting and emissives. + //
This avoids dumb seethrough without breaking stuff like thermals." plane = LIGHT_MASK_PLANE appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR // Fullwhite where there's any color, no alpha otherwise From 1748bc149852a43fcc8c8cbc88bebf0d007f21b9 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:12:21 -0500 Subject: [PATCH 003/144] this too ggg --- code/__DEFINES/layers.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index c8598014fce9..7adfdd278ab6 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -107,7 +107,6 @@ #define EMISSIVE_PLANE 13 #define EMISSIVE_LAYER 13 -#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" /// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas. #define EMISSIVE_RENDER_PLATE 14 From 56d58505ca621c2ac8015ddd5c7150db5d28c914 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:59:11 -0500 Subject: [PATCH 004/144] remove this stupid --- code/modules/surgery/organs/eyes.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 3a1fef1a4bcf..a043d0794bef 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -136,9 +136,9 @@ /obj/item/organ/eyes/night_vision/Initialize(mapload) . = ..() - if (PERFORM_ALL_TESTS(focus_only/nightvision_color_cutoffs) && type != /obj/item/organ/eyes/night_vision) - if(length(low_light_cutoff) != 3 || length(medium_light_cutoff) != 3 || length(high_light_cutoff) != 3) - stack_trace("[type] did not have fully filled out color cutoff lists") + + if(length(low_light_cutoff) != 3 || length(medium_light_cutoff) != 3 || length(high_light_cutoff) != 3) + stack_trace("[type] did not have fully filled out color cutoff lists") if(low_light_cutoff) color_cutoffs = low_light_cutoff.Copy() light_level = NIGHTVISION_LIGHT_LOW From 8ad08b2b9998c29eb85da8f796677e202541b00d Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 28 Nov 2023 23:00:42 -0500 Subject: [PATCH 005/144] haha fuck --- code/__DEFINES/sight.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 7952d9addd21..97fc5aed3fb5 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -33,3 +33,7 @@ /// Bitfield of sight flags that show THINGS but no lighting /// Since lighting is an underlay on turfs, this is everything but that #define SEE_AVOID_TURF_BLACKNESS (SEE_MOBS|SEE_OBJS) + +#define VISOR_TINT (1<<1) +#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses +#define VISOR_DARKNESSVIEW (1<<3) From 46b86dc327ad46a4a68d2638e8c9689895ce09fd Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 01:00:29 -0500 Subject: [PATCH 006/144] oh my fuck what am I doing --- code/__DEFINES/dcs/signals/mapping.dm | 2 + code/__DEFINES/dcs/signals/signals_global.dm | 2 + code/__DEFINES/dcs/signals/signals_huds.dm | 8 + .../dcs/signals/signals_mob/signals_living.dm | 4 + code/__DEFINES/layers.dm | 55 +- code/__DEFINES/misc.dm | 30 + code/__DEFINES/traits.dm | 5 + code/__HELPERS/_planes.dm | 75 +- code/__HELPERS/filters.dm | 305 +++++++- code/_onclick/hud/hud.dm | 38 +- code/_onclick/hud/plane_master.dm | 737 ++++-------------- code/_onclick/hud/plane_master_controller.dm | 103 +++ code/_onclick/hud/plane_master_group.dm | 199 +++++ code/_onclick/hud/plane_master_subtypes.dm | 447 +++++++++++ code/_onclick/hud/render_plate.dm | 386 +++++++++ code/controllers/subsystem/events.dm | 1 + code/controllers/subsystem/mapping.dm | 3 + code/datums/brain_damage/creepy_trauma.dm | 2 +- code/datums/brain_damage/mild.dm | 2 +- code/datums/components/hide_highest_offset.dm | 24 + code/datums/datum.dm | 36 + .../diseases/advance/symptoms/sensory.dm | 6 +- .../diseases/advance/symptoms/vision.dm | 4 +- code/datums/diseases/sleepy.dm | 4 +- code/datums/martial/flying_fang.dm | 2 +- .../status_effects/debuffs/drowsiness.dm | 2 +- code/datums/status_effects/debuffs/drunk.dm | 2 +- .../status_effects/debuffs/screen_blur.dm | 52 ++ code/game/atoms.dm | 19 +- code/game/machinery/slotmachine.dm | 2 +- code/game/objects/items.dm | 6 +- code/game/objects/items/crayons.dm | 2 +- .../structures/bloodsucker_life.dm | 2 +- .../antagonists/changeling/powers/headcrab.dm | 2 +- .../changeling/powers/tiny_prick.dm | 2 +- .../clock_items/wraith_spectacles.dm | 4 +- code/modules/antagonists/cult/runes.dm | 6 + .../antagonists/demon/general_powers.dm | 2 +- .../eldritch_cult/knowledge/mind_lore.dm | 4 +- .../antagonists/traitor/syndicate_contract.dm | 8 +- code/modules/client/multiz_parallax.dm | 16 + .../client/preferences/ambient_occlusion.dm | 8 +- code/modules/clothing/glasses/_glasses.dm | 2 +- code/modules/events/flutes.dm | 14 +- .../food_and_drinks/food/snacks_pie.dm | 4 +- code/modules/hydroponics/grown/nettle.dm | 2 +- code/modules/mining/ores_coins.dm | 2 +- code/modules/mob/living/blood.dm | 2 +- code/modules/mob/living/brain/status_procs.dm | 25 - .../mob/living/carbon/carbon_defense.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 2 +- .../mob/living/carbon/human/species.dm | 2 +- code/modules/mob/living/damage_procs.dm | 2 +- code/modules/mob/living/life.dm | 4 +- code/modules/mob/living/living.dm | 16 +- code/modules/mob/living/living_defines.dm | 2 + .../mob/living/simple_animal/status_procs.dm | 25 - code/modules/mob/status_procs.dm | 29 - code/modules/paperwork/paperplane.dm | 4 +- .../projectile/special/hallucination.dm | 2 +- .../chemistry/reagents/alcohol_reagents.dm | 2 +- .../chemistry/reagents/drink_reagents.dm | 4 +- .../chemistry/reagents/food_reagents.dm | 16 +- .../chemistry/reagents/medicine_reagents.dm | 8 +- .../chemistry/reagents/toxin_reagents.dm | 4 +- code/modules/spells/spell_types/hivemind.dm | 2 +- .../spells/spell_types/pointed/blind.dm | 2 +- code/modules/surgery/eye_surgery.dm | 2 +- code/modules/surgery/organs/augments_chest.dm | 4 +- code/modules/surgery/organs/eyes.dm | 4 +- code/modules/surgery/organs/stomach.dm | 2 +- yogstation.dme | 9 +- .../code/datums/martial/explosive_fist.dm | 2 +- .../simple_animal/hostile/floor_cluwne.dm | 4 +- 74 files changed, 2018 insertions(+), 807 deletions(-) create mode 100644 code/__DEFINES/dcs/signals/mapping.dm create mode 100644 code/_onclick/hud/plane_master_controller.dm create mode 100644 code/_onclick/hud/plane_master_group.dm create mode 100644 code/_onclick/hud/plane_master_subtypes.dm create mode 100644 code/_onclick/hud/render_plate.dm create mode 100644 code/datums/components/hide_highest_offset.dm create mode 100644 code/datums/status_effects/debuffs/screen_blur.dm create mode 100644 code/modules/client/multiz_parallax.dm delete mode 100644 code/modules/mob/living/simple_animal/status_procs.dm diff --git a/code/__DEFINES/dcs/signals/mapping.dm b/code/__DEFINES/dcs/signals/mapping.dm new file mode 100644 index 000000000000..d80d60365802 --- /dev/null +++ b/code/__DEFINES/dcs/signals/mapping.dm @@ -0,0 +1,2 @@ +// Sent when the max plane offset changes : (old_max_offset, new_max_offset) +#define COMSIG_PLANE_OFFSET_INCREASE "plane_offset_increase" diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index 79e35ec3feed..d70d3e49b02c 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -74,3 +74,5 @@ #define COMSIG_GLOB_LIGHT_MECHANISM_COMPLETED "!light_mechanism_completed" /// Global Signal sent when the crew wins the revolution (No arguments). #define COMSIG_GLOB_REVOLUTION_VICTORY "!revolution_victory" +/// Global signal sent when narsie summon count is updated: (new count) +#define COMSIG_NARSIE_SUMMON_UPDATE "!narsie_summon_update" diff --git a/code/__DEFINES/dcs/signals/signals_huds.dm b/code/__DEFINES/dcs/signals/signals_huds.dm index 50e3069a6149..2d5d3eaa59cc 100644 --- a/code/__DEFINES/dcs/signals/signals_huds.dm +++ b/code/__DEFINES/dcs/signals/signals_huds.dm @@ -1,2 +1,10 @@ +/// Sent from /datum/hud/proc/on_eye_change(): (atom/old_eye, atom/new_eye) +#define COMSIG_HUD_EYE_CHANGED "hud_eye_changed" /// Sent from /datum/hud/proc/eye_z_changed() : (old_offset, new_offset) #define COMSIG_HUD_OFFSET_CHANGED "hud_offset_changed" +/// Sent from /atom/movable/screen/lobby/button/collapse/proc/collapse_buttons() : () +#define COMSIG_HUD_LOBBY_COLLAPSED "hud_lobby_collapsed" +/// Sent from /atom/movable/screen/lobby/button/collapse/proc/expand_buttons() : () +#define COMSIG_HUD_LOBBY_EXPANDED "hud_lobby_expanded" +/// Sent from /atom/movable/screen/lobby/button/ready/Click() : () +#define COMSIG_HUD_PLAYER_READY_TOGGLE "hud_player_ready_toggle" diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm index b8dd7713d195..468c7e4ad071 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm @@ -138,3 +138,7 @@ ///from mind/transfer_to. Sent after the mind has been transferred: (mob/previous_body) #define COMSIG_MIND_TRANSFERRED "mind_transferred" +///From living/Life(). (deltatime, times_fired) +#define COMSIG_LIVING_LIFE "living_life" + /// Block the Life() proc from proceeding... this should really only be done in some really wacky situations. + #define COMPONENT_LIVING_CANCEL_LIFE_PROCESSING (1<<0) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 7adfdd278ab6..0c78ecdc9740 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -6,6 +6,9 @@ #define CLICKCATCHER_PLANE -99 +#define FIELD_OF_VISION_BLOCKER_PLANE -96 +#define FIELD_OF_VISION_BLOCKER_RENDER_TARGET "*FIELD_OF_VISION_BLOCKER_RENDER_TARGET" + #define PLANE_SPACE -95 #define PLANE_SPACE_RENDER_TARGET "PLANE_SPACE" #define PLANE_SPACE_PARALLAX -90 @@ -18,13 +21,21 @@ #define SINGULARITY_RENDER_TARGET "*SINGULARITY_EFFECTS_PLANE" #define RENDER_PLANE_TRANSPARENT -12 //Transparent plane that shows openspace underneath the floor -#define TRANSPARENT_FLOOR_PLANE -5 -#define FLOOR_PLANE -4 +#define TRANSPARENT_FLOOR_PLANE -11 +#define FLOOR_PLANE -10 #define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE" -#define WALL_PLANE -3 -#define GAME_PLANE -2 +#define WALL_PLANE -9 +#define GAME_PLANE_FOV_HIDDEN -8 +#define GAME_PLANE_UPPER -7 +#define GAME_PLANE -6 #define GAME_PLANE_RENDER_TARGET "GAME_PLANE" -#define WALL_PLANE_UPPER -1 +#define WALL_PLANE_UPPER -5 +#define GAME_PLANE_UPPER_FOV_HIDDEN -4 +///Slightly above the game plane but does not catch mouse clicks. Useful for certain visuals that should be clicked through, like seethrough trees +#define SEETHROUGH_PLANE -3 +#define ABOVE_GAME_PLANE -2 + +#define RENDER_PLANE_GAME_WORLD -1 #define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals #define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE" @@ -153,9 +164,23 @@ #define CAMERA_STATIC_LAYER 19 #define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE" +///---------------- MISC ----------------------- + +///Pipecrawling images +#define PIPECRAWL_IMAGES_PLANE 20 + +///AI Camera Static +#define CAMERA_STATIC_PLANE 21 + +///Anything that wants to be part of the game plane, but also wants to draw above literally everything else +#define HIGH_GAME_PLANE 22 + +#define FULLSCREEN_PLANE 23 + + #define RUNECHAT_PLANE 20 -#define BALLOON_CHAT_PLANE 20.9 +#define BALLOON_CHAT_PLANE 21 //HUD layer defines @@ -210,8 +235,26 @@ #define GHOST_PLANE 4 #define POINT_PLANE 5 +/// Plane related to the menu when pressing Escape. +/// Needed so that we can apply a blur effect to EVERYTHING, and guarantee we are above all UI. +#define ESCAPE_MENU_PLANE 105 + #define RENDER_PLANE_MASTER 110 +/// A value of /datum/preference/numeric/multiz_performance that disables the option +#define MULTIZ_PERFORMANCE_DISABLE -1 +/// We expect at most 3 layers of multiz +/// Increment this define if you make a huge map. We unit test for it too just to make it easy for you +/// If you modify this, you'll need to modify the tsx file too +#define MAX_EXPECTED_Z_DEPTH 3 + + +///Plane master controller keys +#define PLANE_MASTERS_GAME "plane_masters_game" +#define PLANE_MASTERS_NON_MASTER "plane_masters_non_master" +#define PLANE_MASTERS_COLORBLIND "plane_masters_colorblind" + + // Lummox I swear to god I will find you // NOTE! You can only ever have planes greater then -10000, if you add too many with large offsets you will brick multiz // Same can be said for large multiz maps. Tread carefully mappers diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 1f1efa711b5f..0ae3833d57f3 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -481,3 +481,33 @@ GLOBAL_LIST_INIT(donor_pdas, list(PDA_COLOR_NORMAL, PDA_COLOR_TRANSPARENT, PDA_C #define ui_vamprank_display "WEST:6,CENTER-2:-5" /// 6 pixels to the right, zero tiles & 5 pixels DOWN. #define ui_sunlight_display "WEST:6,CENTER-0:0" + +//singularity defines +/// Singularity is stage 1 (1x1) +#define STAGE_ONE 1 +/// Singularity is stage 2 (3x3) +#define STAGE_TWO 3 +/// Singularity is stage 3 (5x5) +#define STAGE_THREE 5 +/// Singularity is stage 4 (7x7) +#define STAGE_FOUR 7 +/// Singularity is stage 5 (9x9) +#define STAGE_FIVE 9 +/// Singularity is stage 6 (11x11) +#define STAGE_SIX 11 //From supermatter shard + +/** + * The point where gravity is negative enough to pull you upwards. + * That means walking checks for a ceiling instead of a floor, and you can fall "upwards" + * + * This should only be possible on multi-z maps because it works like shit on maps that aren't. + */ +#define NEGATIVE_GRAVITY -1 + +#define STANDARD_GRAVITY 1 //Anything above this is high gravity, anything below no grav until negative gravity +/// The gravity strength threshold for high gravity damage. +#define GRAVITY_DAMAGE_THRESHOLD 3 +/// The scaling factor for high gravity damage. +#define GRAVITY_DAMAGE_SCALING 0.5 +/// The maximum [BRUTE] damage a mob can take from high gravity per second. +#define GRAVITY_DAMAGE_MAXIMUM 1.5 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e812b802fcbd..422b3acda456 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -498,3 +498,8 @@ #define TRAIT_MESON_VISION "meson_vision" /// Ignores darkness for hearing #define TRAIT_HEAR_THROUGH_DARKNESS "hear_through_darkness" +/// "Magic" trait that blocks the mob from moving or interacting with anything. Used for transient stuff like mob transformations or incorporality in special cases. +/// Will block movement, `Life()` (!!!), and other stuff based on the mob. +#define TRAIT_NO_TRANSFORM "block_transformations" +/// Does nothing on its own, applied via status effect. +#define TRAIT_STASIS "in_stasis" diff --git a/code/__HELPERS/_planes.dm b/code/__HELPERS/_planes.dm index c9d8c8de21cb..769c4283ea62 100644 --- a/code/__HELPERS/_planes.dm +++ b/code/__HELPERS/_planes.dm @@ -1,19 +1,19 @@ -/// Takes a plane to offset, and the multiplier to use, and well, does the offsetting -/// Respects a blacklist we use to remove redundant plane masters, such as hud objects -#define GET_NEW_PLANE(new_value, multiplier) (SSmapping.plane_offset_blacklist?["[new_value]"] ? new_value : (new_value) - (PLANE_RANGE * (multiplier))) -/// Takes a render target and an offset, returns a canonical render target string for it -#define OFFSET_RENDER_TARGET(render_target, offset) (_OFFSET_RENDER_TARGET(render_target, SSmapping.render_offset_blacklist?["[render_target]"] ? 0 : offset)) -/// Helper macro for the above -/// Honestly just exists to make the pattern of render target strings more readable -#define _OFFSET_RENDER_TARGET(render_target, offset) ("[(render_target)] #[(offset)]") -/// Takes a plane, returns TRUE if it is of critical priority, FALSE otherwise -#define PLANE_IS_CRITICAL(plane) ((SSmapping.plane_to_offset) ? !!SSmapping.critical_planes["[plane]"] : FALSE) -/// Implicit plane set. We take the turf from the object we're changing the plane of, and use ITS z as a spokesperson for our plane value -#define SET_PLANE_IMPLICIT(thing, new_value) SET_PLANE_EXPLICIT(thing, new_value, thing) -/// Takes a plane, returns the canonical, unoffset plane it represents -#define PLANE_TO_TRUE(plane) ((SSmapping.plane_offset_to_true) ? SSmapping.plane_offset_to_true["[plane]"] : plane) -/// Takes a plane, returns the offset it uses -#define PLANE_TO_OFFSET(plane) ((SSmapping.plane_to_offset) ? SSmapping.plane_to_offset["[plane]"] : plane) +// This file contains helper macros for plane operations +// See the planes section of Visuals.md for more detail, but essentially +// When we render multiz, we do it by placing all atoms on lower levels on well, lower planes +// This is done with stacks of plane masters (things we use to apply effects to planes) +// These macros exist to facilitate working with this system, and other associated small bits + +/// Takes an atom to change the plane of, a new plane value, and something that can be used as a reference to a z level as input +/// Modifies the new value to match the plane we actually want. Note, if you pass in an already offset plane the offsets will add up +/// Use PLANE_TO_TRUE() to avoid this +#define SET_PLANE(thing, new_value, z_reference) (thing.plane = MUTATE_PLANE(new_value, z_reference)) + +/// Takes a plane and a z reference, and offsets the plane by the mutation +/// The SSmapping.max_plane_offset bit here is technically redundant, but saves a bit of work in the base case +/// And the base case is important to me. Non multiz shouldn't get hit too bad by this code +#define MUTATE_PLANE(new_value, z_reference) ((SSmapping.max_plane_offset) ? GET_NEW_PLANE(new_value, GET_TURF_PLANE_OFFSET(z_reference)) : (new_value)) + /// Takes a z reference that we are unsure of, sanity checks it /// Returns either its offset, or 0 if it's not a valid ref /// Will return the reference's PLANE'S offset if we can't get anything out of the z level. We do our best @@ -22,8 +22,22 @@ /// Takes a z value we returns its offset with a list lookup /// Will runtime during parts of init. Be careful :) #define GET_Z_PLANE_OFFSET(z) (SSmapping.z_level_to_plane_offset[z]) -/// Takes a true plane, returns the offset planes that would canonically represent it -#define TRUE_PLANE_TO_OFFSETS(plane) ((SSmapping.true_to_offset_planes) ? SSmapping.true_to_offset_planes["[plane]"] : list(plane)) + +/// Takes a plane to offset, and the multiplier to use, and well, does the offsetting +/// Respects a blacklist we use to remove redundant plane masters, such as hud objects +#define GET_NEW_PLANE(new_value, multiplier) (SSmapping.plane_offset_blacklist?["[new_value]"] ? new_value : (new_value) - (PLANE_RANGE * (multiplier))) + +// Now for the more niche things + +/// Takes an object, new plane, and multipler, and offsets the plane +/// This is for cases where you have a multipler precalculated, and just want to use it +/// Often an optimization, sometimes a necessity +#define SET_PLANE_W_SCALAR(thing, new_value, multiplier) (thing.plane = GET_NEW_PLANE(new_value, multiplier)) + + +/// Implicit plane set. We take the turf from the object we're changing the plane of, and use ITS z as a spokesperson for our plane value +#define SET_PLANE_IMPLICIT(thing, new_value) SET_PLANE_EXPLICIT(thing, new_value, thing) + // This is an unrolled and optimized version of SET_PLANE, for use anywhere where you are unsure of a source's "turfness" // We do also try and guess at what the thing's z level is, even if it's not a z // The plane is cached to allow for fancy stuff to be eval'd once, rather then often @@ -47,3 +61,28 @@ }\ }\ while (FALSE) + +// Now for macros that exist to get info from SSmapping +// Mostly about details of planes, or z levels + +/// Takes a z level, gets the lowest plane offset in its "stack" +#define GET_LOWEST_STACK_OFFSET(z) ((SSmapping.max_plane_offset) ? SSmapping.z_level_to_lowest_plane_offset[z] : 0) +/// Takes a plane, returns the canonical, unoffset plane it represents +#define PLANE_TO_TRUE(plane) ((SSmapping.plane_offset_to_true) ? SSmapping.plane_offset_to_true["[plane]"] : plane) +/// Takes a plane, returns the offset it uses +#define PLANE_TO_OFFSET(plane) ((SSmapping.plane_to_offset) ? SSmapping.plane_to_offset["[plane]"] : plane) +/// Takes a plane, returns TRUE if it is of critical priority, FALSE otherwise +#define PLANE_IS_CRITICAL(plane) ((SSmapping.plane_to_offset) ? !!SSmapping.critical_planes["[plane]"] : FALSE) +/// Takes a true plane, returns the offset planes that would canonically represent it +#define TRUE_PLANE_TO_OFFSETS(plane) ((SSmapping.true_to_offset_planes) ? SSmapping.true_to_offset_planes["[plane]"] : list(plane)) +/// Takes a render target and an offset, returns a canonical render target string for it +#define OFFSET_RENDER_TARGET(render_target, offset) (_OFFSET_RENDER_TARGET(render_target, SSmapping.render_offset_blacklist?["[render_target]"] ? 0 : offset)) +/// Helper macro for the above +/// Honestly just exists to make the pattern of render target strings more readable +#define _OFFSET_RENDER_TARGET(render_target, offset) ("[(render_target)] #[(offset)]") + +// Known issues: +// Potentially too much client load? Hard to tell due to not having a potato pc to hand. +// This is solvable with lowspec preferences, which would not be hard to implement +// Player popups will now render their effects, like overlay lights. this is fixable, but I've not gotten to it +// I think overlay lights can render on the wrong z layer. s fucked diff --git a/code/__HELPERS/filters.dm b/code/__HELPERS/filters.dm index 29825367c33e..cd44409ddb23 100644 --- a/code/__HELPERS/filters.dm +++ b/code/__HELPERS/filters.dm @@ -1,3 +1,146 @@ +#define ICON_NOT_SET "Not Set" + +//This is stored as a nested list instead of datums or whatever because it json encodes nicely for usage in tgui +GLOBAL_LIST_INIT(master_filter_info, list( + "alpha" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "icon" = ICON_NOT_SET, + "render_source" = "", + "flags" = 0 + ), + "flags" = list( + "MASK_INVERSE" = MASK_INVERSE, + "MASK_SWAP" = MASK_SWAP + ) + ), + "angular_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1 + ) + ), + // Not implemented, but if this isn't uncommented some windows will just error + // Needs either a proper matrix editor, or just a hook to our existing one + // Issue is filterrific assumes variables will have the same value type if they share the same name, which this violates + // Gotta refactor this sometime + "color" = list( + "defaults" = list( + "color" = matrix(), + "space" = FILTER_COLOR_RGB + ) + ), + "displace" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = null, + "icon" = ICON_NOT_SET, + "render_source" = "" + ) + ), + "drop_shadow" = list( + "defaults" = list( + "x" = 1, + "y" = -1, + "size" = 1, + "offset" = 0, + "color" = COLOR_HALF_TRANSPARENT_BLACK + ) + ), + "blur" = list( + "defaults" = list( + "size" = 1 + ) + ), + "layer" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "icon" = ICON_NOT_SET, + "render_source" = "", + "flags" = FILTER_OVERLAY, + "color" = "", + "transform" = null, + "blend_mode" = BLEND_DEFAULT + ) + ), + "motion_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0 + ) + ), + "outline" = list( + "defaults" = list( + "size" = 0, + "color" = COLOR_BLACK, + "flags" = NONE + ), + "flags" = list( + "OUTLINE_SHARP" = OUTLINE_SHARP, + "OUTLINE_SQUARE" = OUTLINE_SQUARE + ) + ), + "radial_blur" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 0.01 + ) + ), + "rays" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 16, + "color" = COLOR_WHITE, + "offset" = 0, + "density" = 10, + "threshold" = 0.5, + "factor" = 0, + "flags" = FILTER_OVERLAY | FILTER_UNDERLAY + ), + "flags" = list( + "FILTER_OVERLAY" = FILTER_OVERLAY, + "FILTER_UNDERLAY" = FILTER_UNDERLAY + ) + ), + "ripple" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1, + "repeat" = 2, + "radius" = 0, + "falloff" = 1, + "flags" = NONE + ), + "flags" = list( + "WAVE_BOUNDED" = WAVE_BOUNDED + ) + ), + "wave" = list( + "defaults" = list( + "x" = 0, + "y" = 0, + "size" = 1, + "offset" = 0, + "flags" = NONE + ), + "flags" = list( + "WAVE_SIDEWAYS" = WAVE_SIDEWAYS, + "WAVE_BOUNDED" = WAVE_BOUNDED + ) + ) +)) + +#undef ICON_NOT_SET + +//Helpers to generate lists for filter helpers +//This is the only practical way of writing these that actually produces sane lists /proc/alpha_mask_filter(x, y, icon/icon, render_source, flags) . = list("type" = "alpha") if(!isnull(x)) @@ -11,6 +154,78 @@ if(!isnull(flags)) .["flags"] = flags +/proc/angular_blur_filter(x, y, size) + . = list("type" = "angular_blur") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + +/proc/color_matrix_filter(matrix/in_matrix, space) + . = list("type" = "color") + .["color"] = in_matrix + if(!isnull(space)) + .["space"] = space + +/proc/displacement_map_filter(icon, render_source, x, y, size = 32) + . = list("type" = "displace") + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + +/proc/drop_shadow_filter(x, y, size, offset, color) + . = list("type" = "drop_shadow") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(size)) + .["size"] = size + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(color)) + .["color"] = color + +/proc/gauss_blur_filter(size) + . = list("type" = "blur") + if(!isnull(size)) + .["size"] = size + +/proc/layering_filter(icon, render_source, x, y, flags, color, transform, blend_mode) + . = list("type" = "layer") + if(!isnull(icon)) + .["icon"] = icon + if(!isnull(render_source)) + .["render_source"] = render_source + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(color)) + .["color"] = color + if(!isnull(flags)) + .["flags"] = flags + if(!isnull(transform)) + .["transform"] = transform + if(!isnull(blend_mode)) + .["blend_mode"] = blend_mode + +/proc/motion_blur_filter(x, y) + . = list("type" = "motion_blur") + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + /proc/outline_filter(size, color, flags) . = list("type" = "outline") if(!isnull(size)) @@ -19,9 +234,87 @@ .["color"] = color if(!isnull(flags)) .["flags"] = flags - -/proc/color_matrix_filter(matrix/in_matrix, space) - . = list("type" = "color") - .["color"] = in_matrix - if(!isnull(space)) - .["space"] = space + +/proc/radial_blur_filter(size, x, y) + . = list("type" = "radial_blur") + if(!isnull(size)) + .["size"] = size + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + +/proc/rays_filter(size, color, offset, density, threshold, factor, x, y, flags) + . = list("type" = "rays") + if(!isnull(size)) + .["size"] = size + if(!isnull(color)) + .["color"] = color + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(density)) + .["density"] = density + if(!isnull(threshold)) + .["threshold"] = threshold + if(!isnull(factor)) + .["factor"] = factor + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(flags)) + .["flags"] = flags + +/proc/ripple_filter(radius, size, falloff, repeat, x, y, flags) + . = list("type" = "ripple") + if(!isnull(radius)) + .["radius"] = radius + if(!isnull(size)) + .["size"] = size + if(!isnull(falloff)) + .["falloff"] = falloff + if(!isnull(repeat)) + .["repeat"] = repeat + if(!isnull(flags)) + .["flags"] = flags + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + +/proc/wave_filter(x, y, size, offset, flags) + . = list("type" = "wave") + if(!isnull(size)) + .["size"] = size + if(!isnull(x)) + .["x"] = x + if(!isnull(y)) + .["y"] = y + if(!isnull(offset)) + .["offset"] = offset + if(!isnull(flags)) + .["flags"] = flags + +/proc/apply_wibbly_filters(atom/in_atom, length) + for(var/i in 1 to 7) + //This is a very baffling and strange way of doing this but I am just preserving old functionality + var/X + var/Y + var/rsq + do + X = 60*rand() - 30 + Y = 60*rand() - 30 + rsq = X*X + Y*Y + while(rsq<100 || rsq>900) // Yeah let's just loop infinitely due to bad luck what's the worst that could happen? + var/random_roll = rand() + in_atom.add_filter("wibbly-[i]", 5, wave_filter(x = X, y = Y, size = rand() * 2.5 + 0.5, offset = random_roll)) + var/filter = in_atom.get_filter("wibbly-[i]") + animate(filter, offset = random_roll, time = 0, loop = -1, flags = ANIMATION_PARALLEL) + animate(offset = random_roll - 1, time = rand() * 20 + 10) + +/proc/remove_wibbly_filters(atom/in_atom) + var/filter + for(var/i in 1 to 7) + filter = in_atom.get_filter("wibbly-[i]") + animate(filter) + in_atom.remove_filter("wibbly-[i]") diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index bc28261dc38e..0cb75cf7d1da 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -93,10 +93,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() - for(var/mytype in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/plane_master/instance = new mytype() - plane_masters["[instance.plane]"] = instance - instance.backdrop(mymob) + for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) + var/atom/movable/plane_master_controller/controller_instance = new mytype(null,src) + plane_master_controllers[controller_instance.name] = controller_instance /datum/hud/Destroy() if(mymob.hud_used == src) @@ -249,11 +248,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( return TRUE /datum/hud/proc/plane_masters_update() - // Plane masters are always shown to OUR mob, never to observers - for(var/thing in plane_masters) - var/atom/movable/screen/plane_master/PM = plane_masters[thing] - PM.backdrop(mymob) - mymob.client.screen += PM + for(var/group_key in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + // Plane masters are always shown to OUR mob, never to observers + group.refresh_hud() /datum/hud/human/show_hud(version = 0,mob/viewmob) . = ..() @@ -662,10 +660,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( current_plane_offset = new_offset SEND_SIGNAL(src, COMSIG_HUD_OFFSET_CHANGED, old_offset, new_offset) - if(should_use_scale()) - for(var/group_key as anything in master_groups) - var/datum/plane_master_group/group = master_groups[group_key] - group.transform_lower_turfs(src, new_offset) + // if(should_use_scale()) + // for(var/group_key as anything in master_groups) + // var/datum/plane_master_group/group = master_groups[group_key] + // group.transform_lower_turfs(src, new_offset) /// Returns the plane master that matches the input plane from the passed in group /datum/hud/proc/get_plane_master(plane, group_key = PLANE_GROUP_MAIN) @@ -688,3 +686,17 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /// Returns the corresponding plane group datum if one exists /datum/hud/proc/get_plane_group(key) return master_groups[key] + +/datum/hud/proc/on_eye_change(datum/source, atom/old_eye, atom/new_eye) + SIGNAL_HANDLER + SEND_SIGNAL(src, COMSIG_HUD_EYE_CHANGED, old_eye, new_eye) + + if(old_eye) + UnregisterSignal(old_eye, COMSIG_MOVABLE_Z_CHANGED) + if(new_eye) + // By the time logout runs, the client's eye has already changed + // There's just no log of the old eye, so we need to override + // :sadkirby: + RegisterSignal(new_eye, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(eye_z_changed), override = TRUE) + eye_z_changed(new_eye) + diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index 50bc5e6d5cbe..13f94fa9f5aa 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -1,58 +1,120 @@ +// I hate this place +INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master) + /atom/movable/screen/plane_master screen_loc = "CENTER" icon_state = "blank" - appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + appearance_flags = PLANE_MASTER blend_mode = BLEND_OVERLAY - var/show_alpha = 255 - var/hide_alpha = 0 + plane = LOWEST_EVER_PLANE + /// Will be sent to the debug ui as a description for each plane + /// Also useful as a place to explain to coders how/why your plane works, and what it's meant to do + /// Plaintext and basic html are fine to use here. + /// I'll bonk you if I find you putting "lmao stuff" in here, make this useful. + var/documentation = "" + /// Our real alpha value, so alpha can persist through being hidden/shown + var/true_alpha = 255 + /// Tracks if we're using our true alpha, or being manipulated in some other way + var/alpha_enabled = TRUE + + /// The plane master group we're a member of, our "home" + var/datum/plane_master_group/home + /// If our plane master allows for offsetting /// Mostly used for planes that really don't need to be duplicated, like the hud planes var/allows_offsetting = TRUE + /// Our offset from our "true" plane, see below + var/offset + /// When rendering multiz, lower levels get their own set of plane masters + /// Real plane here represents the "true" plane value of something, ignoring the offset required to handle lower levels + var/real_plane + //--rendering relay vars-- /// list of planes we will relay this plane's render to var/list/render_relay_planes = list(RENDER_PLANE_GAME) + /// blend mode to apply to the render relay in case you dont want to use the plane_masters blend_mode + var/blend_mode_override + /// list of current relays this plane is utilizing to render + var/list/atom/movable/render_plane_relay/relays = list() + /// if render relays have already be generated + var/relays_generated = FALSE + + /// If this plane master should be hidden from the player at roundstart + /// We do this so PMs can opt into being temporary, to reduce load on clients + var/start_hidden = FALSE /// If this plane master is being forced to hide. /// Hidden PMs will dump ANYTHING relayed or drawn onto them. Be careful with this /// Remember: a hidden plane master will dump anything drawn directly to it onto the output render. It does NOT hide its contents /// Use alpha for that var/force_hidden = FALSE - /// If this plane master is outside of our visual bounds right now - var/is_outside_bounds = FALSE - /// Our offset from our "true" plane, see below - var/offset - /// list of current relays this plane is utilizing to render - var/list/atom/movable/render_plane_relay/relays = list() - /// if render relays have already be generated - var/relays_generated = FALSE + + /// If this plane should be scaled by multiz + /// Planes with this set should NEVER be relay'd into each other, as that will cause visual fuck + var/multiz_scaled = TRUE + + /// Bitfield that describes how this plane master will render if its z layer is being "optimized" + /// If a plane master is NOT critical, it will be completely dropped if we start to render outside a client's multiz boundary prefs + /// Of note: most of the time we will relay renders to non critical planes in this stage. so the plane master will end up drawing roughly "in order" with its friends + /// This is NOT done for parallax and other problem children, because the rules of BLEND_MULTIPLY appear to not behave as expected :( + /// This will also just make debugging harder, because we do fragile things in order to ensure things operate as epected. I'm sorry + /// Compile time /// See [code\__DEFINES\layers.dm] for our bitflags var/critical = NONE - /// The plane master group we're a member of, our "home" - var/datum/plane_master_group/home - /// blend mode to apply to the render relay in case you dont want to use the plane_masters blend_mode - var/blend_mode_override - /// Our real alpha value, so alpha can persist through being hidden/shown - var/true_alpha = 255 - /// Tracks if we're using our true alpha, or being manipulated in some other way - var/alpha_enabled = TRUE - -/atom/movable/screen/plane_master/proc/Show(override) - alpha = override || show_alpha + /// If this plane master is outside of our visual bounds right now + var/is_outside_bounds = FALSE -/atom/movable/screen/plane_master/proc/Hide(override) - alpha = override || hide_alpha +/atom/movable/screen/plane_master/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset = 0) + . = ..() + src.offset = offset + true_alpha = alpha + real_plane = plane + + if(!set_home(home)) + return INITIALIZE_HINT_QDEL + update_offset() + if(!documentation && !(istype(src, /atom/movable/screen/plane_master) || istype(src, /atom/movable/screen/plane_master/rendering_plate))) + stack_trace("Plane master created without a description. Document how your thing works so people will know in future, and we can display it in the debug menu") + if(start_hidden) + hide_plane(home.our_hud?.mymob) + generate_render_relays() + +/atom/movable/screen/plane_master/Destroy() + if(home) + // NOTE! We do not clear ourselves from client screens + // We relay on whoever qdel'd us to reset our hud, and properly purge us + home.plane_masters -= "[plane]" + home = null + . = ..() + QDEL_LIST(relays) -//Why do plane masters need a backdrop sometimes? Read https://secure.byond.com/forum/?post=2141928 -//Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. -/atom/movable/screen/plane_master/proc/backdrop(mob/mymob) +/// Sets the plane group that owns us, it also determines what screen we render to +/// Returns FALSE if the set_home fails, TRUE otherwise +/atom/movable/screen/plane_master/proc/set_home(datum/plane_master_group/home) + if(!istype(home, /datum/plane_master_group)) + return FALSE + src.home = home + if(home.map) + screen_loc = "[home.map]:[screen_loc]" + assigned_map = home.map + return TRUE -///Things rendered on "openspace"; holes in multi-z -/atom/movable/screen/plane_master/openspace - name = "open space plane master" - plane = FLOOR_OPENSPACE_PLANE - appearance_flags = PLANE_MASTER - blend_mode = BLEND_MULTIPLY - alpha = 255 +/// Updates our "offset", basically what layer of multiz we're meant to render +/// Top is 0, goes up as you go down +/// It's taken into account by render targets and relays, so we gotta make sure they're on the same page +/atom/movable/screen/plane_master/proc/update_offset() + name = "[initial(name)] #[offset]" + SET_PLANE_W_SCALAR(src, real_plane, offset) + for(var/i in 1 to length(render_relay_planes)) + render_relay_planes[i] = GET_NEW_PLANE(render_relay_planes[i], offset) + if(initial(render_target)) + render_target = OFFSET_RENDER_TARGET(initial(render_target), offset) + +/atom/movable/screen/plane_master/proc/set_alpha(new_alpha) + true_alpha = new_alpha + if(!alpha_enabled) + return + alpha = new_alpha /atom/movable/screen/plane_master/proc/disable_alpha() alpha_enabled = FALSE @@ -61,290 +123,6 @@ /atom/movable/screen/plane_master/proc/enable_alpha() alpha_enabled = TRUE alpha = true_alpha -/atom/movable/screen/plane_master/openspace/backdrop(mob/mymob) - filters = list() - filters += filter(type="alpha", render_source = LIGHTING_RENDER_TARGET, flags = MASK_INVERSE) - filters += filter(type = "drop_shadow", color = "#04080FAA", size = -10) - filters += filter(type = "drop_shadow", color = "#04080FAA", size = -15) - filters += filter(type = "drop_shadow", color = "#04080FAA", size = -20) - -/atom/movable/screen/plane_master/proc/outline(_size, _color) - filters += filter(type = "outline", size = _size, color = _color) - -/atom/movable/screen/plane_master/proc/shadow(_size, _border, _offset = 0, _x = 0, _y = 0, _color = "#04080FAA") - filters += filter(type = "drop_shadow", x = _x, y = _y, color = _color, size = _size, offset = _offset) - -/atom/movable/screen/plane_master/proc/clear_filters() - filters = list() - -///Contains just the floor -/atom/movable/screen/plane_master/floor - name = "floor plane master" - plane = FLOOR_PLANE - appearance_flags = PLANE_MASTER - blend_mode = BLEND_OVERLAY - render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) - -/atom/movable/screen/plane_master/transparent_floor - name = "Transparent Floor" - // documentation = "Really just openspace, stuff that is a turf but has no color or alpha whatsoever. - //
We use this to draw to just the light mask plane, cause if it's not there we get holes of blackness over openspace" - plane = TRANSPARENT_FLOOR_PLANE - render_relay_planes = list(LIGHT_MASK_PLANE) - // Needs to be critical or it uh, it'll look white - critical = PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_RELAY - -/atom/movable/screen/plane_master/floor/backdrop(mob/mymob) - filters = list() - if(istype(mymob) && mymob.eye_blurry) - filters += GAUSSIAN_BLUR(clamp(mymob.eye_blurry*0.1,0.6,3)) - // Should be moved to the world render plate when render plates get ported in - filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) - -///Contains most things in the game world -/atom/movable/screen/plane_master/game_world - name = "game world plane master" - plane = GAME_PLANE - appearance_flags = PLANE_MASTER //should use client color - blend_mode = BLEND_OVERLAY - -/atom/movable/screen/plane_master/game_world/backdrop(mob/mymob) - filters = list() - if(istype(mymob) && mymob.client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion)) - filters += AMBIENT_OCCLUSION - if(istype(mymob) && mymob.eye_blurry) - filters += GAUSSIAN_BLUR(clamp(mymob.eye_blurry*0.1,0.6,3)) - // Should be moved to the world render plate when render plates get ported in - filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) - - -/atom/movable/screen/plane_master/wall - 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_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) - -/atom/movable/screen/plane_master/wall/Initialize(mapload, datum/plane_master_group/home, offset) - . = ..() - add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_WALL_LAYER, relay_color = GLOB.em_block_color) - -/atom/movable/screen/plane_master/wall_upper - name = "Upper wall" - // documentation = "There are some walls that want to render above most things (mostly minerals since they shift over. - //
We draw them to their own plane so we can hijack them for our emissive mask stuff" - plane = WALL_PLANE_UPPER - render_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) - -///Contains all lighting objects -/atom/movable/screen/plane_master/lighting - name = "lighting plane master" - plane = LIGHTING_PLANE - blend_mode = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/plane_master/lighting/Initialize(mapload) - . = ..() - 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) - filters += filter(type="alpha", render_source = O_LIGHTING_VISUAL_RENDER_TARGET, flags = MASK_INVERSE) - // Should be moved to the world render plate when render plates get ported in - filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) - -/** - * 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. - */ -/atom/movable/screen/plane_master/emissive - name = "emissive plane master" - plane = EMISSIVE_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - render_target = EMISSIVE_RENDER_TARGET - -/atom/movable/screen/plane_master/emissive/Initialize(mapload) - . = ..() - filters += filter(type="alpha", render_source=EMISSIVE_BLOCKER_RENDER_TARGET, flags=MASK_INVERSE) - // Should be moved to the world render plate when render plates get ported in - filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) - -/** - * 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. - */ - -/atom/movable/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 - */ -/atom/movable/screen/plane_master/emissive_blocker - name = "emissive blocker plane master" - plane = EMISSIVE_BLOCKER_PLANE - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - render_target = EMISSIVE_BLOCKER_RENDER_TARGET - -///Contains space parallax -/atom/movable/screen/plane_master/parallax - name = "parallax plane master" - plane = PLANE_SPACE_PARALLAX - blend_mode = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/plane_master/parallax/Initialize(mapload) - . = ..() - // Should be moved to the world render plate when render plates get ported in - filters += filter(type="displace", render_source = SINGULARITY_RENDER_TARGET, size=75) - -/atom/movable/screen/plane_master/parallax_white - name = "parallax whitifier plane master" - plane = PLANE_SPACE - appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR - render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) - critical = PLANE_CRITICAL_FUCKO_PARALLAX // goes funny when touched. no idea why I don't trust byond - -/atom/movable/screen/plane_master/lighting/backdrop(mob/mymob) - mymob.overlay_fullscreen("lighting_backdrop_lit", /atom/movable/screen/fullscreen/lighting_backdrop/lit) - mymob.overlay_fullscreen("lighting_backdrop_unlit", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) - -/atom/movable/screen/plane_master/singularity_effect - name = "singularity plane master" - plane = SINGULARITY_EFFECT_PLANE - render_target = SINGULARITY_RENDER_TARGET - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/plane_master/camera_static - name = "camera static plane master" - plane = CAMERA_STATIC_PLANE - appearance_flags = PLANE_MASTER - blend_mode = BLEND_OVERLAY - -/atom/movable/screen/plane_master/runechat - name = "runechat plane master" - plane = RUNECHAT_PLANE - appearance_flags = PLANE_MASTER - blend_mode = BLEND_OVERLAY - -/atom/movable/screen/plane_master/runechat/backdrop(mob/mymob) - filters = list() - if(istype(mymob) && mymob.client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion)) - filters += AMBIENT_OCCLUSION - -/atom/movable/screen/plane_master/o_light_visual - name = "overlight light visual plane master" - layer = O_LIGHTING_VISUAL_LAYER - plane = O_LIGHTING_VISUAL_PLANE - render_target = O_LIGHTING_VISUAL_RENDER_TARGET - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - blend_mode = BLEND_MULTIPLY - -/// Gets the relay atom we're using to connect to the target plane, if one exists -/atom/movable/screen/plane_master/proc/get_relay_to(target_plane) - for(var/atom/movable/render_plane_relay/relay in relays) - if(relay.plane == target_plane) - return relay - -/proc/get_plane_master_render_base(name) - return "*[name]: AUTOGENERATED RENDER TGT" - -/atom/movable/screen/plane_master/proc/generate_relay_to(target_plane, relay_loc, client/show_to, blend_override, relay_layer) - if(!length(relays) && !initial(render_target)) - render_target = OFFSET_RENDER_TARGET(get_plane_master_render_base(name), offset) - if(!relay_loc) - relay_loc = "CENTER" - // If we're using a submap (say for a popup window) make sure we draw onto it - if(home?.map) - relay_loc = "[home.map]:[relay_loc]" - var/blend_to_use = blend_override - if(isnull(blend_to_use)) - blend_to_use = blend_mode_override || initial(blend_mode) - - var/atom/movable/render_plane_relay/relay = new() - relay.render_source = render_target - relay.plane = target_plane - relay.screen_loc = relay_loc - // There are two rules here - // 1: layer needs to be positive (negative layers are treated as float layers) - // 2: lower planes (including offset ones) need to be layered below higher ones (because otherwise they'll render fucky) - // By multiplying LOWEST_EVER_PLANE by 30, we give 30 offsets worth of room to planes before they start going negative - // Bet - // We allow for manuel override if requested. careful with this - relay.layer = relay_layer || (plane + abs(LOWEST_EVER_PLANE * 30)) //layer must be positive but can be a decimal - relay.blend_mode = blend_to_use - relay.mouse_opacity = mouse_opacity - relay.name = render_target - relay.critical_target = PLANE_IS_CRITICAL(target_plane) - relays += relay - // Relays are sometimes generated early, before huds have a mob to display stuff to - // That's what this is for - if(show_to) - show_to.screen += relay - return relay - -/// Creates a connection between this plane master and the passed in plane -/// Helper for out of system code, shouldn't be used in this file -/// Build system to differenchiate between generated and non generated render relays -/atom/movable/screen/plane_master/proc/add_relay_to(target_plane, blend_override, relay_layer, relay_color) - if(get_relay_to(target_plane)) - return - render_relay_planes += target_plane - var/client/display_lad = home?.our_hud?.mymob?.canon_client - var/atom/movable/render_plane_relay/relay = generate_relay_to(target_plane, show_to = display_lad, blend_override = blend_override, relay_layer = relay_layer) - relay.color = relay_color - -/** - * Render relay object assigned to a plane master to be able to relay it's render onto other planes that are not it's own - */ -/atom/movable/render_plane_relay - screen_loc = "CENTER" - layer = -1 - plane = 0 - appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER - /// If we render into a critical plane master, or not - var/critical_target = FALSE - -/// Hook to allow planes to work around is_outside_bounds -/// Return false to allow a show, true otherwise -/atom/movable/screen/plane_master/proc/check_outside_bounds() - return is_outside_bounds - -/atom/movable/screen/plane_master/fullscreen - name = "Fullscreen" - plane = FULLSCREEN_PLANE - appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR - render_relay_planes = list(RENDER_PLANE_NON_GAME) - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - allows_offsetting = FALSE - -/atom/movable/screen/plane_master/parallax - name = "Parallax" - // documentation = "Contains parallax, or to be more exact the screen objects that hold parallax. - //
Note the BLEND_MULTIPLY. The trick here is how low our plane value is. Because of that, we draw below almost everything in the game. - //
We abuse this to ensure we multiply against the Parallax whitifier plane, or space's plane. It's set to full white, so when you do the multiply you just get parallax out where it well, makes sense to be. - //
Also notice that the parent parallax plane is mirrored down to all children. We want to support viewing parallax across all z levels at once." - plane = PLANE_SPACE_PARALLAX - appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR - blend_mode = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - - -/// Hides a plane master from the passeed in mob -/// Do your effect cleanup here -/atom/movable/screen/plane_master/proc/hide_from(mob/oldmob) - SHOULD_CALL_PARENT(TRUE) - var/client/their_client = oldmob?.client - if(!their_client) - return - their_client.screen -= src - their_client.screen -= relays /// Shows a plane master to the passed in mob /// Override this to apply unique effects and such @@ -353,7 +131,8 @@ SHOULD_CALL_PARENT(TRUE) if(force_hidden) return FALSE - var/client/our_client = mymob?.client + + var/client/our_client = mymob?.canon_client // Alright, let's get this out of the way // Mobs can move z levels without their client. If this happens, we need to ensure critical display settings are respected // This is done here. Mild to severe pain but it's nessesary @@ -367,7 +146,6 @@ if(!(critical & PLANE_CRITICAL_NO_RELAY)) our_client.screen += relays return TRUE - return TRUE if(!our_client) @@ -376,7 +154,51 @@ our_client.screen += src our_client.screen += relays return TRUE - + +/// Hook to allow planes to work around is_outside_bounds +/// Return false to allow a show, true otherwise +/atom/movable/screen/plane_master/proc/check_outside_bounds() + return is_outside_bounds + +/// Hides a plane master from the passeed in mob +/// Do your effect cleanup here +/atom/movable/screen/plane_master/proc/hide_from(mob/oldmob) + SHOULD_CALL_PARENT(TRUE) + var/client/their_client = oldmob?.client + if(!their_client) + return + their_client.screen -= src + their_client.screen -= relays + + +/// Forces this plane master to hide, until unhide_plane is called +/// This allows us to disable unused PMs without breaking anything else +/atom/movable/screen/plane_master/proc/hide_plane(mob/cast_away) + force_hidden = TRUE + hide_from(cast_away) + +/// Disables any forced hiding, allows the plane master to be used as normal +/atom/movable/screen/plane_master/proc/unhide_plane(mob/enfold) + force_hidden = FALSE + show_to(enfold) + +/// Mirrors our force hidden state to the hidden state of the plane that came before, assuming it's valid +/// This allows us to mirror any hidden sets from before we were created, no matter how low that chance is +/atom/movable/screen/plane_master/proc/mirror_parent_hidden() + var/mob/our_mob = home?.our_hud?.mymob + var/atom/movable/screen/plane_master/true_plane = our_mob?.hud_used?.get_plane_master(plane) + if(true_plane == src || !true_plane) + return + + if(true_plane.force_hidden == force_hidden) + return + + // If one of us already exists and it's not hidden, unhide ourselves + if(true_plane.force_hidden) + hide_plane(our_mob) + else + unhide_plane(our_mob) + /atom/movable/screen/plane_master/proc/outside_bounds(mob/relevant) if(force_hidden || is_outside_bounds) return @@ -396,266 +218,19 @@ return hide_from(relevant) -/// Datum that represents one "group" of plane masters -/// So all the main window planes would be in one, all the spyglass planes in another -/// Etc -/datum/plane_master_group - /// Our key in the group list on /datum/hud - /// Should be unique for any group of plane masters in the world - var/key - /// Our parent hud - var/datum/hud/our_hud - /// List in the form "[plane]" = object, the plane masters we own - var/list/atom/movable/screen/plane_master/plane_masters = list() - /// The visual offset we are currently using - var/active_offset = 0 - /// What, if any, submap we render onto - var/map = "" - -/// Nice wrapper for the "[]"ing -/datum/plane_master_group/proc/get_plane(plane) - return plane_masters["[plane]"] - -///Contains all lighting objects -/atom/movable/screen/plane_master/rendering_plate/lighting - name = "Lighting plate" - // documentation = "Anything on this plane will be multiplied with the plane it's rendered onto (typically the game plane). - //
That's how lighting functions at base. Because it uses BLEND_MULTIPLY and occasionally color matrixes, it needs a backdrop of blackness. - //
See This byond post - //
Lemme see uh, we're masked by the emissive plane so it can actually function (IE: make things glow in the dark). - //
We're also masked by the overlay lighting plane, which contains all the movable lights in the game. It draws to us and also the game plane. - //
Masks us out so it has the breathing room to apply its effect. - //
Oh and we quite often have our alpha changed to achive night vision effects, or things of that sort." - plane = RENDER_PLANE_LIGHTING - blend_mode_override = BLEND_MULTIPLY - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - critical = PLANE_CRITICAL_DISPLAY - /// A list of light cutoffs we're actively using, (mass, r, g, b) to avoid filter churn - var/list/light_cutoffs - -/atom/movable/screen/plane_master/rendering_plate/lighting/proc/set_light_cutoff(light_cutoff, list/color_cutoffs) - var/list/new_cutoffs = list(light_cutoff) - new_cutoffs += color_cutoffs - if(new_cutoffs ~= light_cutoffs) - return - - remove_filter(list("light_cutdown", "light_cutup")) - - var/ratio = light_cutoff/100 - if(!color_cutoffs) - color_cutoffs = list(0, 0, 0) - - var/red = color_cutoffs[1] / 100 - var/green = color_cutoffs[2] / 100 - var/blue = color_cutoffs[3] / 100 - add_filter("light_cutdown", 3, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, -(ratio + red),-(ratio+green),-(ratio+blue),0))) - add_filter("light_cutup", 4, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, ratio+red,ratio+green,ratio+blue,0))) - -/*! - * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. - * - * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color. - * Emissive blockers are pasted with an atom color that converts them to be entirely some different color. - * Emissive overlays and emissive blockers are put onto the same plane. - * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects. - * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is. - * This is then used to alpha mask the lighting plane. - * - */ -/atom/movable/screen/plane_master/rendering_plate/lighting/Initialize(mapload) - . = ..() - add_filter("emissives", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(EMISSIVE_RENDER_TARGET, offset), flags = MASK_INVERSE)) - add_filter("object_lighting", 2, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(O_LIGHTING_VISUAL_RENDER_TARGET, offset), flags = MASK_INVERSE)) - set_light_cutoff(10) - -/// Breaks a connection between this plane master, and the passed in place -/atom/movable/screen/plane_master/proc/remove_relay_from(target_plane) - render_relay_planes -= target_plane - var/atom/movable/render_plane_relay/existing_relay = get_relay_to(target_plane) - if(!existing_relay) - return - relays -= existing_relay - if(!length(relays) && !initial(render_target)) - render_target = null - var/client/lad = home?.our_hud?.mymob?.canon_client - if(lad) - lad.screen -= existing_relay - -/atom/movable/screen/plane_master/rendering_plate/master/proc/offset_change(new_offset) - if(new_offset == offset) // If we're on our own z layer, relay to nothing, just draw - remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) - else // Otherwise, regenerate the relay - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) - -/atom/movable/screen/plane_master/rendering_plate/master/proc/on_offset_change(datum/source, old_offset, new_offset) - SIGNAL_HANDLER - offset_change(new_offset) - -/atom/movable/screen/plane_master/rendering_plate/lighting/proc/on_offset_change(datum/source, old_offset, new_offset) - SIGNAL_HANDLER - offset_change(new_offset) - -/atom/movable/screen/plane_master/rendering_plate/lighting/proc/offset_change(mob_offset) - // Offsets stack down remember. This implies that we're above the mob's view plane, and shouldn't render - if(offset < mob_offset) - disable_alpha() - else - enable_alpha() - -/atom/movable/screen/plane_master/rendering_plate/lighting/show_to(mob/mymob) - . = ..() - if(!.) - return - // This applies a backdrop to our lighting plane - // Why do plane masters need a backdrop sometimes? Read https://secure.byond.com/forum/?post=2141928 - // Basically, we need something to brighten - // unlit is perhaps less needed rn, it exists to provide a fullbright for things that can't see the lighting plane - // but we don't actually use invisibility to hide the lighting plane anymore, so it's pointless - var/atom/movable/screen/backdrop = mymob.overlay_fullscreen("lighting_backdrop_lit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/lit) - // Need to make sure they're on our plane, ALL the time. We always need a backdrop - SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) - backdrop = mymob.overlay_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) - SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) - // Sorry, this is a bit annoying - // Basically, we only want the lighting plane we can actually see to attempt to render - // If we don't our lower plane gets totally overriden by the black void of the upper plane - var/datum/hud/hud = home.our_hud - // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this - if(hud) - RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) - offset_change(hud?.current_plane_offset || 0) - set_light_cutoff(mymob.lighting_cutoff, mymob.lighting_color_cutoffs) - -/atom/movable/screen/plane_master/rendering_plate/lighting/hide_from(mob/oldmob) - . = ..() - oldmob.clear_fullscreen("lighting_backdrop_lit_[home.key]#[offset]") - oldmob.clear_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]") - var/datum/hud/hud = home.our_hud - if(hud) - UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) - -/atom/movable/screen/plane_master/rendering_plate/emissive_slate/Initialize(mapload, datum/plane_master_group/home, offset) - . = ..() - add_filter("em_block_masking", 2, color_matrix_filter(GLOB.em_mask_matrix)) - if(offset != 0) - add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset - 1), relay_layer = EMISSIVE_Z_BELOW_LAYER) - -/atom/movable/screen/plane_master/rendering_plate/light_mask - name = "Light Mask" - // documentation = "Any part of this plane that is transparent will be black below it on the game rendering plate. - //
This is done to ensure emissives and overlay lights don't light things up \"through\" the darkness that normally sits at the bottom of the lighting plane. - //
We relay copies of the space, floor and wall planes to it, so we can use them as masks. Then we just boost any existing alpha to 100% and we're done. - //
If we ever switch to a sight setup that shows say, mobs but not floors, we instead mask just overlay lighting and emissives. - //
This avoids dumb seethrough without breaking stuff like thermals." - plane = LIGHT_MASK_PLANE - appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR - // Fullwhite where there's any color, no alpha otherwise - color = list(255,255,255,255, 255,255,255,255, 255,255,255,255, 0,0,0,0, 0,0,0,0) - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - render_target = LIGHT_MASK_RENDER_TARGET - // We blend against the game plane, so she's gotta multiply! - blend_mode = BLEND_MULTIPLY - render_relay_planes = list(RENDER_PLANE_GAME) - -/atom/movable/screen/plane_master/rendering_plate/light_mask/show_to(mob/mymob) - . = ..() - if(!.) - return +/atom/movable/screen/plane_master/proc/inside_bounds(mob/relevant) + is_outside_bounds = FALSE + if(critical & PLANE_CRITICAL_DISPLAY) + // We here assume that your render target starts with * + if(critical & PLANE_CRITICAL_CUT_RENDER && render_target) + render_target = "*[render_target]" - RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight)) - handle_sight(mymob, mymob.sight, NONE) + if(!(critical & PLANE_CRITICAL_NO_RELAY)) + return + var/client/our_client = relevant.client + if(our_client) + for(var/atom/movable/render_plane_relay/relay as anything in relays) + our_client.screen += relay -/atom/movable/screen/plane_master/rendering_plate/light_mask/hide_from(mob/oldmob) - . = ..() - var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) - overlay_lights.remove_filter("lighting_mask") - var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) - emissive.remove_filter("lighting_mask") - remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) - UnregisterSignal(oldmob, COMSIG_MOB_SIGHT_CHANGE) - -/atom/movable/screen/plane_master/rendering_plate/light_mask/proc/handle_sight(datum/source, new_sight, old_sight) - // If we can see something that shows "through" blackness, and we can't see turfs, disable our draw to the game plane - // And instead mask JUST the overlay lighting plane, since that will look fuckin wrong - var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) - var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) - if(new_sight & SEE_AVOID_TURF_BLACKNESS && !(new_sight & SEE_TURFS)) - remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) - overlay_lights.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) - emissive.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) - // If we CAN'T see through the black, then draw er down brother! - else - overlay_lights.remove_filter("lighting_mask") - emissive.remove_filter("lighting_mask") - // We max alpha here, so our darkness is actually.. dark - // Can't do it before cause it fucks with the filter - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) -// It would be nice to setup parallaxing for stairs and things when doing this -// So they look nicer. if you can't it's all good, if you think you can sanely look at monster's work -// It's hard, and potentially expensive. be careful -/datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) - // Check if this feature is disabled for the client, in which case don't use scale. - // var/mob/our_mob = our_hud?.mymob - - // No offset? piss off - if(!SSmapping.max_plane_offset) return - - active_offset = new_offset - - // Each time we go "down" a visual z level, we'll reduce the scale by this amount - // Chosen because mothblocks liked it, didn't cause motion sickness while also giving a sense of height - var/scale_by = 0.965 - if(!use_scale) - // This is a workaround for two things - // First of all, if a mob can see objects but not turfs, they will not be shown the holder objects we use for - // What I'd like to do is revert to images if this case throws, but image vis_contents is broken - // https://www.byond.com/forum/post/2821969 - // If that's ever fixed, please just use that. thanks :) - scale_by = 1 - - var/list/offsets = list() - // var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) - - // We accept negatives so going down "zooms" away the drop above as it goes - for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) - // Multiz boundaries disable transforms - // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) - // offsets += null - // continue - - // No transformations if we're landing ON you - if(offset == 0) - offsets += null - continue - - var/scale = scale_by ** (offset) - var/matrix/multiz_shrink = matrix() - multiz_shrink.Scale(scale) - offsets += multiz_shrink - - // So we can talk in 1 -> max_offset * 2 + 1, rather then -max_offset -> max_offset - var/offset_offset = SSmapping.max_plane_offset + 1 - - for(var/plane_key in plane_masters) - var/atom/movable/screen/plane_master/plane = plane_masters[plane_key] - if(!plane.allows_offsetting) - continue - - var/visual_offset = plane.offset - new_offset - - // Basically uh, if we're showing something down X amount of levels, or up any amount of levels - // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) - // plane.outside_bounds(our_mob) - // else if(plane.is_outside_bounds) - // plane.inside_bounds(our_mob) - - // if(!plane.multiz_scaled) - // continue - - if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0) - // We don't animate here because it should be invisble, but we do mark because it'll look nice - plane.transform = offsets[visual_offset + offset_offset] - continue - - animate(plane, transform = offsets[visual_offset + offset_offset], 0.05 SECONDS, easing = LINEAR_EASING) + show_to(relevant) diff --git a/code/_onclick/hud/plane_master_controller.dm b/code/_onclick/hud/plane_master_controller.dm new file mode 100644 index 000000000000..cae4822c6fec --- /dev/null +++ b/code/_onclick/hud/plane_master_controller.dm @@ -0,0 +1,103 @@ +///Atom that manages and controls multiple planes. It's an atom so we can hook into add_filter etc. Multiple controllers can control one plane. +///Of note: plane master controllers are currently not very extensively used, because render plates fill a semi similar niche +///This could well change someday, and I'd like to keep this stuff around, so we use it for a few cases just out of convenience +/atom/movable/plane_master_controller + ///List of planes as defines in this controllers control + var/list/controlled_planes = list() + ///hud that owns this controller + var/datum/hud/owner_hud + +INITIALIZE_IMMEDIATE(/atom/movable/plane_master_controller) + +///Ensures that all the planes are correctly in the controlled_planes list. +/atom/movable/plane_master_controller/Initialize(mapload, datum/hud/hud) + . = ..() + if(!istype(hud)) + return + owner_hud = hud + +/atom/movable/plane_master_controller/proc/get_planes() + var/returned_planes = list() + for(var/true_plane in controlled_planes) + returned_planes += get_true_plane(true_plane) + return returned_planes + +/atom/movable/plane_master_controller/proc/get_true_plane(true_plane) + var/list/returned_planes = owner_hud.get_true_plane_masters(true_plane) + if(!length(returned_planes)) //If we looked for a hud that isn't instanced, just keep going + stack_trace("[plane] isn't a valid plane master layer for [owner_hud.type], are you sure it exists in the first place?") + return + + return returned_planes + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_filter(name, priority, list/params) + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.add_filter(name, priority, params) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/remove_filter(name_or_names) + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.remove_filter(name_or_names) + +/atom/movable/plane_master_controller/update_filters() + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.update_filters() + +///Gets all filters for this controllers plane masters +/atom/movable/plane_master_controller/proc/get_filters(name) + . = list() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + . += pm_iterator.get_filter(name) + +///Transitions all filters owned by this plane master controller +/atom/movable/plane_master_controller/transition_filter(name, time, list/new_params, easing, loop) + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.transition_filter(name, new_params, time, easing, loop) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_atom_colour(coloration, colour_priority) + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.add_atom_colour(coloration, colour_priority) + + +///Removes an instance of colour_type from the atom's atom_colours list +/atom/movable/plane_master_controller/remove_atom_colour(colour_priority, coloration) + . = ..() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.remove_atom_colour(colour_priority, coloration) + + +///Resets the atom's color to null, and then sets it to the highest priority colour available +/atom/movable/plane_master_controller/update_atom_colour() + for(var/atom/movable/screen/plane_master/pm_iterator as anything in get_planes()) + pm_iterator.update_atom_colour() + + +/// Exists for convienience when referencing all game render plates +/atom/movable/plane_master_controller/game + name = PLANE_MASTERS_GAME + controlled_planes = list( + RENDER_PLANE_GAME + ) + +/// Exists for convienience when referencing all non-master render plates. +/// This is the whole game and the UI, but not the escape menu. +/atom/movable/plane_master_controller/non_master + name = PLANE_MASTERS_NON_MASTER + controlled_planes = list( + RENDER_PLANE_GAME, + RENDER_PLANE_NON_GAME, + ) + +/// Exists for convienience when referencing all game render plates +/atom/movable/plane_master_controller/colorblind + name = PLANE_MASTERS_COLORBLIND + controlled_planes = list( + RENDER_PLANE_MASTER + ) diff --git a/code/_onclick/hud/plane_master_group.dm b/code/_onclick/hud/plane_master_group.dm new file mode 100644 index 000000000000..e80588a19c36 --- /dev/null +++ b/code/_onclick/hud/plane_master_group.dm @@ -0,0 +1,199 @@ +/// Datum that represents one "group" of plane masters +/// So all the main window planes would be in one, all the spyglass planes in another +/// Etc +/datum/plane_master_group + /// Our key in the group list on /datum/hud + /// Should be unique for any group of plane masters in the world + var/key + /// Our parent hud + var/datum/hud/our_hud + /// List in the form "[plane]" = object, the plane masters we own + var/list/atom/movable/screen/plane_master/plane_masters = list() + /// The visual offset we are currently using + var/active_offset = 0 + /// What, if any, submap we render onto + var/map = "" + +/datum/plane_master_group/New(key, map = "") + . = ..() + src.key = key + src.map = map + build_plane_masters(0, SSmapping.max_plane_offset) + +/datum/plane_master_group/Destroy() + orphan_hud() + QDEL_LIST_ASSOC_VAL(plane_masters) + return ..() + +/// Display a plane master group to some viewer, so show all our planes to it +/datum/plane_master_group/proc/attach_to(datum/hud/viewing_hud) + if(viewing_hud.master_groups[key]) + stack_trace("Hey brother, our key [key] is already in use by a plane master group on the passed in hud, belonging to [viewing_hud.mymob]. Ya fucked up, why are there dupes") + return + + our_hud = viewing_hud + our_hud.master_groups[key] = src + show_hud() + // transform_lower_turfs(our_hud, active_offset) + +/// Hide the plane master from its current hud, fully clear it out +/datum/plane_master_group/proc/orphan_hud() + if(our_hud) + our_hud.master_groups -= key + hide_hud() + our_hud = null + +/// Well, refresh our group, mostly useful for plane specific updates +/datum/plane_master_group/proc/refresh_hud() + hide_hud() + show_hud() + +/// Fully regenerate our group, resetting our planes to their compile time values +/datum/plane_master_group/proc/rebuild_hud() + hide_hud() + QDEL_LIST_ASSOC_VAL(plane_masters) + build_plane_masters(0, SSmapping.max_plane_offset) + show_hud() + // transform_lower_turfs(our_hud, active_offset) + +/datum/plane_master_group/proc/hide_hud() + for(var/thing in plane_masters) + var/atom/movable/screen/plane_master/plane = plane_masters[thing] + plane.hide_from(our_hud.mymob) + +/datum/plane_master_group/proc/show_hud() + for(var/thing in plane_masters) + var/atom/movable/screen/plane_master/plane = plane_masters[thing] + show_plane(plane) + +/// This is mostly a proc so it can be overriden by popups, since they have unique behavior they want to do +/datum/plane_master_group/proc/show_plane(atom/movable/screen/plane_master/plane) + plane.show_to(our_hud.mymob) + +/// Nice wrapper for the "[]"ing +/datum/plane_master_group/proc/get_plane(plane) + return plane_masters["[plane]"] + +/// Returns a list of all the plane master types we want to create +/datum/plane_master_group/proc/get_plane_types() + return subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/rendering_plate + +/// Actually generate our plane masters, in some offset range (where offset is the z layers to render to, because each "layer" in a multiz stack gets its own plane master cube) +/datum/plane_master_group/proc/build_plane_masters(starting_offset, ending_offset) + for(var/atom/movable/screen/plane_master/mytype as anything in get_plane_types()) + for(var/plane_offset in starting_offset to ending_offset) + if(plane_offset != 0 && !initial(mytype.allows_offsetting)) + continue + var/atom/movable/screen/plane_master/instance = new mytype(null, null, src, plane_offset) + plane_masters["[instance.plane]"] = instance + prep_plane_instance(instance) + +/// Similarly, exists so subtypes can do unique behavior to planes on creation +/datum/plane_master_group/proc/prep_plane_instance(atom/movable/screen/plane_master/instance) + return + +// // It would be nice to setup parallaxing for stairs and things when doing this +// // So they look nicer. if you can't it's all good, if you think you can sanely look at monster's work +// // It's hard, and potentially expensive. be careful +// /datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) +// // Check if this feature is disabled for the client, in which case don't use scale. +// var/mob/our_mob = our_hud?.mymob +// if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) +// use_scale = FALSE + +// // No offset? piss off +// if(!SSmapping.max_plane_offset) +// return + +// active_offset = new_offset + +// // Each time we go "down" a visual z level, we'll reduce the scale by this amount +// // Chosen because mothblocks liked it, didn't cause motion sickness while also giving a sense of height +// var/scale_by = 0.965 +// if(!use_scale) +// // This is a workaround for two things +// // First of all, if a mob can see objects but not turfs, they will not be shown the holder objects we use for +// // What I'd like to do is revert to images if this case throws, but image vis_contents is broken +// // https://www.byond.com/forum/post/2821969 +// // If that's ever fixed, please just use that. thanks :) +// scale_by = 1 + +// var/list/offsets = list() +// var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) + +// // We accept negatives so going down "zooms" away the drop above as it goes +// for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) +// // Multiz boundaries disable transforms +// if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) +// offsets += null +// continue + +// // No transformations if we're landing ON you +// if(offset == 0) +// offsets += null +// continue + +// var/scale = scale_by ** (offset) +// var/matrix/multiz_shrink = matrix() +// multiz_shrink.Scale(scale) +// offsets += multiz_shrink + +// // So we can talk in 1 -> max_offset * 2 + 1, rather then -max_offset -> max_offset +// var/offset_offset = SSmapping.max_plane_offset + 1 + +// for(var/plane_key in plane_masters) +// var/atom/movable/screen/plane_master/plane = plane_masters[plane_key] +// if(!plane.allows_offsetting) +// continue + +// var/visual_offset = plane.offset - new_offset + +// // Basically uh, if we're showing something down X amount of levels, or up any amount of levels +// if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) +// plane.outside_bounds(our_mob) +// else if(plane.is_outside_bounds) +// plane.inside_bounds(our_mob) + +// if(!plane.multiz_scaled) +// continue + +// if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0) +// // We don't animate here because it should be invisble, but we do mark because it'll look nice +// plane.transform = offsets[visual_offset + offset_offset] +// continue + +// animate(plane, transform = offsets[visual_offset + offset_offset], 0.05 SECONDS, easing = LINEAR_EASING) + +/// Holds plane masters for popups, like camera windows +/// Note: We do not scale this plane, even though we could +/// This is because it's annoying to get turfs to position inside it correctly +/// If you wanna try someday feel free, but I can't manage it +/datum/plane_master_group/popup + +// /datum/plane_master_group/popup/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) +// return ..(source, new_offset, FALSE) + +/// Holds the main plane master +/datum/plane_master_group/main + +// /datum/plane_master_group/main/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) +// if(use_scale) +// return ..(source, new_offset, source.should_use_scale()) +// return ..() + +/// Hudless group. Exists for testing +/datum/plane_master_group/hudless + var/mob/our_mob + +/datum/plane_master_group/hudless/Destroy() + . = ..() + our_mob = null + +/datum/plane_master_group/hudless/hide_hud() + for(var/thing in plane_masters) + var/atom/movable/screen/plane_master/plane = plane_masters[thing] + plane.hide_from(our_mob) + +/// This is mostly a proc so it can be overriden by popups, since they have unique behavior they want to do +/datum/plane_master_group/hudless/show_plane(atom/movable/screen/plane_master/plane) + plane.show_to(our_mob) diff --git a/code/_onclick/hud/plane_master_subtypes.dm b/code/_onclick/hud/plane_master_subtypes.dm new file mode 100644 index 000000000000..8988b2f7f33c --- /dev/null +++ b/code/_onclick/hud/plane_master_subtypes.dm @@ -0,0 +1,447 @@ +/atom/movable/screen/plane_master/clickcatcher + name = "Click Catcher" + documentation = "Contains the screen object we use as a backdrop to catch clicks on portions of the screen that would otherwise contain nothing else. \ +
Will always be below almost everything else" + plane = CLICKCATCHER_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + multiz_scaled = FALSE + critical = PLANE_CRITICAL_DISPLAY + +/atom/movable/screen/plane_master/clickcatcher/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(offset_increased)) + offset_increased(SSmapping, 0, SSmapping.max_plane_offset) + +/atom/movable/screen/plane_master/clickcatcher/proc/offset_increased(datum/source, old_off, new_off) + SIGNAL_HANDLER + // We only want need the lowest level + // If my system better supported changing PM plane values mid op I'd do that, but I do NOT so + if(new_off > offset) + hide_plane(home?.our_hud?.mymob) + +/atom/movable/screen/plane_master/parallax_white + name = "Parallax whitifier" + documentation = "Essentially a backdrop for the parallax plane. We're rendered just below it, so we'll be multiplied by its well, parallax.\ +
If you want something to look as if it has parallax on it, draw it to this plane." + plane = PLANE_SPACE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) + critical = PLANE_CRITICAL_FUCKO_PARALLAX // goes funny when touched. no idea why I don't trust byond + +/atom/movable/screen/plane_master/parallax_white/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_SPACE_LAYER) + +///Contains space parallax +/atom/movable/screen/plane_master/parallax + name = "Parallax" + documentation = "Contains parallax, or to be more exact the screen objects that hold parallax.\ +
Note the BLEND_MULTIPLY. The trick here is how low our plane value is. Because of that, we draw below almost everything in the game.\ +
We abuse this to ensure we multiply against the Parallax whitifier plane, or space's plane. It's set to full white, so when you do the multiply you just get parallax out where it well, makes sense to be.\ +
Also notice that the parent parallax plane is mirrored down to all children. We want to support viewing parallax across all z levels at once." + plane = PLANE_SPACE_PARALLAX + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + blend_mode = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + multiz_scaled = FALSE + +/atom/movable/screen/plane_master/parallax/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + if(offset != 0) + // You aren't the source? don't change yourself + return + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_increase)) + RegisterSignal(SSdcs, COMSIG_NARSIE_SUMMON_UPDATE, PROC_REF(narsie_modified)) + if(GLOB.narsie_summon_count >= 1) + narsie_start_midway(GLOB.narsie_effect_last_modified) // We assume we're on the start, so we can use this number + offset_increase(0, SSmapping.max_plane_offset) + +/atom/movable/screen/plane_master/parallax/proc/on_offset_increase(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_increase(old_offset, new_offset) + +/atom/movable/screen/plane_master/parallax/proc/offset_increase(old_offset, new_offset) + // Parallax will be mirrored down to any new planes that are added, so it will properly render across mirage borders + for(var/offset in old_offset to new_offset) + if(offset != 0) + // Overlay so we don't multiply twice, and thus fuck up our rendering + add_relay_to(GET_NEW_PLANE(plane, offset), BLEND_OVERLAY) + +// Hacky shit to ensure parallax works in perf mode +/atom/movable/screen/plane_master/parallax/outside_bounds(mob/relevant) + if(offset == 0) + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, 0)) + is_outside_bounds = TRUE // I'm sorry :( + return + // If we can't render, and we aren't the bottom layer, don't render us + // This way we only multiply against stuff that's not fullwhite space + var/atom/movable/screen/plane_master/parent_parallax = home.our_hud.get_plane_master(PLANE_SPACE_PARALLAX) + var/turf/viewing_turf = get_turf(relevant) + if(!viewing_turf || offset != GET_LOWEST_STACK_OFFSET(viewing_turf.z)) + parent_parallax.remove_relay_from(plane) + else + parent_parallax.add_relay_to(plane, BLEND_OVERLAY) + return ..() + +/atom/movable/screen/plane_master/parallax/inside_bounds(mob/relevant) + if(offset == 0) + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, 0)) + is_outside_bounds = FALSE + return + // Always readd, just in case we lost it + var/atom/movable/screen/plane_master/parent_parallax = home.our_hud.get_plane_master(PLANE_SPACE_PARALLAX) + parent_parallax.add_relay_to(plane, BLEND_OVERLAY) + return ..() + +// Needs to handle rejoining on a lower z level, so we NEED to readd old planes +/atom/movable/screen/plane_master/parallax/check_outside_bounds() + // If we're outside bounds AND we're the 0th plane, we need to show cause parallax is hacked to hell + return offset != 0 && is_outside_bounds + +/// Starts the narsie animation midway, so we can catch up to everyone else quickly +/atom/movable/screen/plane_master/parallax/proc/narsie_start_midway(start_time) + var/time_elapsed = world.time - start_time + narsie_summoned_effect(max(16 SECONDS - time_elapsed, 0)) + +/// Starts the narsie animation, make us grey, then red +/atom/movable/screen/plane_master/parallax/proc/narsie_modified(datum/source, new_count) + SIGNAL_HANDLER + if(new_count >= 1) + narsie_summoned_effect(16 SECONDS) + else + narsie_unsummoned() + +/atom/movable/screen/plane_master/parallax/proc/narsie_summoned_effect(animate_time) + if(GLOB.narsie_summon_count >= 2) + var/static/list/nightmare_parallax = list(255,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, -130,0,0,0) + animate(src, color = nightmare_parallax, time = animate_time) + return + + var/static/list/grey_parallax = list(0.4,0.4,0.4,0, 0.4,0.4,0.4,0, 0.4,0.4,0.4,0, 0,0,0,1, -0.1,-0.1,-0.1,0) + // We're gonna animate ourselves grey + // Then, once it's done, about 40 seconds into the event itself, we're gonna start doin some shit. see below + animate(src, color = grey_parallax, time = animate_time) + +/atom/movable/screen/plane_master/parallax/proc/narsie_unsummoned() + animate(src, color = null, time = 8 SECONDS) + +/atom/movable/screen/plane_master/gravpulse + name = "Gravpulse" + documentation = "Ok so this one's fun. Basically, we want to be able to distort the game plane when a grav annom is around.\ +
So we draw the pattern we want to use to this plane, and it's then used as a render target by a distortion filter on the game plane.\ +
Note the blend mode and lack of relay targets. This plane exists only to distort, it's never rendered anywhere." + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + plane = GRAVITY_PULSE_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + blend_mode = BLEND_ADD + render_target = GRAVITY_PULSE_RENDER_TARGET + render_relay_planes = list() + +///Contains just the floor +/atom/movable/screen/plane_master/floor + name = "Floor" + documentation = "The well, floor. This is mostly used as a sorting mechanism, but it also lets us create a \"border\" around the game world plane, so its drop shadow will actually work." + plane = FLOOR_PLANE + render_relay_planes = list(RENDER_PLANE_GAME, LIGHT_MASK_PLANE) + +/atom/movable/screen/plane_master/transparent_floor + name = "Transparent Floor" + documentation = "Really just openspace, stuff that is a turf but has no color or alpha whatsoever.\ +
We use this to draw to just the light mask plane, cause if it's not there we get holes of blackness over openspace" + plane = TRANSPARENT_FLOOR_PLANE + render_relay_planes = list(LIGHT_MASK_PLANE) + // Needs to be critical or it uh, it'll look white + critical = PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_RELAY + +/atom/movable/screen/plane_master/floor/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_FLOOR_LAYER, relay_color = GLOB.em_block_color) + +/atom/movable/screen/plane_master/wall + 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_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) + +/atom/movable/screen/plane_master/wall/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_WALL_LAYER, relay_color = GLOB.em_block_color) + +/atom/movable/screen/plane_master/game + name = "Lower game world" + documentation = "Exists mostly because of FOV shit. Basically, if you've just got a normal not ABOVE fov thing, and you don't want it masked, stick it here yeah?" + plane = GAME_PLANE + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + +/atom/movable/screen/plane_master/game_world_fov_hidden + name = "lower game world fov hidden" + documentation = "If you want something to be hidden by fov, stick it on this plane. We're masked by the fov blocker plane, so the items on us can actually well, disappear." + plane = GAME_PLANE_FOV_HIDDEN + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + +/atom/movable/screen/plane_master/game_world_fov_hidden/Initialize(mapload, datum/hud/hud_owner) + . = ..() + add_filter("vision_cone", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(FIELD_OF_VISION_BLOCKER_RENDER_TARGET, offset), flags = MASK_INVERSE)) + +/atom/movable/screen/plane_master/field_of_vision_blocker + name = "Field of vision blocker" + documentation = "This is one of those planes that's only used as a filter. It masks out things that want to be hidden by fov.\ +
Literally just contains FOV images, or masks." + plane = FIELD_OF_VISION_BLOCKER_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_target = FIELD_OF_VISION_BLOCKER_RENDER_TARGET + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_relay_planes = list() + // We do NOT allow offsetting, because there's no case where you would want to block only one layer, at least currently + allows_offsetting = FALSE + start_hidden = TRUE + // We mark as multiz_scaled FALSE so transforms don't effect us, and we draw to the planes below us as if they were us. + // This is safe because we will ALWAYS be on the top z layer, so it DON'T MATTER + multiz_scaled = FALSE + +/atom/movable/screen/plane_master/field_of_vision_blocker/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + mirror_parent_hidden() + +/atom/movable/screen/plane_master/game_world_upper + name = "Upper game world" + documentation = "Ok so fov is kinda fucky, because planes in byond serve both as effect groupings and as rendering orderers. Since that's true, we need a plane that we can stick stuff that draws above fov blocked stuff on." + plane = GAME_PLANE_UPPER + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + +/atom/movable/screen/plane_master/wall_upper + name = "Upper wall" + documentation = "There are some walls that want to render above most things (mostly minerals since they shift over.\ +
We draw them to their own plane so we can hijack them for our emissive mask stuff" + plane = WALL_PLANE_UPPER + render_relay_planes = list(RENDER_PLANE_GAME_WORLD, LIGHT_MASK_PLANE) + +/atom/movable/screen/plane_master/wall_upper/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset), relay_layer = EMISSIVE_WALL_LAYER, relay_color = GLOB.em_block_color) + +/atom/movable/screen/plane_master/game_world_upper_fov_hidden + name = "Upper game world fov hidden" + documentation = "Just as we need a place to draw things \"above\" the hidden fov plane, we also need to be able to hide stuff that draws over the upper game plane." + plane = GAME_PLANE_UPPER_FOV_HIDDEN + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + +/atom/movable/screen/plane_master/game_world_upper_fov_hidden/Initialize(mapload, datum/hud/hud_owner) + . = ..() + // Dupe of the other hidden plane + add_filter("vision_cone", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(FIELD_OF_VISION_BLOCKER_RENDER_TARGET, offset), flags = MASK_INVERSE)) + +/atom/movable/screen/plane_master/seethrough + name = "Seethrough" + documentation = "Holds the seethrough versions (done using image overrides) of large objects. Mouse transparent, so you can click through them." + plane = SEETHROUGH_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + start_hidden = TRUE + +/atom/movable/screen/plane_master/game_world_above + name = "Above game world" + documentation = "We need a place that's unmasked by fov that also draws above the upper game world fov hidden plane. I told you fov was hacky man." + plane = ABOVE_GAME_PLANE + render_relay_planes = list(RENDER_PLANE_GAME_WORLD) + +/** + * Plane master that byond will by default draw to + * Shouldn't be used, exists to prevent people using plane 0 + * NOTE: If we used SEE_BLACKNESS on a map format that wasn't SIDE_MAP, this is where its darkness would land + * This would allow us to control it and do fun things. But we can't because side map doesn't support it, so this is just a stub + */ +/atom/movable/screen/plane_master/default + name = "Default" + documentation = "This is quite fiddly, so bear with me. By default (in byond) everything in the game is rendered onto plane 0. It's the default plane. \ +
But, because we've moved everything we control off plane 0, all that's left is stuff byond internally renders. \ +
What I'd like to do with this is capture byond blackness by giving mobs the SEE_BLACKNESS sight flag. \ +
But we CAN'T because SEE_BLACKNESS does not work with our rendering format. So I just eat it I guess" + plane = DEFAULT_PLANE + multiz_scaled = FALSE + start_hidden = TRUE // Doesn't DO anything, exists to hold this place + +/atom/movable/screen/plane_master/area + name = "Area" + documentation = "Holds the areas themselves, which ends up meaning it holds any overlays/effects we apply to areas. NOT snow or rad storms, those go on above lighting" + plane = AREA_PLANE + +/atom/movable/screen/plane_master/massive_obj + name = "Massive object" + documentation = "Huge objects need to render above everything else on the game plane, otherwise they'd well, get clipped and look not that huge. This does that." + plane = MASSIVE_OBJ_PLANE + +/atom/movable/screen/plane_master/point + name = "Point" + documentation = "I mean like, what do you want me to say? Points draw over pretty much everything else, so they get their own plane. Remember we layer render relays to draw planes in their proper order on render plates." + plane = POINT_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +///Contains all turf lighting +/atom/movable/screen/plane_master/turf_lighting + name = "Turf Lighting" + documentation = "Contains all lighting drawn to turfs. Not so complex, draws directly onto the lighting plate." + plane = LIGHTING_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_LIGHTING) + blend_mode_override = BLEND_ADD + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + critical = PLANE_CRITICAL_DISPLAY + +/// This will not work through multiz, because of a byond bug with BLEND_MULTIPLY +/// Bug report is up, waiting on a fix +/atom/movable/screen/plane_master/o_light_visual + name = "Overlight light visual" + documentation = "Holds overlay lighting objects, or the sort of lighting that's a well, overlay stuck to something.\ +
Exists because lighting updating is really slow, and movement needs to feel smooth.\ +
We draw to the game plane, and mask out space for ourselves on the lighting plane so any color we have has the chance to display." + plane = O_LIGHTING_VISUAL_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_target = O_LIGHTING_VISUAL_RENDER_TARGET + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + blend_mode = BLEND_MULTIPLY + critical = PLANE_CRITICAL_DISPLAY + +/atom/movable/screen/plane_master/above_lighting + name = "Above lighting" + plane = ABOVE_LIGHTING_PLANE + documentation = "Anything on the game plane that needs a space to draw on that will be above the lighting plane.\ +
Mostly little alerts and effects, also sometimes contains things that are meant to look as if they glow." + +/** + * Handles emissive overlays and emissive blockers. + */ +/atom/movable/screen/plane_master/emissive + name = "Emissive" + documentation = "Holds things that will be used to mask the lighting plane later on. Masked by the Emissive Mask plane to ensure we don't emiss out under a wall.\ +
Relayed onto the Emissive render plane to do the actual masking of lighting, since we need to be transformed and other emissive stuff needs to be transformed too.\ +
Don't want to double scale now." + plane = EMISSIVE_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_relay_planes = list(EMISSIVE_RENDER_PLATE) + critical = PLANE_CRITICAL_DISPLAY + +/atom/movable/screen/plane_master/pipecrawl + name = "Pipecrawl" + documentation = "Holds pipecrawl images generated during well, pipecrawling.\ +
Has a few effects and a funky color matrix designed to make things a bit more visually readable." + plane = PIPECRAWL_IMAGES_PLANE + start_hidden = TRUE + +/atom/movable/screen/plane_master/pipecrawl/Initialize(mapload, datum/hud/hud_owner) + . = ..() + // Makes everything on this plane slightly brighter + // Has a nice effect, makes thing stand out + color = list(1.2,0,0,0, 0,1.2,0,0, 0,0,1.2,0, 0,0,0,1, 0,0,0,0) + // This serves a similar purpose, I want the pipes to pop + add_filter("pipe_dropshadow", 1, drop_shadow_filter(x = -1, y= -1, size = 1, color = "#0000007A")) + mirror_parent_hidden() + +/atom/movable/screen/plane_master/camera_static + name = "Camera static" + documentation = "Holds camera static images. Usually only visible to people who can well, see static.\ +
We use images rather then vis contents because they're lighter on maptick, and maptick sucks butt." + plane = CAMERA_STATIC_PLANE + +/atom/movable/screen/plane_master/camera_static/show_to(mob/mymob) + . = ..() + if(!.) + return + var/datum/hud/our_hud = home.our_hud + if(isnull(our_hud)) + return + + // We'll hide the slate if we're not seeing through a camera eye + // This can call on a cycle cause we don't clear in hide_from + // Yes this is the best way of hooking into the hud, I hate myself too + RegisterSignal(our_hud, COMSIG_HUD_EYE_CHANGED, PROC_REF(eye_changed), override = TRUE) + eye_changed(our_hud, null, our_hud.mymob?.canon_client?.eye) + +/atom/movable/screen/plane_master/camera_static/proc/eye_changed(datum/hud/source, atom/old_eye, atom/new_eye) + SIGNAL_HANDLER + + if(!isaicamera(new_eye)) + if(!force_hidden) + hide_plane(source.mymob) + return + + if(force_hidden) + unhide_plane(source.mymob) + +/atom/movable/screen/plane_master/high_game + name = "High Game" + documentation = "Holds anything that wants to be displayed above the rest of the game plane, and doesn't want to be clickable. \ +
This includes atmos debug overlays, blind sound images, and mining scanners. \ +
Really only exists for its layering potential, we don't use this for any vfx" + plane = HIGH_GAME_PLANE + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/atom/movable/screen/plane_master/ghost + name = "Ghost" + documentation = "Ghosts draw here, so they don't get mixed up in the visuals of the game world. Note, this is not not how we HIDE ghosts from people, that's done with invisible and see_invisible." + plane = GHOST_PLANE + render_relay_planes = list(RENDER_PLANE_NON_GAME) + +/atom/movable/screen/plane_master/fullscreen + name = "Fullscreen" + documentation = "Holds anything that applies to or above the full screen. \ +
Note, it's still rendered underneath hud objects, but this lets us control the order that things like death/damage effects render in." + plane = FULLSCREEN_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_NON_GAME) + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + allows_offsetting = FALSE + +/atom/movable/screen/plane_master/runechat + name = "Runechat" + documentation = "Holds runechat images, that text that pops up when someone say something. Uses a dropshadow to well, look nice." + plane = RUNECHAT_PLANE + render_relay_planes = list(RENDER_PLANE_NON_GAME) + +/atom/movable/screen/plane_master/runechat/show_to(mob/mymob) + . = ..() + if(!.) + return + remove_filter("AO") + if(istype(mymob) && mymob.canon_client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion)) + add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) + +/atom/movable/screen/plane_master/balloon_chat + name = "Balloon chat" + documentation = "Holds ballon chat images, those little text bars that pop up for a second when you do some things. NOT runechat." + plane = BALLOON_CHAT_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_NON_GAME) + +/atom/movable/screen/plane_master/hud + name = "HUD" + documentation = "Contains anything that want to be rendered on the hud. Typically is just screen elements." + plane = HUD_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_NON_GAME) + allows_offsetting = FALSE + +/atom/movable/screen/plane_master/above_hud + name = "Above HUD" + documentation = "Anything that wants to be drawn ABOVE the rest of the hud. Typically close buttons and other elements that need to be always visible. Think preventing draggable action button memes." + plane = ABOVE_HUD_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_NON_GAME) + allows_offsetting = FALSE + +/atom/movable/screen/plane_master/splashscreen + name = "Splashscreen" + documentation = "Cinematics and the splash screen." + plane = SPLASHSCREEN_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_NON_GAME) + allows_offsetting = FALSE + +/atom/movable/screen/plane_master/escape_menu + name = "Escape Menu" + documentation = "Anything relating to the escape menu." + plane = ESCAPE_MENU_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + render_relay_planes = list(RENDER_PLANE_MASTER) + allows_offsetting = FALSE diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm new file mode 100644 index 000000000000..9d5b5db99338 --- /dev/null +++ b/code/_onclick/hud/render_plate.dm @@ -0,0 +1,386 @@ +/*! + * Custom rendering solution to allow for advanced effects + * We (ab)use plane masters and render source/target to cheaply render 2+ planes as 1 + * if you want to read more read the _render_readme.md + */ + + +/** + * Render relay object assigned to a plane master to be able to relay it's render onto other planes that are not it's own + */ +/atom/movable/render_plane_relay + screen_loc = "CENTER" + layer = -1 + plane = 0 + appearance_flags = PASS_MOUSE | NO_CLIENT_COLOR | KEEP_TOGETHER + /// If we render into a critical plane master, or not + var/critical_target = FALSE + +/** + * ## Rendering plate + * + * Acts like a plane master, but for plane masters + * Renders other planes onto this plane, through the use of render objects + * Any effects applied onto this plane will act on the unified plane + * IE a bulge filter will apply as if the world was one object + * remember that once planes are unified on a render plate you cant change the layering of them! + */ +/atom/movable/screen/plane_master/rendering_plate + name = "Default rendering plate" + multiz_scaled = FALSE + +///this plate renders the final screen to show to the player +/atom/movable/screen/plane_master/rendering_plate/master + name = "Master rendering plate" + documentation = "The endpoint of all plane masters, you can think of this as the final \"view\" we draw.\ +
If offset is not 0 this will be drawn to the transparent plane of the floor above, but otherwise this is drawn to nothing, or shown to the player." + plane = RENDER_PLANE_MASTER + render_relay_planes = list() + +/atom/movable/screen/plane_master/rendering_plate/master/show_to(mob/mymob) + . = ..() + if(!.) + return + if(offset == 0) + return + // Non 0 offset render plates will relay up to the transparent plane above them, assuming they're not on the same z level as their target of course + var/datum/hud/hud = home.our_hud + // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this + if(hud) + RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) + offset_change(hud?.current_plane_offset || 0) + +/atom/movable/screen/plane_master/rendering_plate/master/hide_from(mob/oldmob) + . = ..() + if(offset == 0) + return + var/datum/hud/hud = home.our_hud + if(hud) + UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + +/atom/movable/screen/plane_master/rendering_plate/master/proc/on_offset_change(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_change(new_offset) + +/atom/movable/screen/plane_master/rendering_plate/master/proc/offset_change(new_offset) + if(new_offset == offset) // If we're on our own z layer, relay to nothing, just draw + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) + else // Otherwise, regenerate the relay + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_TRANSPARENT, offset - 1)) + +///renders general in charachter game objects +/atom/movable/screen/plane_master/rendering_plate/game_plate + name = "Game rendering plate" + documentation = "Holds all objects that are ahhh, in character? is maybe the best way to describe it.\ +
We apply a displacement effect from the gravity pulse plane too, so we can warp the game world." + plane = RENDER_PLANE_GAME + render_relay_planes = list(RENDER_PLANE_MASTER) + +/atom/movable/screen/plane_master/rendering_plate/game_plate/Initialize(mapload, datum/hud/hud_owner) + . = ..() + add_filter("displacer", 1, displacement_map_filter(render_source = OFFSET_RENDER_TARGET(GRAVITY_PULSE_RENDER_TARGET, offset), size = 10)) + +// Blackness renders weird when you view down openspace, because of transforms and borders and such +// This is a consequence of not using lummy's grouped transparency, but I couldn't get that to work without totally fucking up +// Sight flags, and shooting vis_contents usage to the moon. So we're doin it different. +// If image vis contents worked (it should in 515), and we were ok with a maptick cost (wait for threaded maptick) this could be fixed +/atom/movable/screen/plane_master/rendering_plate/transparent + name = "Transparent plate" + documentation = "The master rendering plate from the offset below ours will be mirrored onto this plane. That way we achive a \"stack\" effect.\ +
This plane exists to uplayer the master rendering plate to the correct spot in our z layer's rendering order" + plane = RENDER_PLANE_TRANSPARENT + appearance_flags = PLANE_MASTER + +/atom/movable/screen/plane_master/rendering_plate/transparent/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + // Don't display us if we're below everything else yeah? + AddComponent(/datum/component/plane_hide_highest_offset) + color = list(0.9,0,0,0, 0,0.9,0,0, 0,0,0.9,0, 0,0,0,1, 0,0,0,0) + +///Contains most things in the game world +/atom/movable/screen/plane_master/rendering_plate/game_world + name = "Game world plate" + documentation = "Contains most of the objects in the world. Mobs, machines, etc. Note the drop shadow, it gives a very nice depth effect." + plane = RENDER_PLANE_GAME_WORLD + appearance_flags = PLANE_MASTER //should use client color + blend_mode = BLEND_OVERLAY + +/atom/movable/screen/plane_master/rendering_plate/game_world/show_to(mob/mymob) + . = ..() + if(!.) + return + remove_filter("AO") + if(istype(mymob) && mymob.canon_client?.prefs?.read_preference(/datum/preference/toggle/ambient_occlusion)) + add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) + +///Contains all lighting objects +/atom/movable/screen/plane_master/rendering_plate/lighting + name = "Lighting plate" + documentation = "Anything on this plane will be multiplied with the plane it's rendered onto (typically the game plane).\ +
That's how lighting functions at base. Because it uses BLEND_MULTIPLY and occasionally color matrixes, it needs a backdrop of blackness.\ +
See This byond post\ +
Lemme see uh, we're masked by the emissive plane so it can actually function (IE: make things glow in the dark).\ +
We're also masked by the overlay lighting plane, which contains all the movable lights in the game. It draws to us and also the game plane.\ +
Masks us out so it has the breathing room to apply its effect.\ +
Oh and we quite often have our alpha changed to achive night vision effects, or things of that sort." + plane = RENDER_PLANE_LIGHTING + blend_mode_override = BLEND_MULTIPLY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + critical = PLANE_CRITICAL_DISPLAY + /// A list of light cutoffs we're actively using, (mass, r, g, b) to avoid filter churn + var/list/light_cutoffs + +/*! + * This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers. + * + * Emissive overlays are pasted with an atom color that converts them to be entirely some specific color. + * Emissive blockers are pasted with an atom color that converts them to be entirely some different color. + * Emissive overlays and emissive blockers are put onto the same plane. + * The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects. + * A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is. + * This is then used to alpha mask the lighting plane. + */ +/atom/movable/screen/plane_master/rendering_plate/lighting/Initialize(mapload, datum/hud/hud_owner) + . = ..() + add_filter("emissives", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(EMISSIVE_RENDER_TARGET, offset), flags = MASK_INVERSE)) + add_filter("object_lighting", 2, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(O_LIGHTING_VISUAL_RENDER_TARGET, offset), flags = MASK_INVERSE)) + set_light_cutoff(10) + +/atom/movable/screen/plane_master/rendering_plate/lighting/show_to(mob/mymob) + . = ..() + if(!.) + return + // This applies a backdrop to our lighting plane + // Why do plane masters need a backdrop sometimes? Read https://secure.byond.com/forum/?post=2141928 + // Basically, we need something to brighten + // unlit is perhaps less needed rn, it exists to provide a fullbright for things that can't see the lighting plane + // but we don't actually use invisibility to hide the lighting plane anymore, so it's pointless + var/atom/movable/screen/backdrop = mymob.overlay_fullscreen("lighting_backdrop_lit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/lit) + // Need to make sure they're on our plane, ALL the time. We always need a backdrop + SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) + backdrop = mymob.overlay_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]", /atom/movable/screen/fullscreen/lighting_backdrop/unlit) + SET_PLANE_EXPLICIT(backdrop, PLANE_TO_TRUE(backdrop.plane), src) + + // Sorry, this is a bit annoying + // Basically, we only want the lighting plane we can actually see to attempt to render + // If we don't our lower plane gets totally overriden by the black void of the upper plane + var/datum/hud/hud = home.our_hud + // show_to can be called twice successfully with no hide_from call. Ensure no runtimes off the registers from this + if(hud) + RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change), override = TRUE) + offset_change(hud?.current_plane_offset || 0) + set_light_cutoff(mymob.lighting_cutoff, mymob.lighting_color_cutoffs) + + +/atom/movable/screen/plane_master/rendering_plate/lighting/hide_from(mob/oldmob) + . = ..() + oldmob.clear_fullscreen("lighting_backdrop_lit_[home.key]#[offset]") + oldmob.clear_fullscreen("lighting_backdrop_unlit_[home.key]#[offset]") + var/datum/hud/hud = home.our_hud + if(hud) + UnregisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, PROC_REF(on_offset_change)) + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/on_offset_change(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_change(new_offset) + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/offset_change(mob_offset) + // Offsets stack down remember. This implies that we're above the mob's view plane, and shouldn't render + if(offset < mob_offset) + disable_alpha() + else + enable_alpha() + +/atom/movable/screen/plane_master/rendering_plate/lighting/proc/set_light_cutoff(light_cutoff, list/color_cutoffs) + var/list/new_cutoffs = list(light_cutoff) + new_cutoffs += color_cutoffs + if(new_cutoffs ~= light_cutoffs) + return + + remove_filter(list("light_cutdown", "light_cutup")) + + var/ratio = light_cutoff/100 + if(!color_cutoffs) + color_cutoffs = list(0, 0, 0) + + var/red = color_cutoffs[1] / 100 + var/green = color_cutoffs[2] / 100 + var/blue = color_cutoffs[3] / 100 + add_filter("light_cutdown", 3, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, -(ratio + red),-(ratio+green),-(ratio+blue),0))) + add_filter("light_cutup", 4, color_matrix_filter(list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, ratio+red,ratio+green,ratio+blue,0))) + +/atom/movable/screen/plane_master/rendering_plate/emissive_slate + name = "Emissive Plate" + documentation = "This system works by exploiting BYONDs color matrix filter to use layers to handle emissive blockers.\ +
Emissive overlays are pasted with an atom color that converts them to be entirely some specific color.\ +
Emissive blockers are pasted with an atom color that converts them to be entirely some different color.\ +
Emissive overlays and emissive blockers are put onto the same plane (This one).\ +
The layers for the emissive overlays and emissive blockers cause them to mask eachother similar to normal BYOND objects.\ +
A color matrix filter is applied to the emissive plane to mask out anything that isn't whatever the emissive color is.\ +
This is then used to alpha mask the lighting plane." + plane = EMISSIVE_RENDER_PLATE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = EMISSIVE_RENDER_TARGET + render_relay_planes = list() + critical = PLANE_CRITICAL_DISPLAY + +/atom/movable/screen/plane_master/rendering_plate/emissive_slate/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset) + . = ..() + add_filter("em_block_masking", 2, color_matrix_filter(GLOB.em_mask_matrix)) + if(offset != 0) + add_relay_to(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset - 1), relay_layer = EMISSIVE_Z_BELOW_LAYER) + +/atom/movable/screen/plane_master/rendering_plate/light_mask + name = "Light Mask" + documentation = "Any part of this plane that is transparent will be black below it on the game rendering plate.\ +
This is done to ensure emissives and overlay lights don't light things up \"through\" the darkness that normally sits at the bottom of the lighting plane.\ +
We relay copies of the space, floor and wall planes to it, so we can use them as masks. Then we just boost any existing alpha to 100% and we're done.\ +
If we ever switch to a sight setup that shows say, mobs but not floors, we instead mask just overlay lighting and emissives.\ +
This avoids dumb seethrough without breaking stuff like thermals." + plane = LIGHT_MASK_PLANE + appearance_flags = PLANE_MASTER|NO_CLIENT_COLOR + // Fullwhite where there's anything, no color otherwise + color = list(255,255,255,255, 255,255,255,255, 255,255,255,255, 255,255,255,255, 0,0,0,0) + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + render_target = LIGHT_MASK_RENDER_TARGET + // We blend against the game plane, so she's gotta multiply! + blend_mode = BLEND_MULTIPLY + render_relay_planes = list(RENDER_PLANE_GAME) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/show_to(mob/mymob) + . = ..() + if(!.) + return + + RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight)) + handle_sight(mymob, mymob.sight, NONE) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/hide_from(mob/oldmob) + . = ..() + var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) + overlay_lights.remove_filter("lighting_mask") + var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) + emissive.remove_filter("lighting_mask") + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) + UnregisterSignal(oldmob, COMSIG_MOB_SIGHT_CHANGE) + +/atom/movable/screen/plane_master/rendering_plate/light_mask/proc/handle_sight(datum/source, new_sight, old_sight) + // If we can see something that shows "through" blackness, and we can't see turfs, disable our draw to the game plane + // And instead mask JUST the overlay lighting plane, since that will look fuckin wrong + var/atom/movable/screen/plane_master/overlay_lights = home.get_plane(GET_NEW_PLANE(O_LIGHTING_VISUAL_PLANE, offset)) + var/atom/movable/screen/plane_master/emissive = home.get_plane(GET_NEW_PLANE(EMISSIVE_RENDER_PLATE, offset)) + if(new_sight & SEE_AVOID_TURF_BLACKNESS && !(new_sight & SEE_TURFS)) + remove_relay_from(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) + overlay_lights.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) + emissive.add_filter("lighting_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(LIGHT_MASK_RENDER_TARGET, offset))) + // If we CAN'T see through the black, then draw er down brother! + else + overlay_lights.remove_filter("lighting_mask") + emissive.remove_filter("lighting_mask") + // We max alpha here, so our darkness is actually.. dark + // Can't do it before cause it fucks with the filter + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) + +///render plate for OOC stuff like ghosts, hud-screen effects, etc +/atom/movable/screen/plane_master/rendering_plate/non_game + name = "Non-Game rendering plate" + documentation = "Renders anything that's out of character. Mostly useful as a converse to the game rendering plate." + plane = RENDER_PLANE_NON_GAME + render_relay_planes = list(RENDER_PLANE_MASTER) + +/** + * Plane master proc called in Initialize() that creates relay objects, and sets them uo as needed + * Sets: + * * layer from plane to avoid z-fighting + * * planes to relay the render to + * * render_source so that the plane will render on these objects + * * mouse opacity to ensure proper mouse hit tracking + * * name for debugging purposes + * Other vars such as alpha will automatically be applied with the render source + */ +/atom/movable/screen/plane_master/proc/generate_render_relays() + var/relay_loc = "CENTER" + // If we're using a submap (say for a popup window) make sure we draw onto it + if(home?.map) + relay_loc = "[home.map]:[relay_loc]" + + var/list/generated_planes = list() + for(var/atom/movable/render_plane_relay/relay as anything in relays) + generated_planes += relay.plane + + for(var/relay_plane in (render_relay_planes - generated_planes)) + generate_relay_to(relay_plane, relay_loc) + + if(blend_mode != BLEND_MULTIPLY) + blend_mode = BLEND_DEFAULT + relays_generated = TRUE + +/// Creates a connection between this plane master and the passed in plane +/// Helper for out of system code, shouldn't be used in this file +/// Build system to differenchiate between generated and non generated render relays +/atom/movable/screen/plane_master/proc/add_relay_to(target_plane, blend_override, relay_layer, relay_color) + if(get_relay_to(target_plane)) + return + render_relay_planes += target_plane + var/client/display_lad = home?.our_hud?.mymob?.canon_client + var/atom/movable/render_plane_relay/relay = generate_relay_to(target_plane, show_to = display_lad, blend_override = blend_override, relay_layer = relay_layer) + relay.color = relay_color + +/proc/get_plane_master_render_base(name) + return "*[name]: AUTOGENERATED RENDER TGT" + +/atom/movable/screen/plane_master/proc/generate_relay_to(target_plane, relay_loc, client/show_to, blend_override, relay_layer) + if(!length(relays) && !initial(render_target)) + render_target = OFFSET_RENDER_TARGET(get_plane_master_render_base(name), offset) + if(!relay_loc) + relay_loc = "CENTER" + // If we're using a submap (say for a popup window) make sure we draw onto it + if(home?.map) + relay_loc = "[home.map]:[relay_loc]" + var/blend_to_use = blend_override + if(isnull(blend_to_use)) + blend_to_use = blend_mode_override || initial(blend_mode) + + var/atom/movable/render_plane_relay/relay = new() + relay.render_source = render_target + relay.plane = target_plane + relay.screen_loc = relay_loc + // There are two rules here + // 1: layer needs to be positive (negative layers are treated as float layers) + // 2: lower planes (including offset ones) need to be layered below higher ones (because otherwise they'll render fucky) + // By multiplying LOWEST_EVER_PLANE by 30, we give 30 offsets worth of room to planes before they start going negative + // Bet + // We allow for manuel override if requested. careful with this + relay.layer = relay_layer || (plane + abs(LOWEST_EVER_PLANE * 30)) //layer must be positive but can be a decimal + relay.blend_mode = blend_to_use + relay.mouse_opacity = mouse_opacity + relay.name = render_target + relay.critical_target = PLANE_IS_CRITICAL(target_plane) + relays += relay + // Relays are sometimes generated early, before huds have a mob to display stuff to + // That's what this is for + if(show_to) + show_to.screen += relay + return relay + +/// Breaks a connection between this plane master, and the passed in place +/atom/movable/screen/plane_master/proc/remove_relay_from(target_plane) + render_relay_planes -= target_plane + var/atom/movable/render_plane_relay/existing_relay = get_relay_to(target_plane) + if(!existing_relay) + return + relays -= existing_relay + if(!length(relays) && !initial(render_target)) + render_target = null + var/client/lad = home?.our_hud?.mymob?.canon_client + if(lad) + lad.screen -= existing_relay + +/// Gets the relay atom we're using to connect to the target plane, if one exists +/atom/movable/screen/plane_master/proc/get_relay_to(target_plane) + for(var/atom/movable/render_plane_relay/relay in relays) + if(relay.plane == target_plane) + return relay + + return null diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 3d0e1295dc5b..bc7305876274 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -185,3 +185,4 @@ SUBSYSTEM_DEF(events) /datum/controller/subsystem/events/proc/resetFrequency() frequency_lower = initial(frequency_lower) frequency_upper = initial(frequency_upper) + diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index f572a652d1b0..7a7f5eb69860 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -26,6 +26,9 @@ SUBSYSTEM_DEF(mapping) var/list/station_minimaps = list() + /// List of z level (as number) -> The lowest plane offset in that z stack + var/list/z_level_to_lowest_plane_offset = list() + /// Assoc list of string plane to the plane's offset value var/list/plane_to_offset diff --git a/code/datums/brain_damage/creepy_trauma.dm b/code/datums/brain_damage/creepy_trauma.dm index a8c87ab78a83..ad3cac664e2b 100644 --- a/code/datums/brain_damage/creepy_trauma.dm +++ b/code/datums/brain_damage/creepy_trauma.dm @@ -91,7 +91,7 @@ switch(rand(1, 100)) if(1 to 40) INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), pick("blink", "blink_r")) - owner.blur_eyes(10) + owner.adjust_eye_blur(10) to_chat(owner, span_userdanger("You sweat profusely and have a hard time focusing...")) if(41 to 80) INVOKE_ASYNC(owner, TYPE_PROC_REF(/mob, emote), "pale") diff --git a/code/datums/brain_damage/mild.dm b/code/datums/brain_damage/mild.dm index 9eccabd5d59a..cf8b54ba9c48 100644 --- a/code/datums/brain_damage/mild.dm +++ b/code/datums/brain_damage/mild.dm @@ -117,7 +117,7 @@ owner.adjust_dizzy(20 SECONDS) if(4,5) owner.adjust_confusion(10 SECONDS) - owner.blur_eyes(10) + owner.adjust_eye_blur(10) if(6 to 9) owner.adjust_slurring(1 MINUTES) if(10) diff --git a/code/datums/components/hide_highest_offset.dm b/code/datums/components/hide_highest_offset.dm new file mode 100644 index 000000000000..eb5b5660db0f --- /dev/null +++ b/code/datums/components/hide_highest_offset.dm @@ -0,0 +1,24 @@ +/// Component that takes a plane master, and will hide it if it's the highest offset of its kind +/// This allows us to not show PMs to clients if they're not actively doing anything +/datum/component/plane_hide_highest_offset + +/datum/component/plane_hide_highest_offset/Initialize() + if(!istype(parent, /atom/movable/screen/plane_master)) + return + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_increase)) + offset_increase(SSmapping.max_plane_offset) + +/datum/component/plane_hide_highest_offset/proc/on_offset_increase(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + offset_increase(new_offset) + +/datum/component/plane_hide_highest_offset/proc/offset_increase(new_offset) + var/atom/movable/screen/plane_master/plane_parent = parent + var/mob/our_mob = plane_parent.home?.our_hud?.mymob + var/our_offset = plane_parent.offset + if(!our_mob) + return + if(our_offset == new_offset) + plane_parent.hide_plane(our_mob) + else if(plane_parent.force_hidden) + plane_parent.unhide_plane(our_mob) diff --git a/code/datums/datum.dm b/code/datums/datum.dm index 303ca4d21f04..884218199d8f 100644 --- a/code/datums/datum.dm +++ b/code/datums/datum.dm @@ -313,3 +313,39 @@ /obj/item/update_filters() . = ..() update_item_action_buttons() + +/datum/proc/add_filter(name, priority, list/params) + LAZYINITLIST(filter_data) + var/list/copied_parameters = params.Copy() + copied_parameters["priority"] = priority + filter_data[name] = copied_parameters + update_filters() + +/// Returns the indice in filters of the given filter name. +/// If it is not found, returns null. +/datum/proc/get_filter_index(name) + return filter_data?.Find(name) + +/// Removes the passed filter, or multiple filters, if supplied with a list. +/datum/proc/remove_filter(name_or_names) + if(!filter_data) + return + + var/list/names = islist(name_or_names) ? name_or_names : list(name_or_names) + + for(var/name in names) + if(filter_data[name]) + filter_data -= name + update_filters() + +/datum/proc/clear_filters() + ASSERT(isatom(src) || istype(src, /image)) + var/atom/atom_cast = src // filters only work with images or atoms. + filter_data = null + atom_cast.filters = null + +/// Return text from this proc to provide extra context to hard deletes that happen to it +/// Optional, you should use this for cases where replication is difficult and extra context is required +/// Can be called more then once per object, use harddel_deets_dumped to avoid duplicate calls (I am so sorry) +/datum/proc/dump_harddel_info() + return diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 410a215652c7..bd4682516c3d 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -98,16 +98,16 @@ to_chat(M, span_notice("Your vision slowly returns...")) M.cure_blind(EYE_DAMAGE) M.cure_nearsighted(EYE_DAMAGE) - M.blur_eyes(35) + M.adjust_eye_blur(35) else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE)) to_chat(M, span_notice("You can finally focus your eyes on distant objects.")) M.cure_nearsighted(EYE_DAMAGE) - M.blur_eyes(10) + M.adjust_eye_blur(10) else if(M.eye_blind || M.eye_blurry) M.set_blindness(0) - M.set_blurriness(0) + M.set_eye_blur(0) else if(eyes.damage > 0) eyes.applyOrganDamage(-1) else diff --git a/code/datums/diseases/advance/symptoms/vision.dm b/code/datums/diseases/advance/symptoms/vision.dm index 7d428afa0f53..c860a9f5a25d 100644 --- a/code/datums/diseases/advance/symptoms/vision.dm +++ b/code/datums/diseases/advance/symptoms/vision.dm @@ -57,10 +57,10 @@ Bonus to_chat(M, span_warning("Your eyes itch.")) if(3, 4) to_chat(M, span_warning("Your eyes burn!")) - M.blur_eyes(10) + M.adjust_eye_blur(10) eyes.applyOrganDamage(1) else - M.blur_eyes(20) + M.adjust_eye_blur(20) eyes.applyOrganDamage(5) if(eyes.damage >= 10) M.become_nearsighted(EYE_DAMAGE) diff --git a/code/datums/diseases/sleepy.dm b/code/datums/diseases/sleepy.dm index 0ca951fa8a04..209a4ef207c3 100644 --- a/code/datums/diseases/sleepy.dm +++ b/code/datums/diseases/sleepy.dm @@ -50,10 +50,10 @@ affected_mob.adjustStaminaLoss(10) if(prob(3)) to_chat(affected_mob, span_danger("Your eyes feel strained.")) - affected_mob.blur_eyes(6) + affected_mob.adjust_eye_blur(6) if(prob(3)) to_chat(affected_mob, span_warning("[pick("So tired...","You feel very sleepy.","You have a hard time keeping your eyes open.","You try to stay awake.")]")) - affected_mob.blur_eyes(6) + affected_mob.adjust_eye_blur(6) affected_mob.set_confusion_if_lower(4 SECONDS) affected_mob.adjustStaminaLoss(15) if(prob(5)) diff --git a/code/datums/martial/flying_fang.dm b/code/datums/martial/flying_fang.dm index 95e8eeef2bf2..a50a66ebb534 100644 --- a/code/datums/martial/flying_fang.dm +++ b/code/datums/martial/flying_fang.dm @@ -132,7 +132,7 @@ playsound(D, 'sound/weapons/genhit1.ogg', 50, TRUE, -1) D.apply_damage(disarm_damage, STAMINA, BODY_ZONE_HEAD, armor_block) D.apply_damage(disarm_damage, A.dna.species.attack_type, BODY_ZONE_HEAD, armor_block) - D.blur_eyes(4) + D.adjust_eye_blur(4) if(!istype(D.head, /obj/item/clothing/head/helmet)) D.dna.species.aiminginaccuracy += 25 addtimer(CALLBACK(src, PROC_REF(remove_bonk), D), 10 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) diff --git a/code/datums/status_effects/debuffs/drowsiness.dm b/code/datums/status_effects/debuffs/drowsiness.dm index d2707049a8c2..c719573772e3 100644 --- a/code/datums/status_effects/debuffs/drowsiness.dm +++ b/code/datums/status_effects/debuffs/drowsiness.dm @@ -37,6 +37,6 @@ if(owner.resting && remove_duration(2 * initial(tick_interval))) return - owner.blur_eyes(4 SECONDS) + owner.adjust_eye_blur(4 SECONDS) if(prob(5)) owner.AdjustSleeping(10 SECONDS) diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm index d305e194edb5..35c9764193da 100644 --- a/code/datums/status_effects/debuffs/drunk.dm +++ b/code/datums/status_effects/debuffs/drunk.dm @@ -171,7 +171,7 @@ // Over 71, we will constantly have blurry eyes if(drunk_value >= 71) - owner.blur_eyes(drunk_value * 2 - 140) + owner.adjust_eye_blur(drunk_value * 2 - 140) // Over 81, we will gain constant toxloss if(drunk_value >= 81) diff --git a/code/datums/status_effects/debuffs/screen_blur.dm b/code/datums/status_effects/debuffs/screen_blur.dm new file mode 100644 index 000000000000..abdd07d3cd59 --- /dev/null +++ b/code/datums/status_effects/debuffs/screen_blur.dm @@ -0,0 +1,52 @@ +/// This number is multiplied by the duration remaining (IN SECONDS, NOT DECISECONDS) +/// of the eye blur status effect to determine the intensity of the blur on the user +#define BLUR_DURATION_TO_INTENSITY 0.05 + +/// Applies a blur to the user's screen, increasing in strength depending on duration remaining. +/datum/status_effect/eye_blur + id = "eye_blur" + tick_interval = 1 SECONDS + alert_type = null + remove_on_fullheal = TRUE + +/datum/status_effect/eye_blur/on_creation(mob/living/new_owner, duration = 10 SECONDS) + src.duration = duration + return ..() + +/datum/status_effect/eye_blur/on_apply() + if(owner.mob_biotypes & (MOB_ROBOTIC|MOB_SPIRIT|MOB_SPECIAL)) + return FALSE + + // Refresh the blur when a client jumps into the mob, in case we get put on a clientless mob with no hud + RegisterSignal(owner, COMSIG_MOB_LOGIN, PROC_REF(update_blur)) + // Apply initial blur + update_blur() + return TRUE + +/datum/status_effect/eye_blur/on_remove() + UnregisterSignal(owner, COMSIG_MOB_LOGIN) + if(!owner.hud_used) + return + + var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + game_plane_master_controller.remove_filter("eye_blur") + +/datum/status_effect/eye_blur/tick(seconds_between_ticks) + // Blur lessens the closer we are to expiring, so we update per tick. + update_blur() + +/// Updates the blur of the owner of the status effect. +/// Also a signal proc for [COMSIG_MOB_LOGIN], to trigger then when the mob gets a client. +/datum/status_effect/eye_blur/proc/update_blur(datum/source) + SIGNAL_HANDLER + + if(!owner.hud_used) + return + + var/time_left_in_seconds = (duration - world.time) / (1 SECONDS) + var/amount_of_blur = clamp(time_left_in_seconds * BLUR_DURATION_TO_INTENSITY, 0.6, 3) + + var/atom/movable/plane_master_controller/game_plane_master_controller = owner.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(amount_of_blur)) + +#undef BLUR_DURATION_TO_INTENSITY diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 25ee96acc14a..44ff68c6c5ae 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -1492,13 +1492,7 @@ victim.log_message(message, LOG_ATTACK, color="blue") -/atom/movable/proc/add_filter(name,priority,list/params) - if(!filter_data) - filter_data = list() - var/list/p = params.Copy() - p["priority"] = priority - filter_data[name] = p - update_filters() + /obj/item/update_filters() . = ..() @@ -1506,17 +1500,6 @@ var/datum/action/A = X A.build_all_button_icons() -/// Returns the indice in filters of the given filter name. -/// If it is not found, returns null. -/atom/proc/get_filter_index(name) - return filter_data?.Find(name) - -/atom/movable/proc/remove_filter(name) - if(filter_data && filter_data[name]) - filter_data -= name - update_filters() - - /atom/proc/intercept_zImpact(atom/movable/AM, levels = 1) return FALSE diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 536d61200dcb..4c06dfff4b67 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -289,7 +289,7 @@ if(did_player_win) add_filter("jackpot_rays", 3, ray_filter) animate(get_filter("jackpot_rays"), offset = 10, time = 3 SECONDS, loop = -1) - addtimer(CALLBACK(src, TYPE_PROC_REF(/atom/movable, remove_filter), "jackpot_rays"), 3 SECONDS) + addtimer(CALLBACK(src, TYPE_PROC_REF(/datum, remove_filter), "jackpot_rays"), 3 SECONDS) playsound(src, 'sound/machines/roulettejackpot.ogg', 50, TRUE) /obj/machinery/computer/slot_machine/proc/get_lines() diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index c7137fc51a82..da5e2603479b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -635,10 +635,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES) if (!eyes) return - M.adjust_blurriness(3) + M.adjust_eye_blur(3) eyes.applyOrganDamage(rand(2,4)) if(eyes.damage >= 10) - M.adjust_blurriness(15) + M.adjust_eye_blur(15) if(M.stat != DEAD) to_chat(M, span_danger("Your eyes start to bleed profusely!")) if(!(HAS_TRAIT(M, TRAIT_BLIND) || HAS_TRAIT(M, TRAIT_NEARSIGHT))) @@ -648,7 +648,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(M.stat != DEAD) if(M.drop_all_held_items()) to_chat(M, span_danger("You drop what you're holding and clutch at your eyes!")) - M.adjust_blurriness(10) + M.adjust_eye_blur(10) M.Unconscious(20) M.Paralyze(40) if (prob(eyes.damage - 10 + 1)) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index 3e823857a4d9..443abb3556c8 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -674,7 +674,7 @@ to_chat(target, span_userdanger("[user] sprays [src] into your face!")) if(C.client) - C.blur_eyes(3) + C.adjust_eye_blur(3) C.blind_eyes(1) if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS. C.adjust_confusion(3) diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm index 2d0673457ffa..549342f2173b 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm @@ -285,7 +285,7 @@ owner.current.adjust_jitter(3 SECONDS) // BLOOD_VOLUME_SURVIVE: [122] - Blur Vision if(bloodsucker_blood_volume < BLOOD_VOLUME_SURVIVE(owner.current)) - owner.current.blur_eyes((8 - 8 * (bloodsucker_blood_volume / BLOOD_VOLUME_BAD(owner.current)))* 2 SECONDS) + owner.current.adjust_eye_blur((8 - 8 * (bloodsucker_blood_volume / BLOOD_VOLUME_BAD(owner.current)))* 2 SECONDS) // The more blood, the better the Regeneration, get too low blood, and you enter Frenzy. if(bloodsucker_blood_volume < (FRENZY_THRESHOLD_ENTER + humanity_lost * 10) && !frenzied) diff --git a/code/modules/antagonists/changeling/powers/headcrab.dm b/code/modules/antagonists/changeling/powers/headcrab.dm index 920cad4f34d7..45765c9006be 100644 --- a/code/modules/antagonists/changeling/powers/headcrab.dm +++ b/code/modules/antagonists/changeling/powers/headcrab.dm @@ -31,7 +31,7 @@ if(eyes) to_chat(H, span_userdanger("You are blinded by a shower of blood!")) H.Stun(20) - H.blur_eyes(20) + H.adjust_eye_blur(20) eyes.applyOrganDamage(5) H.adjust_confusion(3 SECONDS) for(var/mob/living/silicon/S in range(2,user)) diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 5631ac7de2f6..0fc3a1fa17c4 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -235,7 +235,7 @@ to_chat(target, span_danger("Your eyes burn horrifically!")) target.become_nearsighted(EYE_DAMAGE) target.blind_eyes(20) - target.blur_eyes(40) + target.adjust_eye_blur(40) return TRUE /datum/action/changeling/sting/LSD diff --git a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm index 7a7febba425b..b2fc01309dae 100644 --- a/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm +++ b/code/modules/antagonists/clockcult/clock_items/wraith_spectacles.dm @@ -53,7 +53,7 @@ to_chat(victim, span_userdanger("Your eyes explode with horrific pain!")) victim.emote("scream") eyes.applyOrganDamage(eyes.maxHealth) - victim.adjust_blurriness(30) + victim.adjust_eye_blur(30) victim.adjust_blindness(30) return TRUE @@ -157,7 +157,7 @@ eyes.applyOrganDamage(0.5) eye_damage_done += 0.5 if(eye_damage_done >= 20) - H.adjust_blurriness(2) + H.adjust_eye_blur(2) if(eye_damage_done >= nearsight_breakpoint) if(!HAS_TRAIT(H, TRAIT_NEARSIGHT)) to_chat(H, span_nzcrentr("Your vision doubles, then trembles. Darkness begins to close in. You can't keep this up!")) diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 4884191cd10c..331b6cb47f54 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -525,6 +525,12 @@ structure_check() searches for nearby cultist structures required for the invoca /obj/effect/rune/narsie/conceal() //can't hide this, and you wouldn't want to return +GLOBAL_VAR_INIT(narsie_effect_last_modified, 0) +GLOBAL_VAR_INIT(narsie_summon_count, 0) +/proc/set_narsie_count(new_count) + GLOB.narsie_summon_count = new_count + SEND_GLOBAL_SIGNAL(COMSIG_NARSIE_SUMMON_UPDATE, GLOB.narsie_summon_count) + /obj/effect/rune/narsie/attack_hand(mob/living/user) if(user.mind?.has_antag_datum(/datum/antagonist/cult/master)) req_cultists -= 4 //leader counts as 5 cultists if they are the invoker diff --git a/code/modules/antagonists/demon/general_powers.dm b/code/modules/antagonists/demon/general_powers.dm index ff8eb520ecd0..050712982846 100644 --- a/code/modules/antagonists/demon/general_powers.dm +++ b/code/modules/antagonists/demon/general_powers.dm @@ -109,7 +109,7 @@ ..() return TRUE playsound(caster, 'sound/magic/demon_attack1.ogg', 75, TRUE) - victim.blur_eyes(15) //huge array of relatively minor effects. + victim.adjust_eye_blur(15) //huge array of relatively minor effects. victim.adjust_jitter(5 SECONDS) victim.set_confusion_if_lower(5 SECONDS) victim.adjust_disgust(40) diff --git a/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm b/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm index a39b68b38f7c..195140c21169 100644 --- a/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm +++ b/code/modules/antagonists/eldritch_cult/knowledge/mind_lore.dm @@ -31,7 +31,7 @@ if(!ishuman(target)) return COMPONENT_BLOCK_HAND_USE var/mob/living/carbon/human/human_target = target - human_target.blur_eyes(1 SECONDS) + human_target.adjust_eye_blur(1 SECONDS) human_target.Knockdown(2 SECONDS) /datum/eldritch_knowledge/spell/eldritchbolt @@ -76,7 +76,7 @@ if(!ishuman(target)) return COMPONENT_BLOCK_HAND_USE var/mob/living/carbon/human/human_target = target - human_target.blur_eyes(2 SECONDS) + human_target.adjust_eye_blur(2 SECONDS) human_target.blind_eyes(1 SECONDS) /datum/eldritch_knowledge/spell/assault diff --git a/code/modules/antagonists/traitor/syndicate_contract.dm b/code/modules/antagonists/traitor/syndicate_contract.dm index 52fed5895983..2025c419f1ad 100644 --- a/code/modules/antagonists/traitor/syndicate_contract.dm +++ b/code/modules/antagonists/traitor/syndicate_contract.dm @@ -163,7 +163,7 @@ M.flash_act() M.adjust_confusion(10 SECONDS) - M.blur_eyes(0.5 SECONDS) + M.adjust_eye_blur(0.5 SECONDS) to_chat(M, span_warning("You feel strange...")) sleep(6 SECONDS) to_chat(M, span_warning("That pod did something to you...")) @@ -172,7 +172,7 @@ to_chat(M, span_warning("Your head pounds... It feels like it's going to burst out your skull!")) M.flash_act() M.adjust_confusion(20 SECONDS) - M.blur_eyes(3) + M.adjust_eye_blur(3) sleep(3 SECONDS) to_chat(M, span_warning("Your head pounds...")) sleep(10 SECONDS) @@ -181,7 +181,7 @@ to_chat(M, "A million voices echo in your head... \"Your mind held many valuable secrets - \ we thank you for providing them. Your value is expended, and you will be ransomed back to your station. We always get paid, \ so it's only a matter of time before we ship you back...\"") - M.blur_eyes(1 SECONDS) + M.adjust_eye_blur(1 SECONDS) M.adjust_dizzy(1.5 SECONDS) M.adjust_confusion(20 SECONDS) @@ -220,7 +220,7 @@ M.forceMove(return_pod) M.flash_act() - M.blur_eyes(30) + M.adjust_eye_blur(30) M.adjust_dizzy(35 SECONDS) M.adjust_confusion(20 SECONDS) diff --git a/code/modules/client/multiz_parallax.dm b/code/modules/client/multiz_parallax.dm new file mode 100644 index 000000000000..f8bfad97bc26 --- /dev/null +++ b/code/modules/client/multiz_parallax.dm @@ -0,0 +1,16 @@ +// /// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. +// /datum/preference/toggle/multiz_parallax +// category = PREFERENCE_CATEGORY_GAME_PREFERENCES +// savefile_key = "multiz_parallax" +// savefile_identifier = PREFERENCE_PLAYER + +// /datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) +// // Update the plane master group's Z transforms. + +// var/datum/hud/my_hud = client.mob?.hud_used +// if(!my_hud) +// return + +// for(var/group_key as anything in my_hud.master_groups) +// var/datum/plane_master_group/group = my_hud.master_groups[group_key] +// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) diff --git a/code/modules/client/preferences/ambient_occlusion.dm b/code/modules/client/preferences/ambient_occlusion.dm index a81efca00bd8..cf8bf28c1e56 100644 --- a/code/modules/client/preferences/ambient_occlusion.dm +++ b/code/modules/client/preferences/ambient_occlusion.dm @@ -5,8 +5,6 @@ savefile_identifier = PREFERENCE_PLAYER /datum/preference/toggle/ambient_occlusion/apply_to_client(client/client, value) - var/atom/movable/screen/plane_master/game_world/plane_master = locate() in client?.screen - if (!plane_master) - return - - plane_master.backdrop(client.mob) + /// Backdrop for the game world plane. + for(var/atom/movable/screen/plane_master/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(GAME_PLANE)) + plane_master.show_to(client.mob) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 2048bf937375..90733df90106 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -59,7 +59,7 @@ to_chat(H, span_danger("[src] overloads and blinds you!")) H.flash_act(visual = 1) H.blind_eyes(3) - H.blur_eyes(5) + H.adjust_eye_blur(5) eyes.applyOrganDamage(5) /obj/item/clothing/glasses/meson diff --git a/code/modules/events/flutes.dm b/code/modules/events/flutes.dm index 10734d1859b7..ac328f006291 100644 --- a/code/modules/events/flutes.dm +++ b/code/modules/events/flutes.dm @@ -57,23 +57,23 @@ /datum/round_event/flutes/proc/flute_vis_flicker(mob/living/carbon/M) to_chat(M, span_warning("Your vision flickers.")) - M.blur_eyes(15) + M.adjust_eye_blur(15) /datum/round_event/flutes/proc/flute_headache(mob/living/carbon/M) to_chat(M, span_warning("You get an intense headache!")) - M.blur_eyes(15) + M.adjust_eye_blur(15) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 20, 30) M.adjustStaminaLoss(15) /datum/round_event/flutes/proc/flute_tremble(mob/living/carbon/M) to_chat(M, span_warning("Something trembles along the edge of your vision, your eyes water, with the familiar beat of blood racing through your head.")) - M.blur_eyes(30) + M.adjust_eye_blur(30) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30, 35) M.adjustStaminaLoss(30) /datum/round_event/flutes/proc/flute_chanting(mob/living/carbon/M) to_chat(M, "You hear faint chanting.. You feel a heavy weight upon your shoulders, as something shifts it's gaze towards you..") - M.blur_eyes(30) + M.adjust_eye_blur(30) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 60) M.adjustStaminaLoss(50) ADD_TRAIT(M, TRAIT_UNSTABLE, M) @@ -82,7 +82,7 @@ /datum/round_event/flutes/proc/flute_starlight(mob/living/carbon/M) to_chat(M, span_warning("As the nearest stars light your skin and your station, you can make out the faint whispers being spoken in turn with the monotone flutes playing beyond you. You feel so tired, as the struts of metal piping, the walls, the floor twist in unnatural ways, as the lights dim.")) sleep(30 SECONDS) - M.blur_eyes(40) + M.adjust_eye_blur(40) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 65, 70, 80) ADD_TRAIT(M, TRAIT_UNSTABLE, M) //sanity = 50 @@ -108,7 +108,7 @@ to_chat(M, span_suicide("Your flesh undulates, and boils off your bones. You were blind, yet now you've seen a glimpse behind the cosmic curtain.")) //sanity = 25 REMOVE_TRAIT(M, TRAIT_UNSTABLE, M) - M.blur_eyes(5) + M.adjust_eye_blur(5) M.adjustStaminaLoss(90) M.adjustBruteLoss(60, 70, 75, 80, 85) M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 65, 70, 75, 80, 90) @@ -120,7 +120,7 @@ ADD_TRAIT(M, TRAIT_UNSTABLE, M) //sanity = 1 M.SetSleeping(30) - M.blur_eyes(40) + M.adjust_eye_blur(40) M.adjustStaminaLoss(99) to_chat(M, span_narsie("Y'HAH HT'HU THRZHZU. UA'KLL GHRT AWN ZUU!")) M.adjustBruteLoss(60, 70, 75, 80, 85) diff --git a/code/modules/food_and_drinks/food/snacks_pie.dm b/code/modules/food_and_drinks/food/snacks_pie.dm index b0b63954b023..31298dfc77ce 100644 --- a/code/modules/food_and_drinks/food/snacks_pie.dm +++ b/code/modules/food_and_drinks/food/snacks_pie.dm @@ -49,7 +49,7 @@ creamoverlay.icon_state = "creampie_human" if(stunning) H.Paralyze(20) //splat! - H.adjust_blurriness(1) + H.adjust_eye_blur(1) H.visible_message(span_warning("[H] is creamed by [src]!"), span_userdanger("You've been creamed by [src]!")) playsound(H, "desceration", 50, TRUE) if(!H.creamed) // one layer at a time @@ -301,4 +301,4 @@ bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 4) list_reagents = list(/datum/reagent/consumable/nutriment = 4, /datum/reagent/consumable/nutriment/vitamin = 4) tastes = list("pie" = 1, "dark chocolate" = 3) - foodtype = GRAIN | SUGAR | CHOCOLATE \ No newline at end of file + foodtype = GRAIN | SUGAR | CHOCOLATE diff --git a/code/modules/hydroponics/grown/nettle.dm b/code/modules/hydroponics/grown/nettle.dm index f94de039f47a..f53b16f47ab1 100644 --- a/code/modules/hydroponics/grown/nettle.dm +++ b/code/modules/hydroponics/grown/nettle.dm @@ -114,4 +114,4 @@ to_chat(M, span_danger("You are blinded by the powerful acid of [src]!")) log_combat(user, M, "attacked", src) - M.adjust_blurriness(force/7) + M.adjust_eye_blur(force/7) diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index 646b2cf26cec..e0ac50704f6b 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -154,7 +154,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ if(C.is_eyes_covered()) C.visible_message(span_danger("[C]'s eye protection blocks the sand!"), span_warning("Your eye protection blocks the sand!")) return - C.adjust_blurriness(6) + C.adjust_eye_blur(6) C.adjustStaminaLoss(15)//the pain from your eyes burning does stamina damage C.adjust_confusion(5 SECONDS) to_chat(C, span_userdanger("\The [src] gets into your eyes! The pain, it burns!")) diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm index 9f4d093d4f67..490124767faf 100644 --- a/code/modules/mob/living/blood.dm +++ b/code/modules/mob/living/blood.dm @@ -68,7 +68,7 @@ if(BLOOD_BAD) adjustOxyLoss(round((BLOOD_VOLUME_NORMAL(src) - blood_volume) * 0.02, 1)) if(prob(5)) - blur_eyes(6) + adjust_eye_blur(6) to_chat(src, span_warning("You feel very [word].")) if(BLOOD_SURVIVE) adjustOxyLoss(5) diff --git a/code/modules/mob/living/brain/status_procs.dm b/code/modules/mob/living/brain/status_procs.dm index 1c5aeb1f47c0..e69de29bb2d1 100644 --- a/code/modules/mob/living/brain/status_procs.dm +++ b/code/modules/mob/living/brain/status_procs.dm @@ -1,25 +0,0 @@ -//Here are the procs used to modify status effects of a mob. -//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness -// eye damage, eye_blind, eye_blurry, druggy, TRAIT_BLIND trait, and TRAIT_NEARSIGHT trait. - -/////////////////////////////////// EYE_BLIND //////////////////////////////////// - -/mob/living/brain/blind_eyes() // no eyes to damage or heal - return - -/mob/living/brain/adjust_blindness() - return - -/mob/living/brain/set_blindness() - return - -/////////////////////////////////// EYE_BLURRY //////////////////////////////////// - -/mob/living/brain/blur_eyes() - return - -/mob/living/brain/adjust_blurriness() - return - -/mob/living/brain/set_blurriness() - return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index b69a40db20dc..861582d06371 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -533,7 +533,7 @@ if(eyes.damage > 10) blind_eyes(damage) - blur_eyes(damage * rand(3, 6)) + adjust_eye_blur(damage * rand(3, 6)) if(eyes.damage > 20) if(prob(eyes.damage - 20)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 990eafe0c222..4ef4c703a43e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -98,7 +98,7 @@ else adjust_blindness(-1) if(eye_blurry) //blurry eyes heal slowly - adjust_blurriness(-1) + adjust_eye_blur(-1) if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 60) SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "brain_damage", /datum/mood_event/brain_damage) diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 571facfad919..6f85af68780b 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -1849,7 +1849,7 @@ GLOBAL_LIST_EMPTY(features_by_species) H.visible_message(span_danger("[H] has been knocked senseless!"), \ span_userdanger("[H] has been knocked senseless!")) H.set_confusion_if_lower(20 SECONDS) - H.adjust_blurriness(10) + H.adjust_eye_blur(10) if(prob(10)) H.gain_trauma(/datum/brain_trauma/mild/concussion) else diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm index 42afcb604854..7b8cba63935e 100644 --- a/code/modules/mob/living/damage_procs.dm +++ b/code/modules/mob/living/damage_procs.dm @@ -99,7 +99,7 @@ if(!HAS_TRAIT(src, TRAIT_RADIMMUNE)&& !(status_flags & GODMODE)) radiation += max(effect * hit_percent, 0) if(EFFECT_EYE_BLUR) - blur_eyes(effect * hit_percent) + adjust_eye_blur(effect * hit_percent) if(EFFECT_PARALYZE) Paralyze(effect * hit_percent) if(EFFECT_IMMOBILIZE) diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm index 8baca92c259c..7a28d1d9a11d 100644 --- a/code/modules/mob/living/life.dm +++ b/code/modules/mob/living/life.dm @@ -121,9 +121,7 @@ eye_blind = max(eye_blind-1,1) if(eye_blurry) //blurry eyes heal slowly eye_blurry = max(eye_blurry-1, 0) - if(client) - update_eye_blur() - + /mob/living/proc/update_damage_hud() return diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index cce17d6775e8..a02f43a97d97 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -606,7 +606,7 @@ set_nutrition(NUTRITION_LEVEL_FED + 50) bodytemperature = BODYTEMP_NORMAL set_blindness(0) - set_blurriness(0) + set_eye_blur(0) cure_nearsighted() cure_blind() @@ -1550,7 +1550,7 @@ GLOBAL_LIST_EMPTY(fire_appearances) if(E) E.setOrganDamage(var_value) if("eye_blurry") - set_blurriness(var_value) + set_eye_blur(var_value) if("maxHealth") updatehealth() if("resize") @@ -1687,3 +1687,15 @@ GLOBAL_LIST_EMPTY(fire_appearances) // if(!resting) // get_up() set_resting(FALSE) + +/mob/living/proc/move_to_error_room() + var/obj/effect/landmark/error/error_landmark = locate(/obj/effect/landmark/error) in GLOB.landmarks_list + if(error_landmark) + forceMove(error_landmark.loc) + else + forceMove(locate(4,4,1)) //Even if the landmark is missing, this should put them in the error room. + //If you're here from seeing this error, I'm sorry. I'm so very sorry. The error landmark should be a sacred object that nobody has any business messing with, and someone did! + //Consider seeing a therapist. + var/ERROR_ERROR_LANDMARK_ERROR = "ERROR-ERROR: ERROR landmark missing!" + log_mapping(ERROR_ERROR_LANDMARK_ERROR) + CRASH(ERROR_ERROR_LANDMARK_ERROR) diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm index 217078bf717a..f76206f6c8fd 100644 --- a/code/modules/mob/living/living_defines.dm +++ b/code/modules/mob/living/living_defines.dm @@ -148,3 +148,5 @@ var/num_hands = 2 ///How many usable hands does this mob currently have. Should only be changed through set_usable_hands() var/usable_hands = 2 + /// What our current gravity state is. Used to avoid duplicate animates and such + var/gravity_state = null diff --git a/code/modules/mob/living/simple_animal/status_procs.dm b/code/modules/mob/living/simple_animal/status_procs.dm deleted file mode 100644 index 62a262f9e605..000000000000 --- a/code/modules/mob/living/simple_animal/status_procs.dm +++ /dev/null @@ -1,25 +0,0 @@ - -/mob/living/simple_animal/blind_eyes() - return - -/mob/living/simple_animal/adjust_blindness() - return - -/mob/living/simple_animal/set_blindness() - return - - - -/mob/living/simple_animal/blur_eyes() - return - -/mob/living/simple_animal/adjust_blurriness() - return - -/mob/living/simple_animal/set_blurriness() - return - - - -/mob/living/simple_animal/become_blind() - return diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index a94f8efeaa0f..d74abe19e4ca 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -71,35 +71,6 @@ clear_alert("blind") clear_fullscreen("blind") -/** - * Make the mobs vision blurry - */ -/mob/proc/blur_eyes(amount) - if(amount>0) - eye_blurry = max(amount, eye_blurry) - update_eye_blur() - -/** - * Adjust the current blurriness of the mobs vision by amount - */ -/mob/proc/adjust_blurriness(amount) - eye_blurry = max(eye_blurry+amount, 0) - update_eye_blur() - -///Set the mobs blurriness of vision to an amount -/mob/proc/set_blurriness(amount) - eye_blurry = max(amount, 0) - update_eye_blur() - -///Apply the blurry overlays to a mobs clients screen -/mob/proc/update_eye_blur() - if(!client) - return - var/atom/movable/screen/plane_master/floor/OT = locate(/atom/movable/screen/plane_master/floor) in client.screen - var/atom/movable/screen/plane_master/game_world/GW = locate(/atom/movable/screen/plane_master/game_world) in client.screen - GW.backdrop(src) - OT.backdrop(src) - ///Adjust the disgust level of a mob /mob/proc/adjust_disgust(amount) return diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm index 84115fc68f1f..1f93cc578d6c 100644 --- a/code/modules/paperwork/paperplane.dm +++ b/code/modules/paperwork/paperplane.dm @@ -46,7 +46,7 @@ var/obj/item/organ/eyes/eyes = user.getorganslot(ORGAN_SLOT_EYES) user.Stun(200) user.visible_message(span_suicide("[user] jams [src] in [user.p_their()] nose. It looks like [user.p_theyre()] trying to commit suicide!")) - user.adjust_blurriness(6) + user.adjust_eye_blur(6) if(eyes) eyes.applyOrganDamage(rand(6,8)) sleep(1 SECONDS) @@ -114,7 +114,7 @@ if(H.is_eyes_covered()) return visible_message(span_danger("\The [src] hits [H] in the eye!")) - H.adjust_blurriness(6) + H.adjust_eye_blur(6) eyes.applyOrganDamage(rand(6,8)) H.Paralyze(40) H.emote("scream") diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm index 58234a8a9001..6c3538abcff4 100644 --- a/code/modules/projectiles/projectile/special/hallucination.dm +++ b/code/modules/projectiles/projectile/special/hallucination.dm @@ -152,7 +152,7 @@ /obj/projectile/hallucination/laser/hal_apply_effect() hal_target.adjustStaminaLoss(20) - hal_target.blur_eyes(2) + hal_target.adjust_eye_blur(2) /obj/projectile/hallucination/taser name = "electrode" diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 207e13497cf6..ccde5791f095 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -2383,7 +2383,7 @@ All effects don't start immediately, but rather get worse over time; the rate is /datum/reagent/consumable/ethanol/inocybeshine/on_mob_life(mob/living/carbon/M) if(prob(10)) M.adjustStaminaLoss(10,0) - M.blur_eyes(3) + M.adjust_eye_blur(3) M.adjust_disgust(1) . = TRUE return ..() diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 2f8cd7d85297..3669ab2062c8 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -59,7 +59,7 @@ glass_desc = "It's just like a carrot but without crunching." /datum/reagent/consumable/carrotjuice/on_mob_life(mob/living/carbon/M) - M.adjust_blurriness(-1) + M.adjust_eye_blur(-1) M.adjust_blindness(-1) switch(current_cycle) if(1 to 20) @@ -1116,4 +1116,4 @@ taste_description = "citrus soda with cucumber" glass_icon_state = "cucumber_lemonade" glass_name = "cucumber lemonade" - glass_desc = "Lemonade, with added cucumber." \ No newline at end of file + glass_desc = "Lemonade, with added cucumber." diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 8e67b9a4c82f..c3b6234f5007 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -317,7 +317,7 @@ else if ( mouth_covered ) // Reduced effects if partially protected if(prob(50)) victim.emote("scream") - victim.blur_eyes(14) + victim.adjust_eye_blur(14) victim.blind_eyes(10) victim.set_confusion_if_lower(10 SECONDS) victim.damageoverlaytemp = 75 @@ -327,7 +327,7 @@ else if ( eyes_covered ) // Eye cover is better than mouth cover if(prob(20)) victim.emote("cough") - victim.blur_eyes(4) + victim.adjust_eye_blur(4) victim.set_confusion_if_lower(5 SECONDS) victim.damageoverlaytemp = 50 M.adjustStaminaLoss(3) @@ -335,7 +335,7 @@ else // Oh dear :D if(prob(60)) victim.emote("scream") - victim.blur_eyes(14) + victim.adjust_eye_blur(14) victim.blind_eyes(10) victim.set_confusion_if_lower(12 SECONDS) victim.damageoverlaytemp = 100 @@ -638,13 +638,13 @@ if(!M.eye_blurry) to_chat(M, "Tears well up in your eyes!") M.blind_eyes(2) - M.blur_eyes(5) + M.adjust_eye_blur(5) return ..() /datum/reagent/consumable/tearjuice/on_mob_life(mob/living/carbon/M) ..() if(M.eye_blurry) //Don't worsen vision if it was otherwise fine - M.blur_eyes(4) + M.adjust_eye_blur(4) if(prob(10)) to_chat(M, "Your eyes sting!") M.blind_eyes(2) @@ -680,7 +680,7 @@ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150) M.adjustToxLoss(3*REM,0) M.adjustStaminaLoss(10*REM,0) - M.blur_eyes(5) + M.adjust_eye_blur(5) . = TRUE ..() @@ -942,3 +942,7 @@ nutriment_factor = 15 * REAGENTS_METABOLISM color = "#D9A066" // rgb: 217, 160, 102 taste_description = "peanuts" + +/// Gets just how much nutrition this reagent is worth for the passed mob +/datum/reagent/consumable/proc/get_nutriment_factor(mob/living/carbon/eater) + return nutriment_factor * REAGENTS_METABOLISM * 2 diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index 24d73f8a1047..fa18ac543c5b 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -46,7 +46,7 @@ M.adjustToxLoss(-5, 0, TRUE) M.remove_status_effect(/datum/status_effect/hallucination) REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT)) - M.set_blurriness(0) + M.set_eye_blur(0) M.set_blindness(0) M.SetKnockdown(0, FALSE) M.SetStun(0, FALSE) @@ -821,15 +821,15 @@ to_chat(M, span_warning("Your vision slowly returns...")) M.cure_blind(EYE_DAMAGE) M.cure_nearsighted(EYE_DAMAGE) - M.blur_eyes(35) + M.adjust_eye_blur(35) else if(HAS_TRAIT_FROM(M, TRAIT_NEARSIGHT, EYE_DAMAGE)) to_chat(M, span_warning("The blackness in your peripheral vision fades.")) M.cure_nearsighted(EYE_DAMAGE) - M.blur_eyes(10) + M.adjust_eye_blur(10) else if(M.eye_blind || M.eye_blurry) M.set_blindness(0) - M.set_blurriness(0) + M.set_eye_blur(0) ..() /datum/reagent/medicine/atropine diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index 7ce23f0c061f..26ed4a61e979 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -305,7 +305,7 @@ /datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/C) C.damageoverlaytemp = 60 C.update_damage_hud() - C.blur_eyes(3) + C.adjust_eye_blur(3) return ..() /datum/reagent/toxin/spore_burning @@ -470,7 +470,7 @@ switch(pick(1, 2, 3, 4)) if(1) to_chat(M, span_danger("You can barely see!")) - M.blur_eyes(3) + M.adjust_eye_blur(3) if(2) M.emote("cough") if(3) diff --git a/code/modules/spells/spell_types/hivemind.dm b/code/modules/spells/spell_types/hivemind.dm index f1fd17b6b7d5..f8222acbeeb2 100644 --- a/code/modules/spells/spell_types/hivemind.dm +++ b/code/modules/spells/spell_types/hivemind.dm @@ -212,7 +212,7 @@ if(!hive.is_carbon_member(target)) power *= 0.5 target.blind_eyes(4*power) - target.blur_eyes(30*power) + target.adjust_eye_blur(30*power) target.minimumDeafTicks(15*power) //equivalent to 30s deafness max target.adjust_jitter(power SECONDS) target.silent += 10*power diff --git a/code/modules/spells/spell_types/pointed/blind.dm b/code/modules/spells/spell_types/pointed/blind.dm index f4c9b9c0958a..ba3bfbd87ba7 100644 --- a/code/modules/spells/spell_types/pointed/blind.dm +++ b/code/modules/spells/spell_types/pointed/blind.dm @@ -39,5 +39,5 @@ to_chat(cast_on, span_warning("Your eyes cry out in pain!")) cast_on.adjust_blindness(eye_blind_duration) - cast_on.blur_eyes(eye_blur_duration) + cast_on.adjust_eye_blur(eye_blur_duration) return TRUE diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm index 9cfb874c4b65..94d02d6901fd 100644 --- a/code/modules/surgery/eye_surgery.dm +++ b/code/modules/surgery/eye_surgery.dm @@ -49,7 +49,7 @@ target.cure_blind(list(EYE_DAMAGE)) target.set_blindness(0) target.cure_nearsighted(list(EYE_DAMAGE)) - target.blur_eyes(35) //this will fix itself slowly. + target.adjust_eye_blur(35) //this will fix itself slowly. E.setOrganDamage(0) return TRUE diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 6c7d7c292465..48188b6399bc 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -348,7 +348,7 @@ if(EMP_HEAVY) owner.set_drugginess(40) owner.adjust_hallucinations(500 SECONDS) - owner.blur_eyes(20) + owner.adjust_eye_blur(20) owner.adjust_dizzy(10 SECONDS) time_on += 10 owner.adjustFireLoss(10) @@ -356,7 +356,7 @@ if(EMP_LIGHT) owner.set_drugginess(20) owner.adjust_hallucinations(200 SECONDS) - owner.blur_eyes(10) + owner.adjust_eye_blur(10) owner.adjust_dizzy(5 SECONDS) time_on += 5 owner.adjustFireLoss(5) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index a043d0794bef..db6dab5339f3 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -55,7 +55,7 @@ HMN.update_body() M.cure_blind(list(EYE_DAMAGE)) // can't be blind from eye damage if there's no eye to be damaged, still blind from not having eyes though M.cure_nearsighted(list(EYE_DAMAGE)) // likewise for nearsightedness - M.set_blurriness(0) // no eyes to blur + M.set_eye_blur(0) // no eyes to blur M.update_tint() M.update_sight() @@ -201,7 +201,7 @@ to_chat(owner, span_danger("your eyes overload and blind you!")) owner.flash_act(override_blindness_check = 1) owner.blind_eyes(5) - owner.blur_eyes(8) + owner.adjust_eye_blur(8) eyes.applyOrganDamage(20 / severity) /obj/item/organ/eyes/robotic/xray diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index b46391ae3c4f..b2572da28bf1 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -63,7 +63,7 @@ H.adjust_dizzy(5 SECONDS) if(H.disgust >= DISGUST_LEVEL_DISGUSTED) if(prob(25)) - H.blur_eyes(3) //We need to add more shit down here + H.adjust_eye_blur(3) //We need to add more shit down here H.adjust_disgust(-0.5 * disgust_metabolism) switch(H.disgust) diff --git a/yogstation.dme b/yogstation.dme index dd062cd59f21..e05d5c5526c2 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -143,6 +143,7 @@ #include "code\__DEFINES\wounds.dm" #include "code\__DEFINES\dcs\flags.dm" #include "code\__DEFINES\dcs\helpers.dm" +#include "code\__DEFINES\dcs\signals\mapping.dm" #include "code\__DEFINES\dcs\signals\signal_species.dm" #include "code\__DEFINES\dcs\signals\signals_action.dm" #include "code\__DEFINES\dcs\signals\signals_area.dm" @@ -313,8 +314,12 @@ #include "code\_onclick\hud\parallax.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" +#include "code\_onclick\hud\plane_master_controller.dm" +#include "code\_onclick\hud\plane_master_group.dm" +#include "code\_onclick\hud\plane_master_subtypes.dm" #include "code\_onclick\hud\radial.dm" #include "code\_onclick\hud\radial_persistent.dm" +#include "code\_onclick\hud\render_plate.dm" #include "code\_onclick\hud\revenanthud.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" @@ -522,6 +527,7 @@ #include "code\datums\components\gunpoint.dm" #include "code\datums\components\heal_react.dm" #include "code\datums\components\heirloom.dm" +#include "code\datums\components\hide_highest_offset.dm" #include "code\datums\components\hot_ice.dm" #include "code\datums\components\ice_walk.dm" #include "code\datums\components\igniter.dm" @@ -773,6 +779,7 @@ #include "code\datums\status_effects\debuffs\jitteriness.dm" #include "code\datums\status_effects\debuffs\knuckleroot.dm" #include "code\datums\status_effects\debuffs\red_eye.dm" +#include "code\datums\status_effects\debuffs\screen_blur.dm" #include "code\datums\status_effects\debuffs\silenced.dm" #include "code\datums\status_effects\debuffs\speech_debuffs.dm" #include "code\datums\traits\_quirk.dm" @@ -2097,6 +2104,7 @@ #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" +#include "code\modules\client\multiz_parallax.dm" #include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_menu.dm" @@ -2879,7 +2887,6 @@ #include "code\modules\mob\living\simple_animal\parrot.dm" #include "code\modules\mob\living\simple_animal\shade.dm" #include "code\modules\mob\living\simple_animal\simple_animal.dm" -#include "code\modules\mob\living\simple_animal\status_procs.dm" #include "code\modules\mob\living\simple_animal\bot\atmosbot.dm" #include "code\modules\mob\living\simple_animal\bot\bot.dm" #include "code\modules\mob\living\simple_animal\bot\cleanbot.dm" diff --git a/yogstation/code/datums/martial/explosive_fist.dm b/yogstation/code/datums/martial/explosive_fist.dm index bd2d3b791f14..2d400f84bbfd 100644 --- a/yogstation/code/datums/martial/explosive_fist.dm +++ b/yogstation/code/datums/martial/explosive_fist.dm @@ -366,7 +366,7 @@ var/armor_block = D.run_armor_check(hed, BOMB) D.apply_damage(A.get_punchdamagehigh() + 3, BURN, BODY_ZONE_HEAD, armor_block) //10 burn (vs bomb armor) D.emote("scream") - D.blur_eyes(4) + D.adjust_eye_blur(4) A.apply_damage(10, BURN, BODY_ZONE_CHEST, 0) //Take some unblockable damage since you're using your inner flame or something diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index 9f12c8ccc5a8..20c405f410d9 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -242,7 +242,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) switch(stage) if(STAGE_HAUNT) if(prob(5)) - H.blur_eyes(1) + H.adjust_eye_blur(1) if(prob(5)) H.playsound_local(src,'yogstation/sound/voice/cluwnelaugh2_reversed.ogg', 1) @@ -421,7 +421,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) H.invisibility = initial(H.invisibility) H.density = initial(H.density) H.anchored = initial(H.anchored) - H.blur_eyes(10) + H.adjust_eye_blur(10) animate(H.client,color = old_color, time = 2 SECONDS) eating = FALSE From 47bf5e5c6c96a3b7aa1e1b9869641d4aac0e3631 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:23:44 -0500 Subject: [PATCH 007/144] yea yea --- code/__DEFINES/misc.dm | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 0ae3833d57f3..6c09f9fd4a86 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -423,8 +423,14 @@ GLOBAL_LIST_INIT(donor_pdas, list(PDA_COLOR_NORMAL, PDA_COLOR_TRANSPARENT, PDA_C // Used by PDA and cartridge code to reduce repetitiveness of spritesheets #define PDAIMG(what) {""} +#define NEGATIVE_GRAVITY -1 + #define STANDARD_GRAVITY 1 //Anything above this is high gravity, anything below no grav #define GRAVITY_DAMAGE_TRESHOLD 3 //Starting with this value gravity will start to damage mobs +/// The scaling factor for high gravity damage. +#define GRAVITY_DAMAGE_SCALING 3.5 +/// The maximum [BRUTE] damage a mob can take from high gravity per second. +#define GRAVITY_DAMAGE_MAXIMUM 4.5 #define CAMERA_NO_GHOSTS 0 #define CAMERA_SEE_GHOSTS_BASIC 1 @@ -482,32 +488,5 @@ GLOBAL_LIST_INIT(donor_pdas, list(PDA_COLOR_NORMAL, PDA_COLOR_TRANSPARENT, PDA_C /// 6 pixels to the right, zero tiles & 5 pixels DOWN. #define ui_sunlight_display "WEST:6,CENTER-0:0" -//singularity defines -/// Singularity is stage 1 (1x1) -#define STAGE_ONE 1 -/// Singularity is stage 2 (3x3) -#define STAGE_TWO 3 -/// Singularity is stage 3 (5x5) -#define STAGE_THREE 5 -/// Singularity is stage 4 (7x7) -#define STAGE_FOUR 7 -/// Singularity is stage 5 (9x9) -#define STAGE_FIVE 9 -/// Singularity is stage 6 (11x11) -#define STAGE_SIX 11 //From supermatter shard -/** - * The point where gravity is negative enough to pull you upwards. - * That means walking checks for a ceiling instead of a floor, and you can fall "upwards" - * - * This should only be possible on multi-z maps because it works like shit on maps that aren't. - */ -#define NEGATIVE_GRAVITY -1 -#define STANDARD_GRAVITY 1 //Anything above this is high gravity, anything below no grav until negative gravity -/// The gravity strength threshold for high gravity damage. -#define GRAVITY_DAMAGE_THRESHOLD 3 -/// The scaling factor for high gravity damage. -#define GRAVITY_DAMAGE_SCALING 0.5 -/// The maximum [BRUTE] damage a mob can take from high gravity per second. -#define GRAVITY_DAMAGE_MAXIMUM 1.5 From 1a6eae0fc7f32c2f88d1271a5109bc4513fb152f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:26:07 -0500 Subject: [PATCH 008/144] ywa ea --- code/__DEFINES/layers.dm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 0c78ecdc9740..feb7c65a2636 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -222,12 +222,6 @@ #define RENDER_PLANE_GAME 100 #define RENDER_PLANE_NON_GAME 101 -///Slightly above the game plane but does not catch mouse clicks. Useful for certain visuals that should be clicked through, like seethrough trees -#define SEETHROUGH_PLANE -3 -#define ABOVE_GAME_PLANE -2 - -#define RENDER_PLANE_GAME_WORLD -1 - #define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it #define AREA_PLANE 2 From ce088701eccd880751886731cd1f32abbc3bec2d Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:27:58 -0500 Subject: [PATCH 009/144] we're gonna have to redo this arent we fuck me --- code/__DEFINES/layers.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index feb7c65a2636..9b6b8ab8b294 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -169,9 +169,6 @@ ///Pipecrawling images #define PIPECRAWL_IMAGES_PLANE 20 -///AI Camera Static -#define CAMERA_STATIC_PLANE 21 - ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else #define HIGH_GAME_PLANE 22 @@ -184,7 +181,6 @@ //HUD layer defines -#define FULLSCREEN_PLANE 20 #define FLASH_LAYER 20 #define FULLSCREEN_LAYER 20.1 #define UI_DAMAGE_LAYER 20.2 From 2878993f312c3eb8b69c184d8cf71c58e38791bd Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:43:05 -0500 Subject: [PATCH 010/144] yea yea --- code/__DEFINES/sight.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 97fc5aed3fb5..7952d9addd21 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -33,7 +33,3 @@ /// Bitfield of sight flags that show THINGS but no lighting /// Since lighting is an underlay on turfs, this is everything but that #define SEE_AVOID_TURF_BLACKNESS (SEE_MOBS|SEE_OBJS) - -#define VISOR_TINT (1<<1) -#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses -#define VISOR_DARKNESSVIEW (1<<3) From 35f76b66ca177bd298ea99420478d2168a0fd6a7 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 09:43:49 -0500 Subject: [PATCH 011/144] this too me idiot --- code/__DEFINES/dcs/signals/signals_mob/signals_living.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm index 468c7e4ad071..9ae610b43222 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_living.dm @@ -38,8 +38,6 @@ #define COMSIG_LIVING_SET_BODY_POSITION "living_set_body_position" ///From post-can inject check of syringe after attack (mob/user) #define COMSIG_LIVING_TRY_SYRINGE "living_try_syringe" -///From living/Life(seconds_per_tick = SSMOBS_DT, times_fired). (deltatime, times_fired) -#define COMSIG_LIVING_LIFE "living_life" ///From living/set_resting(): (new_resting, silent, instant) #define COMSIG_LIVING_RESTING "living_resting" From 9787e1b4eb60a361addd35f1b2e1b27f620d6210 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:41:55 -0500 Subject: [PATCH 012/144] fucks up everything again --- code/__DEFINES/layers.dm | 395 +++++++++++------- code/__DEFINES/traits.dm | 7 + code/_onclick/hud/blob_overmind.dm | 3 +- code/_onclick/hud/credits.dm | 2 +- code/_onclick/hud/devil.dm | 4 +- code/_onclick/hud/fullscreen.dm | 6 +- code/_onclick/hud/radial.dm | 4 +- code/_onclick/hud/robot.dm | 3 +- code/_onclick/hud/screen_objects.dm | 10 - code/_onclick/telekinesis.dm | 1 - code/datums/chatmessage.dm | 9 + code/datums/cinematic.dm | 1 - code/datums/components/storage/storage.dm | 3 - code/datums/mutations/olfaction.dm | 3 +- code/datums/weather/weather.dm | 2 +- code/game/area/areas.dm | 2 +- code/game/machinery/airlock_cycle_control.dm | 2 +- code/game/machinery/navbeacon.dm | 2 +- code/game/objects/effects/countdown.dm | 4 +- code/game/objects/effects/landmarks.dm | 11 +- code/game/objects/effects/misc.dm | 2 +- code/game/objects/effects/overlays.dm | 1 - .../effects/temporary_visuals/clockcult.dm | 2 +- .../temporary_visuals/projectiles/tracer.dm | 1 - code/game/objects/structures/wire_splicing.dm | 2 +- code/game/turfs/openspace/openspace.dm | 20 +- code/game/turfs/turf.dm | 3 + .../clock_effects/general_markers.dm | 2 +- .../antagonists/clockcult/clock_structure.dm | 2 +- .../antagonists/cult/cult_structures.dm | 4 +- .../antagonists/devil/true_devil/inventory.dm | 2 - code/modules/antagonists/revenant/revenant.dm | 2 +- .../components/binary_devices/circulator.dm | 10 +- .../components/unary_devices/vent_pump.dm | 2 - .../components/unary_devices/vent_scrubber.dm | 2 - .../atmospherics/machinery/other/meter.dm | 2 +- code/modules/buildmode/buttons.dm | 3 +- .../clothing/glasses/engine_goggles.dm | 1 - code/modules/flufftext/Hallucination.dm | 1 - code/modules/food_and_drinks/plate.dm | 4 +- code/modules/mapping/mapping_helpers.dm | 2 +- code/modules/mining/ores_coins.dm | 2 +- code/modules/mob/dead/observer/observer.dm | 2 +- code/modules/mob/inventory.dm | 1 - code/modules/mob/living/carbon/inventory.dm | 1 - .../living/silicon/ai/freelook/cameranet.dm | 1 - .../mob/living/silicon/robot/inventory.dm | 1 - .../modules/mob/living/silicon/robot/robot.dm | 1 - .../simple_animal/friendly/drone/inventory.dm | 1 - .../friendly/drone/visuals_icons.dm | 2 - .../simple_animal/hostile/jungle/seedling.dm | 2 +- .../mob/living/simple_animal/simple_animal.dm | 2 - code/modules/mob/living/ventcrawling.dm | 1 - code/modules/point/point.dm | 2 +- code/modules/power/generator.dm | 2 +- code/modules/power/singularity/singularity.dm | 2 +- .../shuttle_creation/shuttle_creator_eye.dm | 2 +- .../spells/spell_types/jaunt/wirecrawl.dm | 2 - code/modules/swarmers/swarmer_objs.dm | 2 +- .../code/datums/status_effects/neutral.dm | 2 - .../guardian/abilities/special/pocket.dm | 2 +- yogstation/code/modules/guardian/guardian.dm | 16 +- .../code/modules/mining/lavaland/bloodbook.dm | 8 +- yogstation/code/modules/spacepods/spacepod.dm | 2 +- 64 files changed, 336 insertions(+), 267 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 9b6b8ab8b294..8bb03d1c38e4 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -4,203 +4,318 @@ //NEVER HAVE ANYTHING BELOW THIS PLANE ADJUST IF YOU NEED MORE SPACE #define LOWEST_EVER_PLANE -100 -#define CLICKCATCHER_PLANE -99 - -#define FIELD_OF_VISION_BLOCKER_PLANE -96 +#define FIELD_OF_VISION_BLOCKER_PLANE -90 #define FIELD_OF_VISION_BLOCKER_RENDER_TARGET "*FIELD_OF_VISION_BLOCKER_RENDER_TARGET" -#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 CLICKCATCHER_PLANE -80 -#define GRAVITY_PULSE_PLANE -89 -#define GRAVITY_PULSE_RENDER_TARGET "*GRAVPULSE_RENDER_TARGET" +#define PLANE_SPACE -25 +#define PLANE_SPACE_PARALLAX -20 -#define SINGULARITY_EFFECT_PLANE -80 +#define SINGULARITY_EFFECT_PLANE -15 #define SINGULARITY_RENDER_TARGET "*SINGULARITY_EFFECTS_PLANE" +#define GRAVITY_PULSE_PLANE -13 +#define GRAVITY_PULSE_RENDER_TARGET "*GRAVPULSE_RENDER_TARGET" + #define RENDER_PLANE_TRANSPARENT -12 //Transparent plane that shows openspace underneath the floor + #define TRANSPARENT_FLOOR_PLANE -11 + #define FLOOR_PLANE -10 -#define FLOOR_PLANE_RENDER_TARGET "FLOOR_PLANE" + #define WALL_PLANE -9 -#define GAME_PLANE_FOV_HIDDEN -8 -#define GAME_PLANE_UPPER -7 -#define GAME_PLANE -6 -#define GAME_PLANE_RENDER_TARGET "GAME_PLANE" +#define GAME_PLANE -8 +#define GAME_PLANE_FOV_HIDDEN -7 +#define GAME_PLANE_UPPER -6 #define WALL_PLANE_UPPER -5 #define GAME_PLANE_UPPER_FOV_HIDDEN -4 + ///Slightly above the game plane but does not catch mouse clicks. Useful for certain visuals that should be clicked through, like seethrough trees #define SEETHROUGH_PLANE -3 #define ABOVE_GAME_PLANE -2 #define RENDER_PLANE_GAME_WORLD -1 -#define BLACKNESS_PLANE 0 //To keep from conflicts with SEE_BLACKNESS internals -#define BLACKNESS_PLANE_RENDER_TARGET "BLACKNESS_PLANE" +#define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it + +#define AREA_PLANE 2 +#define MASSIVE_OBJ_PLANE 3 +#define GHOST_PLANE 4 +#define POINT_PLANE 5 + +//---------- LIGHTING ------------- +///Normal 1 per turf dynamic lighting underlays +#define LIGHTING_PLANE 10 + +///Lighting objects that are "free floating" +#define O_LIGHTING_VISUAL_PLANE 11 +#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" + +#define EMISSIVE_PLANE 13 +/// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas. +#define EMISSIVE_RENDER_PLATE 14 +#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" +// Ensures all the render targets that point at the emissive plate layer correctly +#define EMISSIVE_Z_BELOW_LAYER 1 +#define EMISSIVE_FLOOR_LAYER 2 +#define EMISSIVE_SPACE_LAYER 3 +#define EMISSIVE_WALL_LAYER 4 + +#define RENDER_PLANE_LIGHTING 15 + +/// Masks the lighting plane with turfs, so we never light up the void +/// Failing that, masks emissives and the overlay lighting plane +#define LIGHT_MASK_PLANE 16 +#define LIGHT_MASK_RENDER_TARGET "*LIGHT_MASK_PLANE" + +///Things that should render ignoring lighting +#define ABOVE_LIGHTING_PLANE 17 + +///---------------- MISC ----------------------- + +///Pipecrawling images +#define PIPECRAWL_IMAGES_PLANE 20 + +///AI Camera Static +#define CAMERA_STATIC_PLANE 21 + +///Anything that wants to be part of the game plane, but also wants to draw above literally everything else +#define HIGH_GAME_PLANE 22 + +#define FULLSCREEN_PLANE 23 + +///--------------- FULLSCREEN RUNECHAT BUBBLES ------------ + +///Popup Chat Messages +#define RUNECHAT_PLANE 30 +/// Plane for balloon text (text that fades up) +#define BALLOON_CHAT_PLANE 31 + +//-------------------- HUD --------------------- +//HUD layer defines +#define HUD_PLANE 40 +#define ABOVE_HUD_PLANE 41 + +///Plane of the "splash" icon used that shows on the lobby screen +#define SPLASHSCREEN_PLANE 50 + +// The largest plane here must still be less than RENDER_PLANE_GAME + +//-------------------- Rendering --------------------- +#define RENDER_PLANE_GAME 100 +#define RENDER_PLANE_NON_GAME 101 + +// Only VERY special planes should be here, as they are above not just the game, but the UI planes as well. + +/// Plane related to the menu when pressing Escape. +/// Needed so that we can apply a blur effect to EVERYTHING, and guarantee we are above all UI. +#define ESCAPE_MENU_PLANE 105 + +#define RENDER_PLANE_MASTER 110 + +// Lummox I swear to god I will find you +// NOTE! You can only ever have planes greater then -10000, if you add too many with large offsets you will brick multiz +// Same can be said for large multiz maps. Tread carefully mappers +#define HIGHEST_EVER_PLANE RENDER_PLANE_MASTER +/// The range unique planes can be in +#define PLANE_RANGE (HIGHEST_EVER_PLANE - LOWEST_EVER_PLANE) + +// PLANE_SPACE layer(s) #define SPACE_LAYER 1.8 -//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define + +//#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define. Most floors (FLOOR_PLANE) and walls (WALL_PLANE) use this. + +//FLOOR_PLANE layers +#define TURF_PLATING_DECAL_LAYER 2.001 +#define TURF_DECAL_LAYER 2.009 //Makes turf decals appear in DM how they will look inworld. +#define CULT_OVERLAY_LAYER 2.01 #define MID_TURF_LAYER 2.02 #define HIGH_TURF_LAYER 2.03 -#define TURF_PLATING_DECAL_LAYER 2.031 -#define TURF_DECAL_LAYER 2.039 //Makes turf decals appear in DM how they will look inworld. -#define ABOVE_OPEN_TURF_LAYER 2.04 +#define LATTICE_LAYER 2.04 +#define DISPOSAL_PIPE_LAYER 2.042 +#define WIRE_LAYER 2.044 +#define GLASS_FLOOR_LAYER 2.046 +#define TRAM_RAIL_LAYER 2.047 +#define ABOVE_OPEN_TURF_LAYER 2.049 + +//WALL_PLANE layers #define CLOSED_TURF_LAYER 2.05 + +// GAME_PLANE layers #define BULLET_HOLE_LAYER 2.06 #define ABOVE_NORMAL_TURF_LAYER 2.08 -#define LATTICE_LAYER 2.2 -#define DISPOSAL_PIPE_LAYER 2.25 #define GAS_PIPE_HIDDEN_LAYER 2.35 //layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap -#define WIRE_LAYER 2.4 +#define WIRE_BRIDGE_LAYER 2.44 #define WIRE_TERMINAL_LAYER 2.45 -#define UNDER_CATWALK 2.454 -#define CATWALK_LAYER 2.455 -#define GAS_SCRUBBER_LAYER 2.46 +#define GAS_SCRUBBER_LAYER 2.46 #define GAS_PIPE_VISIBLE_LAYER 2.47 //layer = initial(layer) + piping_layer / 1000 in atmospherics/update_icon() to determine order of pipe overlap #define GAS_FILTER_LAYER 2.48 #define GAS_PUMP_LAYER 2.49 +#define PLUMBING_PIPE_VISIBILE_LAYER 2.495//layer = initial(layer) + ducting_layer / 3333 in atmospherics/handle_layer() to determine order of duct overlap +#define BOT_PATH_LAYER 2.497 #define LOW_OBJ_LAYER 2.5 +///catwalk overlay of /turf/open/floor/plating/catwalk_floor +#define CATWALK_LAYER 2.51 #define LOW_SIGIL_LAYER 2.52 -#define SIGIL_LAYER 2.54 -#define HIGH_SIGIL_LAYER 2.56 +#define SIGIL_LAYER 2.53 +#define HIGH_SIGIL_LAYER 2.54 +#define HIGH_PIPE_LAYER 2.55 +// Anything above this layer is not "on" a turf for the purposes of washing +// I hate this life of ours +#define FLOOR_CLEAN_LAYER 2.56 +#define TRAM_STRUCTURE_LAYER 2.57 +#define TRAM_FLOOR_LAYER 2.58 +#define TRAM_WALL_LAYER 2.59 + #define BELOW_OPEN_DOOR_LAYER 2.6 -#define GAS_METER_LAYER 2.61 +///Anything below this layer is to be considered completely (visually) under water by the immerse layer. +#define WATER_LEVEL_LAYER 2.61 #define BLASTDOOR_LAYER 2.65 #define OPEN_DOOR_LAYER 2.7 -#define DOOR_HELPER_LAYER 2.71 //keep this above OPEN_DOOR_LAYER +#define DOOR_ACCESS_HELPER_LAYER 2.71 //keep this above OPEN_DOOR_LAYER, special layer used for /obj/effect/mapping_helpers/airlock/access +#define DOOR_HELPER_LAYER 2.72 //keep this above DOOR_ACCESS_HELPER_LAYER and OPEN_DOOR_LAYER since the others tend to have tiny sprites that tend to be covered up. #define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible #define TABLE_LAYER 2.8 +#define GATEWAY_UNDERLAY_LAYER 2.85 #define BELOW_OBJ_LAYER 2.9 #define LOW_ITEM_LAYER 2.95 //#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define -#define CLOSED_BLASTDOOR_LAYER 3.05 #define CLOSED_DOOR_LAYER 3.1 #define CLOSED_FIREDOOR_LAYER 3.11 -#define SHUTTER_LAYER 3.12 // HERE BE DRAGONS #define ABOVE_OBJ_LAYER 3.2 +#define CLOSED_BLASTDOOR_LAYER 3.3 // ABOVE WINDOWS AND DOORS +#define SHUTTER_LAYER 3.3 // HERE BE DRAGONS #define ABOVE_WINDOW_LAYER 3.3 #define SIGN_LAYER 3.4 +#define CORGI_ASS_PIN_LAYER 3.41 #define NOT_HIGH_OBJ_LAYER 3.5 #define HIGH_OBJ_LAYER 3.6 - #define BELOW_MOB_LAYER 3.7 + +// GAME_PLANE_FOV_HIDDEN layers +#define LOW_MOB_LAYER 3.75 #define LYING_MOB_LAYER 3.8 -#define SPACEPOD_LAYER 3.9 // yogs +#define VEHICLE_LAYER 3.9 +#define MOB_BELOW_PIGGYBACK_LAYER 3.94 //#define MOB_LAYER 4 //For easy recordkeeping; this is a byond define +#define MOB_SHIELD_LAYER 4.01 +#define MOB_ABOVE_PIGGYBACK_LAYER 4.06 +#define MOB_UPPER_LAYER 4.07 +#define HITSCAN_PROJECTILE_LAYER 4.09 //above all mob but still hidden by FoV + +// GAME_PLANE_UPPER layers #define ABOVE_MOB_LAYER 4.1 #define WALL_OBJ_LAYER 4.25 +#define TRAM_SIGNAL_LAYER 4.26 +// WALL_PLANE_UPPER layers #define EDGED_TURF_LAYER 4.3 #define ON_EDGED_TURF_LAYER 4.35 -#define LARGE_MOB_LAYER 4.4 -#define ABOVE_ALL_MOB_LAYER 4.5 -#define SPACEVINE_LAYER 4.8 -#define SPACEVINE_MOB_LAYER 4.9 +// GAME_PLANE_UPPER_FOV_HIDDEN layers +#define SPACEVINE_LAYER 4.4 +#define LARGE_MOB_LAYER 4.5 +#define SPACEVINE_MOB_LAYER 4.6 + +// Intermediate layer used by both GAME_PLANE_FOV_HIDDEN and ABOVE_GAME_PLANE +#define ABOVE_ALL_MOB_LAYER 4.7 + +// ABOVE_GAME_PLANE layers +#define NAVIGATION_EYE_LAYER 4.9 //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define #define GASFIRE_LAYER 5.05 #define RIPPLE_LAYER 5.1 -#define GHOST_LAYER 6 -#define LOW_LANDMARK_LAYER 9 -#define MID_LANDMARK_LAYER 9.1 -#define HIGH_LANDMARK_LAYER 9.2 -#define AREA_LAYER 10 -#define MASSIVE_OBJ_LAYER 11 -#define POINT_LAYER 12 +/** + * The layer of the visual overlay used in the submerge element. + * The vis overlay inherits the planes of the movables it's attached to (that also have KEEP_TOGETHER added) + * We just have to make sure the visual overlay is rendered above all the other overlays of those movables. + */ +#define WATER_VISUAL_OVERLAY_LAYER 1000 + +//---------- LIGHTING ------------- + +// LIGHTING_PLANE layers +// The layer of turf underlays starts at 0.01 and goes up by 0.01 +// Based off the z level. No I do not remember why, should check that +/// Typically overlays, that "hide" portions of the turf underlay layer +/// I'm allotting 100 z levels before this breaks. That'll never happen +/// --Lemon +#define LIGHTING_MASK_LAYER 10 +/// Misc things that draw on the turf lighting plane +/// Space, solar beams, etc +#define LIGHTING_PRIMARY_LAYER 15 +/// Stuff that needs to draw above everything else on this plane +#define LIGHTING_ABOVE_ALL 20 + + +//---------- EMISSIVES ------------- +//Layering order of these is not particularly meaningful. +//Important part is the seperation of the planes for control via plane_master #define EMISSIVE_BLOCKER_PLANE 12 #define EMISSIVE_BLOCKER_LAYER 12 #define EMISSIVE_BLOCKER_RENDER_TARGET "*EMISSIVE_BLOCKER_PLANE" -#define CHAT_LAYER 12.0001 // Do not insert layers between these two values -#define CHAT_LAYER_MAX 12.9999 +/// The layer you should use if you _really_ don't want an emissive overlay to be blocked. +#define EMISSIVE_LAYER_UNBLOCKABLE 9999 -#define EMISSIVE_PLANE 13 -#define EMISSIVE_LAYER 13 - -/// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas. -#define EMISSIVE_RENDER_PLATE 14 -#define EMISSIVE_RENDER_TARGET "*EMISSIVE_PLANE" - -// Ensures all the render targets that point at the emissive plate layer correctly -#define EMISSIVE_Z_BELOW_LAYER 1 -#define EMISSIVE_FLOOR_LAYER 2 -#define EMISSIVE_SPACE_LAYER 3 -#define EMISSIVE_WALL_LAYER 4 - -#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 RAD_TEXT_LAYER 15.1 - -#define O_LIGHTING_VISUAL_PLANE 16 -#define O_LIGHTING_VISUAL_LAYER 16 -#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" - -#define RENDER_PLANE_LIGHTING 15 -/// Masks the lighting plane with turfs, so we never light up the void -/// Failing that, masks emissives and the overlay lighting plane -#define LIGHT_MASK_PLANE 16 -#define LIGHT_MASK_RENDER_TARGET "*LIGHT_MASK_PLANE" - -#define ABOVE_LIGHTING_PLANE 200 //things that should render ignoring lightning -#define ABOVE_LIGHTING_LAYER 17 -#define ABOVE_LIGHTING_RENDER_TARGET "ABOVE_LIGHTING_PLANE" +///--------------- FULLSCREEN IMAGES ------------ -#define FLOOR_OPENSPACE_PLANE 17 -#define OPENSPACE_LAYER 17 +#define FLASH_LAYER 1 +#define FULLSCREEN_LAYER 2 +#define UI_DAMAGE_LAYER 3 +#define BLIND_LAYER 4 +#define CRIT_LAYER 5 +#define CURSE_LAYER 6 +#define ECHO_LAYER 7 +#define PARRY_LAYER 8 -#define BYOND_LIGHTING_PLANE 18 -#define BYOND_LIGHTING_LAYER 18 -#define BYOND_LIGHTING_RENDER_TARGET "BYOND_LIGHTING_PLANE" +#define FOV_EFFECT_LAYER 100 -#define CAMERA_STATIC_PLANE 19 -#define CAMERA_STATIC_LAYER 19 -#define CAMERA_STATIC_RENDER_TARGET "CAMERA_STATIC_PLANE" +///--------------- FULLSCREEN RUNECHAT BUBBLES ------------ +/// Bubble for typing indicators +#define TYPING_LAYER 500 -///---------------- MISC ----------------------- +#define RADIAL_BACKGROUND_LAYER 0 +///1000 is an unimportant number, it's just to normalize copied layers +#define RADIAL_CONTENT_LAYER 1000 -///Pipecrawling images -#define PIPECRAWL_IMAGES_PLANE 20 +#define ADMIN_POPUP_LAYER 1 -///Anything that wants to be part of the game plane, but also wants to draw above literally everything else -#define HIGH_GAME_PLANE 22 +///Layer for screentips +#define SCREENTIP_LAYER 4 -#define FULLSCREEN_PLANE 23 +/// Layer for tutorial instructions +#define TUTORIAL_INSTRUCTIONS_LAYER 5 +/// Layer for light overlays +#define LIGHT_DEBUG_LAYER 6 -#define RUNECHAT_PLANE 20 +#define LOBBY_BACKGROUND_LAYER 3 +#define LOBBY_BUTTON_LAYER 4 -#define BALLOON_CHAT_PLANE 21 +///Layer for lobby menu collapse button +#define LOBBY_BELOW_MENU_LAYER 2 +///Layer for lobby menu background image and main buttons (Join/Ready, Observe, Charater Prefs) +#define LOBBY_MENU_LAYER 3 +///Layer for lobby menu shutter, which covers up the menu to collapse/expand it +#define LOBBY_SHUTTER_LAYER 4 +///Layer for lobby menu buttons that are hanging away from and lower than the main panel +#define LOBBY_BOTTOM_BUTTON_LAYER 5 -//HUD layer defines +///cinematics are "below" the splash screen +#define CINEMATIC_LAYER -1 -#define FLASH_LAYER 20 -#define FULLSCREEN_LAYER 20.1 -#define UI_DAMAGE_LAYER 20.2 -#define BLIND_LAYER 20.3 -#define CRIT_LAYER 20.4 -#define CURSE_LAYER 20.5 -#define ECHO_LAYER 20.6 -#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" +///Plane master controller keys +#define PLANE_MASTERS_GAME "plane_masters_game" +#define PLANE_MASTERS_NON_MASTER "plane_masters_non_master" +#define PLANE_MASTERS_COLORBLIND "plane_masters_colorblind" +//Plane master critical flags +//Describes how different plane masters behave when they are being culled for performance reasons +/// This plane master will not go away if its layer is culled. useful for preserving effects +#define PLANE_CRITICAL_DISPLAY (1<<0) /// This plane master will temporarially remove relays to all other planes /// Allows us to retain the effects of a plane while cutting off the changes it makes #define PLANE_CRITICAL_NO_RELAY (1<<1) @@ -209,49 +324,9 @@ #define PLANE_CRITICAL_FUCKO_PARALLAX (PLANE_CRITICAL_DISPLAY|PLANE_CRITICAL_NO_RELAY|PLANE_CRITICAL_CUT_RENDER) -//-------------------- Rendering --------------------- -//Plane master critical flags -//Describes how different plane masters behave when they are being culled for performance reasons -/// This plane master will not go away if its layer is culled. useful for preserving effects -#define PLANE_CRITICAL_DISPLAY (1<<0) - -#define RENDER_PLANE_GAME 100 -#define RENDER_PLANE_NON_GAME 101 - -#define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it - -#define AREA_PLANE 2 -#define MASSIVE_OBJ_PLANE 3 -#define GHOST_PLANE 4 -#define POINT_PLANE 5 - -/// Plane related to the menu when pressing Escape. -/// Needed so that we can apply a blur effect to EVERYTHING, and guarantee we are above all UI. -#define ESCAPE_MENU_PLANE 105 - -#define RENDER_PLANE_MASTER 110 - /// A value of /datum/preference/numeric/multiz_performance that disables the option #define MULTIZ_PERFORMANCE_DISABLE -1 /// We expect at most 3 layers of multiz /// Increment this define if you make a huge map. We unit test for it too just to make it easy for you /// If you modify this, you'll need to modify the tsx file too #define MAX_EXPECTED_Z_DEPTH 3 - - -///Plane master controller keys -#define PLANE_MASTERS_GAME "plane_masters_game" -#define PLANE_MASTERS_NON_MASTER "plane_masters_non_master" -#define PLANE_MASTERS_COLORBLIND "plane_masters_colorblind" - - -// Lummox I swear to god I will find you -// NOTE! You can only ever have planes greater then -10000, if you add too many with large offsets you will brick multiz -// Same can be said for large multiz maps. Tread carefully mappers -#define HIGHEST_EVER_PLANE RENDER_PLANE_MASTER -/// The range unique planes can be in -#define PLANE_RANGE (HIGHEST_EVER_PLANE - LOWEST_EVER_PLANE) - - -///1000 is an unimportant number, it's just to normalize copied layers -#define RADIAL_CONTENT_LAYER 1000 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 422b3acda456..61ad2ef71afa 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -503,3 +503,10 @@ #define TRAIT_NO_TRANSFORM "block_transformations" /// Does nothing on its own, applied via status effect. #define TRAIT_STASIS "in_stasis" +/* Traits for ventcrawling. + * Both give access to ventcrawling, but *_NUDE requires the user to be + * wearing no clothes and holding no items. If both present, *_ALWAYS + * takes precedence. + */ +#define TRAIT_VENTCRAWLER_ALWAYS "ventcrawler_always" +#define TRAIT_VENTCRAWLER_NUDE "ventcrawler_nude" diff --git a/code/_onclick/hud/blob_overmind.dm b/code/_onclick/hud/blob_overmind.dm index 8a1c0a940299..d16cd8493823 100644 --- a/code/_onclick/hud/blob_overmind.dm +++ b/code/_onclick/hud/blob_overmind.dm @@ -131,8 +131,7 @@ blobpwrdisplay.icon_state = "block" blobpwrdisplay.screen_loc = ui_health blobpwrdisplay.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - blobpwrdisplay.layer = ABOVE_HUD_LAYER - blobpwrdisplay.plane = ABOVE_HUD_PLANE + SET_PLANE_EXPLICIT(blobpwrdisplay, ABOVE_HUD_PLANE, owner) infodisplay += blobpwrdisplay healths = new /atom/movable/screen/healths/blob(src) diff --git a/code/_onclick/hud/credits.dm b/code/_onclick/hud/credits.dm index 68470eb14c0b..bb48756d3b0a 100644 --- a/code/_onclick/hud/credits.dm +++ b/code/_onclick/hud/credits.dm @@ -34,7 +34,7 @@ GLOBAL_LIST(end_titles) mouse_opacity = MOUSE_OPACITY_TRANSPARENT alpha = 0 screen_loc = "2,2" - layer = SPLASHSCREEN_LAYER + plane = SPLASHSCREEN_PLANE var/matrix/target /atom/movable/screen/credit/Initialize(mapload, credited) diff --git a/code/_onclick/hud/devil.dm b/code/_onclick/hud/devil.dm index 618aa89189f4..ddbcbd5818d9 100644 --- a/code/_onclick/hud/devil.dm +++ b/code/_onclick/hud/devil.dm @@ -24,7 +24,7 @@ using.icon = ui_style using.icon_state = "swap_1_m" using.screen_loc = ui_swaphand_position(owner,1) - using.layer = HUD_LAYER + SET_PLANE_EXPLICIT(using, ABOVE_HUD_PLANE, owner) using.plane = HUD_PLANE static_inventory += using @@ -33,7 +33,7 @@ using.icon = ui_style using.icon_state = "swap_2" using.screen_loc = ui_swaphand_position(owner,2) - using.layer = HUD_LAYER + SET_PLANE_EXPLICIT(using, ABOVE_HUD_PLANE, owner) using.plane = HUD_PLANE static_inventory += using diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 0fe15e009176..44448a99468a 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -173,13 +173,13 @@ screen_loc = "WEST,SOUTH to EAST,NORTH" icon_state = "flash" plane = SPLASHSCREEN_PLANE - layer = SPLASHSCREEN_LAYER - 1 + layer = CINEMATIC_LAYER color = "#000000" show_when_dead = TRUE /atom/movable/screen/fullscreen/cinematic_backdrop/Initialize(mapload) . = ..() - layer = SPLASHSCREEN_LAYER - 1 + layer = CINEMATIC_LAYER /atom/movable/screen/fullscreen/lighting_backdrop icon = 'icons/mob/screen_gen.dmi' @@ -204,7 +204,7 @@ /atom/movable/screen/fullscreen/see_through_darkness icon_state = "nightvision" plane = LIGHTING_PLANE - layer = LIGHTING_LAYER + layer = LIGHTING_ABOVE_ALL blend_mode = BLEND_ADD show_when_dead = TRUE diff --git a/code/_onclick/hud/radial.dm b/code/_onclick/hud/radial.dm index 4b8ca93d56f5..f994cac81afc 100644 --- a/code/_onclick/hud/radial.dm +++ b/code/_onclick/hud/radial.dm @@ -326,8 +326,8 @@ GLOBAL_LIST_EMPTY(radial_menus) return current_user = M.client //Blank - menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = ABOVE_HUD_LAYER) - menu_holder.plane = ABOVE_HUD_PLANE + menu_holder = image(icon='icons/effects/effects.dmi',loc=anchor,icon_state="nothing",layer = RADIAL_BACKGROUND_LAYER) + SET_PLANE_EXPLICIT(menu_holder, ABOVE_HUD_PLANE, M) menu_holder.appearance_flags |= KEEP_APART menu_holder.vis_contents += elements + close_button current_user.images += menu_holder diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm index 37acb22e59e2..271097598806 100644 --- a/code/_onclick/hud/robot.dm +++ b/code/_onclick/hud/robot.dm @@ -224,8 +224,7 @@ A.screen_loc = "CENTER[x]:16,SOUTH+[y]:7" else A.screen_loc = "CENTER+[x]:16,SOUTH+[y]:7" - A.layer = ABOVE_HUD_LAYER - A.plane = ABOVE_HUD_PLANE + SET_PLANE_IMPLICIT(A, ABOVE_HUD_PLANE) x++ if(x == 4) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c6d23ad8b245..b7e32e87acff 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -9,7 +9,6 @@ /atom/movable/screen name = "" icon = 'icons/mob/screen_gen.dmi' - layer = HUD_LAYER plane = HUD_PLANE animate_movement = SLIDE_STEPS speech_span = SPAN_ROBOT @@ -48,7 +47,6 @@ maptext_width = 480 /atom/movable/screen/swap_hand - layer = HUD_LAYER plane = HUD_PLANE name = "swap hand" @@ -156,7 +154,6 @@ var/icon_empty // Icon when empty. For now used only by humans. var/icon_full // Icon when contains an item. For now used only by humans. var/list/object_overlays = list() - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/inventory/Click(location, control, params) @@ -264,7 +261,6 @@ /atom/movable/screen/close name = "close" - layer = ABOVE_HUD_LAYER plane = ABOVE_HUD_PLANE icon_state = "backpack_close" @@ -281,7 +277,6 @@ name = "drop" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_drop" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/drop/Click() @@ -362,7 +357,6 @@ name = "resist" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_resist" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/resist/Click() @@ -374,7 +368,6 @@ name = "rest" icon = 'icons/mob/screen_midnight.dmi' icon_state = "act_rest" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/rest/Click() @@ -393,7 +386,6 @@ name = "storage" icon_state = "block" screen_loc = "7,7 to 10,8" - layer = HUD_LAYER plane = HUD_PLANE /atom/movable/screen/storage/Initialize(mapload, new_master) @@ -474,7 +466,6 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT alpha = 128 anchored = TRUE - layer = ABOVE_HUD_LAYER plane = ABOVE_HUD_PLANE /atom/movable/screen/zone_sel/MouseExited(location, control, params) @@ -657,7 +648,6 @@ icon = 'icons/blanks/blank_title.png' icon_state = "" screen_loc = "1,1" - layer = SPLASHSCREEN_LAYER plane = SPLASHSCREEN_PLANE var/client/holder diff --git a/code/_onclick/telekinesis.dm b/code/_onclick/telekinesis.dm index 26489fe5537f..25fe8a0ac051 100644 --- a/code/_onclick/telekinesis.dm +++ b/code/_onclick/telekinesis.dm @@ -76,7 +76,6 @@ item_flags = NOBLUDGEON | ABSTRACT | DROPDEL //item_state = null w_class = WEIGHT_CLASS_GIGANTIC - layer = ABOVE_HUD_LAYER plane = ABOVE_HUD_PLANE var/atom/movable/focus = null diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 5694bfa0fd08..19197289cc66 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -21,6 +21,15 @@ /// The dimensions of the chat message icons #define CHAT_MESSAGE_ICON_SIZE 9 +///Base layer of chat elements +#define CHAT_LAYER 1 +///Highest possible layer of chat elements +#define CHAT_LAYER_MAX 2 +/// Maximum precision of float before rounding errors occur (in this context) +#define CHAT_LAYER_Z_STEP 0.0001 +/// The number of z-layer 'slices' usable by the chat message layering +#define CHAT_LAYER_MAX_Z (CHAT_LAYER_MAX - CHAT_LAYER) / CHAT_LAYER_Z_STEP + /** * # Chat Message Overlay * diff --git a/code/datums/cinematic.dm b/code/datums/cinematic.dm index 22a76a7c2d0a..29ba4e960219 100644 --- a/code/datums/cinematic.dm +++ b/code/datums/cinematic.dm @@ -23,7 +23,6 @@ icon_state = "station_intact" plane = SPLASHSCREEN_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT - layer = SPLASHSCREEN_LAYER screen_loc = "BOTTOM,LEFT+50%" appearance_flags = APPEARANCE_UI | TILE_BOUND diff --git a/code/datums/components/storage/storage.dm b/code/datums/components/storage/storage.dm index bd557a8bd347..40cc6aa80321 100644 --- a/code/datums/components/storage/storage.dm +++ b/code/datums/components/storage/storage.dm @@ -357,7 +357,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) ND.sample_object.mouse_opacity = MOUSE_OPACITY_OPAQUE ND.sample_object.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" ND.sample_object.maptext = "[(ND.number > 1)? "[ND.number]" : ""]" - ND.sample_object.layer = ABOVE_HUD_LAYER ND.sample_object.plane = ABOVE_HUD_PLANE cx++ if(cx - screen_start_x >= cols) @@ -373,7 +372,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip" O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]" O.maptext = "" - O.layer = ABOVE_HUD_LAYER O.plane = ABOVE_HUD_PLANE cx++ if(cx - screen_start_x >= cols) @@ -439,7 +437,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(QDELETED(O)) continue O.screen_loc = "[cx],[cy]" - O.layer = ABOVE_HUD_LAYER O.plane = ABOVE_HUD_PLANE cx++ if(cx > mx) diff --git a/code/datums/mutations/olfaction.dm b/code/datums/mutations/olfaction.dm index 3b9e3817b073..4bf2b3a0afd7 100644 --- a/code/datums/mutations/olfaction.dm +++ b/code/datums/mutations/olfaction.dm @@ -60,8 +60,7 @@ trail.Flip(dir) trail.Turn(180) - img = image(trail, loc = src, layer = HUD_LAYER) - img.layer = HUD_LAYER + img = image(trail, loc = src) img.plane = HUD_PLANE img.appearance_flags = NO_CLIENT_COLOR img.alpha = 0 diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index 1a8d9800b424..f9c6d963ebba 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -29,7 +29,7 @@ var/impacted_z_levels // The list of z-levels that this weather is actively affecting var/overlay_layer = AREA_LAYER //Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that. - var/overlay_plane = BLACKNESS_PLANE + var/overlay_plane = DEFAULT_PLANE var/aesthetic = FALSE //If the weather has no purpose other than looks var/immunity_type = WEATHER_STORM //Used by mobs to prevent them from being affected by the weather diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index afab00c7f397..1e4f2d754cd6 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -10,7 +10,7 @@ icon_state = "unknown" layer = AREA_LAYER //Keeping this on the default plane, GAME_PLANE, will make area overlays fail to render on FLOOR_PLANE. - plane = BLACKNESS_PLANE + plane = DEFAULT_PLANE mouse_opacity = MOUSE_OPACITY_TRANSPARENT invisibility = INVISIBILITY_LIGHTING diff --git a/code/game/machinery/airlock_cycle_control.dm b/code/game/machinery/airlock_cycle_control.dm index 852ac542b135..3f9c14a28861 100644 --- a/code/game/machinery/airlock_cycle_control.dm +++ b/code/game/machinery/airlock_cycle_control.dm @@ -184,7 +184,7 @@ var/matrix/TR = new TR.Translate(0, 16) TR.Multiply(new /matrix(s_dx, f_dx, 0, s_dy, f_dy, 0)) - var/mutable_appearance/M = mutable_appearance(icon, "hologram-line", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE) + var/mutable_appearance/M = mutable_appearance(icon, "hologram-line", ABOVE_LIGHTING_PLANE) M.transform = TR add_overlay(M) diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index 6e14252d83cd..07fc5c3a3a63 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -8,7 +8,7 @@ name = "navigation beacon" desc = "A radio beacon used for bot navigation." level = 1 // underfloor - layer = UNDER_CATWALK + layer = LOW_OBJ_LAYER max_integrity = 500 armor = list(MELEE = 70, BULLET = 70, LASER = 70, ENERGY = 70, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 80) diff --git a/code/game/objects/effects/countdown.dm b/code/game/objects/effects/countdown.dm index 7f5933b4c125..f9a73eba6e5d 100644 --- a/code/game/objects/effects/countdown.dm +++ b/code/game/objects/effects/countdown.dm @@ -7,7 +7,7 @@ invisibility = INVISIBILITY_OBSERVER anchored = TRUE - layer = GHOST_LAYER + plane = GHOST_PLANE color = "#ff0000" // text color var/text_size = 3 // larger values clip when the displayed text is larger than 2 digits. var/started = FALSE @@ -107,7 +107,7 @@ name = "gateway countdown" text_size = 1 color = "#BE8700" - layer = POINT_LAYER + plane = POINT_PLANE /obj/effect/countdown/clockworkgate/get_value() var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = attached_to diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 12efb829cb06..86c543b3a69d 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -3,7 +3,8 @@ icon = 'icons/effects/landmarks_static.dmi' icon_state = "x2" anchored = TRUE - layer = MID_LANDMARK_LAYER + layer = OBJ_LAYER + plane = GAME_PLANE invisibility = INVISIBILITY_ABSTRACT resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF @@ -415,7 +416,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/event_spawn name = "generic event spawn" icon_state = "generic_event" - layer = HIGH_LANDMARK_LAYER + layer = OBJ_LAYER /obj/effect/landmark/event_spawn/New() ..() @@ -428,7 +429,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/brazil name = "brazilian reception marker" icon_state = "x" - layer = HIGH_LANDMARK_LAYER + layer = OBJ_LAYER /obj/effect/landmark/brazil/New() ..() @@ -465,9 +466,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) /obj/effect/landmark/centcom name = "centcomspawn" icon_state = "x" - layer = HIGH_LANDMARK_LAYER + layer = OBJ_LAYER /obj/effect/landmark/wiki name = "wiki sprite room" icon_state = "x" - layer = HIGH_LANDMARK_LAYER + layer = OBJ_LAYER diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index c7de6a2597cc..9e64edab098d 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -48,7 +48,7 @@ icon = 'icons/effects/alphacolors.dmi' icon_state = "white" plane = LIGHTING_PLANE - layer = LIGHTING_LAYER + layer = LIGHTING_ABOVE_ALL blend_mode = BLEND_ADD /obj/effect/abstract/marker diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index dfd44008cdbb..bff32277a9e5 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -82,7 +82,6 @@ name = "" icon = 'icons/effects/light_overlays/light_32.dmi' icon_state = "light" - layer = O_LIGHTING_VISUAL_LAYER plane = O_LIGHTING_VISUAL_PLANE appearance_flags = RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM mouse_opacity = MOUSE_OPACITY_TRANSPARENT diff --git a/code/game/objects/effects/temporary_visuals/clockcult.dm b/code/game/objects/effects/temporary_visuals/clockcult.dm index 16d10fd03483..dc7e982f8698 100644 --- a/code/game/objects/effects/temporary_visuals/clockcult.dm +++ b/code/game/objects/effects/temporary_visuals/clockcult.dm @@ -262,7 +262,7 @@ icon_state = "eminence" mouse_opacity = MOUSE_OPACITY_TRANSPARENT resistance_flags = INDESTRUCTIBLE - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE duration = 30 SECONDS /obj/effect/temp_visual/ratvar/command_point/Initialize(mapload, appearance) diff --git a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm index 5dc526f1436e..495af7510ec4 100644 --- a/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm +++ b/code/game/objects/effects/temporary_visuals/projectiles/tracer.dm @@ -61,7 +61,6 @@ /obj/effect/projectile/tracer/tracer/aiming icon_state = "pixelbeam_greyscale" - layer = ABOVE_LIGHTING_LAYER plane = ABOVE_LIGHTING_PLANE /obj/effect/projectile/tracer/wormhole diff --git a/code/game/objects/structures/wire_splicing.dm b/code/game/objects/structures/wire_splicing.dm index 63b2b327110e..15770ff8dfac 100644 --- a/code/game/objects/structures/wire_splicing.dm +++ b/code/game/objects/structures/wire_splicing.dm @@ -6,7 +6,7 @@ density = FALSE anchored = TRUE flags_1 = CONDUCT_1 - layer = UNDER_CATWALK + layer = CATWALK_LAYER var/messiness = 0 // How bad the splicing was, determines the chance of shock /obj/structure/wire_splicing/Initialize(mapload) diff --git a/code/game/turfs/openspace/openspace.dm b/code/game/turfs/openspace/openspace.dm index 292707fdebc1..154cccf79383 100644 --- a/code/game/turfs/openspace/openspace.dm +++ b/code/game/turfs/openspace/openspace.dm @@ -16,9 +16,25 @@ /turf/open/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker . = ..() - plane = FLOOR_OPENSPACE_PLANE - layer = OPENSPACE_LAYER + + RegisterSignal(src, COMSIG_ATOM_AFTER_SUCCESSFUL_INITIALIZE, PROC_REF(on_atom_created)) + var/area/our_area = loc + if(istype(our_area, /area/space)) + force_no_gravity = TRUE return INITIALIZE_HINT_LATELOAD +/** + * Drops movables spawned on this turf after they are successfully initialized. + * so that spawned movables that should fall to gravity, will fall. + */ +/turf/open/openspace/proc/on_atom_created(datum/source, atom/created_atom) + SIGNAL_HANDLER + if(ismovable(created_atom)) + zfall_if_on_turf(created_atom) + +/turf/open/openspace/proc/zfall_if_on_turf(atom/movable/movable) + if(QDELETED(movable) || movable.loc != src) + return + zFall(movable) /turf/open/openspace/LateInitialize() update_multiz(TRUE, TRUE) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 57df5c8c6f31..d0aedb4525d9 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -57,6 +57,9 @@ GLOBAL_LIST_EMPTY(station_turfs) ///Lazylist of movable atoms providing opacity sources. var/list/atom/movable/opacity_sources + var/force_no_gravity = FALSE + + /turf/vv_edit_var(var_name, new_value) var/static/list/banned_edits = list("x", "y", "z") if(var_name in banned_edits) diff --git a/code/modules/antagonists/clockcult/clock_effects/general_markers.dm b/code/modules/antagonists/clockcult/clock_effects/general_markers.dm index eda88f27e706..b37f58ddd271 100644 --- a/code/modules/antagonists/clockcult/clock_effects/general_markers.dm +++ b/code/modules/antagonists/clockcult/clock_effects/general_markers.dm @@ -4,7 +4,7 @@ desc = "Some big guy. For you." clockwork_desc = "One of Ratvar's generals." alpha = 200 - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE /obj/effect/clockwork/general_marker/Initialize(mapload) . = ..() diff --git a/code/modules/antagonists/clockcult/clock_structure.dm b/code/modules/antagonists/clockcult/clock_structure.dm index 768d550e5378..b4d71902b183 100644 --- a/code/modules/antagonists/clockcult/clock_structure.dm +++ b/code/modules/antagonists/clockcult/clock_structure.dm @@ -130,7 +130,7 @@ /obj/structure/destructible/clockwork/massive name = "massive construct" desc = "A very large construction." - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE density = FALSE resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF | FREEZE_PROOF diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm index 7727d52ce3ff..716568c4736c 100644 --- a/code/modules/antagonists/cult/cult_structures.dm +++ b/code/modules/antagonists/cult/cult_structures.dm @@ -282,7 +282,7 @@ max_integrity = 200 break_sound = 'sound/effects/meteorimpact.ogg' break_message = span_warning("The pillar crumbles!") - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE var/alt = 0 is_endgame = TRUE @@ -342,7 +342,7 @@ max_integrity = 600 break_sound = 'sound/effects/glassbr2.ogg' break_message = span_warning("The bloodstone resonates violently before crumbling to the floor!") - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE light_color = "#FF0000" var/current_fullness = 0 var/anchor = FALSE //are we the bloodstone used to summon Nar'sie? used in the final part of the summoning diff --git a/code/modules/antagonists/devil/true_devil/inventory.dm b/code/modules/antagonists/devil/true_devil/inventory.dm index a3d0dbdf582b..61b09348b1dc 100644 --- a/code/modules/antagonists/devil/true_devil/inventory.dm +++ b/code/modules/antagonists/devil/true_devil/inventory.dm @@ -17,7 +17,6 @@ hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand @@ -28,7 +27,6 @@ hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index f5eaa26713b7..b5ddf9a469cd 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -21,7 +21,7 @@ invisibility = INVISIBILITY_REVENANT health = INFINITY //Revenants don't use health, they use essence instead maxHealth = INFINITY - layer = GHOST_LAYER + plane = GHOST_PLANE healable = FALSE spacewalk = TRUE sight = SEE_MOBS | SEE_OBJS | SEE_TURFS | SEE_SELF diff --git a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm index 9c9a7203f343..24700606fdae 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/circulator.dm @@ -124,7 +124,7 @@ else if(!last_pressure_delta) set_light(1) - SSvis_overlays.add_vis_overlay(src, icon, "circ-off", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "circ-off", ABOVE_LIGHTING_PLANE, dir) return else if(last_pressure_delta > ONE_ATMOSPHERE) //fast @@ -132,15 +132,15 @@ set_light(3,2,"#4F82FF") else set_light(3,2,"#FF3232") - SSvis_overlays.add_vis_overlay(src, icon, "circ-ex[mode?"cold":"hot"]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) - SSvis_overlays.add_vis_overlay(src, icon, "circ-run", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "circ-ex[mode?"cold":"hot"]", ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "circ-run", ABOVE_LIGHTING_PLANE, dir) else //slow if(mode) set_light(2,1,"#4F82FF") else set_light(2,1,"#FF3232") - SSvis_overlays.add_vis_overlay(src, icon, "circ-[mode?"cold":"hot"]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) - SSvis_overlays.add_vis_overlay(src, icon, "circ-slow", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "circ-[mode?"cold":"hot"]", ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "circ-slow", ABOVE_LIGHTING_PLANE, dir) /obj/machinery/atmospherics/components/binary/circulator/wrench_act(mob/living/user, obj/item/I) if(user.a_intent == INTENT_HARM) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index bc6b484c6dd2..643b0a0f25f8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -316,7 +316,6 @@ user.visible_message("[user] unwelded the vent.", span_notice("You unweld the vent."), span_italics("You hear welding.")) welded = FALSE update_appearance(UPDATE_ICON) - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE investigate_log("was [welded ? "welded shut" : "unwelded"] by [key_name(user)]", INVESTIGATE_ATMOS) add_fingerprint(user) @@ -346,7 +345,6 @@ user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the vent", "You hear loud scraping noises.") welded = FALSE update_appearance(UPDATE_ICON) - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 2729cb4f456a..c9e777161718 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -262,7 +262,6 @@ user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.") welded = FALSE update_appearance(UPDATE_ICON) - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE investigate_log("was [welded ? "welded shut" : "unwelded"] by [key_name(user)]", INVESTIGATE_ATMOS) add_fingerprint(user) @@ -288,7 +287,6 @@ user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.") welded = FALSE update_appearance(UPDATE_ICON) - pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) diff --git a/code/modules/atmospherics/machinery/other/meter.dm b/code/modules/atmospherics/machinery/other/meter.dm index e05e29c009d4..b066398a892a 100644 --- a/code/modules/atmospherics/machinery/other/meter.dm +++ b/code/modules/atmospherics/machinery/other/meter.dm @@ -3,7 +3,7 @@ desc = "It measures something." icon = 'icons/obj/atmospherics/pipes/meter.dmi' icon_state = "meterX" - layer = GAS_METER_LAYER + layer = HIGH_PIPE_LAYER power_channel = AREA_USAGE_ENVIRON use_power = IDLE_POWER_USE idle_power_usage = 2 diff --git a/code/modules/buildmode/buttons.dm b/code/modules/buildmode/buttons.dm index 8468962b9c38..217a583cf147 100644 --- a/code/modules/buildmode/buttons.dm +++ b/code/modules/buildmode/buttons.dm @@ -2,7 +2,8 @@ icon = 'icons/misc/buildmode.dmi' var/datum/buildmode/bd // If we don't do this, we get occluded by item action buttons - layer = ABOVE_HUD_LAYER + plane = ABOVE_HUD_PLANE + /atom/movable/screen/buildmode/New(bld) bd = bld diff --git a/code/modules/clothing/glasses/engine_goggles.dm b/code/modules/clothing/glasses/engine_goggles.dm index e672db3326c8..de0761e3cfea 100644 --- a/code/modules/clothing/glasses/engine_goggles.dm +++ b/code/modules/clothing/glasses/engine_goggles.dm @@ -97,7 +97,6 @@ var/mutable_appearance/MA = new() MA.maptext = span_maptext("[strength]k") MA.color = "#04e604" - MA.layer = RAD_TEXT_LAYER MA.plane = GAME_PLANE pic.appearance = MA flick_overlay(pic, list(user.client), 10) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 8ede48819396..3984c220b126 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -1023,7 +1023,6 @@ GLOBAL_LIST_INIT(hallucination_list, list( slots_free += ui_storage2 if(slots_free.len) target.halitem.screen_loc = pick(slots_free) - target.halitem.layer = ABOVE_HUD_LAYER target.halitem.plane = ABOVE_HUD_PLANE switch(rand(1,6)) if(1) //revolver diff --git a/code/modules/food_and_drinks/plate.dm b/code/modules/food_and_drinks/plate.dm index 693d0727ba54..54fb5f412922 100644 --- a/code/modules/food_and_drinks/plate.dm +++ b/code/modules/food_and_drinks/plate.dm @@ -64,7 +64,7 @@ /obj/item/plate/proc/AddToPlate(obj/item/item_to_plate) vis_contents += item_to_plate item_to_plate.vis_flags |= VIS_INHERIT_PLANE - item_to_plate.layer = ABOVE_HUD_LAYER + item_to_plate.plane = ABOVE_HUD_PLANE RegisterSignal(item_to_plate, COMSIG_MOVABLE_MOVED, PROC_REF(ItemMoved)) RegisterSignal(item_to_plate, COMSIG_PARENT_QDELETING, PROC_REF(ItemMoved)) @@ -188,4 +188,4 @@ . = ..() AddComponent(/datum/component/caltrop, force) -#undef PLATE_SHARD_PIECES \ No newline at end of file +#undef PLATE_SHARD_PIECES diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm index 0858fb4ea0dd..1d065cb064eb 100644 --- a/code/modules/mapping/mapping_helpers.dm +++ b/code/modules/mapping/mapping_helpers.dm @@ -10,7 +10,7 @@ var/list/baseturf_to_replace var/baseturf - layer = POINT_LAYER + plane = POINT_PLANE /obj/effect/baseturf_helper/Initialize(mapload) . = ..() diff --git a/code/modules/mining/ores_coins.dm b/code/modules/mining/ores_coins.dm index e0ac50704f6b..f1e05ac9a6e7 100644 --- a/code/modules/mining/ores_coins.dm +++ b/code/modules/mining/ores_coins.dm @@ -603,7 +603,7 @@ GLOBAL_LIST_INIT(sand_recipes, list(\ flick("coin_[cmineral]_flip", src) icon_state = "coin_[cmineral]_[coinflip]" if(flash) - SSvis_overlays.add_vis_overlay(src, icon, "flash", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, unique = TRUE) + SSvis_overlays.add_vis_overlay(src, icon, "flash", ABOVE_LIGHTING_PLANE, unique = TRUE) playsound(loc, 'sound/items/coinflip.ogg', 50, TRUE) var/oldloc = loc sleep(1.5 SECONDS) diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 6ae0b1d9039b..2a9e8ea0c618 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -8,7 +8,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) desc = "It's a g-g-g-g-ghooooost!" //jinkies! icon = 'icons/mob/mob.dmi' icon_state = "ghost" - layer = GHOST_LAYER + layer = GHOST_PLANE stat = DEAD density = FALSE see_invisible = SEE_INVISIBLE_OBSERVER diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 79ca3f7ade87..92623189667e 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -185,7 +185,6 @@ dropItemToGround(get_item_for_held_index(hand_index), force = TRUE) I.forceMove(src) held_items[hand_index] = I - I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE I.equipped(src, ITEM_SLOT_HANDS, no_sound) if(I.pulledby) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index f56a8d5d5274..21becca2178d 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -70,7 +70,6 @@ if(observe.client) observe.client.screen -= I I.forceMove(src) - I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE I.appearance_flags |= NO_CLIENT_COLOR var/not_handled = FALSE diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index efd4184eee1f..cb0791cd757a 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -165,5 +165,4 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT - layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/robot/inventory.dm b/code/modules/mob/living/silicon/robot/inventory.dm index 90f8eab243b4..2751c0d0dd26 100644 --- a/code/modules/mob/living/silicon/robot/inventory.dm +++ b/code/modules/mob/living/silicon/robot/inventory.dm @@ -81,7 +81,6 @@ held_items[module_num] = item_module item_module.equipped(src, ITEM_SLOT_HANDS) item_module.mouse_opacity = initial(item_module.mouse_opacity) - item_module.layer = ABOVE_HUD_LAYER item_module.plane = ABOVE_HUD_PLANE item_module.cyborg_equip(src) item_module.forceMove(src) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index c5bc9df32716..86ab220b480f 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -127,7 +127,6 @@ robot_modules_background = new() robot_modules_background.icon_state = "block" - robot_modules_background.layer = HUD_LAYER //Objects that appear on screen are on layer ABOVE_HUD_LAYER, UI should be just below it. robot_modules_background.plane = HUD_PLANE ident = rand(1, 999) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm index 1124de738d39..56652f0ea487 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm @@ -66,7 +66,6 @@ I.screen_loc = null // will get moved if inventory is visible I.forceMove(src) - I.layer = ABOVE_HUD_LAYER I.plane = ABOVE_HUD_PLANE switch(slot) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index b6fe86efe0db..9400e17ebc50 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -35,7 +35,6 @@ hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand @@ -48,7 +47,6 @@ hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) - l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand diff --git a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm index 7607ed386e14..09cf499c80b0 100644 --- a/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm +++ b/code/modules/mob/living/simple_animal/hostile/jungle/seedling.dm @@ -57,7 +57,7 @@ name = "beam of solar energy" icon_state = "solar_beam" icon = 'icons/effects/beam.dmi' - layer = LIGHTING_LAYER + plane = LIGHTING_PLANE duration = 5 randomdir = FALSE diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index c4885bec37a1..8d832a895dd1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -546,12 +546,10 @@ var/obj/item/l_hand = get_item_for_held_index(1) var/obj/item/r_hand = get_item_for_held_index(2) if(r_hand) - r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand if(l_hand) - l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 33e5cc3d4d90..4eebe8f0b7e4 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -107,7 +107,6 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. if(in_view_range(client.mob, A)) if(!A.pipe_vision_img) - A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) A.pipe_vision_img.plane = ABOVE_HUD_PLANE client.images += A.pipe_vision_img pipes_shown += A.pipe_vision_img diff --git a/code/modules/point/point.dm b/code/modules/point/point.dm index bda5e2a63407..d28d1811d82f 100644 --- a/code/modules/point/point.dm +++ b/code/modules/point/point.dm @@ -68,7 +68,7 @@ name = "pointer" icon = 'icons/mob/screen_gen.dmi' icon_state = "arrow" - layer = POINT_LAYER + plane = POINT_PLANE duration = POINT_TIME /obj/effect/temp_visual/point/Initialize(mapload, set_invis = 0) diff --git a/code/modules/power/generator.dm b/code/modules/power/generator.dm index 5fdb7e9646cf..789edf8a813b 100644 --- a/code/modules/power/generator.dm +++ b/code/modules/power/generator.dm @@ -56,7 +56,7 @@ var/L = min(round(lastgenlev/100000), 11) if(L != 0) - SSvis_overlays.add_vis_overlay(src, icon, "teg-op[L]", ABOVE_LIGHTING_LAYER, ABOVE_LIGHTING_PLANE, dir) + SSvis_overlays.add_vis_overlay(src, icon, "teg-op[L]", ABOVE_LIGHTING_PLANE, dir) #define GENRATE 800 // generator output coefficient from Q diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 3689d4eb9d73..31633999f379 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -19,7 +19,7 @@ anchored = TRUE density = TRUE move_resist = INFINITY - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE light_range = 6 appearance_flags = LONG_GLIDE var/current_size = 1 diff --git a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm index 23742a544efe..fe5faeee75f4 100644 --- a/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm +++ b/code/modules/shuttle/shuttle_creation/shuttle_creator_eye.dm @@ -51,6 +51,6 @@ if(eye_user?.client) eye_user.client.images -= user_image var/image/I = image(icon, loc, icon_state, FLY_LAYER, dir) - I.plane = MASSIVE_OBJ_LAYER + I.plane = MASSIVE_OBJ_PLANE user_image = I eye_user.client.images += user_image diff --git a/code/modules/spells/spell_types/jaunt/wirecrawl.dm b/code/modules/spells/spell_types/jaunt/wirecrawl.dm index a1829b04dbf6..d05bebe338b7 100644 --- a/code/modules/spells/spell_types/jaunt/wirecrawl.dm +++ b/code/modules/spells/spell_types/jaunt/wirecrawl.dm @@ -221,7 +221,6 @@ if(istype(object, /obj/structure/cable)) var/obj/structure/cable/display = object if(!display.wire_vision_img) - display.wire_vision_img = image(display, display.loc, layer = ABOVE_HUD_LAYER, dir = display.dir) display.wire_vision_img.plane = ABOVE_HUD_PLANE client.images += display.wire_vision_img wires_shown += display.wire_vision_img @@ -229,7 +228,6 @@ else if(istype(object, /obj/machinery/power)) var/obj/machinery/power/display = object if(!display.wire_vision_img) - display.wire_vision_img = image(display, display.loc, layer = ABOVE_HUD_LAYER, dir = display.dir) display.wire_vision_img.plane = ABOVE_HUD_PLANE client.images += display.wire_vision_img wires_shown += display.wire_vision_img diff --git a/code/modules/swarmers/swarmer_objs.dm b/code/modules/swarmers/swarmer_objs.dm index 69cda8ec6278..c5801983b834 100644 --- a/code/modules/swarmers/swarmer_objs.dm +++ b/code/modules/swarmers/swarmer_objs.dm @@ -46,7 +46,7 @@ icon_state = "swarmer_console" armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 100, BOMB = 50, BIO = 100, RAD = 100, FIRE = 100, ACID = 100) max_integrity = 400 - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE light_color = LIGHT_COLOR_CYAN light_range = 10 anchored = TRUE diff --git a/yogstation/code/datums/status_effects/neutral.dm b/yogstation/code/datums/status_effects/neutral.dm index 258cf221dc3c..809cb5ab86c2 100644 --- a/yogstation/code/datums/status_effects/neutral.dm +++ b/yogstation/code/datums/status_effects/neutral.dm @@ -46,7 +46,6 @@ var/icon/temp = icon(sniffee.icon, sniffee.icon_state) var/image/scent_glow = image(temp, layer = ABOVE_MOB_LAYER, loc = sniffee) scent_glow.copy_overlays(sniffee) - scent_glow.layer = HUD_LAYER scent_glow.plane = HUD_PLANE scent_glow.appearance_flags = NO_CLIENT_COLOR scent_glow.color = scent_color @@ -90,7 +89,6 @@ if(!red_thirst) red_thirst = owner.overlay_fullscreen("thirsting", /atom/movable/screen/fullscreen/brute, 4) red_thirst.alpha = 0 - red_thirst.layer = HUD_LAYER red_thirst.plane = HUD_PLANE animate(red_thirst, alpha = 255, time = 1 SECONDS, easing = EASE_IN) //fade IN to_chat(owner, span_userdanger("As the scent of your prey overwhelms your sense of smell, the thrill of the hunt empowers you!")) diff --git a/yogstation/code/modules/guardian/abilities/special/pocket.dm b/yogstation/code/modules/guardian/abilities/special/pocket.dm index 438e87521f7d..e98154ac2949 100644 --- a/yogstation/code/modules/guardian/abilities/special/pocket.dm +++ b/yogstation/code/modules/guardian/abilities/special/pocket.dm @@ -288,7 +288,7 @@ GLOBAL_LIST_EMPTY(pocket_mirrors) G.status_flags &= ~GODMODE /obj/effect/manifestation - layer = ABOVE_LIGHTING_LAYER + plane = ABOVE_LIGHTING_PLANE appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE alpha = 0 mouse_opacity = FALSE diff --git a/yogstation/code/modules/guardian/guardian.dm b/yogstation/code/modules/guardian/guardian.dm index f4f711438dd3..1848f7508bd1 100644 --- a/yogstation/code/modules/guardian/guardian.dm +++ b/yogstation/code/modules/guardian/guardian.dm @@ -112,17 +112,17 @@ GLOBAL_LIST_INIT(guardian_projectile_damage, list( if (sx - range - 1 < 1 || sx + range + 1 > world.maxx || sy - range - 1 < 1 || sy + range + 1 > world.maxy) return for (var/turf/T in getline(locate(sx - range, sy + range + 1, sz), locate(sx + range, sy + range + 1, sz))) - barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_LAYER, SOUTH) + barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_PLANE, SOUTH) for (var/turf/T in getline(locate(sx - range, sy - range - 1, sz), locate(sx + range, sy - range - 1, sz))) - barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_LAYER, NORTH) + barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_PLANE, NORTH) for (var/turf/T in getline(locate(sx - range - 1, sy - range, sz), locate(sx - range - 1, sy + range, sz))) - barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_LAYER, EAST) + barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_PLANE, EAST) for (var/turf/T in getline(locate(sx + range + 1, sy - range, sz), locate(sx + range + 1, sy + range, sz))) - barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_LAYER, WEST) - barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx - range - 1 , sy + range + 1, sz), "barrier", ABOVE_LIGHTING_LAYER, SOUTHEAST) - barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx + range + 1, sy + range + 1, sz), "barrier", ABOVE_LIGHTING_LAYER, SOUTHWEST) - barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx + range + 1, sy - range - 1, sz), "barrier", ABOVE_LIGHTING_LAYER, NORTHWEST) - barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx - range - 1, sy - range - 1, sz), "barrier", ABOVE_LIGHTING_LAYER, NORTHEAST) + barrier_images += image('yogstation/icons/effects/effects.dmi', T, "barrier", ABOVE_LIGHTING_PLANE, WEST) + barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx - range - 1 , sy + range + 1, sz), "barrier", ABOVE_LIGHTING_PLANE, SOUTHEAST) + barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx + range + 1, sy + range + 1, sz), "barrier", ABOVE_LIGHTING_PLANE, SOUTHWEST) + barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx + range + 1, sy - range - 1, sz), "barrier", ABOVE_LIGHTING_PLANE, NORTHWEST) + barrier_images += image('yogstation/icons/effects/effects.dmi', locate(sx - range - 1, sy - range - 1, sz), "barrier", ABOVE_LIGHTING_PLANE, NORTHEAST) for (var/image/I in barrier_images) I.layer = ABOVE_LIGHTING_PLANE I.plane = FLOOR_PLANE diff --git a/yogstation/code/modules/mining/lavaland/bloodbook.dm b/yogstation/code/modules/mining/lavaland/bloodbook.dm index 747c487ddc94..d1a7b56caf97 100644 --- a/yogstation/code/modules/mining/lavaland/bloodbook.dm +++ b/yogstation/code/modules/mining/lavaland/bloodbook.dm @@ -756,7 +756,7 @@ desc = "A blood-red prison." density = FALSE anchored = TRUE - layer = MASSIVE_OBJ_LAYER + plane= MASSIVE_OBJ_PLANE icon = 'icons/obj/projectiles.dmi' icon_state = "leaper" max_integrity = 500 @@ -782,14 +782,14 @@ /obj/structure/prop anchored = TRUE density = FALSE - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE max_integrity = 500 /obj/structure/prop/killrock name = "ruby spire" desc = "An unrelenting claw." anchored = TRUE - layer = MASSIVE_OBJ_LAYER + plane = MASSIVE_OBJ_PLANE icon = 'icons/obj/cult_64x64.dmi' icon_state = "bloodstone-enter1" var/stage = 1 @@ -870,7 +870,7 @@ /obj/structure/slash icon = 'icons/effects/effects.dmi' icon_state = "slash" - layer = POINT_LAYER + plane = POINT_PLANE color = "#ffa600" /obj/structure/slash/Initialize(mapload) diff --git a/yogstation/code/modules/spacepods/spacepod.dm b/yogstation/code/modules/spacepods/spacepod.dm index 73b9bf4e6306..4622fc26379b 100644 --- a/yogstation/code/modules/spacepods/spacepod.dm +++ b/yogstation/code/modules/spacepods/spacepod.dm @@ -14,7 +14,7 @@ GLOBAL_LIST_INIT(spacepods_list, list()) density = 1 opacity = FALSE dir = NORTH // always points north because why not - layer = SPACEPOD_LAYER + layer = VEHICLE_LAYER bound_width = 64 bound_height = 64 animate_movement = NO_STEPS // we do our own gliding here From 3577d656cf1b981287520b371e17fe8af1543087 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:53:51 -0500 Subject: [PATCH 013/144] fix this --- code/datums/chatmessage.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 19197289cc66..67f4f5102aa1 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -25,10 +25,6 @@ #define CHAT_LAYER 1 ///Highest possible layer of chat elements #define CHAT_LAYER_MAX 2 -/// Maximum precision of float before rounding errors occur (in this context) -#define CHAT_LAYER_Z_STEP 0.0001 -/// The number of z-layer 'slices' usable by the chat message layering -#define CHAT_LAYER_MAX_Z (CHAT_LAYER_MAX - CHAT_LAYER) / CHAT_LAYER_Z_STEP /** * # Chat Message Overlay From e1bbb247569730dca9e2c32d8f41c0611bf3817f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:59:22 -0500 Subject: [PATCH 014/144] ye the --- code/modules/awaymissions/super_secret_room.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index f6e18b6ec5b5..7c8af5490bb9 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -4,7 +4,8 @@ verb_say = "intones" icon = 'icons/obj/structures.dmi' icon_state = "speaking_tile" - layer = 5 + layer = FLY_LAYER + plane = ABOVE_GAME_PLANE resistance_flags = INDESTRUCTIBLE var/speaking = FALSE var/times_spoken_to = 0 From 76428ae4600fce4c7ef716fe82cd2328b4b92571 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:55:01 -0500 Subject: [PATCH 015/144] yeah we update these thanks tg --- code/__DEFINES/construction.dm | 18 + code/__DEFINES/dcs/signals/signals_global.dm | 2 + code/__DEFINES/dcs/signals/signals_turf.dm | 2 + code/__DEFINES/flags.dm | 18 + code/__DEFINES/is_helpers.dm | 9 + code/__DEFINES/lighting.dm | 4 + code/__DEFINES/map_switch.dm | 8 + code/__DEFINES/mapping.dm | 6 + code/__DEFINES/movement.dm | 53 +++ code/__DEFINES/multiz.dm | 8 + code/__DEFINES/obj_flags.dm | 5 + code/__DEFINES/space.dm | 5 + code/__DEFINES/traits.dm | 3 + code/__DEFINES/turfs.dm | 7 + code/__HELPERS/lighting.dm | 73 ++++ code/__HELPERS/string_lists.dm | 31 ++ code/_onclick/hud/hud.dm | 272 +++++++++----- code/_onclick/hud/plane_master_group.dm | 136 +++---- code/_onclick/hud/screen_objects.dm | 3 + code/controllers/subsystem/mapping.dm | 7 + code/datums/elements/turf_transparency.dm | 280 +++++++++++++++ code/game/atoms.dm | 3 + code/game/atoms_movable.dm | 179 +++++++++- code/game/objects/effects/effects.dm | 1 + code/game/turfs/baseturfs/baseturfs.dm | 127 +++++++ code/game/turfs/open.dm | 64 ++++ code/game/turfs/simulated/floor/plating.dm | 5 + code/game/turfs/space/space.dm | 335 +++++++++++------- code/game/turfs/turf.dm | 28 +- .../environmental/LINDA_turf_tile.dm | 2 + code/modules/client/client_procs.dm | 9 + .../client/preferences/multiz_parallax.dm | 16 + .../client/preferences/multiz_performance.dm | 21 ++ code/modules/lighting/static_lighting_area.dm | 59 +++ code/modules/mob/mob_movement.dm | 2 +- code/modules/visual/render_step.dm | 92 +++++ yogstation.dme | 12 + yogstation/code/game/turfs/change_turf.dm | 12 +- 38 files changed, 1618 insertions(+), 299 deletions(-) create mode 100644 code/__DEFINES/map_switch.dm create mode 100644 code/__DEFINES/mapping.dm create mode 100644 code/__DEFINES/multiz.dm create mode 100644 code/__DEFINES/space.dm create mode 100644 code/__HELPERS/lighting.dm create mode 100644 code/__HELPERS/string_lists.dm create mode 100644 code/datums/elements/turf_transparency.dm create mode 100644 code/game/turfs/baseturfs/baseturfs.dm create mode 100644 code/modules/client/preferences/multiz_parallax.dm create mode 100644 code/modules/client/preferences/multiz_performance.dm create mode 100644 code/modules/lighting/static_lighting_area.dm create mode 100644 code/modules/visual/render_step.dm diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 8658a984936d..bdaf1343ac68 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -2,6 +2,24 @@ //Defines for construction states +//rcd constants for the design list +/// The mode of operation to design an specific type of rcd design +#define RCD_DESIGN_MODE "rcd_design_mode" + /// For changing turfs + #define RCD_TURF (1 << 0) + /// Full tile windows + #define RCD_WINDOWGRILLE (1 << 1) + /// Windoors & Airlocks + #define RCD_AIRLOCK (1 << 2) + /// Literarly anything that is spawned on top of a turf such as tables, machines etc + #define RCD_STRUCTURE (1 << 3) + /// For wallmounts like air alarms, fire alarms & apc + #define RCD_WALLFRAME (1 << 4) + /// For deconstructing an structure + #define RCD_DECONSTRUCT (1 << 5) +/// The typepath of the structure the rcd is trying to build +#define RCD_DESIGN_PATH "rcd_design_path" + //girder construction states #define GIRDER_NORMAL 0 #define GIRDER_REINF_STRUTS 1 diff --git a/code/__DEFINES/dcs/signals/signals_global.dm b/code/__DEFINES/dcs/signals/signals_global.dm index d70d3e49b02c..1026950b9e5b 100644 --- a/code/__DEFINES/dcs/signals/signals_global.dm +++ b/code/__DEFINES/dcs/signals/signals_global.dm @@ -76,3 +76,5 @@ #define COMSIG_GLOB_REVOLUTION_VICTORY "!revolution_victory" /// Global signal sent when narsie summon count is updated: (new count) #define COMSIG_NARSIE_SUMMON_UPDATE "!narsie_summon_update" +/// Global signal when starlight color is changed (old_star, new_star) +#define COMSIG_STARLIGHT_COLOR_CHANGED "!starlight_color_changed" diff --git a/code/__DEFINES/dcs/signals/signals_turf.dm b/code/__DEFINES/dcs/signals/signals_turf.dm index 08b1a59d7bc0..256f71cc5a94 100644 --- a/code/__DEFINES/dcs/signals/signals_turf.dm +++ b/code/__DEFINES/dcs/signals/signals_turf.dm @@ -14,3 +14,5 @@ #define COMSIG_TURF_PREPARE_STEP_SOUND "turf_prepare_step_sound" ///from base of datum/thrownthing/finalize(): (turf/turf, atom/movable/thrownthing) when something is thrown and lands on us #define COMSIG_TURF_MOVABLE_THROW_LANDED "turf_movable_throw_landed" +///from base of turf/multiz_turf_del(): (turf/source, direction) +#define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del" diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 92c389063f8a..20b0012fbc8d 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -211,3 +211,21 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define IGNORE_SLOWDOWNS (1<<4) #define IGNORE_ALL (IGNORE_USER_LOC_CHANGE|IGNORE_TARGET_LOC_CHANGE|IGNORE_HELD_ITEM|IGNORE_INCAPACITATED|IGNORE_SLOWDOWNS) + +//TURF FLAGS +/// If a turf cant be jaunted through. +#define NOJAUNT (1<<0) +/// If a turf is an usused reservation turf awaiting assignment +#define UNUSED_RESERVATION_TURF (1<<1) +/// If a turf is a reserved turf +#define RESERVATION_TURF (1<<2) +/// Blocks lava rivers being generated on the turf. +#define NO_LAVA_GEN (1<<3) +/// Blocks ruins spawning on the turf. +#define NO_RUINS (1<<4) +/// Blocks this turf from being rusted +#define NO_RUST (1<<5) +/// Is this turf is "solid". Space and lava aren't for instance +#define IS_SOLID (1<<6) +/// This turf will never be cleared away by other objects on Initialize. +#define NO_CLEARING (1<<7) diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index 128866d2f223..1f75466f98bc 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -240,3 +240,12 @@ GLOBAL_LIST_INIT(glass_sheet_types, typecacheof(list( #define isfugitive(M) (istype(M) && M.mind?.has_antag_datum(/datum/antagonist/fugitive)) #define isProbablyWallMounted(O) (O.pixel_x > 20 || O.pixel_x < -20 || O.pixel_y > 20 || O.pixel_y < -20) + +GLOBAL_LIST_INIT(turfs_openspace, typecacheof(list( + /turf/open/openspace, + /turf/open/space/openspace + ))) + +#define istransparentturf(A) (HAS_TRAIT(A, TURF_Z_TRANSPARENT_TRAIT)) + +#define isopenspaceturf(A) (is_type_in_typecache(A, GLOB.turfs_openspace)) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index b1c2408dd2c4..2bfb2d8313bc 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -26,6 +26,10 @@ #define LIGHTING_FALLOFF 1 /// use lambertian shading for light sources #define LIGHTING_LAMBERTIAN 0 +/// light UNDER the floor. primarily used for starlight, shouldn't fuck with this +#define LIGHTING_HEIGHT_SPACE -0.5 +/// light ON the floor +#define LIGHTING_HEIGHT_FLOOR 0 /// height off the ground of light sources on the pseudo-z-axis, you should probably leave this alone #define LIGHTING_HEIGHT 1 /// Value used to round lumcounts, values smaller than 1/129 don't matter (if they do, thanks sinking points), greater values will make lighting less precise, but in turn increase performance, VERY SLIGHTLY. diff --git a/code/__DEFINES/map_switch.dm b/code/__DEFINES/map_switch.dm new file mode 100644 index 000000000000..dbb0059786ee --- /dev/null +++ b/code/__DEFINES/map_switch.dm @@ -0,0 +1,8 @@ +/// Uses the left operator when compiling, uses the right operator when not compiling. +// Currently uses the CBT macro, but if http://www.byond.com/forum/post/2831057 is ever added, +// or if map tools ever agree on a standard, this should switch to use that. +#ifdef CBT +#define MAP_SWITCH(compile_time, map_time) ##compile_time +#else +#define MAP_SWITCH(compile_time, map_time) ##map_time +#endif diff --git a/code/__DEFINES/mapping.dm b/code/__DEFINES/mapping.dm new file mode 100644 index 000000000000..3c08679e2a4b --- /dev/null +++ b/code/__DEFINES/mapping.dm @@ -0,0 +1,6 @@ +// Defines for SSmapping's multiz_levels +/// TRUE if we're ok with going up +#define Z_LEVEL_UP 1 +/// TRUE if we're ok with going down +#define Z_LEVEL_DOWN 2 +#define LARGEST_Z_LEVEL_INDEX Z_LEVEL_DOWN diff --git a/code/__DEFINES/movement.dm b/code/__DEFINES/movement.dm index c26cc24925b4..ecbd6e8fc6d6 100644 --- a/code/__DEFINES/movement.dm +++ b/code/__DEFINES/movement.dm @@ -14,3 +14,56 @@ GLOBAL_VAR_INIT(glide_size_multiplier, 1.0) /// The whole result is then clamped to within the range above. /// Not very readable but it works #define DELAY_TO_GLIDE_SIZE(delay) (clamp(((32 / max((delay) / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE)) + + +/** + * currently_z_moving defines. Higher numbers mean higher priority. + * This one is for falling down open space from stuff such as deleted tile, pit grate... + */ +#define CURRENTLY_Z_FALLING 1 +/// currently_z_moving is set to this in zMove() if 0. +#define CURRENTLY_Z_MOVING_GENERIC 2 +/// This one is for falling down open space from movement. +#define CURRENTLY_Z_FALLING_FROM_MOVE 3 +/// This one is for going upstairs. +#define CURRENTLY_Z_ASCENDING 4 + +/// possible bitflag return values of [atom/proc/intercept_zImpact] calls +/// Stops the movable from falling further and crashing on the ground. Example: stairs. +#define FALL_INTERCEPTED (1<<0) +/// Suppresses the "[movable] falls through [old_turf]" message because it'd make little sense in certain contexts like climbing stairs. +#define FALL_NO_MESSAGE (1<<1) +/// Used when the whole intercept_zImpact forvar loop should be stopped. For example: when someone falls into the supermatter and becomes dust. +#define FALL_STOP_INTERCEPTING (1<<2) +/// Used when the grip on a pulled object shouldn't be broken. +#define FALL_RETAIN_PULL (1<<3) + +/// Runs check_pulling() by the end of [/atom/movable/proc/zMove] for every movable that's pulling something. Should be kept enabled unless you know what you are doing. +#define ZMOVE_CHECK_PULLING (1<<0) +/// Checks if pulledby is nearby. if not, stop being pulled. +#define ZMOVE_CHECK_PULLEDBY (1<<1) +/// flags for different checks done in [/atom/movable/proc/can_z_move]. Should be self-explainatory. +#define ZMOVE_FALL_CHECKS (1<<2) +#define ZMOVE_CAN_FLY_CHECKS (1<<3) +#define ZMOVE_INCAPACITATED_CHECKS (1<<4) +/// Doesn't call zPassIn() and zPassOut() +#define ZMOVE_IGNORE_OBSTACLES (1<<5) +/// Gives players chat feedbacks if they're unable to move through z levels. +#define ZMOVE_FEEDBACK (1<<6) +/// Whether we check the movable (if it exists) the living mob is buckled on or not. +#define ZMOVE_ALLOW_BUCKLED (1<<7) +/// If the movable is actually ventcrawling vertically. +#define ZMOVE_VENTCRAWLING (1<<8) +/// Includes movables that're either pulled by the source or mobs buckled to it in the list of moving movables. +#define ZMOVE_INCLUDE_PULLED (1<<9) +/// Skips check for whether the moving atom is anchored or not. +#define ZMOVE_ALLOW_ANCHORED (1<<10) + +#define ZMOVE_CHECK_PULLS (ZMOVE_CHECK_PULLING|ZMOVE_CHECK_PULLEDBY) + +/// Flags used in "Move Upwards" and "Move Downwards" verbs. +#define ZMOVE_FLIGHT_FLAGS (ZMOVE_CAN_FLY_CHECKS|ZMOVE_INCAPACITATED_CHECKS|ZMOVE_CHECK_PULLS|ZMOVE_ALLOW_BUCKLED) +/// Used when walking upstairs +#define ZMOVE_STAIRS_FLAGS (ZMOVE_CHECK_PULLEDBY|ZMOVE_ALLOW_BUCKLED) +/// Used for falling down open space. +#define ZMOVE_FALL_FLAGS (ZMOVE_FALL_CHECKS|ZMOVE_ALLOW_BUCKLED) diff --git a/code/__DEFINES/multiz.dm b/code/__DEFINES/multiz.dm new file mode 100644 index 000000000000..370eaa8ba459 --- /dev/null +++ b/code/__DEFINES/multiz.dm @@ -0,0 +1,8 @@ +/// Attempt to get the turf below the provided one according to Z traits +#define GET_TURF_BELOW(turf) ( \ + (turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_below(turf) : \ + (!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_DOWN]) ? null : get_step((turf), DOWN)) +/// Attempt to get the turf above the provided one according to Z traits +#define GET_TURF_ABOVE(turf) ( \ + (turf.turf_flags & RESERVATION_TURF) ? SSmapping.get_reservation_from_turf(turf)?.get_turf_above(turf) : \ + (!(turf) || !length(SSmapping.multiz_levels) || !SSmapping.multiz_levels[(turf).z][Z_LEVEL_UP]) ? null : get_step((turf), UP)) diff --git a/code/__DEFINES/obj_flags.dm b/code/__DEFINES/obj_flags.dm index 4c5d348b082c..420a92373891 100644 --- a/code/__DEFINES/obj_flags.dm +++ b/code/__DEFINES/obj_flags.dm @@ -86,3 +86,8 @@ #define ADD_CLOTHING_TRAIT(mob, trait) ADD_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]") /// Wrapper for removing clothing based traits #define REMOVE_CLOTHING_TRAIT(mob, trait) REMOVE_TRAIT(mob, trait, "[CLOTHING_TRAIT]_[REF(src)]") + +#define BLOCK_Z_OUT_DOWN (1<<5) // Should this object block z falling from loc? +#define BLOCK_Z_OUT_UP (1<<6) // Should this object block z uprise from loc? +#define BLOCK_Z_IN_DOWN (1<<7) // Should this object block z falling from above? +#define BLOCK_Z_IN_UP (1<<8) // Should this object block z uprise from below? diff --git a/code/__DEFINES/space.dm b/code/__DEFINES/space.dm new file mode 100644 index 000000000000..eff2aebff3e7 --- /dev/null +++ b/code/__DEFINES/space.dm @@ -0,0 +1,5 @@ +#define SPACE_SIGNAL_GPSTAG "Distant Signal" + +/// Every mob in the game will have a screen object sitting inside them with a reference matching this +/// So you can render_source against it and never need to update it again +#define SPACE_OVERLAY_RENDER_TARGET(offset) "*space_overlay_target[offset]" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 61ad2ef71afa..fbd330ae2e86 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -510,3 +510,6 @@ */ #define TRAIT_VENTCRAWLER_ALWAYS "ventcrawler_always" #define TRAIT_VENTCRAWLER_NUDE "ventcrawler_nude" +#define TRAIT_SPACEWALK "spacewalk" +///Turf trait for when a turf is transparent +#define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent" diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index 549af806ee03..9f54a7fcfbb9 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -10,3 +10,10 @@ #define ALL_TURFS(...) block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)) #define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) + +/// The pipes, disposals, and wires are hidden +#define UNDERFLOOR_HIDDEN 0 +/// The pipes, disposals, and wires are visible but cannot be interacted with +#define UNDERFLOOR_VISIBLE 1 +/// The pipes, disposals, and wires are visible and can be interacted with +#define UNDERFLOOR_INTERACTABLE 2 diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm new file mode 100644 index 000000000000..96087ba17377 --- /dev/null +++ b/code/__HELPERS/lighting.dm @@ -0,0 +1,73 @@ +/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. +/proc/emissive_appearance(icon, icon_state = "", atom/offset_spokesman, layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE, offset_const) + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, 255, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) + if(alpha == 255) + appearance.color = GLOB.emissive_color + else + var/alpha_ratio = alpha/255 + appearance.color = _EMISSIVE_COLOR(alpha_ratio) + + //Test to make sure emissives with broken or missing icon states are created + if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) + if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace + stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") + + return appearance + +// This is a semi hot proc, so we micro it. saves maybe 150ms +// sorry :) +/proc/fast_emissive_blocker(atom/make_blocker) + var/mutable_appearance/blocker = new() + blocker.icon = make_blocker.icon + blocker.icon_state = make_blocker.icon_state + // blocker.layer = FLOAT_LAYER // Implied, FLOAT_LAYER is default for appearances + blocker.appearance_flags |= make_blocker.appearance_flags | EMISSIVE_APPEARANCE_FLAGS + blocker.dir = make_blocker.dir + if(make_blocker.alpha == 255) + blocker.color = GLOB.em_block_color + else + var/alpha_ratio = make_blocker.alpha/255 + blocker.color = _EM_BLOCK_COLOR(alpha_ratio) + + // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be + // Not passing ANYTHING in, key difference + SET_PLANE_EXPLICIT(blocker, EMISSIVE_PLANE, make_blocker) + return blocker + +/// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR]. +/proc/emissive_blocker(icon, icon_state = "", atom/offset_spokesman, layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE, offset_const) + var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) + if(alpha == 255) + appearance.color = GLOB.em_block_color + else + var/alpha_ratio = alpha/255 + appearance.color = _EM_BLOCK_COLOR(alpha_ratio) + return appearance + +/// Takes a non area atom and a threshold +/// Makes it block emissive with any pixels with more alpha then that threshold, with the rest allowing the light to pass +/// Returns a list of objects, automatically added to your vis_contents, that apply this effect +/// QDEL them when appropriate +/proc/partially_block_emissives(atom/make_blocker, alpha_to_leave) + var/static/uid = 0 + uid++ + if(!make_blocker.render_target) + make_blocker.render_target = "partial_emissive_block_[uid]" + + // First, we cut away a constant amount + var/cut_away = (alpha_to_leave - 1) / 255 + var/atom/movable/render_step/color/alpha_threshold_down = new(null, make_blocker, list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,-cut_away)) + alpha_threshold_down.render_target = "*emissive_block_alpha_down_[uid]" + // Then we multiply what remains by the amount we took away + var/atom/movable/render_step/color/alpha_threshold_up = new(null, alpha_threshold_down, list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,alpha_to_leave, 0,0,0,0)) + alpha_threshold_up.render_target = "*emissive_block_alpha_up_[uid]" + // Now we just feed that into an emissive blocker + var/atom/movable/render_step/emissive_blocker/em_block = new(null, alpha_threshold_up) + var/list/hand_back = list() + hand_back += alpha_threshold_down + hand_back += alpha_threshold_up + hand_back += em_block + // Cast to movable so we can use vis_contents. will work for turfs, but not for areas + var/atom/movable/vis_cast = make_blocker + vis_cast.vis_contents += hand_back + return hand_back diff --git a/code/__HELPERS/string_lists.dm b/code/__HELPERS/string_lists.dm new file mode 100644 index 000000000000..99ce28fba1df --- /dev/null +++ b/code/__HELPERS/string_lists.dm @@ -0,0 +1,31 @@ +GLOBAL_LIST_EMPTY(string_lists) + +/** + * Caches lists with non-numeric stringify-able values (text or typepath). + */ +/proc/string_list(list/values) + var/string_id = values.Join("-") + + . = GLOB.string_lists[string_id] + + if(.) + return . + + return GLOB.string_lists[string_id] = values + +///A wrapper for baseturf string lists, to offer support of non list values, and a stack_trace if we have major issues +/proc/baseturfs_string_list(list/values, turf/baseturf_holder) + if(!islist(values)) + return values //baseturf things + // return values + if(length(values) > 10) + stack_trace("The baseturfs list of [baseturf_holder] at [baseturf_holder.x], [baseturf_holder.y], [baseturf_holder.x] is [length(values)], it should never be this long, investigate. I've set baseturfs to a flashing wall as a visual queue") + baseturf_holder.ChangeTurf(/turf/closed/indestructible/baseturfs_ded, list(/turf/closed/indestructible/baseturfs_ded), flags = CHANGETURF_FORCEOP) + return string_list(list(/turf/closed/indestructible/baseturfs_ded)) //I want this reported god damn it + return string_list(values) + +/turf/closed/indestructible/baseturfs_ded + name = "Report this" + desc = "It looks like base turfs went to the fucking moon, TELL YOUR LOCAL CODER TODAY" + icon = 'icons/turf/debug.dmi' + icon_state = "fucked_baseturfs" diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 0cb75cf7d1da..1cf9e183c40e 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -22,10 +22,10 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud var/mob/mymob - var/hud_shown = TRUE //Used for the HUD toggle (F12) - var/hud_version = HUD_STYLE_STANDARD //Current displayed version of the HUD - var/inventory_shown = FALSE //Equipped item inventory - var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) + var/hud_shown = TRUE //Used for the HUD toggle (F12) + var/hud_version = HUD_STYLE_STANDARD //Current displayed version of the HUD + var/inventory_shown = FALSE //Equipped item inventory + var/hotkey_ui_hidden = FALSE //This is to hide the buttons that can be used via hotkeys. (hotkeybuttons list of buttons) var/atom/movable/screen/blobpwrdisplay @@ -33,6 +33,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/atom/movable/screen/alien_queen_finder var/atom/movable/screen/devil/soul_counter/devilsouldisplay + var/atom/movable/screen/combo/combo_display var/atom/movable/screen/action_intent var/atom/movable/screen/zone_select @@ -47,11 +48,37 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/list/infodisplay = list() //the screen objects that display mob info (health, alien plasma, etc...) /// Screen objects that never exit view. var/list/always_visible_inventory = list() - var/list/screenoverlays = list() //the screen objects used as whole screen overlays (flash, damageoverlay, etc...) var/list/inv_slots[SLOTS_AMT] // /atom/movable/screen/inventory objects, ordered by their slot ID. var/list/hand_slots // /atom/movable/screen/inventory/hand objects, assoc list of "[held_index]" = object + + /// Assoc list of key => "plane master groups" + /// This is normally just the main window, but it'll occasionally contain things like spyglasses windows + var/list/datum/plane_master_group/master_groups = list() + ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref + var/list/atom/movable/plane_master_controller/plane_master_controllers = list() var/list/atom/movable/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object + /// Think of multiz as a stack of z levels. Each index in that stack has its own group of plane masters + /// This variable is the plane offset our mob/client is currently "on" + /// We use it to track what we should show/not show + /// Goes from 0 to the max (z level stack size - 1) + var/current_plane_offset = 0 + + ///UI for screentips that appear when you mouse over things + var/atom/movable/screen/screentip/screentip_text + + /// Whether to use text or images for click hints. + /// Same behavior as `screentips_enabled`--very hot, updated when the preference is updated. + var/screentip_images = TRUE + /// If this client is being shown atmos debug overlays or not + var/atmos_debug_overlays = FALSE + + /// The color to use for the screentips. + /// This is updated by the preference for cheaper reads than would be + /// had with a proc call, especially on one of the hottest procs in the + /// game (MouseEntered). + var/screentip_color + var/atom/movable/screen/button_palette/toggle_palette var/atom/movable/screen/palette_scroll/down/palette_down var/atom/movable/screen/palette_scroll/up/palette_up @@ -61,22 +88,17 @@ GLOBAL_LIST_INIT(available_ui_styles, list( var/list/floating_actions var/atom/movable/screen/healths - var/atom/movable/screen/healthdoll var/atom/movable/screen/stamina - /// Think of multiz as a stack of z levels. Each index in that stack has its own group of plane masters - /// This variable is the plane offset our mob/client is currently "on" - /// We use it to track what we should show/not show - /// Goes from 0 to the max (z level stack size - 1) - var/current_plane_offset = 0 - /// Assoc list of key => "plane master groups" - /// This is normally just the main window, but it'll occasionally contain things like spyglasses windows - var/list/datum/plane_master_group/master_groups = list() - ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref - var/list/atom/movable/plane_master_controller/plane_master_controllers = list() - + var/atom/movable/screen/healthdoll + var/atom/movable/screen/spacesuit // subtypes can override this to force a specific UI style var/ui_style + // List of weakrefs to objects that we add to our screen that we don't expect to DO anything + // They typically use * in their render target. They exist solely so we can reuse them, + // and avoid needing to make changes to all idk 300 consumers if we want to change the appearance + var/list/asset_refs_for_reuse = list() + /datum/hud/New(mob/owner) mymob = owner @@ -93,10 +115,88 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() + var/datum/plane_master_group/main/main_group = new(PLANE_GROUP_MAIN) + main_group.attach_to(src) + for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) var/atom/movable/plane_master_controller/controller_instance = new mytype(null,src) plane_master_controllers[controller_instance.name] = controller_instance + owner.overlay_fullscreen("see_through_darkness", /atom/movable/screen/fullscreen/see_through_darkness) + + // Register onto the global spacelight appearances + // So they can be render targeted by anything in the world + for(var/obj/starlight_appearance/starlight as anything in GLOB.starlight_objects) + register_reuse(starlight) + + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_plane_increase)) + RegisterSignal(mymob, COMSIG_MOB_LOGIN, PROC_REF(client_refresh)) + RegisterSignal(mymob, COMSIG_MOB_LOGOUT, PROC_REF(clear_client)) + RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(update_sightflags)) + RegisterSignal(mymob, COMSIG_VIEWDATA_UPDATE, PROC_REF(on_viewdata_update)) + update_sightflags(mymob, mymob.sight, NONE) + +/datum/hud/proc/client_refresh(datum/source) + SIGNAL_HANDLER + RegisterSignal(mymob.canon_client, COMSIG_CLIENT_SET_EYE, PROC_REF(on_eye_change)) + on_eye_change(null, null, mymob.canon_client.eye) + +/datum/hud/proc/clear_client(datum/source) + SIGNAL_HANDLER + if(mymob.canon_client) + UnregisterSignal(mymob.canon_client, COMSIG_CLIENT_SET_EYE) + +/datum/hud/proc/on_viewdata_update(datum/source, view) + SIGNAL_HANDLER + + view_audit_buttons() + +/datum/hud/proc/on_eye_change(datum/source, atom/old_eye, atom/new_eye) + SIGNAL_HANDLER + SEND_SIGNAL(src, COMSIG_HUD_EYE_CHANGED, old_eye, new_eye) + + if(old_eye) + UnregisterSignal(old_eye, COMSIG_MOVABLE_Z_CHANGED) + if(new_eye) + // By the time logout runs, the client's eye has already changed + // There's just no log of the old eye, so we need to override + // :sadkirby: + RegisterSignal(new_eye, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(eye_z_changed), override = TRUE) + eye_z_changed(new_eye) + +/datum/hud/proc/update_sightflags(datum/source, new_sight, old_sight) + SIGNAL_HANDLER + // If neither the old and new flags can see turfs but not objects, don't transform the turfs + // This is to ensure parallax works when you can't see holder objects + if(should_sight_scale(new_sight) == should_sight_scale(old_sight)) + return + + for(var/group_key as anything in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.transform_lower_turfs(src, current_plane_offset) + +/datum/hud/proc/should_use_scale() + return should_sight_scale(mymob.sight) + +/datum/hud/proc/should_sight_scale(sight_flags) + return (sight_flags & (SEE_TURFS | SEE_OBJS)) != SEE_TURFS + +/datum/hud/proc/eye_z_changed(atom/eye) + SIGNAL_HANDLER + update_parallax_pref() // If your eye changes z level, so should your parallax prefs + var/turf/eye_turf = get_turf(eye) + var/new_offset = GET_TURF_PLANE_OFFSET(eye_turf) + if(current_plane_offset == new_offset) + return + var/old_offset = current_plane_offset + current_plane_offset = new_offset + + SEND_SIGNAL(src, COMSIG_HUD_OFFSET_CHANGED, old_offset, new_offset) + if(should_use_scale()) + for(var/group_key as anything in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.transform_lower_turfs(src, new_offset) + /datum/hud/Destroy() if(mymob.hud_used == src) mymob.hud_used = null @@ -111,10 +211,13 @@ GLOBAL_LIST_INIT(available_ui_styles, list( QDEL_NULL(module_store_icon) QDEL_LIST(static_inventory) + // all already deleted by static inventory clear inv_slots.Cut() action_intent = null zone_select = null pull_icon = null + rest_icon = null + hand_slots.Cut() QDEL_LIST(toggleable_inventory) QDEL_LIST(hotkeybuttons) @@ -124,18 +227,53 @@ GLOBAL_LIST_INIT(available_ui_styles, list( healths = null stamina = null healthdoll = null - devilsouldisplay = null + spacesuit = null blobpwrdisplay = null alien_plasma_display = null alien_queen_finder = null - QDEL_LIST_ASSOC_VAL(plane_masters) - QDEL_LIST(screenoverlays) + QDEL_LIST_ASSOC_VAL(master_groups) + QDEL_LIST_ASSOC_VAL(plane_master_controllers) QDEL_LIST(always_visible_inventory) mymob = null + return ..() +/datum/hud/proc/on_plane_increase(datum/source, old_max_offset, new_max_offset) + SIGNAL_HANDLER + for(var/i in old_max_offset + 1 to new_max_offset) + register_reuse(GLOB.starlight_objects[i + 1]) + build_plane_groups(old_max_offset + 1, new_max_offset) + +/// Creates the required plane masters to fill out new z layers (because each "level" of multiz gets its own plane master set) +/datum/hud/proc/build_plane_groups(starting_offset, ending_offset) + for(var/group_key in master_groups) + var/datum/plane_master_group/group = master_groups[group_key] + group.build_plane_masters(starting_offset, ending_offset) + +/// Returns the plane master that matches the input plane from the passed in group +/datum/hud/proc/get_plane_master(plane, group_key = PLANE_GROUP_MAIN) + var/plane_key = "[plane]" + var/datum/plane_master_group/group = master_groups[group_key] + return group.plane_masters[plane_key] + +/// Returns a list of all plane masters that match the input true plane, drawn from the passed in group (ignores z layer offsets) +/datum/hud/proc/get_true_plane_masters(true_plane, group_key = PLANE_GROUP_MAIN) + var/list/atom/movable/screen/plane_master/masters = list() + for(var/plane in TRUE_PLANE_TO_OFFSETS(true_plane)) + masters += get_plane_master(plane, group_key) + return masters + +/// Returns all the planes belonging to the passed in group key +/datum/hud/proc/get_planes_from(group_key) + var/datum/plane_master_group/group = master_groups[group_key] + return group.plane_masters + +/// Returns the corresponding plane group datum if one exists +/datum/hud/proc/get_plane_group(key) + return master_groups[key] + /mob/proc/create_mob_hud() if(!client || hud_used) return @@ -163,7 +301,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( // This code is the absolute fucking worst, I want it to go die in a fire // Seriously, why - screenmob.client.screen = list() + screenmob.client.clear_screen() screenmob.client.apply_clickcatcher() var/display_hud_version = version @@ -234,6 +372,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( reorganize_alerts(screenmob) screenmob.reload_fullscreen() update_parallax_pref(screenmob) + update_reuse(screenmob) // ensure observers get an accurate and up-to-date view if (!viewmob) @@ -278,13 +417,29 @@ GLOBAL_LIST_INIT(available_ui_styles, list( if (initial(ui_style) || ui_style == new_ui_style) return - for(var/atom/item in static_inventory + toggleable_inventory + hotkeybuttons + infodisplay + screenoverlays + always_visible_inventory + inv_slots) + for(var/atom/item in static_inventory + toggleable_inventory + hotkeybuttons + infodisplay + always_visible_inventory + inv_slots) if (item.icon == ui_style) item.icon = new_ui_style ui_style = new_ui_style build_hand_slots() +/datum/hud/proc/register_reuse(atom/movable/screen/reuse) + asset_refs_for_reuse += WEAKREF(reuse) + mymob?.client?.screen += reuse + +/datum/hud/proc/unregister_reuse(atom/movable/screen/reuse) + asset_refs_for_reuse -= WEAKREF(reuse) + mymob?.client?.screen -= reuse + +/datum/hud/proc/update_reuse(mob/show_to) + for(var/datum/weakref/screen_ref as anything in asset_refs_for_reuse) + var/atom/movable/screen/reuse = screen_ref.resolve() + if(isnull(reuse)) + asset_refs_for_reuse -= screen_ref + continue + show_to.client?.screen += reuse + //Triggered when F12 is pressed (Unless someone changed something in the DMF) /mob/verb/button_pressed_F12() set name = "F12" @@ -292,9 +447,9 @@ GLOBAL_LIST_INIT(available_ui_styles, list( if(hud_used && client) hud_used.show_hud() //Shows the next hud preset - to_chat(usr, "Switched HUD mode. Press F12 to toggle.") + to_chat(usr, span_info("Switched HUD mode. Press F12 to toggle.")) else - to_chat(usr, "This mob type does not use a HUD.") + to_chat(usr, span_warning("This mob type does not use a HUD.")) //(re)builds the hand ui slots, throwing away old ones @@ -308,7 +463,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() var/atom/movable/screen/inventory/hand/hand_box for(var/i in 1 to mymob.held_items.len) - hand_box = new /atom/movable/screen/inventory/hand(src) + hand_box = new /atom/movable/screen/inventory/hand(null, src) hand_box.name = mymob.get_held_index_name(i) hand_box.icon = ui_style hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" @@ -316,7 +471,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_box.held_index = i hand_slots["[i]"] = hand_box static_inventory += hand_box - hand_box.update_appearance(UPDATE_ICON) + hand_box.update_appearance() var/i = 1 for(var/atom/movable/screen/swap_hand/SH in static_inventory) @@ -331,7 +486,6 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/hud/proc/update_locked_slots() return - /datum/hud/proc/position_action(atom/movable/screen/movable/action_button/button, position) // This is kinda a hack, I'm sorry. // Basically, FLOATING is never a valid position to pass into this proc. It exists as a generic marker for manually positioned buttons @@ -369,7 +523,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( palette_actions.insert_action(button, palette_actions.index_of(relative_to)) if(SCRN_OBJ_FLOATING) // If we don't have it as a define, this is a screen_loc, and we should be floating floating_actions += button - var/client/our_client = mymob.client + var/client/our_client = mymob.canon_client if(!our_client) position_action(button, button.linked_action.default_button_position) return @@ -410,7 +564,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /// Ensures all of our buttons are properly within the bounds of our client's view, moves them if they're not /datum/hud/proc/view_audit_buttons() - var/our_view = mymob?.client?.view + var/our_view = mymob?.canon_client?.view if(!our_view) return listed_actions.check_against_view() @@ -526,7 +680,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( return "WEST[coord_col]:[coord_col_offset],NORTH[coord_row]:-[pixel_north_offset]" /datum/action_group/proc/check_against_view() - var/owner_view = owner?.mymob?.client?.view + var/owner_view = owner?.mymob?.canon_client?.view if(!owner_view) return // Unlikey as it is, we may have been changed. Want to start from our target position and fail down @@ -642,61 +796,3 @@ GLOBAL_LIST_INIT(available_ui_styles, list( /datum/action_group/listed/refresh_actions() . = ..() owner.palette_actions.refresh_actions() // We effect them, so we gotta refresh em - -/datum/hud/proc/should_use_scale() - return should_sight_scale(mymob.sight) - -/datum/hud/proc/should_sight_scale(sight_flags) - return (sight_flags & (SEE_TURFS | SEE_OBJS)) != SEE_TURFS - -/datum/hud/proc/eye_z_changed(atom/eye) - SIGNAL_HANDLER - update_parallax_pref() // If your eye changes z level, so should your parallax prefs - var/turf/eye_turf = get_turf(eye) - var/new_offset = GET_TURF_PLANE_OFFSET(eye_turf) - if(current_plane_offset == new_offset) - return - var/old_offset = current_plane_offset - current_plane_offset = new_offset - - SEND_SIGNAL(src, COMSIG_HUD_OFFSET_CHANGED, old_offset, new_offset) - // if(should_use_scale()) - // for(var/group_key as anything in master_groups) - // var/datum/plane_master_group/group = master_groups[group_key] - // group.transform_lower_turfs(src, new_offset) - -/// Returns the plane master that matches the input plane from the passed in group -/datum/hud/proc/get_plane_master(plane, group_key = PLANE_GROUP_MAIN) - var/plane_key = "[plane]" - var/datum/plane_master_group/group = master_groups[group_key] - return group.plane_masters[plane_key] - -/// Returns a list of all plane masters that match the input true plane, drawn from the passed in group (ignores z layer offsets) -/datum/hud/proc/get_true_plane_masters(true_plane, group_key = PLANE_GROUP_MAIN) - var/list/atom/movable/screen/plane_master/masters = list() - for(var/plane in TRUE_PLANE_TO_OFFSETS(true_plane)) - masters += get_plane_master(plane, group_key) - return masters - -/// Returns all the planes belonging to the passed in group key -/datum/hud/proc/get_planes_from(group_key) - var/datum/plane_master_group/group = master_groups[group_key] - return group.plane_masters - -/// Returns the corresponding plane group datum if one exists -/datum/hud/proc/get_plane_group(key) - return master_groups[key] - -/datum/hud/proc/on_eye_change(datum/source, atom/old_eye, atom/new_eye) - SIGNAL_HANDLER - SEND_SIGNAL(src, COMSIG_HUD_EYE_CHANGED, old_eye, new_eye) - - if(old_eye) - UnregisterSignal(old_eye, COMSIG_MOVABLE_Z_CHANGED) - if(new_eye) - // By the time logout runs, the client's eye has already changed - // There's just no log of the old eye, so we need to override - // :sadkirby: - RegisterSignal(new_eye, COMSIG_MOVABLE_Z_CHANGED, PROC_REF(eye_z_changed), override = TRUE) - eye_z_changed(new_eye) - diff --git a/code/_onclick/hud/plane_master_group.dm b/code/_onclick/hud/plane_master_group.dm index e80588a19c36..4775d3553fce 100644 --- a/code/_onclick/hud/plane_master_group.dm +++ b/code/_onclick/hud/plane_master_group.dm @@ -95,74 +95,74 @@ // // It would be nice to setup parallaxing for stairs and things when doing this // // So they look nicer. if you can't it's all good, if you think you can sanely look at monster's work // // It's hard, and potentially expensive. be careful -// /datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) -// // Check if this feature is disabled for the client, in which case don't use scale. -// var/mob/our_mob = our_hud?.mymob -// if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) -// use_scale = FALSE - -// // No offset? piss off -// if(!SSmapping.max_plane_offset) -// return - -// active_offset = new_offset - -// // Each time we go "down" a visual z level, we'll reduce the scale by this amount -// // Chosen because mothblocks liked it, didn't cause motion sickness while also giving a sense of height -// var/scale_by = 0.965 -// if(!use_scale) -// // This is a workaround for two things -// // First of all, if a mob can see objects but not turfs, they will not be shown the holder objects we use for -// // What I'd like to do is revert to images if this case throws, but image vis_contents is broken -// // https://www.byond.com/forum/post/2821969 -// // If that's ever fixed, please just use that. thanks :) -// scale_by = 1 - -// var/list/offsets = list() -// var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) - -// // We accept negatives so going down "zooms" away the drop above as it goes -// for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) -// // Multiz boundaries disable transforms -// if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) -// offsets += null -// continue - -// // No transformations if we're landing ON you -// if(offset == 0) -// offsets += null -// continue - -// var/scale = scale_by ** (offset) -// var/matrix/multiz_shrink = matrix() -// multiz_shrink.Scale(scale) -// offsets += multiz_shrink - -// // So we can talk in 1 -> max_offset * 2 + 1, rather then -max_offset -> max_offset -// var/offset_offset = SSmapping.max_plane_offset + 1 - -// for(var/plane_key in plane_masters) -// var/atom/movable/screen/plane_master/plane = plane_masters[plane_key] -// if(!plane.allows_offsetting) -// continue - -// var/visual_offset = plane.offset - new_offset - -// // Basically uh, if we're showing something down X amount of levels, or up any amount of levels -// if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) -// plane.outside_bounds(our_mob) -// else if(plane.is_outside_bounds) -// plane.inside_bounds(our_mob) - -// if(!plane.multiz_scaled) -// continue - -// if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0) -// // We don't animate here because it should be invisble, but we do mark because it'll look nice -// plane.transform = offsets[visual_offset + offset_offset] -// continue - -// animate(plane, transform = offsets[visual_offset + offset_offset], 0.05 SECONDS, easing = LINEAR_EASING) +/datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) + // Check if this feature is disabled for the client, in which case don't use scale. + var/mob/our_mob = our_hud?.mymob + if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) + use_scale = FALSE + + // No offset? piss off + if(!SSmapping.max_plane_offset) + return + + active_offset = new_offset + + // Each time we go "down" a visual z level, we'll reduce the scale by this amount + // Chosen because mothblocks liked it, didn't cause motion sickness while also giving a sense of height + var/scale_by = 0.965 + if(!use_scale) + // This is a workaround for two things + // First of all, if a mob can see objects but not turfs, they will not be shown the holder objects we use for + // What I'd like to do is revert to images if this case throws, but image vis_contents is broken + // https://www.byond.com/forum/post/2821969 + // If that's ever fixed, please just use that. thanks :) + scale_by = 1 + + var/list/offsets = list() + var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) + + // We accept negatives so going down "zooms" away the drop above as it goes + for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) + // Multiz boundaries disable transforms + if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) + offsets += null + continue + + // No transformations if we're landing ON you + if(offset == 0) + offsets += null + continue + + var/scale = scale_by ** (offset) + var/matrix/multiz_shrink = matrix() + multiz_shrink.Scale(scale) + offsets += multiz_shrink + + // So we can talk in 1 -> max_offset * 2 + 1, rather then -max_offset -> max_offset + var/offset_offset = SSmapping.max_plane_offset + 1 + + for(var/plane_key in plane_masters) + var/atom/movable/screen/plane_master/plane = plane_masters[plane_key] + if(!plane.allows_offsetting) + continue + + var/visual_offset = plane.offset - new_offset + + // Basically uh, if we're showing something down X amount of levels, or up any amount of levels + if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) + plane.outside_bounds(our_mob) + else if(plane.is_outside_bounds) + plane.inside_bounds(our_mob) + + if(!plane.multiz_scaled) + continue + + if(plane.force_hidden || plane.is_outside_bounds || visual_offset < 0) + // We don't animate here because it should be invisble, but we do mark because it'll look nice + plane.transform = offsets[visual_offset + offset_offset] + continue + + animate(plane, transform = offsets[visual_offset + offset_offset], 0.05 SECONDS, easing = LINEAR_EASING) /// Holds plane masters for popups, like camera windows /// Note: We do not scale this plane, even though we could diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index b7e32e87acff..78637e568ee2 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -19,6 +19,9 @@ /// A reference to the owner HUD, if any. VAR_PRIVATE/datum/hud/hud = null + /// If FALSE, this will not be cleared when calling /client/clear_screen() + var/clear_with_screen = TRUE + /atom/movable/screen/New(datum/hud/new_hud) . = ..() if(istype(new_hud)) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 7a7f5eb69860..7403efe086d3 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -55,6 +55,9 @@ SUBSYSTEM_DEF(mapping) var/list/areas_in_z = list() + ///list of lists, inner lists are of the form: list("up or down link direction" = TRUE) + var/list/multiz_levels = list() + var/loading_ruins = FALSE var/list/turf/unused_turfs = list() //Not actually unused turfs they're unused but reserved for use for whatever requests them. "[zlevel_of_turf]" = list(turfs) var/list/datum/turf_reservations //list of turf reservations @@ -650,3 +653,7 @@ GLOBAL_LIST_EMPTY(the_station_areas) for(var/turf/to_contain as anything in Z_TURFS(z_level)) var/area/our_area = to_contain.loc our_area.contained_turfs += to_contain + +/datum/controller/subsystem/mapping/proc/get_reservation_from_turf(turf/T) + RETURN_TYPE(/datum/turf_reservation) + return used_turfs[T] diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm new file mode 100644 index 000000000000..b050dd0866f0 --- /dev/null +++ b/code/datums/elements/turf_transparency.dm @@ -0,0 +1,280 @@ +/// List of z pillars (datums placed in the bottom left of XbyX squares that control transparency in that space) +/// The pillars are stored in triple depth lists indexed by (world_size % pillar_size) + 1 +/// They are created at transparent turf request, and deleted when no turfs remain +GLOBAL_LIST_EMPTY(pillars_by_z) +#define Z_PILLAR_RADIUS 20 +// Takes a position, transforms it into a z pillar key +#define Z_PILLAR_TRANSFORM(pos) (ROUND_UP(pos / Z_PILLAR_RADIUS)) +// Takes a z pillar key, hands back the actual posiiton it represents +// A key of 1 becomes 1, a key of 2 becomes Z_PILLAR_RADIUS + 1, etc. +#define Z_KEY_TO_POSITION(key) (((key - 1) * Z_PILLAR_RADIUS) + 1) + +/// Returns a z pillar to insert turfs into +/proc/request_z_pillar(x, y, z) + var/list/pillars_by_z = GLOB.pillars_by_z + if(length(pillars_by_z) < z) + pillars_by_z.len = z + var/list/our_z = pillars_by_z[z] + if(!our_z) + our_z = list() + pillars_by_z[z] = our_z + + //Now that we've got the z layer sorted, we're gonna check the X line + var/x_key = Z_PILLAR_TRANSFORM(x) + if(length(our_z) < x_key) + our_z.len = x_key + var/list/our_x = our_z[x_key] + if(!our_x) + our_x = list() + our_z[x_key] = our_x + + //And now the y layer + var/y_key = Z_PILLAR_TRANSFORM(y) + if(length(our_x) < y_key) + our_x.len = y_key + var/datum/z_pillar/our_lad = our_x[y_key] + if(!our_lad) + our_lad = new(x_key, y_key, z) + our_x[y_key] = our_lad + return our_lad + +/// Exists to be placed on the turf of walls and such to hold the vis_contents of the tile below +/// Otherwise the lower turf might get shifted around, which is dumb. do this instead. +/obj/effect/abstract/z_holder + var/datum/z_pillar/pillar + var/turf/show_for + appearance_flags = PIXEL_SCALE + plane = HUD_PLANE + anchored = TRUE + move_resist = INFINITY + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/obj/effect/abstract/z_holder/Destroy() + if(pillar) + pillar.drawing_object -= show_for + pillar = null + show_for = null + return ..() + +/obj/effect/abstract/z_holder/proc/display(turf/display, datum/z_pillar/behalf_of) + if(pillar) + CRASH("We attempted to use a z holder to display when it was already in use, what'd you do") + + pillar = behalf_of + show_for = display + vis_contents += display + behalf_of.drawing_object[display] = src + +/// Grouping datum that manages transparency for a block of space +/// Setup to ease debugging, and to make add/remove operations cheaper +/datum/z_pillar + var/x_pos + var/y_pos + var/z_pos + /// Assoc list in the form displayed turf -> list of sources + var/list/turf_sources = list() + /// Assoc list of turfs using z holders in the form displayed turf -> z holder + var/list/drawing_object = list() + +/datum/z_pillar/New(x_pos, y_pos, z_pos) + . = ..() + src.x_pos = x_pos + src.y_pos = y_pos + src.z_pos = z_pos + +/datum/z_pillar/Destroy() + GLOB.pillars_by_z[z_pos][x_pos][y_pos] = null + // Just to be totally clear, this is code that exists to + // A: make sure cleanup is actually possible for this datum, just in case someone goes insane + // B: allow for easier debugging and making sure everything behaves as expected when fully removed + // It is not meant to be relied on, please don't actually it's not very fast + for(var/turf/displaying in turf_sources) + for(var/turf/displaying_for in turf_sources[displaying]) + hide_turf(displaying, displaying_for) + return ..() + +/// Displays a turf from the z level below us on our level +/datum/z_pillar/proc/display_turf(turf/to_display, turf/source) + var/list/sources = turf_sources[to_display] + + if(sources) // If we aren't the first to request this turf, return + sources |= source + var/obj/effect/abstract/z_holder/holding = drawing_object[to_display] + if(!holding) + return + + var/turf/visual_target = GET_TURF_ABOVE(to_display) + /// Basically, if we used to be under a non transparent turf, but are no longer in that position + /// Then we add to the transparent turf we're now under, and nuke the old object + if(!istransparentturf(visual_target)) + return + + holding.vis_contents -= to_display + qdel(holding) + drawing_object -= to_display + visual_target.vis_contents += to_display + return + + // Otherwise, we need to create a new set of sources. let's do that yeah? + sources = list() + turf_sources[to_display] = sources + sources |= source + + var/turf/visual_target = GET_TURF_ABOVE(to_display) + if(istransparentturf(visual_target) || isopenspaceturf(visual_target)) + visual_target.vis_contents += to_display + else + var/obj/effect/abstract/z_holder/hold_this = new(visual_target) + hold_this.display(to_display, src) + +/// Hides an existing turf from our vis_contents, or the vis_contents of the source if applicable +/datum/z_pillar/proc/hide_turf(turf/to_hide, turf/source) + var/list/sources = turf_sources[to_hide] + if(!sources) + return + sources -= source + // More sources remain + if(length(sources)) + return + + turf_sources -= to_hide + var/obj/effect/abstract/z_holder/holding = drawing_object[to_hide] + if(holding) + qdel(holding) + else + var/turf/visual_target = GET_TURF_ABOVE(to_hide) + visual_target.vis_contents -= to_hide + + if(!length(turf_sources) && !QDELETED(src)) + qdel(src) + +/// Called when a transparent turf is cleared. We wait a tick, then check to see what +/// Kind of turf replaced our former holder, and resetup our visuals as desired +/// We do not need to do this for non transparent holders, because they will have their abstract object cleared +/// When a transparent holder comes back. +/datum/z_pillar/proc/parent_cleared(turf/visual, turf/current_holder) + addtimer(CALLBACK(src, PROC_REF(refresh_orphan), visual, current_holder)) + +/// Runs the actual refresh of some formerly orphaned via vis_loc deletiong turf +/// We'll only reup if we either have no souece, or if the source is a transparent turf +/datum/z_pillar/proc/refresh_orphan(turf/orphan, turf/parent) + var/list/sources = turf_sources[orphan] + if(!length(sources)) + return + + var/obj/effect/abstract/z_holder/holding = drawing_object[orphan] + if(holding) + return + + if(istransparentturf(parent) || isopenspaceturf(parent)) + parent.vis_contents += orphan + else + var/obj/effect/abstract/z_holder/hold_this = new(parent) + hold_this.display(orphan, src) + +/datum/element/turf_z_transparency + element_flags = ELEMENT_DETACH_ON_HOST_DESTROY + +///This proc sets up the signals to handle updating viscontents when turfs above/below update. Handle plane and layer here too so that they don't cover other obs/turfs in Dream Maker +/datum/element/turf_z_transparency/Attach(datum/target, mapload) + . = ..() + if(!isturf(target)) + return ELEMENT_INCOMPATIBLE + + var/turf/our_turf = target + + RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, PROC_REF(on_multiz_turf_del)) + RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, PROC_REF(on_multiz_turf_new)) + + ADD_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, ELEMENT_TRAIT(type)) + + if(!mapload) + update_multi_z(our_turf) + +/datum/element/turf_z_transparency/Detach(datum/source) + . = ..() + var/turf/our_turf = source + clear_multiz(our_turf) + + UnregisterSignal(our_turf, list(COMSIG_TURF_MULTIZ_NEW, COMSIG_TURF_MULTIZ_DEL)) + REMOVE_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, ELEMENT_TRAIT(type)) + +///Updates the viscontents or underlays below this tile. +/datum/element/turf_z_transparency/proc/update_multi_z(turf/our_turf) + var/turf/below_turf = GET_TURF_BELOW(our_turf) + if(below_turf) // If we actually have something below us, display it. + for(var/turf/partner in range(1, below_turf)) + // We use our z here to ensure the pillar is actually on our level + var/datum/z_pillar/z_boss = request_z_pillar(partner.x, partner.y, our_turf.z) + z_boss.display_turf(partner, our_turf) + else + our_turf.underlays += get_baseturf_underlay(our_turf) + + // This shit is stupid + // z transparency is for making something SHOW WHAT'S BENEATH it, or if nothing is, show + // the appropriate underlay + // IT IS NOT FOR MAKING YOUR CLOSED TURF SEETHROUGH + // these are different concerns, and should not be HANDLED TOGETHER + // similarly, if you rip this out, rework diagonal closed turfs to work with this system + // it will make them look significantly nicer, and should let you tie into their logic more easily + // Just please don't break behavior yeah? thanks, I love you <3 + if(isclosedturf(our_turf)) //Show girders below closed turfs + var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01) + girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR + our_turf.underlays += girder_underlay + var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02) + plating_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR + our_turf.underlays += plating_underlay + return TRUE + +/datum/element/turf_z_transparency/proc/clear_multiz(turf/our_turf) + var/turf/below_turf = GET_TURF_BELOW(our_turf) + if(below_turf) // If we actually have something below us, we need to clear ourselves from it + for(var/turf/partner in range(1, below_turf)) + // We use our z here to ensure the pillar is actually on our level + var/datum/z_pillar/z_boss = request_z_pillar(partner.x, partner.y, our_turf.z) + z_boss.hide_turf(partner, our_turf) + if(partner == below_turf) + z_boss.parent_cleared(below_turf, our_turf) + else + our_turf.underlays -= get_baseturf_underlay(our_turf) + + if(isclosedturf(our_turf)) //Show girders below closed turfs + var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01) + girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR + our_turf.underlays -= girder_underlay + var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02) + plating_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR + our_turf.underlays -= plating_underlay + +/datum/element/turf_z_transparency/proc/on_multiz_turf_del(turf/our_turf, turf/below_turf, dir) + SIGNAL_HANDLER + + if(dir != DOWN) + return + + update_multi_z(our_turf) + +/datum/element/turf_z_transparency/proc/on_multiz_turf_new(turf/our_turf, turf/below_turf, dir) + SIGNAL_HANDLER + + if(dir != DOWN) + return + + update_multi_z(our_turf) + +///Called when there is no real turf below this turf +/datum/element/turf_z_transparency/proc/get_baseturf_underlay(turf/our_turf) + var/turf/path = SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF) || /turf/open/space + if(!ispath(path)) + path = text2path(path) + if(!ispath(path)) + warning("Z-level [our_turf.z] has invalid baseturf '[SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF)]'") + path = /turf/open/space + var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, offset_spokesman = our_turf, plane = PLANE_SPACE) + underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR + return underlay_appearance + +#undef Z_PILLAR_RADIUS +#undef Z_PILLAR_TRANSFORM +#undef Z_KEY_TO_POSITION diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 44ff68c6c5ae..941865b02e93 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -12,6 +12,9 @@ ///If non-null, overrides a/an/some in all cases var/article + /// How many tiles "up" this light is. 1 is typical, should only really change this if it's a floor light + var/light_height = LIGHTING_HEIGHT + ///First atom flags var var/flags_1 = NONE ///Intearaction flags diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index e1f80cde837e..ebfd1e4aa26e 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -45,6 +45,10 @@ var/zfalling = FALSE + ///is the mob currently ascending or descending through z levels? + var/currently_z_moving + + /// 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 @@ -126,15 +130,24 @@ vis_contents.Cut() /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, dir) + // This one is incredible. + // `if (x) else { /* code */ }` is surprisingly fast, and it's faster than a switch, which is seemingly not a jump table. + // From what I can tell, a switch case checks every single branch individually, although sane, is slow in a hot proc like this. + // So, we make the most common `blocks_emissive` value, EMISSIVE_BLOCK_GENERIC, 0, getting to the fast else branch quickly. + // If it fails, then we can check over every value it can be (here, EMISSIVE_BLOCK_UNIQUE is the only one that matters). + // This saves several hundred milliseconds of init time. + if (blocks_emissive) + if (blocks_emissive == EMISSIVE_BLOCK_UNIQUE) + if(em_block) + SET_PLANE(em_block, EMISSIVE_PLANE, src) + else if(!QDELETED(src)) + render_target = ref(src) + em_block = new(null, src) + return em_block + // Implied else if (blocks_emissive == EMISSIVE_BLOCK_NONE) -> return + // EMISSIVE_BLOCK_GENERIC == 0 + else + return fast_emissive_blocker(src) /atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction) if(!direction) @@ -1044,3 +1057,151 @@ if(. <= GRAB_AGGRESSIVE) ADD_TRAIT(pulling, TRAIT_FLOORED, CHOKEHOLD_TRAIT) ADD_TRAIT(pulling, TRAIT_HANDS_BLOCKED, CHOKEHOLD_TRAIT) +/* + * The core multi-z movement proc. Used to move a movable through z levels. + * If target is null, it'll be determined by the can_z_move proc, which can potentially return null if + * conditions aren't met (see z_move_flags defines in __DEFINES/movement.dm for info) or if dir isn't set. + * Bear in mind you don't need to set both target and dir when calling this proc, but at least one or two. + * This will set the currently_z_moving to CURRENTLY_Z_MOVING_GENERIC if unset, and then clear it after + * Forcemove(). + * + * + * Args: + * * dir: the direction to go, UP or DOWN, only relevant if target is null. + * * target: The target turf to move the src to. Set by can_z_move() if null. + * * z_move_flags: bitflags used for various checks in both this proc and can_z_move(). See __DEFINES/movement.dm. + */ +/atom/movable/proc/zMove(dir, turf/target, z_move_flags = ZMOVE_FLIGHT_FLAGS) + if(!target) + target = can_z_move(dir, get_turf(src), null, z_move_flags) + if(!target) + set_currently_z_moving(FALSE, TRUE) + return FALSE + + var/list/moving_movs = get_z_move_affected(z_move_flags) + + for(var/atom/movable/movable as anything in moving_movs) + movable.currently_z_moving = currently_z_moving || CURRENTLY_Z_MOVING_GENERIC + movable.forceMove(target) + movable.set_currently_z_moving(FALSE, TRUE) + // This is run after ALL movables have been moved, so pulls don't get broken unless they are actually out of range. + if(z_move_flags & ZMOVE_CHECK_PULLS) + for(var/atom/movable/moved_mov as anything in moving_movs) + if(z_move_flags & ZMOVE_CHECK_PULLEDBY && moved_mov.pulledby && (moved_mov.z != moved_mov.pulledby.z || get_dist(moved_mov, moved_mov.pulledby) > 1)) + moved_mov.pulledby.stop_pulling() + if(z_move_flags & ZMOVE_CHECK_PULLING) + moved_mov.check_pulling(TRUE) + return TRUE + +/// Returns a list of movables that should also be affected when src moves through zlevels, and src. +/atom/movable/proc/get_z_move_affected(z_move_flags) + . = list(src) + if(buckled_mobs) + . |= buckled_mobs + if(!(z_move_flags & ZMOVE_INCLUDE_PULLED)) + return + for(var/mob/living/buckled as anything in buckled_mobs) + if(buckled.pulling) + . |= buckled.pulling + if(pulling) + . |= pulling + +/** + * Checks if the destination turf is elegible for z movement from the start turf to a given direction and returns it if so. + * Args: + * * direction: the direction to go, UP or DOWN, only relevant if target is null. + * * start: Each destination has a starting point on the other end. This is it. Most of the times the location of the source. + * * z_move_flags: bitflags used for various checks. See __DEFINES/movement.dm. + * * rider: A living mob in control of the movable. Only non-null when a mob is riding a vehicle through z-levels. + */ +/atom/movable/proc/can_z_move(direction, turf/start, turf/destination, z_move_flags = ZMOVE_FLIGHT_FLAGS, mob/living/rider) + if(!start) + start = get_turf(src) + if(!start) + return FALSE + if(!direction) + if(!destination) + return FALSE + direction = get_dir_multiz(start, destination) + if(direction != UP && direction != DOWN) + return FALSE + if(!destination) + destination = get_step_multiz(start, direction) + if(!destination) + if(z_move_flags & ZMOVE_FEEDBACK) + to_chat(rider || src, span_warning("There's nowhere to go in that direction!")) + return FALSE + if(z_move_flags & ZMOVE_FALL_CHECKS && (throwing || (movement_type & (FLYING|FLOATING)) || !has_gravity(start))) + return FALSE + if(z_move_flags & ZMOVE_CAN_FLY_CHECKS && !(movement_type & (FLYING|FLOATING)) && has_gravity(start)) + if(z_move_flags & ZMOVE_FEEDBACK) + if(rider) + to_chat(rider, span_warning("[src] is is not capable of flight.")) + else + to_chat(src, span_warning("You are not Superman.")) + return FALSE + if((!(z_move_flags & ZMOVE_IGNORE_OBSTACLES) && !(start.zPassOut(direction) && destination.zPassIn(direction))) || (!(z_move_flags & ZMOVE_ALLOW_ANCHORED) && anchored)) + if(z_move_flags & ZMOVE_FEEDBACK) + to_chat(rider || src, span_warning("You couldn't move there!")) + return FALSE + return destination //used by some child types checks and zMove() + +/// Sets the currently_z_moving variable to a new value. Used to allow some zMovement sources to have precedence over others. +/atom/movable/proc/set_currently_z_moving(new_z_moving_value, forced = FALSE) + if(forced) + currently_z_moving = new_z_moving_value + return TRUE + var/old_z_moving_value = currently_z_moving + currently_z_moving = max(currently_z_moving, new_z_moving_value) + return currently_z_moving > old_z_moving_value + +/// Generates a space underlay for a turf +/// This provides proper lighting support alongside just looking nice +/// Accepts the appearance to make "spaceish", and the turf we're doing this for +/proc/generate_space_underlay(mutable_appearance/underlay_appearance, turf/generate_for) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = "space" + SET_PLANE(underlay_appearance, PLANE_SPACE, generate_for) + if(!generate_for.render_target) + generate_for.render_target = ref(generate_for) + var/atom/movable/render_step/emissive_blocker/em_block = new(null, generate_for) + underlay_appearance.overlays += em_block + // We used it because it's convienient and easy, but it's gotta go now or it'll hang refs + QDEL_NULL(em_block) + // We're gonna build a light, and mask it with the base turf's appearance + // grab a 32x32 square of it + // I would like to use GLOB.starbright_overlays here + // But that breaks down for... some? reason. I think recieving a render relay breaks keep_together or something + // So we're just gonna accept that this'll break with starlight color changing. hardly matters since this is really only for offset stuff, but I'd love to fix it someday + var/mutable_appearance/light = new(GLOB.starlight_objects[GET_TURF_PLANE_OFFSET(generate_for) + 1]) + light.render_target = "" + light.appearance_flags |= KEEP_TOGETHER + // Now apply a copy of the turf, set to multiply + // This will multiply against our light, so we only light up the bits that aren't "on" the wall + var/mutable_appearance/mask = new(generate_for.appearance) + mask.blend_mode = BLEND_MULTIPLY + mask.render_target = "" + mask.pixel_x = 0 + mask.pixel_y = 0 + mask.pixel_w = 0 + mask.pixel_z = 0 + mask.transform = null + mask.underlays = list() // Begone foul lighting overlay + SET_PLANE(mask, FLOAT_PLANE, generate_for) + mask.layer = FLOAT_LAYER + + // Bump the opacity to full, will this work? + mask.color = list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,255, 0,0,0,0) + light.overlays += mask + underlay_appearance.overlays += light + + // Now, we're going to make a copy of the mask. Instead of using it to multiply against our light + // We're going to use it to multiply against the turf lighting plane. Going to mask away the turf light + // And rely on LIGHTING_MASK_LAYER to ensure we mask ONLY that bit + var/mutable_appearance/turf_mask = new(mask.appearance) + SET_PLANE(turf_mask, LIGHTING_PLANE, generate_for) + turf_mask.layer = LIGHTING_MASK_LAYER + /// Any color becomes white. Anything else is black, and it's fully opaque + /// Ought to work + turf_mask.color = list(255,255,255,0, 255,255,255,0, 255,255,255,0, 0,0,0,0, 0,0,0,255) + underlay_appearance.overlays += turf_mask diff --git a/code/game/objects/effects/effects.dm b/code/game/objects/effects/effects.dm index 04ed1950154f..338fa9dabf2e 100644 --- a/code/game/objects/effects/effects.dm +++ b/code/game/objects/effects/effects.dm @@ -6,6 +6,7 @@ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF move_resist = INFINITY obj_flags = 0 + blocks_emissive = EMISSIVE_BLOCK_GENERIC /obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = TRUE, attack_dir, armour_penetration = 0) return diff --git a/code/game/turfs/baseturfs/baseturfs.dm b/code/game/turfs/baseturfs/baseturfs.dm new file mode 100644 index 000000000000..195b52de1106 --- /dev/null +++ b/code/game/turfs/baseturfs/baseturfs.dm @@ -0,0 +1,127 @@ +/// Places the given turf on the bottom of the turf stack. +/turf/proc/place_on_bottom(turf/bottom_turf) + baseturfs = baseturfs_string_list( + list(initial(bottom_turf.baseturfs), bottom_turf) + baseturfs, + src + ) + +/// Places a turf at the top of the stack +/turf/proc/place_on_top(turf/added_layer, flags) + var/list/turf/new_baseturfs = list() + + new_baseturfs.Add(baseturfs) + if(isopenturf(src)) + new_baseturfs.Add(type) + + return ChangeTurf(added_layer, new_baseturfs, flags) + +/// Places a turf on top - for map loading +/turf/proc/load_on_top(turf/added_layer, flags) + var/area/our_area = get_area(src) + flags = our_area.PlaceOnTopReact(list(baseturfs), added_layer, flags) + + if(flags & CHANGETURF_SKIP) // We haven't been initialized + if(flags_1 & INITIALIZED_1) + stack_trace("CHANGETURF_SKIP was used in a PlaceOnTop call for a turf that's initialized. This is a mistake. [src]([type])") + assemble_baseturfs() + + var/turf/new_turf + if(!length(baseturfs)) + baseturfs = list(baseturfs) + + var/list/old_baseturfs = baseturfs.Copy() + if(!isclosedturf(src)) + old_baseturfs += type + + new_turf = ChangeTurf(added_layer, null, flags) + new_turf.assemble_baseturfs(initial(added_layer.baseturfs)) // The baseturfs list is created like roundstart + if(!length(new_turf.baseturfs)) + new_turf.baseturfs = list(baseturfs) + + // The old baseturfs are put underneath, and we sort out the unwanted ones + new_turf.baseturfs = baseturfs_string_list(old_baseturfs + (new_turf.baseturfs - GLOB.blacklisted_automated_baseturfs), new_turf) + return new_turf + +/// Tries to find the given type in baseturfs. +/// If found, returns how deep it is for use in other baseturf procs, or null if it cannot be found. +/// For example, this number can be passed into ScrapeAway to scrape everything until that point. +/turf/proc/depth_to_find_baseturf(baseturf_type) + if(!islist(baseturfs)) + return baseturfs == baseturf_type ? 1 : null + var/index = baseturfs.Find(baseturf_type) + if (index == 0) + return null + return baseturfs.len - index + 1 + +/// Returns the baseturf at the given depth. +/// For example, baseturf_at_depth(1) will give the baseturf that would show up when scraping once. +/turf/proc/baseturf_at_depth(index) + TEST_ONLY_ASSERT(isnum(index), "baseturf_at_depth must be given a number, received [index]") + if (islist(baseturfs)) + return LAZYACCESS(baseturfs, baseturfs.len - index + 1) + else if (index == 1) + return baseturfs + else + return null + +/// Replaces all instances of needle_type in baseturfs with replacement_type +/turf/proc/replace_baseturf(needle_type, replacement_type) + if (islist(baseturfs)) + var/list/new_baseturfs + + while (TRUE) + var/found_index = baseturfs.Find(needle_type) + if (found_index == 0) + break + + new_baseturfs ||= baseturfs.Copy() + new_baseturfs[found_index] = replacement_type + + if (!isnull(new_baseturfs)) + baseturfs = baseturfs_string_list(new_baseturfs, src) + else if (baseturfs == needle_type) + baseturfs = replacement_type + +/// Removes all baseturfs that are found in the given typecache. +/turf/proc/remove_baseturfs_from_typecache(list/typecache) + if (islist(baseturfs)) + var/list/new_baseturfs + + for (var/baseturf in baseturfs) + if (!typecache[baseturf]) + continue + + new_baseturfs ||= baseturfs.Copy() + new_baseturfs -= baseturf + + if (!isnull(new_baseturfs)) + baseturfs = baseturfs_string_list(new_baseturfs, src) + else if (typecache[baseturfs]) + baseturfs = /turf/baseturf_bottom + +/// Returns the total number of baseturfs +/turf/proc/count_baseturfs() + return islist(baseturfs) ? length(baseturfs) : 1 + +/// Inserts a baseturf at the given level. +/// "Level" here doesn't mean depth. +/// For example, `insert_baseturf(2, /turf/open/floor/plating)` will make it so +/// the 2nd to last turf in the list is plating. +/// This is different from *depth*, since depth is the level from the top. +/turf/proc/insert_baseturf(level, turf_type) + if (!islist(baseturfs)) + assemble_baseturfs() + if(!islist(baseturfs)) + baseturfs = list(baseturfs) + + var/list/baseturfs_copy = baseturfs.Copy() + baseturfs_copy.Insert(level, turf_type) + baseturfs = baseturfs_string_list(baseturfs_copy, src) + +/// Places a baseturf ontop of a searched for baseturf. +/turf/proc/stack_ontop_of_baseturf(floor, roof) + if (!islist(baseturfs)) + baseturfs = list(baseturfs) + var/floor_position = baseturfs.Find(floor) + if(floor_position != 0) + insert_baseturf(floor_position + 1, roof) diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm index affcf0cd9e5d..0d23d1d6f8e9 100644 --- a/code/game/turfs/open.dm +++ b/code/game/turfs/open.dm @@ -36,6 +36,19 @@ /turf/open/zAirOut(direction, turf/source) return (direction == UP) +/** + * Replace an open turf with another open turf while avoiding the pitfall of replacing plating with a floor tile, leaving a hole underneath. + * This replaces the current turf if it is plating and is passed plating, is tile and is passed tile. + * It places the new turf on top of itself if it is plating and is passed a tile. + * It also replaces the turf if it is tile and is passed plating, essentially destroying the over turf. + * Flags argument is passed directly to ChangeTurf or PlaceOnTop + */ +/turf/open/proc/replace_floor(turf/open/new_floor_path, flags) + if (!overfloor_placed && initial(new_floor_path.overfloor_placed)) + place_on_top(new_floor_path, flags = flags) + return + ChangeTurf(new_floor_path, flags = flags) + /turf/open/indestructible name = "floor" icon = 'icons/turf/floors.dmi' @@ -618,3 +631,54 @@ flammability = initial(flammability) return flammability = new_flammability + +/// Builds with rods. This doesn't exist to be overriden, just to remove duplicate logic for turfs that want +/// To support floor tile creation +/// I'd make it a component, but one of these things is space. So no. +/turf/open/proc/build_with_rods(obj/item/stack/rods/used_rods, mob/user) + var/obj/structure/lattice/catwalk_bait = locate(/obj/structure/lattice, src) + var/obj/structure/lattice/catwalk/existing_catwalk = locate(/obj/structure/lattice/catwalk, src) + if(existing_catwalk) + to_chat(user, span_warning("There is already a catwalk here!")) + return + + if(catwalk_bait) + if(used_rods.use(1)) + qdel(catwalk_bait) + to_chat(user, span_notice("You construct a catwalk.")) + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /obj/structure/lattice/catwalk(src) + else + to_chat(user, span_warning("You need two rods to build a catwalk!")) + return + + if(used_rods.use(1)) + to_chat(user, span_notice("You construct a lattice.")) + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + new /obj/structure/lattice(src) + else + to_chat(user, span_warning("You need one rod to build a lattice.")) + +/// Very similar to build_with_rods, this exists to allow consistent behavior between different types in terms of how +/// Building floors works +/turf/open/proc/build_with_floor_tiles(obj/item/stack/tile/plasteel/used_tiles, user) + var/obj/structure/lattice/lattice = locate(/obj/structure/lattice, src) + if(!has_valid_support() && !lattice) + balloon_alert(user, "needs support, place rods!") + return + if(!used_tiles.use(1)) + balloon_alert(user, "need a floor tile to build!") + return + + playsound(src, 'sound/weapons/genhit.ogg', 50, TRUE) + var/turf/open/floor/plating/new_plating = place_on_top(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) + if(lattice) + qdel(lattice) + else + new_plating.lattice_underneath = FALSE + +/turf/open/proc/has_valid_support() + for (var/direction in GLOB.cardinals) + if(istype(get_step(src, direction), /turf/open/floor)) + return TRUE + return FALSE diff --git a/code/game/turfs/simulated/floor/plating.dm b/code/game/turfs/simulated/floor/plating.dm index 5fdd9fa14468..cfffea5f0cf6 100644 --- a/code/game/turfs/simulated/floor/plating.dm +++ b/code/game/turfs/simulated/floor/plating.dm @@ -188,3 +188,8 @@ if(locate(/obj/structure/lattice/catwalk, src)) return FALSE return TRUE +///not an actual turf its used just for rcd ui purposes +/turf/open/floor/plating/rcd + name = "Floor/Wall" + icon = 'icons/mob/radial.dmi' + icon_state = "wallfloor" diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index f45f1085b16f..33e4221dbf82 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -1,59 +1,88 @@ +///The base color of light space emits +GLOBAL_VAR_INIT(base_starlight_color, default_starlight_color()) +///The color of light space is currently emitting +GLOBAL_VAR_INIT(starlight_color, default_starlight_color()) +/proc/default_starlight_color() + var/turf/open/space/read_from = /turf/open/space + return initial(read_from.light_color) + +///The range of the light space is displaying +GLOBAL_VAR_INIT(starlight_range, default_starlight_range()) +/proc/default_starlight_range() + var/turf/open/space/read_from = /turf/open/space + return initial(read_from.light_range) + +///The power of the light space is throwin out +GLOBAL_VAR_INIT(starlight_power, default_starlight_power()) +/proc/default_starlight_power() + var/turf/open/space/read_from = /turf/open/space + return initial(read_from.light_power) + +/proc/set_base_starlight(star_color = null, range = null, power = null) + GLOB.base_starlight_color = star_color + set_starlight(star_color, range, power) + +/proc/set_starlight(star_color = null, range = null, power = null) + if(isnull(star_color)) + star_color = GLOB.starlight_color + var/old_star_color = GLOB.starlight_color + GLOB.starlight_color = star_color + // set light color on all lit turfs + for(var/turf/open/space/spess as anything in GLOB.starlight) + spess.set_light(l_range = range, l_power = power, l_color = star_color) + + if(star_color == old_star_color) + return + + // Update the base overlays + for(var/obj/light as anything in GLOB.starlight_objects) + light.color = star_color + // Send some signals that'll update everything that uses the color + SEND_GLOBAL_SIGNAL(COMSIG_STARLIGHT_COLOR_CHANGED, old_star_color, star_color) + +GLOBAL_LIST_EMPTY(starlight) + /turf/open/space icon = 'icons/turf/space.dmi' - icon_state = "0" + icon_state = "space" name = "\proper space" - intact = 0 + overfloor_placed = FALSE + underfloor_accessibility = UNDERFLOOR_INTERACTABLE temperature = TCMB thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT heat_capacity = 700000 - - FASTDMM_PROP(\ - pipe_astar_cost = 3\ - ) + var/starlight_source_count = 0 var/destination_z var/destination_x var/destination_y - var/global/datum/gas_mixture/immutable/space/space_gas = new + var/static/datum/gas_mixture/immutable/space/space_gas = new + // We do NOT want atmos adjacent turfs + init_air = FALSE + run_later = TRUE plane = PLANE_SPACE layer = SPACE_LAYER - light_power = 0.25 - dynamic_lighting = DYNAMIC_LIGHTING_DISABLED + light_power = 1 + light_range = 2 + light_color = COLOR_STARLIGHT + light_height = LIGHTING_HEIGHT_SPACE + light_on = FALSE + space_lit = TRUE bullet_bounce_sound = null + vis_flags = VIS_INHERIT_ID //when this be added to vis_contents of something it be associated with something on clicking, important for visualisation of turf in openspace and interraction with openspace that show you turf. -/turf/open/space/basic/New() //Do not convert to Initialize - //This is used to optimize the map loader - return + force_no_gravity = TRUE -/turf/open/space/Initialize(mapload) +/turf/open/space/basic/New() //Do not convert to Initialize SHOULD_CALL_PARENT(FALSE) - icon_state = SPACE_ICON_STATE - air = space_gas - update_air_ref() - vis_contents.Cut() //removes inherited overlays - visibilityChanged() - - if (PERFORM_ALL_TESTS(focus_only/multiple_space_initialization)) - if(flags_1 & INITIALIZED_1) - stack_trace("Warning: [src]([type]) initialized multiple times!") - flags_1 |= INITIALIZED_1 - - var/area/A = loc - if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) - add_overlay(/obj/effect/fullbright) - - if(requires_activation) - SSair.add_to_active(src) - - if (light_system == STATIC_LIGHT && light_power && light_range) - update_light() - - if (opacity) - directional_opacity = ALL_CARDINALS + //This is used to optimize the map loader + return - return INITIALIZE_HINT_NORMAL +/turf/open/space/Destroy() + GLOB.starlight -= src + return ..() //ATTACK GHOST IGNORING PARENT RETURN VALUE /turf/open/space/attack_ghost(mob/dead/observer/user) @@ -61,9 +90,6 @@ var/turf/T = locate(destination_x, destination_y, destination_z) user.forceMove(T) -/turf/open/space/Initalize_Atmos(times_fired) - return - /turf/open/space/TakeTemperature(temp) /turf/open/space/RemoveLattice() @@ -80,20 +106,32 @@ /turf/open/space/remove_air(amount) return null +/// Updates starlight. Called when we're unsure of a turf's starlight state +/// Returns TRUE if we succeed, FALSE otherwise /turf/open/space/proc/update_starlight() - if(CONFIG_GET(flag/starlight)) - for(var/t in RANGE_TURFS(1,src)) //RANGE_TURFS is in code\__HELPERS\game.dm - if(isspaceturf(t)) - //let's NOT update this that much pls - continue - set_light(2) - return - set_light(0) - -/turf/open/space/attack_paw(mob/user) - return attack_hand(user) + for(var/t in RANGE_TURFS(1, src)) //RANGE_TURFS is in code\__HELPERS\game.dm + // I've got a lot of cordons near spaceturfs, be good kids + if(isspaceturf(t) || istype(t, /turf/cordon)) + //let's NOT update this that much pls + continue + enable_starlight() + return TRUE + GLOB.starlight -= src + set_light(l_on = FALSE) + return FALSE + +/// Turns on the stars, if they aren't already +/turf/open/space/proc/enable_starlight() + if(!light_on) + set_light(l_on = TRUE, l_range = GLOB.starlight_range, l_power = GLOB.starlight_power, l_color = GLOB.starlight_color) + GLOB.starlight += src + +/turf/open/space/attack_paw(mob/user, list/modifiers) + return attack_hand(user, modifiers) /turf/open/space/proc/CanBuildHere() + if(destination_z) + return FALSE return TRUE /turf/open/space/handle_slip() @@ -104,54 +142,24 @@ if(!CanBuildHere()) return if(istype(C, /obj/item/stack/rods)) - var/obj/item/stack/rods/R = C - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - var/obj/structure/lattice/catwalk/W = locate(/obj/structure/lattice/catwalk, src) - if(W) - to_chat(user, span_warning("There is already a catwalk here!")) - return - if(L) - if(R.use(1)) - to_chat(user, span_notice("You construct a catwalk.")) - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - new/obj/structure/lattice/catwalk(src) - else - to_chat(user, span_warning("You need one rod to build a catwalk!")) - return - if(R.use(1)) - to_chat(user, span_notice("You construct a lattice.")) - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - ReplaceWithLattice() - else - to_chat(user, span_warning("You need one rod to build a lattice.")) - return - if(istype(C, /obj/item/stack/tile/plasteel)) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - var/obj/item/stack/tile/plasteel/S = C - if(S.use(1)) - qdel(L) - playsound(src, 'sound/weapons/genhit.ogg', 50, 1) - to_chat(user, span_notice("You build a floor.")) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - else - to_chat(user, span_warning("You need one floor tile to build a floor!")) - else - to_chat(user, span_warning("The plating is going to need some support! Place metal rods first.")) + build_with_rods(C, user) + else if(istype(C, /obj/item/stack/tile/plasteel)) + build_with_floor_tiles(C, user) -/turf/open/space/Entered(atom/movable/A) - ..() - if ((!(A) || src != A.loc)) + +/turf/open/space/Entered(atom/movable/arrived, atom/old_loc, list/atom/old_locs) + . = ..() + if(!arrived || src != arrived.loc) return - if(destination_z && destination_x && destination_y && !(A.pulledby || !A.can_be_z_moved)) + if(destination_z && destination_x && destination_y && !arrived.pulledby && !arrived.currently_z_moving) var/tx = destination_x var/ty = destination_y var/turf/DT = locate(tx, ty, destination_z) var/itercount = 0 while(DT.density || istype(DT.loc,/area/shuttle)) // Extend towards the center of the map, trying to look for a better place to arrive if (itercount++ >= 100) - log_game("SPACE Z-TRANSIT ERROR: Could not find a safe place to land [A] within 100 iterations.") + log_game("SPACE Z-TRANSIT ERROR: Could not find a safe place to land [arrived] within 100 iterations.") break if (tx < 128) tx++ @@ -163,18 +171,13 @@ ty-- DT = locate(tx, ty, destination_z) - var/atom/movable/AM = A.pulling - A.forceMove(DT) - if(AM) - var/turf/T = get_step(A.loc,turn(A.dir, 180)) - AM.can_be_z_moved = FALSE - AM.forceMove(T) - A.start_pulling(AM) - AM.can_be_z_moved = TRUE + arrived.zMove(null, DT, ZMOVE_ALLOW_BUCKLED) - //now we're on the new z_level, proceed the space drifting - stoplag()//Let a diagonal move finish, if necessary - A.newtonian_move(A.inertia_dir) + var/atom/movable/current_pull = arrived.pulling + while (current_pull) + var/turf/target_turf = get_step(current_pull.pulledby.loc, REVERSE_DIR(current_pull.pulledby.dir)) || current_pull.pulledby.loc + current_pull.zMove(null, target_turf, ZMOVE_ALLOW_BUCKLED) + current_pull = current_pull.pulling /turf/open/space/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent) @@ -185,46 +188,25 @@ /turf/open/space/can_have_cabling() if(locate(/obj/structure/lattice/catwalk, src)) - return 1 - return 0 + return TRUE + return FALSE /turf/open/space/is_transition_turf() if(destination_x || destination_y || destination_z) - return 1 + return TRUE /turf/open/space/acid_act(acidpwr, acid_volume) - return 0 + return FALSE /turf/open/space/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = SPACE_ICON_STATE - underlay_appearance.plane = PLANE_SPACE + generate_space_underlay(underlay_appearance, asking_turf) return TRUE - -/turf/open/space/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd) - if(!CanBuildHere()) - return FALSE - - switch(the_rcd.mode) - if(RCD_FLOORWALL) - var/obj/structure/lattice/L = locate(/obj/structure/lattice, src) - if(L) - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 1) - else - return list("mode" = RCD_FLOORWALL, "delay" = 0, "cost" = 3) - return FALSE - -/turf/open/space/rcd_act(mob/user, obj/item/construction/rcd/the_rcd, passed_mode) - switch(passed_mode) - if(RCD_FLOORWALL) - to_chat(user, span_notice("You build a floor.")) - PlaceOnTop(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR) - return TRUE +/turf/open/space/rust_heretic_act() return FALSE -/turf/open/space/ReplaceWithLattice() +/turf/open/space/attempt_lattice_replacement() var/dest_x = destination_x var/dest_y = destination_y var/dest_z = destination_z @@ -232,3 +214,98 @@ destination_x = dest_x destination_y = dest_y destination_z = dest_z + +/turf/open/space/can_cross_safely(atom/movable/crossing) + return HAS_TRAIT(crossing, TRAIT_SPACEWALK) + +/turf/open/space/openspace + icon = 'icons/turf/floors.dmi' + icon_state = MAP_SWITCH("pure_white", "invisible") + plane = TRANSPARENT_FLOOR_PLANE + +/turf/open/space/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker + . = ..() + if(PERFORM_ALL_TESTS(focus_only/openspace_clear) && !GET_TURF_BELOW(src)) + stack_trace("[src] was inited as openspace with nothing below it at ([x], [y], [z])") + icon_state = "pure_white" + // We make the assumption that the space plane will never be blacklisted, as an optimization + if(SSmapping.max_plane_offset) + plane = TRANSPARENT_FLOOR_PLANE - (PLANE_RANGE * SSmapping.z_level_to_plane_offset[z]) + return INITIALIZE_HINT_LATELOAD + +/turf/open/space/openspace/LateInitialize() + . = ..() + AddElement(/datum/element/turf_z_transparency) + +/turf/open/space/openspace/Destroy() + // Signals persist through destroy, GO HOME + var/turf/below = GET_TURF_BELOW(src) + if(below) + UnregisterSignal(below, COMSIG_TURF_CHANGE) + return ..() + +/turf/open/space/openspace/zAirIn() + return TRUE + +/turf/open/space/openspace/zAirOut() + return TRUE + +/turf/open/space/openspace/zPassIn(direction) + if(direction == DOWN) + for(var/obj/contained_object in contents) + if(contained_object.obj_flags & BLOCK_Z_IN_DOWN) + return FALSE + return TRUE + if(direction == UP) + for(var/obj/contained_object in contents) + if(contained_object.obj_flags & BLOCK_Z_IN_UP) + return FALSE + return TRUE + return FALSE + +/turf/open/space/openspace/zPassOut(direction) + if(direction == DOWN) + for(var/obj/contained_object in contents) + if(contained_object.obj_flags & BLOCK_Z_OUT_DOWN) + return FALSE + return TRUE + if(direction == UP) + for(var/obj/contained_object in contents) + if(contained_object.obj_flags & BLOCK_Z_OUT_UP) + return FALSE + return TRUE + return FALSE + +/turf/open/space/openspace/enable_starlight() + var/turf/below = GET_TURF_BELOW(src) + // Override = TRUE beacuse we could have our starlight updated many times without a failure, which'd trigger this + RegisterSignal(below, COMSIG_TURF_CHANGE, PROC_REF(on_below_change), override = TRUE) + if(!isspaceturf(below) || light_on) + return + set_light(l_on = TRUE, l_range = GLOB.starlight_range, l_power = GLOB.starlight_power, l_color = GLOB.starlight_color) + GLOB.starlight += src + +/turf/open/space/openspace/update_starlight() + . = ..() + if(.) + return + // If we're here, the starlight is not to be + var/turf/below = GET_TURF_BELOW(src) + UnregisterSignal(below, COMSIG_TURF_CHANGE) + +/turf/open/space/openspace/proc/on_below_change(turf/source, path, list/new_baseturfs, flags, list/post_change_callbacks) + SIGNAL_HANDLER + if(isspaceturf(source) && !ispath(path, /turf/open/space)) + GLOB.starlight += src + set_light(l_on = TRUE, l_range = GLOB.starlight_range, l_power = GLOB.starlight_power, l_color = GLOB.starlight_color) + else if(!isspaceturf(source) && ispath(path, /turf/open/space)) + GLOB.starlight -= src + set_light(l_on = FALSE) + +/turf/open/space/replace_floor(turf/open/new_floor_path, flags) + if (!initial(new_floor_path.overfloor_placed)) + ChangeTurf(new_floor_path, flags = flags) + return + // Create plating under tiled floor we try to create directly onto space + place_on_top(/turf/open/floor/plating, flags = flags) + place_on_top(new_floor_path, flags = flags) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index d0aedb4525d9..0c4bd62332b5 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY(station_turfs) icon = 'icons/turf/floors.dmi' level = 1 luminosity = 1 - + light_height = LIGHTING_HEIGHT_FLOOR var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED var/intact = 1 @@ -16,12 +16,25 @@ GLOBAL_LIST_EMPTY(station_turfs) // This shouldn't be modified directly, use the helper procs. var/list/baseturfs = /turf/baseturf_bottom + /// Turf bitflags, see code/__DEFINES/flags.dm + var/turf_flags = NONE + var/temperature = T20C var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to + /// If there's a tile over a basic floor that can be ripped out + var/overfloor_placed = FALSE + /// How accessible underfloor pieces such as wires, pipes, etc are on this turf. Can be HIDDEN, VISIBLE, or INTERACTABLE. + var/underfloor_accessibility = UNDERFLOOR_HIDDEN + /// If there is a lattice underneat this turf. Used for the attempt_lattice_replacement proc to determine if it should place lattice. + var/lattice_underneath = TRUE + var/blocks_air = FALSE + // Optimization, not for setting outside of initialize + var/init_air = TRUE + flags_1 = CAN_BE_DIRTY_1 var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes @@ -59,6 +72,10 @@ GLOBAL_LIST_EMPTY(station_turfs) var/force_no_gravity = FALSE + ///Bool, whether this turf will always be illuminated no matter what area it is in + ///Makes it look blue, be warned + var/space_lit = FALSE + /turf/vv_edit_var(var_name, new_value) var/static/list/banned_edits = list("x", "y", "z") @@ -159,8 +176,6 @@ GLOBAL_LIST_EMPTY(station_turfs) return user.Move_Pulled(src) -/turf/proc/multiz_turf_del(turf/T, dir) - /turf/proc/multiz_turf_new(turf/T, dir) //zPassIn doesn't necessarily pass an atom! @@ -652,3 +667,10 @@ GLOBAL_LIST_EMPTY(station_turfs) /// Called when attempting to set fire to a turf /turf/proc/IgniteTurf(power, fire_color="red") return + +/// Returns whether it is safe for an atom to move across this turf +/turf/proc/can_cross_safely(atom/movable/crossing) + return TRUE + +/turf/proc/multiz_turf_del(turf/T, dir) + SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_DEL, T, dir) diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 1fd2e701d888..7db5896f21d8 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -33,6 +33,8 @@ var/list/atmos_overlay_types //gas IDs of current active gas overlays is_openturf = TRUE + /// exists so things like space can ask to take 100% of a tile's gas + var/run_later = FALSE /turf/open/Initialize(mapload) if(!blocks_air) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 31adecb27a05..1ddb1a1cbc2d 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -1116,3 +1116,12 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( if(holder) holder.particool = new /datum/particle_editor(in_atom) holder.particool.ui_interact(mob) +/// Clears the client's screen, aside from ones that opt out +/client/proc/clear_screen() + for (var/object in screen) + if (istype(object, /atom/movable/screen)) + var/atom/movable/screen/screen_object = object + if (!screen_object.clear_with_screen) + continue + + screen -= object diff --git a/code/modules/client/preferences/multiz_parallax.dm b/code/modules/client/preferences/multiz_parallax.dm new file mode 100644 index 000000000000..d4f77e206b2a --- /dev/null +++ b/code/modules/client/preferences/multiz_parallax.dm @@ -0,0 +1,16 @@ +/// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. +/datum/preference/toggle/multiz_parallax + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "multiz_parallax" + savefile_identifier = PREFERENCE_PLAYER + +/datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) + // Update the plane master group's Z transforms. + + var/datum/hud/my_hud = client.mob?.hud_used + if(!my_hud) + return + + for(var/group_key as anything in my_hud.master_groups) + var/datum/plane_master_group/group = my_hud.master_groups[group_key] + group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) diff --git a/code/modules/client/preferences/multiz_performance.dm b/code/modules/client/preferences/multiz_performance.dm new file mode 100644 index 000000000000..7591401f2d8d --- /dev/null +++ b/code/modules/client/preferences/multiz_performance.dm @@ -0,0 +1,21 @@ +/// Boundary for how many z levels down to render properly before we start going cheapo mode +/datum/preference/numeric/multiz_performance + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "multiz_performance" + savefile_identifier = PREFERENCE_PLAYER + + minimum = MULTIZ_PERFORMANCE_DISABLE + maximum = MAX_EXPECTED_Z_DEPTH - 1 + +/datum/preference/numeric/multiz_performance/create_default_value() + return -1 + +/datum/preference/numeric/multiz_performance/apply_to_client(client/client, value) + // Update the plane master group's layering + var/datum/hud/my_hud = client.mob?.hud_used + if(!my_hud) + return + + for(var/group_key as anything in my_hud.master_groups) + var/datum/plane_master_group/group = my_hud.master_groups[group_key] + group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) diff --git a/code/modules/lighting/static_lighting_area.dm b/code/modules/lighting/static_lighting_area.dm new file mode 100644 index 000000000000..e05868d0b829 --- /dev/null +++ b/code/modules/lighting/static_lighting_area.dm @@ -0,0 +1,59 @@ +/// List of plane offset + 1 -> object to display to use +/// Fills with offsets as they are generated +/// Holds a list of objects that represent starlight. The idea is to render_source them +/// So modifying starlight requires touching only one place (NOTE: this doesn't work for the area overlays) +/// In order to modify them you need to use set_starlight. Areas don't work with render sources it looks like +GLOBAL_LIST_INIT_TYPED(starlight_objects, /obj, list(starlight_object(0))) +/obj/starlight_appearance + icon = 'icons/effects/alphacolors.dmi' + icon_state = "white" + layer = LIGHTING_PRIMARY_LAYER + blend_mode = BLEND_ADD + screen_loc = "1,1" + +/proc/starlight_object(offset) + var/obj/starlight_appearance/glow = new() + SET_PLANE_W_SCALAR(glow, LIGHTING_PLANE, offset) + glow.layer = LIGHTING_PRIMARY_LAYER + glow.blend_mode = BLEND_ADD + glow.color = GLOB.starlight_color + glow.render_target = SPACE_OVERLAY_RENDER_TARGET(offset) + return glow + +/// List of plane offset + 1 -> mutable appearance to use +/// Fills with offsets as they are generated +/// They mirror their appearance from the starlight objects, which lets us save +/// time updating them +GLOBAL_LIST_INIT_TYPED(starlight_overlays, /obj, list(starlight_overlay(0))) + +/proc/starlight_overlay(offset) + var/mutable_appearance/glow = new /mutable_appearance() + SET_PLANE_W_SCALAR(glow, LIGHTING_PLANE, offset) + glow.layer = LIGHTING_PRIMARY_LAYER + glow.blend_mode = BLEND_ADD + glow.render_source = SPACE_OVERLAY_RENDER_TARGET(offset) + return glow + +/area + ///Whether this area allows static lighting and thus loads the lighting objects + var/static_lighting = TRUE + +//Non static lighting areas. +//Any lighting area that wont support static lights. +//These areas will NOT have corners generated. + +///regenerates lighting objects for turfs in this area, primary use is VV changes +/area/proc/create_area_lighting_objects() + for(var/turf/T in src) + if(T.space_lit) + continue + T.lighting_build_overlay() + CHECK_TICK + +///Removes lighting objects from turfs in this area if we have them, primary use is VV changes +/area/proc/remove_area_lighting_objects() + for(var/turf/T in src) + if(T.space_lit) + continue + T.lighting_clear_overlay() + CHECK_TICK diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index e62c604fd91f..5ebf5ca364d6 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -528,7 +528,7 @@ return ..() ///Move a mob between z levels, if it's valid to move z's on this turf -/mob/proc/zMove(dir, feedback = FALSE) +/mob/proc/zMoveMob(dir, feedback = FALSE) if(dir != UP && dir != DOWN) return FALSE var/turf/target = get_step_multiz(src, dir) diff --git a/code/modules/visual/render_step.dm b/code/modules/visual/render_step.dm new file mode 100644 index 000000000000..2dae53b44ba0 --- /dev/null +++ b/code/modules/visual/render_step.dm @@ -0,0 +1,92 @@ +/** + * Internal atom that uses render relays to apply "appearance things" to a render source + * Branch, subtypes have behavior +*/ +/atom/movable/render_step + name = "render step" + plane = DEFAULT_PLANE + layer = FLOAT_LAYER + mouse_opacity = MOUSE_OPACITY_TRANSPARENT + //Why? + //render_targets copy the transform of the target as well, but vis_contents also applies the transform + //we'll display using that, so we gotta reset + appearance_flags = KEEP_APART|KEEP_TOGETHER|RESET_TRANSFORM + +/atom/movable/render_step/Initialize(mapload, atom/source) + . = ..() + verbs.Cut() //Cargo cultttttt + + if(!source) + return + + render_source = source.render_target + SET_PLANE_EXPLICIT(src, initial(plane), source) + RegisterSignal(source, COMSIG_PARENT_QDELETING, PROC_REF(on_source_deleting)) + +/atom/movable/render_step/ex_act(severity) + return FALSE + +/atom/movable/render_step/singularity_act() + return + +/atom/movable/render_step/singularity_pull() + return + +/atom/movable/render_step/blob_act() + return + +//Prevents people from moving these after creation, because they shouldn't be. +/atom/movable/render_step/forceMove(atom/destination, no_tp=FALSE, harderforce = FALSE) + if(harderforce) + return ..() + +/atom/movable/render_step/proc/on_source_deleting(atom/source) + SIGNAL_HANDLER + + if(!QDELING(src)) + qdel(src) + +/** + * Render step that modfies an atom's color + * Useful for creating coherent emissive blockers out of things like glass floors by lowering alpha statically using matrixes + * Other stuff too I'm sure + */ +/atom/movable/render_step/color + name = "color step" + //RESET_COLOR is obvious I hope + appearance_flags = KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_TRANSFORM + +/atom/movable/render_step/color/Initialize(mapload, atom/source, color) + . = ..() + src.color = color + +/** + * Render step that makes the passed in render source block emissives + * + * 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/render_step/emissive_blocker + name = "emissive blocker" + plane = EMISSIVE_PLANE + appearance_flags = EMISSIVE_APPEARANCE_FLAGS|RESET_TRANSFORM + +/atom/movable/render_step/emissive_blocker/Initialize(mapload, atom/source) + . = ..() + src.color = GLOB.em_block_color + +/** + * Render step that makes the passed in render source GLOW + * + * Copies an appearance vis render_target and render_source on to the emissive plane + */ +/atom/movable/render_step/emissive + name = "emissive" + plane = EMISSIVE_PLANE + appearance_flags = EMISSIVE_APPEARANCE_FLAGS|RESET_TRANSFORM + +/atom/movable/render_step/emissive/Initialize(mapload, source) + . = ..() + src.color = GLOB.emissive_color diff --git a/yogstation.dme b/yogstation.dme index e05d5c5526c2..cc5e642104a2 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -79,6 +79,8 @@ #include "code\__DEFINES\logging.dm" #include "code\__DEFINES\machines.dm" #include "code\__DEFINES\magic.dm" +#include "code\__DEFINES\map_switch.dm" +#include "code\__DEFINES\mapping.dm" #include "code\__DEFINES\maps.dm" #include "code\__DEFINES\materials.dm" #include "code\__DEFINES\maths.dm" @@ -91,6 +93,7 @@ #include "code\__DEFINES\move_force.dm" #include "code\__DEFINES\movement.dm" #include "code\__DEFINES\movespeed_modification.dm" +#include "code\__DEFINES\multiz.dm" #include "code\__DEFINES\nanites.dm" #include "code\__DEFINES\networks.dm" #include "code\__DEFINES\obj_flags.dm" @@ -118,6 +121,7 @@ #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\sound.dm" +#include "code\__DEFINES\space.dm" #include "code\__DEFINES\spaceman_dmm.dm" #include "code\__DEFINES\span.dm" #include "code\__DEFINES\speech_channels.dm" @@ -223,6 +227,7 @@ #include "code\__HELPERS\icon_smoothing.dm" #include "code\__HELPERS\icons.dm" #include "code\__HELPERS\level_traits.dm" +#include "code\__HELPERS\lighting.dm" #include "code\__HELPERS\maths.dm" #include "code\__HELPERS\matrices.dm" #include "code\__HELPERS\mobs.dm" @@ -240,6 +245,7 @@ #include "code\__HELPERS\screen_objs.dm" #include "code\__HELPERS\shell.dm" #include "code\__HELPERS\stat_tracking.dm" +#include "code\__HELPERS\string_lists.dm" #include "code\__HELPERS\text.dm" #include "code\__HELPERS\time.dm" #include "code\__HELPERS\traits.dm" @@ -678,6 +684,7 @@ #include "code\datums\elements\regenerator.dm" #include "code\datums\elements\rust.dm" #include "code\datums\elements\squish.dm" +#include "code\datums\elements\turf_transparency.dm" #include "code\datums\elements\update_icon_blocker.dm" #include "code\datums\helper_datums\events.dm" #include "code\datums\helper_datums\getrev.dm" @@ -1512,6 +1519,7 @@ #include "code\game\turfs\closed.dm" #include "code\game\turfs\open.dm" #include "code\game\turfs\turf.dm" +#include "code\game\turfs\baseturfs\baseturfs.dm" #include "code\game\turfs\openspace\openspace.dm" #include "code\game\turfs\simulated\chasm.dm" #include "code\game\turfs\simulated\dirtystation.dm" @@ -2135,6 +2143,8 @@ #include "code\modules\client\preferences\jobless_role.dm" #include "code\modules\client\preferences\mood.dm" #include "code\modules\client\preferences\mood_enabling.dm" +#include "code\modules\client\preferences\multiz_parallax.dm" +#include "code\modules\client\preferences\multiz_performance.dm" #include "code\modules\client\preferences\names.dm" #include "code\modules\client\preferences\ooc.dm" #include "code\modules\client\preferences\parallax.dm" @@ -2602,6 +2612,7 @@ #include "code\modules\lighting\lighting_setup.dm" #include "code\modules\lighting\lighting_source.dm" #include "code\modules\lighting\lighting_turf.dm" +#include "code\modules\lighting\static_lighting_area.dm" #include "code\modules\mapping\map_template.dm" #include "code\modules\mapping\mapping_helpers.dm" #include "code\modules\mapping\minimap.dm" @@ -3796,6 +3807,7 @@ #include "code\modules\vending\toys.dm" #include "code\modules\vending\wardrobes.dm" #include "code\modules\vending\youtool.dm" +#include "code\modules\visual\render_step.dm" #include "code\modules\VR\vr_human.dm" #include "code\modules\VR\vr_sleeper.dm" #include "code\modules\zombie\items.dm" diff --git a/yogstation/code/game/turfs/change_turf.dm b/yogstation/code/game/turfs/change_turf.dm index 45ea3eca74db..3e0fdf6d164e 100644 --- a/yogstation/code/game/turfs/change_turf.dm +++ b/yogstation/code/game/turfs/change_turf.dm @@ -5,4 +5,14 @@ if(islist(baseturfs)) return ChangeTurf(baseturfs[1],baseturfs[1],flags) else - return ChangeTurf(baseturfs, baseturfs, flags) // The bottom baseturf will never go away \ No newline at end of file + return ChangeTurf(baseturfs, baseturfs, flags) // The bottom baseturf will never go away + + +/// Attempts to replace a tile with lattice. Amount is the amount of tiles to scrape away. +/turf/proc/attempt_lattice_replacement(amount = 2) + if(lattice_underneath) + var/turf/new_turf = ScrapeAway(amount, flags = CHANGETURF_INHERIT_AIR) + if(!istype(new_turf, /turf/open/floor)) + new /obj/structure/lattice(src) + else + ScrapeAway(amount, flags = CHANGETURF_INHERIT_AIR) From 64eaab46e624a1d5799bf6d645a433f785614d15 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 18:25:09 -0500 Subject: [PATCH 016/144] bye runtimes not me --- _maps/_basemap.dm | 2 +- code/_onclick/hud/parallax.dm | 42 +++++++++++++++++------------ code/modules/surgery/organs/eyes.dm | 3 +++ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index 48b96c8948f7..aadbfa88a035 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 046cdc245ab6..fab37f81b666 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -14,9 +14,15 @@ /datum/hud/proc/create_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client + if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref + for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) + parallax.hide_plane(screenmob) return + for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) + parallax.unhide_plane(screenmob) + if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) @@ -35,28 +41,30 @@ C.parallax_layers.len = C.parallax_layers_max C.screen |= (C.parallax_layers) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = list( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 1, 1, 1, 1, - 0, 0, 0, 0 - ) - + // We could do not do parallax for anything except the main plane group + // This could be changed, but it would require refactoring this whole thing + // And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :( + for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += plane_master + plane_master.color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) /datum/hud/proc/remove_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client C.screen -= (C.parallax_layers_cached) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = initial(PM.color) + for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += plane_master + plane_master.color = initial(plane_master.color) C.parallax_layers = null /datum/hud/proc/apply_parallax_pref(mob/viewmob) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index db6dab5339f3..64fccd134caa 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -182,6 +182,9 @@ /obj/item/organ/eyes/night_vision/mushroom name = "fung-eye" desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + low_light_cutoff = list(0, 15, 20) + medium_light_cutoff = list(0, 20, 35) + high_light_cutoff = list(0, 40, 50) ///Robotic From 2526e4bd85831f60e3dbe63530b4db2d454f5e77 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 18:46:07 -0500 Subject: [PATCH 017/144] yeah ok --- code/__DEFINES/construction.dm | 6 --- code/__DEFINES/flags.dm | 2 - code/game/objects/structures/ladders.dm | 2 +- code/game/turfs/simulated/chasm.dm | 6 ++- code/game/turfs/turf.dm | 4 +- code/modules/mapping/ruins.dm | 4 +- .../space_management/multiz_helpers.dm | 6 +-- .../space_management/space_reservation.dm | 7 +++ .../mapping/space_management/traits.dm | 52 ++++++++++++++++--- code/modules/power/reactor/reactor.dm | 4 +- 10 files changed, 66 insertions(+), 27 deletions(-) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index bdaf1343ac68..5578cf9a927b 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -7,16 +7,10 @@ #define RCD_DESIGN_MODE "rcd_design_mode" /// For changing turfs #define RCD_TURF (1 << 0) - /// Full tile windows - #define RCD_WINDOWGRILLE (1 << 1) /// Windoors & Airlocks - #define RCD_AIRLOCK (1 << 2) - /// Literarly anything that is spawned on top of a turf such as tables, machines etc #define RCD_STRUCTURE (1 << 3) /// For wallmounts like air alarms, fire alarms & apc #define RCD_WALLFRAME (1 << 4) - /// For deconstructing an structure - #define RCD_DECONSTRUCT (1 << 5) /// The typepath of the structure the rcd is trying to build #define RCD_DESIGN_PATH "rcd_design_path" diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 20b0012fbc8d..aa70ac67f0ea 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -223,8 +223,6 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204 #define NO_LAVA_GEN (1<<3) /// Blocks ruins spawning on the turf. #define NO_RUINS (1<<4) -/// Blocks this turf from being rusted -#define NO_RUST (1<<5) /// Is this turf is "solid". Space and lava aren't for instance #define IS_SOLID (1<<6) /// This turf will never be cleared away by other objects on Initialize. diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 27ee9e973cb2..7521fc6b8047 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -32,7 +32,7 @@ var/obj/structure/ladder/L if (!down) - L = locate() in SSmapping.get_turf_below(T) + L = locate() in GET_TURF_BELOW(T) if (L) down = L L.up = src // Don't waste effort looping the other way diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm index 482a7a9a7a7e..1c38a9af75a8 100644 --- a/code/game/turfs/simulated/chasm.dm +++ b/code/game/turfs/simulated/chasm.dm @@ -12,7 +12,7 @@ /turf/open/chasm/Initialize(mapload) . = ..() - AddComponent(/datum/component/chasm, SSmapping.get_turf_below(src)) + apply_components(mapload) /turf/open/chasm/proc/set_target(turf/target) var/datum/component/chasm/chasm_component = GetComponent(/datum/component/chasm) @@ -126,3 +126,7 @@ var/turf/T = pick(get_area_turfs(/area/fabric_of_reality)) if(T) set_target(T) + +/// Handles adding the chasm component to the turf (So stuff falls into it!) +/turf/open/chasm/proc/apply_components(mapload) + AddComponent(/datum/component/chasm, GET_TURF_BELOW(src), mapload) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0c4bd62332b5..6a75bcefe155 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -119,7 +119,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if(T) T.multiz_turf_new(src, DOWN) SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN) - T = SSmapping.get_turf_below(src) + T = GET_TURF_BELOW(src) if(T) T.multiz_turf_new(src, UP) SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP) @@ -142,7 +142,7 @@ GLOBAL_LIST_EMPTY(station_turfs) var/turf/T = SSmapping.get_turf_above(src) if(T) T.multiz_turf_del(src, DOWN) - T = SSmapping.get_turf_below(src) + T = GET_TURF_BELOW(src) if(T) T.multiz_turf_del(src, UP) if(force) diff --git a/code/modules/mapping/ruins.dm b/code/modules/mapping/ruins.dm index f6ed99bf937d..b6f3b8750112 100644 --- a/code/modules/mapping/ruins.dm +++ b/code/modules/mapping/ruins.dm @@ -121,7 +121,7 @@ for(var/v in current_pick.always_spawn_with) if(current_pick.always_spawn_with[v] == PLACE_BELOW) var/turf/T = locate(1,1,target_z) - if(!SSmapping.get_turf_below(T)) + if(!GET_TURF_BELOW(T)) if(forced_z) continue outer else @@ -181,7 +181,7 @@ if(PLACE_DEFAULT) forced_ruins[linked] = -1 if(PLACE_BELOW) - forced_ruins[linked] = SSmapping.get_turf_below(placed_turf) + forced_ruins[linked] = GET_TURF_BELOW(placed_turf) forced_z = 0 //Update the availible list diff --git a/code/modules/mapping/space_management/multiz_helpers.dm b/code/modules/mapping/space_management/multiz_helpers.dm index ca7cd8d52042..6d2f648c227c 100644 --- a/code/modules/mapping/space_management/multiz_helpers.dm +++ b/code/modules/mapping/space_management/multiz_helpers.dm @@ -1,12 +1,12 @@ /proc/get_step_multiz(ref, dir) + var/turf/us = get_turf(ref) if(dir & UP) dir &= ~UP - return get_step(SSmapping.get_turf_above(get_turf(ref)), dir) + return get_step(GET_TURF_ABOVE(us), dir) if(dir & DOWN) dir &= ~DOWN - return get_step(SSmapping.get_turf_below(get_turf(ref)), dir) + return get_step(GET_TURF_BELOW(us), dir) return get_step(ref, dir) - /proc/get_dir_multiz(turf/us, turf/them) us = get_turf(us) them = get_turf(them) diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm index 12137ebf4ca5..cfe9b5043b89 100644 --- a/code/modules/mapping/space_management/space_reservation.dm +++ b/code/modules/mapping/space_management/space_reservation.dm @@ -13,6 +13,13 @@ var/turf_type = /turf/open/space ///Distance away from the cordon where we can put a "sort-cordon" and run some extra code (see make_repel). 0 makes nothing happen var/pre_cordon_distance = 0 + /// The z stack size of the reservation. Note that reservations are ALWAYS reserved from the bottom up + var/z_size = 0 + /// List of the bottom left turfs. Indexed by what their z index for this reservation is + var/list/bottom_left_turfs = list() + + /// List of the top right turfs. Indexed by what their z index for this reservation is + var/list/top_right_turfs = list() /datum/turf_reservation/transit turf_type = /turf/open/space/transit diff --git a/code/modules/mapping/space_management/traits.dm b/code/modules/mapping/space_management/traits.dm index 9ba8d96d5e1c..11f4ccaf203e 100644 --- a/code/modules/mapping/space_management/traits.dm +++ b/code/modules/mapping/space_management/traits.dm @@ -49,14 +49,50 @@ . += S.z_value break -// Attempt to get the turf below the provided one according to Z traits -/datum/controller/subsystem/mapping/proc/get_turf_below(turf/T) - if (!T) - return - var/offset = level_trait(T.z, ZTRAIT_DOWN) - if (!offset) - return - return locate(T.x, T.y, T.z + offset) +/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable. +/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target) + for(var/z_idx in 1 to z_size) + var/turf/bottom_left = bottom_left_turfs[z_idx] + var/turf/top_right = top_right_turfs[z_idx] + var/bl_x = bottom_left.x + var/bl_y = bottom_left.y + var/tr_x = top_right.x + var/tr_y = top_right.y + + if(target.x < bl_x) + continue + + if(target.y < bl_y) + continue + + if(target.x > tr_x) + continue + + if(target.y > tr_y) + continue + + var/list/return_information = list() + return_information["z_idx"] = z_idx + return_information["offset_x"] = target.x - bl_x + return_information["offset_y"] = target.y - bl_y + return return_information + return null + +/// Gets the turf below the given target. Returns null if there is no turf below the target +/datum/turf_reservation/proc/get_turf_below(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the max, then there is no turf below + if(z_idx == z_size) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx + 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) // Attempt to get the turf above the provided one according to Z traits /datum/controller/subsystem/mapping/proc/get_turf_above(turf/T) diff --git a/code/modules/power/reactor/reactor.dm b/code/modules/power/reactor/reactor.dm index 5874490f5f25..da2b5fdafabb 100644 --- a/code/modules/power/reactor/reactor.dm +++ b/code/modules/power/reactor/reactor.dm @@ -593,10 +593,10 @@ T.assume_air(coolant_input) T.assume_air(moderator_input) T.assume_air(coolant_output) - var/turf/lower_turf = SSmapping.get_turf_below(T) + var/turf/lower_turf = GET_TURF_BELOW(T) if(lower_turf) // reactor fuel will melt down into the lower levels on multi-z maps like icemeta new /obj/structure/reactor_corium(lower_turf) - var/turf/lowest_turf = SSmapping.get_turf_below(lower_turf) + var/turf/lowest_turf = GET_TURF_BELOW(lower_turf) if(lowest_turf) // WE NEED TO GO DEEPER new /obj/structure/reactor_corium(lower_turf) explosion(get_turf(src), 0, 5, 10, 20, TRUE, TRUE) From 5544943c748b1fe12d0c58427fafdca5d0276bd4 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 18:54:42 -0500 Subject: [PATCH 018/144] yes yes --- code/game/objects/structures/ladders.dm | 2 +- code/game/turfs/turf.dm | 4 ++-- .../space_management/multiz_helpers.dm | 1 + .../mapping/space_management/traits.dm | 22 ++++++++++++------- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index 7521fc6b8047..6c8863004e56 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -38,7 +38,7 @@ L.up = src // Don't waste effort looping the other way L.update_appearance(UPDATE_ICON) if (!up) - L = locate() in SSmapping.get_turf_above(T) + L = locate() in GET_TURF_ABOVE(T) if (L) up = L L.down = src // Don't waste effort looping the other way diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 6a75bcefe155..0c9fcaea7f07 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -115,7 +115,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if (light_system == STATIC_LIGHT && light_power && light_range) update_light() - var/turf/T = SSmapping.get_turf_above(src) + var/turf/T = GET_TURF_ABOVE(src) if(T) T.multiz_turf_new(src, DOWN) SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN) @@ -139,7 +139,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if(!changing_turf) stack_trace("Incorrect turf deletion") changing_turf = FALSE - var/turf/T = SSmapping.get_turf_above(src) + var/turf/T = GET_TURF_ABOVE(src) if(T) T.multiz_turf_del(src, DOWN) T = GET_TURF_BELOW(src) diff --git a/code/modules/mapping/space_management/multiz_helpers.dm b/code/modules/mapping/space_management/multiz_helpers.dm index 6d2f648c227c..a481aa005978 100644 --- a/code/modules/mapping/space_management/multiz_helpers.dm +++ b/code/modules/mapping/space_management/multiz_helpers.dm @@ -7,6 +7,7 @@ dir &= ~DOWN return get_step(GET_TURF_BELOW(us), dir) return get_step(ref, dir) + /proc/get_dir_multiz(turf/us, turf/them) us = get_turf(us) them = get_turf(them) diff --git a/code/modules/mapping/space_management/traits.dm b/code/modules/mapping/space_management/traits.dm index 11f4ccaf203e..7545b2508a95 100644 --- a/code/modules/mapping/space_management/traits.dm +++ b/code/modules/mapping/space_management/traits.dm @@ -94,15 +94,21 @@ var/turf/bottom_left = bottom_left_turfs[z_idx + 1] return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) -// Attempt to get the turf above the provided one according to Z traits -/datum/controller/subsystem/mapping/proc/get_turf_above(turf/T) - if (!T) - return - var/offset = level_trait(T.z, ZTRAIT_UP) - if (!offset) - return - return locate(T.x, T.y, T.z + offset) +/// Gets the turf above the given target. Returns null if there is no turf above the target +/datum/turf_reservation/proc/get_turf_above(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the min, then there is no turf above + if(z_idx == 1) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx - 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) // Prefer not to use this one too often /datum/controller/subsystem/mapping/proc/get_station_center() var/station_z = levels_by_trait(ZTRAIT_STATION)[1] From 025f5c25922a706e2d5feeae6f831631b44234f0 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:03:37 -0500 Subject: [PATCH 019/144] why am I updating this god save me --- .../space_management/multiz_helpers.dm | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/code/modules/mapping/space_management/multiz_helpers.dm b/code/modules/mapping/space_management/multiz_helpers.dm index a481aa005978..34f2774b5aa8 100644 --- a/code/modules/mapping/space_management/multiz_helpers.dm +++ b/code/modules/mapping/space_management/multiz_helpers.dm @@ -7,7 +7,7 @@ dir &= ~DOWN return get_step(GET_TURF_BELOW(us), dir) return get_step(ref, dir) - + /proc/get_dir_multiz(turf/us, turf/them) us = get_turf(us) them = get_turf(them) @@ -16,23 +16,34 @@ if(us.z == them.z) return get_dir(us, them) else - var/turf/T = us.above() + var/turf/T = GET_TURF_ABOVE(us) var/dir = NONE if(T && (T.z == them.z)) dir = UP else - T = us.below() + T = GET_TURF_BELOW(us) if(T && (T.z == them.z)) dir = DOWN else return get_dir(us, them) return (dir | get_dir(us, them)) -/turf/proc/above() - return get_step_multiz(src, UP) +/proc/get_lowest_turf(atom/ref) + var/turf/us = get_turf(ref) + var/turf/next = GET_TURF_BELOW(us) + while(next) + us = next + next = GET_TURF_BELOW(us) + return us -/turf/proc/below() - return get_step_multiz(src, DOWN) +// I wish this was lisp +/proc/get_highest_turf(atom/ref) + var/turf/us = get_turf(ref) + var/turf/next = GET_TURF_ABOVE(us) + while(next) + us = next + next = GET_TURF_ABOVE(us) + return us /proc/dir_inverse_multiz(dir) var/holder = dir & (UP|DOWN) @@ -46,3 +57,9 @@ holder = UP dir |= holder return dir + +/turf/proc/above() + return get_step_multiz(src, UP) + +/turf/proc/below() + return get_step_multiz(src, DOWN) From 7fd3733984fefbc9c3a2e1ffc270ef0b51b646eb Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:10:43 -0500 Subject: [PATCH 020/144] this is just like call of duty bro --- code/datums/mutable_appearance.dm | 53 +++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index f248da2a7323..c066b96cea41 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,18 +4,45 @@ // Mutable appearances are children of images, just so you know. -/mutable_appearance/New() +// Mutable appearances erase template vars on new, because they accept an appearance to copy as an arg +// If we have nothin to copy, we set the float plane +/mutable_appearance/New(mutable_appearance/to_copy) ..() - plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE - // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var + if(!to_copy) + plane = FLOAT_PLANE -// Helper similar to image() -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE) - var/mutable_appearance/MA = new() - MA.icon = icon - MA.icon_state = icon_state - MA.layer = layer - MA.plane = plane - MA.alpha = alpha - MA.appearance_flags |= appearance_flags - return MA +/** Helper similar to image() + * + * icon - Our appearance's icon + * icon_state - Our appearance's icon state + * layer - Our appearance's layer + * atom/offset_spokesman - An atom to use as reference for the z position of this appearance. + * Only required if a plane is passed in. If this is not passed in we accept offset_const as a substitute + * plane - The plane to use for the appearance. If this is not FLOAT_PLANE we require context for the offset to use + * alpha - Our appearance's alpha + * appearance_flags - Our appearance's appearance_flags + * offset_const - A constant to offset our plane by, so it renders on the right "z layer" +**/ +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, atom/offset_spokesman, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, offset_const) + var/mutable_appearance/appearance = new() + appearance.icon = icon + appearance.icon_state = icon_state + appearance.layer = layer + appearance.alpha = alpha + appearance.appearance_flags |= appearance_flags + if(plane != FLOAT_PLANE) + // You need to pass in some non null object to reference + if(isatom(offset_spokesman)) + // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be + // Not passing ANYTHING in, key difference + SET_PLANE_EXPLICIT(appearance, plane, offset_spokesman) + // That or I'll let you pass in a static offset. Don't be stupid now + else if(!isnull(offset_const)) + SET_PLANE_W_SCALAR(appearance, plane, offset_const) + // otherwise if you're setting plane you better have the guts to back it up + else + stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") + else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) + stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") + + return appearance From df2f3124ab11949fa47d9a472f4fa06ef4da1a02 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:18:35 -0500 Subject: [PATCH 021/144] nah we back --- code/datums/mutable_appearance.dm | 53 ++++++++----------------------- 1 file changed, 13 insertions(+), 40 deletions(-) diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index c066b96cea41..f248da2a7323 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,45 +4,18 @@ // Mutable appearances are children of images, just so you know. -// Mutable appearances erase template vars on new, because they accept an appearance to copy as an arg -// If we have nothin to copy, we set the float plane -/mutable_appearance/New(mutable_appearance/to_copy) +/mutable_appearance/New() ..() - if(!to_copy) - plane = FLOAT_PLANE + plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE + // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var -/** Helper similar to image() - * - * icon - Our appearance's icon - * icon_state - Our appearance's icon state - * layer - Our appearance's layer - * atom/offset_spokesman - An atom to use as reference for the z position of this appearance. - * Only required if a plane is passed in. If this is not passed in we accept offset_const as a substitute - * plane - The plane to use for the appearance. If this is not FLOAT_PLANE we require context for the offset to use - * alpha - Our appearance's alpha - * appearance_flags - Our appearance's appearance_flags - * offset_const - A constant to offset our plane by, so it renders on the right "z layer" -**/ -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, atom/offset_spokesman, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, offset_const) - var/mutable_appearance/appearance = new() - appearance.icon = icon - appearance.icon_state = icon_state - appearance.layer = layer - appearance.alpha = alpha - appearance.appearance_flags |= appearance_flags - if(plane != FLOAT_PLANE) - // You need to pass in some non null object to reference - if(isatom(offset_spokesman)) - // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be - // Not passing ANYTHING in, key difference - SET_PLANE_EXPLICIT(appearance, plane, offset_spokesman) - // That or I'll let you pass in a static offset. Don't be stupid now - else if(!isnull(offset_const)) - SET_PLANE_W_SCALAR(appearance, plane, offset_const) - // otherwise if you're setting plane you better have the guts to back it up - else - stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") - else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) - stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") - - return appearance +// Helper similar to image() +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE) + var/mutable_appearance/MA = new() + MA.icon = icon + MA.icon_state = icon_state + MA.layer = layer + MA.plane = plane + MA.alpha = alpha + MA.appearance_flags |= appearance_flags + return MA From fba7c4d2707fd6415c09f9d877fda9d8c6b19b5b Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:59:47 -0500 Subject: [PATCH 022/144] keep this up and you'll get a gold star me --- code/_onclick/hud/render_plate.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index 9d5b5db99338..359e3b9aa0bb 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -280,7 +280,7 @@ emissive.remove_filter("lighting_mask") // We max alpha here, so our darkness is actually.. dark // Can't do it before cause it fucks with the filter - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) + ///add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) ///render plate for OOC stuff like ghosts, hud-screen effects, etc /atom/movable/screen/plane_master/rendering_plate/non_game From fcf38325f9b364c3236e7755cdf770f95adc33e7 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:50:30 -0500 Subject: [PATCH 023/144] im a twisted fucking cycle path yes --- code/__DEFINES/dcs/signals/signals_client.dm | 14 + code/__DEFINES/lag_switch.dm | 20 ++ code/__DEFINES/maps.dm | 2 + code/__DEFINES/sight.dm | 63 +++- code/__DEFINES/traits.dm | 2 + code/__HELPERS/_lists.dm | 26 ++ code/_globalvars/lists/mobs.dm | 1 + code/_onclick/hud/parallax.dm | 295 +++++++++--------- code/_onclick/hud/random_layer.dm | 52 +++ code/_onclick/hud/render_plate.dm | 2 +- .../configuration/entries/general.dm | 4 + code/controllers/lag_switch.dm | 146 +++++++++ code/controllers/subsystem/parallax.dm | 95 ++++-- code/datums/components/connect_mob_behalf.dm | 59 ++++ code/game/atom_invisibility.dm | 72 +++++ code/game/objects/items/robot/robot_items.dm | 2 +- code/modules/admin/holder2.dm | 2 + code/modules/client/client_defines.dm | 20 ++ code/modules/client/client_procs.dm | 55 +--- .../modules/mob/living/silicon/robot/robot.dm | 2 +- yogstation.dme | 6 + 21 files changed, 719 insertions(+), 221 deletions(-) create mode 100644 code/__DEFINES/dcs/signals/signals_client.dm create mode 100644 code/__DEFINES/lag_switch.dm create mode 100644 code/_onclick/hud/random_layer.dm create mode 100644 code/controllers/lag_switch.dm create mode 100644 code/datums/components/connect_mob_behalf.dm create mode 100644 code/game/atom_invisibility.dm diff --git a/code/__DEFINES/dcs/signals/signals_client.dm b/code/__DEFINES/dcs/signals/signals_client.dm new file mode 100644 index 000000000000..07e5251cad3b --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_client.dm @@ -0,0 +1,14 @@ +// from /client/proc/change_view() : (new_size) +#define COMSIG_VIEW_SET "view_set" + +// from /client/proc/handle_popup_close() : (window_id) +#define COMSIG_POPUP_CLEARED "popup_cleared" + +/// Called after one or more verbs are added: (list of verbs added) +#define COMSIG_CLIENT_VERB_ADDED "client_verb_added" + +/// Called after one or more verbs are added: (list of verbs added) +#define COMSIG_CLIENT_VERB_REMOVED "client_verb_removed" + +/// Called after a client logs into a mob: (mob) +#define COMSIG_CLIENT_MOB_LOGIN "client_mob_changed" diff --git a/code/__DEFINES/lag_switch.dm b/code/__DEFINES/lag_switch.dm new file mode 100644 index 000000000000..2115ce4a5dd4 --- /dev/null +++ b/code/__DEFINES/lag_switch.dm @@ -0,0 +1,20 @@ +// All of the possible Lag Switch lag mitigation measures +// If you add more do not forget to update MEASURES_AMOUNT accordingly +/// Stops ghosts flying around freely, they can still jump and orbit, staff exempted +#define DISABLE_DEAD_KEYLOOP 1 +/// Stops ghosts using zoom/t-ray verbs and resets their view if zoomed out, staff exempted +#define DISABLE_GHOST_ZOOM_TRAY 2 +/// Disable runechat and enable the bubbles, speaking mobs with TRAIT_BYPASS_MEASURES exempted +#define DISABLE_RUNECHAT 3 +/// Disable icon2html procs from verbs like examine, mobs calling with TRAIT_BYPASS_MEASURES exempted +#define DISABLE_USR_ICON2HTML 4 +/// Prevents anyone from joining the game as anything but observer +#define DISABLE_NON_OBSJOBS 5 +/// Limit IC/dchat spam to one message every x seconds per client, TRAIT_BYPASS_MEASURES exempted +#define SLOWMODE_SAY 6 +/// Disables parallax, as if everyone had disabled their preference, TRAIT_BYPASS_MEASURES exempted +#define DISABLE_PARALLAX 7 +/// Disables footsteps, TRAIT_BYPASS_MEASURES exempted +#define DISABLE_FOOTSTEPS 8 + +#define MEASURES_AMOUNT 8 // The total number of switches defined above diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 6bacc65b3ea1..635b395df8bc 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -140,3 +140,5 @@ require only minor tweaks. #define PLACE_LAVA_RUIN "lavaland" #define PLACE_ICE_RUIN "icesurface" #define PLACE_ICE_UNDERGROUND_RUIN "iceunderground" +///boolean - does this z disable parallax? +#define ZTRAIT_NOPARALLAX "No Parallax" diff --git a/code/__DEFINES/sight.dm b/code/__DEFINES/sight.dm index 7952d9addd21..645e00941359 100644 --- a/code/__DEFINES/sight.dm +++ b/code/__DEFINES/sight.dm @@ -1,3 +1,5 @@ +#define INVISIBILITY_NONE 0 + #define SEE_INVISIBLE_MINIMUM 5 #define INVISIBILITY_LIGHTING 20 @@ -10,6 +12,8 @@ //#define SEE_INVISIBLE_LEVEL_TWO 45 //currently unused //#define INVISIBILITY_LEVEL_TWO 45 //currently unused +#define INVISIBILITY_REVENANT 50 + #define INVISIBILITY_OBSERVER 60 #define SEE_INVISIBLE_OBSERVER 60 @@ -17,19 +21,58 @@ #define INVISIBILITY_ABSTRACT 101 //only used for abstract objects (e.g. spacevine_controller), things that are not really there. -#define BORGMESON (1<<0) -#define BORGMESON_NIGHTVISION (1<<1) -#define BORGTHERM (1<<2) -#define BORGXRAY (1<<3) -#define BORGMATERIAL (1<<4) +#define BORGMESON (1<<0) +#define BORGTHERM (1<<1) +#define BORGXRAY (1<<2) +#define BORGMATERIAL (1<<3) //for clothing visor toggles, these determine which vars to toggle -#define VISOR_FLASHPROTECT (1<<0) -#define VISOR_TINT (1<<1) -#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses -#define VISOR_DARKNESSVIEW (1<<3) -#define VISOR_INVISVIEW (1<<3) +#define VISOR_FLASHPROTECT (1<<0) +#define VISOR_TINT (1<<1) +#define VISOR_VISIONFLAGS (1<<2) //all following flags only matter for glasses +#define VISOR_INVISVIEW (1<<3) + +// BYOND internal values for the sight flags +// See [https://www.byond.com/docs/ref/#/mob/var/sight] +/// can't see anything +//#define BLIND (1<<0) +/// can see all mobs, no matter what +//#define SEE_MOBS (1<<2) +/// can see all objs, no matter what +//#define SEE_OBJS (1<<3) +// can see all turfs (and areas), no matter what +//#define SEE_TURFS (1<<4) +/// can see self, no matter what +//#define SEE_SELF (1<<5) +/// can see infra-red objects (different sort of luminosity, essentially a copy of it, one we do not use) +//#define SEE_INFRA (1<<6) +/// if an object is located on an unlit area, but some of its pixels are +/// in a lit area (via pixel_x,y or smooth movement), can see those pixels +//#define SEE_PIXELS (1<<8) +/// can see through opaque objects +//#define SEE_THRU (1<<9) +/// render dark tiles as blackness (Note, this basically means we draw dark tiles to plane 0) +/// we can then hijack that plane with a plane master, and start drawing it anywhere we want +/// NOTE: this does not function with the SIDE_MAP map format. So we can't. :( +//#define SEE_BLACKNESS (1<<10) /// Bitfield of sight flags that show THINGS but no lighting /// Since lighting is an underlay on turfs, this is everything but that #define SEE_AVOID_TURF_BLACKNESS (SEE_MOBS|SEE_OBJS) + +//------------------------ +// INVISIBILITY PRIORITIES + +#define INVISIBILITY_PRIORITY_ADMIN 100 +#define INVISIBILITY_PRIORITY_TURRET_COVER 20 +#define INVISIBILITY_PRIORITY_BASIC_ANTI_INVISIBILITY 10 +#define INVISIBILITY_PRIORITY_NONE 0 + +//------------------------ +// INVISIBILITY SOURCE IDS +// Though don't feel the need to add one here if you have a simple effect that +// gets added and/or removed in only one place near eachother in the code. + +#define INVISIBILITY_SOURCE_INVISIMIN "invisimin" +#define INVISIBILITY_SOURCE_STEALTHMODE "stealthmode" + diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index fbd330ae2e86..ba56ac55edb0 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -513,3 +513,5 @@ #define TRAIT_SPACEWALK "spacewalk" ///Turf trait for when a turf is transparent #define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent" +/// This mob overrides certian SSlag_switch measures with this special trait +#define TRAIT_BYPASS_MEASURES "bypass_lagswitch_measures" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index 5b5e11d4cafd..0331c7010150 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -739,3 +739,29 @@ ///sort any value in a list /proc/sort_list(list/list_to_sort, cmp=/proc/cmp_text_asc) return sortTim(list_to_sort.Copy(), cmp) + +/** + * Picks a random element from a list based on a weighting system. + * For example, given the following list: + * A = 6, B = 3, C = 1, D = 0 + * A would have a 60% chance of being picked, + * B would have a 30% chance of being picked, + * C would have a 10% chance of being picked, + * and D would have a 0% chance of being picked. + * You should only pass integers in. + */ +/proc/pick_weight(list/list_to_pick) + var/total = 0 + var/item + for(item in list_to_pick) + if(!list_to_pick[item]) + list_to_pick[item] = 0 + total += list_to_pick[item] + + total = rand(1, total) + for(item in list_to_pick) + total -= list_to_pick[item] + if(total <= 0 && list_to_pick[item]) + return item + + return null diff --git a/code/_globalvars/lists/mobs.dm b/code/_globalvars/lists/mobs.dm index f0b9240d33e0..1d5863f3ce2b 100644 --- a/code/_globalvars/lists/mobs.dm +++ b/code/_globalvars/lists/mobs.dm @@ -7,6 +7,7 @@ GLOBAL_LIST_EMPTY(stealthminID) //reference list with IDs that store ckeys, //This is for procs to replace all the goddamn 'in world's that are chilling around the code GLOBAL_LIST_EMPTY(player_list) //all mobs **with clients attached**. +GLOBAL_LIST_EMPTY(keyloop_list) //as above but can be limited to boost performance GLOBAL_LIST_EMPTY(mob_list) //all mobs, including clientless GLOBAL_LIST_EMPTY(mob_directory) //mob_id -> mob GLOBAL_LIST_EMPTY(alive_mob_list) //all alive mobs, including clientless. Excludes /mob/dead/new_player diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index fab37f81b666..506226b41ead 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -1,16 +1,4 @@ -/client - var/list/parallax_layers - var/list/parallax_layers_cached - var/atom/movable/movingmob - var/turf/previous_turf - var/dont_animate_parallax //world.time of when we can state animate()ing parallax again - var/last_parallax_shift //world.time of last update - var/parallax_throttle = 0 //ds between updates - var/parallax_movedir = 0 - var/parallax_layers_max = 4 - var/parallax_animate_timer - /datum/hud/proc/create_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client @@ -25,15 +13,12 @@ if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) - if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) - else - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) + C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) C.parallax_layers = C.parallax_layers_cached.Copy() @@ -69,44 +54,60 @@ /datum/hud/proc/apply_parallax_pref(mob/viewmob) var/mob/screenmob = viewmob || mymob + var/turf/screen_location = get_turf(screenmob) + + if(SSmapping.level_trait(screen_location?.z, ZTRAIT_NOPARALLAX)) + for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) + white_space.hide_plane(screenmob) + return FALSE + + for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) + white_space.unhide_plane(screenmob) + + if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(viewmob, TRAIT_BYPASS_MEASURES)) + return FALSE + var/client/C = screenmob.client - if(C.prefs) - var/pref = C.prefs.read_preference(/datum/preference/choiced/parallax) - if (isnull(pref)) - pref = PARALLAX_HIGH - switch(pref) - if (PARALLAX_INSANE) - C.parallax_throttle = FALSE - C.parallax_layers_max = 5 - return TRUE - - if (PARALLAX_MED) - C.parallax_throttle = PARALLAX_DELAY_MED - C.parallax_layers_max = 3 - return TRUE - - if (PARALLAX_LOW) - C.parallax_throttle = PARALLAX_DELAY_LOW - C.parallax_layers_max = 1 - return TRUE - - if (PARALLAX_DISABLE) - return FALSE - - //This is high parallax. - C.parallax_throttle = PARALLAX_DELAY_DEFAULT - C.parallax_layers_max = 4 - return TRUE + // Default to HIGH + var/parallax_selection = C?.prefs.read_preference(/datum/preference/choiced/parallax) || PARALLAX_HIGH + + switch(parallax_selection) + if (PARALLAX_INSANE) + C.parallax_layers_max = 5 + C.do_parallax_animations = TRUE + return TRUE + + if(PARALLAX_HIGH) + C.parallax_layers_max = 4 + C.do_parallax_animations = TRUE + return TRUE + + if (PARALLAX_MED) + C.parallax_layers_max = 3 + C.do_parallax_animations = TRUE + return TRUE + + if (PARALLAX_LOW) + C.parallax_layers_max = 1 + C.do_parallax_animations = FALSE + return TRUE + + if (PARALLAX_DISABLE) + return FALSE /datum/hud/proc/update_parallax_pref(mob/viewmob) - remove_parallax(viewmob) - create_parallax(viewmob) - update_parallax() + var/mob/screen_mob = viewmob || mymob + if(!screen_mob.client) + return + remove_parallax(screen_mob) + create_parallax(screen_mob) + update_parallax(screen_mob) // This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups) +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = 0, skip_windups, mob/viewmob) . = FALSE - var/client/C = mymob.client + var/mob/screenmob = viewmob || mymob + var/client/C = screenmob.client if(new_parallax_movedir == C.parallax_movedir) return var/animatedir = new_parallax_movedir @@ -178,29 +179,25 @@ L.transform = newtransform - animate(L, transform = L.transform, time = 0 SECONDS, loop = -1, flags = ANIMATION_END_NOW) + animate(L, transform = L.transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) animate(transform = matrix(), time = T) -/datum/hud/proc/update_parallax() - var/client/C = mymob.client - if(!C) - return - var/turf/posobj = get_turf_global(C.eye) // yogs - replace get_turf with get_turf_global +/datum/hud/proc/update_parallax(mob/viewmob) + var/mob/screenmob = viewmob || mymob + var/client/C = screenmob.client + var/turf/posobj = get_turf(C.eye) if(!posobj) return - var/area/areaobj = posobj.loc + var/area/areaobj = posobj.loc // Update the movement direction of the parallax if necessary (for shuttles) - set_parallax_movedir(areaobj.parallax_movedir, FALSE) + set_parallax_movedir(areaobj.parallax_movedir, FALSE, screenmob) - var/force + var/force = FALSE if(!C.previous_turf || (C.previous_turf.z != posobj.z)) C.previous_turf = posobj force = TRUE - if (!force && world.time < C.last_parallax_shift+C.parallax_throttle) - return - //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. var/offset_x = posobj.x - C.previous_turf.x var/offset_y = posobj.y - C.previous_turf.y @@ -208,83 +205,105 @@ if(!offset_x && !offset_y && !force) return - var/last_delay = world.time - C.last_parallax_shift - last_delay = min(last_delay, C.parallax_throttle) + var/glide_rate = round(world.icon_size / screenmob.glide_size * world.tick_lag, world.tick_lag) C.previous_turf = posobj - C.last_parallax_shift = world.time - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - L.update_status(mymob) - if (L.view_sized != C.view) - L.update_o(C.view) + var/largest_change = max(abs(offset_x), abs(offset_y)) + var/max_allowed_dist = (glide_rate / world.tick_lag) + 1 + // If we aren't already moving/don't allow parallax, have made some movement, and that movement was smaller then our "glide" size, animate + var/run_parralax = (C.do_parallax_animations && glide_rate && !areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && largest_change <= max_allowed_dist) + for(var/atom/movable/screen/parallax_layer/parallax_layer as anything in C.parallax_layers) + var/our_speed = parallax_layer.speed var/change_x var/change_y - - if(L.absolute) - L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed - L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed + if(parallax_layer.absolute) + // We use change here so the typically large absolute objects (just lavaland for now) don't jitter so much + change_x = (posobj.x - SSparallax.planet_x_offset) * our_speed + parallax_layer.offset_x + change_y = (posobj.y - SSparallax.planet_y_offset) * our_speed + parallax_layer.offset_y else - change_x = offset_x * L.speed - L.offset_x -= change_x - change_y = offset_y * L.speed - L.offset_y -= change_y - - if(L.offset_x > 240) - L.offset_x -= 480 - if(L.offset_x < -240) - L.offset_x += 480 - if(L.offset_y > 240) - L.offset_y -= 480 - if(L.offset_y < -240) - L.offset_y += 480 - - - if(!areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1)) - L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed) - animate(L, transform=matrix(), time = last_delay) - - L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" + change_x = offset_x * our_speed + change_y = offset_y * our_speed + + // This is how we tile parralax sprites + // It doesn't use change because we really don't want to animate this + if(parallax_layer.offset_x - change_x > 240) + parallax_layer.offset_x -= 480 + else if(parallax_layer.offset_x - change_x < -240) + parallax_layer.offset_x += 480 + if(parallax_layer.offset_y - change_y > 240) + parallax_layer.offset_y -= 480 + else if(parallax_layer.offset_y - change_y < -240) + parallax_layer.offset_y += 480 + + // Now that we have our offsets, let's do our positioning + parallax_layer.offset_x -= change_x + parallax_layer.offset_y -= change_y + + parallax_layer.screen_loc = "CENTER-7:[round(parallax_layer.offset_x, 1)],CENTER-7:[round(parallax_layer.offset_y, 1)]" + + // We're going to use a transform to "glide" that last movement out, so it looks nicer + // Don't do any animates if we're not actually moving enough distance yeah? thanks lad + if(run_parralax && (largest_change * our_speed > 1)) + parallax_layer.transform = matrix(1,0,change_x, 0,1,change_y) + animate(parallax_layer, transform=matrix(), time = glide_rate) /atom/movable/proc/update_parallax_contents() - if(length(client_mobs_in_contents)) - for(var/thing in client_mobs_in_contents) - var/mob/M = thing - if(M && M.client && M.hud_used && length(M.client.parallax_layers)) - M.hud_used.update_parallax() - -/mob/proc/update_parallax_teleport() //used for arrivals shuttle - if(client && client.eye && hud_used && length(client.parallax_layers)) + for(var/mob/client_mob as anything in client_mobs_in_contents) + if(length(client_mob?.client?.parallax_layers) && client_mob.hud_used) + client_mob.hud_used.update_parallax() + +/mob/proc/update_parallax_teleport() //used for arrivals shuttle + if(client?.eye && hud_used && length(client.parallax_layers)) var/area/areaobj = get_area(client.eye) hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) +// We need parallax to always pass its args down into initialize, so we immediate init it +INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer icon = 'icons/effects/parallax.dmi' var/speed = 1 var/offset_x = 0 var/offset_y = 0 - var/view_sized var/absolute = FALSE blend_mode = BLEND_ADD plane = PLANE_SPACE_PARALLAX screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/parallax_layer/Initialize(mapload, view) +/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE) . = ..() - if (!view) - view = world.view + // Parallax layers are independant of hud, they care about client + // Not doing this will just create a bunch of hard deletes + hud = null + + if(template) + return + + var/client/boss = hud_owner?.mymob?.canon_client + + if(!boss) // If this typepath all starts to harddel your culprit is likely this + return INITIALIZE_HINT_QDEL + + // I do not want to know bestie + var/view = boss.view || world.view update_o(view) + RegisterSignal(boss, COMSIG_VIEW_SET, PROC_REF(on_view_change)) + +/atom/movable/screen/parallax_layer/proc/on_view_change(datum/source, new_size) + SIGNAL_HANDLER + update_o(new_size) /atom/movable/screen/parallax_layer/proc/update_o(view) if (!view) view = world.view + var/static/parallax_scaler = world.icon_size / 480 + + // Turn the view size into a grid of correctly scaled overlays var/list/viewscales = getviewsize(view) - var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 - var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 + var/countx = CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1 + var/county = CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1 var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) @@ -295,10 +314,6 @@ new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) - view_sized = view - -/atom/movable/screen/parallax_layer/proc/update_status(mob/M) - return /atom/movable/screen/parallax_layer/layer_1 icon_state = "layer1" @@ -315,21 +330,6 @@ speed = 1.4 layer = 3 -/atom/movable/screen/parallax_layer/random - blend_mode = BLEND_OVERLAY - speed = 3 - layer = 3 - -/atom/movable/screen/parallax_layer/random/space_gas - icon_state = "random_layer1" - -/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) - . = ..() - src.add_atom_colour(SSparallax.random_parallax_color, ADMIN_COLOUR_PRIORITY) - -/atom/movable/screen/parallax_layer/random/asteroids - icon_state = "random_layer2" - /atom/movable/screen/parallax_layer/planet icon_state = "planet" blend_mode = BLEND_OVERLAY @@ -337,15 +337,30 @@ speed = 3 layer = 30 -/atom/movable/screen/parallax_layer/planet/moonscorch - icon_state = "rheus_moon" - -/atom/movable/screen/parallax_layer/planet/update_status(mob/M) - var/turf/T = get_turf(M) - if(is_station_level(T.z)) - invisibility = 0 - else - invisibility = INVISIBILITY_ABSTRACT +/atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) + . = ..() + var/client/boss = hud_owner?.mymob?.canon_client + if(!boss) + return + var/static/list/connections = list( + COMSIG_MOVABLE_Z_CHANGED = PROC_REF(on_z_change), + COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout), + ) + AddComponent(/datum/component/connect_mob_behalf, boss, connections) + on_z_change(hud_owner?.mymob) + +/atom/movable/screen/parallax_layer/planet/proc/on_mob_logout(mob/source) + SIGNAL_HANDLER + var/client/boss = source.canon_client + on_z_change(boss.mob) + +/atom/movable/screen/parallax_layer/planet/proc/on_z_change(mob/source) + SIGNAL_HANDLER + var/client/boss = source.client + var/turf/posobj = get_turf(boss?.eye) + if(!posobj) + return + SetInvisibility(is_station_level(posobj.z) ? INVISIBILITY_NONE : INVISIBILITY_ABSTRACT, id=type) /atom/movable/screen/parallax_layer/planet/update_o() - return //Shit wont move + return //Shit won't move diff --git a/code/_onclick/hud/random_layer.dm b/code/_onclick/hud/random_layer.dm new file mode 100644 index 000000000000..379c0cbe2d9b --- /dev/null +++ b/code/_onclick/hud/random_layer.dm @@ -0,0 +1,52 @@ +/// Parallax layers that vary between rounds. Has some code to make sure we all have the same one +/atom/movable/screen/parallax_layer/random + blend_mode = BLEND_OVERLAY + speed = 2 + layer = 3 + +/atom/movable/screen/parallax_layer/random/Initialize(mapload, datum/hud/hud_owner, template, atom/movable/screen/parallax_layer/random/twin) + . = ..() + + if(twin) + copy_parallax(twin) + +/// Make this layer unique, with color or position or something +/atom/movable/screen/parallax_layer/random/proc/get_random_look() + return + +/// Copy a parallax instance to ensure parity between everyones parallax +/atom/movable/screen/parallax_layer/random/proc/copy_parallax(atom/movable/screen/parallax_layer/random/twin) + return + +/// For applying minor effects related to parallax. If you want big stuff, put it in a station trait or something +/atom/movable/screen/parallax_layer/random/proc/apply_global_effects() + return + +/// Gassy background with a few random colors +/atom/movable/screen/parallax_layer/random/space_gas + icon_state = "space_gas" + + /// The colors we can be + var/possible_colors = list(COLOR_TEAL, COLOR_GREEN, COLOR_SILVER, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE) + /// The color we are + var/parallax_color + +/atom/movable/screen/parallax_layer/random/space_gas/get_random_look() + parallax_color = parallax_color || pick(possible_colors) + +/atom/movable/screen/parallax_layer/random/space_gas/copy_parallax(atom/movable/screen/parallax_layer/random/space_gas/twin) + parallax_color = twin.parallax_color + add_atom_colour(parallax_color, ADMIN_COLOUR_PRIORITY) + +/// Space gas but green for the radioactive nebula station trait +/atom/movable/screen/parallax_layer/random/space_gas/radioactive + parallax_color = list(0,0,0,0, 0,2,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) //very vibrant green + +/atom/movable/screen/parallax_layer/random/space_gas/radioactive/apply_global_effects() + . = ..() + set_base_starlight("#189156") + +/// Big asteroid rocks appear in the background +/atom/movable/screen/parallax_layer/random/asteroids + icon_state = "asteroids" + layer = 4 diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index 359e3b9aa0bb..ae05da8839a7 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -280,7 +280,7 @@ emissive.remove_filter("lighting_mask") // We max alpha here, so our darkness is actually.. dark // Can't do it before cause it fucks with the filter - ///add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) + ///add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) -- this makes the walls pitch black (cant see stuff on them) ///render plate for OOC stuff like ghosts, hud-screen effects, etc /atom/movable/screen/plane_master/rendering_plate/non_game diff --git a/code/controllers/configuration/entries/general.dm b/code/controllers/configuration/entries/general.dm index 2252e5ea54de..d221400577f3 100644 --- a/code/controllers/configuration/entries/general.dm +++ b/code/controllers/configuration/entries/general.dm @@ -308,6 +308,10 @@ max_val = 1 integer = FALSE +/datum/config_entry/number/auto_lag_switch_pop //Number of clients at which drastic lag mitigation measures kick in + config_entry_value = null + min_val = 0 + /datum/config_entry/number/soft_popcap config_entry_value = null min_val = 0 diff --git a/code/controllers/lag_switch.dm b/code/controllers/lag_switch.dm new file mode 100644 index 000000000000..c79db0518601 --- /dev/null +++ b/code/controllers/lag_switch.dm @@ -0,0 +1,146 @@ +/// The subsystem for controlling drastic performance enhancements aimed at reducing server load for a smoother albeit slightly duller gaming experience +SUBSYSTEM_DEF(lag_switch) + name = "Lag Switch" + flags = SS_NO_FIRE + + /// If the lag switch measures should attempt to trigger automatically, TRUE if a config value exists + var/auto_switch = FALSE + /// Amount of connected clients at which the Lag Switch should engage, set via config or admin panel + var/trigger_pop = INFINITY - 1337 + /// List of bools corresponding to code/__DEFINES/lag_switch.dm + var/static/list/measures[MEASURES_AMOUNT] + /// List of measures that toggle automatically + var/list/auto_measures = list(DISABLE_GHOST_ZOOM_TRAY, DISABLE_RUNECHAT, DISABLE_USR_ICON2HTML, DISABLE_PARALLAX, DISABLE_FOOTSTEPS) + /// Timer ID for the automatic veto period + var/veto_timer_id + /// Cooldown between say verb uses when slowmode is enabled + var/slowmode_cooldown = 3 SECONDS + +/datum/controller/subsystem/lag_switch/Initialize() + for(var/i in 1 to measures.len) + measures[i] = FALSE + var/auto_switch_pop = CONFIG_GET(number/auto_lag_switch_pop) + if(auto_switch_pop) + auto_switch = TRUE + trigger_pop = auto_switch_pop + RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT, PROC_REF(client_connected)) + return SS_INIT_SUCCESS + +/datum/controller/subsystem/lag_switch/proc/client_connected(datum/source, client/connected) + SIGNAL_HANDLER + if(TGS_CLIENT_COUNT < trigger_pop) + return + + auto_switch = FALSE + UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT) + veto_timer_id = addtimer(CALLBACK(src, PROC_REF(set_all_measures), TRUE, TRUE), 20 SECONDS, TIMER_STOPPABLE) + message_admins("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds. (CANCEL)") + log_admin("Lag Switch population threshold reached. Automatic activation of lag mitigation measures occuring in 20 seconds.") + +/// (En/Dis)able automatic triggering of switches based on client count +/datum/controller/subsystem/lag_switch/proc/toggle_auto_enable() + auto_switch = !auto_switch + if(auto_switch) + RegisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT, PROC_REF(client_connected)) + else + UnregisterSignal(SSdcs, COMSIG_GLOB_CLIENT_CONNECT) + +/// Called from an admin chat link +/datum/controller/subsystem/lag_switch/proc/cancel_auto_enable_in_progress() + if(!veto_timer_id) + return FALSE + + deltimer(veto_timer_id) + veto_timer_id = null + return TRUE + +/// Update the slowmode timer length and clear existing ones if reduced +/datum/controller/subsystem/lag_switch/proc/change_slowmode_cooldown(length) + if(!length) + return FALSE + + var/length_secs = length SECONDS + if(length_secs <= 0) + length_secs = 1 // one tick because cooldowns do not like 0 + + if(length_secs < slowmode_cooldown) + for(var/client/C as anything in GLOB.clients) + COOLDOWN_RESET(C, say_slowmode) + + slowmode_cooldown = length_secs + if(measures[SLOWMODE_SAY]) + to_chat(world, span_boldannounce("Slowmode timer has been changed to [length] seconds by an admin.")) + return TRUE + +/// Handle the state change for individual measures +/datum/controller/subsystem/lag_switch/proc/set_measure(measure_key, state) + if(isnull(measure_key) || isnull(state)) + stack_trace("SSlag_switch.set_measure() was called with a null arg") + return FALSE + if(isnull(LAZYACCESS(measures, measure_key))) + stack_trace("SSlag_switch.set_measure() was called with a measure_key not in the list of measures") + return FALSE + if(measures[measure_key] == state) + return TRUE + + measures[measure_key] = state + + switch(measure_key) + if(DISABLE_DEAD_KEYLOOP) + if(state) + for(var/mob/user as anything in GLOB.player_list) + if(user.stat == DEAD && !user.client?.holder) + GLOB.keyloop_list -= user + deadchat_broadcast(span_big("To increase performance Observer freelook is now disabled. Please use Orbit, Teleport, and Jump to look around."), message_type = DEADCHAT_ANNOUNCEMENT) + else + GLOB.keyloop_list |= GLOB.player_list + deadchat_broadcast("Observer freelook has been re-enabled. Enjoy your wooshing.", message_type = DEADCHAT_ANNOUNCEMENT) + if(DISABLE_GHOST_ZOOM_TRAY) + if(state) // if enabling make sure current ghosts are updated + for(var/mob/dead/observer/ghost in GLOB.dead_mob_list) + if(!ghost.client) + continue + if(!ghost.client.holder && ghost.client.view_size.getView() != ghost.client.view_size.default) + ghost.client.view_size.resetToDefault() + if(SLOWMODE_SAY) + if(state) + to_chat(world, span_boldannounce("Slowmode for IC/dead chat has been enabled with [slowmode_cooldown/10] seconds between messages.")) + else + for(var/client/C as anything in GLOB.clients) + COOLDOWN_RESET(C, say_slowmode) + to_chat(world, span_boldannounce("Slowmode for IC/dead chat has been disabled by an admin.")) + if(DISABLE_NON_OBSJOBS) + world.update_status() + if(DISABLE_PARALLAX) + if (state) + to_chat(world, span_boldannounce("Parallax has been disabled for performance concerns.")) + else + to_chat(world, span_boldannounce("Parallax has been re-enabled.")) + + for (var/mob/mob as anything in GLOB.mob_list) + mob.hud_used?.update_parallax_pref() + if (DISABLE_FOOTSTEPS) + if (state) + to_chat(world, span_boldannounce("Footstep sounds have been disabled for performance concerns.")) + else + to_chat(world, span_boldannounce("Footstep sounds have been re-enabled.")) + + return TRUE + +/// Helper to loop over all measures for mass changes +/datum/controller/subsystem/lag_switch/proc/set_all_measures(state, automatic = FALSE) + if(isnull(state)) + stack_trace("SSlag_switch.set_all_measures() was called with a null state arg") + return FALSE + + if(automatic) + message_admins("Lag Switch enabling automatic measures now.") + log_admin("Lag Switch enabling automatic measures now.") + veto_timer_id = null + for(var/i in 1 to auto_measures.len) + set_measure(auto_measures[i], state) + return TRUE + + for(var/i in 1 to measures.len) + set_measure(i, state) + return TRUE diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 9f2f57d48c60..c756723308b8 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -1,24 +1,34 @@ +/// Define for the pickweight value where you get no parallax +#define PARALLAX_NONE "parallax_none" + SUBSYSTEM_DEF(parallax) name = "Parallax" wait = 2 - flags = SS_POST_FIRE_TIMING | SS_BACKGROUND + flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT priority = FIRE_PRIORITY_PARALLAX runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun var/planet_x_offset = 128 var/planet_y_offset = 128 - var/random_layer - var/random_parallax_color + /// A random parallax layer that we sent to every player + var/atom/movable/screen/parallax_layer/random/random_layer + /// Weighted list with the parallax layers we could spawn + var/random_parallax_weights = list( + /atom/movable/screen/parallax_layer/random/space_gas = 35, + /atom/movable/screen/parallax_layer/random/asteroids = 35, + PARALLAX_NONE = 30, + ) + +//These are cached per client so needs to be done asap so people joining at roundstart do not miss these. +/datum/controller/subsystem/parallax/PreInit() + . = ..() + + set_random_parallax_layer(pick_weight(random_parallax_weights)) -/datum/controller/subsystem/parallax/Initialize(timeofday) - if(prob(70)) //70% chance to pick a special extra layer - random_layer = pick(/atom/movable/screen/parallax_layer/random/space_gas, /atom/movable/screen/parallax_layer/random/asteroids) - random_parallax_color = pick(COLOR_TEAL, COLOR_GREEN, COLOR_SILVER, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE)//Special color for random_layer1. Has to be done here so everyone sees the same color. planet_y_offset = rand(100, 160) planet_x_offset = rand(100, 160) - return SS_INIT_SUCCESS -/datum/controller/subsystem/parallax/fire(resumed = 0) +/datum/controller/subsystem/parallax/fire(resumed = FALSE) if (!resumed) src.currentrun = GLOB.clients.Copy() @@ -26,24 +36,65 @@ SUBSYSTEM_DEF(parallax) var/list/currentrun = src.currentrun while(length(currentrun)) - var/client/C = currentrun[currentrun.len] + var/client/processing_client = currentrun[currentrun.len] currentrun.len-- - if (!C || !C.eye) + if (QDELETED(processing_client) || !processing_client.eye) if (MC_TICK_CHECK) return continue - var/atom/movable/A = C.eye - if(!istype(A)) + + var/atom/movable/movable_eye = processing_client.eye + if(!istype(movable_eye)) + continue + + while(isloc(movable_eye.loc) && !isturf(movable_eye.loc)) + movable_eye = movable_eye.loc + //get the last movable holding the mobs eye + + if(movable_eye == processing_client.movingmob) + if (MC_TICK_CHECK) + return continue - for (A; isloc(A.loc) && !isturf(A.loc); A = A.loc); - - if(A != C.movingmob) - if(C.movingmob != null) - C.movingmob.client_mobs_in_contents -= C.mob - UNSETEMPTY(C.movingmob.client_mobs_in_contents) - LAZYINITLIST(A.client_mobs_in_contents) - A.client_mobs_in_contents += C.mob - C.movingmob = A + + //eye and the last recorded eye are different, and the last recorded eye isnt just the clients mob + if(!isnull(processing_client.movingmob)) + LAZYREMOVE(processing_client.movingmob.client_mobs_in_contents, processing_client.mob) + LAZYADD(movable_eye.client_mobs_in_contents, processing_client.mob) + + processing_client.movingmob = movable_eye if (MC_TICK_CHECK) return currentrun = null + +/// Generate a random layer for parallax +/datum/controller/subsystem/parallax/proc/set_random_parallax_layer(picked_parallax) + if(picked_parallax == PARALLAX_NONE) + return + + random_layer = new picked_parallax(null, /* hud_owner = */ null, /* template = */ TRUE) + RegisterSignal(random_layer, COMSIG_PARENT_QDELETING, PROC_REF(clear_references)) + random_layer.get_random_look() + +/// Change the random parallax layer after it's already been set. update_player_huds = TRUE will also replace them in the players client images, if it was set +/datum/controller/subsystem/parallax/proc/swap_out_random_parallax_layer(atom/movable/screen/parallax_layer/new_type, update_player_huds = TRUE) + set_random_parallax_layer(new_type) + + if(!update_player_huds) + return + + //Parallax is one of the first things to be set (during client join), so rarely is anything fast enough to swap it out + //That's why we need to swap the layers out for fast joining clients :/ + for(var/client/client as anything in GLOB.clients) + client.parallax_layers_cached?.Cut() + client.mob?.hud_used?.update_parallax_pref(client.mob) + +/datum/controller/subsystem/parallax/proc/clear_references() + SIGNAL_HANDLER + + random_layer = null + +/// Called at the end of SSstation setup, in-case we want to run some code that would otherwise be too early to run (like GLOB. stuff) +/datum/controller/subsystem/parallax/proc/post_station_setup() + random_layer?.apply_global_effects() + +#undef PARALLAX_NONE diff --git a/code/datums/components/connect_mob_behalf.dm b/code/datums/components/connect_mob_behalf.dm new file mode 100644 index 000000000000..1c1a8a652342 --- /dev/null +++ b/code/datums/components/connect_mob_behalf.dm @@ -0,0 +1,59 @@ +/// This component behaves similar to connect_loc_behalf, but working off clients and mobs instead of loc +/// To be clear, we hook into a signal on a tracked client's mob +/// We retain the ability to react to that signal on a seperate listener, which makes this quite powerful +/datum/component/connect_mob_behalf + dupe_mode = COMPONENT_DUPE_UNIQUE + + /// An assoc list of signal -> procpath to register to the mob our client "owns" + var/list/connections + /// The master client we're working with + var/client/tracked + /// The mob we're currently tracking + var/mob/tracked_mob + +/datum/component/connect_mob_behalf/Initialize(client/tracked, list/connections) + . = ..() + if (!istype(tracked)) + return COMPONENT_INCOMPATIBLE + src.connections = connections + src.tracked = tracked + +/datum/component/connect_mob_behalf/RegisterWithParent() + RegisterSignal(tracked, COMSIG_PARENT_QDELETING, PROC_REF(handle_tracked_qdel)) + update_signals() + +/datum/component/connect_mob_behalf/UnregisterFromParent() + unregister_signals() + UnregisterSignal(tracked, COMSIG_PARENT_QDELETING) + + tracked = null + tracked_mob = null + +/datum/component/connect_mob_behalf/proc/handle_tracked_qdel() + SIGNAL_HANDLER + qdel(src) + +/datum/component/connect_mob_behalf/proc/update_signals() + unregister_signals() + // Yes this is a runtime silencer + // We could be in a position where logout is sent to two things, one thing intercepts it, then deletes the client's new mob + // It's rare, and the same check in connect_loc_behalf is more fruitful, but it's still worth doing + if(QDELETED(tracked?.mob)) + return + tracked_mob = tracked.mob + RegisterSignal(tracked_mob, COMSIG_MOB_LOGOUT, PROC_REF(on_logout)) + for (var/signal in connections) + parent.RegisterSignal(tracked_mob, signal, connections[signal]) + +/datum/component/connect_mob_behalf/proc/unregister_signals() + if(isnull(tracked_mob)) + return + + parent.UnregisterSignal(tracked_mob, connections) + UnregisterSignal(tracked_mob, COMSIG_MOB_LOGOUT) + + tracked_mob = null + +/datum/component/connect_mob_behalf/proc/on_logout(mob/source) + SIGNAL_HANDLER + update_signals() diff --git a/code/game/atom_invisibility.dm b/code/game/atom_invisibility.dm new file mode 100644 index 000000000000..53fbe895817c --- /dev/null +++ b/code/game/atom_invisibility.dm @@ -0,0 +1,72 @@ +// Index defines +#define INVISIBILITY_VALUE 1 +#define INVISIBILITY_PRIORITY 2 + +/atom + VAR_PRIVATE/list/invisibility_sources + VAR_PRIVATE/current_invisibility_priority = -INFINITY + +/atom/proc/RecalculateInvisibility() + PRIVATE_PROC(TRUE) + + if(!invisibility_sources) + current_invisibility_priority = -INFINITY + invisibility = initial(invisibility) + return + + var/highest_priority + var/list/highest_priority_invisibility_data + for(var/entry in invisibility_sources) + var/list/priority_data + if(islist(entry)) + priority_data = entry + else + priority_data = invisibility_sources[entry] + + var/priority = priority_data[INVISIBILITY_PRIORITY] + if(highest_priority > priority) // In the case of equal priorities, we use the last thing in the list so that more recent changes apply first + continue + + highest_priority = priority + highest_priority_invisibility_data = priority_data + + current_invisibility_priority = highest_priority + invisibility = highest_priority_invisibility_data[INVISIBILITY_VALUE] + +/** + * Sets invisibility according to priority. + * If you want to be able to undo the value you set back to what it would be otherwise, + * you should provide an id here and remove it using RemoveInvisibility(id) + */ +/atom/proc/SetInvisibility(desired_value, id, priority=0) + if(!invisibility_sources) + invisibility_sources = list() + + if(id) + invisibility_sources[id] = list(desired_value, priority) + else + invisibility_sources += list(list(desired_value, priority)) + + if(current_invisibility_priority > priority) + return + + RecalculateInvisibility() + +/// Removes the specified invisibility source from the tracker +/atom/proc/RemoveInvisibility(id) + if(!invisibility_sources) + return + + var/list/priority_data = invisibility_sources[id] + invisibility_sources -= id + + if(length(invisibility_sources) == 0) + invisibility_sources = null + + if(current_invisibility_priority > priority_data[INVISIBILITY_PRIORITY]) + return + + RecalculateInvisibility() + +#undef INVISIBILITY_VALUE +#undef INVISIBILITY_PRIORITY diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index cb459e0914fc..085995314b2c 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -754,7 +754,7 @@ name = "\proper night vision meson vision" icon = 'icons/obj/clothing/glasses.dmi' icon_state = "nvgmeson" - sight_mode = BORGMESON_NIGHTVISION + sight_mode = BORGMESON /obj/item/borg/sight/material name = "\proper material vision" diff --git a/code/modules/admin/holder2.dm b/code/modules/admin/holder2.dm index 9ae6194dfd44..3ac0b351c7e2 100644 --- a/code/modules/admin/holder2.dm +++ b/code/modules/admin/holder2.dm @@ -23,6 +23,8 @@ GLOBAL_PROTECT(href_token) var/deadmined + var/datum/plane_master_debug/plane_debug + var/ip_cache var/cid_cache diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 9f876156b699..63e68959cfed 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -173,3 +173,23 @@ /// Whether or not this client has the combo HUD enabled var/combo_hud_enabled = FALSE + + var/list/parallax_layers + var/list/parallax_layers_cached + ///Tracks say() usage for ic/dchat while slowmode is enabled + COOLDOWN_DECLARE(say_slowmode) + + ///this is the last recorded client eye by SSparallax/fire() + var/atom/movable/movingmob + var/turf/previous_turf + ///world.time of when we can state animate()ing parallax again + var/dont_animate_parallax + /// Direction our current area wants to move parallax + var/parallax_movedir = 0 + /// How many parallax layers to show our client + var/parallax_layers_max = 4 + /// Timer for the area directional animation + var/parallax_animate_timer + /// Do we want to do parallax animations at all? + /// Exists to prevent laptop fires + var/do_parallax_animations = TRUE diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 1ddb1a1cbc2d..9786155eb104 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -482,52 +482,15 @@ GLOBAL_LIST_INIT(blacklisted_builds, list( ////////////// /client/Del() - //if(credits) - //QDEL_LIST(credits) - log_access("Logout: [key_name(src)]") - if(holder) - adminGreet(1) - holder.owner = null - GLOB.permissions.admins -= src - if (!GLOB.permissions.admins.len && SSticker.IsRoundInProgress()) //Only report this stuff if we are currently playing. - var/cheesy_message = pick( - "I have no admins online!",\ - "I'm all alone :(",\ - "I'm feeling lonely :(",\ - "I'm so lonely :(",\ - "Why does nobody love me? :(",\ - "I want a man :(",\ - "Where has everyone gone?",\ - "I need a hug :(",\ - "Someone come hold me :(",\ - "I need someone on me :(",\ - "What happened? Where has everyone gone?",\ - "Forever alone :("\ - ) - - send2irc("Server", "[cheesy_message] (No admins online)") - qdel(holder) - if(ckey in GLOB.permissions.deadmins) - qdel(GLOB.permissions.deadmins[ckey]) - - GLOB.ahelp_tickets.ClientLogout(src) - GLOB.directory -= ckey - GLOB.clients -= src - - SSambience.remove_ambience_client(src) - - var/datum/connection_log/CL = GLOB.connection_logs[ckey] - if(CL) - CL.logout(mob) - - QDEL_LIST_ASSOC_VAL(char_render_holders) - if(movingmob != null) - movingmob.client_mobs_in_contents -= mob - UNSETEMPTY(movingmob.client_mobs_in_contents) - seen_messages = null - Master.UpdateTickRate() - world.sync_logout_with_db(connection_number) // yogs - logout logging - + if(!gc_destroyed) + gc_destroyed = world.time + if (!QDELING(src)) + stack_trace("Client does not purport to be QDELING, this is going to cause bugs in other places!") + + // Yes this is the same as what's found in qdel(). Yes it does need to be here + // Get off my back + SEND_SIGNAL(src, COMSIG_PARENT_QDELETING, TRUE) + Destroy() //Clean up signals and timers. return ..() /client/proc/set_client_age_from_db(connectiontopic) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 86ab220b480f..36cd6b981425 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -1081,7 +1081,7 @@ sight |= SEE_TURFS lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(5, 15, 5)) - if(sight_mode & BORGMESON_NIGHTVISION) + if(sight_mode & BORGMESON) sight |= SEE_TURFS lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, list(5, 30, 5)) diff --git a/yogstation.dme b/yogstation.dme index cc5e642104a2..36abde8b97e0 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -73,6 +73,7 @@ #include "code\__DEFINES\inventory.dm" #include "code\__DEFINES\is_helpers.dm" #include "code\__DEFINES\jobs.dm" +#include "code\__DEFINES\lag_switch.dm" #include "code\__DEFINES\language.dm" #include "code\__DEFINES\layers.dm" #include "code\__DEFINES\lighting.dm" @@ -151,6 +152,7 @@ #include "code\__DEFINES\dcs\signals\signal_species.dm" #include "code\__DEFINES\dcs\signals\signals_action.dm" #include "code\__DEFINES\dcs\signals\signals_area.dm" +#include "code\__DEFINES\dcs\signals\signals_client.dm" #include "code\__DEFINES\dcs\signals\signals_datum.dm" #include "code\__DEFINES\dcs\signals\signals_food.dm" #include "code\__DEFINES\dcs\signals\signals_gib.dm" @@ -325,6 +327,7 @@ #include "code\_onclick\hud\plane_master_subtypes.dm" #include "code\_onclick\hud\radial.dm" #include "code\_onclick\hud\radial_persistent.dm" +#include "code\_onclick\hud\random_layer.dm" #include "code\_onclick\hud\render_plate.dm" #include "code\_onclick\hud\revenanthud.dm" #include "code\_onclick\hud\robot.dm" @@ -335,6 +338,7 @@ #include "code\controllers\controller.dm" #include "code\controllers\failsafe.dm" #include "code\controllers\globals.dm" +#include "code\controllers\lag_switch.dm" #include "code\controllers\master.dm" #include "code\controllers\subsystem.dm" #include "code\controllers\configuration\config_entry.dm" @@ -519,6 +523,7 @@ #include "code\datums\components\butchering.dm" #include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" +#include "code\datums\components\connect_mob_behalf.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\curse_of_hunger.dm" #include "code\datums\components\decal.dm" @@ -828,6 +833,7 @@ #include "code\datums\wounds\slash.dm" #include "code\datums\wounds\scars\_scars.dm" #include "code\game\alternate_appearance.dm" +#include "code\game\atom_invisibility.dm" #include "code\game\atoms.dm" #include "code\game\atoms_movable.dm" #include "code\game\communications.dm" From d1750eda16f4308a991d5639e65d6b6e58069e7e Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:51:56 -0500 Subject: [PATCH 024/144] adds my stuff back it it'll show up one day --- code/_onclick/hud/parallax.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 506226b41ead..3662882d5dd6 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -15,7 +15,10 @@ C.parallax_layers_cached = list() C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) + if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) + else + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) if(SSparallax.random_layer) C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) From f3d43651f8554a58a37f8e87d3c8e93c564b78c0 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:54:16 -0500 Subject: [PATCH 025/144] this too duh --- code/_onclick/hud/parallax.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 3662882d5dd6..ff43b84ceeb2 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -340,6 +340,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 +/atom/movable/screen/parallax_layer/planet/moonscorch + icon_state = "rheus_moon" + /atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) . = ..() var/client/boss = hud_owner?.mymob?.canon_client From 4c06635a3213f2c43addff3f5d5b9fbc86b5bbdc Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 00:00:07 -0500 Subject: [PATCH 026/144] push it duh --- code/datums/elements/turf_transparency.dm | 2 +- code/modules/antagonists/revenant/revenant.dm | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/code/datums/elements/turf_transparency.dm b/code/datums/elements/turf_transparency.dm index b050dd0866f0..e8312aa4dd2d 100644 --- a/code/datums/elements/turf_transparency.dm +++ b/code/datums/elements/turf_transparency.dm @@ -271,7 +271,7 @@ GLOBAL_LIST_EMPTY(pillars_by_z) if(!ispath(path)) warning("Z-level [our_turf.z] has invalid baseturf '[SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF)]'") path = /turf/open/space - var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, offset_spokesman = our_turf, plane = PLANE_SPACE) + var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = PLANE_SPACE) underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR return underlay_appearance diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm index b5ddf9a469cd..fdd5d2b8690e 100644 --- a/code/modules/antagonists/revenant/revenant.dm +++ b/code/modules/antagonists/revenant/revenant.dm @@ -3,7 +3,6 @@ //Don't hear deadchat and are NOT normal ghosts //Admin-spawn or random event -#define INVISIBILITY_REVENANT 50 #define REVENANT_NAME_FILE "revenant_names.json" /mob/living/simple_animal/revenant From 37fb345a723a90e6f3090f84511b675f3bf0184a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 00:28:56 -0500 Subject: [PATCH 027/144] so close yet so far --- code/_onclick/hud/render_plate.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index ae05da8839a7..d4e5bd9777eb 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -280,7 +280,7 @@ emissive.remove_filter("lighting_mask") // We max alpha here, so our darkness is actually.. dark // Can't do it before cause it fucks with the filter - ///add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) -- this makes the walls pitch black (cant see stuff on them) + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) ///render plate for OOC stuff like ghosts, hud-screen effects, etc /atom/movable/screen/plane_master/rendering_plate/non_game From 603b4e5f3c4e551e61ec4ef6cfc1ef61619ba001 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:19:13 -0500 Subject: [PATCH 028/144] dont ever say its over ahuh --- code/game/turfs/space/space.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 33e4221dbf82..a26e40e09d22 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -44,7 +44,7 @@ GLOBAL_LIST_EMPTY(starlight) /turf/open/space icon = 'icons/turf/space.dmi' - icon_state = "space" + icon_state = "0" name = "\proper space" overfloor_placed = FALSE underfloor_accessibility = UNDERFLOOR_INTERACTABLE @@ -220,7 +220,7 @@ GLOBAL_LIST_EMPTY(starlight) /turf/open/space/openspace icon = 'icons/turf/floors.dmi' - icon_state = MAP_SWITCH("pure_white", "invisible") + icon_state = MAP_SWITCH("pure_white", "transparent") plane = TRANSPARENT_FLOOR_PLANE /turf/open/space/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker From aebff052bf836d3bc963b56522a57a39e2f5d58f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:30:49 -0500 Subject: [PATCH 029/144] adds this back should help --- code/__DEFINES/layers.dm | 1 + code/modules/antagonists/devil/true_devil/inventory.dm | 2 ++ .../mob/living/simple_animal/friendly/drone/visuals_icons.dm | 2 ++ code/modules/mob/living/simple_animal/simple_animal.dm | 2 ++ 4 files changed, 7 insertions(+) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 8bb03d1c38e4..4199d972132c 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -96,6 +96,7 @@ //HUD layer defines #define HUD_PLANE 40 #define ABOVE_HUD_PLANE 41 +#define ABOVE_HUD_LAYER 41 ///Plane of the "splash" icon used that shows on the lobby screen #define SPLASHSCREEN_PLANE 50 diff --git a/code/modules/antagonists/devil/true_devil/inventory.dm b/code/modules/antagonists/devil/true_devil/inventory.dm index 61b09348b1dc..a3d0dbdf582b 100644 --- a/code/modules/antagonists/devil/true_devil/inventory.dm +++ b/code/modules/antagonists/devil/true_devil/inventory.dm @@ -17,6 +17,7 @@ hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand @@ -27,6 +28,7 @@ hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand diff --git a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm index 9400e17ebc50..b6fe86efe0db 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/visuals_icons.dm @@ -35,6 +35,7 @@ hands_overlays += r_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand @@ -47,6 +48,7 @@ hands_overlays += l_hand_overlay if(client && hud_used && hud_used.hud_version != HUD_STYLE_NOHUD) + l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 8d832a895dd1..c4885bec37a1 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -546,10 +546,12 @@ var/obj/item/l_hand = get_item_for_held_index(1) var/obj/item/r_hand = get_item_for_held_index(2) if(r_hand) + r_hand.layer = ABOVE_HUD_LAYER r_hand.plane = ABOVE_HUD_PLANE r_hand.screen_loc = ui_hand_position(get_held_index_of_item(r_hand)) client.screen |= r_hand if(l_hand) + l_hand.layer = ABOVE_HUD_LAYER l_hand.plane = ABOVE_HUD_PLANE l_hand.screen_loc = ui_hand_position(get_held_index_of_item(l_hand)) client.screen |= l_hand From dfd72a901019e3e54e21022e096727fd2aab2cf9 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:55:58 -0500 Subject: [PATCH 030/144] oh yeah fix this idiot --- code/_onclick/hud/hud.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 1cf9e183c40e..ea8ca758d39b 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -463,7 +463,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_slots = list() var/atom/movable/screen/inventory/hand/hand_box for(var/i in 1 to mymob.held_items.len) - hand_box = new /atom/movable/screen/inventory/hand(null, src) + hand_box = new /atom/movable/screen/inventory/hand(src) hand_box.name = mymob.get_held_index_name(i) hand_box.icon = ui_style hand_box.icon_state = "hand_[mymob.held_index_to_dir(i)]" @@ -471,7 +471,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list( hand_box.held_index = i hand_slots["[i]"] = hand_box static_inventory += hand_box - hand_box.update_appearance() + hand_box.update_appearance(UPDATE_ICON) var/i = 1 for(var/atom/movable/screen/swap_hand/SH in static_inventory) From 0339b78d7f7cf1083ba6cfd79171c68e78a5e5e4 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:07:05 -0500 Subject: [PATCH 031/144] yea yea --- _maps/_basemap.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index aadbfa88a035..48b96c8948f7 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" From 252c687197f69dcf9c9aa60e0ea71f1872f3741a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 11:33:07 -0500 Subject: [PATCH 032/144] this bye --- code/__HELPERS/lighting.dm | 6 ++---- code/game/turfs/space/space.dm | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index 96087ba17377..5e5924abc8d2 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -7,10 +7,8 @@ var/alpha_ratio = alpha/255 appearance.color = _EMISSIVE_COLOR(alpha_ratio) - //Test to make sure emissives with broken or missing icon states are created - if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) - if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace - stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") + if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace + stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") return appearance diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index a26e40e09d22..bf74a2df7077 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -225,8 +225,6 @@ GLOBAL_LIST_EMPTY(starlight) /turf/open/space/openspace/Initialize(mapload) // handle plane and layer here so that they don't cover other obs/turfs in Dream Maker . = ..() - if(PERFORM_ALL_TESTS(focus_only/openspace_clear) && !GET_TURF_BELOW(src)) - stack_trace("[src] was inited as openspace with nothing below it at ([x], [y], [z])") icon_state = "pure_white" // We make the assumption that the space plane will never be blacklisted, as an optimization if(SSmapping.max_plane_offset) From 68d3b28c002542f7f0672c8f7fd386c38f1c7389 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:18:30 -0500 Subject: [PATCH 033/144] this is probably important probably --- code/_onclick/hud/random_layer.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/_onclick/hud/random_layer.dm b/code/_onclick/hud/random_layer.dm index 379c0cbe2d9b..2a20889dd0ae 100644 --- a/code/_onclick/hud/random_layer.dm +++ b/code/_onclick/hud/random_layer.dm @@ -24,7 +24,7 @@ /// Gassy background with a few random colors /atom/movable/screen/parallax_layer/random/space_gas - icon_state = "space_gas" + icon_state = "random_layer1" /// The colors we can be var/possible_colors = list(COLOR_TEAL, COLOR_GREEN, COLOR_SILVER, COLOR_YELLOW, COLOR_CYAN, COLOR_ORANGE, COLOR_PURPLE) @@ -48,5 +48,5 @@ /// Big asteroid rocks appear in the background /atom/movable/screen/parallax_layer/random/asteroids - icon_state = "asteroids" + icon_state = "random_layer2" layer = 4 From 6e9bb1085e3ba78d6ec17d8ce7304e078bac76a6 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:41:43 -0500 Subject: [PATCH 034/144] test? lets see --- code/controllers/subsystem/parallax.dm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index c756723308b8..51d2c20bb472 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -19,6 +19,12 @@ SUBSYSTEM_DEF(parallax) PARALLAX_NONE = 30, ) +/datum/controller/subsystem/parallax/Initialize(timeofday) + if(prob(70)) //70% chance to pick a special extra layer + random_layer = pick(/atom/movable/screen/parallax_layer/random/space_gas, /atom/movable/screen/parallax_layer/random/asteroids) + planet_x_offset = rand(100, 160) + return SS_INIT_SUCCESS + //These are cached per client so needs to be done asap so people joining at roundstart do not miss these. /datum/controller/subsystem/parallax/PreInit() . = ..() From d9742b21487f3b91d6c95dc125c94e8a5b69bb39 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:56:09 -0500 Subject: [PATCH 035/144] maybe this will fix it not likely --- code/_onclick/hud/parallax.dm | 6 ++++++ code/_onclick/hud/random_layer.dm | 2 ++ code/controllers/subsystem/parallax.dm | 6 ------ 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index ff43b84ceeb2..1787a783ecd3 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -340,6 +340,12 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 +/atom/movable/screen/parallax_layer/random/space_gas + icon_state = "random_layer1" + +/atom/movable/screen/parallax_layer/random/asteroids + icon_state = "random_layer2" + /atom/movable/screen/parallax_layer/planet/moonscorch icon_state = "rheus_moon" diff --git a/code/_onclick/hud/random_layer.dm b/code/_onclick/hud/random_layer.dm index 2a20889dd0ae..5cab174e04ce 100644 --- a/code/_onclick/hud/random_layer.dm +++ b/code/_onclick/hud/random_layer.dm @@ -4,6 +4,8 @@ speed = 2 layer = 3 +/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) + /atom/movable/screen/parallax_layer/random/Initialize(mapload, datum/hud/hud_owner, template, atom/movable/screen/parallax_layer/random/twin) . = ..() diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 51d2c20bb472..c756723308b8 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -19,12 +19,6 @@ SUBSYSTEM_DEF(parallax) PARALLAX_NONE = 30, ) -/datum/controller/subsystem/parallax/Initialize(timeofday) - if(prob(70)) //70% chance to pick a special extra layer - random_layer = pick(/atom/movable/screen/parallax_layer/random/space_gas, /atom/movable/screen/parallax_layer/random/asteroids) - planet_x_offset = rand(100, 160) - return SS_INIT_SUCCESS - //These are cached per client so needs to be done asap so people joining at roundstart do not miss these. /datum/controller/subsystem/parallax/PreInit() . = ..() From 646ac967d774dcadaadad0aadeccca3b840abab5 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:05:09 -0500 Subject: [PATCH 036/144] update pupdate --- code/_onclick/hud/random_layer.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/_onclick/hud/random_layer.dm b/code/_onclick/hud/random_layer.dm index 5cab174e04ce..2a20889dd0ae 100644 --- a/code/_onclick/hud/random_layer.dm +++ b/code/_onclick/hud/random_layer.dm @@ -4,8 +4,6 @@ speed = 2 layer = 3 -/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) - /atom/movable/screen/parallax_layer/random/Initialize(mapload, datum/hud/hud_owner, template, atom/movable/screen/parallax_layer/random/twin) . = ..() From ae9d21d0b4d9b4d64c044005124e3773ff04f6ab Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:36:47 -0500 Subject: [PATCH 037/144] eee aaa --- code/controllers/subsystem/demo.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/demo.dm b/code/controllers/subsystem/demo.dm index 5296f21dd20c..5b88c20e431d 100644 --- a/code/controllers/subsystem/demo.dm +++ b/code/controllers/subsystem/demo.dm @@ -444,7 +444,7 @@ SUBSYSTEM_DEF(demo) return if(!isobj(M) && !ismob(M)) return - if(M.gc_destroyed) + if(M.gc_destroyed || !M) return marked_new[M] = TRUE if(marked_dirty[M]) From b55e1ac5284078a3eaff507ae66c0909bc5b56dd Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:52:39 -0500 Subject: [PATCH 038/144] round 2 FIGHT --- code/_onclick/hud/parallax.dm | 6 ------ code/controllers/subsystem/demo.dm | 2 +- code/game/atoms.dm | 3 ++- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 1787a783ecd3..ff43b84ceeb2 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -340,12 +340,6 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 -/atom/movable/screen/parallax_layer/random/space_gas - icon_state = "random_layer1" - -/atom/movable/screen/parallax_layer/random/asteroids - icon_state = "random_layer2" - /atom/movable/screen/parallax_layer/planet/moonscorch icon_state = "rheus_moon" diff --git a/code/controllers/subsystem/demo.dm b/code/controllers/subsystem/demo.dm index 5b88c20e431d..0833575471c8 100644 --- a/code/controllers/subsystem/demo.dm +++ b/code/controllers/subsystem/demo.dm @@ -444,7 +444,7 @@ SUBSYSTEM_DEF(demo) return if(!isobj(M) && !ismob(M)) return - if(M.gc_destroyed || !M) + if(M.gc_destroyed || QDELETED(M)) return marked_new[M] = TRUE if(marked_dirty[M]) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 941865b02e93..c4491b248627 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -145,7 +145,6 @@ if(SSatoms.InitAtom(src, args)) //we were deleted return - SSdemo.mark_new(src) /** * The primary method that objects are setup in SS13 with @@ -205,6 +204,8 @@ custom_materials = null //Null the list to prepare for applying the materials properly set_custom_materials(temp_list) + + SSdemo.mark_new(src) return INITIALIZE_HINT_NORMAL From 4bb344d57a4d16bb2c607be9837e14d9c38f1fa2 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:07:03 -0500 Subject: [PATCH 039/144] ok we're back in black --- code/_onclick/hud/parallax.dm | 320 +++++++++++-------------- code/controllers/subsystem/parallax.dm | 1 + code/modules/client/client_defines.dm | 2 + 3 files changed, 142 insertions(+), 181 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index ff43b84ceeb2..3da632374a8e 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -1,27 +1,20 @@ - /datum/hud/proc/create_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client - if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref - for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) - parallax.hide_plane(screenmob) return - for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) - parallax.unhide_plane(screenmob) - if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) else - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) + C.parallax_layers_cached += new SSparallax.random_layer + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) C.parallax_layers = C.parallax_layers_cached.Copy() @@ -29,88 +22,70 @@ C.parallax_layers.len = C.parallax_layers_max C.screen |= (C.parallax_layers) - // We could do not do parallax for anything except the main plane group - // This could be changed, but it would require refactoring this whole thing - // And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :( - for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += plane_master - plane_master.color = list( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 1, 1, 1, 1, - 0, 0, 0, 0 - ) + var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += PM + PM.color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) + /datum/hud/proc/remove_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client C.screen -= (C.parallax_layers_cached) - for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += plane_master - plane_master.color = initial(plane_master.color) + var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += PM + PM.color = initial(PM.color) C.parallax_layers = null /datum/hud/proc/apply_parallax_pref(mob/viewmob) var/mob/screenmob = viewmob || mymob - var/turf/screen_location = get_turf(screenmob) - - if(SSmapping.level_trait(screen_location?.z, ZTRAIT_NOPARALLAX)) - for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) - white_space.hide_plane(screenmob) - return FALSE - - for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) - white_space.unhide_plane(screenmob) - - if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(viewmob, TRAIT_BYPASS_MEASURES)) - return FALSE - var/client/C = screenmob.client - // Default to HIGH - var/parallax_selection = C?.prefs.read_preference(/datum/preference/choiced/parallax) || PARALLAX_HIGH - - switch(parallax_selection) - if (PARALLAX_INSANE) - C.parallax_layers_max = 5 - C.do_parallax_animations = TRUE - return TRUE - - if(PARALLAX_HIGH) - C.parallax_layers_max = 4 - C.do_parallax_animations = TRUE - return TRUE - - if (PARALLAX_MED) - C.parallax_layers_max = 3 - C.do_parallax_animations = TRUE - return TRUE - - if (PARALLAX_LOW) - C.parallax_layers_max = 1 - C.do_parallax_animations = FALSE - return TRUE - - if (PARALLAX_DISABLE) - return FALSE + if(C.prefs) + var/pref = C.prefs.read_preference(/datum/preference/choiced/parallax) + if (isnull(pref)) + pref = PARALLAX_HIGH + switch(pref) + if (PARALLAX_INSANE) + C.parallax_throttle = FALSE + C.parallax_layers_max = 5 + return TRUE + + if (PARALLAX_MED) + C.parallax_throttle = PARALLAX_DELAY_MED + C.parallax_layers_max = 3 + return TRUE + + if (PARALLAX_LOW) + C.parallax_throttle = PARALLAX_DELAY_LOW + C.parallax_layers_max = 1 + return TRUE + + if (PARALLAX_DISABLE) + return FALSE + + //This is high parallax. + C.parallax_throttle = PARALLAX_DELAY_DEFAULT + C.parallax_layers_max = 4 + return TRUE /datum/hud/proc/update_parallax_pref(mob/viewmob) - var/mob/screen_mob = viewmob || mymob - if(!screen_mob.client) - return - remove_parallax(screen_mob) - create_parallax(screen_mob) - update_parallax(screen_mob) + remove_parallax(viewmob) + create_parallax(viewmob) + update_parallax() // This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = 0, skip_windups, mob/viewmob) +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups) . = FALSE - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client + var/client/C = mymob.client if(new_parallax_movedir == C.parallax_movedir) return var/animatedir = new_parallax_movedir @@ -182,25 +157,29 @@ L.transform = newtransform - animate(L, transform = L.transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) + animate(L, transform = L.transform, time = 0 SECONDS, loop = -1, flags = ANIMATION_END_NOW) animate(transform = matrix(), time = T) -/datum/hud/proc/update_parallax(mob/viewmob) - var/mob/screenmob = viewmob || mymob - var/client/C = screenmob.client - var/turf/posobj = get_turf(C.eye) +/datum/hud/proc/update_parallax() + var/client/C = mymob.client + if(!C) + return + var/turf/posobj = get_turf_global(C.eye) // yogs - replace get_turf with get_turf_global if(!posobj) return - var/area/areaobj = posobj.loc + // Update the movement direction of the parallax if necessary (for shuttles) - set_parallax_movedir(areaobj.parallax_movedir, FALSE, screenmob) + set_parallax_movedir(areaobj.parallax_movedir, FALSE) - var/force = FALSE + var/force if(!C.previous_turf || (C.previous_turf.z != posobj.z)) C.previous_turf = posobj force = TRUE + if (!force && world.time < C.last_parallax_shift+C.parallax_throttle) + return + //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. var/offset_x = posobj.x - C.previous_turf.x var/offset_y = posobj.y - C.previous_turf.y @@ -208,105 +187,83 @@ if(!offset_x && !offset_y && !force) return - var/glide_rate = round(world.icon_size / screenmob.glide_size * world.tick_lag, world.tick_lag) + var/last_delay = world.time - C.last_parallax_shift + last_delay = min(last_delay, C.parallax_throttle) C.previous_turf = posobj + C.last_parallax_shift = world.time - var/largest_change = max(abs(offset_x), abs(offset_y)) - var/max_allowed_dist = (glide_rate / world.tick_lag) + 1 - // If we aren't already moving/don't allow parallax, have made some movement, and that movement was smaller then our "glide" size, animate - var/run_parralax = (C.do_parallax_animations && glide_rate && !areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && largest_change <= max_allowed_dist) + for(var/thing in C.parallax_layers) + var/atom/movable/screen/parallax_layer/L = thing + L.update_status(mymob) + if (L.view_sized != C.view) + L.update_o(C.view) - for(var/atom/movable/screen/parallax_layer/parallax_layer as anything in C.parallax_layers) - var/our_speed = parallax_layer.speed var/change_x var/change_y - if(parallax_layer.absolute) - // We use change here so the typically large absolute objects (just lavaland for now) don't jitter so much - change_x = (posobj.x - SSparallax.planet_x_offset) * our_speed + parallax_layer.offset_x - change_y = (posobj.y - SSparallax.planet_y_offset) * our_speed + parallax_layer.offset_y + + if(L.absolute) + L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed + L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed else - change_x = offset_x * our_speed - change_y = offset_y * our_speed - - // This is how we tile parralax sprites - // It doesn't use change because we really don't want to animate this - if(parallax_layer.offset_x - change_x > 240) - parallax_layer.offset_x -= 480 - else if(parallax_layer.offset_x - change_x < -240) - parallax_layer.offset_x += 480 - if(parallax_layer.offset_y - change_y > 240) - parallax_layer.offset_y -= 480 - else if(parallax_layer.offset_y - change_y < -240) - parallax_layer.offset_y += 480 - - // Now that we have our offsets, let's do our positioning - parallax_layer.offset_x -= change_x - parallax_layer.offset_y -= change_y - - parallax_layer.screen_loc = "CENTER-7:[round(parallax_layer.offset_x, 1)],CENTER-7:[round(parallax_layer.offset_y, 1)]" - - // We're going to use a transform to "glide" that last movement out, so it looks nicer - // Don't do any animates if we're not actually moving enough distance yeah? thanks lad - if(run_parralax && (largest_change * our_speed > 1)) - parallax_layer.transform = matrix(1,0,change_x, 0,1,change_y) - animate(parallax_layer, transform=matrix(), time = glide_rate) + change_x = offset_x * L.speed + L.offset_x -= change_x + change_y = offset_y * L.speed + L.offset_y -= change_y -/atom/movable/proc/update_parallax_contents() - for(var/mob/client_mob as anything in client_mobs_in_contents) - if(length(client_mob?.client?.parallax_layers) && client_mob.hud_used) - client_mob.hud_used.update_parallax() + if(L.offset_x > 240) + L.offset_x -= 480 + if(L.offset_x < -240) + L.offset_x += 480 + if(L.offset_y > 240) + L.offset_y -= 480 + if(L.offset_y < -240) + L.offset_y += 480 -/mob/proc/update_parallax_teleport() //used for arrivals shuttle - if(client?.eye && hud_used && length(client.parallax_layers)) + + if(!areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1)) + L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed) + animate(L, transform=matrix(), time = last_delay) + + L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" + +/atom/movable/proc/update_parallax_contents() + if(length(client_mobs_in_contents)) + for(var/thing in client_mobs_in_contents) + var/mob/M = thing + if(M && M.client && M.hud_used && length(M.client.parallax_layers)) + M.hud_used.update_parallax() + +/mob/proc/update_parallax_teleport() //used for arrivals shuttle + if(client && client.eye && hud_used && length(client.parallax_layers)) var/area/areaobj = get_area(client.eye) hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) -// We need parallax to always pass its args down into initialize, so we immediate init it -INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer icon = 'icons/effects/parallax.dmi' var/speed = 1 var/offset_x = 0 var/offset_y = 0 + var/view_sized var/absolute = FALSE blend_mode = BLEND_ADD plane = PLANE_SPACE_PARALLAX screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT -/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE) - . = ..() - // Parallax layers are independant of hud, they care about client - // Not doing this will just create a bunch of hard deletes - hud = null - - if(template) - return - - var/client/boss = hud_owner?.mymob?.canon_client - - if(!boss) // If this typepath all starts to harddel your culprit is likely this - return INITIALIZE_HINT_QDEL - // I do not want to know bestie - var/view = boss.view || world.view +/atom/movable/screen/parallax_layer/Initialize(mapload, view) + . = ..() + if (!view) + view = world.view update_o(view) - RegisterSignal(boss, COMSIG_VIEW_SET, PROC_REF(on_view_change)) - -/atom/movable/screen/parallax_layer/proc/on_view_change(datum/source, new_size) - SIGNAL_HANDLER - update_o(new_size) /atom/movable/screen/parallax_layer/proc/update_o(view) if (!view) view = world.view - var/static/parallax_scaler = world.icon_size / 480 - - // Turn the view size into a grid of correctly scaled overlays var/list/viewscales = getviewsize(view) - var/countx = CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1 - var/county = CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1 + var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 + var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) @@ -317,6 +274,10 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) + view_sized = view + +/atom/movable/screen/parallax_layer/proc/update_status(mob/M) + return /atom/movable/screen/parallax_layer/layer_1 icon_state = "layer1" @@ -333,6 +294,21 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 1.4 layer = 3 +/atom/movable/screen/parallax_layer/random + blend_mode = BLEND_OVERLAY + speed = 3 + layer = 3 + +/atom/movable/screen/parallax_layer/random/space_gas + icon_state = "random_layer1" + +/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) + . = ..() + src.add_atom_colour(SSparallax.random_parallax_color, ADMIN_COLOUR_PRIORITY) + +/atom/movable/screen/parallax_layer/random/asteroids + icon_state = "random_layer2" + /atom/movable/screen/parallax_layer/planet icon_state = "planet" blend_mode = BLEND_OVERLAY @@ -343,30 +319,12 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer/planet/moonscorch icon_state = "rheus_moon" -/atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) - . = ..() - var/client/boss = hud_owner?.mymob?.canon_client - if(!boss) - return - var/static/list/connections = list( - COMSIG_MOVABLE_Z_CHANGED = PROC_REF(on_z_change), - COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout), - ) - AddComponent(/datum/component/connect_mob_behalf, boss, connections) - on_z_change(hud_owner?.mymob) - -/atom/movable/screen/parallax_layer/planet/proc/on_mob_logout(mob/source) - SIGNAL_HANDLER - var/client/boss = source.canon_client - on_z_change(boss.mob) - -/atom/movable/screen/parallax_layer/planet/proc/on_z_change(mob/source) - SIGNAL_HANDLER - var/client/boss = source.client - var/turf/posobj = get_turf(boss?.eye) - if(!posobj) - return - SetInvisibility(is_station_level(posobj.z) ? INVISIBILITY_NONE : INVISIBILITY_ABSTRACT, id=type) +/atom/movable/screen/parallax_layer/planet/update_status(mob/M) + var/turf/T = get_turf(M) + if(is_station_level(T.z)) + invisibility = 0 + else + invisibility = INVISIBILITY_ABSTRACT /atom/movable/screen/parallax_layer/planet/update_o() - return //Shit won't move + return //Shit wont move diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index c756723308b8..f78ee723f072 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -10,6 +10,7 @@ SUBSYSTEM_DEF(parallax) var/list/currentrun var/planet_x_offset = 128 var/planet_y_offset = 128 + var/random_parallax_color /// A random parallax layer that we sent to every player var/atom/movable/screen/parallax_layer/random/random_layer /// Weighted list with the parallax layers we could spawn diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 63e68959cfed..9d7db5e25668 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -193,3 +193,5 @@ /// Do we want to do parallax animations at all? /// Exists to prevent laptop fires var/do_parallax_animations = TRUE + var/parallax_throttle = 0 //ds between updates + var/last_parallax_shift //world.time of last update From 503a1c055953bdecd9221a1a428f369e80ae4119 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:57:59 -0500 Subject: [PATCH 040/144] sunglasses update ok --- code/modules/clothing/glasses/hud.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index b60bfafaa647..a770e77d6439 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -144,7 +144,7 @@ flash_protect = 1 tint = 1 // Red with a tint of green - color_cutoffs = list(35, 5, 5) + color_cutoffs = list(15, 5, 5) glass_colour_type = /datum/client_colour/glass_colour/darkred /obj/item/clothing/glasses/hud/security/sunglasses/hos @@ -157,6 +157,7 @@ desc = "An advanced heads-up display which provides ID data and vision in complete darkness." icon_state = "securityhudnight" flash_protect = -1 + color_cutoffs = list(35, 5, 5) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/security/sunglasses/gars From fb3f40c47f54d5ac309b1091b8054101fa7093ae Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:40:38 -0500 Subject: [PATCH 041/144] ok back to this I guess --- code/_onclick/hud/parallax.dm | 326 +++++++++++++++++++--------------- 1 file changed, 181 insertions(+), 145 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 3da632374a8e..506226b41ead 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -1,20 +1,24 @@ + /datum/hud/proc/create_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client + if (!apply_parallax_pref(viewmob)) //don't want shit computers to crash when specing someone with insane parallax, so use the viewer's pref + for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) + parallax.hide_plane(screenmob) return + for(var/atom/movable/screen/plane_master/parallax as anything in get_true_plane_masters(PLANE_SPACE_PARALLAX)) + parallax.unhide_plane(screenmob) + if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) - if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) - else - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) + C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) C.parallax_layers = C.parallax_layers_cached.Copy() @@ -22,70 +26,88 @@ C.parallax_layers.len = C.parallax_layers_max C.screen |= (C.parallax_layers) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = list( - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 1, 1, 1, 1, - 0, 0, 0, 0 - ) - + // We could do not do parallax for anything except the main plane group + // This could be changed, but it would require refactoring this whole thing + // And adding non client particular hooks for all the inputs, and I do not have the time I'm sorry :( + for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += plane_master + plane_master.color = list( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 1, 1, 1, 1, + 0, 0, 0, 0 + ) /datum/hud/proc/remove_parallax(mob/viewmob) var/mob/screenmob = viewmob || mymob var/client/C = screenmob.client C.screen -= (C.parallax_layers_cached) - var/atom/movable/screen/plane_master/PM = screenmob.hud_used.plane_masters["[PLANE_SPACE]"] - if(screenmob != mymob) - C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen - C.screen += PM - PM.color = initial(PM.color) + for(var/atom/movable/screen/plane_master/plane_master as anything in screenmob.hud_used.get_true_plane_masters(PLANE_SPACE)) + if(screenmob != mymob) + C.screen -= locate(/atom/movable/screen/plane_master/parallax_white) in C.screen + C.screen += plane_master + plane_master.color = initial(plane_master.color) C.parallax_layers = null /datum/hud/proc/apply_parallax_pref(mob/viewmob) var/mob/screenmob = viewmob || mymob + var/turf/screen_location = get_turf(screenmob) + + if(SSmapping.level_trait(screen_location?.z, ZTRAIT_NOPARALLAX)) + for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) + white_space.hide_plane(screenmob) + return FALSE + + for(var/atom/movable/screen/plane_master/white_space as anything in get_true_plane_masters(PLANE_SPACE)) + white_space.unhide_plane(screenmob) + + if (SSlag_switch.measures[DISABLE_PARALLAX] && !HAS_TRAIT(viewmob, TRAIT_BYPASS_MEASURES)) + return FALSE + var/client/C = screenmob.client - if(C.prefs) - var/pref = C.prefs.read_preference(/datum/preference/choiced/parallax) - if (isnull(pref)) - pref = PARALLAX_HIGH - switch(pref) - if (PARALLAX_INSANE) - C.parallax_throttle = FALSE - C.parallax_layers_max = 5 - return TRUE - - if (PARALLAX_MED) - C.parallax_throttle = PARALLAX_DELAY_MED - C.parallax_layers_max = 3 - return TRUE - - if (PARALLAX_LOW) - C.parallax_throttle = PARALLAX_DELAY_LOW - C.parallax_layers_max = 1 - return TRUE - - if (PARALLAX_DISABLE) - return FALSE - - //This is high parallax. - C.parallax_throttle = PARALLAX_DELAY_DEFAULT - C.parallax_layers_max = 4 - return TRUE + // Default to HIGH + var/parallax_selection = C?.prefs.read_preference(/datum/preference/choiced/parallax) || PARALLAX_HIGH + + switch(parallax_selection) + if (PARALLAX_INSANE) + C.parallax_layers_max = 5 + C.do_parallax_animations = TRUE + return TRUE + + if(PARALLAX_HIGH) + C.parallax_layers_max = 4 + C.do_parallax_animations = TRUE + return TRUE + + if (PARALLAX_MED) + C.parallax_layers_max = 3 + C.do_parallax_animations = TRUE + return TRUE + + if (PARALLAX_LOW) + C.parallax_layers_max = 1 + C.do_parallax_animations = FALSE + return TRUE + + if (PARALLAX_DISABLE) + return FALSE /datum/hud/proc/update_parallax_pref(mob/viewmob) - remove_parallax(viewmob) - create_parallax(viewmob) - update_parallax() + var/mob/screen_mob = viewmob || mymob + if(!screen_mob.client) + return + remove_parallax(screen_mob) + create_parallax(screen_mob) + update_parallax(screen_mob) // This sets which way the current shuttle is moving (returns true if the shuttle has stopped moving so the caller can append their animation) -/datum/hud/proc/set_parallax_movedir(new_parallax_movedir, skip_windups) +/datum/hud/proc/set_parallax_movedir(new_parallax_movedir = 0, skip_windups, mob/viewmob) . = FALSE - var/client/C = mymob.client + var/mob/screenmob = viewmob || mymob + var/client/C = screenmob.client if(new_parallax_movedir == C.parallax_movedir) return var/animatedir = new_parallax_movedir @@ -157,29 +179,25 @@ L.transform = newtransform - animate(L, transform = L.transform, time = 0 SECONDS, loop = -1, flags = ANIMATION_END_NOW) + animate(L, transform = L.transform, time = 0, loop = -1, flags = ANIMATION_END_NOW) animate(transform = matrix(), time = T) -/datum/hud/proc/update_parallax() - var/client/C = mymob.client - if(!C) - return - var/turf/posobj = get_turf_global(C.eye) // yogs - replace get_turf with get_turf_global +/datum/hud/proc/update_parallax(mob/viewmob) + var/mob/screenmob = viewmob || mymob + var/client/C = screenmob.client + var/turf/posobj = get_turf(C.eye) if(!posobj) return - var/area/areaobj = posobj.loc + var/area/areaobj = posobj.loc // Update the movement direction of the parallax if necessary (for shuttles) - set_parallax_movedir(areaobj.parallax_movedir, FALSE) + set_parallax_movedir(areaobj.parallax_movedir, FALSE, screenmob) - var/force + var/force = FALSE if(!C.previous_turf || (C.previous_turf.z != posobj.z)) C.previous_turf = posobj force = TRUE - if (!force && world.time < C.last_parallax_shift+C.parallax_throttle) - return - //Doing it this way prevents parallax layers from "jumping" when you change Z-Levels. var/offset_x = posobj.x - C.previous_turf.x var/offset_y = posobj.y - C.previous_turf.y @@ -187,83 +205,105 @@ if(!offset_x && !offset_y && !force) return - var/last_delay = world.time - C.last_parallax_shift - last_delay = min(last_delay, C.parallax_throttle) + var/glide_rate = round(world.icon_size / screenmob.glide_size * world.tick_lag, world.tick_lag) C.previous_turf = posobj - C.last_parallax_shift = world.time - for(var/thing in C.parallax_layers) - var/atom/movable/screen/parallax_layer/L = thing - L.update_status(mymob) - if (L.view_sized != C.view) - L.update_o(C.view) + var/largest_change = max(abs(offset_x), abs(offset_y)) + var/max_allowed_dist = (glide_rate / world.tick_lag) + 1 + // If we aren't already moving/don't allow parallax, have made some movement, and that movement was smaller then our "glide" size, animate + var/run_parralax = (C.do_parallax_animations && glide_rate && !areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && largest_change <= max_allowed_dist) + for(var/atom/movable/screen/parallax_layer/parallax_layer as anything in C.parallax_layers) + var/our_speed = parallax_layer.speed var/change_x var/change_y - - if(L.absolute) - L.offset_x = -(posobj.x - SSparallax.planet_x_offset) * L.speed - L.offset_y = -(posobj.y - SSparallax.planet_y_offset) * L.speed + if(parallax_layer.absolute) + // We use change here so the typically large absolute objects (just lavaland for now) don't jitter so much + change_x = (posobj.x - SSparallax.planet_x_offset) * our_speed + parallax_layer.offset_x + change_y = (posobj.y - SSparallax.planet_y_offset) * our_speed + parallax_layer.offset_y else - change_x = offset_x * L.speed - L.offset_x -= change_x - change_y = offset_y * L.speed - L.offset_y -= change_y - - if(L.offset_x > 240) - L.offset_x -= 480 - if(L.offset_x < -240) - L.offset_x += 480 - if(L.offset_y > 240) - L.offset_y -= 480 - if(L.offset_y < -240) - L.offset_y += 480 - - - if(!areaobj.parallax_movedir && C.dont_animate_parallax <= world.time && (offset_x || offset_y) && abs(offset_x) <= max(C.parallax_throttle/world.tick_lag+1,1) && abs(offset_y) <= max(C.parallax_throttle/world.tick_lag+1,1) && (round(abs(change_x)) > 1 || round(abs(change_y)) > 1)) - L.transform = matrix(1, 0, offset_x*L.speed, 0, 1, offset_y*L.speed) - animate(L, transform=matrix(), time = last_delay) - - L.screen_loc = "CENTER-7:[round(L.offset_x,1)],CENTER-7:[round(L.offset_y,1)]" + change_x = offset_x * our_speed + change_y = offset_y * our_speed + + // This is how we tile parralax sprites + // It doesn't use change because we really don't want to animate this + if(parallax_layer.offset_x - change_x > 240) + parallax_layer.offset_x -= 480 + else if(parallax_layer.offset_x - change_x < -240) + parallax_layer.offset_x += 480 + if(parallax_layer.offset_y - change_y > 240) + parallax_layer.offset_y -= 480 + else if(parallax_layer.offset_y - change_y < -240) + parallax_layer.offset_y += 480 + + // Now that we have our offsets, let's do our positioning + parallax_layer.offset_x -= change_x + parallax_layer.offset_y -= change_y + + parallax_layer.screen_loc = "CENTER-7:[round(parallax_layer.offset_x, 1)],CENTER-7:[round(parallax_layer.offset_y, 1)]" + + // We're going to use a transform to "glide" that last movement out, so it looks nicer + // Don't do any animates if we're not actually moving enough distance yeah? thanks lad + if(run_parralax && (largest_change * our_speed > 1)) + parallax_layer.transform = matrix(1,0,change_x, 0,1,change_y) + animate(parallax_layer, transform=matrix(), time = glide_rate) /atom/movable/proc/update_parallax_contents() - if(length(client_mobs_in_contents)) - for(var/thing in client_mobs_in_contents) - var/mob/M = thing - if(M && M.client && M.hud_used && length(M.client.parallax_layers)) - M.hud_used.update_parallax() - -/mob/proc/update_parallax_teleport() //used for arrivals shuttle - if(client && client.eye && hud_used && length(client.parallax_layers)) + for(var/mob/client_mob as anything in client_mobs_in_contents) + if(length(client_mob?.client?.parallax_layers) && client_mob.hud_used) + client_mob.hud_used.update_parallax() + +/mob/proc/update_parallax_teleport() //used for arrivals shuttle + if(client?.eye && hud_used && length(client.parallax_layers)) var/area/areaobj = get_area(client.eye) hud_used.set_parallax_movedir(areaobj.parallax_movedir, TRUE) +// We need parallax to always pass its args down into initialize, so we immediate init it +INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) /atom/movable/screen/parallax_layer icon = 'icons/effects/parallax.dmi' var/speed = 1 var/offset_x = 0 var/offset_y = 0 - var/view_sized var/absolute = FALSE blend_mode = BLEND_ADD plane = PLANE_SPACE_PARALLAX screen_loc = "CENTER-7,CENTER-7" mouse_opacity = MOUSE_OPACITY_TRANSPARENT - -/atom/movable/screen/parallax_layer/Initialize(mapload, view) +/atom/movable/screen/parallax_layer/Initialize(mapload, datum/hud/hud_owner, template = FALSE) . = ..() - if (!view) - view = world.view + // Parallax layers are independant of hud, they care about client + // Not doing this will just create a bunch of hard deletes + hud = null + + if(template) + return + + var/client/boss = hud_owner?.mymob?.canon_client + + if(!boss) // If this typepath all starts to harddel your culprit is likely this + return INITIALIZE_HINT_QDEL + + // I do not want to know bestie + var/view = boss.view || world.view update_o(view) + RegisterSignal(boss, COMSIG_VIEW_SET, PROC_REF(on_view_change)) + +/atom/movable/screen/parallax_layer/proc/on_view_change(datum/source, new_size) + SIGNAL_HANDLER + update_o(new_size) /atom/movable/screen/parallax_layer/proc/update_o(view) if (!view) view = world.view + var/static/parallax_scaler = world.icon_size / 480 + + // Turn the view size into a grid of correctly scaled overlays var/list/viewscales = getviewsize(view) - var/countx = CEILING((viewscales[1]/2)/(480/world.icon_size), 1)+1 - var/county = CEILING((viewscales[2]/2)/(480/world.icon_size), 1)+1 + var/countx = CEILING((viewscales[1] / 2) * parallax_scaler, 1) + 1 + var/county = CEILING((viewscales[2] / 2) * parallax_scaler, 1) + 1 var/list/new_overlays = new for(var/x in -countx to countx) for(var/y in -county to county) @@ -274,10 +314,6 @@ new_overlays += texture_overlay cut_overlays() add_overlay(new_overlays) - view_sized = view - -/atom/movable/screen/parallax_layer/proc/update_status(mob/M) - return /atom/movable/screen/parallax_layer/layer_1 icon_state = "layer1" @@ -294,21 +330,6 @@ speed = 1.4 layer = 3 -/atom/movable/screen/parallax_layer/random - blend_mode = BLEND_OVERLAY - speed = 3 - layer = 3 - -/atom/movable/screen/parallax_layer/random/space_gas - icon_state = "random_layer1" - -/atom/movable/screen/parallax_layer/random/space_gas/Initialize(mapload, view) - . = ..() - src.add_atom_colour(SSparallax.random_parallax_color, ADMIN_COLOUR_PRIORITY) - -/atom/movable/screen/parallax_layer/random/asteroids - icon_state = "random_layer2" - /atom/movable/screen/parallax_layer/planet icon_state = "planet" blend_mode = BLEND_OVERLAY @@ -316,15 +337,30 @@ speed = 3 layer = 30 -/atom/movable/screen/parallax_layer/planet/moonscorch - icon_state = "rheus_moon" - -/atom/movable/screen/parallax_layer/planet/update_status(mob/M) - var/turf/T = get_turf(M) - if(is_station_level(T.z)) - invisibility = 0 - else - invisibility = INVISIBILITY_ABSTRACT +/atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) + . = ..() + var/client/boss = hud_owner?.mymob?.canon_client + if(!boss) + return + var/static/list/connections = list( + COMSIG_MOVABLE_Z_CHANGED = PROC_REF(on_z_change), + COMSIG_MOB_LOGOUT = PROC_REF(on_mob_logout), + ) + AddComponent(/datum/component/connect_mob_behalf, boss, connections) + on_z_change(hud_owner?.mymob) + +/atom/movable/screen/parallax_layer/planet/proc/on_mob_logout(mob/source) + SIGNAL_HANDLER + var/client/boss = source.canon_client + on_z_change(boss.mob) + +/atom/movable/screen/parallax_layer/planet/proc/on_z_change(mob/source) + SIGNAL_HANDLER + var/client/boss = source.client + var/turf/posobj = get_turf(boss?.eye) + if(!posobj) + return + SetInvisibility(is_station_level(posobj.z) ? INVISIBILITY_NONE : INVISIBILITY_ABSTRACT, id=type) /atom/movable/screen/parallax_layer/planet/update_o() - return //Shit wont move + return //Shit won't move From 9aa9b4403b1d74cf5df0b5ffe8f8ec265c587000 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:42:54 -0500 Subject: [PATCH 042/144] oops forgot this :) --- code/_onclick/hud/parallax.dm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 506226b41ead..069d6971e762 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -13,12 +13,15 @@ if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) + if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) + else + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) + C.parallax_layers_cached += new SSparallax.random_layer + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) C.parallax_layers = C.parallax_layers_cached.Copy() @@ -337,6 +340,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 +/atom/movable/screen/parallax_layer/planet/moonscorch + icon_state = "rheus_moon" + /atom/movable/screen/parallax_layer/planet/Initialize(mapload, datum/hud/hud_owner) . = ..() var/client/boss = hud_owner?.mymob?.canon_client From e50bf9b25ed7fdfee21fcf2b80f367328c29c255 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:53:19 -0500 Subject: [PATCH 043/144] test test --- code/controllers/subsystem/parallax.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index f78ee723f072..aed4b5c1c3d2 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -16,7 +16,7 @@ SUBSYSTEM_DEF(parallax) /// Weighted list with the parallax layers we could spawn var/random_parallax_weights = list( /atom/movable/screen/parallax_layer/random/space_gas = 35, - /atom/movable/screen/parallax_layer/random/asteroids = 35, + // /atom/movable/screen/parallax_layer/random/asteroids = 35, PARALLAX_NONE = 30, ) From c395bc0ba82c30031db5cd6aefb5e6c0df43a913 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 16:52:22 -0500 Subject: [PATCH 044/144] yea yea --- code/_onclick/hud/parallax.dm | 12 ++++++------ code/controllers/subsystem/parallax.dm | 3 +-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 069d6971e762..3643d7848834 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -13,15 +13,15 @@ if(!length(C.parallax_layers_cached)) C.parallax_layers_cached = list() - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, C.view) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, src) else - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) if(SSparallax.random_layer) - C.parallax_layers_cached += new SSparallax.random_layer - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, C.view) + C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) C.parallax_layers = C.parallax_layers_cached.Copy() diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index aed4b5c1c3d2..d412900c9433 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -10,13 +10,12 @@ SUBSYSTEM_DEF(parallax) var/list/currentrun var/planet_x_offset = 128 var/planet_y_offset = 128 - var/random_parallax_color /// A random parallax layer that we sent to every player var/atom/movable/screen/parallax_layer/random/random_layer /// Weighted list with the parallax layers we could spawn var/random_parallax_weights = list( /atom/movable/screen/parallax_layer/random/space_gas = 35, - // /atom/movable/screen/parallax_layer/random/asteroids = 35, + ///atom/movable/screen/parallax_layer/random/asteroids = 35, PARALLAX_NONE = 30, ) From a13da223bd8a887fe8e3eff421f681fcb07713f8 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:10:54 -0500 Subject: [PATCH 045/144] peko pain pain peko --- code/game/turfs/space/space.dm | 1 - code/modules/atmospherics/environmental/LINDA_turf_tile.dm | 2 -- code/modules/mob/living/ventcrawling.dm | 1 + 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index bf74a2df7077..5e7fa31c7a9d 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -61,7 +61,6 @@ GLOBAL_LIST_EMPTY(starlight) var/static/datum/gas_mixture/immutable/space/space_gas = new // We do NOT want atmos adjacent turfs init_air = FALSE - run_later = TRUE plane = PLANE_SPACE layer = SPACE_LAYER light_power = 1 diff --git a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm index 7db5896f21d8..1fd2e701d888 100644 --- a/code/modules/atmospherics/environmental/LINDA_turf_tile.dm +++ b/code/modules/atmospherics/environmental/LINDA_turf_tile.dm @@ -33,8 +33,6 @@ var/list/atmos_overlay_types //gas IDs of current active gas overlays is_openturf = TRUE - /// exists so things like space can ask to take 100% of a tile's gas - var/run_later = FALSE /turf/open/Initialize(mapload) if(!blocks_air) diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm index 4eebe8f0b7e4..33e5cc3d4d90 100644 --- a/code/modules/mob/living/ventcrawling.dm +++ b/code/modules/mob/living/ventcrawling.dm @@ -107,6 +107,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list( var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type. if(in_view_range(client.mob, A)) if(!A.pipe_vision_img) + A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir) A.pipe_vision_img.plane = ABOVE_HUD_PLANE client.images += A.pipe_vision_img pipes_shown += A.pipe_vision_img From c2597e2f59ab44d7ab0238dad501de8baec2cde4 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 16:44:03 -0600 Subject: [PATCH 046/144] Update gas_mixture.dm --- code/modules/atmospherics/gasmixtures/gas_mixture.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 991907fbd814..7bb79aac5347 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -374,7 +374,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() //math is under the assumption temperatures are equal var/self_moles = get_moles(gas_id) var/other_moles = other.get_moles(gas_id) - if(abs(self_moles / return_volume() - other_moles / other.return_volume()) > min_p_delta / (R_IDEAL_GAS_EQUATION * return_temperature())) + if(abs(self_moles / max(return_volume(), 0.000001) - other_moles / max(other.return_volume()), 0.000001) > min_p_delta / max(R_IDEAL_GAS_EQUATION * return_temperature(), 0.00001)) . = TRUE var/total_moles = self_moles + other_moles set_moles(gas_id, total_moles * (return_volume() / total_volume)) From 8032d26bbc306588000a6025e9d4a7c3551126f8 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 17:05:20 -0600 Subject: [PATCH 047/144] Update gas_mixture.dm --- code/modules/atmospherics/gasmixtures/gas_mixture.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 7bb79aac5347..9902736b9d70 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -374,7 +374,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() //math is under the assumption temperatures are equal var/self_moles = get_moles(gas_id) var/other_moles = other.get_moles(gas_id) - if(abs(self_moles / max(return_volume(), 0.000001) - other_moles / max(other.return_volume()), 0.000001) > min_p_delta / max(R_IDEAL_GAS_EQUATION * return_temperature(), 0.00001)) + if(abs(self_moles / max(return_volume(), 0.000001) - other_moles / max(other.return_volume(), 0.000001)) > min_p_delta / max(R_IDEAL_GAS_EQUATION * return_temperature(), 0.00001)) . = TRUE var/total_moles = self_moles + other_moles set_moles(gas_id, total_moles * (return_volume() / total_volume)) From 65a993824ad7b0a4b83b27a8224bc1d8a9ebe6b8 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 17:17:29 -0600 Subject: [PATCH 048/144] Update gas_mixture.dm --- code/modules/atmospherics/gasmixtures/gas_mixture.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 9902736b9d70..20d89a4717d9 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -374,6 +374,8 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() //math is under the assumption temperatures are equal var/self_moles = get_moles(gas_id) var/other_moles = other.get_moles(gas_id) + + //i apologize for this terrible change, i added a bunch of max() procs because they were often dividing by 0 and causing errors if(abs(self_moles / max(return_volume(), 0.000001) - other_moles / max(other.return_volume(), 0.000001)) > min_p_delta / max(R_IDEAL_GAS_EQUATION * return_temperature(), 0.00001)) . = TRUE var/total_moles = self_moles + other_moles From 12cb28518e1f1894ba82037205cd875121156204 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:23:27 -0500 Subject: [PATCH 049/144] yea yeah --- code/game/turfs/space/space.dm | 8 +++++++- code/modules/atmospherics/gasmixtures/gas_mixture.dm | 3 +-- .../machinery/components/unary_devices/passive_vent.dm | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 5e7fa31c7a9d..57421fd4e461 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -52,18 +52,24 @@ GLOBAL_LIST_EMPTY(starlight) temperature = TCMB thermal_conductivity = OPEN_HEAT_TRANSFER_COEFFICIENT heat_capacity = 700000 + + FASTDMM_PROP(\ + pipe_astar_cost = 3\ + ) + var/starlight_source_count = 0 var/destination_z var/destination_x var/destination_y - var/static/datum/gas_mixture/immutable/space/space_gas = new + var/global/datum/gas_mixture/immutable/space/space_gas = new // We do NOT want atmos adjacent turfs init_air = FALSE plane = PLANE_SPACE layer = SPACE_LAYER light_power = 1 + dynamic_lighting = DYNAMIC_LIGHTING_DISABLED light_range = 2 light_color = COLOR_STARLIGHT light_height = LIGHTING_HEIGHT_SPACE diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index 20d89a4717d9..60e60dea8d6e 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -375,8 +375,7 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() var/self_moles = get_moles(gas_id) var/other_moles = other.get_moles(gas_id) - //i apologize for this terrible change, i added a bunch of max() procs because they were often dividing by 0 and causing errors - if(abs(self_moles / max(return_volume(), 0.000001) - other_moles / max(other.return_volume(), 0.000001)) > min_p_delta / max(R_IDEAL_GAS_EQUATION * return_temperature(), 0.00001)) + if(abs(self_moles / return_volume() - other_moles / other.return_volume()) > min_p_delta / (R_IDEAL_GAS_EQUATION * return_temperature())) . = TRUE var/total_moles = self_moles + other_moles set_moles(gas_id, total_moles * (return_volume() / total_volume)) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm index b511f3ff624a..cb66af8e5bba 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/passive_vent.dm @@ -24,6 +24,9 @@ var/datum/gas_mixture/external = location.return_air() var/datum/gas_mixture/internal = airs[1] + // if(!internal.return_temperature()) //temp fix + // return + if(internal.equalize(external)) air_update_turf() update_parents() From 549a0bc12faa0f01ab31aca78bcb952195b9ad8a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:31:25 -0500 Subject: [PATCH 050/144] Why did you remove this I am such a moron --- code/game/turfs/space/space.dm | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index 57421fd4e461..d514dd123c34 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -85,6 +85,35 @@ GLOBAL_LIST_EMPTY(starlight) //This is used to optimize the map loader return +/turf/open/space/Initialize(mapload) + SHOULD_CALL_PARENT(FALSE) + icon_state = SPACE_ICON_STATE + air = space_gas + update_air_ref() + vis_contents.Cut() //removes inherited overlays + visibilityChanged() + + if (PERFORM_ALL_TESTS(focus_only/multiple_space_initialization)) + if(flags_1 & INITIALIZED_1) + stack_trace("Warning: [src]([type]) initialized multiple times!") + flags_1 |= INITIALIZED_1 + + var/area/A = loc + if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) + add_overlay(/obj/effect/fullbright) + + if(requires_activation) + SSair.add_to_active(src) + + if (light_system == STATIC_LIGHT && light_power && light_range) + update_light() + + if (opacity) + directional_opacity = ALL_CARDINALS + + return INITIALIZE_HINT_NORMAL + + /turf/open/space/Destroy() GLOB.starlight -= src return ..() @@ -95,6 +124,9 @@ GLOBAL_LIST_EMPTY(starlight) var/turf/T = locate(destination_x, destination_y, destination_z) user.forceMove(T) +/turf/open/space/Initalize_Atmos(times_fired) + return + /turf/open/space/TakeTemperature(temp) /turf/open/space/RemoveLattice() From 4f82e9361a25627f87f422c06e60648498e7c7ff Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 19:38:15 -0500 Subject: [PATCH 051/144] should fix this yeah --- .../machinery/components/unary_devices/vent_pump.dm | 2 ++ .../machinery/components/unary_devices/vent_scrubber.dm | 2 ++ code/modules/spells/spell_types/jaunt/wirecrawl.dm | 2 ++ 3 files changed, 6 insertions(+) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 643b0a0f25f8..bc6b484c6dd2 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -316,6 +316,7 @@ user.visible_message("[user] unwelded the vent.", span_notice("You unweld the vent."), span_italics("You hear welding.")) welded = FALSE update_appearance(UPDATE_ICON) + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE investigate_log("was [welded ? "welded shut" : "unwelded"] by [key_name(user)]", INVESTIGATE_ATMOS) add_fingerprint(user) @@ -345,6 +346,7 @@ user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the vent", "You hear loud scraping noises.") welded = FALSE update_appearance(UPDATE_ICON) + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index c9e777161718..2729cb4f456a 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -262,6 +262,7 @@ user.visible_message("[user] unwelds the scrubber.", "You unweld the scrubber.", "You hear welding.") welded = FALSE update_appearance(UPDATE_ICON) + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE investigate_log("was [welded ? "welded shut" : "unwelded"] by [key_name(user)]", INVESTIGATE_ATMOS) add_fingerprint(user) @@ -287,6 +288,7 @@ user.visible_message("[user] furiously claws at [src]!", "You manage to clear away the stuff blocking the scrubber.", "You hear loud scraping noises.") welded = FALSE update_appearance(UPDATE_ICON) + pipe_vision_img = image(src, loc, layer = ABOVE_HUD_LAYER, dir = dir) pipe_vision_img.plane = ABOVE_HUD_PLANE playsound(loc, 'sound/weapons/bladeslice.ogg', 100, 1) diff --git a/code/modules/spells/spell_types/jaunt/wirecrawl.dm b/code/modules/spells/spell_types/jaunt/wirecrawl.dm index d05bebe338b7..a1829b04dbf6 100644 --- a/code/modules/spells/spell_types/jaunt/wirecrawl.dm +++ b/code/modules/spells/spell_types/jaunt/wirecrawl.dm @@ -221,6 +221,7 @@ if(istype(object, /obj/structure/cable)) var/obj/structure/cable/display = object if(!display.wire_vision_img) + display.wire_vision_img = image(display, display.loc, layer = ABOVE_HUD_LAYER, dir = display.dir) display.wire_vision_img.plane = ABOVE_HUD_PLANE client.images += display.wire_vision_img wires_shown += display.wire_vision_img @@ -228,6 +229,7 @@ else if(istype(object, /obj/machinery/power)) var/obj/machinery/power/display = object if(!display.wire_vision_img) + display.wire_vision_img = image(display, display.loc, layer = ABOVE_HUD_LAYER, dir = display.dir) display.wire_vision_img.plane = ABOVE_HUD_PLANE client.images += display.wire_vision_img wires_shown += display.wire_vision_img From 676f127ab829ff29906a38c118a9723e8633b8fb Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 30 Nov 2023 20:07:09 -0500 Subject: [PATCH 052/144] adjustments then we open it up --- code/modules/clothing/glasses/hud.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index a770e77d6439..ddb8f96210ce 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -45,7 +45,7 @@ item_state = "glasses" flash_protect = -1 // Blue green, dark - color_cutoffs = list(5, 15, 30) + color_cutoffs = list(5, 10, 30) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/health/meson @@ -54,6 +54,8 @@ icon_state = "mesonhealth" item_state = "mesonhealth" vision_flags = SEE_TURFS + // Mesons get to be lightly green + color_cutoffs = list(5, 5, 15) clothing_traits = list(TRAIT_MESONS) glass_colour_type = /datum/client_colour/glass_colour/lightblue From 06a5788a1f45db90b9492f9a659eafe3a60ab847 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 20:53:21 -0600 Subject: [PATCH 053/144] eyes --- code/modules/surgery/organs/eyes.dm | 3 ++ .../human/species_types/preternis/organs.dm | 35 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 64fccd134caa..a04f105036a0 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -169,15 +169,18 @@ name = "alien eyes" desc = "It turned out they had them after all!" sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) /obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) /obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" + color_cutoffs = list(20, 10, 40) /obj/item/organ/eyes/night_vision/mushroom name = "fung-eye" diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 037da0f9230a..a3e2334b168d 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -1,7 +1,6 @@ #define NIGHTVISION_LIGHT_OFF 0 #define NIGHTVISION_LIGHT_LOW 1 -#define NIGHTVISION_LIGHT_MID 2 -#define NIGHTVISION_LIGHT_HIG 3 +#define NIGHTVISION_LIGHT_HIGH 2 /obj/item/organ/eyes/robotic/preternis name = "preternis eyes" @@ -17,14 +16,11 @@ now_fixed = span_info("Lines of text scroll in your vision as your eyes begin rebooting.") high_threshold_cleared = span_info("Your Preternis eyes have recharged enough to re-enable most functionality.") low_threshold_cleared = span_info("Your Preternis eyes have almost fully recharged.") - var/powered = TRUE actions_types = list(/datum/action/item_action/organ_action/use) - var/night_vision = TRUE + var/powered = TRUE // These lists are used as the color cutoff for the eye - // They need to be filled out for subtypes - var/list/low_light_cutoff - var/list/medium_light_cutoff - var/list/high_light_cutoff + var/list/low_light_cutoff = list(5, 20, 10) + var/list/high_light_cutoff = list(10, 30, 20) var/light_level = NIGHTVISION_LIGHT_OFF @@ -40,11 +36,8 @@ color_cutoffs = low_light_cutoff.Copy() light_level = NIGHTVISION_LIGHT_LOW if (NIGHTVISION_LIGHT_LOW) - color_cutoffs = medium_light_cutoff.Copy() - light_level = NIGHTVISION_LIGHT_MID - if (NIGHTVISION_LIGHT_MID) color_cutoffs = high_light_cutoff.Copy() - light_level = NIGHTVISION_LIGHT_HIG + light_level = NIGHTVISION_LIGHT_HIGH else color_cutoffs = list() light_level = NIGHTVISION_LIGHT_OFF @@ -67,12 +60,6 @@ //to simulate running out of power, they take damage owner.adjustOrganLoss(ORGAN_SLOT_EYES,0.5) -#undef NIGHTVISION_LIGHT_OFF -#undef NIGHTVISION_LIGHT_LOW -#undef NIGHTVISION_LIGHT_MID -#undef NIGHTVISION_LIGHT_HIG - - /obj/item/organ/eyes/robotic/preternis/examine(mob/user) . = ..() if(status == ORGAN_ROBOTIC && (organ_flags & ORGAN_FAILING)) @@ -84,6 +71,13 @@ else if(damage > high_threshold) . += span_warning("[src] seem to flicker on and off. They must be pretty low on charge without being in a Preternis") +#undef NIGHTVISION_LIGHT_OFF +#undef NIGHTVISION_LIGHT_LOW +#undef NIGHTVISION_LIGHT_HIGH + +/////////////////////////////////////////////////////////// +//----------------------Preternis Lungs------------------// +/////////////////////////////////////////////////////////// /obj/item/organ/lungs/preternis name = "preternis lungs" desc = "A specialized set of lungs. Due to the cybernetic nature of these lungs, they are far less resistant to cold but are more heat resistant and more efficent at filtering oxygen." @@ -107,7 +101,10 @@ heat_level_2_damage = 7 heat_level_3_threshold = 35000 //are you on the fucking surface of the sun or something? heat_level_3_damage = 25 //you should already be dead - + +/////////////////////////////////////////////////////////// +//---------------------Preternis Stomach-----------------// +/////////////////////////////////////////////////////////// /obj/item/organ/stomach/cell/preternis name = "preternis cell-stomach" desc = "Calling it a stomach is perhaps a bit generous. It's better at grinding rocks than dissolving food. Also works as a power cell." From 6bad340ccd124ec50024dc54bae1fa9ba850a49d Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 21:40:11 -0600 Subject: [PATCH 054/144] fix eyes break huds --- code/modules/clothing/glasses/hud.dm | 8 ++--- code/modules/mob/living/carbon/carbon.dm | 10 ++++++ code/modules/surgery/organs/eyes.dm | 16 ++++----- .../human/species_types/preternis/organs.dm | 34 +++++-------------- 4 files changed, 30 insertions(+), 38 deletions(-) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index ddb8f96210ce..4286eec82af8 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -45,7 +45,7 @@ item_state = "glasses" flash_protect = -1 // Blue green, dark - color_cutoffs = list(5, 10, 30) + color_cutoffs = list(10, 10, 30) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/health/meson @@ -86,7 +86,7 @@ item_state = "glasses" flash_protect = -1 // Pale yellow - color_cutoffs = list(30, 20, 5) + color_cutoffs = list(30, 20, 10) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/diagnostic/sunglasses @@ -145,8 +145,6 @@ icon_state = "sunhudsec" flash_protect = 1 tint = 1 - // Red with a tint of green - color_cutoffs = list(15, 5, 5) glass_colour_type = /datum/client_colour/glass_colour/darkred /obj/item/clothing/glasses/hud/security/sunglasses/hos @@ -159,7 +157,7 @@ desc = "An advanced heads-up display which provides ID data and vision in complete darkness." icon_state = "securityhudnight" flash_protect = -1 - color_cutoffs = list(35, 5, 5) + color_cutoffs = list(35, 10, 10) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/security/sunglasses/gars diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a3eb04ddc2ca..c21bcf7e6969 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -574,6 +574,16 @@ lighting_cutoff = initial(lighting_cutoff) lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) + var/obj/item/organ/eyes/eyes = getorganslot(ORGAN_SLOT_EYES) + if(eyes) + set_invis_see(eyes.see_invisible) + new_sight |= eyes.sight_flags + if(!isnull(eyes.lighting_cutoff)) + lighting_cutoff = eyes.lighting_cutoff + if(!isnull(eyes.color_cutoffs)) + lighting_color_cutoffs = blend_cutoff_colors(lighting_color_cutoffs, eyes.color_cutoffs) + + if(client.eye && client.eye != src) var/atom/A = client.eye if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates. diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index a04f105036a0..3c7546d488b3 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -165,6 +165,14 @@ #undef NIGHTVISION_LIGHT_MID #undef NIGHTVISION_LIGHT_HIG +/obj/item/organ/eyes/night_vision/mushroom + name = "fung-eye" + desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + low_light_cutoff = list(0, 15, 20) + medium_light_cutoff = list(0, 20, 35) + high_light_cutoff = list(0, 40, 50) + +//innate nightvision eyes /obj/item/organ/eyes/alien name = "alien eyes" desc = "It turned out they had them after all!" @@ -182,15 +190,7 @@ icon_state = "burning_eyes" color_cutoffs = list(20, 10, 40) -/obj/item/organ/eyes/night_vision/mushroom - name = "fung-eye" - desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." - low_light_cutoff = list(0, 15, 20) - medium_light_cutoff = list(0, 20, 35) - high_light_cutoff = list(0, 40, 50) - ///Robotic - /obj/item/organ/eyes/robotic name = "robotic eyes" icon_state = "cybernetic_eyeballs" diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index a3e2334b168d..4909b3c92787 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -1,10 +1,6 @@ -#define NIGHTVISION_LIGHT_OFF 0 -#define NIGHTVISION_LIGHT_LOW 1 -#define NIGHTVISION_LIGHT_HIGH 2 - /obj/item/organ/eyes/robotic/preternis name = "preternis eyes" - desc = "An experimental upgraded version of eyes that can see in the dark. They are designed to fit preternis" + desc = "A form archaic robotic eyes that can see in the dark. " //preternis eyes need to be powered by a preternis to function, in a non preternis they slowly power down to blindness status = ORGAN_ROBOTIC organ_flags = ORGAN_SYNTHETIC @@ -18,29 +14,20 @@ low_threshold_cleared = span_info("Your Preternis eyes have almost fully recharged.") actions_types = list(/datum/action/item_action/organ_action/use) var/powered = TRUE - // These lists are used as the color cutoff for the eye - var/list/low_light_cutoff = list(5, 20, 10) - var/list/high_light_cutoff = list(10, 30, 20) - var/light_level = NIGHTVISION_LIGHT_OFF - - - + var/night_vision = FALSE + // This list is used as the color cutoff for the night vision + var/list/light_cutoff = list(30, 12, 60) /obj/item/organ/eyes/robotic/preternis/ui_action_click() if(damage > low_threshold) //no nightvision if your eyes are hurt return sight_flags = initial(sight_flags) - switch(light_level) - if (NIGHTVISION_LIGHT_OFF) - color_cutoffs = low_light_cutoff.Copy() - light_level = NIGHTVISION_LIGHT_LOW - if (NIGHTVISION_LIGHT_LOW) - color_cutoffs = high_light_cutoff.Copy() - light_level = NIGHTVISION_LIGHT_HIGH - else - color_cutoffs = list() - light_level = NIGHTVISION_LIGHT_OFF + night_vision = !night_vision + if (night_vision) + color_cutoffs = light_cutoff.Copy() + else + color_cutoffs = list() owner.update_sight() /obj/item/organ/eyes/robotic/preternis/on_life() @@ -71,9 +58,6 @@ else if(damage > high_threshold) . += span_warning("[src] seem to flicker on and off. They must be pretty low on charge without being in a Preternis") -#undef NIGHTVISION_LIGHT_OFF -#undef NIGHTVISION_LIGHT_LOW -#undef NIGHTVISION_LIGHT_HIGH /////////////////////////////////////////////////////////// //----------------------Preternis Lungs------------------// From e6c8e834a42628ae8eb0390b73dafbf3aecc0601 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 21:57:51 -0600 Subject: [PATCH 055/144] colour tweaks --- code/modules/clothing/glasses/hud.dm | 4 ++-- code/modules/surgery/organs/eyes.dm | 2 +- .../mob/living/carbon/human/species_types/preternis/organs.dm | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 4286eec82af8..686ade9038dc 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -45,7 +45,7 @@ item_state = "glasses" flash_protect = -1 // Blue green, dark - color_cutoffs = list(10, 10, 30) + color_cutoffs = list(20, 20, 75) //yog change, blue night vision is so much weaker for some reason, so it's been significantly buffed to actually work as night vision glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/health/meson @@ -86,7 +86,7 @@ item_state = "glasses" flash_protect = -1 // Pale yellow - color_cutoffs = list(30, 20, 10) + color_cutoffs = list(40, 30, 15) glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/diagnostic/sunglasses diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 3c7546d488b3..755be018ecab 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -156,7 +156,7 @@ color_cutoffs = high_light_cutoff.Copy() light_level = NIGHTVISION_LIGHT_HIG else - color_cutoffs = list() + color_cutoffs = null light_level = NIGHTVISION_LIGHT_OFF owner.update_sight() diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 4909b3c92787..a8405b0e0cb5 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -16,7 +16,7 @@ var/powered = TRUE var/night_vision = FALSE // This list is used as the color cutoff for the night vision - var/list/light_cutoff = list(30, 12, 60) + var/list/light_cutoff = list(25, 10, 60) /obj/item/organ/eyes/robotic/preternis/ui_action_click() if(damage > low_threshold) @@ -27,7 +27,7 @@ if (night_vision) color_cutoffs = light_cutoff.Copy() else - color_cutoffs = list() + color_cutoffs = null owner.update_sight() /obj/item/organ/eyes/robotic/preternis/on_life() From 66c412cd25eff366c6f0b2ecdf9d465569aeb2ed Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 22:41:16 -0600 Subject: [PATCH 056/144] fixes --- code/__DEFINES/layers.dm | 3 --- code/_onclick/hud/render_plate.dm | 2 +- code/datums/progressbar.dm | 3 +-- code/modules/power/singularity/singularity.dm | 2 +- code/modules/spells/spell_types/jaunt/wirecrawl.dm | 5 +++-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 4199d972132c..e81166024dcc 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -12,9 +12,6 @@ #define PLANE_SPACE -25 #define PLANE_SPACE_PARALLAX -20 -#define SINGULARITY_EFFECT_PLANE -15 -#define SINGULARITY_RENDER_TARGET "*SINGULARITY_EFFECTS_PLANE" - #define GRAVITY_PULSE_PLANE -13 #define GRAVITY_PULSE_RENDER_TARGET "*GRAVPULSE_RENDER_TARGET" diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index d4e5bd9777eb..584d8b4275d9 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -78,7 +78,7 @@ /atom/movable/screen/plane_master/rendering_plate/game_plate/Initialize(mapload, datum/hud/hud_owner) . = ..() - add_filter("displacer", 1, displacement_map_filter(render_source = OFFSET_RENDER_TARGET(GRAVITY_PULSE_RENDER_TARGET, offset), size = 10)) + add_filter("displacer", 1, displacement_map_filter(render_source = OFFSET_RENDER_TARGET(GRAVITY_PULSE_RENDER_TARGET, offset), size = 75)) // Blackness renders weird when you view down openspace, because of transforms and borders and such // This is a consequence of not using lummy's grouped transparency, but I couldn't get that to work without totally fucking up diff --git a/code/datums/progressbar.dm b/code/datums/progressbar.dm index 23b916604dfe..225fa2e363ea 100644 --- a/code/datums/progressbar.dm +++ b/code/datums/progressbar.dm @@ -35,8 +35,7 @@ goal = goal_number bar_loc = target bar = image('icons/effects/progessbar.dmi', bar_loc, "prog_bar_0") - bar.plane = ABOVE_HUD_PLANE + 1 //yogs change, increased so it draws ontop of ventcrawling overlays - //SET_PLANE_EXPLICIT(bar, ABOVE_HUD_PLANE, User) //comment in when we port TG planes + SET_PLANE_EXPLICIT(bar, ABOVE_HUD_PLANE, User) //yogs change, increased so it draws ontop of ventcrawling overlays bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA user = User diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 31633999f379..cb1d0a12590a 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -4,7 +4,7 @@ #define SINGULARITY_INTEREST_NONSPACE 2 /atom/movable/gravity_lens - plane = SINGULARITY_EFFECT_PLANE + plane = GRAVITY_PULSE_PLANE //plane = GHOST_LAYER appearance_flags = PIXEL_SCALE | RESET_TRANSFORM icon = 'icons/effects/512x512.dmi' diff --git a/code/modules/spells/spell_types/jaunt/wirecrawl.dm b/code/modules/spells/spell_types/jaunt/wirecrawl.dm index a1829b04dbf6..84b4a367be0a 100644 --- a/code/modules/spells/spell_types/jaunt/wirecrawl.dm +++ b/code/modules/spells/spell_types/jaunt/wirecrawl.dm @@ -108,7 +108,6 @@ wire.visible_message(span_warning("[jaunter] zips into [wire]!")) jaunter.extinguish_mob() - jaunter.sight |= (SEE_TURFS|BLIND) jaunter.add_wirevision(wire) holder.travelled = wire.powernet do_sparks(10, FALSE, jaunter) @@ -135,7 +134,6 @@ if(!exit_jaunt(jaunter, get_turf(wire))) return FALSE - jaunter.sight &= ~(SEE_TURFS|BLIND) jaunter.remove_wirevision() do_sparks(10, FALSE, jaunter) @@ -214,6 +212,8 @@ if(!totalMembers.len) return + + sight |= (SEE_TURFS|BLIND) if(client) for(var/object in totalMembers)//cables and power machinery are not the same unfortunately @@ -239,6 +239,7 @@ for(var/image/current_image in wires_shown) client.images -= current_image wires_shown.len = 0 + sight &= ~(SEE_TURFS|BLIND) /obj/item/wirecrawl From dfdf1ca7ed78434df39da547d8f348a3f96370c7 Mon Sep 17 00:00:00 2001 From: Molti Date: Thu, 30 Nov 2023 22:48:43 -0600 Subject: [PATCH 057/144] Update living.dm --- yogstation/code/modules/mob/living/living.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/yogstation/code/modules/mob/living/living.dm b/yogstation/code/modules/mob/living/living.dm index 5a123f460b41..17fd8746224d 100644 --- a/yogstation/code/modules/mob/living/living.dm +++ b/yogstation/code/modules/mob/living/living.dm @@ -19,3 +19,4 @@ for(var/mob/living/simple_animal/hostile/guardian/holopara as anything in hasparasites()) holopara.lighting_cutoff = lighting_cutoff holopara.update_sight() + update_wire_vision() From 65a95052cf3064976993074256230fbc65751af1 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:28:38 -0500 Subject: [PATCH 058/144] yea ea --- byond-extools.dll | Bin 0 -> 1276928 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 byond-extools.dll diff --git a/byond-extools.dll b/byond-extools.dll new file mode 100644 index 0000000000000000000000000000000000000000..37efe6c6e4032e29893c927152badee402ba60ae GIT binary patch literal 1276928 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
H{ycLo3t2`P9fWb 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

  • DJ?Sg*r0L1rlqujx@#;_hERuEf>9 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 z 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 CITy$P literal 0 HcmV?d00001 From b26841ff21b6dee6889d879f4bf7d2883585b3ef Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:40:13 -0500 Subject: [PATCH 059/144] readd this and this --- code/game/turfs/turf.dm | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 0d676cd092d3..4f75d24c115c 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -19,10 +19,17 @@ GLOBAL_LIST_EMPTY(station_turfs) var/initial_temperature = T20C var/to_be_destroyed = 0 //Used for fire, if a melting temperature was reached, it will be destroyed var/max_fire_temperature_sustained = 0 //The max temperature of the fire which it was subjected to - + /// If there's a tile over a basic floor that can be ripped out + var/overfloor_placed = FALSE + /// How accessible underfloor pieces such as wires, pipes, etc are on this turf. Can be HIDDEN, VISIBLE, or INTERACTABLE. + var/underfloor_accessibility = UNDERFLOOR_HIDDEN var/blocks_air = FALSE - + ///Bool, whether this turf will always be illuminated no matter what area it is in + ///Makes it look blue, be warned + var/space_lit = FALSE + var/force_no_gravity = TRUE flags_1 = CAN_BE_DIRTY_1 + var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes From c1d9fd4e1a9bedc9b4881fb6f5fda540dff5d361 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:51:21 -0500 Subject: [PATCH 060/144] pupdate yeah --- code/game/turfs/turf.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 4f75d24c115c..c686c4dc7f79 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -29,6 +29,8 @@ GLOBAL_LIST_EMPTY(station_turfs) var/space_lit = FALSE var/force_no_gravity = TRUE flags_1 = CAN_BE_DIRTY_1 + /// If there is a lattice underneat this turf. Used for the attempt_lattice_replacement proc to determine if it should place lattice. + var/lattice_underneath = TRUE var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes From 2a00b4d710f2459e3a3bdcd96119c56451d57c09 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 00:59:00 -0500 Subject: [PATCH 061/144] slow update sucks --- code/_globalvars/bitfields.dm | 9 +++++++++ code/game/turfs/turf.dm | 3 +++ 2 files changed, 12 insertions(+) diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm index 2123f6a32d20..b098b265c9c0 100644 --- a/code/_globalvars/bitfields.dm +++ b/code/_globalvars/bitfields.dm @@ -235,3 +235,12 @@ DEFINE_BITFIELD(vis_flags, list( "VIS_UNDERLAY" = VIS_UNDERLAY, "VIS_HIDE" = VIS_HIDE, )) +DEFINE_BITFIELD(turf_flags, list( + "NO_LAVA_GEN" = NO_LAVA_GEN, + "NO_RUINS" = NO_RUINS, + "NO_RUST" = NO_RUST, + "NOJAUNT" = NOJAUNT, + "IS_SOLID" = IS_SOLID, + "UNUSED_RESERVATION_TURF" = UNUSED_RESERVATION_TURF, + "RESERVATION_TURF" = RESERVATION_TURF, +)) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index c686c4dc7f79..4327d5153392 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -671,3 +671,6 @@ GLOBAL_LIST_EMPTY(station_turfs) /// Called when attempting to set fire to a turf /turf/proc/IgniteTurf(power, fire_color="red") return +/// Returns whether it is safe for an atom to move across this turf +/turf/proc/can_cross_safely(atom/movable/crossing) + return TRUE From 7ef5c075acdc9c8b8fd6bfeb0247180b5587868a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:06:37 -0500 Subject: [PATCH 062/144] why no work angy --- code/game/turfs/turf.dm | 3 +- .../space_management/space_reservation.dm | 116 ++++++++++++++++++ .../mapping/space_management/traits.dm | 115 ----------------- 3 files changed, 118 insertions(+), 116 deletions(-) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 4327d5153392..5a973a320f99 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -31,7 +31,8 @@ GLOBAL_LIST_EMPTY(station_turfs) flags_1 = CAN_BE_DIRTY_1 /// If there is a lattice underneat this turf. Used for the attempt_lattice_replacement proc to determine if it should place lattice. var/lattice_underneath = TRUE - + /// Turf bitflags, see code/__DEFINES/flags.dm + var/turf_flags = NONE var/list/image/blueprint_data //for the station blueprints, images of objects eg: pipes diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm index cfe9b5043b89..855b14e0e4b7 100644 --- a/code/modules/mapping/space_management/space_reservation.dm +++ b/code/modules/mapping/space_management/space_reservation.dm @@ -168,3 +168,119 @@ Release() LAZYREMOVE(SSmapping.turf_reservations, src) return ..() + +// Look up levels[z].traits[trait] +/datum/controller/subsystem/mapping/proc/level_trait(z, trait) + if (!isnum(z) || z < 1) + return null + if (z_list) + if (z > z_list.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]") + return list() + var/datum/space_level/S = get_level(z) + return S.traits[trait] + else + var/list/default = DEFAULT_MAP_TRAITS + if (z > default.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]") + return list() + return default[z][DL_TRAITS][trait] + +// Check if levels[z] has any of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits) + for (var/I in traits) + if (level_trait(z, I)) + return TRUE + return FALSE + +// Check if levels[z] has all of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits) + for (var/I in traits) + if (!level_trait(z, I)) + return FALSE + return TRUE + +// Get a list of all z which have the specified trait +/datum/controller/subsystem/mapping/proc/levels_by_trait(trait) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + if (S.traits[trait]) + . += S.z_value + +// Get a list of all z which have any of the specified traits +/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + for (var/trait in traits) + if (S.traits[trait]) + . += S.z_value + break + +/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable. +/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target) + for(var/z_idx in 1 to z_size) + var/turf/bottom_left = bottom_left_turfs[z_idx] + var/turf/top_right = top_right_turfs[z_idx] + var/bl_x = bottom_left.x + var/bl_y = bottom_left.y + var/tr_x = top_right.x + var/tr_y = top_right.y + + if(target.x < bl_x) + continue + + if(target.y < bl_y) + continue + + if(target.x > tr_x) + continue + + if(target.y > tr_y) + continue + + var/list/return_information = list() + return_information["z_idx"] = z_idx + return_information["offset_x"] = target.x - bl_x + return_information["offset_y"] = target.y - bl_y + return return_information + return null + +/// Gets the turf below the given target. Returns null if there is no turf below the target +/datum/turf_reservation/proc/get_turf_below(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the max, then there is no turf below + if(z_idx == z_size) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx + 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) + +/// Gets the turf above the given target. Returns null if there is no turf above the target +/datum/turf_reservation/proc/get_turf_above(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the min, then there is no turf above + if(z_idx == 1) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx - 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) +// Prefer not to use this one too often +/datum/controller/subsystem/mapping/proc/get_station_center() + var/station_z = levels_by_trait(ZTRAIT_STATION)[1] + return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), station_z) diff --git a/code/modules/mapping/space_management/traits.dm b/code/modules/mapping/space_management/traits.dm index 7545b2508a95..e69de29bb2d1 100644 --- a/code/modules/mapping/space_management/traits.dm +++ b/code/modules/mapping/space_management/traits.dm @@ -1,115 +0,0 @@ -// Look up levels[z].traits[trait] -/datum/controller/subsystem/mapping/proc/level_trait(z, trait) - if (!isnum(z) || z < 1) - return null - if (z_list) - if (z > z_list.len) - stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]") - return list() - var/datum/space_level/S = get_level(z) - return S.traits[trait] - else - var/list/default = DEFAULT_MAP_TRAITS - if (z > default.len) - stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]") - return list() - return default[z][DL_TRAITS][trait] - -// Check if levels[z] has any of the specified traits -/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits) - for (var/I in traits) - if (level_trait(z, I)) - return TRUE - return FALSE - -// Check if levels[z] has all of the specified traits -/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits) - for (var/I in traits) - if (!level_trait(z, I)) - return FALSE - return TRUE - -// Get a list of all z which have the specified trait -/datum/controller/subsystem/mapping/proc/levels_by_trait(trait) - . = list() - var/list/_z_list = z_list - for(var/A in _z_list) - var/datum/space_level/S = A - if (S.traits[trait]) - . += S.z_value - -// Get a list of all z which have any of the specified traits -/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits) - . = list() - var/list/_z_list = z_list - for(var/A in _z_list) - var/datum/space_level/S = A - for (var/trait in traits) - if (S.traits[trait]) - . += S.z_value - break - -/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable. -/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target) - for(var/z_idx in 1 to z_size) - var/turf/bottom_left = bottom_left_turfs[z_idx] - var/turf/top_right = top_right_turfs[z_idx] - var/bl_x = bottom_left.x - var/bl_y = bottom_left.y - var/tr_x = top_right.x - var/tr_y = top_right.y - - if(target.x < bl_x) - continue - - if(target.y < bl_y) - continue - - if(target.x > tr_x) - continue - - if(target.y > tr_y) - continue - - var/list/return_information = list() - return_information["z_idx"] = z_idx - return_information["offset_x"] = target.x - bl_x - return_information["offset_y"] = target.y - bl_y - return return_information - return null - -/// Gets the turf below the given target. Returns null if there is no turf below the target -/datum/turf_reservation/proc/get_turf_below(turf/target) - var/list/bounds_info = calculate_turf_bounds_information(target) - if(isnull(bounds_info)) - return null - - var/z_idx = bounds_info["z_idx"] - // check what z level, if its the max, then there is no turf below - if(z_idx == z_size) - return null - - var/offset_x = bounds_info["offset_x"] - var/offset_y = bounds_info["offset_y"] - var/turf/bottom_left = bottom_left_turfs[z_idx + 1] - return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) - -/// Gets the turf above the given target. Returns null if there is no turf above the target -/datum/turf_reservation/proc/get_turf_above(turf/target) - var/list/bounds_info = calculate_turf_bounds_information(target) - if(isnull(bounds_info)) - return null - - var/z_idx = bounds_info["z_idx"] - // check what z level, if its the min, then there is no turf above - if(z_idx == 1) - return null - - var/offset_x = bounds_info["offset_x"] - var/offset_y = bounds_info["offset_y"] - var/turf/bottom_left = bottom_left_turfs[z_idx - 1] - return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) -// Prefer not to use this one too often -/datum/controller/subsystem/mapping/proc/get_station_center() - var/station_z = levels_by_trait(ZTRAIT_STATION)[1] - return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), station_z) From 567ef0d75a7742d55227127158c93af8b2e38baa Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:16:26 -0500 Subject: [PATCH 063/144] weird errors shit sucks --- code/game/turfs/turf.dm | 9 +- .../space_management/space_reservation.dm | 116 ------------------ .../mapping/space_management/traits.dm | 115 +++++++++++++++++ 3 files changed, 120 insertions(+), 120 deletions(-) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 5a973a320f99..e0ed6c8de25e 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -104,11 +104,11 @@ GLOBAL_LIST_EMPTY(station_turfs) if (light_system == STATIC_LIGHT && light_power && light_range) update_light() - var/turf/T = SSmapping.get_turf_above(src) + var/turf/T = GET_TURF_ABOVE(src) if(T) T.multiz_turf_new(src, DOWN) SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, DOWN) - T = SSmapping.get_turf_below(src) + T = GET_TURF_BELOW(src) if(T) T.multiz_turf_new(src, UP) SEND_SIGNAL(T, COMSIG_TURF_MULTIZ_NEW, src, UP) @@ -143,10 +143,10 @@ GLOBAL_LIST_EMPTY(station_turfs) if(!changing_turf) stack_trace("Incorrect turf deletion") changing_turf = FALSE - var/turf/T = SSmapping.get_turf_above(src) + var/turf/T = GET_TURN_ABOVE(src) if(T) T.multiz_turf_del(src, DOWN) - T = SSmapping.get_turf_below(src) + T = GET_TURF_BELOW(src) if(T) T.multiz_turf_del(src, UP) if(force) @@ -675,3 +675,4 @@ GLOBAL_LIST_EMPTY(station_turfs) /// Returns whether it is safe for an atom to move across this turf /turf/proc/can_cross_safely(atom/movable/crossing) return TRUE + diff --git a/code/modules/mapping/space_management/space_reservation.dm b/code/modules/mapping/space_management/space_reservation.dm index 855b14e0e4b7..cfe9b5043b89 100644 --- a/code/modules/mapping/space_management/space_reservation.dm +++ b/code/modules/mapping/space_management/space_reservation.dm @@ -168,119 +168,3 @@ Release() LAZYREMOVE(SSmapping.turf_reservations, src) return ..() - -// Look up levels[z].traits[trait] -/datum/controller/subsystem/mapping/proc/level_trait(z, trait) - if (!isnum(z) || z < 1) - return null - if (z_list) - if (z > z_list.len) - stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]") - return list() - var/datum/space_level/S = get_level(z) - return S.traits[trait] - else - var/list/default = DEFAULT_MAP_TRAITS - if (z > default.len) - stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]") - return list() - return default[z][DL_TRAITS][trait] - -// Check if levels[z] has any of the specified traits -/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits) - for (var/I in traits) - if (level_trait(z, I)) - return TRUE - return FALSE - -// Check if levels[z] has all of the specified traits -/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits) - for (var/I in traits) - if (!level_trait(z, I)) - return FALSE - return TRUE - -// Get a list of all z which have the specified trait -/datum/controller/subsystem/mapping/proc/levels_by_trait(trait) - . = list() - var/list/_z_list = z_list - for(var/A in _z_list) - var/datum/space_level/S = A - if (S.traits[trait]) - . += S.z_value - -// Get a list of all z which have any of the specified traits -/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits) - . = list() - var/list/_z_list = z_list - for(var/A in _z_list) - var/datum/space_level/S = A - for (var/trait in traits) - if (S.traits[trait]) - . += S.z_value - break - -/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable. -/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target) - for(var/z_idx in 1 to z_size) - var/turf/bottom_left = bottom_left_turfs[z_idx] - var/turf/top_right = top_right_turfs[z_idx] - var/bl_x = bottom_left.x - var/bl_y = bottom_left.y - var/tr_x = top_right.x - var/tr_y = top_right.y - - if(target.x < bl_x) - continue - - if(target.y < bl_y) - continue - - if(target.x > tr_x) - continue - - if(target.y > tr_y) - continue - - var/list/return_information = list() - return_information["z_idx"] = z_idx - return_information["offset_x"] = target.x - bl_x - return_information["offset_y"] = target.y - bl_y - return return_information - return null - -/// Gets the turf below the given target. Returns null if there is no turf below the target -/datum/turf_reservation/proc/get_turf_below(turf/target) - var/list/bounds_info = calculate_turf_bounds_information(target) - if(isnull(bounds_info)) - return null - - var/z_idx = bounds_info["z_idx"] - // check what z level, if its the max, then there is no turf below - if(z_idx == z_size) - return null - - var/offset_x = bounds_info["offset_x"] - var/offset_y = bounds_info["offset_y"] - var/turf/bottom_left = bottom_left_turfs[z_idx + 1] - return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) - -/// Gets the turf above the given target. Returns null if there is no turf above the target -/datum/turf_reservation/proc/get_turf_above(turf/target) - var/list/bounds_info = calculate_turf_bounds_information(target) - if(isnull(bounds_info)) - return null - - var/z_idx = bounds_info["z_idx"] - // check what z level, if its the min, then there is no turf above - if(z_idx == 1) - return null - - var/offset_x = bounds_info["offset_x"] - var/offset_y = bounds_info["offset_y"] - var/turf/bottom_left = bottom_left_turfs[z_idx - 1] - return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) -// Prefer not to use this one too often -/datum/controller/subsystem/mapping/proc/get_station_center() - var/station_z = levels_by_trait(ZTRAIT_STATION)[1] - return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), station_z) diff --git a/code/modules/mapping/space_management/traits.dm b/code/modules/mapping/space_management/traits.dm index e69de29bb2d1..7545b2508a95 100644 --- a/code/modules/mapping/space_management/traits.dm +++ b/code/modules/mapping/space_management/traits.dm @@ -0,0 +1,115 @@ +// Look up levels[z].traits[trait] +/datum/controller/subsystem/mapping/proc/level_trait(z, trait) + if (!isnum(z) || z < 1) + return null + if (z_list) + if (z > z_list.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], z_list.len = [z_list.len]") + return list() + var/datum/space_level/S = get_level(z) + return S.traits[trait] + else + var/list/default = DEFAULT_MAP_TRAITS + if (z > default.len) + stack_trace("Unmanaged z-level [z]! maxz = [world.maxz], default.len = [default.len]") + return list() + return default[z][DL_TRAITS][trait] + +// Check if levels[z] has any of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_any_trait(z, list/traits) + for (var/I in traits) + if (level_trait(z, I)) + return TRUE + return FALSE + +// Check if levels[z] has all of the specified traits +/datum/controller/subsystem/mapping/proc/level_has_all_traits(z, list/traits) + for (var/I in traits) + if (!level_trait(z, I)) + return FALSE + return TRUE + +// Get a list of all z which have the specified trait +/datum/controller/subsystem/mapping/proc/levels_by_trait(trait) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + if (S.traits[trait]) + . += S.z_value + +// Get a list of all z which have any of the specified traits +/datum/controller/subsystem/mapping/proc/levels_by_any_trait(list/traits) + . = list() + var/list/_z_list = z_list + for(var/A in _z_list) + var/datum/space_level/S = A + for (var/trait in traits) + if (S.traits[trait]) + . += S.z_value + break + +/// Calculates the effective bounds information for the given turf. Returns a list of the information, or null if not applicable. +/datum/turf_reservation/proc/calculate_turf_bounds_information(turf/target) + for(var/z_idx in 1 to z_size) + var/turf/bottom_left = bottom_left_turfs[z_idx] + var/turf/top_right = top_right_turfs[z_idx] + var/bl_x = bottom_left.x + var/bl_y = bottom_left.y + var/tr_x = top_right.x + var/tr_y = top_right.y + + if(target.x < bl_x) + continue + + if(target.y < bl_y) + continue + + if(target.x > tr_x) + continue + + if(target.y > tr_y) + continue + + var/list/return_information = list() + return_information["z_idx"] = z_idx + return_information["offset_x"] = target.x - bl_x + return_information["offset_y"] = target.y - bl_y + return return_information + return null + +/// Gets the turf below the given target. Returns null if there is no turf below the target +/datum/turf_reservation/proc/get_turf_below(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the max, then there is no turf below + if(z_idx == z_size) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx + 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) + +/// Gets the turf above the given target. Returns null if there is no turf above the target +/datum/turf_reservation/proc/get_turf_above(turf/target) + var/list/bounds_info = calculate_turf_bounds_information(target) + if(isnull(bounds_info)) + return null + + var/z_idx = bounds_info["z_idx"] + // check what z level, if its the min, then there is no turf above + if(z_idx == 1) + return null + + var/offset_x = bounds_info["offset_x"] + var/offset_y = bounds_info["offset_y"] + var/turf/bottom_left = bottom_left_turfs[z_idx - 1] + return locate(bottom_left.x + offset_x, bottom_left.y + offset_y, bottom_left.z) +// Prefer not to use this one too often +/datum/controller/subsystem/mapping/proc/get_station_center() + var/station_z = levels_by_trait(ZTRAIT_STATION)[1] + return locate(round(world.maxx * 0.5, 1), round(world.maxy * 0.5, 1), station_z) From b82a6cc1aa2f78ec3fbf978a32a8e863aa59cf85 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:17:08 -0500 Subject: [PATCH 064/144] fixved it I can spell good --- code/game/turfs/turf.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e0ed6c8de25e..9173c4486564 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -143,7 +143,7 @@ GLOBAL_LIST_EMPTY(station_turfs) if(!changing_turf) stack_trace("Incorrect turf deletion") changing_turf = FALSE - var/turf/T = GET_TURN_ABOVE(src) + var/turf/T = GET_TURF_ABOVE(src) if(T) T.multiz_turf_del(src, DOWN) T = GET_TURF_BELOW(src) From 0d2c511f79a9ff577738535399d30391a377f313 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:34:32 -0500 Subject: [PATCH 065/144] fix? POSSIBLY --- code/game/turfs/space/space.dm | 47 ++++++++++++++++++-------- code/modules/lighting/lighting_area.dm | 2 ++ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index a69c134cff3f..fde2a8888224 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -83,30 +83,47 @@ GLOBAL_LIST_EMPTY(starlight) //This is used to optimize the map loader return +/** + * Space Initialize + * + * Doesn't call parent, see [/atom/proc/Initialize]. + * When adding new stuff to /atom/Initialize, /turf/Initialize, etc + * don't just add it here unless space actually needs it. + * + * There is a lot of work that is intentionally not done because it is not currently used. + * This includes stuff like smoothing, blocking camera visibility, etc. + * If you are facing some odd bug with specifically space, check if it's something that was + * intentionally ommitted from this implementation. + */ /turf/open/space/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) - icon_state = SPACE_ICON_STATE - if(!space_gas) - space_gas = new air = space_gas - update_air_ref(0) - vis_contents.Cut() //removes inherited overlays - visibilityChanged() if (PERFORM_ALL_TESTS(focus_only/multiple_space_initialization)) if(flags_1 & INITIALIZED_1) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 - var/area/A = loc - if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) - add_overlay(/obj/effect/fullbright) - - if (light_system == STATIC_LIGHT && light_power && light_range) - update_light() - - if (opacity) - directional_opacity = ALL_CARDINALS + // We make the assumption that the space plane will never be blacklisted, as an optimization + if(SSmapping.max_plane_offset) + plane = PLANE_SPACE - (PLANE_RANGE * SSmapping.z_level_to_plane_offset[z]) + + var/area/our_area = loc + if(!our_area.area_has_base_lighting && space_lit) //Only provide your own lighting if the area doesn't for you + // Intentionally not add_overlay for performance reasons. + // add_overlay does a bunch of generic stuff, like creating a new list for overlays, + // queueing compile, cloning appearance, etc etc etc that is not necessary here. + overlays += GLOB.starlight_overlays[GET_TURF_PLANE_OFFSET(src) + 1] + + if (!mapload) + + if(SSmapping.max_plane_offset) + var/turf/T = GET_TURF_ABOVE(src) + if(T) + T.multiz_turf_new(src, DOWN) + T = GET_TURF_BELOW(src) + if(T) + T.multiz_turf_new(src, UP) return INITIALIZE_HINT_NORMAL diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm index 58ee031d3281..76e13368a3d5 100644 --- a/code/modules/lighting/lighting_area.dm +++ b/code/modules/lighting/lighting_area.dm @@ -1,6 +1,8 @@ /area luminosity = TRUE var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED + ///Whether this area has a currently active base lighting, bool + var/area_has_base_lighting = FALSE /area/proc/set_dynamic_lighting(new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED) if (new_dynamic_lighting == dynamic_lighting) From ecaffbc8b7dd7dd8cbed7a89f389bb13fb867a94 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 01:37:43 -0500 Subject: [PATCH 066/144] nope wasnt this --- code/game/turfs/space/space.dm | 47 ++++++++------------------ code/modules/lighting/lighting_area.dm | 2 -- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index fde2a8888224..a69c134cff3f 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -83,47 +83,30 @@ GLOBAL_LIST_EMPTY(starlight) //This is used to optimize the map loader return -/** - * Space Initialize - * - * Doesn't call parent, see [/atom/proc/Initialize]. - * When adding new stuff to /atom/Initialize, /turf/Initialize, etc - * don't just add it here unless space actually needs it. - * - * There is a lot of work that is intentionally not done because it is not currently used. - * This includes stuff like smoothing, blocking camera visibility, etc. - * If you are facing some odd bug with specifically space, check if it's something that was - * intentionally ommitted from this implementation. - */ /turf/open/space/Initialize(mapload) SHOULD_CALL_PARENT(FALSE) + icon_state = SPACE_ICON_STATE + if(!space_gas) + space_gas = new air = space_gas + update_air_ref(0) + vis_contents.Cut() //removes inherited overlays + visibilityChanged() if (PERFORM_ALL_TESTS(focus_only/multiple_space_initialization)) if(flags_1 & INITIALIZED_1) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 - // We make the assumption that the space plane will never be blacklisted, as an optimization - if(SSmapping.max_plane_offset) - plane = PLANE_SPACE - (PLANE_RANGE * SSmapping.z_level_to_plane_offset[z]) - - var/area/our_area = loc - if(!our_area.area_has_base_lighting && space_lit) //Only provide your own lighting if the area doesn't for you - // Intentionally not add_overlay for performance reasons. - // add_overlay does a bunch of generic stuff, like creating a new list for overlays, - // queueing compile, cloning appearance, etc etc etc that is not necessary here. - overlays += GLOB.starlight_overlays[GET_TURF_PLANE_OFFSET(src) + 1] - - if (!mapload) - - if(SSmapping.max_plane_offset) - var/turf/T = GET_TURF_ABOVE(src) - if(T) - T.multiz_turf_new(src, DOWN) - T = GET_TURF_BELOW(src) - if(T) - T.multiz_turf_new(src, UP) + var/area/A = loc + if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) + add_overlay(/obj/effect/fullbright) + + if (light_system == STATIC_LIGHT && light_power && light_range) + update_light() + + if (opacity) + directional_opacity = ALL_CARDINALS return INITIALIZE_HINT_NORMAL diff --git a/code/modules/lighting/lighting_area.dm b/code/modules/lighting/lighting_area.dm index 76e13368a3d5..58ee031d3281 100644 --- a/code/modules/lighting/lighting_area.dm +++ b/code/modules/lighting/lighting_area.dm @@ -1,8 +1,6 @@ /area luminosity = TRUE var/dynamic_lighting = DYNAMIC_LIGHTING_ENABLED - ///Whether this area has a currently active base lighting, bool - var/area_has_base_lighting = FALSE /area/proc/set_dynamic_lighting(new_dynamic_lighting = DYNAMIC_LIGHTING_ENABLED) if (new_dynamic_lighting == dynamic_lighting) From c02d04ad4b65a5d75561b4dc1e646d40d2eb9dd8 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 08:34:35 -0500 Subject: [PATCH 067/144] no more immutable thhanks koffee --- code/game/turfs/space/space.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index a69c134cff3f..e5ce5053fad7 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(starlight) var/destination_x var/destination_y - var/global/datum/gas_mixture/immutable/space/space_gas = new + var/global/datum/gas_mixture/immutable/space/space_gas plane = PLANE_SPACE layer = SPACE_LAYER light_power = 1 From ad150548fafed17370837ebbff8afa315d1eece8 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 08:45:55 -0500 Subject: [PATCH 068/144] ok ok --- code/_onclick/hud/plane_master_group.dm | 20 +++++------ .../client/preferences/multiz_parallax.dm | 26 +++++++------- .../client/preferences/multiz_performance.dm | 34 +++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/code/_onclick/hud/plane_master_group.dm b/code/_onclick/hud/plane_master_group.dm index 4775d3553fce..3b32c6d213bc 100644 --- a/code/_onclick/hud/plane_master_group.dm +++ b/code/_onclick/hud/plane_master_group.dm @@ -98,8 +98,8 @@ /datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) // Check if this feature is disabled for the client, in which case don't use scale. var/mob/our_mob = our_hud?.mymob - if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) - use_scale = FALSE + // if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) + // use_scale = FALSE // No offset? piss off if(!SSmapping.max_plane_offset) @@ -119,14 +119,14 @@ scale_by = 1 var/list/offsets = list() - var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) + // var/multiz_boundary = our_mob?.client?.prefs?.read_preference(/datum/preference/numeric/multiz_performance) // We accept negatives so going down "zooms" away the drop above as it goes for(var/offset in -SSmapping.max_plane_offset to SSmapping.max_plane_offset) // Multiz boundaries disable transforms - if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) - offsets += null - continue + // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (multiz_boundary < abs(offset))) + // offsets += null + // continue // No transformations if we're landing ON you if(offset == 0) @@ -149,10 +149,10 @@ var/visual_offset = plane.offset - new_offset // Basically uh, if we're showing something down X amount of levels, or up any amount of levels - if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) - plane.outside_bounds(our_mob) - else if(plane.is_outside_bounds) - plane.inside_bounds(our_mob) + // if(multiz_boundary != MULTIZ_PERFORMANCE_DISABLE && (visual_offset > multiz_boundary || visual_offset < 0)) + // plane.outside_bounds(our_mob) + // else if(plane.is_outside_bounds) + // plane.inside_bounds(our_mob) if(!plane.multiz_scaled) continue diff --git a/code/modules/client/preferences/multiz_parallax.dm b/code/modules/client/preferences/multiz_parallax.dm index d4f77e206b2a..f8bfad97bc26 100644 --- a/code/modules/client/preferences/multiz_parallax.dm +++ b/code/modules/client/preferences/multiz_parallax.dm @@ -1,16 +1,16 @@ -/// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. -/datum/preference/toggle/multiz_parallax - category = PREFERENCE_CATEGORY_GAME_PREFERENCES - savefile_key = "multiz_parallax" - savefile_identifier = PREFERENCE_PLAYER +// /// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. +// /datum/preference/toggle/multiz_parallax +// category = PREFERENCE_CATEGORY_GAME_PREFERENCES +// savefile_key = "multiz_parallax" +// savefile_identifier = PREFERENCE_PLAYER -/datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) - // Update the plane master group's Z transforms. +// /datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) +// // Update the plane master group's Z transforms. - var/datum/hud/my_hud = client.mob?.hud_used - if(!my_hud) - return +// var/datum/hud/my_hud = client.mob?.hud_used +// if(!my_hud) +// return - for(var/group_key as anything in my_hud.master_groups) - var/datum/plane_master_group/group = my_hud.master_groups[group_key] - group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) +// for(var/group_key as anything in my_hud.master_groups) +// var/datum/plane_master_group/group = my_hud.master_groups[group_key] +// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) diff --git a/code/modules/client/preferences/multiz_performance.dm b/code/modules/client/preferences/multiz_performance.dm index 7591401f2d8d..a7b8131a62f6 100644 --- a/code/modules/client/preferences/multiz_performance.dm +++ b/code/modules/client/preferences/multiz_performance.dm @@ -1,21 +1,21 @@ -/// Boundary for how many z levels down to render properly before we start going cheapo mode -/datum/preference/numeric/multiz_performance - category = PREFERENCE_CATEGORY_GAME_PREFERENCES - savefile_key = "multiz_performance" - savefile_identifier = PREFERENCE_PLAYER +// /// Boundary for how many z levels down to render properly before we start going cheapo mode +// /datum/preference/numeric/multiz_performance +// category = PREFERENCE_CATEGORY_GAME_PREFERENCES +// savefile_key = "multiz_performance" +// savefile_identifier = PREFERENCE_PLAYER - minimum = MULTIZ_PERFORMANCE_DISABLE - maximum = MAX_EXPECTED_Z_DEPTH - 1 +// minimum = MULTIZ_PERFORMANCE_DISABLE +// maximum = MAX_EXPECTED_Z_DEPTH - 1 -/datum/preference/numeric/multiz_performance/create_default_value() - return -1 +// /datum/preference/numeric/multiz_performance/create_default_value() +// return -1 -/datum/preference/numeric/multiz_performance/apply_to_client(client/client, value) - // Update the plane master group's layering - var/datum/hud/my_hud = client.mob?.hud_used - if(!my_hud) - return +// /datum/preference/numeric/multiz_performance/apply_to_client(client/client, value) +// // Update the plane master group's layering +// var/datum/hud/my_hud = client.mob?.hud_used +// if(!my_hud) +// return - for(var/group_key as anything in my_hud.master_groups) - var/datum/plane_master_group/group = my_hud.master_groups[group_key] - group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) +// for(var/group_key as anything in my_hud.master_groups) +// var/datum/plane_master_group/group = my_hud.master_groups[group_key] +// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) From 63c418dce223b56ce891b4080c627d8a0f3ac85c Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 08:52:27 -0500 Subject: [PATCH 069/144] removes all the pref stuff ""removes"" --- code/_onclick/hud/plane_master_group.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/_onclick/hud/plane_master_group.dm b/code/_onclick/hud/plane_master_group.dm index 3b32c6d213bc..1205b871fd81 100644 --- a/code/_onclick/hud/plane_master_group.dm +++ b/code/_onclick/hud/plane_master_group.dm @@ -97,7 +97,7 @@ // // It's hard, and potentially expensive. be careful /datum/plane_master_group/proc/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) // Check if this feature is disabled for the client, in which case don't use scale. - var/mob/our_mob = our_hud?.mymob + // var/mob/our_mob = our_hud?.mymob // if(!our_mob?.client?.prefs?.read_preference(/datum/preference/toggle/multiz_parallax)) // use_scale = FALSE From c389b271d9ae30e0fd6205325600e180c2d4714e Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:19:15 -0500 Subject: [PATCH 070/144] remove this idiot --- code/__DEFINES/construction.dm | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/code/__DEFINES/construction.dm b/code/__DEFINES/construction.dm index 5578cf9a927b..8658a984936d 100644 --- a/code/__DEFINES/construction.dm +++ b/code/__DEFINES/construction.dm @@ -2,18 +2,6 @@ //Defines for construction states -//rcd constants for the design list -/// The mode of operation to design an specific type of rcd design -#define RCD_DESIGN_MODE "rcd_design_mode" - /// For changing turfs - #define RCD_TURF (1 << 0) - /// Windoors & Airlocks - #define RCD_STRUCTURE (1 << 3) - /// For wallmounts like air alarms, fire alarms & apc - #define RCD_WALLFRAME (1 << 4) -/// The typepath of the structure the rcd is trying to build -#define RCD_DESIGN_PATH "rcd_design_path" - //girder construction states #define GIRDER_NORMAL 0 #define GIRDER_REINF_STRUTS 1 From 54d5710ddfb3dee29f31d185106ccc8f2b5958c4 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:25:25 -0500 Subject: [PATCH 071/144] this goes bye bye --- code/modules/client/multiz_parallax.dm | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 code/modules/client/multiz_parallax.dm diff --git a/code/modules/client/multiz_parallax.dm b/code/modules/client/multiz_parallax.dm deleted file mode 100644 index f8bfad97bc26..000000000000 --- a/code/modules/client/multiz_parallax.dm +++ /dev/null @@ -1,16 +0,0 @@ -// /// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. -// /datum/preference/toggle/multiz_parallax -// category = PREFERENCE_CATEGORY_GAME_PREFERENCES -// savefile_key = "multiz_parallax" -// savefile_identifier = PREFERENCE_PLAYER - -// /datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) -// // Update the plane master group's Z transforms. - -// var/datum/hud/my_hud = client.mob?.hud_used -// if(!my_hud) -// return - -// for(var/group_key as anything in my_hud.master_groups) -// var/datum/plane_master_group/group = my_hud.master_groups[group_key] -// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) From 39b2fe2f0752ccb9250c9cca766fc14694a475a8 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:26:14 -0500 Subject: [PATCH 072/144] these go too genius --- .../client/preferences/multiz_parallax.dm | 16 -------------- .../client/preferences/multiz_performance.dm | 21 ------------------- 2 files changed, 37 deletions(-) delete mode 100644 code/modules/client/preferences/multiz_parallax.dm delete mode 100644 code/modules/client/preferences/multiz_performance.dm diff --git a/code/modules/client/preferences/multiz_parallax.dm b/code/modules/client/preferences/multiz_parallax.dm deleted file mode 100644 index f8bfad97bc26..000000000000 --- a/code/modules/client/preferences/multiz_parallax.dm +++ /dev/null @@ -1,16 +0,0 @@ -// /// Whether or not to toggle multiz parallax, the parallax effect for lower z-levels. -// /datum/preference/toggle/multiz_parallax -// category = PREFERENCE_CATEGORY_GAME_PREFERENCES -// savefile_key = "multiz_parallax" -// savefile_identifier = PREFERENCE_PLAYER - -// /datum/preference/toggle/multiz_parallax/apply_to_client(client/client, value) -// // Update the plane master group's Z transforms. - -// var/datum/hud/my_hud = client.mob?.hud_used -// if(!my_hud) -// return - -// for(var/group_key as anything in my_hud.master_groups) -// var/datum/plane_master_group/group = my_hud.master_groups[group_key] -// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) diff --git a/code/modules/client/preferences/multiz_performance.dm b/code/modules/client/preferences/multiz_performance.dm deleted file mode 100644 index a7b8131a62f6..000000000000 --- a/code/modules/client/preferences/multiz_performance.dm +++ /dev/null @@ -1,21 +0,0 @@ -// /// Boundary for how many z levels down to render properly before we start going cheapo mode -// /datum/preference/numeric/multiz_performance -// category = PREFERENCE_CATEGORY_GAME_PREFERENCES -// savefile_key = "multiz_performance" -// savefile_identifier = PREFERENCE_PLAYER - -// minimum = MULTIZ_PERFORMANCE_DISABLE -// maximum = MAX_EXPECTED_Z_DEPTH - 1 - -// /datum/preference/numeric/multiz_performance/create_default_value() -// return -1 - -// /datum/preference/numeric/multiz_performance/apply_to_client(client/client, value) -// // Update the plane master group's layering -// var/datum/hud/my_hud = client.mob?.hud_used -// if(!my_hud) -// return - -// for(var/group_key as anything in my_hud.master_groups) -// var/datum/plane_master_group/group = my_hud.master_groups[group_key] -// group.transform_lower_turfs(my_hud, my_hud.current_plane_offset) From f02183c2c2d2ac665007d5a7425669725b4d3c46 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:28:57 -0500 Subject: [PATCH 073/144] bye bye --- yogstation.dme | 3 --- 1 file changed, 3 deletions(-) diff --git a/yogstation.dme b/yogstation.dme index f4c48f52b2b9..374f54ea108d 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2124,7 +2124,6 @@ #include "code\modules\client\client_defines.dm" #include "code\modules\client\client_procs.dm" #include "code\modules\client\message.dm" -#include "code\modules\client\multiz_parallax.dm" #include "code\modules\client\player_details.dm" #include "code\modules\client\preferences.dm" #include "code\modules\client\preferences_menu.dm" @@ -2155,8 +2154,6 @@ #include "code\modules\client\preferences\jobless_role.dm" #include "code\modules\client\preferences\mood.dm" #include "code\modules\client\preferences\mood_enabling.dm" -#include "code\modules\client\preferences\multiz_parallax.dm" -#include "code\modules\client\preferences\multiz_performance.dm" #include "code\modules\client\preferences\names.dm" #include "code\modules\client\preferences\ooc.dm" #include "code\modules\client\preferences\parallax.dm" From bd3d6325cc517c8988693840f0eeee8ca53050eb Mon Sep 17 00:00:00 2001 From: Molti Date: Fri, 1 Dec 2023 13:27:42 -0600 Subject: [PATCH 074/144] better night vision --- code/modules/clothing/glasses/_glasses.dm | 1 + code/modules/clothing/glasses/hud.dm | 6 ++++-- code/modules/surgery/organs/eyes.dm | 3 +++ .../living/carbon/human/species_types/preternis/organs.dm | 8 ++++++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm index 90733df90106..cc1236235cfd 100644 --- a/code/modules/clothing/glasses/_glasses.dm +++ b/code/modules/clothing/glasses/_glasses.dm @@ -149,6 +149,7 @@ flash_protect = -1 // Real vivid purple color_cutoffs = list(50, 10, 30) + lighting_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/clothing/glasses/night name = "night vision goggles" diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 686ade9038dc..eefa6d6b7381 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -45,7 +45,8 @@ item_state = "glasses" flash_protect = -1 // Blue green, dark - color_cutoffs = list(20, 20, 75) //yog change, blue night vision is so much weaker for some reason, so it's been significantly buffed to actually work as night vision + color_cutoffs = list(10, 10, 30) + lighting_cutoff = LIGHTING_CUTOFF_HIGH glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/health/meson @@ -86,7 +87,8 @@ item_state = "glasses" flash_protect = -1 // Pale yellow - color_cutoffs = list(40, 30, 15) + color_cutoffs = list(30, 20, 10) + lighting_cutoff = LIGHTING_CUTOFF_HIGH glass_colour_type = /datum/client_colour/glass_colour/green /obj/item/clothing/glasses/hud/diagnostic/sunglasses diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 755be018ecab..cbfcc08db923 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -178,17 +178,20 @@ desc = "It turned out they had them after all!" sight_flags = SEE_MOBS color_cutoffs = list(25, 5, 42) + lighting_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." color_cutoffs = list(25, 35, 5) + lighting_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" color_cutoffs = list(20, 10, 40) + lighting_cutoff = LIGHTING_CUTOFF_HIGH ///Robotic /obj/item/organ/eyes/robotic diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 20941d24018f..0b65f1bc8ab4 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -16,7 +16,9 @@ var/powered = TRUE var/night_vision = FALSE // This list is used as the color cutoff for the night vision - var/list/light_cutoff = list(25, 10, 60) + var/list/colour_cutoff_list = list(12, 0, 50) + // This variable is the actual night vision strength + var/light_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/organ/eyes/robotic/preternis/ui_action_click() if(damage > low_threshold) @@ -25,9 +27,11 @@ sight_flags = initial(sight_flags) night_vision = !night_vision if (night_vision) - color_cutoffs = light_cutoff.Copy() + color_cutoffs = colour_cutoff_list.Copy() + lighting_cutoff = light_cutoff else color_cutoffs = null + lighting_cutoff = null owner.update_sight() /obj/item/organ/eyes/robotic/preternis/on_life() From 2d14fbae66df4b54865cd284e63c356af1f6db10 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:02:49 -0500 Subject: [PATCH 075/144] tries to fix camera maybe --- .../packages/tgui/interfaces/CameraConsole.js | 143 ------------- .../tgui/interfaces/CameraConsole.tsx | 198 ++++++++++++++++++ tgui/packages/tgui/interfaces/NtosSecurEye.js | 60 ------ .../tgui/interfaces/NtosSecureEye.tsx | 12 ++ .../tgui/styles/interfaces/CameraConsole.scss | 53 ----- tgui/packages/tgui/styles/main.scss | 1 - 6 files changed, 210 insertions(+), 257 deletions(-) delete mode 100644 tgui/packages/tgui/interfaces/CameraConsole.js create mode 100644 tgui/packages/tgui/interfaces/CameraConsole.tsx delete mode 100644 tgui/packages/tgui/interfaces/NtosSecurEye.js create mode 100644 tgui/packages/tgui/interfaces/NtosSecureEye.tsx delete mode 100644 tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js deleted file mode 100644 index 8ece49eff205..000000000000 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ /dev/null @@ -1,143 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Flex, Input, Section } from '../components'; -import { Window } from '../layouts'; - -/** - * Returns previous and next camera names relative to the currently - * active camera. - */ -export const prevNextCamera = (cameras, activeCamera) => { - if (!activeCamera) { - return []; - } - const index = cameras.findIndex(camera => ( - camera.name === activeCamera.name - )); - return [ - cameras[index - 1]?.name, - cameras[index + 1]?.name, - ]; -}; - -/** - * Camera selector. - * - * Filters cameras, applies search terms and sorts the alphabetically. - */ -export const selectCameras = (cameras, searchText = '') => { - const testSearch = createSearch(searchText, camera => camera.name); - return flow([ - // Null camera filter - filter(camera => camera?.name), - // Optional search term - searchText && filter(testSearch), - // Slightly expensive, but way better than sorting in BYOND - sortBy(camera => camera.name), - ])(cameras); -}; - -export const CameraConsole = (props, context) => { - const { act, data } = useBackend(context); - const { mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - -

    - - - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    - - ); -}; - -export const CameraConsoleContent = (props, context) => { - const { act, data } = useBackend(context); - const [ - searchText, - setSearchText, - ] = useLocalState(context, 'searchText', ''); - const { activeCamera } = data; - const cameras = selectCameras(data.cameras, searchText); - return ( - - - setSearchText(value)} /> - - -
    - {cameras.map(camera => ( - // We're not using the component here because performance - // would be absolutely abysmal (50+ ms for each re-render). -
    [act('switch_camera', { - name: camera.name, - }), document.getElementsByClassName('CameraConsole__left')[0].focus()]}> - {camera.name} -
    - ))} -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx new file mode 100644 index 000000000000..4feb31faaf67 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CameraConsole.tsx @@ -0,0 +1,198 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { BooleanLike, classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type Data = { + can_spy: BooleanLike; + mapRef: string; + cameras: Camera[]; + activeCamera: Camera & { status: BooleanLike }; + network: string[]; +}; + +type Camera = { + name: string; +}; + +/** + * Returns previous and next camera names relative to the currently + * active camera. + */ +const prevNextCamera = ( + cameras: Camera[], + activeCamera: Camera & { status: BooleanLike } +) => { + if (!activeCamera) { + return []; + } + const index = cameras.findIndex( + (camera) => camera?.name === activeCamera.name + ); + return [cameras[index - 1]?.name, cameras[index + 1]?.name]; +}; + +/** + * Camera selector. + * + * Filters cameras, applies search terms and sorts the alphabetically. + */ +const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { + const testSearch = createSearch(searchText, (camera: Camera) => camera.name); + + return flow([ + // Null camera filter + filter((camera: Camera) => !!camera?.name), // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy((camera: Camera) => camera.name), + ])(cameras); +}; + +export const CameraConsole = (props, context) => { + return ( + + + + + + ); +}; + +export const CameraContent = (props, context) => { + return ( + + + + + + + + + ); +}; + +const CameraSelector = (props, context) => { + const { act, data } = useBackend(context); + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const { activeCamera } = data; + const cameras = selectCameras(data.cameras, searchText); + + return ( + + + setSearchText(value)} + /> + + +
    + {cameras.map((camera) => ( + // We're not using the component here because performance + // would be absolutely abysmal (50+ ms for each re-render). +
    + act('switch_camera', { + name: camera.name, + }) + }> + {camera.name} +
    + ))} +
    +
    +
    + ); +}; + +const CameraControls = (props, context) => { + const { act, data } = useBackend(context); + const { activeCamera, can_spy, mapRef } = data; + const cameras = selectCameras(data.cameras); + + const [prevCameraName, nextCameraName] = prevNextCamera( + cameras, + activeCamera + ); + + return ( +
    + + + + + {activeCamera?.name ? ( + {activeCamera.name} + ) : ( + No input signal + )} + + + + {!!can_spy && ( +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosSecurEye.js b/tgui/packages/tgui/interfaces/NtosSecurEye.js deleted file mode 100644 index 8d4bc6274528..000000000000 --- a/tgui/packages/tgui/interfaces/NtosSecurEye.js +++ /dev/null @@ -1,60 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { Fragment } from 'inferno'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Input, Section } from '../components'; -import { NtosWindow } from '../layouts'; -import { prevNextCamera, selectCameras, CameraConsoleContent } from './CameraConsole'; -import { logger } from "../logging"; - -export const NtosSecurEye = (props, context) => { - const { act, data, config } = useBackend(context); - const { PC_device_theme, mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - - -
    - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx new file mode 100644 index 000000000000..c445b6f160f5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx @@ -0,0 +1,12 @@ +import { NtosWindow } from '../layouts'; +import { CameraContent } from './CameraConsole'; + +export const NtosSecurEye = (props) => { + return ( + + + + + + ); +}; diff --git a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss deleted file mode 100644 index 7e8f99fdcceb..000000000000 --- a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss +++ /dev/null @@ -1,53 +0,0 @@ -@use '../base.scss'; - -$background-color: rgba(0, 0, 0, 0.33) !default; - -.CameraConsole__left { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: base.em(220px); -} - -.CameraConsole__right { - position: absolute; - top: 0; - bottom: 0; - left: base.em(220px); - right: 0; - background-color: $background-color; -} - -.CameraConsole__toolbar { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.25em 1em 0; -} - -.CameraConsole__toolbarRight { - position: absolute; - top: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.33em 0.5em 0; -} - -.CameraConsole__map { - position: absolute; - top: base.em(26px); - bottom: 0; - left: 0; - right: 0; - margin: 0.5em; - text-align: center; - - .NoticeBox { - margin-top: calc(50% - 2em); - } -} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index d60242ae8627..9a7a42fcf5aa 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -48,7 +48,6 @@ // Interfaces @include meta.load-css('./interfaces/AlertModal.scss'); -@include meta.load-css('./interfaces/CameraConsole.scss'); @include meta.load-css('./interfaces/InspectorBooth.scss'); @include meta.load-css('./interfaces/ListInput.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); From fece8d2354a1a3e3fda95e12b299edcc96c4e297 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:38:46 -0500 Subject: [PATCH 076/144] ok fuck it we ball we ball --- code/__HELPERS/cameras.dm | 35 ++++++ code/_onclick/hud/map_view.dm | 69 +++++++++++ code/game/machinery/camera/tracking.dm | 12 -- code/game/machinery/computer/camera.dm | 157 ++++++++++--------------- yogstation.dme | 2 + 5 files changed, 168 insertions(+), 107 deletions(-) create mode 100644 code/__HELPERS/cameras.dm create mode 100644 code/_onclick/hud/map_view.dm diff --git a/code/__HELPERS/cameras.dm b/code/__HELPERS/cameras.dm new file mode 100644 index 000000000000..9d74f3fe71b4 --- /dev/null +++ b/code/__HELPERS/cameras.dm @@ -0,0 +1,35 @@ +/** + * get_camera_list + * + * Builds a list of all available cameras that can be seen to networks_available + * Args: + * networks_available - List of networks that we use to see which cameras are visible to it. + */ +/proc/get_camera_list(list/networks_available) + var/list/all_camera_list = list() + for(var/obj/machinery/camera/camera as anything in GLOB.cameranet.cameras) + all_camera_list.Add(camera) + + camera_sort(all_camera_list) + + var/list/usable_camera_list = list() + + for(var/obj/machinery/camera/camera as anything in all_camera_list) + var/list/tempnetwork = camera.network & networks_available + if(length(tempnetwork)) + usable_camera_list["[camera.c_tag][camera.can_use() ? null : " (Deactivated)"]"] = camera + + return usable_camera_list + +///Sorts the list of cameras by their c_tag to display to players. +/proc/camera_sort(list/camera_list) + var/obj/machinery/camera/camera_comparing_a + var/obj/machinery/camera/camera_comparing_b + + for(var/i = length(camera_list), i > 0, i--) + for(var/j = 1 to i - 1) + camera_comparing_a = camera_list[j] + camera_comparing_b = camera_list[j + 1] + if(sorttext(camera_comparing_a.c_tag, camera_comparing_b.c_tag) < 0) + camera_list.Swap(j, j + 1) + return camera_list diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm new file mode 100644 index 000000000000..bc304f20f8a1 --- /dev/null +++ b/code/_onclick/hud/map_view.dm @@ -0,0 +1,69 @@ +/** + * A screen object, which acts as a container for turfs and other things + * you want to show on the map, which you usually attach to "vis_contents". + * Additionally manages the plane masters required to display said container contents + */ +INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) +/atom/movable/screen/map_view + name = "screen" + // Map view has to be on the lowest plane to enable proper lighting + layer = GAME_PLANE + plane = GAME_PLANE + del_on_map_removal = FALSE + + // Weakrefs of all our hud viewers -> a weakref to the hud datum they last used + var/list/datum/weakref/viewers_to_huds = list() + +/atom/movable/screen/map_view/Destroy() + for(var/datum/weakref/client_ref in viewers_to_huds) + var/client/our_client = client_ref.resolve() + if(!our_client) + continue + hide_from(our_client.mob) + + return ..() + +/atom/movable/screen/map_view/proc/generate_view(map_key) + // Map keys have to start and end with an A-Z character, + // and definitely NOT with a square bracket or even a number. + // I wasted 6 hours on this. :agony: + // -- Stylemistake + assigned_map = map_key + set_position(1, 1) + +/atom/movable/screen/map_view/proc/display_to(mob/show_to) + show_to.client.register_map_obj(src) + // We need to add planesmasters to the popup, otherwise + // blending fucks up massively. Any planesmaster on the main screen does + // NOT apply to map popups. If there's ever a way to make planesmasters + // omnipresent, then this wouldn't be needed. + // We lazy load this because there's no point creating all these if none's gonna see em + + // Store this info in a client -> hud pattern, so ghosts closing the window nukes the right group + var/datum/weakref/client_ref = WEAKREF(show_to.client) + + var/datum/weakref/hud_ref = viewers_to_huds[client_ref] + var/datum/hud/our_hud = hud_ref?.resolve() + if(our_hud) + return our_hud.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) + + // Generate a new plane group for this case + var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) + viewers_to_huds[client_ref] = WEAKREF(show_to.hud_used) + pop_planes.attach_to(show_to.hud_used) + + return pop_planes + +/atom/movable/screen/map_view/proc/hide_from(mob/hide_from) + hide_from?.canon_client.clear_map(assigned_map) + var/client_ref = WEAKREF(hide_from?.canon_client) + + // Make sure we clear the *right* hud + var/datum/weakref/hud_ref = viewers_to_huds[client_ref] + viewers_to_huds -= client_ref + var/datum/hud/clear_from = hud_ref?.resolve() + if(!clear_from) + return + + var/datum/plane_master_group/popup/pop_planes = clear_from.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) + qdel(pop_planes) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 0976aba838e4..9e7c56217422 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -137,15 +137,3 @@ if (!can_use()) return user.switchCamera(src) - -/proc/camera_sort(list/L) - var/obj/machinery/camera/a - var/obj/machinery/camera/b - - for (var/i = L.len, i > 0, i--) - for (var/j = 1 to i - 1) - a = L[j] - b = L[j + 1] - if (sorttext(a.c_tag, b.c_tag) < 0) - L.Swap(j, j + 1) - return L diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 43f22a4e2754..a8f9e110ea2a 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,64 +1,54 @@ +#define DEFAULT_MAP_SIZE 15 + /obj/machinery/computer/security name = "security camera console" desc = "Used to access the various cameras on the station." icon_screen = "cameras" icon_keyboard = "security_key" circuit = /obj/item/circuitboard/computer/security - light_color = LIGHT_COLOR_RED + light_color = COLOR_SOFT_RED var/list/network = list("ss13") + var/obj/machinery/camera/active_camera + /// The turf where the camera was last updated. + var/turf/last_camera_turf var/list/concurrent_users = list() // Stuff needed to render the map - var/map_name - var/const/default_map_size = 15 - var/atom/movable/screen/cam_screen + var/atom/movable/screen/map_view/cam_screen /// All the plane masters that need to be applied. - var/list/cam_plane_masters var/atom/movable/screen/background/cam_background - var/obj/machinery/camera/active_camera - - var/processing = FALSE - /obj/machinery/computer/security/Initialize(mapload) . = ..() // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. // I wasted 6 hours on this. :agony: - map_name = "camera_console_[REF(src)]_map" + var/map_name = "camera_console_[REF(src)]_map" // Convert networks to lowercase for(var/i in network) network -= i network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/instance = new plane() - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance + cam_screen.generate_view(map_name) cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE /obj/machinery/computer/security/Destroy() - qdel(cam_screen) - QDEL_LIST(cam_plane_masters) - qdel(cam_background) + QDEL_NULL(cam_screen) + QDEL_NULL(cam_background) return ..() /obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui) + . = ..() + // Update UI ui = SStgui.try_update_ui(user, src, ui) - // Show static if can't use the camera - if(!active_camera?.can_use()) - show_camera_static() + + // Update the camera, showing static if necessary and updating data if the location has moved. + update_active_camera_screen() + if(!ui) var/user_ref = REF(user) var/is_living = isliving(user) @@ -71,47 +61,43 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + cam_screen.display_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) ui.open() +/obj/machinery/computer/security/ui_status(mob/user) + . = ..() + if(. == UI_DISABLED) + return UI_CLOSE + return . + /obj/machinery/computer/security/ui_data() var/list/data = list() - data["network"] = network data["activeCamera"] = null if(active_camera) data["activeCamera"] = list( name = active_camera.c_tag, + ref = REF(active_camera), status = active_camera.status, ) return data /obj/machinery/computer/security/ui_static_data() var/list/data = list() - data["mapRef"] = map_name - var/list/cameras = get_available_cameras() + data["network"] = network + data["mapRef"] = cam_screen.assigned_map + var/list/cameras = get_camera_list(network) data["cameras"] = list() for(var/i in cameras) var/obj/machinery/camera/C = cameras[i] data["cameras"] += list(list( name = C.c_tag, + ref = REF(C), )) - return data -/obj/machinery/computer/security/process() - if(active_camera && active_camera.built_in) - if(!active_camera?.can_use()) - show_camera_static() - return TRUE - update_camera(active_camera) - else - STOP_PROCESSING(SSfastprocess, src) - processing = FALSE - ..() + return data /obj/machinery/computer/security/ui_act(action, params) . = ..() @@ -119,42 +105,43 @@ return if(action == "switch_camera") - var/c_tag = params["name"] - var/list/cameras = get_available_cameras() - var/obj/machinery/camera/C = cameras[c_tag] - active_camera = C + var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras + active_camera = selected_camera playsound(src, get_sfx("terminal_type"), 25, FALSE) - - // Show static if can't use the camera - if(!active_camera?.can_use()) - show_camera_static() + if(isnull(active_camera)) return TRUE - - //Assume it's a moving camera. - if(C.built_in) - if(!processing) - START_PROCESSING(SSfastprocess, src) - processing = TRUE - else - STOP_PROCESSING(SSfastprocess, src) - processing = FALSE - - update_camera(C) + update_active_camera_screen() return TRUE -/obj/machinery/computer/security/proc/update_camera(obj/machinery/camera/C) - var/originator = C - if(C.built_in) - originator = get_turf(C.built_in) +/obj/machinery/computer/security/proc/update_active_camera_screen() + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + return var/list/visible_turfs = list() - for(var/turf/T in (C.isXRay() \ - ? range(C.view_range, originator) \ - : view(C.view_range, originator))) - visible_turfs += T + // Get the camera's turf to correctly gather what's visible from it's turf, in case it's located in a moving object (borgs / mechs) + var/new_cam_turf = get_turf(active_camera) + + // If we're not forcing an update for some reason and the cameras are in the same location, + // we don't need to update anything. + // Most security cameras will end here as they're not moving. + if(last_camera_turf == new_cam_turf) + return + + // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. + last_camera_turf = new_cam_turf + + //Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present + var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf) + + for(var/turf/visible_turf in visible_things) + visible_turfs += visible_turf + + //Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area var/list/bbox = get_bbox_of_atoms(visible_turfs) var/size_x = bbox[3] - bbox[1] + 1 var/size_y = bbox[4] - bbox[2] + 1 @@ -164,44 +151,24 @@ cam_background.fill_rect(1, 1, size_x, size_y) /obj/machinery/computer/security/ui_close(mob/user) + . = ..() var/user_ref = REF(user) var/is_living = isliving(user) // Living creature or not, we remove you anyway. concurrent_users -= user_ref // Unregister map objects - user.client.clear_map(map_name) + cam_screen.hide_from(user) // Turn off the console if(length(concurrent_users) == 0 && is_living) active_camera = null + last_camera_turf = null playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE) use_power(0) /obj/machinery/computer/security/proc/show_camera_static() cam_screen.vis_contents.Cut() cam_background.icon_state = "scanline2" - cam_background.fill_rect(1, 1, default_map_size, default_map_size) - -//returns the list of cameras accessible from this computer -/obj/machinery/computer/security/proc/get_available_cameras() - var/list/L = list() - for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) - if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras - continue - L.Add(C) - - var/list/D = list() - - for(var/obj/machinery/camera/C in L) - if(!C.network) - stack_trace("Camera in a cameranet has no camera network") - continue - if(!(islist(C.network))) - stack_trace("Camera in a cameranet has a non-list camera network") - continue - var/list/tempnetwork = C.network & network - if(tempnetwork.len) - D["[C.c_tag]"] = C - return D + cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE) // SECURITY MONITORS diff --git a/yogstation.dme b/yogstation.dme index 374f54ea108d..fac8f88d5fd2 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -217,6 +217,7 @@ #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\AStar.dm" +#include "code\__HELPERS\cameras.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\colors.dm" #include "code\__HELPERS\config.dm" @@ -319,6 +320,7 @@ #include "code\_onclick\hud\lavaland_elite.dm" #include "code\_onclick\hud\living.dm" #include "code\_onclick\hud\map_popups.dm" +#include "code\_onclick\hud\map_view.dm" #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\pai.dm" From 74aa73d32a0080552682932c77f676a4aa73df76 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:45:41 -0500 Subject: [PATCH 077/144] ok lets go back go back go back go back --- code/game/machinery/computer/camera.dm | 157 +++++++++++++++---------- 1 file changed, 95 insertions(+), 62 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index a8f9e110ea2a..43f22a4e2754 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,54 +1,64 @@ -#define DEFAULT_MAP_SIZE 15 - /obj/machinery/computer/security name = "security camera console" desc = "Used to access the various cameras on the station." icon_screen = "cameras" icon_keyboard = "security_key" circuit = /obj/item/circuitboard/computer/security - light_color = COLOR_SOFT_RED + light_color = LIGHT_COLOR_RED var/list/network = list("ss13") - var/obj/machinery/camera/active_camera - /// The turf where the camera was last updated. - var/turf/last_camera_turf var/list/concurrent_users = list() // Stuff needed to render the map - var/atom/movable/screen/map_view/cam_screen + var/map_name + var/const/default_map_size = 15 + var/atom/movable/screen/cam_screen /// All the plane masters that need to be applied. + var/list/cam_plane_masters var/atom/movable/screen/background/cam_background + var/obj/machinery/camera/active_camera + + var/processing = FALSE + /obj/machinery/computer/security/Initialize(mapload) . = ..() // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. // I wasted 6 hours on this. :agony: - var/map_name = "camera_console_[REF(src)]_map" + map_name = "camera_console_[REF(src)]_map" // Convert networks to lowercase for(var/i in network) network -= i network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.generate_view(map_name) + cam_screen.name = "screen" + cam_screen.assigned_map = map_name + cam_screen.del_on_map_removal = FALSE + cam_screen.screen_loc = "[map_name]:1,1" + cam_plane_masters = list() + for(var/plane in subtypesof(/atom/movable/screen/plane_master)) + var/atom/movable/screen/instance = new plane() + instance.assigned_map = map_name + instance.del_on_map_removal = FALSE + instance.screen_loc = "[map_name]:CENTER" + cam_plane_masters += instance cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE /obj/machinery/computer/security/Destroy() - QDEL_NULL(cam_screen) - QDEL_NULL(cam_background) + qdel(cam_screen) + QDEL_LIST(cam_plane_masters) + qdel(cam_background) return ..() /obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui) - . = ..() - // Update UI ui = SStgui.try_update_ui(user, src, ui) - - // Update the camera, showing static if necessary and updating data if the location has moved. - update_active_camera_screen() - + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() if(!ui) var/user_ref = REF(user) var/is_living = isliving(user) @@ -61,87 +71,90 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - cam_screen.display_to(user) + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) ui.open() -/obj/machinery/computer/security/ui_status(mob/user) - . = ..() - if(. == UI_DISABLED) - return UI_CLOSE - return . - /obj/machinery/computer/security/ui_data() var/list/data = list() + data["network"] = network data["activeCamera"] = null if(active_camera) data["activeCamera"] = list( name = active_camera.c_tag, - ref = REF(active_camera), status = active_camera.status, ) return data /obj/machinery/computer/security/ui_static_data() var/list/data = list() - data["network"] = network - data["mapRef"] = cam_screen.assigned_map - var/list/cameras = get_camera_list(network) + data["mapRef"] = map_name + var/list/cameras = get_available_cameras() data["cameras"] = list() for(var/i in cameras) var/obj/machinery/camera/C = cameras[i] data["cameras"] += list(list( name = C.c_tag, - ref = REF(C), )) - return data +/obj/machinery/computer/security/process() + if(active_camera && active_camera.built_in) + if(!active_camera?.can_use()) + show_camera_static() + return TRUE + update_camera(active_camera) + else + STOP_PROCESSING(SSfastprocess, src) + processing = FALSE + ..() + /obj/machinery/computer/security/ui_act(action, params) . = ..() if(.) return if(action == "switch_camera") - var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras - active_camera = selected_camera + var/c_tag = params["name"] + var/list/cameras = get_available_cameras() + var/obj/machinery/camera/C = cameras[c_tag] + active_camera = C playsound(src, get_sfx("terminal_type"), 25, FALSE) - if(isnull(active_camera)) - return TRUE - - update_active_camera_screen() - return TRUE - -/obj/machinery/computer/security/proc/update_active_camera_screen() - // Show static if can't use the camera - if(!active_camera?.can_use()) - show_camera_static() - return + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + return TRUE - var/list/visible_turfs = list() - // Get the camera's turf to correctly gather what's visible from it's turf, in case it's located in a moving object (borgs / mechs) - var/new_cam_turf = get_turf(active_camera) + //Assume it's a moving camera. + if(C.built_in) + if(!processing) + START_PROCESSING(SSfastprocess, src) + processing = TRUE + else + STOP_PROCESSING(SSfastprocess, src) + processing = FALSE - // If we're not forcing an update for some reason and the cameras are in the same location, - // we don't need to update anything. - // Most security cameras will end here as they're not moving. - if(last_camera_turf == new_cam_turf) - return + update_camera(C) - // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. - last_camera_turf = new_cam_turf + return TRUE - //Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present - var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf) +/obj/machinery/computer/security/proc/update_camera(obj/machinery/camera/C) + var/originator = C + if(C.built_in) + originator = get_turf(C.built_in) - for(var/turf/visible_turf in visible_things) - visible_turfs += visible_turf + var/list/visible_turfs = list() + for(var/turf/T in (C.isXRay() \ + ? range(C.view_range, originator) \ + : view(C.view_range, originator))) + visible_turfs += T - //Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area var/list/bbox = get_bbox_of_atoms(visible_turfs) var/size_x = bbox[3] - bbox[1] + 1 var/size_y = bbox[4] - bbox[2] + 1 @@ -151,24 +164,44 @@ cam_background.fill_rect(1, 1, size_x, size_y) /obj/machinery/computer/security/ui_close(mob/user) - . = ..() var/user_ref = REF(user) var/is_living = isliving(user) // Living creature or not, we remove you anyway. concurrent_users -= user_ref // Unregister map objects - cam_screen.hide_from(user) + user.client.clear_map(map_name) // Turn off the console if(length(concurrent_users) == 0 && is_living) active_camera = null - last_camera_turf = null playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE) use_power(0) /obj/machinery/computer/security/proc/show_camera_static() cam_screen.vis_contents.Cut() cam_background.icon_state = "scanline2" - cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE) + cam_background.fill_rect(1, 1, default_map_size, default_map_size) + +//returns the list of cameras accessible from this computer +/obj/machinery/computer/security/proc/get_available_cameras() + var/list/L = list() + for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) + if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras + continue + L.Add(C) + + var/list/D = list() + + for(var/obj/machinery/camera/C in L) + if(!C.network) + stack_trace("Camera in a cameranet has no camera network") + continue + if(!(islist(C.network))) + stack_trace("Camera in a cameranet has a non-list camera network") + continue + var/list/tempnetwork = C.network & network + if(tempnetwork.len) + D["[C.c_tag]"] = C + return D // SECURITY MONITORS From f3ef0a6d748cf2704c94fc47572c8448c8c6b5dd Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:55:54 -0500 Subject: [PATCH 078/144] WORK DAMNIT --- code/_onclick/hud/map_view.dm | 2 +- code/game/machinery/computer/camera.dm | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm index bc304f20f8a1..d571f2cff4ea 100644 --- a/code/_onclick/hud/map_view.dm +++ b/code/_onclick/hud/map_view.dm @@ -22,7 +22,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) hide_from(our_client.mob) return ..() - + /atom/movable/screen/map_view/proc/generate_view(map_key) // Map keys have to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 43f22a4e2754..83854ef1a438 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -32,18 +32,9 @@ network -= i network += lowertext(i) // Initialize map objects + // Initialize map objects cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/instance = new plane() - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance + cam_screen.generate_view(map_name) cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE From 561b45d25931736c6c29f10dfc72042ab42b54ac Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:59:27 -0500 Subject: [PATCH 079/144] ha fuc kyou --- code/game/machinery/computer/camera.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 83854ef1a438..206dd406fcdb 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -12,7 +12,8 @@ // Stuff needed to render the map var/map_name var/const/default_map_size = 15 - var/atom/movable/screen/cam_screen + // Stuff needed to render the map + var/atom/movable/screen/map_view/cam_screen /// All the plane masters that need to be applied. var/list/cam_plane_masters var/atom/movable/screen/background/cam_background @@ -26,7 +27,7 @@ // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. // I wasted 6 hours on this. :agony: - map_name = "camera_console_[REF(src)]_map" + var/map_name = "camera_console_[REF(src)]_map" // Convert networks to lowercase for(var/i in network) network -= i From d3826c107e49caeef8a5fd1d28f7a6c71070c9ed Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:03:18 -0500 Subject: [PATCH 080/144] this maybe --- code/game/machinery/computer/camera.dm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 206dd406fcdb..ee8827e6ebd0 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -63,9 +63,7 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + cam_screen.display_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) From c8a091402aeedf6784453ef779f966f7f8175de6 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:14:58 -0500 Subject: [PATCH 081/144] this doesnt work :( --- code/game/machinery/computer/camera.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index ee8827e6ebd0..a78099ef3abc 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -33,7 +33,6 @@ network -= i network += lowertext(i) // Initialize map objects - // Initialize map objects cam_screen = new cam_screen.generate_view(map_name) cam_background = new @@ -62,8 +61,10 @@ if(length(concurrent_users) == 1 && is_living) playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) - // Register map objects - cam_screen.display_to(user) + /// Register map objects + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) From 4fe889a931126976f9db16d1bdb3082c0ed67a9c Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:18:14 -0500 Subject: [PATCH 082/144] maybe fix maybe --- code/_onclick/hud/map_popups.dm | 9 ++++----- code/game/machinery/computer/camera.dm | 6 ++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index f070084f4770..8a4a1de86977 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -77,10 +77,9 @@ screen_maps[screen_obj.assigned_map] = list() // NOTE: Possibly an expensive operation var/list/screen_map = screen_maps[screen_obj.assigned_map] - if(!screen_map.Find(screen_obj)) - screen_map += screen_obj - if(!screen.Find(screen_obj)) - screen += screen_obj + screen_map |= screen_obj + screen |= screen_obj + /** * Clears the map of registered screen objects. @@ -167,4 +166,4 @@ */ /client/verb/handle_popup_close(window_id as text) set hidden = TRUE - clear_map("[window_id]_map") \ No newline at end of file + clear_map("[window_id]_map") diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index a78099ef3abc..d0ba380e40c7 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -61,10 +61,8 @@ if(length(concurrent_users) == 1 && is_living) playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) - /// Register map objects - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + // Register map objects + cam_screen.display_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) From 6095dec3318dc77449551b0d40fc4d2f2d303d3e Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 16:48:01 -0500 Subject: [PATCH 083/144] fucks everything why do i do this --- code/__DEFINES/cameranets.dm | 5 + code/__DEFINES/turfs.dm | 3 + code/game/mecha/mecha.dm | 3 + .../living/silicon/ai/freelook/cameranet.dm | 136 +++++++++++------- .../mob/living/silicon/ai/freelook/chunk.dm | 119 ++++++++------- yogstation.dme | 1 + 6 files changed, 162 insertions(+), 105 deletions(-) create mode 100644 code/__DEFINES/cameranets.dm diff --git a/code/__DEFINES/cameranets.dm b/code/__DEFINES/cameranets.dm new file mode 100644 index 000000000000..b88678db4a5e --- /dev/null +++ b/code/__DEFINES/cameranets.dm @@ -0,0 +1,5 @@ +/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. +#define CHUNK_SIZE 16 +/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always +#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1)) + diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index 9f54a7fcfbb9..a85ee0a5520d 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -9,6 +9,9 @@ ///Returns all currently loaded turfs #define ALL_TURFS(...) block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)) +/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you +#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0) + #define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) /// The pipes, disposals, and wires are hidden diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 80dd0936ce17..d51308b09dd7 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -92,6 +92,9 @@ var/silicon_pilot = FALSE //set to true if an AI or MMI is piloting. + ///Camera installed into the mech + var/obj/machinery/camera/exosuit/chassis_camera + var/enter_delay = 40 //Time taken to enter the mech var/exit_delay = 20 //Time to exit mech var/destruction_sleep_duration = 20 //Time that mech pilot is put to sleep for if mech is destroyed diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index cb0791cd757a..cf4f9fca9fcb 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,8 +2,6 @@ // // The datum containing all the chunks. -#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. - GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -11,38 +9,54 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/cameras = list() + var/list/obj/machinery/camera/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick - ///The image given to the effect in vis_contents on AI clients - var/image/obscured + + /// List of images cloned by all chunk static images put onto turfs cameras cant see + /// Indexed by the plane offset to use + var/list/image/obscured_images /datum/cameranet/New() - obscured = new('icons/effects/cameravis.dmi') - obscured.plane = CAMERA_STATIC_PLANE - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE + obscured_images = list() + update_offsets(SSmapping.max_plane_offset) + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) + +/datum/cameranet/proc/update_offsets(new_offset) + for(var/i in length(obscured_images) to new_offset) + var/image/obscured = new('icons/effects/cameravis.dmi') + SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE + obscured_images += obscured + +/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + update_offsets(new_offset) /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + if(GET_LOWEST_STACK_OFFSET(z) != 0) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + return chunks["[x],[y],[lowest.z]"] + return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) - var/key = "[x],[y],[z]" + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + var/key = "[x],[y],[lowest.z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, z) + chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) -/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. +/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -53,21 +67,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() + //Get the eye's turf in case it's located in an object like a mecha + var/turf/eye_turf = get_turf(eye) if(eye.loc) - var/x_value = eye.x - var/y_value = eye.y - var/z_value = eye.z - // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) - + var/x1 = max(1, eye_turf.x - static_range) + var/y1 = max(1, eye_turf.y - static_range) + var/x2 = min(world.maxx, eye_turf.x + static_range) + var/y2 = min(world.maxy, eye_turf.y + static_range) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, z_value) + visibleChunks |= getCameraChunk(x, y, eye_turf.z) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -78,7 +89,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -99,10 +110,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) +/** + * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. + * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement + * to change the time between static updates. +*/ +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) + if(updating_camera.can_use()) + majorChunkChange(updating_camera, 1, update_delay_buffer) /** * Never access this proc directly!!!! @@ -110,37 +125,52 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement + * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice) - if(!c) - return +/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) + if(QDELETED(c) && choice == 1) + CRASH("Tried to add a qdeleting camera to the net") var/turf/T = get_turf(c) if(T) - var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras -= c + chunk.cameras["[T.z]"] -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() + chunk.cameras["[T.z]"] |= c + chunk.hasChanged(update_delay_buffer = update_delay_buffer) + +/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] +/// For use in sensitive code, be careful with it +/datum/cameranet/proc/bareMajorChunkChange(turf/changed) + var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) + for(var/y = y1; y <= y2; y += CHUNK_SIZE) + var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) + chunk?.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) + if(!position) + return return checkTurfVis(position) - /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -148,18 +178,22 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) +/datum/cameranet/proc/getTurfVis(turf/position) + RETURN_TYPE(/datum/camerachunk) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(!chunk) + return FALSE + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return chunk /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR + appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index abf891b011ac..31dea0e79df7 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -11,23 +11,24 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid + ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs + ///list of all turfs, associative with that turf's static image + ///turf -> /image var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() - ///images created to represent obscured turfs - var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/z = 0 + var/lower_z + var/upper_z /// Add an AI eye to the chunk, then update if changed. -/datum/camerachunk/proc/add(mob/camera/aiEye/eye) +/datum/camerachunk/proc/add(var/mob/camera/aiEye/eye) eye.visibleCameraChunks += src seenby += eye if(changed) @@ -38,7 +39,7 @@ client.images += active_static_images /// Remove an AI eye from the chunk -/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_static_with_last_chunk = TRUE) +/datum/camerachunk/proc/remove(var/mob/camera/aiEye/eye, remove_static_with_last_chunk = TRUE) eye.visibleCameraChunks -= src seenby -= eye @@ -55,28 +56,33 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. + * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and + * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because + * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0) +/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/datum/camerachunk/proc/update() +/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below +/datum/camerachunk/proc/update(partial_update = FALSE) var/list/updated_visible_turfs = list() - for(var/obj/machinery/camera/current_camera as anything in cameras) - if(!current_camera || !current_camera.can_use()) - continue + for(var/z_level in lower_z to upper_z) + for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -91,31 +97,24 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] - if(!static_image_to_deallocate) + var/image/static_image = obscuredTurfs[visible_turf] + if(!static_image) continue - static_image_to_deallocate.loc = null - active_static_images -= static_image_to_deallocate - inactive_static_images += static_image_to_deallocate - + active_static_images -= static_image obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] - if(!static_image_to_allocate) - stack_trace("somehow a camera chunk ran out of static images!") + var/image/static_image = turfs[obscured_turf] + if(!static_image) + stack_trace("somehow a camera chunk used a turf it didn't contain!!") break - obscuredTurfs[obscured_turf] = static_image_to_allocate - static_image_to_allocate.loc = obscured_turf - - inactive_static_images -= static_image_to_allocate - active_static_images += static_image_to_allocate - + obscuredTurfs[obscured_turf] = static_image + active_static_images += static_image visibleTurfs = updated_visible_turfs changed = FALSE @@ -127,39 +126,51 @@ client.images += active_static_images + /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) +/datum/camerachunk/New(x, y, lower_z) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) src.x = x src.y = y - src.z = z + src.lower_z = lower_z + var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) + src.upper_z = upper_turf.z - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) - if(camera.can_use()) - cameras += camera + for(var/z_level in lower_z to upper_z) + var/list/local_cameras = list() + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(camera.can_use()) + local_cameras += camera - for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) - turfs[t] = t + for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(sillycone.builtInCamera?.can_use()) + local_cameras += sillycone.builtInCamera - for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured) + cameras["[z_level]"] = local_cameras - for(var/obj/machinery/camera/camera as anything in cameras) - if(!camera || !camera.can_use()) - continue + var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level) + 1] + var/turf/chunk_corner = locate(x, y, z_level) + for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself + var/image/our_image = new /image(mirror_from) + our_image.loc = lad + turfs[lad] = our_image + + for(var/obj/machinery/camera/camera as anything in local_cameras) + if(!camera) + continue + + if(!camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = inactive_static_images[inactive_static_images.len] - new_static.loc = obscured_turf + var/image/new_static = turfs[obscured_turf] active_static_images += new_static - inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME -#undef CHUNK_SIZE diff --git a/yogstation.dme b/yogstation.dme index fac8f88d5fd2..8c7a2dac7328 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -41,6 +41,7 @@ #include "code\__DEFINES\bindings.dm" #include "code\__DEFINES\bloodsuckers.dm" #include "code\__DEFINES\callbacks.dm" +#include "code\__DEFINES\cameranets.dm" #include "code\__DEFINES\cargo.dm" #include "code\__DEFINES\chat.dm" #include "code\__DEFINES\cinematics.dm" From 7c91ede8111f5f950af66de875a4211da694f3f7 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:06:54 -0500 Subject: [PATCH 084/144] test update test --- code/_onclick/hud/map_view.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm index d571f2cff4ea..3c8eb4faacad 100644 --- a/code/_onclick/hud/map_view.dm +++ b/code/_onclick/hud/map_view.dm @@ -11,6 +11,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) plane = GAME_PLANE del_on_map_removal = FALSE + // Weakrefs of all our hud viewers -> a weakref to the hud datum they last used var/list/datum/weakref/viewers_to_huds = list() From cf2d5f2aa231544bf4be3d514c0fe3de6aabcba5 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:20:13 -0500 Subject: [PATCH 085/144] Revert "tries to fix camera" This reverts commit 2d14fbae66df4b54865cd284e63c356af1f6db10. --- .../packages/tgui/interfaces/CameraConsole.js | 143 +++++++++++++ .../tgui/interfaces/CameraConsole.tsx | 198 ------------------ tgui/packages/tgui/interfaces/NtosSecurEye.js | 60 ++++++ .../tgui/interfaces/NtosSecureEye.tsx | 12 -- .../tgui/styles/interfaces/CameraConsole.scss | 53 +++++ tgui/packages/tgui/styles/main.scss | 1 + 6 files changed, 257 insertions(+), 210 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/CameraConsole.js delete mode 100644 tgui/packages/tgui/interfaces/CameraConsole.tsx create mode 100644 tgui/packages/tgui/interfaces/NtosSecurEye.js delete mode 100644 tgui/packages/tgui/interfaces/NtosSecureEye.tsx create mode 100644 tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js new file mode 100644 index 000000000000..8ece49eff205 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CameraConsole.js @@ -0,0 +1,143 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Flex, Input, Section } from '../components'; +import { Window } from '../layouts'; + +/** + * Returns previous and next camera names relative to the currently + * active camera. + */ +export const prevNextCamera = (cameras, activeCamera) => { + if (!activeCamera) { + return []; + } + const index = cameras.findIndex(camera => ( + camera.name === activeCamera.name + )); + return [ + cameras[index - 1]?.name, + cameras[index + 1]?.name, + ]; +}; + +/** + * Camera selector. + * + * Filters cameras, applies search terms and sorts the alphabetically. + */ +export const selectCameras = (cameras, searchText = '') => { + const testSearch = createSearch(searchText, camera => camera.name); + return flow([ + // Null camera filter + filter(camera => camera?.name), + // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy(camera => camera.name), + ])(cameras); +}; + +export const CameraConsole = (props, context) => { + const { act, data } = useBackend(context); + const { mapRef, activeCamera } = data; + const cameras = selectCameras(data.cameras); + const [ + prevCameraName, + nextCameraName, + ] = prevNextCamera(cameras, activeCamera); + return ( + +
    + + + +
    +
    +
    + Camera: + {activeCamera + && activeCamera.name + || '—'} +
    +
    +
    + +
    +
    + ); +}; + +export const CameraConsoleContent = (props, context) => { + const { act, data } = useBackend(context); + const [ + searchText, + setSearchText, + ] = useLocalState(context, 'searchText', ''); + const { activeCamera } = data; + const cameras = selectCameras(data.cameras, searchText); + return ( + + + setSearchText(value)} /> + + +
    + {cameras.map(camera => ( + // We're not using the component here because performance + // would be absolutely abysmal (50+ ms for each re-render). +
    [act('switch_camera', { + name: camera.name, + }), document.getElementsByClassName('CameraConsole__left')[0].focus()]}> + {camera.name} +
    + ))} +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx deleted file mode 100644 index 4feb31faaf67..000000000000 --- a/tgui/packages/tgui/interfaces/CameraConsole.tsx +++ /dev/null @@ -1,198 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { BooleanLike, classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components'; -import { Window } from '../layouts'; - -type Data = { - can_spy: BooleanLike; - mapRef: string; - cameras: Camera[]; - activeCamera: Camera & { status: BooleanLike }; - network: string[]; -}; - -type Camera = { - name: string; -}; - -/** - * Returns previous and next camera names relative to the currently - * active camera. - */ -const prevNextCamera = ( - cameras: Camera[], - activeCamera: Camera & { status: BooleanLike } -) => { - if (!activeCamera) { - return []; - } - const index = cameras.findIndex( - (camera) => camera?.name === activeCamera.name - ); - return [cameras[index - 1]?.name, cameras[index + 1]?.name]; -}; - -/** - * Camera selector. - * - * Filters cameras, applies search terms and sorts the alphabetically. - */ -const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { - const testSearch = createSearch(searchText, (camera: Camera) => camera.name); - - return flow([ - // Null camera filter - filter((camera: Camera) => !!camera?.name), // Optional search term - searchText && filter(testSearch), - // Slightly expensive, but way better than sorting in BYOND - sortBy((camera: Camera) => camera.name), - ])(cameras); -}; - -export const CameraConsole = (props, context) => { - return ( - - - - - - ); -}; - -export const CameraContent = (props, context) => { - return ( - - - - - - - - - ); -}; - -const CameraSelector = (props, context) => { - const { act, data } = useBackend(context); - const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); - const { activeCamera } = data; - const cameras = selectCameras(data.cameras, searchText); - - return ( - - - setSearchText(value)} - /> - - -
    - {cameras.map((camera) => ( - // We're not using the component here because performance - // would be absolutely abysmal (50+ ms for each re-render). -
    - act('switch_camera', { - name: camera.name, - }) - }> - {camera.name} -
    - ))} -
    -
    -
    - ); -}; - -const CameraControls = (props, context) => { - const { act, data } = useBackend(context); - const { activeCamera, can_spy, mapRef } = data; - const cameras = selectCameras(data.cameras); - - const [prevCameraName, nextCameraName] = prevNextCamera( - cameras, - activeCamera - ); - - return ( -
    - - - - - {activeCamera?.name ? ( - {activeCamera.name} - ) : ( - No input signal - )} - - - - {!!can_spy && ( -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/NtosSecurEye.js b/tgui/packages/tgui/interfaces/NtosSecurEye.js new file mode 100644 index 000000000000..8d4bc6274528 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosSecurEye.js @@ -0,0 +1,60 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Input, Section } from '../components'; +import { NtosWindow } from '../layouts'; +import { prevNextCamera, selectCameras, CameraConsoleContent } from './CameraConsole'; +import { logger } from "../logging"; + +export const NtosSecurEye = (props, context) => { + const { act, data, config } = useBackend(context); + const { PC_device_theme, mapRef, activeCamera } = data; + const cameras = selectCameras(data.cameras); + const [ + prevCameraName, + nextCameraName, + ] = prevNextCamera(cameras, activeCamera); + return ( + + +
    + +
    +
    +
    + Camera: + {activeCamera + && activeCamera.name + || '—'} +
    +
    +
    + +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx deleted file mode 100644 index c445b6f160f5..000000000000 --- a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { NtosWindow } from '../layouts'; -import { CameraContent } from './CameraConsole'; - -export const NtosSecurEye = (props) => { - return ( - - - - - - ); -}; diff --git a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss new file mode 100644 index 000000000000..7e8f99fdcceb --- /dev/null +++ b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss @@ -0,0 +1,53 @@ +@use '../base.scss'; + +$background-color: rgba(0, 0, 0, 0.33) !default; + +.CameraConsole__left { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: base.em(220px); +} + +.CameraConsole__right { + position: absolute; + top: 0; + bottom: 0; + left: base.em(220px); + right: 0; + background-color: $background-color; +} + +.CameraConsole__toolbar { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2em; + line-height: 2em; + margin: 0.25em 1em 0; +} + +.CameraConsole__toolbarRight { + position: absolute; + top: 0; + right: 0; + height: 2em; + line-height: 2em; + margin: 0.33em 0.5em 0; +} + +.CameraConsole__map { + position: absolute; + top: base.em(26px); + bottom: 0; + left: 0; + right: 0; + margin: 0.5em; + text-align: center; + + .NoticeBox { + margin-top: calc(50% - 2em); + } +} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 9a7a42fcf5aa..d60242ae8627 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -48,6 +48,7 @@ // Interfaces @include meta.load-css('./interfaces/AlertModal.scss'); +@include meta.load-css('./interfaces/CameraConsole.scss'); @include meta.load-css('./interfaces/InspectorBooth.scss'); @include meta.load-css('./interfaces/ListInput.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); From 4a37300f1b4100bee6282034cff2a3bec59afd0f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:38:25 -0500 Subject: [PATCH 086/144] reverts everything I just did peko pain --- code/__DEFINES/cameranets.dm | 5 - code/__DEFINES/turfs.dm | 3 - code/__HELPERS/cameras.dm | 35 ----- code/_onclick/hud/map_popups.dm | 7 +- code/_onclick/hud/map_view.dm | 70 --------- code/game/machinery/camera/tracking.dm | 12 ++ code/game/machinery/computer/camera.dm | 21 ++- .../living/silicon/ai/freelook/cameranet.dm | 137 +++++++----------- .../mob/living/silicon/ai/freelook/chunk.dm | 119 +++++++-------- 9 files changed, 138 insertions(+), 271 deletions(-) delete mode 100644 code/__DEFINES/cameranets.dm delete mode 100644 code/__HELPERS/cameras.dm delete mode 100644 code/_onclick/hud/map_view.dm diff --git a/code/__DEFINES/cameranets.dm b/code/__DEFINES/cameranets.dm deleted file mode 100644 index b88678db4a5e..000000000000 --- a/code/__DEFINES/cameranets.dm +++ /dev/null @@ -1,5 +0,0 @@ -/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. -#define CHUNK_SIZE 16 -/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always -#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1)) - diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index a85ee0a5520d..9f54a7fcfbb9 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -9,9 +9,6 @@ ///Returns all currently loaded turfs #define ALL_TURFS(...) block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz)) -/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you -#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0) - #define IS_OPAQUE_TURF(turf) (turf.directional_opacity == ALL_CARDINALS) /// The pipes, disposals, and wires are hidden diff --git a/code/__HELPERS/cameras.dm b/code/__HELPERS/cameras.dm deleted file mode 100644 index 9d74f3fe71b4..000000000000 --- a/code/__HELPERS/cameras.dm +++ /dev/null @@ -1,35 +0,0 @@ -/** - * get_camera_list - * - * Builds a list of all available cameras that can be seen to networks_available - * Args: - * networks_available - List of networks that we use to see which cameras are visible to it. - */ -/proc/get_camera_list(list/networks_available) - var/list/all_camera_list = list() - for(var/obj/machinery/camera/camera as anything in GLOB.cameranet.cameras) - all_camera_list.Add(camera) - - camera_sort(all_camera_list) - - var/list/usable_camera_list = list() - - for(var/obj/machinery/camera/camera as anything in all_camera_list) - var/list/tempnetwork = camera.network & networks_available - if(length(tempnetwork)) - usable_camera_list["[camera.c_tag][camera.can_use() ? null : " (Deactivated)"]"] = camera - - return usable_camera_list - -///Sorts the list of cameras by their c_tag to display to players. -/proc/camera_sort(list/camera_list) - var/obj/machinery/camera/camera_comparing_a - var/obj/machinery/camera/camera_comparing_b - - for(var/i = length(camera_list), i > 0, i--) - for(var/j = 1 to i - 1) - camera_comparing_a = camera_list[j] - camera_comparing_b = camera_list[j + 1] - if(sorttext(camera_comparing_a.c_tag, camera_comparing_b.c_tag) < 0) - camera_list.Swap(j, j + 1) - return camera_list diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index 8a4a1de86977..07c43eac4491 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -77,9 +77,10 @@ screen_maps[screen_obj.assigned_map] = list() // NOTE: Possibly an expensive operation var/list/screen_map = screen_maps[screen_obj.assigned_map] - screen_map |= screen_obj - screen |= screen_obj - + if(!screen_map.Find(screen_obj)) + screen_map += screen_obj + if(!screen.Find(screen_obj)) + screen += screen_obj /** * Clears the map of registered screen objects. diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm deleted file mode 100644 index 3c8eb4faacad..000000000000 --- a/code/_onclick/hud/map_view.dm +++ /dev/null @@ -1,70 +0,0 @@ -/** - * A screen object, which acts as a container for turfs and other things - * you want to show on the map, which you usually attach to "vis_contents". - * Additionally manages the plane masters required to display said container contents - */ -INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) -/atom/movable/screen/map_view - name = "screen" - // Map view has to be on the lowest plane to enable proper lighting - layer = GAME_PLANE - plane = GAME_PLANE - del_on_map_removal = FALSE - - - // Weakrefs of all our hud viewers -> a weakref to the hud datum they last used - var/list/datum/weakref/viewers_to_huds = list() - -/atom/movable/screen/map_view/Destroy() - for(var/datum/weakref/client_ref in viewers_to_huds) - var/client/our_client = client_ref.resolve() - if(!our_client) - continue - hide_from(our_client.mob) - - return ..() - -/atom/movable/screen/map_view/proc/generate_view(map_key) - // Map keys have to start and end with an A-Z character, - // and definitely NOT with a square bracket or even a number. - // I wasted 6 hours on this. :agony: - // -- Stylemistake - assigned_map = map_key - set_position(1, 1) - -/atom/movable/screen/map_view/proc/display_to(mob/show_to) - show_to.client.register_map_obj(src) - // We need to add planesmasters to the popup, otherwise - // blending fucks up massively. Any planesmaster on the main screen does - // NOT apply to map popups. If there's ever a way to make planesmasters - // omnipresent, then this wouldn't be needed. - // We lazy load this because there's no point creating all these if none's gonna see em - - // Store this info in a client -> hud pattern, so ghosts closing the window nukes the right group - var/datum/weakref/client_ref = WEAKREF(show_to.client) - - var/datum/weakref/hud_ref = viewers_to_huds[client_ref] - var/datum/hud/our_hud = hud_ref?.resolve() - if(our_hud) - return our_hud.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) - - // Generate a new plane group for this case - var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) - viewers_to_huds[client_ref] = WEAKREF(show_to.hud_used) - pop_planes.attach_to(show_to.hud_used) - - return pop_planes - -/atom/movable/screen/map_view/proc/hide_from(mob/hide_from) - hide_from?.canon_client.clear_map(assigned_map) - var/client_ref = WEAKREF(hide_from?.canon_client) - - // Make sure we clear the *right* hud - var/datum/weakref/hud_ref = viewers_to_huds[client_ref] - viewers_to_huds -= client_ref - var/datum/hud/clear_from = hud_ref?.resolve() - if(!clear_from) - return - - var/datum/plane_master_group/popup/pop_planes = clear_from.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) - qdel(pop_planes) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 9e7c56217422..0976aba838e4 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -137,3 +137,15 @@ if (!can_use()) return user.switchCamera(src) + +/proc/camera_sort(list/L) + var/obj/machinery/camera/a + var/obj/machinery/camera/b + + for (var/i = L.len, i > 0, i--) + for (var/j = 1 to i - 1) + a = L[j] + b = L[j + 1] + if (sorttext(a.c_tag, b.c_tag) < 0) + L.Swap(j, j + 1) + return L diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index d0ba380e40c7..43f22a4e2754 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -12,8 +12,7 @@ // Stuff needed to render the map var/map_name var/const/default_map_size = 15 - // Stuff needed to render the map - var/atom/movable/screen/map_view/cam_screen + var/atom/movable/screen/cam_screen /// All the plane masters that need to be applied. var/list/cam_plane_masters var/atom/movable/screen/background/cam_background @@ -27,14 +26,24 @@ // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. // I wasted 6 hours on this. :agony: - var/map_name = "camera_console_[REF(src)]_map" + map_name = "camera_console_[REF(src)]_map" // Convert networks to lowercase for(var/i in network) network -= i network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.generate_view(map_name) + cam_screen.name = "screen" + cam_screen.assigned_map = map_name + cam_screen.del_on_map_removal = FALSE + cam_screen.screen_loc = "[map_name]:1,1" + cam_plane_masters = list() + for(var/plane in subtypesof(/atom/movable/screen/plane_master)) + var/atom/movable/screen/instance = new plane() + instance.assigned_map = map_name + instance.del_on_map_removal = FALSE + instance.screen_loc = "[map_name]:CENTER" + cam_plane_masters += instance cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE @@ -62,7 +71,9 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - cam_screen.display_to(user) + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index cf4f9fca9fcb..efd4184eee1f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,6 +2,8 @@ // // The datum containing all the chunks. +#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. + GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -9,54 +11,38 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/obj/machinery/camera/cameras = list() + var/list/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - - /// List of images cloned by all chunk static images put onto turfs cameras cant see - /// Indexed by the plane offset to use - var/list/image/obscured_images + // The object used for the clickable stat() button. + var/obj/effect/statclick/statclick + ///The image given to the effect in vis_contents on AI clients + var/image/obscured /datum/cameranet/New() - obscured_images = list() - update_offsets(SSmapping.max_plane_offset) - RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) - -/datum/cameranet/proc/update_offsets(new_offset) - for(var/i in length(obscured_images) to new_offset) - var/image/obscured = new('icons/effects/cameravis.dmi') - SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE - obscured_images += obscured - -/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) - SIGNAL_HANDLER - update_offsets(new_offset) + obscured = new('icons/effects/cameravis.dmi') + obscured.plane = CAMERA_STATIC_PLANE + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - if(GET_LOWEST_STACK_OFFSET(z) != 0) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - return chunks["[x],[y],[lowest.z]"] - + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - var/key = "[x],[y],[lowest.z]" + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) + var/key = "[x],[y],[z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) + chunks[key] = . = new /datum/camerachunk(x, y, z) -/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. +/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -67,18 +53,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() - //Get the eye's turf in case it's located in an object like a mecha - var/turf/eye_turf = get_turf(eye) if(eye.loc) + var/x_value = eye.x + var/y_value = eye.y + var/z_value = eye.z + // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(1, eye_turf.x - static_range) - var/y1 = max(1, eye_turf.y - static_range) - var/x2 = min(world.maxx, eye_turf.x + static_range) - var/y2 = min(world.maxy, eye_turf.y + static_range) + var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, eye_turf.z) + visibleChunks |= getCameraChunk(x, y, z_value) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -89,7 +78,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -110,14 +99,10 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/** - * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. - * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement - * to change the time between static updates. -*/ -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) - if(updating_camera.can_use()) - majorChunkChange(updating_camera, 1, update_delay_buffer) +/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) /** * Never access this proc directly!!!! @@ -125,52 +110,37 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. - * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement - * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) - if(QDELETED(c) && choice == 1) - CRASH("Tried to add a qdeleting camera to the net") +/datum/cameranet/proc/majorChunkChange(atom/c, choice) + if(!c) + return var/turf/T = get_turf(c) if(T) - var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) + var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras["[T.z]"] -= c + chunk.cameras -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras["[T.z]"] |= c - chunk.hasChanged(update_delay_buffer = update_delay_buffer) - -/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] -/// For use in sensitive code, be careful with it -/datum/cameranet/proc/bareMajorChunkChange(turf/changed) - var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) - for(var/x = x1; x <= x2; x += CHUNK_SIZE) - for(var/y = y1; y <= y2; y += CHUNK_SIZE) - var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) - chunk?.hasChanged() + chunk.cameras |= c + chunk.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) - if(!position) - return return checkTurfVis(position) + /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -178,25 +148,22 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/getTurfVis(turf/position) - RETURN_TYPE(/datum/camerachunk) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) - if(!chunk) - return FALSE - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return chunk +/datum/cameranet/proc/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE + appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT + layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 31dea0e79df7..abf891b011ac 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -11,24 +11,23 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid - ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs, associative with that turf's static image - ///turf -> /image + ///list of all turfs var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() + ///images created to represent obscured turfs + var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/lower_z - var/upper_z + var/z = 0 /// Add an AI eye to the chunk, then update if changed. -/datum/camerachunk/proc/add(var/mob/camera/aiEye/eye) +/datum/camerachunk/proc/add(mob/camera/aiEye/eye) eye.visibleCameraChunks += src seenby += eye if(changed) @@ -39,7 +38,7 @@ client.images += active_static_images /// Remove an AI eye from the chunk -/datum/camerachunk/proc/remove(var/mob/camera/aiEye/eye, remove_static_with_last_chunk = TRUE) +/datum/camerachunk/proc/remove(mob/camera/aiEye/eye, remove_static_with_last_chunk = TRUE) eye.visibleCameraChunks -= src seenby -= eye @@ -56,33 +55,28 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. - * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and - * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because - * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) +/datum/camerachunk/proc/hasChanged(update_now = 0) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below -/datum/camerachunk/proc/update(partial_update = FALSE) +/datum/camerachunk/proc/update() var/list/updated_visible_turfs = list() - for(var/z_level in lower_z to upper_z) - for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) - if(!current_camera || !current_camera.can_use()) - continue + for(var/obj/machinery/camera/current_camera as anything in cameras) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -97,24 +91,31 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image = obscuredTurfs[visible_turf] - if(!static_image) + var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] + if(!static_image_to_deallocate) continue - active_static_images -= static_image + static_image_to_deallocate.loc = null + active_static_images -= static_image_to_deallocate + inactive_static_images += static_image_to_deallocate + obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image = turfs[obscured_turf] - if(!static_image) - stack_trace("somehow a camera chunk used a turf it didn't contain!!") + var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] + if(!static_image_to_allocate) + stack_trace("somehow a camera chunk ran out of static images!") break - obscuredTurfs[obscured_turf] = static_image - active_static_images += static_image + obscuredTurfs[obscured_turf] = static_image_to_allocate + static_image_to_allocate.loc = obscured_turf + + inactive_static_images -= static_image_to_allocate + active_static_images += static_image_to_allocate + visibleTurfs = updated_visible_turfs changed = FALSE @@ -126,51 +127,39 @@ client.images += active_static_images - /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, lower_z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) +/datum/camerachunk/New(x, y, z) + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) src.x = x src.y = y - src.lower_z = lower_z - var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) - src.upper_z = upper_turf.z - - for(var/z_level in lower_z to upper_z) - var/list/local_cameras = list() - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(camera.can_use()) - local_cameras += camera + src.z = z - for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(sillycone.builtInCamera?.can_use()) - local_cameras += sillycone.builtInCamera + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) + if(camera.can_use()) + cameras += camera - cameras["[z_level]"] = local_cameras + for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) + turfs[t] = t - var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level) + 1] - var/turf/chunk_corner = locate(x, y, z_level) - for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself - var/image/our_image = new /image(mirror_from) - our_image.loc = lad - turfs[lad] = our_image + for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses + inactive_static_images += new/image(GLOB.cameranet.obscured) - for(var/obj/machinery/camera/camera as anything in local_cameras) - if(!camera) - continue - - if(!camera.can_use()) - continue + for(var/obj/machinery/camera/camera as anything in cameras) + if(!camera || !camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = turfs[obscured_turf] + var/image/new_static = inactive_static_images[inactive_static_images.len] + new_static.loc = obscured_turf active_static_images += new_static + inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME +#undef CHUNK_SIZE From a4d9e04e523b7d59c2e5c6a9cd3c1396a46b40b2 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:40:33 -0500 Subject: [PATCH 087/144] bye bitch --- yogstation.dme | 3 --- 1 file changed, 3 deletions(-) diff --git a/yogstation.dme b/yogstation.dme index 8c7a2dac7328..374f54ea108d 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -41,7 +41,6 @@ #include "code\__DEFINES\bindings.dm" #include "code\__DEFINES\bloodsuckers.dm" #include "code\__DEFINES\callbacks.dm" -#include "code\__DEFINES\cameranets.dm" #include "code\__DEFINES\cargo.dm" #include "code\__DEFINES\chat.dm" #include "code\__DEFINES\cinematics.dm" @@ -218,7 +217,6 @@ #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\AStar.dm" -#include "code\__HELPERS\cameras.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\colors.dm" #include "code\__HELPERS\config.dm" @@ -321,7 +319,6 @@ #include "code\_onclick\hud\lavaland_elite.dm" #include "code\_onclick\hud\living.dm" #include "code\_onclick\hud\map_popups.dm" -#include "code\_onclick\hud\map_view.dm" #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\pai.dm" From 77738b588765d8dd0d99ec568330face3ff4b8ad Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:49:09 -0500 Subject: [PATCH 088/144] oh yeah add this I guess --- code/__DEFINES/layers.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index e81166024dcc..38bd74949388 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -75,6 +75,7 @@ #define PIPECRAWL_IMAGES_PLANE 20 ///AI Camera Static +#define CAMERA_STATIC_LAYER 21 #define CAMERA_STATIC_PLANE 21 ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else From 0e421ebf5f1d3702739fd7078cf53a8d0ef964a6 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 19:36:45 -0500 Subject: [PATCH 089/144] Fucks up the camera net + chunk why --- .../living/silicon/ai/freelook/cameranet.dm | 144 +++++++++++------- .../mob/living/silicon/ai/freelook/chunk.dm | 118 +++++++------- 2 files changed, 158 insertions(+), 104 deletions(-) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index efd4184eee1f..5f9bea5860b3 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,9 +1,14 @@ +/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. +#define CHUNK_SIZE 16 +/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always +#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1)) + + + // CAMERA NET // // The datum containing all the chunks. -#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. - GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -11,38 +16,54 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/cameras = list() + var/list/obj/machinery/camera/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick - ///The image given to the effect in vis_contents on AI clients - var/image/obscured + + /// List of images cloned by all chunk static images put onto turfs cameras cant see + /// Indexed by the plane offset to use + var/list/image/obscured_images /datum/cameranet/New() - obscured = new('icons/effects/cameravis.dmi') - obscured.plane = CAMERA_STATIC_PLANE - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE + obscured_images = list() + update_offsets(SSmapping.max_plane_offset) + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) + +/datum/cameranet/proc/update_offsets(new_offset) + for(var/i in length(obscured_images) to new_offset) + var/image/obscured = new('icons/effects/cameravis.dmi') + SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE + obscured_images += obscured + +/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + update_offsets(new_offset) /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + if(GET_LOWEST_STACK_OFFSET(z) != 0) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + return chunks["[x],[y],[lowest.z]"] + return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) - var/key = "[x],[y],[z]" + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + var/key = "[x],[y],[lowest.z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, z) + chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) -/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. +/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -53,21 +74,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() + //Get the eye's turf in case it's located in an object like a mecha + var/turf/eye_turf = get_turf(eye) if(eye.loc) - var/x_value = eye.x - var/y_value = eye.y - var/z_value = eye.z - // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) - + var/x1 = max(1, eye_turf.x - static_range) + var/y1 = max(1, eye_turf.y - static_range) + var/x2 = min(world.maxx, eye_turf.x + static_range) + var/y2 = min(world.maxy, eye_turf.y + static_range) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, z_value) + visibleChunks |= getCameraChunk(x, y, eye_turf.z) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -78,7 +96,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -99,10 +117,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) +/** + * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. + * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement + * to change the time between static updates. +*/ +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) + if(updating_camera.can_use()) + majorChunkChange(updating_camera, 1, update_delay_buffer) /** * Never access this proc directly!!!! @@ -110,37 +132,52 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement + * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice) - if(!c) - return +/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) + if(QDELETED(c) && choice == 1) + CRASH("Tried to add a qdeleting camera to the net") var/turf/T = get_turf(c) if(T) - var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras -= c + chunk.cameras["[T.z]"] -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() + chunk.cameras["[T.z]"] |= c + chunk.hasChanged(update_delay_buffer = update_delay_buffer) + +/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] +/// For use in sensitive code, be careful with it +/datum/cameranet/proc/bareMajorChunkChange(turf/changed) + var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) + for(var/y = y1; y <= y2; y += CHUNK_SIZE) + var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) + chunk?.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) + if(!position) + return return checkTurfVis(position) - /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -148,22 +185,25 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) +/datum/cameranet/proc/getTurfVis(turf/position) + RETURN_TYPE(/datum/camerachunk) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(!chunk) + return FALSE + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return chunk /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR + appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT - layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index abf891b011ac..539e783fe036 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,5 +1,8 @@ #define UPDATE_BUFFER_TIME (2.5 SECONDS) +/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you +#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0) + // CAMERA CHUNK // // A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. @@ -11,20 +14,21 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid + ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs + ///list of all turfs, associative with that turf's static image + ///turf -> /image var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() - ///images created to represent obscured turfs - var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/z = 0 + var/lower_z + var/upper_z /// Add an AI eye to the chunk, then update if changed. /datum/camerachunk/proc/add(mob/camera/aiEye/eye) @@ -55,28 +59,33 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. + * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and + * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because + * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0) +/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/datum/camerachunk/proc/update() +/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below +/datum/camerachunk/proc/update(partial_update = FALSE) var/list/updated_visible_turfs = list() - for(var/obj/machinery/camera/current_camera as anything in cameras) - if(!current_camera || !current_camera.can_use()) - continue + for(var/z_level in lower_z to upper_z) + for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -91,31 +100,24 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] - if(!static_image_to_deallocate) + var/image/static_image = obscuredTurfs[visible_turf] + if(!static_image) continue - static_image_to_deallocate.loc = null - active_static_images -= static_image_to_deallocate - inactive_static_images += static_image_to_deallocate - + active_static_images -= static_image obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] - if(!static_image_to_allocate) - stack_trace("somehow a camera chunk ran out of static images!") + var/image/static_image = turfs[obscured_turf] + if(!static_image) + stack_trace("somehow a camera chunk used a turf it didn't contain!!") break - obscuredTurfs[obscured_turf] = static_image_to_allocate - static_image_to_allocate.loc = obscured_turf - - inactive_static_images -= static_image_to_allocate - active_static_images += static_image_to_allocate - + obscuredTurfs[obscured_turf] = static_image + active_static_images += static_image visibleTurfs = updated_visible_turfs changed = FALSE @@ -127,39 +129,51 @@ client.images += active_static_images + /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) +/datum/camerachunk/New(x, y, lower_z) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) src.x = x src.y = y - src.z = z + src.lower_z = lower_z + var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) + src.upper_z = upper_turf.z - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) - if(camera.can_use()) - cameras += camera + for(var/z_level in lower_z to upper_z) + var/list/local_cameras = list() + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(camera.can_use()) + local_cameras += camera - for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) - turfs[t] = t + for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(sillycone.builtInCamera?.can_use()) + local_cameras += sillycone.builtInCamera - for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured) + cameras["[z_level]"] = local_cameras - for(var/obj/machinery/camera/camera as anything in cameras) - if(!camera || !camera.can_use()) - continue + var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level)] + var/turf/chunk_corner = locate(x, y, z_level) + for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself + var/image/our_image = new /image(mirror_from) + our_image.loc = lad + turfs[lad] = our_image + + for(var/obj/machinery/camera/camera as anything in local_cameras) + if(!camera) + continue + + if(!camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = inactive_static_images[inactive_static_images.len] - new_static.loc = obscured_turf + var/image/new_static = turfs[obscured_turf] active_static_images += new_static - inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME -#undef CHUNK_SIZE From 98c5ef1b93b2c695b04fceee43f6f87a446227fe Mon Sep 17 00:00:00 2001 From: Molti Date: Fri, 1 Dec 2023 18:48:47 -0600 Subject: [PATCH 090/144] test maybe revert --- code/__DEFINES/layers.dm | 1 - .../machinery/computer/camera_advanced.dm | 1 + .../mob/living/silicon/ai/freelook/eye.dm | 71 +++++++++++-------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 38bd74949388..e81166024dcc 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -75,7 +75,6 @@ #define PIPECRAWL_IMAGES_PLANE 20 ///AI Camera Static -#define CAMERA_STATIC_LAYER 21 #define CAMERA_STATIC_PLANE 21 ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 0ddf5f2005c8..03012daa78dc 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -204,6 +204,7 @@ if(visible_icon && eye_user.client) eye_user.client.images -= user_image user_image = image(icon,loc,icon_state,FLY_LAYER) + SET_PLANE(user_image, ABOVE_GAME_PLANE, destination) eye_user.client.images += user_image /mob/camera/aiEye/remote/relaymove(mob/user,direct) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 0486fda51619..6b7bdf5c2b54 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -17,6 +17,7 @@ var/static_visibility_range = 16 var/ai_detector_visible = TRUE var/ai_detector_color = COLOR_RED + interaction_range = INFINITY /mob/camera/aiEye/Initialize(mapload) . = ..() @@ -25,6 +26,13 @@ update_ai_detect_hud() setLoc(loc, TRUE) +/mob/camera/aiEye/examine(mob/user) //Displays a silicon's laws to ghosts + . = ..() + if(istype(ai) && ai.laws && isobserver(user)) + . += "[ai] has the following laws:" + for(var/law in ai.laws.get_law_list(include_zeroth = TRUE)) + . += law + /mob/camera/aiEye/proc/update_ai_detect_hud() var/datum/atom_hud/ai_detector/hud = GLOB.huds[DATA_HUD_AI_DETECT] var/list/old_images = hud_list[AI_DETECT_HUD] @@ -71,30 +79,32 @@ // It will also stream the chunk that the new loc is in. /mob/camera/aiEye/proc/setLoc(T, force_update = FALSE) - if(ai) - if(!(isturf(ai.loc) || istype(ai.loc, /obj/machinery/ai/data_core))) - return - T = get_turf(T) - if(!force_update && (T == get_turf(src)) ) - return //we are already here! - if (T) - forceMove(T) - else - moveToNullspace() - if(use_static) - ai.camera_visibility(src) - if(ai.client && !ai.multicam_on) - ai.client.eye = src - update_ai_detect_hud() - update_parallax_contents() - //Holopad - if(istype(ai.current, /obj/machinery/holopad)) - var/obj/machinery/holopad/H = ai.current - H.move_hologram(ai, T) - if(ai.camera_light_on) - ai.light_cameras() - if(ai.master_multicam) - ai.master_multicam.refresh_view() + if(!ai) + return + if(!(isturf(ai.loc) || istype(ai.loc, /obj/machinery/ai/data_core))) + return + T = get_turf(T) + if(!force_update && (T == get_turf(src)) ) + return //we are already here! + if (T) + forceMove(T) + else + moveToNullspace() + if(use_static) + ai.camera_visibility(src) + if(ai.client && !ai.multicam_on) + ai.client.eye = src + update_ai_detect_hud() + update_parallax_contents() + //Holopad + if(istype(ai.current, /obj/machinery/holopad)) + var/obj/machinery/holopad/H = ai.current + H.move_hologram(ai, T) + + if(ai.camera_light_on) + ai.light_cameras() + if(ai.master_multicam) + ai.master_multicam.refresh_view() /mob/camera/aiEye/Move() return 0 @@ -120,12 +130,13 @@ return ..() /atom/proc/move_camera_by_click() - if(isAI(usr)) - var/mob/living/silicon/ai/AI = usr - if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)) && (AI.eyeobj.z == z)) - AI.cameraFollow = null - if (isturf(loc) || isturf(src)) - AI.eyeobj.setLoc(src) + if(!isAI(usr)) + return + var/mob/living/silicon/ai/AI = usr + if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)) && (AI.eyeobj.z == z)) + AI.cameraFollow = null + if (isturf(loc) || isturf(src)) + AI.eyeobj.setLoc(src) // This will move the AIEye. It will also cause lights near the eye to light up, if toggled. // This is handled in the proc below this one. From 3cf31d0720aeff979fde26036f2f70002ab54634 Mon Sep 17 00:00:00 2001 From: Molti Date: Fri, 1 Dec 2023 18:55:38 -0600 Subject: [PATCH 091/144] Revert "test maybe revert" This reverts commit 98c5ef1b93b2c695b04fceee43f6f87a446227fe. --- code/__DEFINES/layers.dm | 1 + .../machinery/computer/camera_advanced.dm | 1 - .../mob/living/silicon/ai/freelook/eye.dm | 71 ++++++++----------- 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index e81166024dcc..38bd74949388 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -75,6 +75,7 @@ #define PIPECRAWL_IMAGES_PLANE 20 ///AI Camera Static +#define CAMERA_STATIC_LAYER 21 #define CAMERA_STATIC_PLANE 21 ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index 03012daa78dc..0ddf5f2005c8 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -204,7 +204,6 @@ if(visible_icon && eye_user.client) eye_user.client.images -= user_image user_image = image(icon,loc,icon_state,FLY_LAYER) - SET_PLANE(user_image, ABOVE_GAME_PLANE, destination) eye_user.client.images += user_image /mob/camera/aiEye/remote/relaymove(mob/user,direct) diff --git a/code/modules/mob/living/silicon/ai/freelook/eye.dm b/code/modules/mob/living/silicon/ai/freelook/eye.dm index 6b7bdf5c2b54..0486fda51619 100644 --- a/code/modules/mob/living/silicon/ai/freelook/eye.dm +++ b/code/modules/mob/living/silicon/ai/freelook/eye.dm @@ -17,7 +17,6 @@ var/static_visibility_range = 16 var/ai_detector_visible = TRUE var/ai_detector_color = COLOR_RED - interaction_range = INFINITY /mob/camera/aiEye/Initialize(mapload) . = ..() @@ -26,13 +25,6 @@ update_ai_detect_hud() setLoc(loc, TRUE) -/mob/camera/aiEye/examine(mob/user) //Displays a silicon's laws to ghosts - . = ..() - if(istype(ai) && ai.laws && isobserver(user)) - . += "[ai] has the following laws:" - for(var/law in ai.laws.get_law_list(include_zeroth = TRUE)) - . += law - /mob/camera/aiEye/proc/update_ai_detect_hud() var/datum/atom_hud/ai_detector/hud = GLOB.huds[DATA_HUD_AI_DETECT] var/list/old_images = hud_list[AI_DETECT_HUD] @@ -79,32 +71,30 @@ // It will also stream the chunk that the new loc is in. /mob/camera/aiEye/proc/setLoc(T, force_update = FALSE) - if(!ai) - return - if(!(isturf(ai.loc) || istype(ai.loc, /obj/machinery/ai/data_core))) - return - T = get_turf(T) - if(!force_update && (T == get_turf(src)) ) - return //we are already here! - if (T) - forceMove(T) - else - moveToNullspace() - if(use_static) - ai.camera_visibility(src) - if(ai.client && !ai.multicam_on) - ai.client.eye = src - update_ai_detect_hud() - update_parallax_contents() - //Holopad - if(istype(ai.current, /obj/machinery/holopad)) - var/obj/machinery/holopad/H = ai.current - H.move_hologram(ai, T) - - if(ai.camera_light_on) - ai.light_cameras() - if(ai.master_multicam) - ai.master_multicam.refresh_view() + if(ai) + if(!(isturf(ai.loc) || istype(ai.loc, /obj/machinery/ai/data_core))) + return + T = get_turf(T) + if(!force_update && (T == get_turf(src)) ) + return //we are already here! + if (T) + forceMove(T) + else + moveToNullspace() + if(use_static) + ai.camera_visibility(src) + if(ai.client && !ai.multicam_on) + ai.client.eye = src + update_ai_detect_hud() + update_parallax_contents() + //Holopad + if(istype(ai.current, /obj/machinery/holopad)) + var/obj/machinery/holopad/H = ai.current + H.move_hologram(ai, T) + if(ai.camera_light_on) + ai.light_cameras() + if(ai.master_multicam) + ai.master_multicam.refresh_view() /mob/camera/aiEye/Move() return 0 @@ -130,13 +120,12 @@ return ..() /atom/proc/move_camera_by_click() - if(!isAI(usr)) - return - var/mob/living/silicon/ai/AI = usr - if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)) && (AI.eyeobj.z == z)) - AI.cameraFollow = null - if (isturf(loc) || isturf(src)) - AI.eyeobj.setLoc(src) + if(isAI(usr)) + var/mob/living/silicon/ai/AI = usr + if(AI.eyeobj && (AI.multicam_on || (AI.client.eye == AI.eyeobj)) && (AI.eyeobj.z == z)) + AI.cameraFollow = null + if (isturf(loc) || isturf(src)) + AI.eyeobj.setLoc(src) // This will move the AIEye. It will also cause lights near the eye to light up, if toggled. // This is handled in the proc below this one. From 4b3e35b0e7b7d5550a8377051b88477dab58bf02 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 1 Dec 2023 21:32:52 -0500 Subject: [PATCH 092/144] Revert "Fucks up the camera net + chunk" This reverts commit 0e421ebf5f1d3702739fd7078cf53a8d0ef964a6. --- .../living/silicon/ai/freelook/cameranet.dm | 144 +++++++----------- .../mob/living/silicon/ai/freelook/chunk.dm | 118 +++++++------- 2 files changed, 104 insertions(+), 158 deletions(-) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 5f9bea5860b3..efd4184eee1f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,14 +1,9 @@ -/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. -#define CHUNK_SIZE 16 -/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always -#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1)) - - - // CAMERA NET // // The datum containing all the chunks. +#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. + GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -16,54 +11,38 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/obj/machinery/camera/cameras = list() + var/list/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - - /// List of images cloned by all chunk static images put onto turfs cameras cant see - /// Indexed by the plane offset to use - var/list/image/obscured_images + // The object used for the clickable stat() button. + var/obj/effect/statclick/statclick + ///The image given to the effect in vis_contents on AI clients + var/image/obscured /datum/cameranet/New() - obscured_images = list() - update_offsets(SSmapping.max_plane_offset) - RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) - -/datum/cameranet/proc/update_offsets(new_offset) - for(var/i in length(obscured_images) to new_offset) - var/image/obscured = new('icons/effects/cameravis.dmi') - SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE - obscured_images += obscured - -/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) - SIGNAL_HANDLER - update_offsets(new_offset) + obscured = new('icons/effects/cameravis.dmi') + obscured.plane = CAMERA_STATIC_PLANE + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - if(GET_LOWEST_STACK_OFFSET(z) != 0) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - return chunks["[x],[y],[lowest.z]"] - + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - var/key = "[x],[y],[lowest.z]" + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) + var/key = "[x],[y],[z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) + chunks[key] = . = new /datum/camerachunk(x, y, z) -/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. +/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -74,18 +53,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() - //Get the eye's turf in case it's located in an object like a mecha - var/turf/eye_turf = get_turf(eye) if(eye.loc) + var/x_value = eye.x + var/y_value = eye.y + var/z_value = eye.z + // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(1, eye_turf.x - static_range) - var/y1 = max(1, eye_turf.y - static_range) - var/x2 = min(world.maxx, eye_turf.x + static_range) - var/y2 = min(world.maxy, eye_turf.y + static_range) + var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, eye_turf.z) + visibleChunks |= getCameraChunk(x, y, z_value) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -96,7 +78,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -117,14 +99,10 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/** - * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. - * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement - * to change the time between static updates. -*/ -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) - if(updating_camera.can_use()) - majorChunkChange(updating_camera, 1, update_delay_buffer) +/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) /** * Never access this proc directly!!!! @@ -132,52 +110,37 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. - * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement - * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) - if(QDELETED(c) && choice == 1) - CRASH("Tried to add a qdeleting camera to the net") +/datum/cameranet/proc/majorChunkChange(atom/c, choice) + if(!c) + return var/turf/T = get_turf(c) if(T) - var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) + var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras["[T.z]"] -= c + chunk.cameras -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras["[T.z]"] |= c - chunk.hasChanged(update_delay_buffer = update_delay_buffer) - -/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] -/// For use in sensitive code, be careful with it -/datum/cameranet/proc/bareMajorChunkChange(turf/changed) - var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) - for(var/x = x1; x <= x2; x += CHUNK_SIZE) - for(var/y = y1; y <= y2; y += CHUNK_SIZE) - var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) - chunk?.hasChanged() + chunk.cameras |= c + chunk.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) - if(!position) - return return checkTurfVis(position) + /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -185,25 +148,22 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/getTurfVis(turf/position) - RETURN_TYPE(/datum/camerachunk) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) - if(!chunk) - return FALSE - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return chunk +/datum/cameranet/proc/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE + appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT + layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index 539e783fe036..abf891b011ac 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -1,8 +1,5 @@ #define UPDATE_BUFFER_TIME (2.5 SECONDS) -/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you -#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0) - // CAMERA CHUNK // // A 16x16 grid of the map with a list of turfs that can be seen, are visible and are dimmed. @@ -14,21 +11,20 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid - ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs, associative with that turf's static image - ///turf -> /image + ///list of all turfs var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() + ///images created to represent obscured turfs + var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/lower_z - var/upper_z + var/z = 0 /// Add an AI eye to the chunk, then update if changed. /datum/camerachunk/proc/add(mob/camera/aiEye/eye) @@ -59,33 +55,28 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. - * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and - * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because - * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) +/datum/camerachunk/proc/hasChanged(update_now = 0) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below -/datum/camerachunk/proc/update(partial_update = FALSE) +/datum/camerachunk/proc/update() var/list/updated_visible_turfs = list() - for(var/z_level in lower_z to upper_z) - for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) - if(!current_camera || !current_camera.can_use()) - continue + for(var/obj/machinery/camera/current_camera as anything in cameras) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -100,24 +91,31 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image = obscuredTurfs[visible_turf] - if(!static_image) + var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] + if(!static_image_to_deallocate) continue - active_static_images -= static_image + static_image_to_deallocate.loc = null + active_static_images -= static_image_to_deallocate + inactive_static_images += static_image_to_deallocate + obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image = turfs[obscured_turf] - if(!static_image) - stack_trace("somehow a camera chunk used a turf it didn't contain!!") + var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] + if(!static_image_to_allocate) + stack_trace("somehow a camera chunk ran out of static images!") break - obscuredTurfs[obscured_turf] = static_image - active_static_images += static_image + obscuredTurfs[obscured_turf] = static_image_to_allocate + static_image_to_allocate.loc = obscured_turf + + inactive_static_images -= static_image_to_allocate + active_static_images += static_image_to_allocate + visibleTurfs = updated_visible_turfs changed = FALSE @@ -129,51 +127,39 @@ client.images += active_static_images - /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, lower_z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) +/datum/camerachunk/New(x, y, z) + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) src.x = x src.y = y - src.lower_z = lower_z - var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) - src.upper_z = upper_turf.z - - for(var/z_level in lower_z to upper_z) - var/list/local_cameras = list() - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(camera.can_use()) - local_cameras += camera + src.z = z - for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(sillycone.builtInCamera?.can_use()) - local_cameras += sillycone.builtInCamera + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) + if(camera.can_use()) + cameras += camera - cameras["[z_level]"] = local_cameras + for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) + turfs[t] = t - var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level)] - var/turf/chunk_corner = locate(x, y, z_level) - for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself - var/image/our_image = new /image(mirror_from) - our_image.loc = lad - turfs[lad] = our_image + for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses + inactive_static_images += new/image(GLOB.cameranet.obscured) - for(var/obj/machinery/camera/camera as anything in local_cameras) - if(!camera) - continue - - if(!camera.can_use()) - continue + for(var/obj/machinery/camera/camera as anything in cameras) + if(!camera || !camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = turfs[obscured_turf] + var/image/new_static = inactive_static_images[inactive_static_images.len] + new_static.loc = obscured_turf active_static_images += new_static + inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME +#undef CHUNK_SIZE From 1d8ceac8673cc8ea4b05ce25da0f67044334da4f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 15:46:10 -0500 Subject: [PATCH 093/144] this isnt going well uh oh --- .../packages/tgui/interfaces/CameraConsole.js | 143 ------------- .../tgui/interfaces/CameraConsole.tsx | 198 ++++++++++++++++++ tgui/packages/tgui/interfaces/NtosSecurEye.js | 60 ------ .../tgui/interfaces/NtosSecureEye.tsx | 12 ++ .../tgui/styles/interfaces/CameraConsole.scss | 53 ----- tgui/packages/tgui/styles/main.scss | 1 - 6 files changed, 210 insertions(+), 257 deletions(-) delete mode 100644 tgui/packages/tgui/interfaces/CameraConsole.js create mode 100644 tgui/packages/tgui/interfaces/CameraConsole.tsx delete mode 100644 tgui/packages/tgui/interfaces/NtosSecurEye.js create mode 100644 tgui/packages/tgui/interfaces/NtosSecureEye.tsx delete mode 100644 tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js deleted file mode 100644 index 8ece49eff205..000000000000 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ /dev/null @@ -1,143 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Flex, Input, Section } from '../components'; -import { Window } from '../layouts'; - -/** - * Returns previous and next camera names relative to the currently - * active camera. - */ -export const prevNextCamera = (cameras, activeCamera) => { - if (!activeCamera) { - return []; - } - const index = cameras.findIndex(camera => ( - camera.name === activeCamera.name - )); - return [ - cameras[index - 1]?.name, - cameras[index + 1]?.name, - ]; -}; - -/** - * Camera selector. - * - * Filters cameras, applies search terms and sorts the alphabetically. - */ -export const selectCameras = (cameras, searchText = '') => { - const testSearch = createSearch(searchText, camera => camera.name); - return flow([ - // Null camera filter - filter(camera => camera?.name), - // Optional search term - searchText && filter(testSearch), - // Slightly expensive, but way better than sorting in BYOND - sortBy(camera => camera.name), - ])(cameras); -}; - -export const CameraConsole = (props, context) => { - const { act, data } = useBackend(context); - const { mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - -
    - - - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    -
    - ); -}; - -export const CameraConsoleContent = (props, context) => { - const { act, data } = useBackend(context); - const [ - searchText, - setSearchText, - ] = useLocalState(context, 'searchText', ''); - const { activeCamera } = data; - const cameras = selectCameras(data.cameras, searchText); - return ( - - - setSearchText(value)} /> - - -
    - {cameras.map(camera => ( - // We're not using the component here because performance - // would be absolutely abysmal (50+ ms for each re-render). -
    [act('switch_camera', { - name: camera.name, - }), document.getElementsByClassName('CameraConsole__left')[0].focus()]}> - {camera.name} -
    - ))} -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx new file mode 100644 index 000000000000..4feb31faaf67 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CameraConsole.tsx @@ -0,0 +1,198 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { BooleanLike, classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type Data = { + can_spy: BooleanLike; + mapRef: string; + cameras: Camera[]; + activeCamera: Camera & { status: BooleanLike }; + network: string[]; +}; + +type Camera = { + name: string; +}; + +/** + * Returns previous and next camera names relative to the currently + * active camera. + */ +const prevNextCamera = ( + cameras: Camera[], + activeCamera: Camera & { status: BooleanLike } +) => { + if (!activeCamera) { + return []; + } + const index = cameras.findIndex( + (camera) => camera?.name === activeCamera.name + ); + return [cameras[index - 1]?.name, cameras[index + 1]?.name]; +}; + +/** + * Camera selector. + * + * Filters cameras, applies search terms and sorts the alphabetically. + */ +const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { + const testSearch = createSearch(searchText, (camera: Camera) => camera.name); + + return flow([ + // Null camera filter + filter((camera: Camera) => !!camera?.name), // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy((camera: Camera) => camera.name), + ])(cameras); +}; + +export const CameraConsole = (props, context) => { + return ( + + + + + + ); +}; + +export const CameraContent = (props, context) => { + return ( + + + + + + + + + ); +}; + +const CameraSelector = (props, context) => { + const { act, data } = useBackend(context); + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const { activeCamera } = data; + const cameras = selectCameras(data.cameras, searchText); + + return ( + + + setSearchText(value)} + /> + + +
    + {cameras.map((camera) => ( + // We're not using the component here because performance + // would be absolutely abysmal (50+ ms for each re-render). +
    + act('switch_camera', { + name: camera.name, + }) + }> + {camera.name} +
    + ))} +
    +
    +
    + ); +}; + +const CameraControls = (props, context) => { + const { act, data } = useBackend(context); + const { activeCamera, can_spy, mapRef } = data; + const cameras = selectCameras(data.cameras); + + const [prevCameraName, nextCameraName] = prevNextCamera( + cameras, + activeCamera + ); + + return ( +
    + + + + + {activeCamera?.name ? ( + {activeCamera.name} + ) : ( + No input signal + )} + + + + {!!can_spy && ( +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosSecurEye.js b/tgui/packages/tgui/interfaces/NtosSecurEye.js deleted file mode 100644 index 8d4bc6274528..000000000000 --- a/tgui/packages/tgui/interfaces/NtosSecurEye.js +++ /dev/null @@ -1,60 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { Fragment } from 'inferno'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Input, Section } from '../components'; -import { NtosWindow } from '../layouts'; -import { prevNextCamera, selectCameras, CameraConsoleContent } from './CameraConsole'; -import { logger } from "../logging"; - -export const NtosSecurEye = (props, context) => { - const { act, data, config } = useBackend(context); - const { PC_device_theme, mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - - -
    - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx new file mode 100644 index 000000000000..c445b6f160f5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx @@ -0,0 +1,12 @@ +import { NtosWindow } from '../layouts'; +import { CameraContent } from './CameraConsole'; + +export const NtosSecurEye = (props) => { + return ( + + + + + + ); +}; diff --git a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss deleted file mode 100644 index 7e8f99fdcceb..000000000000 --- a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss +++ /dev/null @@ -1,53 +0,0 @@ -@use '../base.scss'; - -$background-color: rgba(0, 0, 0, 0.33) !default; - -.CameraConsole__left { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: base.em(220px); -} - -.CameraConsole__right { - position: absolute; - top: 0; - bottom: 0; - left: base.em(220px); - right: 0; - background-color: $background-color; -} - -.CameraConsole__toolbar { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.25em 1em 0; -} - -.CameraConsole__toolbarRight { - position: absolute; - top: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.33em 0.5em 0; -} - -.CameraConsole__map { - position: absolute; - top: base.em(26px); - bottom: 0; - left: 0; - right: 0; - margin: 0.5em; - text-align: center; - - .NoticeBox { - margin-top: calc(50% - 2em); - } -} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index d60242ae8627..9a7a42fcf5aa 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -48,7 +48,6 @@ // Interfaces @include meta.load-css('./interfaces/AlertModal.scss'); -@include meta.load-css('./interfaces/CameraConsole.scss'); @include meta.load-css('./interfaces/InspectorBooth.scss'); @include meta.load-css('./interfaces/ListInput.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); From 78d861da7cd3d45eb6825c7ba6e80d6d99ffd408 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:44:42 -0500 Subject: [PATCH 094/144] Attempts to rework out security camera and probably more --- _maps/_basemap.dm | 2 +- code/__DEFINES/interaction_flags.dm | 2 + code/__HELPERS/cameras.dm | 35 ++++ code/_onclick/hud/map_popups.dm | 35 ---- code/_onclick/hud/map_view.dm | 69 +++++++ code/_onclick/hud/screen_objects.dm | 13 ++ code/controllers/subsystem/mapping.dm | 6 +- code/game/machinery/camera/camera.dm | 1 + code/game/machinery/camera/tracking.dm | 11 -- code/game/machinery/computer/_computer.dm | 6 + code/game/machinery/computer/camera.dm | 171 +++++++++--------- code/modules/client/client_defines.dm | 7 + .../living/silicon/ai/freelook/cameranet.dm | 24 ++- .../mob/living/silicon/ai/freelook/chunk.dm | 2 +- yogstation.dme | 2 + 15 files changed, 242 insertions(+), 144 deletions(-) create mode 100644 code/__HELPERS/cameras.dm create mode 100644 code/_onclick/hud/map_view.dm diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index 48b96c8948f7..aadbfa88a035 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" diff --git a/code/__DEFINES/interaction_flags.dm b/code/__DEFINES/interaction_flags.dm index a85ffb8d7a09..25e31118fd17 100644 --- a/code/__DEFINES/interaction_flags.dm +++ b/code/__DEFINES/interaction_flags.dm @@ -36,3 +36,5 @@ /// This flag determines if a machine set_machine's the user when the user uses it, making updateUsrDialog make the user re-call interact() on it. /// THIS FLAG IS ON ALL MACHINES BY DEFAULT, NEEDS TO BE RE-EVALUATED LATER!! #define INTERACT_MACHINE_SET_MACHINE (1<<6) +/// the user must have vision to interact (blind people need not apply) +#define INTERACT_MACHINE_REQUIRES_SIGHT (1<<7) diff --git a/code/__HELPERS/cameras.dm b/code/__HELPERS/cameras.dm new file mode 100644 index 000000000000..9d74f3fe71b4 --- /dev/null +++ b/code/__HELPERS/cameras.dm @@ -0,0 +1,35 @@ +/** + * get_camera_list + * + * Builds a list of all available cameras that can be seen to networks_available + * Args: + * networks_available - List of networks that we use to see which cameras are visible to it. + */ +/proc/get_camera_list(list/networks_available) + var/list/all_camera_list = list() + for(var/obj/machinery/camera/camera as anything in GLOB.cameranet.cameras) + all_camera_list.Add(camera) + + camera_sort(all_camera_list) + + var/list/usable_camera_list = list() + + for(var/obj/machinery/camera/camera as anything in all_camera_list) + var/list/tempnetwork = camera.network & networks_available + if(length(tempnetwork)) + usable_camera_list["[camera.c_tag][camera.can_use() ? null : " (Deactivated)"]"] = camera + + return usable_camera_list + +///Sorts the list of cameras by their c_tag to display to players. +/proc/camera_sort(list/camera_list) + var/obj/machinery/camera/camera_comparing_a + var/obj/machinery/camera/camera_comparing_b + + for(var/i = length(camera_list), i > 0, i--) + for(var/j = 1 to i - 1) + camera_comparing_a = camera_list[j] + camera_comparing_b = camera_list[j + 1] + if(sorttext(camera_comparing_a.c_tag, camera_comparing_b.c_tag) < 0) + camera_list.Swap(j, j + 1) + return camera_list diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index 07c43eac4491..7f3997ecbd67 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -1,36 +1,3 @@ -/client - /** - * Assoc list with all the active maps - when a screen obj is added to - * a map, it's put in here as well. - * - * Format: list( = list(/atom/movable/screen)) - */ - var/list/screen_maps = list() - -/atom/movable/screen - /** - * Map name assigned to this object. - * Automatically set by /client/proc/add_obj_to_map. - */ - var/assigned_map - /** - * Mark this object as garbage-collectible after you clean the map - * it was registered on. - * - * This could probably be changed to be a proc, for conditional removal. - * But for now, this works. - */ - var/del_on_map_removal = TRUE - -/** - * A screen object, which acts as a container for turfs and other things - * you want to show on the map, which you usually attach to "vis_contents". - */ -/atom/movable/screen/map_view - // Map view has to be on the lowest plane to enable proper lighting - layer = GAME_PLANE - plane = GAME_PLANE - /** * A generic background object. * It is also implicitly used to allocate a rectangle on the map, which will @@ -79,8 +46,6 @@ var/list/screen_map = screen_maps[screen_obj.assigned_map] if(!screen_map.Find(screen_obj)) screen_map += screen_obj - if(!screen.Find(screen_obj)) - screen += screen_obj /** * Clears the map of registered screen objects. diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm new file mode 100644 index 000000000000..bc304f20f8a1 --- /dev/null +++ b/code/_onclick/hud/map_view.dm @@ -0,0 +1,69 @@ +/** + * A screen object, which acts as a container for turfs and other things + * you want to show on the map, which you usually attach to "vis_contents". + * Additionally manages the plane masters required to display said container contents + */ +INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) +/atom/movable/screen/map_view + name = "screen" + // Map view has to be on the lowest plane to enable proper lighting + layer = GAME_PLANE + plane = GAME_PLANE + del_on_map_removal = FALSE + + // Weakrefs of all our hud viewers -> a weakref to the hud datum they last used + var/list/datum/weakref/viewers_to_huds = list() + +/atom/movable/screen/map_view/Destroy() + for(var/datum/weakref/client_ref in viewers_to_huds) + var/client/our_client = client_ref.resolve() + if(!our_client) + continue + hide_from(our_client.mob) + + return ..() + +/atom/movable/screen/map_view/proc/generate_view(map_key) + // Map keys have to start and end with an A-Z character, + // and definitely NOT with a square bracket or even a number. + // I wasted 6 hours on this. :agony: + // -- Stylemistake + assigned_map = map_key + set_position(1, 1) + +/atom/movable/screen/map_view/proc/display_to(mob/show_to) + show_to.client.register_map_obj(src) + // We need to add planesmasters to the popup, otherwise + // blending fucks up massively. Any planesmaster on the main screen does + // NOT apply to map popups. If there's ever a way to make planesmasters + // omnipresent, then this wouldn't be needed. + // We lazy load this because there's no point creating all these if none's gonna see em + + // Store this info in a client -> hud pattern, so ghosts closing the window nukes the right group + var/datum/weakref/client_ref = WEAKREF(show_to.client) + + var/datum/weakref/hud_ref = viewers_to_huds[client_ref] + var/datum/hud/our_hud = hud_ref?.resolve() + if(our_hud) + return our_hud.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) + + // Generate a new plane group for this case + var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) + viewers_to_huds[client_ref] = WEAKREF(show_to.hud_used) + pop_planes.attach_to(show_to.hud_used) + + return pop_planes + +/atom/movable/screen/map_view/proc/hide_from(mob/hide_from) + hide_from?.canon_client.clear_map(assigned_map) + var/client_ref = WEAKREF(hide_from?.canon_client) + + // Make sure we clear the *right* hud + var/datum/weakref/hud_ref = viewers_to_huds[client_ref] + viewers_to_huds -= client_ref + var/datum/hud/clear_from = hud_ref?.resolve() + if(!clear_from) + return + + var/datum/plane_master_group/popup/pop_planes = clear_from.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) + qdel(pop_planes) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 78637e568ee2..5e81424b01d5 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -21,6 +21,19 @@ /// If FALSE, this will not be cleared when calling /client/clear_screen() var/clear_with_screen = TRUE + /** + * Map name assigned to this object. + * Automatically set by /client/proc/add_obj_to_map. + */ + var/assigned_map + /** + * Mark this object as garbage-collectible after you clean the map + * it was registered on. + * + * This could probably be changed to be a proc, for conditional removal. + * But for now, this works. + */ + var/del_on_map_removal = TRUE /atom/movable/screen/New(datum/hud/new_hud) . = ..() diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 7403efe086d3..16ebdab54fb2 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -26,6 +26,9 @@ SUBSYSTEM_DEF(mapping) var/list/station_minimaps = list() + /// The largest plane offset we've generated so far + var/max_plane_offset = 0 + /// List of z level (as number) -> The lowest plane offset in that z stack var/list/z_level_to_lowest_plane_offset = list() @@ -38,9 +41,6 @@ SUBSYSTEM_DEF(mapping) /// List of planes that do not allow for offsetting var/list/plane_offset_blacklist - /// The largest plane offset we've generated so far - var/max_plane_offset = 0 - /// Assoc list of true string plane values to a list of all potential offset planess var/list/true_to_offset_planes diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 6a22487fe039..0cd4b1aa2516 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -11,6 +11,7 @@ idle_power_usage = 5 active_power_usage = 10 layer = WALL_OBJ_LAYER + plane = GAME_PLANE_UPPER resistance_flags = FIRE_PROOF armor = list(MELEE = 50, BULLET = 20, LASER = 20, ENERGY = 20, BOMB = 0, BIO = 0, RAD = 0, FIRE = 90, ACID = 50) diff --git a/code/game/machinery/camera/tracking.dm b/code/game/machinery/camera/tracking.dm index 0976aba838e4..1c99178a2d99 100644 --- a/code/game/machinery/camera/tracking.dm +++ b/code/game/machinery/camera/tracking.dm @@ -138,14 +138,3 @@ return user.switchCamera(src) -/proc/camera_sort(list/L) - var/obj/machinery/camera/a - var/obj/machinery/camera/b - - for (var/i = L.len, i > 0, i--) - for (var/j = 1 to i - 1) - a = L[j] - b = L[j + 1] - if (sorttext(a.c_tag, b.c_tag) < 0) - L.Swap(j, j + 1) - return L diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index bf0662c74313..bb3317a61ac4 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -177,3 +177,9 @@ . = ..() if(istype(mover) && (mover.pass_flags & PASSCOMPUTER)) return TRUE + + +/obj/machinery/computer/ui_interact(mob/user, datum/tgui/ui) + SHOULD_CALL_PARENT(TRUE) + . = ..() + // update_use_power(ACTIVE_POWER_USE) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 43f22a4e2754..8cc1e1fcbf36 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,64 +1,58 @@ +#define DEFAULT_MAP_SIZE 15 + /obj/machinery/computer/security name = "security camera console" desc = "Used to access the various cameras on the station." icon_screen = "cameras" icon_keyboard = "security_key" circuit = /obj/item/circuitboard/computer/security - light_color = LIGHT_COLOR_RED + light_color = COLOR_SOFT_RED var/list/network = list("ss13") + var/obj/machinery/camera/active_camera + /// The turf where the camera was last updated. + var/turf/last_camera_turf var/list/concurrent_users = list() // Stuff needed to render the map - var/map_name - var/const/default_map_size = 15 - var/atom/movable/screen/cam_screen + var/atom/movable/screen/map_view/cam_screen /// All the plane masters that need to be applied. - var/list/cam_plane_masters var/atom/movable/screen/background/cam_background - var/obj/machinery/camera/active_camera - - var/processing = FALSE + interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT /obj/machinery/computer/security/Initialize(mapload) . = ..() // Map name has to start and end with an A-Z character, // and definitely NOT with a square bracket or even a number. // I wasted 6 hours on this. :agony: - map_name = "camera_console_[REF(src)]_map" + var/map_name = "camera_console_[REF(src)]_map" // Convert networks to lowercase for(var/i in network) network -= i network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/instance = new plane() - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance + cam_screen.generate_view(map_name) cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE /obj/machinery/computer/security/Destroy() - qdel(cam_screen) - QDEL_LIST(cam_plane_masters) - qdel(cam_background) + QDEL_NULL(cam_screen) + QDEL_NULL(cam_background) return ..() /obj/machinery/computer/security/ui_interact(mob/user, datum/tgui/ui) + . = ..() + // if(!user.can_perform_action(src, NEED_DEXTERITY)) //prevents monkeys from using camera consoles + // return + // Update UI ui = SStgui.try_update_ui(user, src, ui) - // Show static if can't use the camera - if(!active_camera?.can_use()) - show_camera_static() + + // Update the camera, showing static if necessary and updating data if the location has moved. + update_active_camera_screen() + if(!ui) var/user_ref = REF(user) var/is_living = isliving(user) @@ -71,47 +65,65 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + cam_screen.display_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) ui.open() +/obj/machinery/computer/security/ui_status(mob/user) + . = ..() + if(. == UI_DISABLED) + return UI_CLOSE + return . + /obj/machinery/computer/security/ui_data() var/list/data = list() - data["network"] = network data["activeCamera"] = null if(active_camera) data["activeCamera"] = list( name = active_camera.c_tag, + ref = REF(active_camera), status = active_camera.status, ) return data /obj/machinery/computer/security/ui_static_data() var/list/data = list() - data["mapRef"] = map_name - var/list/cameras = get_available_cameras() + data["network"] = network + data["mapRef"] = cam_screen.assigned_map + var/list/cameras = get_camera_list(network) data["cameras"] = list() for(var/i in cameras) var/obj/machinery/camera/C = cameras[i] data["cameras"] += list(list( name = C.c_tag, + ref = REF(C), )) + return data -/obj/machinery/computer/security/process() - if(active_camera && active_camera.built_in) - if(!active_camera?.can_use()) - show_camera_static() - return TRUE - update_camera(active_camera) - else - STOP_PROCESSING(SSfastprocess, src) - processing = FALSE - ..() +//returns the list of cameras accessible from this computer +/obj/machinery/computer/security/proc/get_available_cameras() + var/list/L = list() + for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) + if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras + continue + L.Add(C) + + var/list/D = list() + + for(var/obj/machinery/camera/C in L) + if(!C.network) + stack_trace("Camera in a cameranet has no camera network") + continue + if(!(islist(C.network))) + stack_trace("Camera in a cameranet has a non-list camera network") + continue + var/list/tempnetwork = C.network & network + if(tempnetwork.len) + D["[C.c_tag]"] = C + return D /obj/machinery/computer/security/ui_act(action, params) . = ..() @@ -125,36 +137,40 @@ active_camera = C playsound(src, get_sfx("terminal_type"), 25, FALSE) - // Show static if can't use the camera - if(!active_camera?.can_use()) - show_camera_static() + if(isnull(active_camera)) return TRUE - - //Assume it's a moving camera. - if(C.built_in) - if(!processing) - START_PROCESSING(SSfastprocess, src) - processing = TRUE - else - STOP_PROCESSING(SSfastprocess, src) - processing = FALSE - - update_camera(C) + update_active_camera_screen() return TRUE -/obj/machinery/computer/security/proc/update_camera(obj/machinery/camera/C) - var/originator = C - if(C.built_in) - originator = get_turf(C.built_in) +/obj/machinery/computer/security/proc/update_active_camera_screen() + // Show static if can't use the camera + if(!active_camera?.can_use()) + show_camera_static() + return var/list/visible_turfs = list() - for(var/turf/T in (C.isXRay() \ - ? range(C.view_range, originator) \ - : view(C.view_range, originator))) - visible_turfs += T + // Get the camera's turf to correctly gather what's visible from it's turf, in case it's located in a moving object (borgs / mechs) + var/new_cam_turf = get_turf(active_camera) + + // If we're not forcing an update for some reason and the cameras are in the same location, + // we don't need to update anything. + // Most security cameras will end here as they're not moving. + if(last_camera_turf == new_cam_turf) + return + + // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. + last_camera_turf = new_cam_turf + + //Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present + var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf) + + for(var/turf/visible_turf in visible_things) + visible_turfs += visible_turf + + //Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area var/list/bbox = get_bbox_of_atoms(visible_turfs) var/size_x = bbox[3] - bbox[1] + 1 var/size_y = bbox[4] - bbox[2] + 1 @@ -164,44 +180,25 @@ cam_background.fill_rect(1, 1, size_x, size_y) /obj/machinery/computer/security/ui_close(mob/user) + . = ..() var/user_ref = REF(user) var/is_living = isliving(user) // Living creature or not, we remove you anyway. concurrent_users -= user_ref // Unregister map objects - user.client.clear_map(map_name) + cam_screen.hide_from(user) // Turn off the console if(length(concurrent_users) == 0 && is_living) active_camera = null + last_camera_turf = null playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE) use_power(0) /obj/machinery/computer/security/proc/show_camera_static() cam_screen.vis_contents.Cut() cam_background.icon_state = "scanline2" - cam_background.fill_rect(1, 1, default_map_size, default_map_size) - -//returns the list of cameras accessible from this computer -/obj/machinery/computer/security/proc/get_available_cameras() - var/list/L = list() - for (var/obj/machinery/camera/C in GLOB.cameranet.cameras) - if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras - continue - L.Add(C) + cam_background.fill_rect(1, 1, DEFAULT_MAP_SIZE, DEFAULT_MAP_SIZE) - var/list/D = list() - - for(var/obj/machinery/camera/C in L) - if(!C.network) - stack_trace("Camera in a cameranet has no camera network") - continue - if(!(islist(C.network))) - stack_trace("Camera in a cameranet has a non-list camera network") - continue - var/list/tempnetwork = C.network & network - if(tempnetwork.len) - D["[C.c_tag]"] = C - return D // SECURITY MONITORS diff --git a/code/modules/client/client_defines.dm b/code/modules/client/client_defines.dm index 9d7db5e25668..a3d7db2478b3 100644 --- a/code/modules/client/client_defines.dm +++ b/code/modules/client/client_defines.dm @@ -195,3 +195,10 @@ var/do_parallax_animations = TRUE var/parallax_throttle = 0 //ds between updates var/last_parallax_shift //world.time of last update + /** + * Assoc list with all the active maps - when a screen obj is added to + * a map, it's put in here as well. + * + * Format: list( = list(/atom/movable/screen)) + */ + var/list/screen_maps = list() diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index efd4184eee1f..cb61915a19cf 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -17,14 +17,26 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/ready = 0 // The object used for the clickable stat() button. var/obj/effect/statclick/statclick - ///The image given to the effect in vis_contents on AI clients - var/image/obscured + /// List of images cloned by all chunk static images put onto turfs cameras cant see + /// Indexed by the plane offset to use + var/list/image/obscured_images /datum/cameranet/New() - obscured = new('icons/effects/cameravis.dmi') - obscured.plane = CAMERA_STATIC_PLANE - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE + obscured_images = list() + update_offsets(SSmapping.max_plane_offset) + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) + +/datum/cameranet/proc/update_offsets(new_offset) + for(var/i in length(obscured_images) to new_offset) + var/image/obscured = new('icons/effects/cameravis.dmi') + SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE + obscured_images += obscured + +/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + update_offsets(new_offset) /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index abf891b011ac..c2178a5be5ba 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -144,7 +144,7 @@ turfs[t] = t for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured) + inactive_static_images += new/image(GLOB.cameranet.obscured_images) for(var/obj/machinery/camera/camera as anything in cameras) if(!camera || !camera.can_use()) diff --git a/yogstation.dme b/yogstation.dme index 374f54ea108d..fac8f88d5fd2 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -217,6 +217,7 @@ #include "code\__HELPERS\animations.dm" #include "code\__HELPERS\areas.dm" #include "code\__HELPERS\AStar.dm" +#include "code\__HELPERS\cameras.dm" #include "code\__HELPERS\cmp.dm" #include "code\__HELPERS\colors.dm" #include "code\__HELPERS\config.dm" @@ -319,6 +320,7 @@ #include "code\_onclick\hud\lavaland_elite.dm" #include "code\_onclick\hud\living.dm" #include "code\_onclick\hud\map_popups.dm" +#include "code\_onclick\hud\map_view.dm" #include "code\_onclick\hud\monkey.dm" #include "code\_onclick\hud\movable_screen_objects.dm" #include "code\_onclick\hud\pai.dm" From e26fb61415cc9f1d48f7528a9ebda34ec93020b0 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:09:27 -0500 Subject: [PATCH 095/144] Revert "this isnt going well" This reverts commit 1d8ceac8673cc8ea4b05ce25da0f67044334da4f. --- .../packages/tgui/interfaces/CameraConsole.js | 143 +++++++++++++ .../tgui/interfaces/CameraConsole.tsx | 198 ------------------ tgui/packages/tgui/interfaces/NtosSecurEye.js | 60 ++++++ .../tgui/interfaces/NtosSecureEye.tsx | 12 -- .../tgui/styles/interfaces/CameraConsole.scss | 53 +++++ tgui/packages/tgui/styles/main.scss | 1 + 6 files changed, 257 insertions(+), 210 deletions(-) create mode 100644 tgui/packages/tgui/interfaces/CameraConsole.js delete mode 100644 tgui/packages/tgui/interfaces/CameraConsole.tsx create mode 100644 tgui/packages/tgui/interfaces/NtosSecurEye.js delete mode 100644 tgui/packages/tgui/interfaces/NtosSecureEye.tsx create mode 100644 tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js new file mode 100644 index 000000000000..8ece49eff205 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CameraConsole.js @@ -0,0 +1,143 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Flex, Input, Section } from '../components'; +import { Window } from '../layouts'; + +/** + * Returns previous and next camera names relative to the currently + * active camera. + */ +export const prevNextCamera = (cameras, activeCamera) => { + if (!activeCamera) { + return []; + } + const index = cameras.findIndex(camera => ( + camera.name === activeCamera.name + )); + return [ + cameras[index - 1]?.name, + cameras[index + 1]?.name, + ]; +}; + +/** + * Camera selector. + * + * Filters cameras, applies search terms and sorts the alphabetically. + */ +export const selectCameras = (cameras, searchText = '') => { + const testSearch = createSearch(searchText, camera => camera.name); + return flow([ + // Null camera filter + filter(camera => camera?.name), + // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy(camera => camera.name), + ])(cameras); +}; + +export const CameraConsole = (props, context) => { + const { act, data } = useBackend(context); + const { mapRef, activeCamera } = data; + const cameras = selectCameras(data.cameras); + const [ + prevCameraName, + nextCameraName, + ] = prevNextCamera(cameras, activeCamera); + return ( + +
    + + + +
    +
    +
    + Camera: + {activeCamera + && activeCamera.name + || '—'} +
    +
    +
    + +
    +
    + ); +}; + +export const CameraConsoleContent = (props, context) => { + const { act, data } = useBackend(context); + const [ + searchText, + setSearchText, + ] = useLocalState(context, 'searchText', ''); + const { activeCamera } = data; + const cameras = selectCameras(data.cameras, searchText); + return ( + + + setSearchText(value)} /> + + +
    + {cameras.map(camera => ( + // We're not using the component here because performance + // would be absolutely abysmal (50+ ms for each re-render). +
    [act('switch_camera', { + name: camera.name, + }), document.getElementsByClassName('CameraConsole__left')[0].focus()]}> + {camera.name} +
    + ))} +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx deleted file mode 100644 index 4feb31faaf67..000000000000 --- a/tgui/packages/tgui/interfaces/CameraConsole.tsx +++ /dev/null @@ -1,198 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { BooleanLike, classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components'; -import { Window } from '../layouts'; - -type Data = { - can_spy: BooleanLike; - mapRef: string; - cameras: Camera[]; - activeCamera: Camera & { status: BooleanLike }; - network: string[]; -}; - -type Camera = { - name: string; -}; - -/** - * Returns previous and next camera names relative to the currently - * active camera. - */ -const prevNextCamera = ( - cameras: Camera[], - activeCamera: Camera & { status: BooleanLike } -) => { - if (!activeCamera) { - return []; - } - const index = cameras.findIndex( - (camera) => camera?.name === activeCamera.name - ); - return [cameras[index - 1]?.name, cameras[index + 1]?.name]; -}; - -/** - * Camera selector. - * - * Filters cameras, applies search terms and sorts the alphabetically. - */ -const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { - const testSearch = createSearch(searchText, (camera: Camera) => camera.name); - - return flow([ - // Null camera filter - filter((camera: Camera) => !!camera?.name), // Optional search term - searchText && filter(testSearch), - // Slightly expensive, but way better than sorting in BYOND - sortBy((camera: Camera) => camera.name), - ])(cameras); -}; - -export const CameraConsole = (props, context) => { - return ( - - - - - - ); -}; - -export const CameraContent = (props, context) => { - return ( - - - - - - - - - ); -}; - -const CameraSelector = (props, context) => { - const { act, data } = useBackend(context); - const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); - const { activeCamera } = data; - const cameras = selectCameras(data.cameras, searchText); - - return ( - - - setSearchText(value)} - /> - - -
    - {cameras.map((camera) => ( - // We're not using the component here because performance - // would be absolutely abysmal (50+ ms for each re-render). -
    - act('switch_camera', { - name: camera.name, - }) - }> - {camera.name} -
    - ))} -
    -
    -
    - ); -}; - -const CameraControls = (props, context) => { - const { act, data } = useBackend(context); - const { activeCamera, can_spy, mapRef } = data; - const cameras = selectCameras(data.cameras); - - const [prevCameraName, nextCameraName] = prevNextCamera( - cameras, - activeCamera - ); - - return ( -
    - - - - - {activeCamera?.name ? ( - {activeCamera.name} - ) : ( - No input signal - )} - - - - {!!can_spy && ( -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/NtosSecurEye.js b/tgui/packages/tgui/interfaces/NtosSecurEye.js new file mode 100644 index 000000000000..8d4bc6274528 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosSecurEye.js @@ -0,0 +1,60 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { Fragment } from 'inferno'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Input, Section } from '../components'; +import { NtosWindow } from '../layouts'; +import { prevNextCamera, selectCameras, CameraConsoleContent } from './CameraConsole'; +import { logger } from "../logging"; + +export const NtosSecurEye = (props, context) => { + const { act, data, config } = useBackend(context); + const { PC_device_theme, mapRef, activeCamera } = data; + const cameras = selectCameras(data.cameras); + const [ + prevCameraName, + nextCameraName, + ] = prevNextCamera(cameras, activeCamera); + return ( + + +
    + +
    +
    +
    + Camera: + {activeCamera + && activeCamera.name + || '—'} +
    +
    +
    + +
    +
    +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx deleted file mode 100644 index c445b6f160f5..000000000000 --- a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { NtosWindow } from '../layouts'; -import { CameraContent } from './CameraConsole'; - -export const NtosSecurEye = (props) => { - return ( - - - - - - ); -}; diff --git a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss new file mode 100644 index 000000000000..7e8f99fdcceb --- /dev/null +++ b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss @@ -0,0 +1,53 @@ +@use '../base.scss'; + +$background-color: rgba(0, 0, 0, 0.33) !default; + +.CameraConsole__left { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: base.em(220px); +} + +.CameraConsole__right { + position: absolute; + top: 0; + bottom: 0; + left: base.em(220px); + right: 0; + background-color: $background-color; +} + +.CameraConsole__toolbar { + position: absolute; + top: 0; + left: 0; + right: 0; + height: 2em; + line-height: 2em; + margin: 0.25em 1em 0; +} + +.CameraConsole__toolbarRight { + position: absolute; + top: 0; + right: 0; + height: 2em; + line-height: 2em; + margin: 0.33em 0.5em 0; +} + +.CameraConsole__map { + position: absolute; + top: base.em(26px); + bottom: 0; + left: 0; + right: 0; + margin: 0.5em; + text-align: center; + + .NoticeBox { + margin-top: calc(50% - 2em); + } +} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index 9a7a42fcf5aa..d60242ae8627 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -48,6 +48,7 @@ // Interfaces @include meta.load-css('./interfaces/AlertModal.scss'); +@include meta.load-css('./interfaces/CameraConsole.scss'); @include meta.load-css('./interfaces/InspectorBooth.scss'); @include meta.load-css('./interfaces/ListInput.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); From c0cf69ebf10d44ab05ceedc3f5a7c51fd074ac08 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:13:33 -0500 Subject: [PATCH 096/144] Revert "Revert "this isnt going well"" This reverts commit e26fb61415cc9f1d48f7528a9ebda34ec93020b0. --- .../packages/tgui/interfaces/CameraConsole.js | 143 ------------- .../tgui/interfaces/CameraConsole.tsx | 198 ++++++++++++++++++ tgui/packages/tgui/interfaces/NtosSecurEye.js | 60 ------ .../tgui/interfaces/NtosSecureEye.tsx | 12 ++ .../tgui/styles/interfaces/CameraConsole.scss | 53 ----- tgui/packages/tgui/styles/main.scss | 1 - 6 files changed, 210 insertions(+), 257 deletions(-) delete mode 100644 tgui/packages/tgui/interfaces/CameraConsole.js create mode 100644 tgui/packages/tgui/interfaces/CameraConsole.tsx delete mode 100644 tgui/packages/tgui/interfaces/NtosSecurEye.js create mode 100644 tgui/packages/tgui/interfaces/NtosSecureEye.tsx delete mode 100644 tgui/packages/tgui/styles/interfaces/CameraConsole.scss diff --git a/tgui/packages/tgui/interfaces/CameraConsole.js b/tgui/packages/tgui/interfaces/CameraConsole.js deleted file mode 100644 index 8ece49eff205..000000000000 --- a/tgui/packages/tgui/interfaces/CameraConsole.js +++ /dev/null @@ -1,143 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Flex, Input, Section } from '../components'; -import { Window } from '../layouts'; - -/** - * Returns previous and next camera names relative to the currently - * active camera. - */ -export const prevNextCamera = (cameras, activeCamera) => { - if (!activeCamera) { - return []; - } - const index = cameras.findIndex(camera => ( - camera.name === activeCamera.name - )); - return [ - cameras[index - 1]?.name, - cameras[index + 1]?.name, - ]; -}; - -/** - * Camera selector. - * - * Filters cameras, applies search terms and sorts the alphabetically. - */ -export const selectCameras = (cameras, searchText = '') => { - const testSearch = createSearch(searchText, camera => camera.name); - return flow([ - // Null camera filter - filter(camera => camera?.name), - // Optional search term - searchText && filter(testSearch), - // Slightly expensive, but way better than sorting in BYOND - sortBy(camera => camera.name), - ])(cameras); -}; - -export const CameraConsole = (props, context) => { - const { act, data } = useBackend(context); - const { mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - -
    - - - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    -
    - ); -}; - -export const CameraConsoleContent = (props, context) => { - const { act, data } = useBackend(context); - const [ - searchText, - setSearchText, - ] = useLocalState(context, 'searchText', ''); - const { activeCamera } = data; - const cameras = selectCameras(data.cameras, searchText); - return ( - - - setSearchText(value)} /> - - -
    - {cameras.map(camera => ( - // We're not using the component here because performance - // would be absolutely abysmal (50+ ms for each re-render). -
    [act('switch_camera', { - name: camera.name, - }), document.getElementsByClassName('CameraConsole__left')[0].focus()]}> - {camera.name} -
    - ))} -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx new file mode 100644 index 000000000000..4feb31faaf67 --- /dev/null +++ b/tgui/packages/tgui/interfaces/CameraConsole.tsx @@ -0,0 +1,198 @@ +import { filter, sortBy } from 'common/collections'; +import { flow } from 'common/fp'; +import { BooleanLike, classes } from 'common/react'; +import { createSearch } from 'common/string'; +import { useBackend, useLocalState } from '../backend'; +import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +type Data = { + can_spy: BooleanLike; + mapRef: string; + cameras: Camera[]; + activeCamera: Camera & { status: BooleanLike }; + network: string[]; +}; + +type Camera = { + name: string; +}; + +/** + * Returns previous and next camera names relative to the currently + * active camera. + */ +const prevNextCamera = ( + cameras: Camera[], + activeCamera: Camera & { status: BooleanLike } +) => { + if (!activeCamera) { + return []; + } + const index = cameras.findIndex( + (camera) => camera?.name === activeCamera.name + ); + return [cameras[index - 1]?.name, cameras[index + 1]?.name]; +}; + +/** + * Camera selector. + * + * Filters cameras, applies search terms and sorts the alphabetically. + */ +const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { + const testSearch = createSearch(searchText, (camera: Camera) => camera.name); + + return flow([ + // Null camera filter + filter((camera: Camera) => !!camera?.name), // Optional search term + searchText && filter(testSearch), + // Slightly expensive, but way better than sorting in BYOND + sortBy((camera: Camera) => camera.name), + ])(cameras); +}; + +export const CameraConsole = (props, context) => { + return ( + + + + + + ); +}; + +export const CameraContent = (props, context) => { + return ( + + + + + + + + + ); +}; + +const CameraSelector = (props, context) => { + const { act, data } = useBackend(context); + const [searchText, setSearchText] = useLocalState(context, 'searchText', ''); + const { activeCamera } = data; + const cameras = selectCameras(data.cameras, searchText); + + return ( + + + setSearchText(value)} + /> + + +
    + {cameras.map((camera) => ( + // We're not using the component here because performance + // would be absolutely abysmal (50+ ms for each re-render). +
    + act('switch_camera', { + name: camera.name, + }) + }> + {camera.name} +
    + ))} +
    +
    +
    + ); +}; + +const CameraControls = (props, context) => { + const { act, data } = useBackend(context); + const { activeCamera, can_spy, mapRef } = data; + const cameras = selectCameras(data.cameras); + + const [prevCameraName, nextCameraName] = prevNextCamera( + cameras, + activeCamera + ); + + return ( +
    + + + + + {activeCamera?.name ? ( + {activeCamera.name} + ) : ( + No input signal + )} + + + + {!!can_spy && ( +
    + ); +}; diff --git a/tgui/packages/tgui/interfaces/NtosSecurEye.js b/tgui/packages/tgui/interfaces/NtosSecurEye.js deleted file mode 100644 index 8d4bc6274528..000000000000 --- a/tgui/packages/tgui/interfaces/NtosSecurEye.js +++ /dev/null @@ -1,60 +0,0 @@ -import { filter, sortBy } from 'common/collections'; -import { flow } from 'common/fp'; -import { classes } from 'common/react'; -import { createSearch } from 'common/string'; -import { Fragment } from 'inferno'; -import { useBackend, useLocalState } from '../backend'; -import { Button, ByondUi, Input, Section } from '../components'; -import { NtosWindow } from '../layouts'; -import { prevNextCamera, selectCameras, CameraConsoleContent } from './CameraConsole'; -import { logger } from "../logging"; - -export const NtosSecurEye = (props, context) => { - const { act, data, config } = useBackend(context); - const { PC_device_theme, mapRef, activeCamera } = data; - const cameras = selectCameras(data.cameras); - const [ - prevCameraName, - nextCameraName, - ] = prevNextCamera(cameras, activeCamera); - return ( - - -
    - -
    -
    -
    - Camera: - {activeCamera - && activeCamera.name - || '—'} -
    -
    -
    - -
    -
    -
    - ); -}; diff --git a/tgui/packages/tgui/interfaces/NtosSecureEye.tsx b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx new file mode 100644 index 000000000000..c445b6f160f5 --- /dev/null +++ b/tgui/packages/tgui/interfaces/NtosSecureEye.tsx @@ -0,0 +1,12 @@ +import { NtosWindow } from '../layouts'; +import { CameraContent } from './CameraConsole'; + +export const NtosSecurEye = (props) => { + return ( + + + + + + ); +}; diff --git a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss b/tgui/packages/tgui/styles/interfaces/CameraConsole.scss deleted file mode 100644 index 7e8f99fdcceb..000000000000 --- a/tgui/packages/tgui/styles/interfaces/CameraConsole.scss +++ /dev/null @@ -1,53 +0,0 @@ -@use '../base.scss'; - -$background-color: rgba(0, 0, 0, 0.33) !default; - -.CameraConsole__left { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: base.em(220px); -} - -.CameraConsole__right { - position: absolute; - top: 0; - bottom: 0; - left: base.em(220px); - right: 0; - background-color: $background-color; -} - -.CameraConsole__toolbar { - position: absolute; - top: 0; - left: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.25em 1em 0; -} - -.CameraConsole__toolbarRight { - position: absolute; - top: 0; - right: 0; - height: 2em; - line-height: 2em; - margin: 0.33em 0.5em 0; -} - -.CameraConsole__map { - position: absolute; - top: base.em(26px); - bottom: 0; - left: 0; - right: 0; - margin: 0.5em; - text-align: center; - - .NoticeBox { - margin-top: calc(50% - 2em); - } -} diff --git a/tgui/packages/tgui/styles/main.scss b/tgui/packages/tgui/styles/main.scss index d60242ae8627..9a7a42fcf5aa 100644 --- a/tgui/packages/tgui/styles/main.scss +++ b/tgui/packages/tgui/styles/main.scss @@ -48,7 +48,6 @@ // Interfaces @include meta.load-css('./interfaces/AlertModal.scss'); -@include meta.load-css('./interfaces/CameraConsole.scss'); @include meta.load-css('./interfaces/InspectorBooth.scss'); @include meta.load-css('./interfaces/ListInput.scss'); @include meta.load-css('./interfaces/HellishRunes.scss'); From 7e7a7f8372cd1ce7169736bf52cd40e568b46c10 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:16:44 -0500 Subject: [PATCH 097/144] ok ok --- code/modules/surgery/organs/augments_chest.dm | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 0ab2df136add..64f102b21f8d 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -335,13 +335,23 @@ to_chat(owner, span_warning("Your spinal implant makes you feel queasy!")) return - owner.set_drugginess(4 * severity) - owner.adjust_hallucinations((50 * severity) SECONDS) - owner.blur_eyes(2 * severity) - owner.adjust_dizzy(severity SECONDS) - time_on += severity - owner.adjustFireLoss(severity) - to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) + switch(severity)//i don't want emps to just be damage again, that's boring + if(EMP_HEAVY) + owner.set_drugginess(40) + owner.adjust_hallucinations(500 SECONDS) + owner.blur_eyes(20) + owner.adjust_dizzy(10 SECONDS) + time_on += 10 + owner.adjustFireLoss(10) + to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) + if(EMP_LIGHT) + owner.set_drugginess(20) + owner.adjust_hallucinations(200 SECONDS) + owner.blur_eyes(10) + owner.adjust_dizzy(5 SECONDS) + time_on += 5 + owner.adjustFireLoss(5) + to_chat(owner, span_danger("Your spinal implant malfunctions and you suddenly feel... wrong.")) /obj/item/organ/cyberimp/chest/spinalspeed/toy name = "glowy after-image trail implant" From 8068af00c7e779ad223e8acd47acc8ac7f29db2a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:24:24 -0500 Subject: [PATCH 098/144] Revert "ok" This reverts commit 7e7a7f8372cd1ce7169736bf52cd40e568b46c10. --- code/modules/surgery/organs/augments_chest.dm | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 64f102b21f8d..0ab2df136add 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -335,23 +335,13 @@ to_chat(owner, span_warning("Your spinal implant makes you feel queasy!")) return - switch(severity)//i don't want emps to just be damage again, that's boring - if(EMP_HEAVY) - owner.set_drugginess(40) - owner.adjust_hallucinations(500 SECONDS) - owner.blur_eyes(20) - owner.adjust_dizzy(10 SECONDS) - time_on += 10 - owner.adjustFireLoss(10) - to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) - if(EMP_LIGHT) - owner.set_drugginess(20) - owner.adjust_hallucinations(200 SECONDS) - owner.blur_eyes(10) - owner.adjust_dizzy(5 SECONDS) - time_on += 5 - owner.adjustFireLoss(5) - to_chat(owner, span_danger("Your spinal implant malfunctions and you suddenly feel... wrong.")) + owner.set_drugginess(4 * severity) + owner.adjust_hallucinations((50 * severity) SECONDS) + owner.blur_eyes(2 * severity) + owner.adjust_dizzy(severity SECONDS) + time_on += severity + owner.adjustFireLoss(severity) + to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) /obj/item/organ/cyberimp/chest/spinalspeed/toy name = "glowy after-image trail implant" From b3fb3ba0db5370e7727c0f841b77569eb86ae012 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:24:38 -0500 Subject: [PATCH 099/144] Revert "Merge remote-tracking branch 'upstream/master' into NahI'dPortit" This reverts commit 01094731c1a031ab50d2d6aa070c01029716f4f0, reversing changes made to c0cf69ebf10d44ab05ceedc3f5a7c51fd074ac08. --- _maps/map_files/DonutStation/DonutStation.dmm | 30 ++-- code/__DEFINES/DNA.dm | 2 + code/__DEFINES/combat.dm | 4 +- code/__DEFINES/traits.dm | 2 + code/_onclick/item_attack.dm | 20 +-- code/datums/components/nanites.dm | 14 +- code/datums/mutations/hulk.dm | 99 ++++++++++++++ code/game/machinery/_machinery.dm | 8 +- code/game/machinery/camera/camera.dm | 4 +- code/game/machinery/cloning.dm | 2 +- code/game/machinery/computer/_computer.dm | 12 +- code/game/machinery/computer/arcade.dm | 7 +- code/game/machinery/computer/dna_console.dm | 6 - code/game/machinery/computer/medical.dm | 2 +- code/game/machinery/computer/security.dm | 2 +- code/game/machinery/doors/airlock_types.dm | 2 +- code/game/machinery/doors/door.dm | 4 +- code/game/machinery/doors/windowdoor.dm | 2 +- code/game/machinery/firealarm.dm | 2 +- code/game/machinery/flasher.dm | 2 +- code/game/machinery/shieldgen.dm | 9 +- code/game/machinery/shuttle/shuttle_heater.dm | 2 +- code/game/machinery/slotmachine.dm | 2 +- code/game/machinery/syndicatebomb.dm | 7 +- .../machinery/telecomms/telecomunications.dm | 4 +- code/game/mecha/mecha_defense.dm | 4 +- code/game/objects/empulse.dm | 42 +++--- code/game/objects/items.dm | 5 - code/game/objects/items/credit_holochip.dm | 2 +- code/game/objects/items/defib.dm | 2 +- code/game/objects/items/devices/PDA/PDA.dm | 2 +- .../objects/items/devices/laserpointer.dm | 2 +- .../game/objects/items/devices/radio/radio.dm | 7 +- code/game/objects/items/devices/scanners.dm | 2 +- code/game/objects/items/dna_injector.dm | 7 +- .../objects/items/granters/magic/charge.dm | 2 +- .../objects/items/grenades/chem_grenade.dm | 2 +- code/game/objects/items/grenades/emgrenade.dm | 2 +- .../objects/items/implants/implant_misc.dm | 8 +- code/game/objects/items/kitchen.dm | 1 - code/game/objects/items/storage/lockbox.dm | 25 ++-- code/game/objects/items/stunbaton.dm | 2 +- .../objects/items/supermatter_delaminator.dm | 2 +- code/game/objects/items/tools/crowbar.dm | 1 - code/game/objects/items/tools/screwdriver.dm | 1 - code/game/objects/items/tools/weldingtool.dm | 3 - code/game/objects/items/tools/wrench.dm | 1 - .../game/objects/items/two_handed/chainsaw.dm | 1 - .../objects/items/two_handed/dualsaber.dm | 4 +- code/game/objects/items/two_handed/fireaxe.dm | 19 ++- code/game/objects/obj_defense.dm | 2 +- code/game/objects/objs.dm | 2 - .../structures/crates_lockers/closets.dm | 4 +- code/modules/admin/verbs/randomverbs.dm | 19 +-- .../blob/blobstrains/electromagnetic_web.dm | 4 +- .../antagonists/blob/structures/_blob.dm | 2 +- .../antagonists/bloodsuckers/powers/feed.dm | 4 +- .../bloodsuckers/powers/gangrel.dm | 6 +- .../structures/bloodsucker_life.dm | 41 +----- .../antagonists/changeling/powers/shriek.dm | 2 +- .../clock_items/clock_weapons/longsword.dm | 5 +- code/modules/antagonists/cult/runes.dm | 2 +- .../magic/general_heretic_magic.dm | 3 +- .../atmospherics/gasmixtures/gas_mixture.dm | 5 +- .../machinery/components/fusion/hfr_procs.dm | 18 ++- .../atmospherics/machinery/portable/pump.dm | 4 +- .../machinery/portable/scrubber.dm | 2 +- code/modules/clothing/neck/_neck.dm | 8 +- code/modules/clothing/neck/bodycamera.dm | 2 +- .../modules/clothing/spacesuits/chronosuit.dm | 12 +- code/modules/clothing/spacesuits/hardsuit.dm | 2 +- .../modules/clothing/suits/reactive_armour.dm | 2 +- .../food_and_drinks/drinks/drinks/bottle.dm | 2 - code/modules/mining/abandoned_crates.dm | 4 +- code/modules/mining/equipment/mining_tools.dm | 1 - .../mining/equipment/wormhole_jaunter.dm | 9 +- code/modules/mob/living/brain/brain_item.dm | 13 +- code/modules/mob/living/carbon/carbon.dm | 4 + .../mob/living/carbon/carbon_defense.dm | 23 ++-- code/modules/mob/living/carbon/human/human.dm | 39 +++++- .../mob/living/carbon/human/human_defense.dm | 30 +++- .../mob/living/carbon/human/human_helpers.dm | 2 +- code/modules/mob/living/carbon/human/life.dm | 2 +- .../mob/living/carbon/human/physiology.dm | 1 - .../mob/living/carbon/human/species.dm | 31 ++--- .../carbon/human/species_types/ethereal.dm | 2 +- .../mob/living/carbon/human/update_icons.dm | 2 +- code/modules/mob/living/carbon/life.dm | 2 +- .../mob/living/silicon/pai/pai_defense.dm | 8 +- .../mob/living/silicon/robot/robot_defense.dm | 6 +- code/modules/mob/living/silicon/silicon.dm | 27 ++-- .../mob/living/silicon/silicon_defense.dm | 10 +- .../mob/living/simple_animal/bot/bot.dm | 2 +- .../mob/living/simple_animal/bot/ed209bot.dm | 4 +- .../simple_animal/friendly/drone/_drone.dm | 4 +- .../ninja/suit/n_suit_verbs/ninja_empulse.dm | 2 +- code/modules/photography/camera/camera.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/power/cell.dm | 4 +- code/modules/power/singularity/singularity.dm | 2 +- code/modules/power/smes.dm | 2 +- code/modules/power/supermatter/supermatter.dm | 6 +- .../ammunition/ballistic/shotgun.dm | 8 +- .../projectiles/ammunition/energy/special.dm | 2 +- .../projectiles/ammunition/reusable/arrow.dm | 10 +- .../boxes_magazines/external/rechargable.dm | 6 +- code/modules/projectiles/guns/energy.dm | 6 +- .../projectiles/guns/misc/beam_rifle.dm | 1 - code/modules/projectiles/projectile/beams.dm | 1 - .../projectile/bullets/_incendiary.dm | 1 - .../projectiles/projectile/bullets/pistol.dm | 2 +- .../projectiles/projectile/bullets/rifle.dm | 2 - .../projectiles/projectile/bullets/shotgun.dm | 8 +- .../projectiles/projectile/bullets/sniper.dm | 9 +- .../projectiles/projectile/energy/stun.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 6 +- .../projectiles/projectile/reusable/arrow.dm | 2 +- .../projectile/special/hallucination.dm | 2 +- .../projectiles/projectile/special/ion.dm | 18 ++- .../projectiles/projectile/special/plasma.dm | 1 - .../projectiles/projectile/special/rocket.dm | 36 +++-- .../chemistry/recipes/pyrotechnics.dm | 6 +- .../chemistry/recipes/slime_extracts.dm | 2 +- code/modules/research/experimentor.dm | 2 +- .../research/nanites/nanite_programs.dm | 2 +- .../nanites/nanite_programs/weapon.dm | 2 +- code/modules/research/server.dm | 4 +- .../research/xenobiology/xenobiology.dm | 2 +- .../spells/spell_types/self/disable_tech.dm | 13 +- code/modules/surgery/bodyparts/_bodyparts.dm | 29 +--- code/modules/surgery/organs/appendix.dm | 3 +- code/modules/surgery/organs/augment_legs.dm | 18 ++- code/modules/surgery/organs/augments_arms.dm | 4 +- code/modules/surgery/organs/augments_chest.dm | 42 ++++-- .../surgery/organs/augments_internal.dm | 11 +- code/modules/surgery/organs/ears.dm | 20 +-- code/modules/surgery/organs/eyes.dm | 116 +++++++++++----- code/modules/surgery/organs/heart.dm | 9 +- code/modules/surgery/organs/liver.dm | 5 +- code/modules/surgery/organs/lungs.dm | 4 +- code/modules/surgery/organs/stomach.dm | 2 +- code/modules/surgery/organs/tongue.dm | 4 +- code/modules/surgery/tools.dm | 2 - code/modules/swarmers/swarmer.dm | 7 +- html/changelog.html | 129 ++++++++++++------ html/changelogs/.all_changelog.yml | 39 ------ .../code/game/gamemodes/gangs/dominator.dm | 2 +- .../objects/items/wielded/sledgehammer.dm | 3 +- .../objects/items/wielded/vxtvulhammer.dm | 1 - .../human/species_types/preternis/organs.dm | 2 +- .../species_types/preternis/preternis.dm | 10 +- .../simple_animal/hostile/floor_cluwne.dm | 2 +- .../hostile/retaliate/king_of_goats.dm | 2 +- .../code/modules/surgery/organs/heart.dm | 6 + 154 files changed, 815 insertions(+), 611 deletions(-) diff --git a/_maps/map_files/DonutStation/DonutStation.dmm b/_maps/map_files/DonutStation/DonutStation.dmm index 2895b1bb47eb..6b77b87b374e 100644 --- a/_maps/map_files/DonutStation/DonutStation.dmm +++ b/_maps/map_files/DonutStation/DonutStation.dmm @@ -5440,6 +5440,20 @@ }, /turf/open/floor/plasteel/grimy, /area/ai_monitored/turret_protected/aisat_interior) +"ciH" = ( +/obj/machinery/door/airlock/external{ + name = "Security External Airlock"; + req_access_txt = "63" + }, +/obj/machinery/atmospherics/pipe/layer_manifold{ + dir = 4 + }, +/obj/effect/mapping_helpers/airlock/cyclelink_helper_target{ + dirx = -2; + diry = 1 + }, +/turf/open/space/basic, +/area/security/main) "ciL" = ( /obj/machinery/atmospherics/components/unary/vent_scrubber/on/layer4{ dir = 1 @@ -30820,20 +30834,6 @@ }, /turf/open/floor/plasteel, /area/security/prison) -"nlF" = ( -/obj/machinery/door/airlock/external{ - name = "Security External Airlock"; - req_access_txt = "63" - }, -/obj/machinery/atmospherics/pipe/layer_manifold{ - dir = 4 - }, -/obj/effect/mapping_helpers/airlock/cyclelink_helper_target{ - dirx = -2; - diry = 1 - }, -/turf/open/floor/plating, -/area/security/main) "nlJ" = ( /obj/structure/frame/machine, /obj/effect/turf_decal/stripes/line{ @@ -105911,7 +105911,7 @@ xGT pzZ alW cJk -nlF +ciH cJk bHj bHj diff --git a/code/__DEFINES/DNA.dm b/code/__DEFINES/DNA.dm index 4424f9a8ca30..b63cb9091b41 100644 --- a/code/__DEFINES/DNA.dm +++ b/code/__DEFINES/DNA.dm @@ -4,6 +4,8 @@ //Defines copying names of mutations in all cases, make sure to change this if you change mutation's type #define HULK /datum/mutation/human/hulk +#define ACTIVE_HULK /datum/mutation/human/active_hulk +#define GENETICS_HULK /datum/mutation/human/genetics_hulk #define XRAY /datum/mutation/human/thermal/x_ray #define SPACEMUT /datum/mutation/human/space_adaptation #define HEATMUT /datum/mutation/human/heat_adaptation diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 29860523630e..ebc28a4d5700 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -236,8 +236,8 @@ GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list( #define EXPLODE_LIGHT 3 #define EXPLODE_GIB_THRESHOLD 50 //ex_act() with EXPLODE_DEVASTATE severity will gib mobs with less than this much bomb armor -#define EMP_LIGHT 5 // maximum severity level without severe effects like organ failure and paralysis -#define EMP_HEAVY 10 // max severity from most sources so you can't use a 5 billion tile EMP to instakill people +#define EMP_HEAVY 1 +#define EMP_LIGHT 2 #define GRENADE_CLUMSY_FUMBLE 1 #define GRENADE_NONCLUMSY_FUMBLE 2 diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e15c4b93df81..ba56ac55edb0 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -291,6 +291,8 @@ #define TRAIT_NOVEHICLE "no_vehicle" /// BALD!!! #define TRAIT_BALD "bald" +/// Reduces severity of EMPs by one level, heavy becomes light and light is ignored +#define TRAIT_FARADAYCAGE "faraday_cage" /// You can't see color! #define TRAIT_COLORBLIND "color_blind" diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 3607a024efe7..3bbcdff95fcc 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -119,20 +119,12 @@ /atom/movable/proc/attacked_by() return -/obj/attacked_by(obj/item/attacking_item, mob/living/user) - if(!attacking_item.force) - return - - var/damage = take_damage(attacking_item.force * attacking_item.demolition_mod, attacking_item.damtype, MELEE, 1, armour_penetration = attacking_item.armour_penetration) - var/damage_verb = "hit" - if(attacking_item.demolition_mod > 1 && damage) - damage_verb = "pulverized" - if(attacking_item.demolition_mod < 1 || !damage) - damage_verb = "ineffectively pierced" - - visible_message(span_danger("[user] [damage_verb] [src] with [attacking_item][damage ? "" : ", without leaving a mark"]!"), null, null, COMBAT_MESSAGE_RANGE) - //only witnesses close by and the victim see a hit message. - log_combat(user, src, "attacked", attacking_item) +/obj/attacked_by(obj/item/I, mob/living/user) + if(I.force) + visible_message(span_danger("[user] has hit [src] with [I]!"), null, null, COMBAT_MESSAGE_RANGE) + //only witnesses close by and the victim see a hit message. + log_combat(user, src, "attacked", I) + take_damage(I.force, I.damtype, MELEE, 1) /mob/living/attacked_by(obj/item/I, mob/living/user) send_item_attack_message(I, user) diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm index 816572e80888..b2b692d27ed8 100644 --- a/code/datums/components/nanites.dm +++ b/code/datums/components/nanites.dm @@ -184,14 +184,12 @@ /datum/component/nanites/proc/on_emp(datum/source, severity) if(HAS_TRAIT(host_mob, TRAIT_EMPPROOF_SELF)) return // don't do EMP effects if they're protected from EMPs - if(iscarbon(host_mob)) - var/mob/living/carbon/host_carbon = host_mob - if(host_carbon.dna?.species) - severity *= host_carbon.dna.species.emp_mod - if(severity < 1) - return // don't bother if it's less than 1 severity - nanite_volume *= 1 - (rand(0.01, 0.025) * severity) //Lose 1-2.5% of nanites for each severity level - adjust_nanites(null, -(rand(0.5, 3) * severity)) //Lose 0.5-3 flat nanite volume for each severity level + if(HAS_TRAIT(host_mob, TRAIT_FARADAYCAGE)) + severity++ + if(severity > EMP_LIGHT) + return + nanite_volume *= 1 - (rand(0.1, 0.25) / severity) //Lose 10-25% of nanites + adjust_nanites(null, -(rand(5, 30) / severity)) //Lose 5-30 flat nanite volume for(var/X in programs) var/datum/nanite_program/NP = X NP.on_emp(severity) diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm index 4aaf778b6b21..1295d857b14c 100644 --- a/code/datums/mutations/hulk.dm +++ b/code/datums/mutations/hulk.dm @@ -43,3 +43,102 @@ message = "[replacetext(message, ".", "!")]!!" wrapped_message[1] = message return COMPONENT_UPPERCASE_SPEECH + +/datum/mutation/human/genetics_hulk + name = "Hulk" + desc = "A seemingly dormant genome, but reacts violently to agitation." + difficulty = 16 + instability = 50 + class = MUT_OTHER + locked = TRUE + quality = POSITIVE + get_chance = 10 + lowest_value = 256 * 14 + text_gain_indication = span_notice("You feel an anger welling inside you.") + health_req = 25 + +/datum/mutation/human/genetics_hulk/on_losing(mob/living/carbon/human/owner) + . = ..() + dna.remove_mutation(ACTIVE_HULK) + return + +/datum/mutation/human/active_hulk + name = "Hulk State" + desc = "The single most angry genome ever seen. Mutating this will incite a one-time immediate Hulkformation in the mutatee." + quality = POSITIVE + instability = 30 + class = MUT_OTHER + locked = TRUE + text_gain_indication = span_notice("Your muscles hurt!") + health_req = 1 + var/health_based = 0 + power_path = /datum/action/cooldown/spell/aoe/repulse/hulk + +/datum/mutation/human/active_hulk/on_acquiring(mob/living/carbon/human/owner) + if(..()) + return + owner.remove_CC() //RAGE RAGE RAGE, RISE RISE RISE + ADD_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) + ADD_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) + ADD_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_HULK) + RegisterSignal(owner, COMSIG_MOB_SAY, PROC_REF(handle_speech)) + if(istype(owner.w_uniform, /obj/item/clothing/under)) + var/obj/item/clothing/under/U = owner.w_uniform + if(owner.canUnEquip(U)) + owner.visible_message("[U] falls apart!", span_warning("You tear your clothes up in anger!")) + qdel(U) + if(istype(owner.wear_suit, /obj/item/clothing/suit)) + var/obj/item/clothing/suit/S = owner.wear_suit + if(owner.canUnEquip(S)) + owner.dropItemToGround(S) + owner.undershirt = "Nude" + owner.dna.species.no_equip.Add(ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING) + owner.say("PUNY HUMANS!!") + owner.physiology.stamina_mod = 0.3 + owner.update_body() + +/datum/mutation/human/active_hulk/on_attack_hand(atom/target, proximity) + if(proximity) //no telekinetic hulk attack + if(prob(3)) + owner.adjust_jitter(10 SECONDS) + owner.adjustStaminaLoss(-0.5) + return target.attack_hulk(owner) + +/datum/mutation/human/active_hulk/on_life() + owner.adjustStaminaLoss(0.9) + if(owner.health < 0) + on_losing(owner) + to_chat(owner, span_danger("You suddenly feel very weak. Your rage dies out.")) + +/datum/mutation/human/active_hulk/on_losing(mob/living/carbon/human/owner) + if(..()) + return + REMOVE_TRAIT(owner, TRAIT_STUNIMMUNE, TRAIT_HULK) + REMOVE_TRAIT(owner, TRAIT_PUSHIMMUNE, TRAIT_HULK) + REMOVE_TRAIT(owner, TRAIT_IGNORESLOWDOWN, TRAIT_HULK) + UnregisterSignal(owner, COMSIG_MOB_SAY) + owner.dna.species.no_equip.Remove(ITEM_SLOT_OCLOTHING, ITEM_SLOT_ICLOTHING) + owner.physiology.stamina_mod = initial(owner.physiology.stamina_mod) + owner.update_body_parts() + owner.dna.species.handle_mutant_bodyparts(owner) + +/datum/mutation/human/active_hulk/proc/handle_speech(original_message, wrapped_message) + var/message = wrapped_message[1] + if(message) + message = "[replacetext(message, ".", "!")]!!" + wrapped_message[1] = message + return COMPONENT_UPPERCASE_SPEECH + +/datum/action/cooldown/spell/aoe/repulse/hulk + name = "Ground Smash" + desc = "Smash the ground to throw your enemies back!" + invocation = "HULK SMASH!!" + button_icon = 'icons/mob/actions.dmi' + button_icon_state = "green_hand" + +/datum/action/cooldown/spell/aoe/repulse/hulk/cast_on_thing_in_aoe(atom/movable/victim, atom/caster) + var/turf/open/floor/turf = get_turf(victim) + if(istype(turf)) + turf.break_tile() + playsound(usr.loc, 'sound/effects/meteorimpact.ogg', 30, TRUE, 2) + return ..() diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 8a017d1be4f5..932d27d041a3 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -191,7 +191,7 @@ Class Procs: /obj/machinery/emp_act(severity) . = ..() if(use_power && !stat && !(. & EMP_PROTECT_SELF)) - use_power(750 * severity) + use_power(7500/severity) new /obj/effect/temp_visual/emp(loc) /obj/machinery/proc/open_machine(drop = TRUE) @@ -300,7 +300,11 @@ Class Procs: var/mob/living/carbon/H = user if(istype(H) && H.has_dna()) - if(!Adjacent(user) && !H.dna.check_mutation(TK)) + if (H.dna.check_mutation(ACTIVE_HULK)) + to_chat(H, span_warning("HULK NOT NERD. HULK SMASH!!!")) + return FALSE // hulks cant use machines + + else if(!Adjacent(user) && !H.dna.check_mutation(TK)) return FALSE // need to be close or have telekinesis return TRUE diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9f6a93a80e28..0cd4b1aa2516 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -145,7 +145,7 @@ if(!status) return if(!(. & EMP_PROTECT_SELF)) - if(prob(15 * severity)) + if(prob(150/severity)) update_appearance(UPDATE_ICON) var/list/previous_network = network network = list() @@ -165,7 +165,7 @@ if(can_use()) GLOB.cameranet.addCamera(src) emped = 0 //Resets the consecutive EMP count - addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), severity SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 100) for(var/i in GLOB.player_list) var/mob/M = i if (M.client.eye == src) diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index 4d8f22c4f9ef..f009648e90b6 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -532,7 +532,7 @@ GLOBAL_VAR_INIT(clones, 0) . = ..() if (!(. & EMP_PROTECT_SELF)) var/mob/living/mob_occupant = occupant - if(mob_occupant && prob(10 * severity / efficiency)) + if(mob_occupant && prob(100/(severity*efficiency))) log_cloning("[key_name(mob_occupant)] ejected from [src] at [AREACOORD(src)] due to EMP pulse.") connected_message(Gibberish("EMP-caused Accidental Ejection", 0)) SPEAK(Gibberish("Exposure to electromagnetic fields has caused the ejection of [mob_occupant.real_name] prematurely." ,0)) diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 03b93209c581..bb3317a61ac4 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -137,10 +137,14 @@ /obj/machinery/computer/emp_act(severity) . = ..() - if(. & EMP_PROTECT_SELF) - return - if(prob(5 * severity)) - obj_break(ENERGY) + if (!(. & EMP_PROTECT_SELF)) + switch(severity) + if(1) + if(prob(50)) + obj_break(ENERGY) + if(2) + if(prob(10)) + obj_break(ENERGY) /obj/machinery/computer/deconstruct(disassembled = TRUE, mob/user) on_deconstruction() diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 7c6a41699814..a124b493fa5d 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -120,7 +120,12 @@ GLOBAL_LIST_INIT(arcade_prize_pool, list( return var/empprize = null - var/num_of_prizes = rand(0, severity / 2.5) + var/num_of_prizes = 0 + switch(severity) + if(1) + num_of_prizes = rand(1,4) + if(2) + num_of_prizes = rand(0,2) for(var/i = num_of_prizes; i > 0; i--) if(override) empprize = pickweight(prize_override) diff --git a/code/game/machinery/computer/dna_console.dm b/code/game/machinery/computer/dna_console.dm index cefddeb1eda1..8fcbfe3f7298 100644 --- a/code/game/machinery/computer/dna_console.dm +++ b/code/game/machinery/computer/dna_console.dm @@ -721,9 +721,6 @@ // GUARD CHECK - This should not be possible. Unexpected result if(!HM) return - if(!HM.allow_cloning) - say("ERROR: This mutation is anomalous, and cannot be saved.") - return var/datum/mutation/human/A = new HM.type() A.copy_mutation(HM) @@ -1392,9 +1389,6 @@ // GUARD CHECK - This should not be possible. Unexpected result if(!HM) return - if(!HM.allow_cloning) - say("ERROR: This mutation is anomalous, and cannot be added to an injector.") - return // We want to make sure we stick within the instability limit. // We start with the instability of the mutation we're intending to add. diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index a26d877798de..cf7ed783af0b 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -534,7 +534,7 @@ . = ..() if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) for(var/datum/data/record/R in GLOB.data_core.medical) - if(prob(severity)) + if(prob(10/severity)) switch(rand(1,6)) if(1) if(prob(10)) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index bd642b99f661..4c3a77264c0d 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -875,7 +875,7 @@ return for(var/datum/data/record/R in GLOB.data_core.security) - if(prob(severity)) + if(prob(10/severity)) switch(rand(1,8)) if(1) if(prob(10)) diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm index 4607882135b0..80f82e598534 100644 --- a/code/game/machinery/doors/airlock_types.dm +++ b/code/game/machinery/doors/airlock_types.dm @@ -586,7 +586,7 @@ . += gear_text /obj/machinery/door/airlock/clockwork/emp_act(severity) - if(prob(8 * severity)) + if(prob(80/severity)) open() /obj/machinery/door/airlock/clockwork/canAIControl(mob/user) diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 4d298a074a71..ec977b8bf6f1 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -315,9 +315,9 @@ . = ..() if (. & EMP_PROTECT_SELF) return - if(prob(2 * severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) + if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) ) INVOKE_ASYNC(src, PROC_REF(open)) - if(prob(severity*2 - 20)) + if(prob(severity*10 - 20)) if(secondsElectrified == MACHINE_NOT_ELECTRIFIED) secondsElectrified = MACHINE_ELECTRIFIED_PERMANENT LAZYADD(shockedby, "\[[time_stamp()]\]EM Pulse") diff --git a/code/game/machinery/doors/windowdoor.dm b/code/game/machinery/doors/windowdoor.dm index 57f0db385dd8..5facd26aa3b7 100644 --- a/code/game/machinery/doors/windowdoor.dm +++ b/code/game/machinery/doors/windowdoor.dm @@ -423,7 +423,7 @@ return ..() /obj/machinery/door/window/clockwork/emp_act(severity) - if(prob(8 * severity)) + if(prob(80/severity)) open() /obj/machinery/door/window/clockwork/ratvar_act() diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 99b5a4987ec9..affa2aee4814 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -119,7 +119,7 @@ if (. & EMP_PROTECT_SELF) return - if(prob(5 * severity)) + if(prob(50 / severity)) alarm() /obj/machinery/firealarm/emag_act(mob/user, obj/item/card/emag/emag_card) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index fbb5417be5b5..5b86b762ba09 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -141,7 +141,7 @@ /obj/machinery/flasher/emp_act(severity) . = ..() if(!(stat & (BROKEN|NOPOWER)) && !(. & EMP_PROTECT_SELF)) - if(bulb && prob(8 * severity)) + if(bulb && prob(75/severity)) flash() bulb.burn_out() power_change() diff --git a/code/game/machinery/shieldgen.dm b/code/game/machinery/shieldgen.dm index f6015bb4142d..26750d15bcf2 100644 --- a/code/game/machinery/shieldgen.dm +++ b/code/game/machinery/shieldgen.dm @@ -25,10 +25,11 @@ . = ..() if (. & EMP_PROTECT_SELF) return - if(severity > EMP_LIGHT) - qdel(src) - return - take_damage(5 * severity, BRUTE, ENERGY, 0) + switch(severity) + if(1) + qdel(src) + if(2) + take_damage(50, BRUTE, ENERGY, 0) /obj/structure/emergency_shield/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0) switch(damage_type) diff --git a/code/game/machinery/shuttle/shuttle_heater.dm b/code/game/machinery/shuttle/shuttle_heater.dm index be8cb0542c9d..dc83f02e6814 100644 --- a/code/game/machinery/shuttle/shuttle_heater.dm +++ b/code/game/machinery/shuttle/shuttle_heater.dm @@ -228,7 +228,7 @@ /obj/machinery/power/engine_capacitor_bank/emp_act(severity) . = ..() - stored_power = stored_power * (0.9**(severity)) // exponential decay based on EMP severity, heavy EMPs (10 severity) reduce to 35% power + stored_power = rand(0, stored_power) /obj/machinery/power/engine_capacitor_bank/escape_pod name = "emergency thruster capacitor bank" diff --git a/code/game/machinery/slotmachine.dm b/code/game/machinery/slotmachine.dm index 96207b5acde1..4c06dfff4b67 100644 --- a/code/game/machinery/slotmachine.dm +++ b/code/game/machinery/slotmachine.dm @@ -182,7 +182,7 @@ return if(prob(1)) // :^) obj_flags |= EMAGGED - var/severity_ascending = 2 + (severity / 5) + var/severity_ascending = 4 - severity money = max(rand(money - (200 * severity_ascending), money + (200 * severity_ascending)), 0) balance = max(rand(balance - (50 * severity_ascending), balance + (50 * severity_ascending)), 0) money -= max(0, give_payout(min(rand(-50, 100 * severity_ascending)), money)) //This starts at -50 because it shouldn't always dispense coins yo diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 3bd5a4d73720..3799c63845e7 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -502,15 +502,16 @@ /obj/item/bombcore/emp name = "EMP payload" desc = "A set of superconducting electromagnetic coils designed to release a powerful pulse to destroy electronics and scramble circuits" - range_heavy = 25 // 25 severity, can do some serious damage + range_heavy = 15 + range_medium = 25 /obj/item/bombcore/emp/detonate() if(adminlog) message_admins(adminlog) log_game(adminlog) - empulse(src, range_heavy) - + empulse(src, range_heavy, range_medium) + qdel(src) ///Syndicate Detonator (aka the big red button)/// diff --git a/code/game/machinery/telecomms/telecomunications.dm b/code/game/machinery/telecomms/telecomunications.dm index 2d536cadb7f6..39455a7972a4 100644 --- a/code/game/machinery/telecomms/telecomunications.dm +++ b/code/game/machinery/telecomms/telecomunications.dm @@ -190,9 +190,9 @@ GLOBAL_LIST_EMPTY(telecomms_list) . = ..() if(. & EMP_PROTECT_SELF) return - if(prob(10 * severity) && !(stat & EMPED)) + if(prob(100/severity) && !(stat & EMPED)) stat |= EMPED - var/duration = (30 SECONDS) * severity // 30 seconds per level of severity, 5 minutes at 10 severity (EMP_HEAVY) + var/duration = (300 * 10)/severity addtimer(CALLBACK(src, PROC_REF(de_emp)), rand(duration - 20, duration + 20)) /obj/machinery/telecomms/proc/de_emp() diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index a2e3d2f9084b..4762da6c0e5e 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -161,8 +161,8 @@ if (. & EMP_PROTECT_SELF) return if(get_charge()) - use_power((cell.charge * severity / 15)) - take_damage(4 * severity, BURN, ENERGY, 1) + use_power((cell.charge/3)/(severity*2)) + take_damage(40 / severity, BURN, ENERGY, 1) log_message("EMP detected", LOG_MECHA, color="red") if(istype(src, /obj/mecha/combat)) diff --git a/code/game/objects/empulse.dm b/code/game/objects/empulse.dm index a9c029047219..34fa0ccd6e2c 100644 --- a/code/game/objects/empulse.dm +++ b/code/game/objects/empulse.dm @@ -1,30 +1,32 @@ -/proc/empulse(turf/epicenter, severity, range=null, log=TRUE) +/proc/empulse(turf/epicenter, heavy_range, light_range, log=0) if(!epicenter) - CRASH("Warning: empulse() called without an epicenter!") - - if(severity < 1) return if(!isturf(epicenter)) epicenter = get_turf(epicenter.loc) - - if(isnull(range)) // range is equal to severity by default - range = severity if(log) - message_admins("EMP with size ([range]) and severity ([severity]) in area [epicenter.loc.name] ") - log_game("EMP with size ([range]) and severity ([severity]) in area [epicenter.loc.name] ") + message_admins("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") + log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ") - if(range <= 0) - for(var/atom/A in epicenter) - A.emp_act(severity) - return + if(heavy_range > 1) + new /obj/effect/temp_visual/emp/pulse(epicenter) + + if(heavy_range > light_range) + light_range = heavy_range - var/tile_falloff = severity / range - for(var/A in spiral_range(range, epicenter)) + for(var/A in spiral_range(light_range, epicenter)) var/atom/T = A - var/decayed_severity = severity - round(get_dist(epicenter, T) * tile_falloff) - if(decayed_severity < 1) - continue - T.emp_act(decayed_severity) - return TRUE + var/distance = get_dist(epicenter, T) + if(distance < 0) + distance = 0 + if(distance < heavy_range) + T.emp_act(EMP_HEAVY) + else if(heavy_range && distance == heavy_range) //0 radius heavy EMPs will have no effect + if(prob(50)) + T.emp_act(EMP_HEAVY) + else + T.emp_act(EMP_LIGHT) + else if(distance <= light_range) + T.emp_act(EMP_LIGHT) + return 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3f4a01368f62..da5e2603479b 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -296,11 +296,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) if(HAS_TRAIT(src, TRAIT_NO_STORAGE)) . += "[gender == PLURAL ? "They are" : "It is"] too bulky, fragile, or cumbersome to fit in a container." - if(demolition_mod > 1) - . += "[src] seems exceptionally good at breaking things!" - else if(demolition_mod < 1) - . += "[src] seems exceptionally bad at breaking things." - if(resistance_flags & INDESTRUCTIBLE) . += "[src] seems extremely robust! It'll probably withstand anything that could happen to it!" else diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm index 6683b6c5481e..5d1cc2e0deb9 100644 --- a/code/game/objects/items/credit_holochip.dm +++ b/code/game/objects/items/credit_holochip.dm @@ -105,7 +105,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - var/wipe_chance = 6 * severity + var/wipe_chance = 60 / severity if(prob(wipe_chance)) visible_message(span_warning("[src] fizzles and disappears!")) qdel(src) //rip cash diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm index 8c7c4fe6122d..3e2b142d372f 100644 --- a/code/game/objects/items/defib.dm +++ b/code/game/objects/items/defib.dm @@ -153,7 +153,7 @@ . = ..() if(cell && !(. & EMP_PROTECT_CONTENTS)) - deductcharge(500 * severity) + deductcharge(5000 / severity) if (. & EMP_PROTECT_SELF) return diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index edd624f642e3..2b184cbf362b 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1226,7 +1226,7 @@ GLOBAL_LIST_EMPTY(PDAs) A.emp_act(severity) if (!(. & EMP_PROTECT_SELF)) emped += 1 - spawn(20 * severity) + spawn(200 * severity) emped -= 1 /proc/get_viewable_pdas() diff --git a/code/game/objects/items/devices/laserpointer.dm b/code/game/objects/items/devices/laserpointer.dm index 84f32bcdabca..dc6c33d1a1b4 100644 --- a/code/game/objects/items/devices/laserpointer.dm +++ b/code/game/objects/items/devices/laserpointer.dm @@ -87,7 +87,7 @@ return if(ishuman(user)) var/mob/living/carbon/human/H = user - if(H.dna.check_mutation(HULK)) + if(H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK)) to_chat(user, span_warning("Your fingers can't press the button!")) return diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm index cb5027fa300c..873b1803cf31 100644 --- a/code/game/objects/items/devices/radio/radio.dm +++ b/code/game/objects/items/devices/radio/radio.dm @@ -429,6 +429,7 @@ GLOBAL_LIST_INIT(channel_tokens, list( if (. & EMP_PROTECT_SELF) return emped++ //There's been an EMP; better count it + var/curremp = emped //Remember which EMP this was if (listening && ismob(loc)) // if the radio is turned on and on someone's person they notice to_chat(loc, span_warning("\The [src] overloads.")) broadcasting = FALSE @@ -436,9 +437,11 @@ GLOBAL_LIST_INIT(channel_tokens, list( for (var/ch_name in channels) channels[ch_name] = 0 on = FALSE - addtimer(CALLBACK(src, PROC_REF(end_emp_effect)), 20 * severity, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(end_emp_effect), curremp), 200) -/obj/item/radio/proc/end_emp_effect() +/obj/item/radio/proc/end_emp_effect(curremp) + if(emped != curremp) //Don't fix it if it's been EMP'd again + return FALSE emped = FALSE on = TRUE return TRUE diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 39633ed98f4d..7b7e66a7769a 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -362,7 +362,7 @@ GENE SCANNER var/mob/living/carbon/human/H = M var/datum/species/S = H.dna.species var/mutant = FALSE - if (H.dna.check_mutation(HULK)) + if (H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK)) mutant = TRUE else if (S.mutantlungs != initial(S.mutantlungs)) mutant = TRUE diff --git a/code/game/objects/items/dna_injector.dm b/code/game/objects/items/dna_injector.dm index 2ec72419d8d2..7d182fba2cbd 100644 --- a/code/game/objects/items/dna_injector.dm +++ b/code/game/objects/items/dna_injector.dm @@ -88,7 +88,12 @@ /obj/item/dnainjector/antihulk name = "\improper DNA injector (Anti-Hulk)" desc = "Cures green skin." - remove_mutations = list(HULK) + remove_mutations = list(HULK, ACTIVE_HULK, GENETICS_HULK) + +/obj/item/dnainjector/hulkmut/genetics_hulk + name = "\improper DNA injector (Genetics Hulk)" + desc = "This will make you big and strong if you get hurt, but give you a bad skin condition." + add_mutations = list(GENETICS_HULK) /obj/item/dnainjector/hulkmut name = "\improper DNA injector (Hulk)" diff --git a/code/game/objects/items/granters/magic/charge.dm b/code/game/objects/items/granters/magic/charge.dm index d0c33ed14701..72ab119aa152 100644 --- a/code/game/objects/items/granters/magic/charge.dm +++ b/code/game/objects/items/granters/magic/charge.dm @@ -17,4 +17,4 @@ /obj/item/book/granter/action/spell/charge/recoil(mob/living/user) . = ..() to_chat(user,span_warning("[src] suddenly feels very warm!")) - empulse(src, EMP_HEAVY, 0) + empulse(src, 1, 1) \ No newline at end of file diff --git a/code/game/objects/items/grenades/chem_grenade.dm b/code/game/objects/items/grenades/chem_grenade.dm index 2423c687ef52..416ac77f0518 100644 --- a/code/game/objects/items/grenades/chem_grenade.dm +++ b/code/game/objects/items/grenades/chem_grenade.dm @@ -151,7 +151,7 @@ /obj/item/grenade/chem_grenade/emp_act(severity) ..() - if(prob(4 * severity)) + if(prob(40/severity)) prime() /obj/item/grenade/chem_grenade/on_found(mob/finder) diff --git a/code/game/objects/items/grenades/emgrenade.dm b/code/game/objects/items/grenades/emgrenade.dm index 082663addd44..99cf4bdf99d1 100644 --- a/code/game/objects/items/grenades/emgrenade.dm +++ b/code/game/objects/items/grenades/emgrenade.dm @@ -6,5 +6,5 @@ /obj/item/grenade/empgrenade/prime() update_mob() - empulse(src, EMP_HEAVY) + empulse(src, 4, 10) qdel(src) diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm index 9bbece6a4047..837b947b3bf7 100644 --- a/code/game/objects/items/implants/implant_misc.dm +++ b/code/game/objects/items/implants/implant_misc.dm @@ -64,7 +64,7 @@ /obj/item/implant/emp/activate() . = ..() uses-- - empulse(imp_in, EMP_HEAVY, 5) // 10 severity, extends to 5 tiles + empulse(imp_in, 3, 5) if(!uses) qdel(src) @@ -174,13 +174,13 @@ UnregisterSignal(target, COMSIG_ATOM_EMP_ACT) return TRUE -/obj/item/implant/empshield/proc/overloaded(mob/living/target, severity) +/obj/item/implant/empshield/proc/overloaded(mob/living/target) if(world.time - lastemp > overloadtimer) numrecent = 0 - numrecent += severity + numrecent ++ lastemp = world.time - if(numrecent >= (5 * EMP_HEAVY) && ishuman(target)) + if(numrecent >= 5 && ishuman(target)) if(warning) to_chat(target, span_userdanger("You feel a twinge inside from your [src], you get the feeling it won't protect you anymore.")) warning = FALSE diff --git a/code/game/objects/items/kitchen.dm b/code/game/objects/items/kitchen.dm index 9d6e0c8a939f..773871e48a49 100644 --- a/code/game/objects/items/kitchen.dm +++ b/code/game/objects/items/kitchen.dm @@ -92,7 +92,6 @@ hitsound = 'sound/weapons/bladeslice.ogg' throw_speed = 3 throw_range = 6 - demolition_mod = 0.8 materials = list(/datum/material/iron=12000) attack_verb = list("slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") sharpness = SHARP_EDGED diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 2fce62a8bc34..98342c6c4910 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -78,18 +78,19 @@ togglelock(user) /obj/item/storage/lockbox/emp_act(severity) - if(severity > EMP_LIGHT) - emag_act() - return - if(prob(6 * severity)) - var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked) - locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) - if(locked) - icon_state = icon_locked - SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL) - else - icon_state = icon_closed + switch(severity) + if(EMP_HEAVY) + emag_act() + if(EMP_LIGHT) + if(prob(60)) + var/locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SET_LOCKSTATE, !locked) + locked = SEND_SIGNAL(src, COMSIG_IS_STORAGE_LOCKED) + if(locked) + icon_state = icon_locked + SEND_SIGNAL(src, COMSIG_TRY_STORAGE_HIDE_ALL) + else + icon_state = icon_closed /obj/item/storage/lockbox/loyalty name = "lockbox of mindshield implants" diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index d7b7421bf7b5..0736463ba346 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -257,7 +257,7 @@ /obj/item/melee/baton/emp_act(severity) . = ..() if (!(. & EMP_PROTECT_SELF)) - deductcharge(100 * severity) + deductcharge(1000 / severity) //Makeshift stun baton. Replacement for stun gloves. /obj/item/melee/baton/cattleprod diff --git a/code/game/objects/items/supermatter_delaminator.dm b/code/game/objects/items/supermatter_delaminator.dm index 2624ca7c7575..08463ca7b125 100644 --- a/code/game/objects/items/supermatter_delaminator.dm +++ b/code/game/objects/items/supermatter_delaminator.dm @@ -201,7 +201,7 @@ investigate_log("has consumed [key_name(user)].", "supermatter") user.dust() radiation_pulse(src, 500, 2) - empulse(src, EMP_HEAVY) + empulse(src, 5, 10) playsound(src, 'sound/effects/supermatter.ogg', 50, 1) QDEL_NULL(shard) update_appearance(UPDATE_ICON) diff --git a/code/game/objects/items/tools/crowbar.dm b/code/game/objects/items/tools/crowbar.dm index 027d16615440..3f84093da693 100644 --- a/code/game/objects/items/tools/crowbar.dm +++ b/code/game/objects/items/tools/crowbar.dm @@ -10,7 +10,6 @@ slot_flags = ITEM_SLOT_BELT force = 5 throwforce = 7 - demolition_mod = 2 // the right tool in the wrong place can make all the difference w_class = WEIGHT_CLASS_SMALL materials = list(/datum/material/iron=50) drop_sound = 'sound/items/handling/crowbar_drop.ogg' diff --git a/code/game/objects/items/tools/screwdriver.dm b/code/game/objects/items/tools/screwdriver.dm index 12a0bbacda73..2db3040fec34 100644 --- a/code/game/objects/items/tools/screwdriver.dm +++ b/code/game/objects/items/tools/screwdriver.dm @@ -9,7 +9,6 @@ flags_1 = CONDUCT_1 slot_flags = ITEM_SLOT_BELT force = 5 - demolition_mod = 0.5 w_class = WEIGHT_CLASS_TINY throwforce = 5 throw_speed = 3 diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm index 5470eef922ec..f69488465225 100644 --- a/code/game/objects/items/tools/weldingtool.dm +++ b/code/game/objects/items/tools/weldingtool.dm @@ -23,7 +23,6 @@ light_on = FALSE throw_speed = 3 throw_range = 5 - demolition_mod = 0.5 // not very good at smashing w_class = WEIGHT_CLASS_SMALL armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 100, ACID = 30) resistance_flags = FIRE_PROOF @@ -226,7 +225,6 @@ playsound(loc, acti_sound, 50, 1) force = 12 damtype = BURN - demolition_mod = 1.5 // pretty good at cutting hitsound = 'sound/items/welder.ogg' update_appearance(UPDATE_ICON) START_PROCESSING(SSobj, src) @@ -245,7 +243,6 @@ force = 3 damtype = "brute" hitsound = "swing_hit" - demolition_mod = initial(demolition_mod) update_appearance(UPDATE_ICON) diff --git a/code/game/objects/items/tools/wrench.dm b/code/game/objects/items/tools/wrench.dm index fcd948da6187..2ff293b763cd 100644 --- a/code/game/objects/items/tools/wrench.dm +++ b/code/game/objects/items/tools/wrench.dm @@ -9,7 +9,6 @@ slot_flags = ITEM_SLOT_BELT force = 5 throwforce = 7 - demolition_mod = 1.5 w_class = WEIGHT_CLASS_SMALL usesound = 'sound/items/ratchet.ogg' materials = list(/datum/material/iron=150) diff --git a/code/game/objects/items/two_handed/chainsaw.dm b/code/game/objects/items/two_handed/chainsaw.dm index 9aa4aa9affe9..38e447b0d432 100644 --- a/code/game/objects/items/two_handed/chainsaw.dm +++ b/code/game/objects/items/two_handed/chainsaw.dm @@ -14,7 +14,6 @@ throwforce = 13 throw_speed = 2 throw_range = 4 - demolition_mod = 1.5 materials = list(/datum/material/iron=13000) attack_verb = list("sawed", "torn", "cut", "chopped", "diced") hitsound = "swing_hit" diff --git a/code/game/objects/items/two_handed/dualsaber.dm b/code/game/objects/items/two_handed/dualsaber.dm index e369a884d41c..04f60ab2e035 100644 --- a/code/game/objects/items/two_handed/dualsaber.dm +++ b/code/game/objects/items/two_handed/dualsaber.dm @@ -93,7 +93,7 @@ /obj/item/melee/dualsaber/attack(mob/target, mob/living/carbon/human/user) if(user.has_dna()) - if(user.dna.check_mutation(HULK)) + if(user.dna.check_mutation(HULK) || user.dna.check_mutation(ACTIVE_HULK)) to_chat(user, span_warning("You grip the blade too hard and accidentally close it!")) if(HAS_TRAIT(src, TRAIT_WIELDED)) user.dropItemToGround(src, force=TRUE) @@ -183,7 +183,7 @@ /obj/item/melee/dualsaber/proc/on_wield(atom/source, mob/living/carbon/M) if(!M.has_dna()) return - if(M.dna.check_mutation(HULK)) + if(M.dna.check_mutation(HULK) || M.dna.check_mutation(ACTIVE_HULK)) to_chat(M, span_warning("You lack the grace to wield this!")) return sharpness = SHARP_EDGED diff --git a/code/game/objects/items/two_handed/fireaxe.dm b/code/game/objects/items/two_handed/fireaxe.dm index 16b1bc27484d..19bfcbc3d6e7 100644 --- a/code/game/objects/items/two_handed/fireaxe.dm +++ b/code/game/objects/items/two_handed/fireaxe.dm @@ -8,7 +8,6 @@ desc = "Truly, the weapon of a madman. Who would think to fight fire with an axe?" force = 5 throwforce = 15 - demolition_mod = 3 // specifically designed for breaking things w_class = WEIGHT_CLASS_BULKY slot_flags = ITEM_SLOT_BACK attack_verb = list("attacked", "chopped", "cleaved", "torn", "cut", "axed") @@ -43,8 +42,6 @@ . = ..() if(!proximity) return - if(QDELETED(A)) - return if(HAS_TRAIT(src, TRAIT_WIELDED)) //destroys shit faster, generally in 1-2 hits. if(istype(A, /obj/structure/window)) var/obj/structure/window/W = A @@ -52,6 +49,12 @@ else if(istype(A, /obj/structure/grille)) var/obj/structure/grille/G = A G.take_damage(G.max_integrity*2, BRUTE, MELEE, FALSE, null, armour_penetration) + else if(istype(A, /obj/machinery/door)) //Nines hits for reinforced airlock, seven for normal + var/obj/machinery/door/D = A + D.take_damage((force+25), BRUTE, MELEE, FALSE, null, armour_penetration) + else if(istype(A, /obj/structure/door_assembly)) //Two hits for frames left behind + var/obj/machinery/door/D = A + D.take_damage((force+25), BRUTE, MELEE, FALSE, null, armour_penetration) /* * Metal Hydrogen Axe @@ -82,7 +85,6 @@ icon = 'icons/obj/weapons/energy.dmi' icon_state = "energy-fireaxe0" base_icon_state = "energy-fireaxe" - demolition_mod = 4 // DESTROY armour_penetration = 50 // Probably doesn't care much for armor given how it can destroy solid metal structures block_chance = 50 // Big handle and large flat energy blade, good for blocking things heat = 1800 // It's a FIRE axe @@ -128,6 +130,15 @@ ..() M.ignite_mob() // Ignites you if you're flammable +/obj/item/fireaxe/energy/afterattack(atom/A, mob/user, proximity) + . = ..() + if(!proximity) + return + if(HAS_TRAIT(src, TRAIT_WIELDED)) // Does x2 damage against inanimate objects like machines, structures, mechs, etc + if(isobj(A) && !isitem(A)) + var/obj/O = A + O.take_damage(force, BRUTE, MELEE, FALSE, null, armour_penetration) + /obj/item/fireaxe/energy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text, final_block_chance, damage, attack_type) if(!HAS_TRAIT(src, TRAIT_WIELDED)) return 0 // large energy blade can only block stuff if it's actually on diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 9b0f45b5b393..52e7e793e80a 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -80,7 +80,7 @@ playsound(src, P.hitsound, 50, 1) visible_message(span_danger("[src] is hit by \a [P]!"), null, null, COMBAT_MESSAGE_RANGE) if(!QDELETED(src)) //Bullet on_hit effect might have already destroyed this object - take_damage(P.damage * P.demolition_mod, P.damage_type, P.armor_flag, 0, turn(P.dir, 180), P.armour_penetration) + take_damage(P.damage, P.damage_type, P.armor_flag, 0, turn(P.dir, 180), P.armour_penetration) ///Called to get the damage that hulks will deal to the obj. /obj/proc/hulk_damage() diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index 686438b8b836..1da9c19201fc 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -16,8 +16,6 @@ var/wound_bonus = 0 /// If this attacks a human with no wound armor on the affected body part, add this to the wound mod. Some attacks may be significantly worse at wounding if there's even a slight layer of armor to absorb some of it vs bare flesh var/bare_wound_bonus = 0 - /// Damage multiplier against structures, machines, mechs, and to a lesser extent silicons - var/demolition_mod = 1 var/datum/armor/armor var/obj_integrity //defaults to max_integrity diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 66d75d7e3125..e0b28c32f251 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -550,10 +550,10 @@ GLOBAL_LIST_EMPTY(lockers) for(var/obj/O in src) O.emp_act(severity) if(secure && !broken && !(. & EMP_PROTECT_SELF)) - if(prob(5 * severity)) + if(prob(50 / severity)) locked = !locked update_appearance(UPDATE_ICON) - if(prob(2 * severity) && !opened) + if(prob(20 / severity) && !opened) if(!locked) open() else diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index a74290108199..495d2ba6db17 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -703,17 +703,18 @@ Traitors and the like can also be revived with the previous role mostly intact. if(!check_rights(R_ADMIN)) return - var/severity = input("Severity of pulse.", text("Input")) as num|null - if(!isnum(severity)) + var/heavy = input("Range of heavy pulse.", text("Input")) as num|null + if(heavy == null) + return + var/light = input("Range of light pulse.", text("Input")) as num|null + if(light == null) return - var/range = input("Range of pulse.", text("Input")) as num|null - if(!isnum(range)) - range = severity - if (severity) - empulse(O, severity, range) - log_admin("[key_name(usr)] created an EM Pulse ([range] range, [severity] severity) at [AREACOORD(O)]") - message_admins("[key_name_admin(usr)] created an EM Pulse ([range] range, [severity] severity) at [AREACOORD(O)]") + if (heavy || light) + + empulse(O, heavy, light) + log_admin("[key_name(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]") + message_admins("[key_name_admin(usr)] created an EM Pulse ([heavy],[light]) at [AREACOORD(O)]") SSblackbox.record_feedback("tally", "admin_verb", 1, "EM Pulse") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! return diff --git a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm index 2ccd4b6f646e..8c98537297d1 100644 --- a/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm +++ b/code/modules/antagonists/blob/blobstrains/electromagnetic_web.dm @@ -22,7 +22,7 @@ /datum/blobstrain/reagent/electromagnetic_web/death_reaction(obj/structure/blob/B, damage_flag) if(damage_flag == MELEE || damage_flag == BULLET || damage_flag == LASER) - empulse(B.loc, EMP_HEAVY, 3) //less than screen range, so you can stand out of range to avoid it + empulse(B.loc, 1, 3) //less than screen range, so you can stand out of range to avoid it /datum/reagent/blob/electromagnetic_web name = "Electromagnetic Web" @@ -32,6 +32,6 @@ /datum/reagent/blob/electromagnetic_web/reaction_mob(mob/living/M, methods = TOUCH, reac_volume, show_message, permeability, mob/camera/blob/O) reac_volume = ..() if(prob(reac_volume*2)) - M.emp_act(min(reac_volume / 10, EMP_HEAVY)) + M.emp_act(EMP_LIGHT) if(M) M.apply_damage(reac_volume, BURN, wound_bonus=CANT_WOUND) diff --git a/code/modules/antagonists/blob/structures/_blob.dm b/code/modules/antagonists/blob/structures/_blob.dm index e7054ad62198..97d62b945c89 100644 --- a/code/modules/antagonists/blob/structures/_blob.dm +++ b/code/modules/antagonists/blob/structures/_blob.dm @@ -206,7 +206,7 @@ if(severity > 0) if(overmind) overmind.blobstrain.emp_reaction(src, severity) - if(prob(40 + (severity * 6))) + if(prob(100 - severity * 30)) new /obj/effect/temp_visual/emp(get_turf(src)) /obj/structure/blob/tesla_act(power, tesla_flags, shocked_targets, zap_gib = FALSE) diff --git a/code/modules/antagonists/bloodsuckers/powers/feed.dm b/code/modules/antagonists/bloodsuckers/powers/feed.dm index 4b62c8dbc97d..d0e5a60401aa 100644 --- a/code/modules/antagonists/bloodsuckers/powers/feed.dm +++ b/code/modules/antagonists/bloodsuckers/powers/feed.dm @@ -58,7 +58,7 @@ /datum/action/cooldown/bloodsucker/feed/DeactivatePower() var/mob/living/user = owner - var/mob/living/feed_target = target_ref?.resolve() + var/mob/living/feed_target = target_ref.resolve() if(isnull(feed_target)) log_combat(user, user, "fed on blood (target not found)", addition="(and took [blood_taken] blood)") else @@ -136,7 +136,7 @@ if(!active) //If we aren't active (running on SSfastprocess) return ..() //Manage our cooldown timers var/mob/living/user = owner - var/mob/living/feed_target = target_ref?.resolve() + var/mob/living/feed_target = target_ref.resolve() if(!ContinueActive(user, feed_target)) if(!silent_feed) user.visible_message( diff --git a/code/modules/antagonists/bloodsuckers/powers/gangrel.dm b/code/modules/antagonists/bloodsuckers/powers/gangrel.dm index 91ab766577bd..1b3962b568db 100644 --- a/code/modules/antagonists/bloodsuckers/powers/gangrel.dm +++ b/code/modules/antagonists/bloodsuckers/powers/gangrel.dm @@ -24,9 +24,11 @@ /datum/action/cooldown/bloodsucker/gangrel/transform/ActivatePower() var/datum/antagonist/bloodsucker/bloodsuckerdatum = owner.mind.has_antag_datum(/datum/antagonist/bloodsucker) var/mob/living/carbon/human/user = owner + if(!do_after(user, 10 SECONDS)) + return var/list/radial_display = list() //get our options, switches are kinda weird here cause wwe ant to stack them - if(bloodsuckerdatum) //makes the icons for the options + if(bloodsuckerdatum.total_blood_drank) //makes the icons for the options var/datum/radial_menu_choice/option = new user.setDir(SOUTH) var/icon/icon_to_mix = getFlatIcon(user) @@ -53,8 +55,6 @@ option.info = "Turn into a giant bat simple mob with unique abilities." radial_display["Bat"] = option var/chosen_transform = show_radial_menu(user, user, radial_display) - if(!chosen_transform || !do_after(user, 10 SECONDS)) - return transform(chosen_transform) //actually transform return ..() diff --git a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm index d019b1f00538..ed424caf0cbd 100644 --- a/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm +++ b/code/modules/antagonists/bloodsuckers/structures/bloodsucker_life.dm @@ -291,46 +291,7 @@ if(bloodsucker_blood_volume < (FRENZY_THRESHOLD_ENTER + humanity_lost * 10) && !frenzied) if(!iscarbon(owner.current)) return - if(my_clan?.get_clan() == CLAN_GANGREL) - var/mob/living/carbon/user = owner.current - switch(frenzies) - if(0) - owner.current.apply_status_effect(STATUS_EFFECT_FRENZY) - if(1) - to_chat(owner, span_warning("You start feeling hungrier, you feel like a normal frenzy won't satiate it enough anymore.")) - owner.current.apply_status_effect(STATUS_EFFECT_FRENZY) - if(2 to INFINITY) - if(do_after(user, 2 SECONDS, user, IGNORE_ALL)) - playsound(user.loc, 'sound/weapons/slash.ogg', 25, 1) - to_chat(user, span_warning("You skin rips and tears.")) - if(do_after(user, 1 SECONDS, user, IGNORE_ALL)) - playsound(user.loc, 'sound/weapons/slashmiss.ogg', 25, 1) - to_chat(user, span_warning("You heart pumps blackened blood into your veins as your skin turns into fur.")) - if(do_after(user, 1 SECONDS, user, IGNORE_ALL)) - playsound(user.loc, 'sound/weapons/slice.ogg', 25, 1) - to_chat(user, span_boldnotice("YOU HAVE AWOKEN.")) - var/mob/living/simple_animal/hostile/bloodsucker/werewolf/ww - if(!ww || ww.stat == DEAD) - AddBloodVolume(560 - user.blood_volume) //so it doesn't happen multiple times and refills your blood when you get out again - ww = new /mob/living/simple_animal/hostile/bloodsucker/werewolf(user.loc) - user.forceMove(ww) - ww.bloodsucker = user - user.mind.transfer_to(ww) - var/list/wolf_powers = list(new /datum/action/cooldown/bloodsucker/targeted/feast,) - for(var/datum/action/cooldown/bloodsucker/power in powers) - if(istype(power, /datum/action/cooldown/bloodsucker/fortitude)) - wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/wolfortitude - if(istype(power, /datum/action/cooldown/bloodsucker/targeted/lunge)) - wolf_powers += new /datum/action/cooldown/bloodsucker/targeted/pounce - if(istype(power, /datum/action/cooldown/bloodsucker/cloak)) - wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/howl - if(istype(power, /datum/action/cooldown/bloodsucker/targeted/trespass)) - wolf_powers += new /datum/action/cooldown/bloodsucker/gangrel/rabidism - for(var/datum/action/cooldown/bloodsucker/power in wolf_powers) - power.Grant(ww) - frenzies ++ - else - owner.current.apply_status_effect(STATUS_EFFECT_FRENZY) + owner.current.apply_status_effect(/datum/status_effect/frenzy) else if(bloodsucker_blood_volume < BLOOD_VOLUME_BAD(owner.current)) additional_regen = 0.1 else if(bloodsucker_blood_volume < BLOOD_VOLUME_OKAY(owner.current)) diff --git a/code/modules/antagonists/changeling/powers/shriek.dm b/code/modules/antagonists/changeling/powers/shriek.dm index 9c3cf68e97b7..6a56642dce33 100644 --- a/code/modules/antagonists/changeling/powers/shriek.dm +++ b/code/modules/antagonists/changeling/powers/shriek.dm @@ -53,5 +53,5 @@ for(var/obj/machinery/light/L in range(5, usr)) L.on = 1 L.break_light_tube() - empulse(get_turf(user), EMP_HEAVY, 5, 1) + empulse(get_turf(user), 2, 5, 1) return TRUE diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm index 1d71903ac051..d931924b3b5d 100644 --- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm +++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/longsword.dm @@ -8,14 +8,13 @@ block_chance = 35 attack_verb = list("attacked", "slashed", "cut", "torn", "gored") clockwork_desc = "A powerful sword of Ratvarian making. Enemies hit with it will be struck with a powerful electromagnetic pulse." - var/emp_severity = EMP_LIGHT var/emp_cooldown = 0 var/cooldown_duration = 10 SECONDS /obj/item/clockwork/weapon/brass_sword/attack(mob/living/target, mob/living/carbon/human/user) . = ..() if(world.time > emp_cooldown && !is_servant_of_ratvar(target)) - target.emp_act(emp_severity) + target.emp_act(EMP_LIGHT) emp_cooldown = world.time + cooldown_duration addtimer(CALLBACK(src, PROC_REF(send_message)), cooldown_duration) to_chat(user, "You strike [target] with an electromagnetic pulse!") @@ -25,7 +24,7 @@ /obj/item/clockwork/weapon/brass_sword/attack_obj(obj/O, mob/living/user) . = ..() if(world.time > emp_cooldown && ismecha(O)) - O.emp_act(emp_severity * 2) + O.emp_act(EMP_HEAVY) emp_cooldown = world.time + cooldown_duration addtimer(CALLBACK(src, PROC_REF(send_message)), cooldown_duration) to_chat(user, "You strike [O] with an electromagnetic pulse!") diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm index 2178b39cbb87..f7205a0f919a 100644 --- a/code/modules/antagonists/cult/runes.dm +++ b/code/modules/antagonists/cult/runes.dm @@ -1052,7 +1052,7 @@ GLOBAL_VAR_INIT(narsie_summon_count, 0) visible_message(span_warning("A colossal shockwave of energy bursts from the rune, disintegrating it in the process!")) for(var/mob/living/L in range(src, 3)) L.Paralyze(30) - empulse(T, 0.42*(intensity)) + empulse(T, 0.42*(intensity), 1) var/list/images = list() var/zmatch = T.z var/datum/atom_hud/AH = GLOB.huds[DATA_HUD_SECURITY_ADVANCED] diff --git a/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm b/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm index ab839dd64ed3..7af0106e0ac7 100644 --- a/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm +++ b/code/modules/antagonists/eldritch_cult/magic/general_heretic_magic.dm @@ -156,7 +156,8 @@ THIS FILE IS FOR ALL HERETIC SPELLS THAT DO NOT CONFER TO A PATH'S THEME OR YOU invocation_type = INVOCATION_WHISPER spell_requirements = SPELL_CASTABLE_WITHOUT_INVOCATION | SPELL_REQUIRES_NO_ANTIMAGIC - radius = 10 + emp_heavy = 6 + emp_light = 10 /datum/action/cooldown/spell/list_target/telepathy/eldritch name = "Eldritch Telepathy" diff --git a/code/modules/atmospherics/gasmixtures/gas_mixture.dm b/code/modules/atmospherics/gasmixtures/gas_mixture.dm index af260e5397f7..b7855c3f54f2 100644 --- a/code/modules/atmospherics/gasmixtures/gas_mixture.dm +++ b/code/modules/atmospherics/gasmixtures/gas_mixture.dm @@ -279,16 +279,13 @@ get_true_breath_pressure(pp) --> gas_pp = pp/breath_pp*total_moles() /datum/gas_mixture/proc/equalize(datum/gas_mixture/other) . = FALSE - if(!return_volume() || !other.return_volume()) - return - var/self_temp = return_temperature() var/other_temp = other.return_temperature() if(abs(self_temp - other_temp) > MINIMUM_TEMPERATURE_DELTA_TO_SUSPEND) . = TRUE var/self_heat_cap = heat_capacity() var/other_heat_cap = other.heat_capacity() - var/new_temp = max((self_temp * self_heat_cap + other_temp * other_heat_cap) / (self_heat_cap + other_heat_cap), TCMB) + var/new_temp = (self_temp * self_heat_cap + other_temp * other_heat_cap) / (self_heat_cap + other_heat_cap) set_temperature(new_temp) other.set_temperature(new_temp) diff --git a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm index e6e67f3c501f..e1603bc97663 100644 --- a/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm +++ b/code/modules/atmospherics/machinery/components/fusion/hfr_procs.dm @@ -439,7 +439,8 @@ var/devastating_explosion = 0 var/em_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_EMP var/rad_pulse = selected_fuel.meltdown_flags & HYPERTORUS_FLAG_RADIATION_PULSE - var/emp_severity = 0 + var/emp_light_size = 0 + var/emp_heavy_size = 0 var/rad_pulse_size = 0 var/rad_pulse_strength = 0 var/gas_spread = 0 @@ -463,7 +464,8 @@ if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MINIMUM_SPREAD) if(em_pulse) - emp_severity = power_level * 3 + emp_light_size = power_level * 3 + emp_heavy_size = power_level * 1 if(rad_pulse) rad_pulse_size = (1 / (power_level + 1)) rad_pulse_strength = power_level * 3000 @@ -472,7 +474,8 @@ if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MEDIUM_SPREAD) if(em_pulse) - emp_severity = power_level * 5 + emp_light_size = power_level * 5 + emp_heavy_size = power_level * 3 if(rad_pulse) rad_pulse_size = (1 / (power_level + 3)) rad_pulse_strength = power_level * 5000 @@ -481,7 +484,8 @@ if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_BIG_SPREAD) if(em_pulse) - emp_severity = power_level * 7 + emp_light_size = power_level * 7 + emp_heavy_size = power_level * 5 if(rad_pulse) rad_pulse_size = (1 / (power_level + 5)) rad_pulse_strength = power_level * 7000 @@ -490,7 +494,8 @@ if(selected_fuel.meltdown_flags & HYPERTORUS_FLAG_MASSIVE_SPREAD) if(em_pulse) - emp_severity = power_level * 9 + emp_light_size = power_level * 9 + emp_heavy_size = power_level * 7 if(rad_pulse) rad_pulse_size = (1 / (power_level + 7)) rad_pulse_strength = power_level * 9000 @@ -545,7 +550,8 @@ if(em_pulse) empulse( epicenter = loc, - severity = critical ? emp_severity * 2 : emp_severity, + heavy_range = critical ? emp_heavy_size * 2 : emp_heavy_size, + light_range = critical ? emp_light_size * 2 : emp_heavy_size, log = TRUE ) diff --git a/code/modules/atmospherics/machinery/portable/pump.dm b/code/modules/atmospherics/machinery/portable/pump.dm index e3a22c002df9..b2950139282a 100644 --- a/code/modules/atmospherics/machinery/portable/pump.dm +++ b/code/modules/atmospherics/machinery/portable/pump.dm @@ -62,9 +62,9 @@ if(. & EMP_PROTECT_SELF) return if(is_operational()) - if(prob(5 * severity)) + if(prob(50 / severity)) on = !on - if(prob(10 * severity)) + if(prob(100 / severity)) direction = PUMP_OUT pump.target_pressure = rand(0, 100 * ONE_ATMOSPHERE) update_appearance(UPDATE_ICON) diff --git a/code/modules/atmospherics/machinery/portable/scrubber.dm b/code/modules/atmospherics/machinery/portable/scrubber.dm index 9cb7373b07be..168942ac0483 100644 --- a/code/modules/atmospherics/machinery/portable/scrubber.dm +++ b/code/modules/atmospherics/machinery/portable/scrubber.dm @@ -64,7 +64,7 @@ if(. & EMP_PROTECT_SELF) return if(is_operational()) - if(prob(5 * severity)) + if(prob(50 / severity)) on = !on update_appearance(UPDATE_ICON) diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index 67b320c3b228..c26244226577 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -515,15 +515,17 @@ cloak_charge_rate = 20 cloak_dodge_loss = 40 var/cloak_emp_disable_duration = 10 SECONDS - var/cloak_emp_loss = 5 + var/cloak_emp_loss = 25 /obj/item/clothing/neck/cloak/ranger/syndie/emp_act(severity) . = ..() if(CHECK_BITFIELD(., EMP_PROTECT_SELF)) return - if(severity > EMP_LIGHT) + if(severity == EMP_HEAVY) + set_cloak(0) TIMER_COOLDOWN_START(src, "cloak_emp_disable", cloak_emp_disable_duration) - set_cloak(max(cloak - (cloak_emp_loss * severity), 0)) + else + set_cloak(cloak - cloak_emp_loss) /obj/item/clothing/neck/cloak/ranger/syndie/process(delta_time) if(TIMER_COOLDOWN_CHECK(src, "cloak_emp_disable")) diff --git a/code/modules/clothing/neck/bodycamera.dm b/code/modules/clothing/neck/bodycamera.dm index 21207b75cfd3..3cd85f30beb1 100644 --- a/code/modules/clothing/neck/bodycamera.dm +++ b/code/modules/clothing/neck/bodycamera.dm @@ -88,7 +88,7 @@ /obj/item/clothing/neck/bodycam/emp_act(severity) . = ..() - if(prob(15 * severity)) + if(prob(150/severity)) Disconnect() bodcam.c_tag = null bodcam.network[1] = null //requires a reset diff --git a/code/modules/clothing/spacesuits/chronosuit.dm b/code/modules/clothing/spacesuits/chronosuit.dm index 5477a25710cf..f6361de4d6b3 100644 --- a/code/modules/clothing/spacesuits/chronosuit.dm +++ b/code/modules/clothing/spacesuits/chronosuit.dm @@ -73,11 +73,13 @@ if(. & EMP_PROTECT_SELF) return var/mob/living/carbon/human/user = src.loc - if(severity > EMP_LIGHT && activated && user && ishuman(user) && (user.wear_suit == src)) - to_chat(user, span_danger("E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD")) - to_chat(user, span_userdanger("An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!")) - user.emote("scream") - deactivate(1, 1) + switch(severity) + if(1) + if(activated && user && ishuman(user) && (user.wear_suit == src)) + to_chat(user, span_danger("E:FATAL:RAM_READ_FAIL\nE:FATAL:STACK_EMPTY\nE:FATAL:READ_NULL_POINT\nE:FATAL:PWR_BUS_OVERLOAD")) + to_chat(user, span_userdanger("An electromagnetic pulse disrupts your [name] and violently tears you out of time-bluespace!")) + user.emote("scream") + deactivate(1, 1) /obj/item/clothing/suit/space/chronos/proc/finish_chronowalk(mob/living/carbon/human/user, turf/to_turf) if(!user) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index f0afd9d5e9f2..2975673406ea 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -144,7 +144,7 @@ /obj/item/clothing/head/helmet/space/hardsuit/emp_act(severity) . = ..() - display_visor_message("Electromagnetic pulse detected! Severity: [severity]") + display_visor_message("[severity > 1 ? "Light" : "Strong"] electromagnetic pulse detected!") /obj/item/clothing/suit/space/hardsuit diff --git a/code/modules/clothing/suits/reactive_armour.dm b/code/modules/clothing/suits/reactive_armour.dm index ededdcda111b..71dd701e00af 100644 --- a/code/modules/clothing/suits/reactive_armour.dm +++ b/code/modules/clothing/suits/reactive_armour.dm @@ -117,7 +117,7 @@ if(ismob(loc)) to_chat(loc, emp_message) bad_effect = TRUE - addtimer(VARSET_CALLBACK(src, bad_effect, FALSE), (3 SECONDS) * severity) + addtimer(VARSET_CALLBACK(src, bad_effect, FALSE), 30 SECONDS) //When the wearer gets hit, this armor will teleport the user a short distance away (to safety or to more danger, no one knows. That's the fun of it!) /obj/item/clothing/suit/armor/reactive/teleport diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index ad98033033bd..bbc06023fda4 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -13,7 +13,6 @@ volume = 100 force = 15 //Smashing bottles over someone's head hurts. throwforce = 15 - demolition_mod = 0.25 item_state = "broken_beer" //Generic held-item sprite until unique ones are made. lefthand_file = 'icons/mob/inhands/misc/food_lefthand.dmi' righthand_file = 'icons/mob/inhands/misc/food_righthand.dmi' @@ -167,7 +166,6 @@ throwforce = 5 throw_speed = 3 throw_range = 5 - demolition_mod = 0.25 w_class = WEIGHT_CLASS_TINY item_state = "beer" hitsound = 'sound/weapons/bladeslice.ogg' diff --git a/code/modules/mining/abandoned_crates.dm b/code/modules/mining/abandoned_crates.dm index 19c4ab3b310d..3239ce7904d4 100644 --- a/code/modules/mining/abandoned_crates.dm +++ b/code/modules/mining/abandoned_crates.dm @@ -84,14 +84,14 @@ new /obj/item/clothing/neck/petcollar(src) if(63 to 64) for(var/i in 1 to rand(4, 7)) - var/newcoin = pickweight(list( + var/newcoin = pickweight( /obj/item/coin/silver = 3, /obj/item/coin/iron = 3, /obj/item/coin/gold = 1, /obj/item/coin/diamond = 1, /obj/item/coin/plasma = 1, /obj/item/coin/uranium = 1, - )) + ) new newcoin(src) if(65 to 66) new /obj/item/clothing/suit/ianshirt(src) diff --git a/code/modules/mining/equipment/mining_tools.dm b/code/modules/mining/equipment/mining_tools.dm index d85dbb56f8e6..ca31e16e0e6d 100644 --- a/code/modules/mining/equipment/mining_tools.dm +++ b/code/modules/mining/equipment/mining_tools.dm @@ -7,7 +7,6 @@ slot_flags = ITEM_SLOT_BELT | ITEM_SLOT_BACK force = 15 throwforce = 10 - demolition_mod = 1.2 item_state = "pickaxe" lefthand_file = 'icons/mob/inhands/equipment/mining_lefthand.dmi' righthand_file = 'icons/mob/inhands/equipment/mining_righthand.dmi' diff --git a/code/modules/mining/equipment/wormhole_jaunter.dm b/code/modules/mining/equipment/wormhole_jaunter.dm index 27fd03403b30..b263c1696d50 100644 --- a/code/modules/mining/equipment/wormhole_jaunter.dm +++ b/code/modules/mining/equipment/wormhole_jaunter.dm @@ -52,7 +52,7 @@ playsound(src,'sound/effects/sparks4.ogg',50,1) qdel(src) -/obj/item/wormhole_jaunter/emp_act(severity) +/obj/item/wormhole_jaunter/emp_act(power) . = ..() if(. & EMP_PROTECT_SELF) return @@ -60,8 +60,11 @@ var/mob/M = loc if(istype(M)) var/triggered = FALSE - if(M.get_item_by_slot(ITEM_SLOT_BELT) == src && prob(10 * severity)) - triggered = TRUE + if(M.get_item_by_slot(ITEM_SLOT_BELT) == src) + if(power == 1) + triggered = TRUE + else if(power == 2 && prob(50)) + triggered = TRUE if(triggered) M.visible_message(span_warning("[src] overloads and activates!")) diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm index 7ceb3f3f93b4..1d0658084614 100644 --- a/code/modules/mob/living/brain/brain_item.dm +++ b/code/modules/mob/living/brain/brain_item.dm @@ -287,10 +287,15 @@ var/obj/item/clothing/head/hat = owner.get_item_by_slot(ITEM_SLOT_HEAD) if(hat && istype(hat, /obj/item/clothing/head/foilhat)) return - to_chat(owner, span_warning("Alert: Posibrain [severity > EMP_LIGHT ? "severely " : ""]damaged.")) - owner.adjust_drugginess(5 * severity) - if(severity > EMP_LIGHT) - owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (2 * (severity - EMP_LIGHT)) * (maxHealth - damage) / maxHealth) // don't give traumas from weak EMPs + + owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, (50/severity) * (maxHealth - damage) / maxHealth) + owner.adjust_drugginess(40/severity) + switch(severity) + if(1) + to_chat(owner, span_warning("Alert: Posibrain heavily damaged.")) + if(2) + to_chat(owner, span_warning("Alert: Posibrain damaged.")) + ////////////////////////////////////TRAUMAS//////////////////////////////////////// diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 81b3d0586b70..c21bcf7e6969 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -541,6 +541,10 @@ /mob/living/carbon/update_stamina() var/stam = getStaminaLoss() + if(ishuman(src)) + var/mob/living/carbon/human/H = src //leaving this here but sus + if(stam && H.hulk_stamina_check()) + return if(stam > DAMAGE_PRECISION && (maxHealth - stam) <= crit_threshold) if(!stat) enter_stamcrit() diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 638b7a82ba22..861582d06371 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -372,16 +372,13 @@ . = ..() if(. & EMP_PROTECT_SELF) return - - if(dna?.species) - severity *= dna.species.emp_mod - if(severity < 1) - return - - var/emp_message = TRUE - for(var/obj/item/bodypart/BP as anything in get_damageable_bodyparts(BODYPART_ROBOTIC)) - if(!(BP.emp_act(severity, emp_message) & EMP_PROTECT_SELF)) - emp_message = FALSE // if the EMP was successful, don't spam the chat with more messages + if(HAS_TRAIT(src, TRAIT_FARADAYCAGE)) + severity++ + if(severity > EMP_LIGHT) + return + for(var/X in internal_organs) + var/obj/item/organ/O = X + O.emp_act(severity) /mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE, gib = FALSE) if(tesla_shock && (flags_1 & TESLA_IGNORE_1)) @@ -486,6 +483,12 @@ adjust_status_effects_on_shake_up() // adjustStaminaLoss(-10) if you want hugs to recover stamina damage, uncomment this + if(dna && dna.check_mutation(ACTIVE_HULK)) + if(prob(30)) + adjustStaminaLoss(10) + to_chat(src, span_notice("[M] calms you down a little.")) + else + to_chat(src, span_warning("[M] tries to calm you!")) set_resting(FALSE) playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index c5508355451b..7f1dcd051b36 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -709,7 +709,7 @@ #undef CPR_PANIC_SPEED /mob/living/carbon/human/cuff_resist(obj/item/I) - if(dna && (dna.check_mutation(HULK))) + if(dna && (dna.check_mutation(HULK) || dna.check_mutation(ACTIVE_HULK))) say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") if(..(I, cuff_break = FAST_CUFFBREAK)) dropItemToGround(I) @@ -1129,8 +1129,12 @@ remove_movespeed_modifier(MOVESPEED_ID_CRAWL_MODIFIER, TRUE) /mob/living/carbon/human/updatehealth() + var/oldhealth = health . = ..() dna?.species.spec_updatehealth(src) + if(!dna) + return + hulk_health_check(oldhealth) /mob/living/carbon/human/adjust_nutrition(change) //Honestly FUCK the oldcoders for putting nutrition on /mob someone else can move it up because holy hell I'd have to fix SO many typechecks if(HAS_TRAIT(src, TRAIT_NOHUNGER)) @@ -1391,3 +1395,36 @@ /mob/living/carbon/human/species/zombie/krokodil_addict race = /datum/species/krokodil_addict + +/mob/living/carbon/human/proc/hulk_health_check(oldhealth) + if(!dna) + return + + if(dna.check_mutation(ACTIVE_HULK)) + if(health < HEALTH_THRESHOLD_CRIT) + dna.remove_mutation(ACTIVE_HULK) + return + if(health < oldhealth) + adjustStaminaLoss(-1.5 * (oldhealth - health)) + else + if(!dna.check_mutation(HULK) && dna.check_mutation(GENETICS_HULK) && stat == CONSCIOUS && (oldhealth >= health + 10 || health < (0.5 * maxHealth))) + dna.add_mutation(ACTIVE_HULK) + +/mob/living/carbon/human/proc/hulk_stamina_check() + if(dna.check_mutation(ACTIVE_HULK)) + if(staminaloss < 60 && prob(1)) + adjust_confusion(7 SECONDS) + say("HULK SMASH!!") + if(staminaloss >= 90) + dna.remove_mutation(ACTIVE_HULK) + to_chat(src, span_notice("You have calm down enough to become human again.")) + Knockdown(6) + return TRUE + else + return FALSE + +/mob/living/carbon/human/Bump(atom/movable/AM) + ..() + if(dna.check_mutation(ACTIVE_HULK) && has_status_effect(/datum/status_effect/confusion) && (world.time - last_bumped) > 15) + Bumped(AM) + return AM.attack_hulk(src) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 109d8c965641..d3259e769e01 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -64,7 +64,7 @@ if(mind) if(mind.martial_art && !incapacitated(FALSE, TRUE) && mind.martial_art.can_use(src) && (mind.martial_art.deflection_chance || ((mind.martial_art.id == "sleeping carp") && in_throw_mode))) //Some martial arts users can deflect projectiles! if(prob(mind.martial_art.deflection_chance) || ((mind.martial_art.id == "sleeping carp") && in_throw_mode)) // special check if sleeping carp is our martial art and throwmode is on, deflect - if((mobility_flags & MOBILITY_USE) && dna && !dna.check_mutation(HULK)) //But only if they're otherwise able to use items, and hulks can't do it + if((mobility_flags & MOBILITY_USE) && dna && !(dna.check_mutation(HULK)|| dna.check_mutation(ACTIVE_HULK))) //But only if they're otherwise able to use items, and hulks can't do it if(!isturf(loc)) //if we're inside something and still got hit P.force_hit = TRUE //The thing we're in passed the bullet to us. Pass it back, and tell it to take the damage. loc.bullet_act(P) @@ -547,8 +547,32 @@ return dna.species.spec_emag_act(src, user, emag_card) /mob/living/carbon/human/emp_act(severity) - severity *= physiology.emp_mod - return ..(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(HAS_TRAIT(src, TRAIT_FARADAYCAGE)) + severity++ + if(severity > EMP_LIGHT) + return + dna?.species.spec_emp_act(src, severity) + var/list/affected_parts = list() + for(var/obj/item/bodypart/BP in bodyparts) + if(istype(BP) && BP.status == BODYPART_ROBOTIC) + if(prob(5) && severity == EMP_HEAVY && (TRAIT_EASYDISMEMBER in dna?.species.inherent_traits) && BP.body_zone != BODY_ZONE_CHEST) + BP.dismember() + else + affected_parts += BP + if(affected_parts.len) + emote("scream") + adjustFireLoss(min(5 * affected_parts.len / severity, 20 / severity), FALSE, FALSE, BODYPART_ROBOTIC) + var/obj/item/bodypart/chest/C = get_bodypart(BODY_ZONE_CHEST) + var/obj/item/bodypart/head/H = get_bodypart(BODY_ZONE_HEAD) + if(((C && C.status == BODYPART_ROBOTIC) || (H && H.status == BODYPART_ROBOTIC)) && severity == EMP_HEAVY) // if your head and/or chest are robotic (aka you're a robotic race or augmented) you get cooler flavor text and rapid-onset paralysis + to_chat(src, span_userdanger("A surge of searing pain erupts throughout your very being! As the pain subsides, a terrible sensation of emptiness is left in its wake.")) + Paralyze(5 SECONDS) //heavy EMPs will fully stun you + else + adjustStaminaLoss(min(15 * affected_parts.len / severity, 60 / severity), FALSE, FALSE, BODYPART_ROBOTIC) + to_chat(src, span_userdanger("You feel a sharp pain as your robotic limbs overload.")) /mob/living/carbon/human/rad_act(amount, collectable_radiation) . = ..() diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm index 8d81a51a33d3..196d5c953109 100644 --- a/code/modules/mob/living/carbon/human/human_helpers.dm +++ b/code/modules/mob/living/carbon/human/human_helpers.dm @@ -142,7 +142,7 @@ . = ..() if(G.trigger_guard == TRIGGER_GUARD_NORMAL) - if(src.dna.check_mutation(HULK)) + if(src.dna.check_mutation(HULK) || src.dna.check_mutation(ACTIVE_HULK)) to_chat(src, span_warning("Your meaty finger is much too large for the trigger guard!")) return FALSE if(HAS_TRAIT(src, TRAIT_NOGUNS)) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index d22f8a1f36d9..4ef4c703a43e 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -107,7 +107,7 @@ if(!dna) return - if(prob(3) && dna.check_mutation(HULK)) + if(prob(3) && dna.check_mutation(ACTIVE_HULK)) say(pick_list_replacements(BRAIN_DAMAGE_FILE, "hulk")) /mob/living/carbon/human/handle_mutations_and_radiation() diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm index 36982d89d352..50f31d0fcd3a 100644 --- a/code/modules/mob/living/carbon/human/physiology.dm +++ b/code/modules/mob/living/carbon/human/physiology.dm @@ -17,7 +17,6 @@ var/damage_resistance = 0 // %damage reduction from all sources var/siemens_coeff = 1 // resistance to shocks - var/emp_mod = 1 // resistance to EMPs var/stun_mod = 1 // % stun modifier var/bleed_mod = 1 // % bleeding modifier diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 813a5a2ce20b..cfcac78caceb 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -97,8 +97,6 @@ GLOBAL_LIST_EMPTY(features_by_species) var/staminamod = 1 /// multiplier for pressure damage var/pressuremod = 1 - /// multiplier for EMP severity - var/emp_mod = 1 /// multiplier for money paid at payday, species dependent var/payday_modifier = 1 ///Type of damage attack does @@ -1037,7 +1035,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(!forced_colour) switch(S.color_src) if(MUTCOLORS) - if(H.dna.check_mutation(HULK)) //HULK GO FIRST + if(H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK)) //HULK GO FIRST accessory_overlay.color = "#00aa00" else if(fixed_mut_color) //Then fixed color if applicable accessory_overlay.color = fixed_mut_color @@ -1765,7 +1763,7 @@ GLOBAL_LIST_EMPTY(features_by_species) if(M.mind) attacker_style = M.mind.martial_art if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) - if(M.dna.check_mutation(HULK) && M.a_intent == "disarm") + if((M.dna.check_mutation(ACTIVE_HULK) || M.dna.check_mutation(HULK)) && M.a_intent == "disarm") H.check_shields(0, M.name) // We check their shields twice since we are a hulk. Also triggers hitreactions for HULK_ATTACK M.visible_message(span_danger("[M]'s punch knocks the shield out of [H]'s hand."), \ span_userdanger("[M]'s punch knocks the shield out of [H]'s hand.")) @@ -2579,22 +2577,6 @@ GLOBAL_LIST_EMPTY(features_by_species) SPECIES_PERK_DESC = "[plural_form] are resilient to being shocked.", )) - if(emp_mod > 1) - to_add += list(list( - SPECIES_PERK_TYPE = SPECIES_NEGATIVE_PERK, - SPECIES_PERK_ICON = "thunderstorm", - SPECIES_PERK_NAME = "EM Weakness", - SPECIES_PERK_DESC = "[plural_form] are weak to electromagnetic interference.", - )) - - if(emp_mod < 1) - to_add += list(list( - SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, - SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash - SPECIES_PERK_NAME = "EM Resistance", - SPECIES_PERK_DESC = "[plural_form] are resistant to electromagnetic interference.", - )) - return to_add /** @@ -2693,6 +2675,15 @@ GLOBAL_LIST_EMPTY(features_by_species) SPECIES_PERK_NAME = "Radiation Immunity", SPECIES_PERK_DESC = "[plural_form] are completely unaffected by radiation. However, this doesn't mean they can't be irradiated.", )) + + if(TRAIT_FARADAYCAGE in inherent_traits) + to_add += list(list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash + SPECIES_PERK_NAME = "Faraday \"Skin\"", + SPECIES_PERK_DESC = "[plural_form] have a unique physiology that shields them from weak EMPs.", + )) + if(TRAIT_LIMBATTACHMENT in inherent_traits) to_add += list(list( SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, diff --git a/code/modules/mob/living/carbon/human/species_types/ethereal.dm b/code/modules/mob/living/carbon/human/species_types/ethereal.dm index 890dac7e8108..341a4ca9ab97 100644 --- a/code/modules/mob/living/carbon/human/species_types/ethereal.dm +++ b/code/modules/mob/living/carbon/human/species_types/ethereal.dm @@ -133,7 +133,7 @@ to_chat(H, span_notice("You feel the light of your body leave you.")) EMPeffect = TRUE spec_updatehealth(H) - addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 20 * severity, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 2 to 20 seconds depending on severity + addtimer(CALLBACK(src, PROC_REF(stop_emp), H), 200 / severity, TIMER_UNIQUE|TIMER_OVERRIDE) //We're out for 10 to 20 seconds depending on severity /datum/species/ethereal/proc/stop_emp(mob/living/carbon/human/H) EMPeffect = FALSE diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 15c1da734fbe..64a179f88e09 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -631,7 +631,7 @@ generate/load female uniform sprites matching all previously decided variables /mob/living/carbon/human/generate_icon_render_key() . = "[dna.species.limbs_id]" - if(dna.check_mutation(HULK)) + if(dna.check_mutation(HULK) || dna.check_mutation(ACTIVE_HULK)) . += "-coloured-hulk" else if(dna.species.use_skintones) . += "-coloured-[skin_tone]" diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 7e860d1e31af..0d36713e6a8b 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -338,7 +338,7 @@ /mob/living/carbon/proc/handle_bodyparts() var/stam_regen = FALSE - if(stam_regen_start_time <= world.time) + if(stam_regen_start_time <= world.time && (has_dna() && !dna.check_mutation(ACTIVE_HULK))) stam_regen = TRUE if(HAS_TRAIT_FROM(src, TRAIT_INCAPACITATED, STAMINA)) . |= BODYPART_LIFE_UPDATE_HEALTH //make sure we remove the stamcrit diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm index 09bb968cd43c..b8be2fda95af 100644 --- a/code/modules/mob/living/silicon/pai/pai_defense.dm +++ b/code/modules/mob/living/silicon/pai/pai_defense.dm @@ -6,16 +6,16 @@ . = ..() if(. & EMP_PROTECT_SELF) return - take_holo_damage(5 * severity) - Paralyze(40 * severity) - silent = max(3 * severity, silent) + take_holo_damage(50/severity) + Paralyze(400/severity) + silent = max(30/severity, silent) if(holoform) fold_in(force = TRUE) //Need more effects that aren't instadeath or permanent law corruption. //Ask and you shall receive switch(rand(1, 3)) if(1) - adjust_stutter((6 * severity) SECONDS) + adjust_stutter(1 MINUTES / severity) to_chat(src, span_danger("Warning: Feedback loop detected in speech module.")) if(2) adjust_slurring(INFINITY) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 01047137f1a1..80e710a1518e 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -80,7 +80,11 @@ . = ..() if(. & EMP_PROTECT_SELF) return - Stun(min((1.6 SECONDS) * severity, 16 SECONDS)) // up to 16 seconds + switch(severity) + if(1) + Stun(160) + if(2) + Stun(60) /mob/living/silicon/robot/emag_act(mob/user, obj/item/card/emag/emag_card) diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 63f34ab86dbb..a2743cbf2527 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -528,17 +528,16 @@ return clamp(damage_amount * (1 - armor_protection/100), 1, damage_amount) // Minimum of 1 damage. /// Copy of '/mob/living/attacked_by', except it sets damage to what is returned by 'proc/run_armor'. -/mob/living/silicon/attacked_by(obj/item/attacking_item, mob/living/user) - send_item_attack_message(attacking_item, user) - if(!attacking_item.force) - return FALSE - // Demolition mod has half the effect on silicons that it does on structures (ex. 2x will act as 1.5x, 0.5x will act as 0.75x) - var/damage = run_armor(attacking_item.force * (1 + attacking_item.demolition_mod)/2, attacking_item.damtype, MELEE) - apply_damage(damage, attacking_item.damtype) - if(attacking_item.damtype == BRUTE && prob(33)) - attacking_item.add_mob_blood(src) - var/turf/location = get_turf(src) - add_splatter_floor(location) - if(get_dist(user, src) <= 1) - user.add_mob_blood(src) - return TRUE +/mob/living/silicon/attacked_by(obj/item/I, mob/living/user) + send_item_attack_message(I, user) + if(I.force) + var/damage = run_armor(I.force, I.damtype, MELEE) + apply_damage(damage, I.damtype) + if(I.damtype == BRUTE) + if(prob(33)) + I.add_mob_blood(src) + var/turf/location = get_turf(src) + add_splatter_floor(location) + if(get_dist(user, src) <= 1) + user.add_mob_blood(src) + return TRUE diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 9cd6b66aed53..3942d298949d 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -109,10 +109,14 @@ to_chat(src, span_danger("Warning: Electromagnetic pulse detected.")) if(. & EMP_PROTECT_SELF) return - take_bodypart_damage(2 * severity) + switch(severity) + if(1) + src.take_bodypart_damage(20) + if(2) + src.take_bodypart_damage(10) to_chat(src, span_userdanger("*BZZZT*")) for(var/mob/living/M in buckled_mobs) - if(prob(5 * severity)) + if(prob(severity*50)) unbuckle_mob(M) M.Paralyze(40) M.visible_message(span_boldwarning("[M] is thrown off of [src]!")) @@ -121,7 +125,7 @@ /mob/living/silicon/bullet_act(obj/projectile/Proj, def_zone) SEND_SIGNAL(src, COMSIG_ATOM_BULLET_ACT, Proj, def_zone) if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - var/damage = run_armor(Proj.damage * (1 + Proj.demolition_mod)/2, Proj.damage_type, Proj.armor_flag, Proj.armour_penetration) + var/damage = run_armor(Proj.damage, Proj.damage_type, Proj.armor_flag, Proj.armour_penetration) adjustBruteLoss(damage) if(prob(damage*1.5)) for(var/mob/living/M in buckled_mobs) diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index bf7a61cc67bb..a6c8a8f93f74 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -364,7 +364,7 @@ ejectpai(0) if(on) turn_off() - spawn(30 * severity) + spawn(severity*300) stat &= ~EMPED if(was_on) turn_on() diff --git a/code/modules/mob/living/simple_animal/bot/ed209bot.dm b/code/modules/mob/living/simple_animal/bot/ed209bot.dm index 39cf352be45c..c1fd265adb0f 100644 --- a/code/modules/mob/living/simple_animal/bot/ed209bot.dm +++ b/code/modules/mob/living/simple_animal/bot/ed209bot.dm @@ -459,10 +459,12 @@ Auto Patrol[]"}, /mob/living/simple_animal/bot/ed209/emp_act(severity) + if(severity == 2 && prob(70)) + severity = 1 . = ..() if(. & EMP_PROTECT_SELF) return - if (severity > EMP_LIGHT || prob(70)) + if (severity >= 2) new /obj/effect/temp_visual/emp(loc) var/list/mob/living/carbon/targets = new for(var/mob/living/carbon/C in view(12,src)) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 3b23f070f3ac..5dcaab702f96 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -231,9 +231,9 @@ . = ..() if(. & EMP_PROTECT_SELF) return - Stun(10 * severity) + Stun(100) to_chat(src, span_danger("ER@%R: MME^RY CO#RU9T! R&$b@0tin)...")) - if(severity > EMP_LIGHT) + if(severity == 1) adjustBruteLoss(heavy_emp_damage) to_chat(src, span_userdanger("HeAV% DA%^MMA+G TO I/O CIR!%UUT!")) diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm index b14cf101e7ab..3d77ac911cbb 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_empulse.dm @@ -6,5 +6,5 @@ if(!ninjacost(250,N_STEALTH_CANCEL)) var/mob/living/carbon/human/H = affecting playsound(H.loc, 'sound/effects/empulse.ogg', 60, 2) - empulse(H, EMP_HEAVY, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. + empulse(H, 4, 6) //Procs sure are nice. Slightly weaker than wizard's disable tch. s_coold = 4 diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm index 5b25b248cab8..27bb868f2371 100644 --- a/code/modules/photography/camera/camera.dm +++ b/code/modules/photography/camera/camera.dm @@ -154,7 +154,7 @@ if(on) // EMP will only work on cameras that are on as it has power going through it icon_state = state_off on = FALSE - addtimer(CALLBACK(src, PROC_REF(emp_after)), (6*severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(emp_after)), (600/severity)) /obj/item/camera/proc/emp_after() on = TRUE diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 215bfb7fab95..e2fcb0d0fea9 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1466,7 +1466,7 @@ environ = 0 update_appearance(UPDATE_ICON) update() - addtimer(CALLBACK(src, PROC_REF(reset), APC_RESET_EMP), (6 * severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(reset), APC_RESET_EMP), 600) /obj/machinery/power/apc/blob_act(obj/structure/blob/B) set_broken() diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index d042bbba6020..6ca8fac3e3e7 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -179,7 +179,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - charge -= max((charge * severity / 100), 50 * severity) + charge -= max((charge * 0.1), 500) / severity if (charge < 0) charge = 0 @@ -392,7 +392,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - charge = clamp((charge-(1000 * severity)),0,maxcharge) + charge = clamp((charge-(10000/severity)),0,maxcharge) /obj/item/stock_parts/cell/emergency_light name = "miniature power cell" diff --git a/code/modules/power/singularity/singularity.dm b/code/modules/power/singularity/singularity.dm index 89cebd706384..cb1d0a12590a 100644 --- a/code/modules/power/singularity/singularity.dm +++ b/code/modules/power/singularity/singularity.dm @@ -583,7 +583,7 @@ /obj/singularity/proc/emp_area() - empulse(src, EMP_HEAVY) + empulse(src, 8, 10) return /obj/singularity/singularity_act() diff --git a/code/modules/power/smes.dm b/code/modules/power/smes.dm index c17a460347bb..ba8c60ddc4ee 100644 --- a/code/modules/power/smes.dm +++ b/code/modules/power/smes.dm @@ -417,7 +417,7 @@ outputting = output_attempt output_level = rand(0, output_level_max) input_level = rand(0, input_level_max) - charge = max(charge - (1e5 * severity), 0) + charge = max(charge - 1e6/severity, 0) update_appearance(UPDATE_ICON) log_smes() diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 93e02b451c90..a9102c23adbf 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -758,7 +758,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) radiation_pulse(src, (100-support_integrity)*2, 4) if(support_integrity<3) var/emp_power = round(explosion_power * (1+(1-(support_integrity/3))),1) - empulse(src, emp_power) + empulse(src, emp_power, emp_power*2) if(support_integrity<100) power += round((100-support_integrity)/2,1) if(support_integrity<70) @@ -779,7 +779,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) if(istype(T, /turf/open/space) || T.return_air().total_moles() < MOLE_SPACE_THRESHOLD) damage += DAMAGE_HARDCAP * explosion_point //Can't cheat by spacing the crystal to buy time, it will just delaminate faster if(prob(2)) - empulse(src, 10-support_integrity) //EMPs must always be spewing every so often to ensure that containment is guaranteed to fail. + empulse(src, 10-support_integrity, (10-support_integrity)*2) //EMPs must always be spewing every so often to ensure that containment is guaranteed to fail. return 1 /obj/machinery/power/supermatter_crystal/bullet_act(obj/projectile/Proj) @@ -1004,7 +1004,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal) to_chat(user, "You attach the antinoblium shard to the [src], moving your hand away before a sudden gravitational wave pulls the [W] into the crystal as it flashes to ash!") playsound(get_turf(src), 'sound/effects/supermatter.ogg', 50, 1) radiation_pulse(src, 150, 4) - empulse(src, EMP_HEAVY, 6) + empulse(src, 3,6) qdel(W) return else if(user.dropItemToGround(W)) diff --git a/code/modules/projectiles/ammunition/ballistic/shotgun.dm b/code/modules/projectiles/ammunition/ballistic/shotgun.dm index 10339f83fce3..5f4be6d2453d 100644 --- a/code/modules/projectiles/ammunition/ballistic/shotgun.dm +++ b/code/modules/projectiles/ammunition/ballistic/shotgun.dm @@ -231,10 +231,10 @@ /obj/item/ammo_casing/shotgun/hardlight/emp_act(severity) if (. & EMP_PROTECT_SELF) return - variance = initial(variance) + severity*4 // yikes - if(severity > EMP_LIGHT) - pellets = initial(pellets) * (0.5**(severity / EMP_HEAVY)) // also yikes - addtimer(CALLBACK(src, PROC_REF(remove_emp)), severity SECONDS, TIMER_OVERRIDE|TIMER_UNIQUE) + variance = 60 // yikes + if(severity == EMP_HEAVY) + pellets = 3 // also yikes + addtimer(CALLBACK(src, PROC_REF(remove_emp)), 10 SECONDS / severity, TIMER_OVERRIDE|TIMER_UNIQUE) /obj/item/ammo_casing/shotgun/hardlight/proc/remove_emp() variance = initial(variance) diff --git a/code/modules/projectiles/ammunition/energy/special.dm b/code/modules/projectiles/ammunition/energy/special.dm index 0aadae394955..6ff05a4c1616 100644 --- a/code/modules/projectiles/ammunition/energy/special.dm +++ b/code/modules/projectiles/ammunition/energy/special.dm @@ -4,7 +4,7 @@ fire_sound = 'sound/weapons/ionrifle.ogg' /obj/item/ammo_casing/energy/ion/hos - projectile_type = /obj/projectile/ion/weak + projectile_type = /obj/projectile/ion/light e_cost = 200 /obj/item/ammo_casing/energy/ion/weak diff --git a/code/modules/projectiles/ammunition/reusable/arrow.dm b/code/modules/projectiles/ammunition/reusable/arrow.dm index c367fdcfbac6..933c10d0511a 100644 --- a/code/modules/projectiles/ammunition/reusable/arrow.dm +++ b/code/modules/projectiles/ammunition/reusable/arrow.dm @@ -464,23 +464,23 @@ if(/obj/item/singularity_shard/stage2) break_chance = 0.5 rads_released = 200 - empulse(src, 1) + empulse(src, 0, 1) if(/obj/item/singularity_shard/stage3) break_chance = 1.5 rads_released = 500 - empulse(src, 3) + empulse(src, 0, 3) if(/obj/item/singularity_shard/stage4) break_chance = 5 rads_released = 1000 - empulse(src, 5) + empulse(src, 1, 5) if(/obj/item/singularity_shard/stage5) break_chance = 10 rads_released = 2000 - empulse(src, 7) + empulse(src, 2, 7) if(/obj/item/singularity_shard/stage6) break_chance = 100 rads_released = 3000 - empulse(src, 15) // Its going to break open into a singulo anyways, may as well add some fireworks + empulse(src, 5, 15) // Its going to break open into a singulo anyways, may as well add some fireworks // Handles releasing rads if(rads_released) diff --git a/code/modules/projectiles/boxes_magazines/external/rechargable.dm b/code/modules/projectiles/boxes_magazines/external/rechargable.dm index 7556ca1c68a3..c9a5c0dea3f1 100644 --- a/code/modules/projectiles/boxes_magazines/external/rechargable.dm +++ b/code/modules/projectiles/boxes_magazines/external/rechargable.dm @@ -102,7 +102,7 @@ . = ..() if(!(. & EMP_PROTECT_CONTENTS)) var/bullet_count = ammo_count() - var/bullets_to_remove = round(bullet_count * (0.5**(severity/EMP_HEAVY))) + var/bullets_to_remove = round(bullet_count / (severity*2)) for(var/i = 0; i < bullets_to_remove, i++) qdel(get_round()) update_appearance(UPDATE_ICON) @@ -111,8 +111,8 @@ if(!G.magazine == src) return G.semicd = TRUE - // up to 10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears - var/unjam_time = (min(severity, EMP_HEAVY) + (rand(-20,20)*0.01)) SECONDS + // 5-10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears + var/unjam_time = ((10/severity) + (rand(-20,20)*0.01)) SECONDS addtimer(CALLBACK(G, TYPE_PROC_REF(/obj/item/gun, reset_semicd)), unjam_time) /obj/item/ammo_casing/caseless/c22hl diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index 7d2e06ec1d04..d6a14d12ec03 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -36,11 +36,11 @@ /obj/item/gun/energy/emp_act(severity) . = ..() if(!(. & EMP_PROTECT_CONTENTS)) - cell.use(round(cell.charge * (0.5**(severity/EMP_HEAVY)))) + cell.use(round(cell.charge / (severity*2))) emp_jammed = TRUE deltimer(emp_jam_timer) - // up to 10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears - var/unjam_time = (min(severity, EMP_HEAVY) + (rand(-20,20)*0.01)) SECONDS + // 5-10 seconds depending on severity, then give or take 0.2 seconds to prevent piercing ears + var/unjam_time = ((10/severity) + (rand(-20,20)*0.01)) SECONDS emp_jam_timer = addtimer(CALLBACK(src, PROC_REF(emp_unjam)), unjam_time, TIMER_STOPPABLE) chambered = null //we empty the chamber recharge_newshot() //and try to charge a new shot diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm index d6dadf6ccf50..477fbd5520ce 100644 --- a/code/modules/projectiles/guns/misc/beam_rifle.dm +++ b/code/modules/projectiles/guns/misc/beam_rifle.dm @@ -425,7 +425,6 @@ armor_flag = ENERGY range = 150 jitter = 10 - demolition_mod = 4 var/obj/item/gun/gun var/structure_pierce_amount = 0 //All set to 0 so the gun can manually set them during firing. var/structure_bleed_coeff = 0 diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm index ebef6ac497c6..4056f1421fe0 100644 --- a/code/modules/projectiles/projectile/beams.dm +++ b/code/modules/projectiles/projectile/beams.dm @@ -153,7 +153,6 @@ damage = 30 wound_bonus = -40 bare_wound_bonus = 70 - demolition_mod = 3 // industrial laser impact_effect_type = /obj/effect/temp_visual/impact_effect/green_laser light_color = LIGHT_COLOR_GREEN diff --git a/code/modules/projectiles/projectile/bullets/_incendiary.dm b/code/modules/projectiles/projectile/bullets/_incendiary.dm index 1a6ed1323113..cb61ee5b7bb0 100644 --- a/code/modules/projectiles/projectile/bullets/_incendiary.dm +++ b/code/modules/projectiles/projectile/bullets/_incendiary.dm @@ -1,7 +1,6 @@ /obj/projectile/bullet/incendiary damage = 20 var/fire_stacks = 4 - demolition_mod = 0.75 /obj/projectile/bullet/incendiary/on_hit(atom/target, blocked = FALSE) . = ..() diff --git a/code/modules/projectiles/projectile/bullets/pistol.dm b/code/modules/projectiles/projectile/bullets/pistol.dm index e9383f89b2dc..b67fe3a84c43 100644 --- a/code/modules/projectiles/projectile/bullets/pistol.dm +++ b/code/modules/projectiles/projectile/bullets/pistol.dm @@ -64,7 +64,7 @@ /obj/projectile/bullet/c10mm/emp/on_hit(atom/target, blocked = FALSE) ..() - empulse(target, EMP_HEAVY, 1) //Heavy EMP on target, light EMP in tiles around + empulse(target, 0.5, 1) //Heavy EMP on target, light EMP in tiles around /obj/projectile/bullet/boltpistol name = "Bolt round" diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index c476a18556f8..d2f1edeec1bd 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -44,7 +44,6 @@ damage = 60 wound_bonus = -35 wound_falloff_tile = 0 - demolition_mod = 1.2 /obj/projectile/bullet/a762/raze name = "7.62mm Raze bullet" @@ -64,7 +63,6 @@ penetrating = TRUE //Passes through two objects, stops on a mob or on a third object penetrations = 2 penetration_type = 1 - demolition_mod = 1.5 // anti-armor /obj/projectile/bullet/a762/vulcan name = "7.62mm Vulcan bullet" diff --git a/code/modules/projectiles/projectile/bullets/shotgun.dm b/code/modules/projectiles/projectile/bullets/shotgun.dm index fbec1b20f8bc..79acfac73304 100644 --- a/code/modules/projectiles/projectile/bullets/shotgun.dm +++ b/code/modules/projectiles/projectile/bullets/shotgun.dm @@ -6,7 +6,6 @@ damage = 46 //About 2/3's the damage of buckshot but doesn't suffer from spread or negative AP sharpness = SHARP_POINTY wound_bonus = -30 - demolition_mod = 2 // good at smashing through stuff /obj/projectile/bullet/shotgun/slug/syndie name = "12g syndicate shotgun slug" @@ -75,7 +74,6 @@ damage = 35 //Most certainly to drop below 3-shot threshold because of damage falloff armour_penetration = 60 // he he funny round go through armor wound_bonus = -40 - demolition_mod = 3 // very good at smashing through stuff penetrating = TRUE //Goes through an infinite number of mobs /obj/projectile/bullet/shotgun/slug/Range() @@ -90,7 +88,6 @@ var/tile_dropoff = 0.4 var/tile_dropoff_s = 0.3 armour_penetration = -20 //Armor is 25% stronger against pellets - demolition_mod = 0.5 // bad at smashing through stuff /obj/projectile/bullet/pellet/shotgun_buckshot name = "buckshot pellet" @@ -203,11 +200,10 @@ desc = "A breaching round designed to destroy airlocks and windows with only a few shots, but is ineffective against other targets." hitsound = 'sound/weapons/sonic_jackhammer.ogg' damage = 10 //does shit damage to everything except doors and windows - demolition_mod = 6 //not that bad at breaking things /obj/projectile/bullet/shotgun/slug/breaching/on_hit(atom/target) - if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly) || istype(target, /obj/structure/grille)) - demolition_mod = 50 //one shot to break a window or 3 shots to breach an airlock door + if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly)) + damage = 500 //one shot to break a window or 3 shots to breach an airlock door ..() /obj/projectile/bullet/pellet/hardlight diff --git a/code/modules/projectiles/projectile/bullets/sniper.dm b/code/modules/projectiles/projectile/bullets/sniper.dm index 262bec69a77f..a845ad1bb599 100644 --- a/code/modules/projectiles/projectile/bullets/sniper.dm +++ b/code/modules/projectiles/projectile/bullets/sniper.dm @@ -7,7 +7,13 @@ paralyze = 100 dismemberment = 50 armour_penetration = 50 - demolition_mod = 2.2 // very effective against armored structures and vehicles + var/breakthings = TRUE + +/obj/projectile/bullet/p50/on_hit(atom/target, blocked = 0) + if(isobj(target) && (blocked != 100) && breakthings) + var/obj/O = target + O.take_damage(80, BRUTE, BULLET, FALSE, null, armour_penetration) + return ..() /obj/projectile/bullet/p50/soporific name = ".50 soporific bullet" @@ -15,6 +21,7 @@ damage = 0 dismemberment = 0 paralyze = 0 + breakthings = FALSE /obj/projectile/bullet/p50/soporific/on_hit(atom/target, blocked = FALSE) if((blocked != 100) && isliving(target)) diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm index 00961f96658f..2a3d794ef06b 100644 --- a/code/modules/projectiles/projectile/energy/stun.dm +++ b/code/modules/projectiles/projectile/energy/stun.dm @@ -20,7 +20,7 @@ var/mob/living/carbon/C = target SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased) SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK) - if(C.dna && (C.dna.check_mutation(HULK))) + if(C.dna && (C.dna.check_mutation(HULK) || C.dna.check_mutation(ACTIVE_HULK))) C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), jitter), 5) diff --git a/code/modules/projectiles/projectile/magic.dm b/code/modules/projectiles/projectile/magic.dm index 0f4a9cd6d130..5b2cb0c7b0de 100644 --- a/code/modules/projectiles/projectile/magic.dm +++ b/code/modules/projectiles/projectile/magic.dm @@ -1102,10 +1102,10 @@ nodamage = TRUE armor_flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/ion - var/ion_severity = EMP_HEAVY //Heavy EMP effect that doesn't spread to adjacent tiles - var/ion_range = 3 + var/light_emp_radius = 3 + var/heavy_emp_radius = 0.5 //Effectively 1 but doesnt spread to adjacent tiles /obj/projectile/magic/ion/on_hit(atom/target, blocked = FALSE) ..() - empulse(target, ion_severity, ion_range) + empulse(target, heavy_emp_radius, light_emp_radius) return BULLET_ACT_HIT diff --git a/code/modules/projectiles/projectile/reusable/arrow.dm b/code/modules/projectiles/projectile/reusable/arrow.dm index 6b615926d848..dd6dcbfdfb67 100644 --- a/code/modules/projectiles/projectile/reusable/arrow.dm +++ b/code/modules/projectiles/projectile/reusable/arrow.dm @@ -289,7 +289,7 @@ var/mob/living/carbon/C = target SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "tased", /datum/mood_event/tased) SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK) - if(C.dna && (C.dna.check_mutation(HULK))) + if(C.dna && (C.dna.check_mutation(HULK) || C.dna.check_mutation(ACTIVE_HULK))) C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(C, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), jitter), 5) diff --git a/code/modules/projectiles/projectile/special/hallucination.dm b/code/modules/projectiles/projectile/special/hallucination.dm index b2de093296c7..6c3538abcff4 100644 --- a/code/modules/projectiles/projectile/special/hallucination.dm +++ b/code/modules/projectiles/projectile/special/hallucination.dm @@ -168,7 +168,7 @@ /obj/projectile/hallucination/taser/hal_apply_effect() hal_target.Paralyze(100) hal_target.adjust_stutter(2 SECONDS) - if(hal_target.dna && (hal_target.dna.check_mutation(HULK))) + if(hal_target.dna && (hal_target.dna.check_mutation(HULK)|| hal_target.dna.check_mutation(ACTIVE_HULK))) hal_target.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk") else if((hal_target.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(hal_target, TRAIT_STUNIMMUNE)) addtimer(CALLBACK(hal_target, TYPE_PROC_REF(/mob/living/carbon, do_jitter_animation), 20), 0.5 SECONDS) diff --git a/code/modules/projectiles/projectile/special/ion.dm b/code/modules/projectiles/projectile/special/ion.dm index 82675908b7cd..4de29713c471 100644 --- a/code/modules/projectiles/projectile/special/ion.dm +++ b/code/modules/projectiles/projectile/special/ion.dm @@ -6,18 +6,22 @@ nodamage = TRUE armor_flag = ENERGY impact_effect_type = /obj/effect/temp_visual/impact_effect/ion - var/ion_severity = EMP_HEAVY // Heavy EMP effects that don't spread to adjacent tiles - var/ion_range = 1 + var/light_emp_radius = 1 + var/heavy_emp_radius = 0.5 //Effectively 1 but doesnt spread to adjacent tiles /obj/projectile/ion/on_hit(atom/target, blocked = FALSE) ..() - empulse(target, ion_severity, ion_range) + empulse(target, heavy_emp_radius, light_emp_radius) return BULLET_ACT_HIT /obj/projectile/ion/weak - ion_severity = EMP_LIGHT // weak ions - ion_range = 0 + light_emp_radius = 0 + heavy_emp_radius = 0 + +/obj/projectile/ion/light + light_emp_radius = 1 + heavy_emp_radius = 0 /obj/projectile/ion/heavy - ion_severity = 15 // STRONG ions - ion_range = 2 + light_emp_radius = 2 + heavy_emp_radius = 2 diff --git a/code/modules/projectiles/projectile/special/plasma.dm b/code/modules/projectiles/projectile/special/plasma.dm index 63f46d4e7785..b98bba4951d8 100644 --- a/code/modules/projectiles/projectile/special/plasma.dm +++ b/code/modules/projectiles/projectile/special/plasma.dm @@ -6,7 +6,6 @@ damage = 5 range = 4 dismemberment = 20 - demolition_mod = 2 // industrial strength plasma cutter designed to cut things impact_effect_type = /obj/effect/temp_visual/impact_effect/purple_laser var/mine_range = 3 //mines this many additional tiles of rock tracer_type = /obj/effect/projectile/tracer/plasma_cutter diff --git a/code/modules/projectiles/projectile/special/rocket.dm b/code/modules/projectiles/projectile/special/rocket.dm index 3d220e4842a3..a0df35e83b00 100644 --- a/code/modules/projectiles/projectile/special/rocket.dm +++ b/code/modules/projectiles/projectile/special/rocket.dm @@ -12,15 +12,21 @@ name ="\improper HEDP rocket" desc = "USE A WEEL GUN" icon_state= "84mm-hedp" - armor_flag = BOMB damage = 80 - demolition_mod = 4 + var/anti_armour_damage = 200 armour_penetration = 100 dismemberment = 100 /obj/projectile/bullet/a84mm/on_hit(atom/target, blocked = FALSE) ..() explosion(target, -1, 1, 3, 1, 0, flame_range = 4) + + if(ismecha(target)) + var/obj/mecha/M = target + M.take_damage(anti_armour_damage, BRUTE, BOMB, FALSE, null, armour_penetration) + if(issilicon(target)) + var/mob/living/silicon/S = target + S.take_overall_damage(anti_armour_damage*0.75, anti_armour_damage*0.25) return BULLET_ACT_HIT /obj/projectile/bullet/a84mm_he @@ -28,7 +34,6 @@ desc = "Boom." icon_state = "missile" damage = 30 - demolition_mod = 4 ricochets_max = 0 //it's a MISSILE /obj/projectile/bullet/a84mm_he/on_hit(atom/target, blocked=0) @@ -44,7 +49,6 @@ desc = "Boom." icon_state = "missile" damage = 30 - demolition_mod = 4 ricochets_max = 0 //it's a MISSILE var/sturdy = list( /turf/closed, @@ -75,18 +79,22 @@ icon_state = "cannonball" desc = "Not for bowling purposes" damage = 30 - demolition_mod = 20 // YARRR /obj/projectile/bullet/cball/on_hit(atom/target, blocked=0) - var/atom/throw_target = get_edge_target_turf(target, firer.dir) - if(ismecha(target) || isliving(target)) - demolition_mod = 5 // woah there let's not one-shot mechs and borgs - . = ..() - if(!ismovable(target)) // if it's not movable then don't bother trying to throw it - return - var/atom/movable/movable_target = target - if(!movable_target.anchored && !movable_target.throwing)//avoid double hits - movable_target.throw_at(throw_target, 2, 4, firer, 3) + var/mob/living/carbon/human/H = firer + var/atom/throw_target = get_edge_target_turf(target, H.dir) + if(istype(target, /obj/structure/window) || istype(target, /obj/machinery/door) || istype(target, /obj/structure/door_assembly)) + damage = 500 + ..() + if(isliving(target)) + var/mob/living/L = target + if(!L.anchored && !L.throwing)//avoid double hits + if(iscarbon(L)) + var/mob/living/carbon/C = L + var/mob/M = firer + if(istype(M)) + C.throw_at(throw_target, 2, 4, H, 3) + return BULLET_ACT_HIT /obj/projectile/bullet/bolt name = "bolt" diff --git a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm index 0cc6b163262d..c924ef3ab58d 100644 --- a/code/modules/reagents/chemistry/recipes/pyrotechnics.dm +++ b/code/modules/reagents/chemistry/recipes/pyrotechnics.dm @@ -119,10 +119,10 @@ /datum/chemical_reaction/emp_pulse/on_reaction(datum/reagents/holder, created_volume) var/location = get_turf(holder.my_atom) - // 100 created volume = 8 severity & 14 range. 4 tiles larger than traitor EMP grenades. - // 200 created volume = 16 (capped to 10) severity & 28 range. 12 tiles larger than traitor EMP grenades. This is the maximum + // 100 created volume = 8 heavy range & 14 light range. 4 tiles larger than traitor EMP grenades. + // 200 created volume = 16 heavy range & 28 light range. 12 tiles larger than traitor EMP grenades. This is the maximum created_volume = min(created_volume, 200) - empulse(location, min(round(created_volume / 12), EMP_HEAVY), round(created_volume / 7), 1) + empulse(location, round(created_volume / 12), round(created_volume / 7), 1) holder.clear_reagents() diff --git a/code/modules/reagents/chemistry/recipes/slime_extracts.dm b/code/modules/reagents/chemistry/recipes/slime_extracts.dm index bd67368f4b60..d93d2cc81af0 100644 --- a/code/modules/reagents/chemistry/recipes/slime_extracts.dm +++ b/code/modules/reagents/chemistry/recipes/slime_extracts.dm @@ -354,7 +354,7 @@ required_other = TRUE /datum/chemical_reaction/slime/slimeoverload/on_reaction(datum/reagents/holder, created_volume) - empulse(get_turf(holder.my_atom), 7) + empulse(get_turf(holder.my_atom), 3, 7) ..() /datum/chemical_reaction/slime/slimecell diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm index 1f34dfb329b7..fef83d18d055 100644 --- a/code/modules/research/experimentor.dm +++ b/code/modules/research/experimentor.dm @@ -369,7 +369,7 @@ else if(prob(EFFECT_PROB_MEDIUM-badThingCoeff)) autoexperiment = 0 visible_message(span_warning("[src] melts [exp_on], ionizing the air around it!")) - empulse(loc, 6) + empulse(loc, 4, 6) investigate_log("Experimentor has generated an Electromagnetic Pulse.", INVESTIGATE_EXPERIMENTOR) ejectItem(TRUE) //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/research/nanites/nanite_programs.dm b/code/modules/research/nanites/nanite_programs.dm index a3751a0d4dd5..cd6be3b94dba 100644 --- a/code/modules/research/nanites/nanite_programs.dm +++ b/code/modules/research/nanites/nanite_programs.dm @@ -194,7 +194,7 @@ /datum/nanite_program/proc/on_emp(severity) if(program_flags & NANITE_EMP_IMMUNE) return - if(prob(8 * severity)) + if(prob(80 / severity)) software_error() /datum/nanite_program/proc/on_shock(shock_damage) diff --git a/code/modules/research/nanites/nanite_programs/weapon.dm b/code/modules/research/nanites/nanite_programs/weapon.dm index 6e5c8fb3380c..2590b8980f49 100644 --- a/code/modules/research/nanites/nanite_programs/weapon.dm +++ b/code/modules/research/nanites/nanite_programs/weapon.dm @@ -134,7 +134,7 @@ /datum/nanite_program/triggered/emp/trigger() if(!..()) return - empulse(host_mob, EMP_HEAVY, 2) + empulse(host_mob, 1, 2) /datum/nanite_program/pyro/active_effect() host_mob.adjust_fire_stacks(1) diff --git a/code/modules/research/server.dm b/code/modules/research/server.dm index b142be514f63..0cc6164d976d 100644 --- a/code/modules/research/server.dm +++ b/code/modules/research/server.dm @@ -96,12 +96,12 @@ working = TRUE update_appearance(UPDATE_ICON) -/obj/machinery/rnd/server/emp_act(severity) +/obj/machinery/rnd/server/emp_act() . = ..() if(. & EMP_PROTECT_SELF) return stat |= EMPED - addtimer(CALLBACK(src, PROC_REF(unemp)), (6 * severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(unemp)), 600) refresh_working() /obj/machinery/rnd/server/proc/unemp() diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm index 3f8e9b2dea74..00ce26f5d727 100644 --- a/code/modules/research/xenobiology/xenobiology.dm +++ b/code/modules/research/xenobiology/xenobiology.dm @@ -279,7 +279,7 @@ if(SLIME_ACTIVATE_MAJOR) user.visible_message(span_warning("[user]'s skin starts flashing intermittently..."), span_warning("Your skin starts flashing intermittently...")) if(do_after(user, 2.5 SECONDS, user)) - empulse(user, EMP_HEAVY, 2) + empulse(user, 1, 2) user.visible_message(span_warning("[user]'s skin flashes!"), span_warning("Your skin flashes as you emit an electromagnetic pulse!")) return 600 diff --git a/code/modules/spells/spell_types/self/disable_tech.dm b/code/modules/spells/spell_types/self/disable_tech.dm index 7def457a89e1..558e4e6943bf 100644 --- a/code/modules/spells/spell_types/self/disable_tech.dm +++ b/code/modules/spells/spell_types/self/disable_tech.dm @@ -6,14 +6,14 @@ school = SCHOOL_EVOCATION - /// The severity of the EMP - var/severity = EMP_HEAVY - /// The radius of the EMP - var/radius = 3 + /// The heavy radius of the EMP + var/emp_heavy = 2 + /// The light radius of the EMP + var/emp_light = 3 /datum/action/cooldown/spell/emp/cast(atom/cast_on) . = ..() - empulse(get_turf(cast_on), severity, radius) + empulse(get_turf(cast_on), emp_heavy, emp_light) /datum/action/cooldown/spell/emp/disable_tech name = "Disable Tech" @@ -26,4 +26,5 @@ invocation = "NEC CANTIO" invocation_type = INVOCATION_SHOUT - radius = 10 + emp_heavy = 6 + emp_light = 10 \ No newline at end of file diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index eda1348554ec..7b22796ef170 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -45,7 +45,6 @@ var/brute_reduction = 0 //Subtracted to brute damage taken var/burn_reduction = 0 //Subtracted to burn damage taken - var/emp_reduction = 0 //Subtracted to EMP severity //Coloring and proper item icon update var/skin_tone = "" @@ -128,32 +127,6 @@ /obj/item/bodypart/blob_act() take_damage(max_damage) -/obj/item/bodypart/emp_act(severity, emp_message=TRUE) - . = ..() - if(. & EMP_PROTECT_SELF) - return - - var/blocked = owner.getarmor(body_zone, ENERGY) // energy armor protects against EMPs - severity *= (100 - blocked) / 100 - severity -= emp_reduction - if(severity < 1) - return - - if(receive_damage(0, severity / 2, severity, FALSE, TRUE, BODYPART_ROBOTIC, CANT_WOUND)) // returns false for non-robotic limbs - if(severity > EMP_LIGHT) - ADD_TRAIT(src, TRAIT_PARALYSIS, "EMP") - addtimer(CALLBACK(src, PROC_REF(after_emp)), min((severity / 2) SECONDS, 5 SECONDS), TIMER_UNIQUE | TIMER_OVERRIDE) - if(owner && emp_message) - owner.emote("scream") - to_chat(src, span_userdanger("You feel a sharp pain as your robotic limbs overload.")) - - if(!(. & EMP_PROTECT_CONTENTS)) - for(var/obj/item/organ/O as anything in get_organs()) - O.emp_act(severity) - -/obj/item/bodypart/proc/after_emp() - REMOVE_TRAIT(src, TRAIT_PARALYSIS, "EMP") - /obj/item/bodypart/Destroy() if(owner) owner.bodyparts -= src @@ -858,7 +831,7 @@ else species_color = "" - if(!dropping_limb && (H.dna.check_mutation(HULK))) + if(!dropping_limb && (H.dna.check_mutation(HULK) || H.dna.check_mutation(ACTIVE_HULK))) mutation_color = "#00aa00" else mutation_color = "" diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm index e45511648e94..b600f356e49e 100644 --- a/code/modules/surgery/organs/appendix.dm +++ b/code/modules/surgery/organs/appendix.dm @@ -83,5 +83,4 @@ . = ..() if(. & EMP_PROTECT_SELF) return - if(severity > EMP_LIGHT) - damage += 20 * (severity - EMP_HEAVY) + damage += 100/severity diff --git a/code/modules/surgery/organs/augment_legs.dm b/code/modules/surgery/organs/augment_legs.dm index 706f430160dc..ea53e3f59c23 100644 --- a/code/modules/surgery/organs/augment_legs.dm +++ b/code/modules/surgery/organs/augment_legs.dm @@ -23,7 +23,7 @@ if(!L) //how did you get an implant in a limb you don't have? return - L.receive_damage(severity / 2, 0, severity) //always take a least a little bit of damage to the leg + L.receive_damage(5,0,10) //always take a least a little bit of damage to the leg if(prob(50)) //you're forced to use two of these for them to work so let's give em a chance to not get completely fucked if(COOLDOWN_FINISHED(src, emp_notice)) @@ -32,15 +32,15 @@ return L.set_disabled(TRUE) //disable the bodypart - addtimer(CALLBACK(src, PROC_REF(reenableleg)), (severity / 2) SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) + addtimer(CALLBACK(src, PROC_REF(reenableleg)), 5 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE) - if(severity > EMP_LIGHT && prob(5) && !syndicate_implant) //put probabilities into a calculator before you try fucking with this - to_chat(owner, span_warning("[src] malfunctions and thrashes your [L] around wildly, breaking it!")) + if(severity & EMP_HEAVY && prob(5) && !syndicate_implant) //put probabilities into a calculator before you try fucking with this + to_chat(owner, span_warning("The EMP causes your [src] to thrash your [L] around wildly, breaking it!")) var/datum/wound/blunt/severe/breakdown = new breakdown.apply_wound(L) L.receive_damage(20) else if(COOLDOWN_FINISHED(src, emp_notice)) - to_chat(owner, span_warning("[src] malfunctions and causes your muscles to seize up, preventing your [L] from moving!")) + to_chat(owner, span_warning("The EMP causes your [src] to seize up, preventing your [L] from moving!")) COOLDOWN_START(src, emp_notice, 30 SECONDS) /obj/item/organ/cyberimp/leg/proc/reenableleg() @@ -84,6 +84,14 @@ to_chat(user, span_notice("You modify [src] to be installed on the [zone == BODY_ZONE_R_LEG ? "right" : "left"] leg.")) update_appearance(UPDATE_ICON) +/obj/item/organ/cyberimp/leg/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(prob(15/severity) && owner) + to_chat(owner, span_warning("[src] is hit by EMP!")) + // give the owner an idea about why his implant is glitching + /obj/item/organ/cyberimp/leg/Insert(mob/living/carbon/M, special, drop_if_replaced, special_zone) . = ..() if(HasBoth()) diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm index 1f018e8918e7..a7aed9252035 100644 --- a/code/modules/surgery/organs/augments_arms.dm +++ b/code/modules/surgery/organs/augments_arms.dm @@ -67,7 +67,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - if(prob(1.5 * severity) && owner) + if(prob(15/severity) && owner) to_chat(owner, span_warning("[src] is hit by EMP!")) // give the owner an idea about why his implant is glitching Retract() @@ -162,7 +162,7 @@ . = ..() if(. & EMP_PROTECT_SELF) return - if(prob(3 * severity) && owner && (organ_flags & ORGAN_FAILING)) + if(prob(30/severity) && owner && (organ_flags & ORGAN_FAILING)) Retract() owner.visible_message(span_danger("A loud bang comes from [owner]\'s [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm!")) playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 0ab2df136add..a11f9e1c5d2c 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -32,8 +32,7 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return - var/existing = owner.reagents.get_reagent_amount(/datum/reagent/toxin/bad_food) - owner.reagents.add_reagent(/datum/reagent/toxin/bad_food, (poison_amount * (severity / EMP_HEAVY)) - existing) + owner.reagents.add_reagent(/datum/reagent/toxin/bad_food, poison_amount / severity) to_chat(owner, span_warning("You feel like your insides are burning.")) @@ -103,10 +102,10 @@ if(ishuman(owner) && !syndicate_implant) var/mob/living/carbon/human/H = owner - if(H.stat != DEAD && prob(5 * severity) && H.can_heartattack()) + if(H.stat != DEAD && prob(50 / severity) && H.can_heartattack()) H.set_heartattack(TRUE) to_chat(H, span_userdanger("You feel a horrible agony in your chest!")) - addtimer(CALLBACK(src, PROC_REF(undo_heart_attack)), severity SECONDS) + addtimer(CALLBACK(src, PROC_REF(undo_heart_attack)), 10 SECONDS / severity) /obj/item/organ/cyberimp/chest/reviver/proc/undo_heart_attack() var/mob/living/carbon/human/H = owner @@ -213,8 +212,13 @@ /obj/item/organ/cyberimp/chest/thrusters/emp_act(severity) . = ..() - owner.adjustFireLoss(3 * severity) - to_chat(owner, span_warning("Your thruster implant malfunctions and severely burns you!")) + switch(severity) + if(EMP_HEAVY) + owner.adjustFireLoss(35) + to_chat(owner, span_warning("Your thruster implant malfunctions and severely burns you!")) + if(EMP_LIGHT) + owner.adjustFireLoss(10) + to_chat(owner, span_danger("Your thruster implant malfunctions and mildly burns you!")) /obj/item/organ/cyberimp/chest/spinalspeed name = "neural overclocker implant" @@ -331,17 +335,27 @@ /obj/item/organ/cyberimp/chest/spinalspeed/emp_act(severity) . = ..() if(!syndicate_implant)//the toy has a different emp act - owner.adjust_dizzy(severity SECONDS) + owner.adjust_dizzy(10 SECONDS / severity) to_chat(owner, span_warning("Your spinal implant makes you feel queasy!")) return - owner.set_drugginess(4 * severity) - owner.adjust_hallucinations((50 * severity) SECONDS) - owner.blur_eyes(2 * severity) - owner.adjust_dizzy(severity SECONDS) - time_on += severity - owner.adjustFireLoss(severity) - to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) + switch(severity)//i don't want emps to just be damage again, that's boring + if(EMP_HEAVY) + owner.set_drugginess(40) + owner.adjust_hallucinations(500 SECONDS) + owner.adjust_eye_blur(20) + owner.adjust_dizzy(10 SECONDS) + time_on += 10 + owner.adjustFireLoss(10) + to_chat(owner, span_warning("Your spinal implant malfunctions and you feel it scramble your brain!")) + if(EMP_LIGHT) + owner.set_drugginess(20) + owner.adjust_hallucinations(200 SECONDS) + owner.adjust_eye_blur(10) + owner.adjust_dizzy(5 SECONDS) + time_on += 5 + owner.adjustFireLoss(5) + to_chat(owner, span_danger("Your spinal implant malfunctions and you suddenly feel... wrong.")) /obj/item/organ/cyberimp/chest/spinalspeed/toy name = "glowy after-image trail implant" diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 87bdd6505488..7f340058b76c 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -36,7 +36,7 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return - owner.Stun(stun_amount * (severity / EMP_HEAVY)) + owner.Stun(stun_amount / severity) to_chat(owner, span_warning("Your body seizes up!")) @@ -74,12 +74,13 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return + var/range = severity ? 10 : 5 var/atom/A if(active) release_items() for(var/obj/item/I in stored_items) - A = pick(oview(severity)) - I.throw_at(A, severity, 2) + A = pick(oview(range)) + I.throw_at(A, range, 2) to_chat(owner, span_warning("Your [owner.get_held_index_name(owner.get_held_index_of_item(I))] spasms and throws the [I.name]!")) stored_items = list() @@ -137,7 +138,7 @@ if((organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF) return organ_flags |= ORGAN_FAILING - addtimer(CALLBACK(src, PROC_REF(reboot)), stun_cap_amount * (severity / 5)) + addtimer(CALLBACK(src, PROC_REF(reboot)), stun_cap_amount * 2 / severity) /obj/item/organ/cyberimp/brain/anti_stun/proc/reboot() clear_stuns() @@ -182,7 +183,7 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return - if(prob(6 * severity)) + if(prob(60/severity)) to_chat(owner, span_warning("Your breathing tube suddenly closes!")) owner.losebreath += 2 diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm index 0c3b10aaf071..cd5364d44b42 100644 --- a/code/modules/surgery/organs/ears.dm +++ b/code/modules/surgery/organs/ears.dm @@ -157,11 +157,15 @@ compatible_biotypes = MOB_ROBOTIC // for IPCs /obj/item/organ/ears/robot/emp_act(severity) - owner.adjust_jitter(3 * severity) - owner.adjust_dizzy(3 * severity) - owner.Knockdown(severity SECONDS) - if(severity > EMP_LIGHT) - deaf = 3 * severity - to_chat(owner, span_warning("Your robotic ears are uselessly ringing.")) - return - to_chat(owner, span_warning("Your robotic ears buzz.")) + switch(severity) + if(1) + owner.adjust_jitter(30 SECONDS) + owner.adjust_dizzy(30) + owner.Knockdown(5 SECONDS) + deaf = 30 + to_chat(owner, span_warning("Your robotic ears are uselessly ringing.")) + if(2) + owner.adjust_jitter(15 SECONDS) + owner.adjust_dizzy(15) + owner.Knockdown(10 SECONDS) + to_chat(owner, span_warning("Your robotic ears buzz.")) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index b295459a9090..cbfcc08db923 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -20,14 +20,16 @@ low_threshold_cleared = span_info("Your vision is cleared of any ailment.") var/sight_flags = 0 - var/see_in_dark = 2 var/tint = 0 var/eye_color = "" //set to a hex code to override a mob's eye color var/eye_icon_state = "eyes" var/old_eye_color = "fff" var/flash_protect = 0 var/see_invisible = SEE_INVISIBLE_LIVING - var/lighting_alpha + /// How much darkness to cut out of your view (basically, night vision) + var/lighting_cutoff = null + /// List of color cutoffs from eyes, or null if not applicable + var/list/color_cutoffs = null var/no_glasses var/damaged = TRUE //damaged indicates that our eyes are undergoing some level of negative effect,starts as true so it removes the impaired vision overlay if it is replacing damaged eyes @@ -40,8 +42,6 @@ HMN.eye_color = eye_color else eye_color = HMN.eye_color - if(HAS_TRAIT(HMN, TRAIT_NIGHT_VISION) && !lighting_alpha) - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT M.update_tint() owner.update_sight() if(M.has_dna() && ishuman(M)) @@ -55,7 +55,7 @@ HMN.update_body() M.cure_blind(list(EYE_DAMAGE)) // can't be blind from eye damage if there's no eye to be damaged, still blind from not having eyes though M.cure_nearsighted(list(EYE_DAMAGE)) // likewise for nearsightedness - M.set_blurriness(0) // no eyes to blur + M.set_eye_blur(0) // no eyes to blur M.update_tint() M.update_sight() @@ -117,48 +117,83 @@ #undef OFFSET_X #undef OFFSET_Y +#define NIGHTVISION_LIGHT_OFF 0 +#define NIGHTVISION_LIGHT_LOW 1 +#define NIGHTVISION_LIGHT_MID 2 +#define NIGHTVISION_LIGHT_HIG 3 + /obj/item/organ/eyes/night_vision name = "shadow eyes" desc = "A spooky set of eyes that can see in the dark." - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + actions_types = list(/datum/action/item_action/organ_action/use) - var/night_vision = TRUE + // These lists are used as the color cutoff for the eye + // They need to be filled out for subtypes + var/list/low_light_cutoff + var/list/medium_light_cutoff + var/list/high_light_cutoff + var/light_level = NIGHTVISION_LIGHT_OFF + +/obj/item/organ/eyes/night_vision/Initialize(mapload) + . = ..() + + if(length(low_light_cutoff) != 3 || length(medium_light_cutoff) != 3 || length(high_light_cutoff) != 3) + stack_trace("[type] did not have fully filled out color cutoff lists") + if(low_light_cutoff) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW /obj/item/organ/eyes/night_vision/ui_action_click() sight_flags = initial(sight_flags) - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + switch(light_level) + if (NIGHTVISION_LIGHT_OFF) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW + if (NIGHTVISION_LIGHT_LOW) + color_cutoffs = medium_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_MID + if (NIGHTVISION_LIGHT_MID) + color_cutoffs = high_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_HIG else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - sight_flags &= ~SEE_BLACKNESS + color_cutoffs = null + light_level = NIGHTVISION_LIGHT_OFF owner.update_sight() -/obj/item/organ/eyes/night_vision/alien +#undef NIGHTVISION_LIGHT_OFF +#undef NIGHTVISION_LIGHT_LOW +#undef NIGHTVISION_LIGHT_MID +#undef NIGHTVISION_LIGHT_HIG + +/obj/item/organ/eyes/night_vision/mushroom + name = "fung-eye" + desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + low_light_cutoff = list(0, 15, 20) + medium_light_cutoff = list(0, 20, 35) + high_light_cutoff = list(0, 40, 50) + +//innate nightvision eyes +/obj/item/organ/eyes/alien name = "alien eyes" desc = "It turned out they had them after all!" sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) + lighting_cutoff = LIGHTING_CUTOFF_HIGH -/obj/item/organ/eyes/night_vision/zombie +/obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) + lighting_cutoff = LIGHTING_CUTOFF_HIGH -/obj/item/organ/eyes/night_vision/nightmare +/obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" - -/obj/item/organ/eyes/night_vision/mushroom - name = "fung-eye" - desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + color_cutoffs = list(20, 10, 40) + lighting_cutoff = LIGHTING_CUTOFF_HIGH ///Robotic - /obj/item/organ/eyes/robotic name = "robotic eyes" icon_state = "cybernetic_eyeballs" @@ -171,19 +206,21 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return + var/obj/item/organ/eyes/eyes = owner.getorganslot(ORGAN_SLOT_EYES) to_chat(owner, span_danger("your eyes overload and blind you!")) owner.flash_act(override_blindness_check = 1) - owner.blind_eyes(severity / 2) - owner.blur_eyes(8) - applyOrganDamage(2 * severity) + owner.blind_eyes(5) + owner.adjust_eye_blur(8) + eyes.applyOrganDamage(20 / severity) /obj/item/organ/eyes/robotic/xray name = "\improper meson eyes" desc = "These cybernetic eyes will give you meson-vision. Looks like it could withstand seeing a supermatter crystal!." eye_color = "00FF00" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) sight_flags = SEE_TURFS - see_in_dark = 4 + /obj/item/organ/eyes/robotic/xray/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE, initialising) . = ..() @@ -198,16 +235,15 @@ desc = "These cybernetic eyes will give you true X-ray vision. Blinking is futile." eye_color = "000" sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS - see_in_dark = 8 /obj/item/organ/eyes/robotic/thermals name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." eye_color = "FC0" sight_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) flash_protect = -1 - see_in_dark = 8 /obj/item/organ/eyes/robotic/flashlight name = "flashlight eyes" @@ -454,5 +490,15 @@ /obj/item/organ/eyes/polysmorph name = "polysmorph eyes" desc = "Eyes from a polysmorph, capable of retaining slightly more vision in low light environments" - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT - see_in_dark = 5 + color_cutoffs = list(25, 5, 42) + +/obj/item/organ/eyes/zombie + name = "undead eyes" + desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) + +/obj/item/organ/eyes/alien + name = "alien eyes" + desc = "It turned out they had them after all!" + sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index c121ae5f79d1..a61aa75c800c 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -239,9 +239,8 @@ . = ..() if(. & EMP_PROTECT_SELF) return - if(severity > EMP_LIGHT) - Stop() - addtimer(CALLBACK(src, PROC_REF(Restart)), restartTimer * min(severity / EMP_HEAVY, 1)) //Can restart itself after an EMP so it isnt an insta death + Stop() + addtimer(CALLBACK(src, PROC_REF(Restart)), restartTimer/severity) //Can restart itself after an EMP so it isnt an insta death /obj/item/organ/heart/cybernetic/upgraded name = "upgraded cybernetic heart" @@ -267,12 +266,12 @@ /obj/item/organ/heart/cybernetic/ipc desc = "An electronic device that appears to mimic the functions of an organic heart." -/obj/item/organ/heart/cybernetic/ipc/emp_act(severity) +/obj/item/organ/heart/cybernetic/ipc/emp_act() if(prob(30)) return . = ..() to_chat(owner, "Alert: Cybernetic heart failed one heartbeat") - addtimer(CALLBACK(src, PROC_REF(Restart)), severity SECONDS) + addtimer(CALLBACK(src, PROC_REF(Restart)), 10 SECONDS) /obj/item/organ/heart/freedom name = "heart of freedom" diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index b57493a2f019..05d0775c9163 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -117,7 +117,8 @@ . = ..() if(. & EMP_PROTECT_SELF) return - applyOrganDamage(5 * severity) + + damage += 50/severity /obj/item/organ/liver/cybernetic/upgraded/ipc name = "substance processor" @@ -134,4 +135,4 @@ if(prob(10)) return to_chat(owner, "Alert: Your Substance Processor has been damaged. An internal chemical leak is affecting performance.") - owner.adjustToxLoss(severity) + owner.adjustToxLoss(10/severity) diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm index fac73fdeac61..4735d278c05f 100644 --- a/code/modules/surgery/organs/lungs.dm +++ b/code/modules/surgery/organs/lungs.dm @@ -581,11 +581,11 @@ safe_breath_min = 13 safe_breath_max = 100 -/obj/item/organ/lungs/cybernetic/emp_act(severity) +/obj/item/organ/lungs/cybernetic/emp_act() . = ..() if(. & EMP_PROTECT_SELF) return - owner.losebreath = 2 * severity + owner.losebreath = 20 /obj/item/organ/lungs/cybernetic/upgraded name = "upgraded cybernetic lungs" diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm index ce03572c32f8..b2572da28bf1 100644 --- a/code/modules/surgery/organs/stomach.dm +++ b/code/modules/surgery/organs/stomach.dm @@ -145,7 +145,7 @@ /obj/item/organ/stomach/cell/emp_act(severity) to_chat(owner, emp_message) - charge(amount = owner.nutrition * -0.02 * severity) + charge(amount = owner.nutrition * -0.2 / severity) /obj/item/organ/stomach/cell/Insert(mob/living/carbon/M, special, drop_if_replaced) . = ..() diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm index 92b50110451d..ac2dced2b692 100644 --- a/code/modules/surgery/organs/tongue.dm +++ b/code/modules/surgery/organs/tongue.dm @@ -266,9 +266,9 @@ /obj/item/organ/tongue/robot/emp_act(severity) if(prob(5)) return - owner.apply_effect(EFFECT_STUTTER, rand(1, severity) * 6 SECONDS) + owner.apply_effect(EFFECT_STUTTER, rand(5 SECONDS, 2 MINUTES)) owner.emote("scream") - to_chat(owner, "Alert: Voice synthesizer is malfunctioning.") + to_chat(owner, "Alert: Vocal cords are malfunctioning.") /obj/item/organ/tongue/robot/can_speak_language(language) return TRUE // THE MAGIC OF ELECTRONICS diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm index 05192ad4b1c2..cb74738d8880 100644 --- a/code/modules/surgery/tools.dm +++ b/code/modules/surgery/tools.dm @@ -169,7 +169,6 @@ throwforce = 5 throw_speed = 3 throw_range = 5 - demolition_mod = 0.25 materials = list(/datum/material/iron=4000, /datum/material/glass=1000) attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut") hitsound = 'sound/weapons/bladeslice.ogg' @@ -400,7 +399,6 @@ light_range = 1 light_color = LIGHT_COLOR_GREEN light_power = 0.2 //Barely glows on low power - demolition_mod = 1.5 // lasers are good at cutting metal sharpness = SHARP_EDGED diff --git a/code/modules/swarmers/swarmer.dm b/code/modules/swarmers/swarmer.dm index 2a7afaa99109..fdfad769000b 100644 --- a/code/modules/swarmers/swarmer.dm +++ b/code/modules/swarmers/swarmer.dm @@ -96,13 +96,12 @@ . = ..() . += "Resources: [resources]" -/mob/living/simple_animal/hostile/swarmer/emp_act(severity) +/mob/living/simple_animal/hostile/swarmer/emp_act() . = ..() if(. & EMP_PROTECT_SELF) return - var/emp_damage = severity/EMP_HEAVY - if(health > emp_damage) - adjustHealth(health - emp_damage) + if(health > 1) + adjustHealth(health-1) else death() diff --git a/html/changelog.html b/html/changelog.html index 74af3e3b611a..14dbeb237076 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -57,49 +57,6 @@ -->
    -

    03 December 2023

    -

    cark updated:

    -
      -
    • fixes missing floor in airlock on donut
    • -
    -

    itseasytosee, sapphicoverload updated:

    -
      -
    • some items and projectiles are now better or worse than others at destroying things
    • -
    • chat messages from hitting an object now tell whether you can damage it
    • -
    • fixed machines/structures/etc not caring about armor penetration when hit by a melee weapon
    • -
    • fixed cannonballs not doing any damage to mobs
    • -
    -

    Moltijoe updated:

    -
      -
    • Sometimes fixes feed ability sometimes breaking
    • -
    • Gangrel transformation ability now shows the radial menu before the 10 second do_after
    • -
    • Fixes gangrel transformation ability sometimes deleting itself without ever being used
    • -
    • Fixes gangrel werewolf transformation being eradicated from the timeline by tattax
    • -
    -

    SapphicOverload updated:

    -
      -
    • fixed ED-209 not being affected by heavy EMPs
    • -
    • fixed leg implants not being affected by EMPs at all
    • -
    • fixed cybernetic ears causing longer knockdown times on light EMPs instead of the other way around
    • -
    • fixed nanite heart killing you instantly on EMP regardless of whether or not it kills your nanites
    • -
    • HoS gun now shoots ion carbine projectiles instead of its own redundant projectile type
    • -
    • mech ion cannon has 1.5x stronger EMPs than the ion rifle
    • -
    • syndicate EMP bomb has 2.5x stronger EMPs than standard EMP grenades
    • -
    • reworks EMPs to allow any severity, which now decreases with distance
    • -
    - -

    02 December 2023

    -

    Moltijoe updated:

    -
      -
    • No more infinitely duplicating hulk DAN
    • -
    • Hulk now occasionally says the brain damage hulk lines
    • -
    -

    SapphicOverload updated:

    -
      -
    • fixed runtime error when passive vents encounter zero temperature or zero volume
    • -
    • fixed abandoned crates having a 2% chance to cause runtime errors when initialized
    • -
    -

    01 December 2023

    Twaticus, Imaginos16, Cark updated:

      @@ -2140,6 +2097,92 @@

      warface1234455 updated:

      • Replaces old pda with modern pda in pda box
      + +

      03 September 2023

      +

      MajManatee updated:

      +
        +
      • The engineering vendor now has one compressed matter per RCD instead of 3/5
      • +
      +

      Moltijoe updated:

      +
        +
      • Preternis Liquidator now needs to actually do the combo
      • +
      +

      SapphicOverload updated:

      +
        +
      • necromancy no longer works on mindshielded people unless they're on a persuasion rack
      • +
      • fixed x-ray bolts causing toxin damage to rad-immune species when embedded
      • +
      • preternis now slow down and suffocate when low on charge instead of just instantly dropping dead when they hit zero
      • +
      • liquid electricity can now actually charge species that run on electricity
      • +
      • radiation charges ethereals now
      • +
      • preternis, ethereal, and IPC charging have been refactored, please report any bugs you find
      • +
      +

      warface1234455 updated:

      +
        +
      • Give the gas analyzer ability to scan turf next to the user
      • +
      + +

      02 September 2023

      +

      @cuackles, @SapphicOverload updated:

      +
        +
      • adds pride jackets to hacked clothing vendors
      • +
      • pride jackets
      • +
      +

      ArcaneMusic, Ktlwjec updated:

      +
        +
      • BBQ sauce, made with 1u ash, 1u tomato juice, 3u saline glucose, 1u black pepper.
      • +
      • BBQ ribs, made with 2 rods, 5u bbq sauce, 2 steaks.
      • +
      • 2 BBQ sauce packets in the kitchen dinnerware vendor.
      • +
      +

      cark updated:

      +
        +
      • kills under-window firelocks across all maps, making them consistent with each other and themselves.
      • +
      +

      JamieD1 updated:

      +
        +
      • Fixes shitty Pranksimov Laws
      • +
      +

      Marmio64 updated:

      +
        +
      • Hecata bloodsuckers take 3x as long (18 seconds) to necromance mindshielded non vassals.
      • +
      • Syndicate derelict engis can use their c20r
      • +
      +

      Moltijoe updated:

      +
        +
      • Holy medbots have antimagic and also inject holy water
      • +
      • Holy revival rite gives 2 minutes of antimagic
      • +
      • Getting the adrenaline buff from damage gives a mood boost
      • +
      • Worldbreaker tweaks
      • +
      • throw only does damage upon collision, not upon throwing
      • +
      • grabbing now stuns for a very short time to allow for aiming
      • +
      • pummel does 20 damage instead of 15
      • +
      • pummel has regular attack cooldown instead of slower (preterni no longer attack slower)
      • +
      • plates have 25 health instead of 15
      • +
      • can only have 3 plates over armour cap instead of 5
      • +
      • plates take 1/4 damage from non brute and burn rather than 1/3
      • +
      • plates give more slowdown
      • +
      • leap cooldown no longer scales directly with number of plates, instead just takes 1 second longer if heavy
      • +
      • leap speed now directly scales with movespeed (meaning outside sources of movespeed will increase it)
      • +
      • leap cooldown only starts once you land, rather than when you start jumping
      • +
      • now gives softcrit immunity
      • +
      • no longer gives damage slowdown resistance
      • +
      • never takes damage from being thrown into a wall
      • +
      • attacks can now hurt mechs
      • +
      +

      Runian updated:

      +
        +
      • A new upgrade for medical cyborgs that gives them a gripper that lets them hold bottles, beakers, and blood bags.
      • +
      • Cyborg gripper now copy overlays for the held items.
      • +
      +

      SomeguyManperson updated:

      +
        +
      • holy light chaplains no longer gain favor from bible bashing people, instead spending favor to heal
      • +
      • holy light now provides a passive buff to people who ingest holy water, increasing incoming healing by 20%, doubled in the chapel. Bonus healing applied by this effect is also turned into favor. Bible bashing someone with this buff has a massively reduced favor cost, but does not heal significantly more than the default.
      • +
      +

      adamsong updated:

      +
        +
      • fixed a few bus buttons being available to moderators
      • +
      • Admins can now view their own permissions
      • +
    GoonStation 13 Development Team diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index b4c1c678ae16..b678b4a6f0de 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -42454,42 +42454,3 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: You can now point while handcuffed cowbot92: - rscadd: Adds new bar signs -2023-12-02: - Moltijoe: - - bugfix: No more infinitely duplicating hulk DAN - - tweak: Hulk now occasionally says the brain damage hulk lines - SapphicOverload: - - bugfix: fixed runtime error when passive vents encounter zero temperature or zero - volume - - bugfix: fixed abandoned crates having a 2% chance to cause runtime errors when - initialized -2023-12-03: - ' cark': - - mapping: fixes missing floor in airlock on donut - ' itseasytosee, sapphicoverload': - - tweak: some items and projectiles are now better or worse than others at destroying - things - - tweak: chat messages from hitting an object now tell whether you can damage it - - bugfix: fixed machines/structures/etc not caring about armor penetration when - hit by a melee weapon - - bugfix: fixed cannonballs not doing any damage to mobs - Moltijoe: - - bugfix: Sometimes fixes feed ability sometimes breaking - - tweak: Gangrel transformation ability now shows the radial menu before the 10 - second do_after - - bugfix: Fixes gangrel transformation ability sometimes deleting itself without - ever being used - - bugfix: Fixes gangrel werewolf transformation being eradicated from the timeline - by tattax - SapphicOverload: - - bugfix: fixed ED-209 not being affected by heavy EMPs - - bugfix: fixed leg implants not being affected by EMPs at all - - bugfix: fixed cybernetic ears causing longer knockdown times on light EMPs instead - of the other way around - - bugfix: fixed nanite heart killing you instantly on EMP regardless of whether - or not it kills your nanites - - tweak: HoS gun now shoots ion carbine projectiles instead of its own redundant - projectile type - - tweak: mech ion cannon has 1.5x stronger EMPs than the ion rifle - - tweak: syndicate EMP bomb has 2.5x stronger EMPs than standard EMP grenades - - experiment: reworks EMPs to allow any severity, which now decreases with distance diff --git a/yogstation/code/game/gamemodes/gangs/dominator.dm b/yogstation/code/game/gamemodes/gangs/dominator.dm index 6faa286dc4c5..d4b82ec6c01c 100644 --- a/yogstation/code/game/gamemodes/gangs/dominator.dm +++ b/yogstation/code/game/gamemodes/gangs/dominator.dm @@ -45,7 +45,7 @@ return ..() /obj/machinery/dominator/emp_act(severity) - gang.domination_time += 3 * severity + gang.domination_time += 30 ..() /obj/machinery/dominator/hulk_damage() diff --git a/yogstation/code/game/objects/items/wielded/sledgehammer.dm b/yogstation/code/game/objects/items/wielded/sledgehammer.dm index 9101954a7a3d..fccce03df081 100644 --- a/yogstation/code/game/objects/items/wielded/sledgehammer.dm +++ b/yogstation/code/game/objects/items/wielded/sledgehammer.dm @@ -14,7 +14,6 @@ throwforce = 18 throw_range = 3 /// Doesn't throw very far sharpness = SHARP_NONE - demolition_mod = 3 // BREAK THINGS armour_penetration = -20 hitsound = 'sound/weapons/smash.ogg' /// Hitsound when thrown at someone attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed") @@ -55,6 +54,8 @@ var/obj/structure/S = target if(istype(S, /obj/structure/window)) // Sledgehammer really good at smashing windows. 2-7 hits to kill a window S.take_damage(S.max_integrity/2, BRUTE, MELEE, FALSE, null, armour_penetration) + else // Sledgehammer can kill airlocks in 17-23 hits, against most other things it's almost as good as a fireaxe + S.take_damage(force*2, BRUTE, MELEE, FALSE, null, armour_penetration) playsound(src, 'sound/effects/bang.ogg', 50, 1) /obj/item/melee/sledgehammer/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, quickstart) diff --git a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm index b5e709874d34..657c81b629db 100644 --- a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm +++ b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm @@ -11,7 +11,6 @@ desc = "A relic sledgehammer with charge packs wired to two blast pads on its head. \ While wielded in two hands, the user can charge a massive blow that will shatter construction and hurl bodies." force = 4 //It's heavy as hell - demolition_mod = 3 // it's a big hammer, what do you expect armour_penetration = 50 //Designed for shattering walls in a single blow, I don't think it cares much about armor throwforce = 18 attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed") diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 590e174bc205..0b65f1bc8ab4 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -113,5 +113,5 @@ /obj/item/organ/stomach/cell/preternis/emp_act(severity) owner.vomit(stun=FALSE) // fuck that - owner.adjust_disgust(2*severity) + owner.adjust_disgust(20) to_chat(owner, "You feel violently ill as the EMP causes your stomach to kick into high gear.") diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm index 867ae2aa24df..22d0b677bcca 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm @@ -3,7 +3,7 @@ plural_form = "Preterni" id = "preternis" changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE) + inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE, TRAIT_FARADAYCAGE) //Faraday cage reduces incoming EMP severity by one level species_traits = list(DYNCOLORS, EYECOLOR, HAIR, LIPS, AGENDER, NOHUSK, DIGITIGRADE)//they're fleshy metal machines, they are efficient, and the outside is metal, no getting husked inherent_biotypes = MOB_ORGANIC|MOB_ROBOTIC|MOB_HUMANOID sexes = FALSE //they're basically ken dolls, come straight out of a printer @@ -59,7 +59,6 @@ for (var/obj/item/bodypart/BP in C.bodyparts) BP.render_like_organic = TRUE // Makes limbs render like organic limbs instead of augmented limbs, check bodyparts.dm - BP.emp_reduction = EMP_LIGHT BP.burn_reduction = 2 BP.brute_reduction = 1 if(BP.body_zone == BODY_ZONE_CHEST) @@ -80,7 +79,6 @@ for (var/V in C.bodyparts) var/obj/item/bodypart/BP = V BP.change_bodypart_status(ORGAN_ORGANIC,FALSE,TRUE) - BP.emp_reduction = initial(BP.emp_reduction) BP.burn_reduction = initial(BP.burn_reduction) BP.brute_reduction = initial(BP.brute_reduction) @@ -296,12 +294,6 @@ var/list/to_add = list() to_add += list( - list( - SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, - SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash - SPECIES_PERK_NAME = "Faraday \"Skin\"", - SPECIES_PERK_DESC = "Preterni have an outer plasteel shell that can block low-intensity EM interference.", - ), list( SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, SPECIES_PERK_ICON = "cookie-bite", diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index ef0adf37aacb..20c405f410d9 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -356,7 +356,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) manifested = TRUE Manifest() if(!eating) - empulse(src, EMP_HEAVY, 6) + empulse(src, 6, 6) addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/simple_animal/hostile/floor_cluwne, Grab), H), 50, TIMER_OVERRIDE|TIMER_UNIQUE) for(var/turf/open/O in range(src, 6)) O.MakeSlippery(TURF_WET_LUBE, 30) diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 5661d84b28be..557b9bdb4b4f 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -214,7 +214,7 @@ Difficulty: Insanely Hard else if(prob(5)) //EMP blast spellscast++ visible_message(span_cult("\The [src] disrupts nearby electrical equipment!")) - empulse(get_turf(src), EMP_HEAVY) + empulse(get_turf(src), 5, 2, 0) else if(prob(5) && melee_damage_type == BRUTE && !special_attacks) //elemental attacks spellscast++ diff --git a/yogstation/code/modules/surgery/organs/heart.dm b/yogstation/code/modules/surgery/organs/heart.dm index da98967b4da4..263fc0c63c2c 100644 --- a/yogstation/code/modules/surgery/organs/heart.dm +++ b/yogstation/code/modules/surgery/organs/heart.dm @@ -6,6 +6,12 @@ compatible_biotypes = ALL_BIOTYPES var/nanite_boost = 1 +/obj/item/organ/heart/nanite/emp_act() + . = ..() + if(!owner || . & EMP_PROTECT_SELF) + return . + Stop() + /obj/item/organ/heart/nanite/on_life() . = ..() if(owner)//makes nanites tick on every life tick, only about 33% speed increase From 56f1434a9af2266db0836428bbb8a111e033fbee Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:30:45 -0500 Subject: [PATCH 100/144] this doesn't need to be redefined I guess --- code/game/machinery/computer/camera.dm | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 8cc1e1fcbf36..16fe1056980c 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,5 +1,3 @@ -#define DEFAULT_MAP_SIZE 15 - /obj/machinery/computer/security name = "security camera console" desc = "Used to access the various cameras on the station." From 363820f7063caa550d9c89d877137d6c686219f2 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 3 Dec 2023 23:44:25 -0500 Subject: [PATCH 101/144] no we need this totally --- code/game/machinery/computer/camera.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 16fe1056980c..8cc1e1fcbf36 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -1,3 +1,5 @@ +#define DEFAULT_MAP_SIZE 15 + /obj/machinery/computer/security name = "security camera console" desc = "Used to access the various cameras on the station." From 778ea63a4676de91cb03e304c85fa6284b97eb0c Mon Sep 17 00:00:00 2001 From: Chubbygummibear Date: Sun, 3 Dec 2023 21:25:42 -0800 Subject: [PATCH 102/144] a familiar pain --- code/__DEFINES/cameranets.dm | 4 + code/__DEFINES/turfs.dm | 14 +++ code/__HELPERS/game.dm | 13 -- code/__HELPERS/unsorted.dm | 1 - code/_onclick/click.dm | 10 ++ code/_onclick/hud/map_popups.dm | 19 ++- code/_onclick/hud/picture_in_picture.dm | 15 ++- code/_onclick/hud/screen_objects.dm | 2 +- code/game/machinery/camera/camera.dm | 44 +++++-- code/game/machinery/computer/_computer.dm | 2 +- code/game/machinery/computer/camera.dm | 6 +- .../living/silicon/ai/freelook/cameranet.dm | 113 +++++++++++------- .../mob/living/silicon/ai/freelook/chunk.dm | 50 ++++---- .../tgui/interfaces/CameraConsole.tsx | 72 ++++++----- yogstation.dme | 1 + 15 files changed, 222 insertions(+), 144 deletions(-) create mode 100644 code/__DEFINES/cameranets.dm diff --git a/code/__DEFINES/cameranets.dm b/code/__DEFINES/cameranets.dm new file mode 100644 index 000000000000..e2da39997e38 --- /dev/null +++ b/code/__DEFINES/cameranets.dm @@ -0,0 +1,4 @@ +/// We only want chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. +#define CHUNK_SIZE 16 +/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always +#define GET_CHUNK_COORD(v) (max((FLOOR(v, CHUNK_SIZE)), 1)) diff --git a/code/__DEFINES/turfs.dm b/code/__DEFINES/turfs.dm index 9f54a7fcfbb9..303384684171 100644 --- a/code/__DEFINES/turfs.dm +++ b/code/__DEFINES/turfs.dm @@ -17,3 +17,17 @@ #define UNDERFLOOR_VISIBLE 1 /// The pipes, disposals, and wires are visible and can be interacted with #define UNDERFLOOR_INTERACTABLE 2 + +#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3])) +/// Returns a list of turfs in the rectangle specified by BOTTOM LEFT corner and height/width, checks for being outside the world border for you +#define CORNER_BLOCK(corner, width, height) CORNER_BLOCK_OFFSET(corner, width, height, 0, 0) + +/// Returns a list of turfs similar to CORNER_BLOCK but with offsets +#define CORNER_BLOCK_OFFSET(corner, width, height, offset_x, offset_y) ((block(locate(corner.x + offset_x, corner.y + offset_y, corner.z), locate(min(corner.x + (width - 1) + offset_x, world.maxx), min(corner.y + (height - 1) + offset_y, world.maxy), corner.z)))) + +/// Returns an outline (neighboring turfs) of the given block +#define CORNER_OUTLINE(corner, width, height) ( \ + CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, -1) + \ + CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, height) + \ + CORNER_BLOCK_OFFSET(corner, 1, height, -1, 0) + \ + CORNER_BLOCK_OFFSET(corner, 1, height, width, 0)) diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 67751fd75f4b..54be14a5a6de 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -8,19 +8,6 @@ #define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL)) #define CULT_POLL_WAIT 2400 -/// Returns a list of turfs similar to CORNER_BLOCK but with offsets -#define CORNER_BLOCK_OFFSET(corner, width, height, offset_x, offset_y) ( \ - (block(locate(corner.x + offset_x, corner.y + offset_y, corner.z), \ - locate(min(corner.x + (width - 1) + offset_x, world.maxx), \ - min(corner.y + (height - 1) + offset_y, world.maxy), corner.z)))) - -/// Returns an outline (neighboring turfs) of the given block -#define CORNER_OUTLINE(corner, width, height) ( \ - CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, -1) + \ - CORNER_BLOCK_OFFSET(corner, width + 2, 1, -1, height) + \ - CORNER_BLOCK_OFFSET(corner, 1, height, -1, 0) + \ - CORNER_BLOCK_OFFSET(corner, 1, height, width, 0)) - /proc/get_area_name(atom/X, format_text = FALSE, is_sensor = FALSE) var/area/A = isarea(X) ? X : get_area(X) if(!A) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 742c86dfae50..cb848000c5f9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1485,4 +1485,3 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) set waitfor = FALSE return call(source, proctype)(arglist(arguments)) -#define TURF_FROM_COORDS_LIST(List) (locate(List[1], List[2], List[3])) diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index f4bd68cd15e9..40a08fb1a167 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -474,6 +474,16 @@ M.Scale(px/sx, py/sy) transform = M +/atom/movable/screen/click_catcher/Initialize(mapload, datum/hud/hud_owner) + . = ..() + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(offset_increased)) + offset_increased(SSmapping, 0, SSmapping.max_plane_offset) + +// Draw to the lowest plane level offered +/atom/movable/screen/click_catcher/proc/offset_increased(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + SET_PLANE_W_SCALAR(src, initial(plane), new_offset) + /atom/movable/screen/click_catcher/Click(location, control, params) var/list/modifiers = params2list(params) if(modifiers["middle"] && iscarbon(usr)) diff --git a/code/_onclick/hud/map_popups.dm b/code/_onclick/hud/map_popups.dm index 7f3997ecbd67..a3b5699c8484 100644 --- a/code/_onclick/hud/map_popups.dm +++ b/code/_onclick/hud/map_popups.dm @@ -44,21 +44,18 @@ screen_maps[screen_obj.assigned_map] = list() // NOTE: Possibly an expensive operation var/list/screen_map = screen_maps[screen_obj.assigned_map] - if(!screen_map.Find(screen_obj)) - screen_map += screen_obj + screen_map |= screen_obj + screen |= screen_obj /** * Clears the map of registered screen objects. - * - * Not really needed most of the time, as the client's screen list gets reset - * on relog. any of the buttons are going to get caught by garbage collection - * anyway. they're effectively qdel'd. */ /client/proc/clear_map(map_name) - if(!map_name || !(map_name in screen_maps)) + if(!map_name || !screen_maps[map_name]) return FALSE for(var/atom/movable/screen/screen_obj in screen_maps[map_name]) screen_maps[map_name] -= screen_obj + screen -= screen_obj if(screen_obj.del_on_map_removal) qdel(screen_obj) screen_maps -= map_name @@ -78,9 +75,10 @@ * * Returns a map name. */ -/client/proc/create_popup(name, ratiox = 100, ratioy = 100) +/client/proc/create_popup(name, title, ratiox = 100, ratioy = 100) winclone(src, "popupwindow", name) var/list/winparams = list() + winparams["title"] = title winparams["size"] = "[ratiox]x[ratioy]" winparams["on-close"] = "handle-popup-close [name]" winset(src, "[name]", list2params(winparams)) @@ -103,13 +101,13 @@ * Width and height are multiplied by 64 by default. */ /client/proc/setup_popup(popup_name, width = 9, height = 9, \ - tilesize = 2, bg_icon) + tilesize = 2, title, bg_icon) if(!popup_name) return clear_map("[popup_name]_map") var/x_value = world.icon_size * tilesize * width var/y_value = world.icon_size * tilesize * height - var/map_name = create_popup(popup_name, x_value, y_value) + var/map_name = create_popup(popup_name, title, x_value, y_value) var/atom/movable/screen/background/background = new background.assigned_map = map_name @@ -133,3 +131,4 @@ /client/verb/handle_popup_close(window_id as text) set hidden = TRUE clear_map("[window_id]_map") + SEND_SIGNAL(src, COMSIG_POPUP_CLEARED, window_id) diff --git a/code/_onclick/hud/picture_in_picture.dm b/code/_onclick/hud/picture_in_picture.dm index 354a6ed54630..dbf4e0af5310 100644 --- a/code/_onclick/hud/picture_in_picture.dm +++ b/code/_onclick/hud/picture_in_picture.dm @@ -12,11 +12,16 @@ var/atom/movable/screen/component_button/button_shrink var/mutable_appearance/standard_background - var/const/max_dimensions = 10 -/atom/movable/screen/movable/pic_in_pic/Initialize(mapload) +/atom/movable/screen/movable/pic_in_pic/Initialize(mapload, datum/hud/hud_owner) . = ..() make_backgrounds() + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(multiz_offset_increase)) + multiz_offset_increase(SSmapping) + +/atom/movable/screen/movable/pic_in_pic/proc/multiz_offset_increase(datum/source) + SIGNAL_HANDLER + SET_PLANE_W_SCALAR(src, initial(plane), SSmapping.max_plane_offset) /atom/movable/screen/movable/pic_in_pic/Destroy() for(var/C in shown_to) @@ -101,9 +106,11 @@ standard_background.transform = M add_overlay(standard_background) +// maximum number of dimensions is 10 + /atom/movable/screen/movable/pic_in_pic/proc/set_view_size(width, height, do_refresh = TRUE) - width = clamp(width, 0, max_dimensions) - height = clamp(height, 0, max_dimensions) + width = clamp(width, 0, 10) + height = clamp(height, 0, 10) src.width = width src.height = height diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 5e81424b01d5..a4f735a9d2a5 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -12,7 +12,7 @@ plane = HUD_PLANE animate_movement = SLIDE_STEPS speech_span = SPAN_ROBOT - vis_flags = VIS_INHERIT_PLANE + //vis_flags = VIS_INHERIT_PLANE appearance_flags = APPEARANCE_UI /// A reference to the object in the slot. Grabs or items, generally. var/obj/master = null diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 0cd4b1aa2516..24ba9e2f4cc2 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -365,7 +365,7 @@ else icon_state = "[xray_module][default_camera_icon][in_use_lights ? "_in_use" : ""]" -/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = 1) +/obj/machinery/camera/proc/toggle_cam(mob/user, displaymessage = TRUE) status = !status if(can_use()) GLOB.cameranet.addCamera(src) @@ -379,12 +379,15 @@ GLOB.cameranet.removeCamera(src) if (isarea(myarea)) LAZYREMOVE(myarea.cameras, src) - GLOB.cameranet.updateChunk(x, y, z) + // We are not guarenteed that the camera will be on a turf. account for that + var/turf/our_turf = get_turf(src) + GLOB.cameranet.updateChunk(our_turf.x, our_turf.y, our_turf.z) var/change_msg = "deactivates" if(status) change_msg = "reactivates" triggerCameraAlarm() - addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 100) + if(!QDELETED(src)) //We'll be doing it anyway in destroy + addtimer(CALLBACK(src, PROC_REF(cancelCameraAlarm)), 100) if(displaymessage) if(user) visible_message(span_danger("[user] [change_msg] [src]!")) @@ -393,16 +396,16 @@ visible_message(span_danger("\The [src] [change_msg]!")) playsound(src, 'sound/items/wirecutter.ogg', 100, TRUE) - update_appearance(UPDATE_ICON) //update Initialize(mapload) if you remove this. + update_appearance() //update Initialize() if you remove this. // now disconnect anyone using the camera //Apparently, this will disconnect anyone even if the camera was re-activated. //I guess that doesn't matter since they can't use it anyway? for(var/mob/O in GLOB.player_list) - if (O.client && O.client.eye == src) + if (O.client?.eye == src) O.unset_machine() O.reset_perspective(null) - to_chat(O, "The screen bursts into static.") + to_chat(O, span_warning("The screen bursts into static!")) /obj/machinery/camera/proc/triggerCameraAlarm() alarm_on = TRUE @@ -424,10 +427,32 @@ /obj/machinery/camera/proc/can_see() var/list/see = null var/turf/pos = get_turf(src) + var/turf/directly_above = GET_TURF_ABOVE(pos) + var/check_lower = pos != get_lowest_turf(pos) + var/check_higher = directly_above && istransparentturf(directly_above) && (pos != get_highest_turf(pos)) + if(isXRay()) see = range(view_range, pos) else see = get_hear(view_range, pos) + if(check_lower || check_higher) + // Haha datum var access KILL ME + for(var/turf/seen in see) + if(check_lower) + var/turf/visible = seen + while(visible && istransparentturf(visible)) + var/turf/below = GET_TURF_BELOW(visible) + for(var/turf/adjacent in range(1, below)) + see += adjacent + see += adjacent.contents + visible = below + if(check_higher) + var/turf/above = GET_TURF_ABOVE(seen) + while(above && istransparentturf(above)) + for(var/turf/adjacent in range(1, above)) + see += adjacent + see += adjacent.contents + above = GET_TURF_ABOVE(above) return see /atom/proc/auto_turn() @@ -469,8 +494,9 @@ user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 2) /obj/machinery/camera/update_remote_sight(mob/living/user) - user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras + user.set_invis_see(SEE_INVISIBLE_LIVING) //can't see ghosts through cameras if(isXRay()) - user.sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS) - + user.add_sight(SEE_TURFS|SEE_MOBS|SEE_OBJS) + else + user.clear_sight(SEE_TURFS|SEE_MOBS|SEE_OBJS) return 1 diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index bb3317a61ac4..9c45e97fe5bc 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -180,6 +180,6 @@ /obj/machinery/computer/ui_interact(mob/user, datum/tgui/ui) - SHOULD_CALL_PARENT(TRUE) + //SHOULD_CALL_PARENT(TRUE) . = ..() // update_use_power(ACTIVE_POWER_USE) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 8cc1e1fcbf36..859c0bb58679 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -131,10 +131,8 @@ return if(action == "switch_camera") - var/c_tag = params["name"] - var/list/cameras = get_available_cameras() - var/obj/machinery/camera/C = cameras[c_tag] - active_camera = C + var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras + active_camera = selected_camera playsound(src, get_sfx("terminal_type"), 25, FALSE) if(isnull(active_camera)) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index cb61915a19cf..cf4f9fca9fcb 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,8 +2,6 @@ // // The datum containing all the chunks. -#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. - GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -11,12 +9,11 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/cameras = list() + var/list/obj/machinery/camera/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick + /// List of images cloned by all chunk static images put onto turfs cameras cant see /// Indexed by the plane offset to use var/list/image/obscured_images @@ -40,21 +37,26 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + if(GET_LOWEST_STACK_OFFSET(z) != 0) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + return chunks["[x],[y],[lowest.z]"] + return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) - var/key = "[x],[y],[z]" + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + var/key = "[x],[y],[lowest.z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, z) + chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) -/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. +/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -65,21 +67,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() + //Get the eye's turf in case it's located in an object like a mecha + var/turf/eye_turf = get_turf(eye) if(eye.loc) - var/x_value = eye.x - var/y_value = eye.y - var/z_value = eye.z - // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) - + var/x1 = max(1, eye_turf.x - static_range) + var/y1 = max(1, eye_turf.y - static_range) + var/x2 = min(world.maxx, eye_turf.x + static_range) + var/y2 = min(world.maxy, eye_turf.y + static_range) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, z_value) + visibleChunks |= getCameraChunk(x, y, eye_turf.z) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -90,7 +89,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -111,10 +110,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) +/** + * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. + * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement + * to change the time between static updates. +*/ +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) + if(updating_camera.can_use()) + majorChunkChange(updating_camera, 1, update_delay_buffer) /** * Never access this proc directly!!!! @@ -122,37 +125,52 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement + * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice) - if(!c) - return +/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) + if(QDELETED(c) && choice == 1) + CRASH("Tried to add a qdeleting camera to the net") var/turf/T = get_turf(c) if(T) - var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras -= c + chunk.cameras["[T.z]"] -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() + chunk.cameras["[T.z]"] |= c + chunk.hasChanged(update_delay_buffer = update_delay_buffer) + +/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] +/// For use in sensitive code, be careful with it +/datum/cameranet/proc/bareMajorChunkChange(turf/changed) + var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) + for(var/y = y1; y <= y2; y += CHUNK_SIZE) + var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) + chunk?.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) + if(!position) + return return checkTurfVis(position) - /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -160,22 +178,25 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) +/datum/cameranet/proc/getTurfVis(turf/position) + RETURN_TYPE(/datum/camerachunk) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(!chunk) + return FALSE + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return chunk /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR + appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT - layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index c2178a5be5ba..6b108b586726 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -11,13 +11,13 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid + ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs + ///list of all turfs, associative with that turf's static image + ///turf -> /image var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() - ///images created to represent obscured turfs - var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() @@ -55,15 +55,19 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. + * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and + * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because + * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0) +/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/datum/camerachunk/proc/update() +/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below +/datum/camerachunk/proc/update(partial_update = FALSE) var/list/updated_visible_turfs = list() for(var/obj/machinery/camera/current_camera as anything in cameras) @@ -91,31 +95,24 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] - if(!static_image_to_deallocate) + var/image/static_image = obscuredTurfs[visible_turf] + if(!static_image) continue - static_image_to_deallocate.loc = null - active_static_images -= static_image_to_deallocate - inactive_static_images += static_image_to_deallocate - + active_static_images -= static_image obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] - if(!static_image_to_allocate) - stack_trace("somehow a camera chunk ran out of static images!") + var/image/static_image = turfs[obscured_turf] + if(!static_image) + stack_trace("somehow a camera chunk used a turf it didn't contain!!") break - obscuredTurfs[obscured_turf] = static_image_to_allocate - static_image_to_allocate.loc = obscured_turf - - inactive_static_images -= static_image_to_allocate - active_static_images += static_image_to_allocate - + obscuredTurfs[obscured_turf] = static_image + active_static_images += static_image visibleTurfs = updated_visible_turfs changed = FALSE @@ -129,8 +126,8 @@ /// Create a new camera chunk, since the chunks are made as they are needed. /datum/camerachunk/New(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) src.x = x src.y = y @@ -144,7 +141,7 @@ turfs[t] = t for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured_images) + active_static_images += new/image(GLOB.cameranet.obscured_images) for(var/obj/machinery/camera/camera as anything in cameras) if(!camera || !camera.can_use()) @@ -155,11 +152,10 @@ visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = inactive_static_images[inactive_static_images.len] + var/image/new_static = active_static_images[active_static_images.len] new_static.loc = obscured_turf active_static_images += new_static - inactive_static_images -= new_static + active_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME -#undef CHUNK_SIZE diff --git a/tgui/packages/tgui/interfaces/CameraConsole.tsx b/tgui/packages/tgui/interfaces/CameraConsole.tsx index 4feb31faaf67..7b898011f7f3 100644 --- a/tgui/packages/tgui/interfaces/CameraConsole.tsx +++ b/tgui/packages/tgui/interfaces/CameraConsole.tsx @@ -7,15 +7,16 @@ import { Button, ByondUi, Input, NoticeBox, Section, Stack } from '../components import { Window } from '../layouts'; type Data = { + activeCamera: Camera & { status: BooleanLike }; + cameras: Camera[]; can_spy: BooleanLike; mapRef: string; - cameras: Camera[]; - activeCamera: Camera & { status: BooleanLike }; network: string[]; }; type Camera = { name: string; + ref: string; }; /** @@ -26,13 +27,30 @@ const prevNextCamera = ( cameras: Camera[], activeCamera: Camera & { status: BooleanLike } ) => { - if (!activeCamera) { + if (!activeCamera || cameras.length < 2) { return []; } - const index = cameras.findIndex( - (camera) => camera?.name === activeCamera.name - ); - return [cameras[index - 1]?.name, cameras[index + 1]?.name]; + + const index = cameras.findIndex((camera) => camera.ref === activeCamera.ref); + + switch (index) { + case -1: // Current camera is not in the list + return [cameras[cameras.length - 1].ref, cameras[0].ref]; + + case 0: // First camera + if (cameras.length === 2) return [cameras[1].ref, cameras[1].ref]; // Only two + + return [cameras[cameras.length - 1].ref, cameras[index + 1].ref]; + + case cameras.length - 1: // Last camera + if (cameras.length === 2) return [cameras[0].ref, cameras[0].ref]; + + return [cameras[index - 1].ref, cameras[0].ref]; + + default: + // Middle camera + return [cameras[index - 1].ref, cameras[index + 1].ref]; + } }; /** @@ -44,15 +62,15 @@ const selectCameras = (cameras: Camera[], searchText = ''): Camera[] => { const testSearch = createSearch(searchText, (camera: Camera) => camera.name); return flow([ - // Null camera filter - filter((camera: Camera) => !!camera?.name), // Optional search term + filter((camera: Camera) => !!camera.name), + // Optional search term searchText && filter(testSearch), // Slightly expensive, but way better than sorting in BYOND - sortBy((camera: Camera) => camera.name), + sortBy((camera: Camera) => camera), ])(cameras); }; -export const CameraConsole = (props, context) => { +export const CameraConsole = (props) => { return ( @@ -62,7 +80,7 @@ export const CameraConsole = (props, context) => { ); }; -export const CameraContent = (props, context) => { +export const CameraContent = (props) => { return ( @@ -98,21 +116,20 @@ const CameraSelector = (props, context) => { // We're not using the component here because performance // would be absolutely abysmal (50+ ms for each re-render).
    act('switch_camera', { - name: camera.name, + camera: camera.ref, }) }> {camera.name} @@ -127,12 +144,11 @@ const CameraSelector = (props, context) => { const CameraControls = (props, context) => { const { act, data } = useBackend(context); const { activeCamera, can_spy, mapRef } = data; - const cameras = selectCameras(data.cameras); + const [searchText] = useLocalState(context, 'searchText', ''); - const [prevCameraName, nextCameraName] = prevNextCamera( - cameras, - activeCamera - ); + const cameras = selectCameras(data.cameras, searchText); + + const [prevCamera, nextCamera] = prevNextCamera(cameras, activeCamera); return (
    @@ -140,7 +156,7 @@ const CameraControls = (props, context) => { - {activeCamera?.name ? ( + {activeCamera?.status ? ( {activeCamera.name} ) : ( No input signal @@ -160,10 +176,10 @@ const CameraControls = (props, context) => {
    GoonStation 13 Development Team diff --git a/yogstation/code/game/gamemodes/gangs/dominator.dm b/yogstation/code/game/gamemodes/gangs/dominator.dm index d4b82ec6c01c..6faa286dc4c5 100644 --- a/yogstation/code/game/gamemodes/gangs/dominator.dm +++ b/yogstation/code/game/gamemodes/gangs/dominator.dm @@ -45,7 +45,7 @@ return ..() /obj/machinery/dominator/emp_act(severity) - gang.domination_time += 30 + gang.domination_time += 3 * severity ..() /obj/machinery/dominator/hulk_damage() diff --git a/yogstation/code/game/objects/items/wielded/sledgehammer.dm b/yogstation/code/game/objects/items/wielded/sledgehammer.dm index fccce03df081..9101954a7a3d 100644 --- a/yogstation/code/game/objects/items/wielded/sledgehammer.dm +++ b/yogstation/code/game/objects/items/wielded/sledgehammer.dm @@ -14,6 +14,7 @@ throwforce = 18 throw_range = 3 /// Doesn't throw very far sharpness = SHARP_NONE + demolition_mod = 3 // BREAK THINGS armour_penetration = -20 hitsound = 'sound/weapons/smash.ogg' /// Hitsound when thrown at someone attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed") @@ -54,8 +55,6 @@ var/obj/structure/S = target if(istype(S, /obj/structure/window)) // Sledgehammer really good at smashing windows. 2-7 hits to kill a window S.take_damage(S.max_integrity/2, BRUTE, MELEE, FALSE, null, armour_penetration) - else // Sledgehammer can kill airlocks in 17-23 hits, against most other things it's almost as good as a fireaxe - S.take_damage(force*2, BRUTE, MELEE, FALSE, null, armour_penetration) playsound(src, 'sound/effects/bang.ogg', 50, 1) /obj/item/melee/sledgehammer/throw_at(atom/target, range, speed, mob/thrower, spin, diagonals_first, datum/callback/callback, force, quickstart) diff --git a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm index 657c81b629db..b5e709874d34 100644 --- a/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm +++ b/yogstation/code/game/objects/items/wielded/vxtvulhammer.dm @@ -11,6 +11,7 @@ desc = "A relic sledgehammer with charge packs wired to two blast pads on its head. \ While wielded in two hands, the user can charge a massive blow that will shatter construction and hurl bodies." force = 4 //It's heavy as hell + demolition_mod = 3 // it's a big hammer, what do you expect armour_penetration = 50 //Designed for shattering walls in a single blow, I don't think it cares much about armor throwforce = 18 attack_verb = list("attacked", "hit", "struck", "bludgeoned", "bashed", "smashed") diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm index 0b65f1bc8ab4..590e174bc205 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/organs.dm @@ -113,5 +113,5 @@ /obj/item/organ/stomach/cell/preternis/emp_act(severity) owner.vomit(stun=FALSE) // fuck that - owner.adjust_disgust(20) + owner.adjust_disgust(2*severity) to_chat(owner, "You feel violently ill as the EMP causes your stomach to kick into high gear.") diff --git a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm index 22d0b677bcca..867ae2aa24df 100644 --- a/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm +++ b/yogstation/code/modules/mob/living/carbon/human/species_types/preternis/preternis.dm @@ -3,7 +3,7 @@ plural_form = "Preterni" id = "preternis" changesource_flags = MIRROR_BADMIN | WABBAJACK | MIRROR_PRIDE | MIRROR_MAGIC | RACE_SWAP | ERT_SPAWN | SLIME_EXTRACT - inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE, TRAIT_FARADAYCAGE) //Faraday cage reduces incoming EMP severity by one level + inherent_traits = list(TRAIT_POWERHUNGRY, TRAIT_RADIMMUNE, TRAIT_MEDICALIGNORE) species_traits = list(DYNCOLORS, EYECOLOR, HAIR, LIPS, AGENDER, NOHUSK, DIGITIGRADE)//they're fleshy metal machines, they are efficient, and the outside is metal, no getting husked inherent_biotypes = MOB_ORGANIC|MOB_ROBOTIC|MOB_HUMANOID sexes = FALSE //they're basically ken dolls, come straight out of a printer @@ -59,6 +59,7 @@ for (var/obj/item/bodypart/BP in C.bodyparts) BP.render_like_organic = TRUE // Makes limbs render like organic limbs instead of augmented limbs, check bodyparts.dm + BP.emp_reduction = EMP_LIGHT BP.burn_reduction = 2 BP.brute_reduction = 1 if(BP.body_zone == BODY_ZONE_CHEST) @@ -79,6 +80,7 @@ for (var/V in C.bodyparts) var/obj/item/bodypart/BP = V BP.change_bodypart_status(ORGAN_ORGANIC,FALSE,TRUE) + BP.emp_reduction = initial(BP.emp_reduction) BP.burn_reduction = initial(BP.burn_reduction) BP.brute_reduction = initial(BP.brute_reduction) @@ -294,6 +296,12 @@ var/list/to_add = list() to_add += list( + list( + SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, + SPECIES_PERK_ICON = "thunderstorm", //if we update font awesome, please swap to bolt-slash + SPECIES_PERK_NAME = "Faraday \"Skin\"", + SPECIES_PERK_DESC = "Preterni have an outer plasteel shell that can block low-intensity EM interference.", + ), list( SPECIES_PERK_TYPE = SPECIES_POSITIVE_PERK, SPECIES_PERK_ICON = "cookie-bite", diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm index 1fbbd5669f9a..84648cf40bd2 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/floor_cluwne.dm @@ -356,7 +356,7 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0) manifested = TRUE Manifest() if(!eating) - empulse(src, 6, 6) + empulse(src, EMP_HEAVY, 6) addtimer(CALLBACK(src, TYPE_PROC_REF(/mob/living/simple_animal/hostile/floor_cluwne, Grab), H), 50, TIMER_OVERRIDE|TIMER_UNIQUE) for(var/turf/open/O in range(src, 6)) O.MakeSlippery(TURF_WET_LUBE, 30) diff --git a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm index 557b9bdb4b4f..5661d84b28be 100644 --- a/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm +++ b/yogstation/code/modules/mob/living/simple_animal/hostile/retaliate/king_of_goats.dm @@ -214,7 +214,7 @@ Difficulty: Insanely Hard else if(prob(5)) //EMP blast spellscast++ visible_message(span_cult("\The [src] disrupts nearby electrical equipment!")) - empulse(get_turf(src), 5, 2, 0) + empulse(get_turf(src), EMP_HEAVY) else if(prob(5) && melee_damage_type == BRUTE && !special_attacks) //elemental attacks spellscast++ diff --git a/yogstation/code/modules/surgery/organs/heart.dm b/yogstation/code/modules/surgery/organs/heart.dm index 263fc0c63c2c..da98967b4da4 100644 --- a/yogstation/code/modules/surgery/organs/heart.dm +++ b/yogstation/code/modules/surgery/organs/heart.dm @@ -6,12 +6,6 @@ compatible_biotypes = ALL_BIOTYPES var/nanite_boost = 1 -/obj/item/organ/heart/nanite/emp_act() - . = ..() - if(!owner || . & EMP_PROTECT_SELF) - return . - Stop() - /obj/item/organ/heart/nanite/on_life() . = ..() if(owner)//makes nanites tick on every life tick, only about 33% speed increase From d383311e39239ed5e9ce1a773791c2c3f8557533 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:30:57 -0500 Subject: [PATCH 110/144] proves to god I exist and im pissed --- code/modules/surgery/organs/augments_chest.dm | 2 +- code/modules/surgery/organs/eyes.dm | 113 ++++++++++++------ 2 files changed, 79 insertions(+), 36 deletions(-) diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 0ab2df136add..c58ac8b27f2f 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -337,7 +337,7 @@ owner.set_drugginess(4 * severity) owner.adjust_hallucinations((50 * severity) SECONDS) - owner.blur_eyes(2 * severity) + owner.adjust_eye_blur(2 * severity) owner.adjust_dizzy(severity SECONDS) time_on += severity owner.adjustFireLoss(severity) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index b295459a9090..755be018ecab 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -20,14 +20,16 @@ low_threshold_cleared = span_info("Your vision is cleared of any ailment.") var/sight_flags = 0 - var/see_in_dark = 2 var/tint = 0 var/eye_color = "" //set to a hex code to override a mob's eye color var/eye_icon_state = "eyes" var/old_eye_color = "fff" var/flash_protect = 0 var/see_invisible = SEE_INVISIBLE_LIVING - var/lighting_alpha + /// How much darkness to cut out of your view (basically, night vision) + var/lighting_cutoff = null + /// List of color cutoffs from eyes, or null if not applicable + var/list/color_cutoffs = null var/no_glasses var/damaged = TRUE //damaged indicates that our eyes are undergoing some level of negative effect,starts as true so it removes the impaired vision overlay if it is replacing damaged eyes @@ -40,8 +42,6 @@ HMN.eye_color = eye_color else eye_color = HMN.eye_color - if(HAS_TRAIT(HMN, TRAIT_NIGHT_VISION) && !lighting_alpha) - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT M.update_tint() owner.update_sight() if(M.has_dna() && ishuman(M)) @@ -55,7 +55,7 @@ HMN.update_body() M.cure_blind(list(EYE_DAMAGE)) // can't be blind from eye damage if there's no eye to be damaged, still blind from not having eyes though M.cure_nearsighted(list(EYE_DAMAGE)) // likewise for nearsightedness - M.set_blurriness(0) // no eyes to blur + M.set_eye_blur(0) // no eyes to blur M.update_tint() M.update_sight() @@ -117,48 +117,80 @@ #undef OFFSET_X #undef OFFSET_Y +#define NIGHTVISION_LIGHT_OFF 0 +#define NIGHTVISION_LIGHT_LOW 1 +#define NIGHTVISION_LIGHT_MID 2 +#define NIGHTVISION_LIGHT_HIG 3 + /obj/item/organ/eyes/night_vision name = "shadow eyes" desc = "A spooky set of eyes that can see in the dark." - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + actions_types = list(/datum/action/item_action/organ_action/use) - var/night_vision = TRUE + // These lists are used as the color cutoff for the eye + // They need to be filled out for subtypes + var/list/low_light_cutoff + var/list/medium_light_cutoff + var/list/high_light_cutoff + var/light_level = NIGHTVISION_LIGHT_OFF + +/obj/item/organ/eyes/night_vision/Initialize(mapload) + . = ..() + + if(length(low_light_cutoff) != 3 || length(medium_light_cutoff) != 3 || length(high_light_cutoff) != 3) + stack_trace("[type] did not have fully filled out color cutoff lists") + if(low_light_cutoff) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW /obj/item/organ/eyes/night_vision/ui_action_click() sight_flags = initial(sight_flags) - switch(lighting_alpha) - if (LIGHTING_PLANE_ALPHA_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - if (LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE) - lighting_alpha = LIGHTING_PLANE_ALPHA_INVISIBLE + switch(light_level) + if (NIGHTVISION_LIGHT_OFF) + color_cutoffs = low_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_LOW + if (NIGHTVISION_LIGHT_LOW) + color_cutoffs = medium_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_MID + if (NIGHTVISION_LIGHT_MID) + color_cutoffs = high_light_cutoff.Copy() + light_level = NIGHTVISION_LIGHT_HIG else - lighting_alpha = LIGHTING_PLANE_ALPHA_VISIBLE - sight_flags &= ~SEE_BLACKNESS + color_cutoffs = null + light_level = NIGHTVISION_LIGHT_OFF owner.update_sight() -/obj/item/organ/eyes/night_vision/alien +#undef NIGHTVISION_LIGHT_OFF +#undef NIGHTVISION_LIGHT_LOW +#undef NIGHTVISION_LIGHT_MID +#undef NIGHTVISION_LIGHT_HIG + +/obj/item/organ/eyes/night_vision/mushroom + name = "fung-eye" + desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + low_light_cutoff = list(0, 15, 20) + medium_light_cutoff = list(0, 20, 35) + high_light_cutoff = list(0, 40, 50) + +//innate nightvision eyes +/obj/item/organ/eyes/alien name = "alien eyes" desc = "It turned out they had them after all!" sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) -/obj/item/organ/eyes/night_vision/zombie +/obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) -/obj/item/organ/eyes/night_vision/nightmare +/obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" - -/obj/item/organ/eyes/night_vision/mushroom - name = "fung-eye" - desc = "While on the outside they look inert and dead, the eyes of mushroom people are actually very advanced." + color_cutoffs = list(20, 10, 40) ///Robotic - /obj/item/organ/eyes/robotic name = "robotic eyes" icon_state = "cybernetic_eyeballs" @@ -171,19 +203,21 @@ . = ..() if(!owner || . & EMP_PROTECT_SELF) return + var/obj/item/organ/eyes/eyes = owner.getorganslot(ORGAN_SLOT_EYES) to_chat(owner, span_danger("your eyes overload and blind you!")) owner.flash_act(override_blindness_check = 1) - owner.blind_eyes(severity / 2) - owner.blur_eyes(8) - applyOrganDamage(2 * severity) + owner.blind_eyes(5) + owner.adjust_eye_blur(8) + eyes.applyOrganDamage(20 / severity) /obj/item/organ/eyes/robotic/xray name = "\improper meson eyes" desc = "These cybernetic eyes will give you meson-vision. Looks like it could withstand seeing a supermatter crystal!." eye_color = "00FF00" - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) sight_flags = SEE_TURFS - see_in_dark = 4 + /obj/item/organ/eyes/robotic/xray/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE, initialising) . = ..() @@ -198,16 +232,15 @@ desc = "These cybernetic eyes will give you true X-ray vision. Blinking is futile." eye_color = "000" sight_flags = SEE_MOBS | SEE_OBJS | SEE_TURFS - see_in_dark = 8 /obj/item/organ/eyes/robotic/thermals name = "thermal eyes" desc = "These cybernetic eye implants will give you thermal vision. Vertical slit pupil included." eye_color = "FC0" sight_flags = SEE_MOBS - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE + // We're gonna downshift green and blue a bit so darkness looks yellow + color_cutoffs = list(25, 8, 5) flash_protect = -1 - see_in_dark = 8 /obj/item/organ/eyes/robotic/flashlight name = "flashlight eyes" @@ -454,5 +487,15 @@ /obj/item/organ/eyes/polysmorph name = "polysmorph eyes" desc = "Eyes from a polysmorph, capable of retaining slightly more vision in low light environments" - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT - see_in_dark = 5 + color_cutoffs = list(25, 5, 42) + +/obj/item/organ/eyes/zombie + name = "undead eyes" + desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." + color_cutoffs = list(25, 35, 5) + +/obj/item/organ/eyes/alien + name = "alien eyes" + desc = "It turned out they had them after all!" + sight_flags = SEE_MOBS + color_cutoffs = list(25, 5, 42) From 841d19b976cab24a45469d4f5249c0a83299a19f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:37:35 -0500 Subject: [PATCH 111/144] yog exclusive feature (tm) plane master --- code/__DEFINES/layers.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 1c98b16882f4..fafbbc3225c7 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -74,10 +74,6 @@ ///Pipecrawling images #define PIPECRAWL_IMAGES_PLANE 20 -///AI Camera Static -#define CAMERA_STATIC_LAYER 40 -#define CAMERA_STATIC_PLANE 40 - ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else #define HIGH_GAME_PLANE 22 @@ -90,6 +86,10 @@ /// Plane for balloon text (text that fades up) #define BALLOON_CHAT_PLANE 31 +///AI Camera Static -- YOG +#define CAMERA_STATIC_LAYER 40 +#define CAMERA_STATIC_PLANE 40 + //-------------------- HUD --------------------- //HUD layer defines #define HUD_PLANE 40 From 443d5ca195022b27c4a758a4fb8b7fe064962d88 Mon Sep 17 00:00:00 2001 From: Molti Date: Mon, 4 Dec 2023 19:50:04 -0600 Subject: [PATCH 112/144] bring this back from previous push --- code/modules/surgery/organs/eyes.dm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 755be018ecab..cbfcc08db923 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -178,17 +178,20 @@ desc = "It turned out they had them after all!" sight_flags = SEE_MOBS color_cutoffs = list(25, 5, 42) + lighting_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/organ/eyes/zombie name = "undead eyes" desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human." color_cutoffs = list(25, 35, 5) + lighting_cutoff = LIGHTING_CUTOFF_HIGH /obj/item/organ/eyes/shadow name = "burning red eyes" desc = "Even without their shadowy owner, looking at these eyes gives you a sense of dread." icon_state = "burning_eyes" color_cutoffs = list(20, 10, 40) + lighting_cutoff = LIGHTING_CUTOFF_HIGH ///Robotic /obj/item/organ/eyes/robotic From 67c7c23a768481e2fa89952ab1dc5bc100dbe57f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:08:00 -0500 Subject: [PATCH 113/144] updates vendor emissives as well as firealarms --- _maps/_basemap.dm | 2 +- code/__DEFINES/layers.dm | 1 + code/game/machinery/firealarm.dm | 9 +++++++++ .../structures/crates_lockers/closets.dm | 5 +++++ code/modules/vending/_vending.dm | 17 +++++++++++++++++ code/modules/vending/assist.dm | 3 +++ code/modules/vending/autodrobe.dm | 2 ++ code/modules/vending/boozeomat.dm | 2 ++ code/modules/vending/cartridge.dm | 2 ++ code/modules/vending/cigarette.dm | 2 ++ code/modules/vending/clothesmate.dm | 2 ++ code/modules/vending/coffee.dm | 2 ++ code/modules/vending/cola.dm | 16 ++++++++++++++++ code/modules/vending/dinnerware.dm | 2 ++ code/modules/vending/engineering.dm | 4 +++- code/modules/vending/engivend.dm | 2 ++ code/modules/vending/games.dm | 2 ++ code/modules/vending/liberation.dm | 4 +++- code/modules/vending/liberation_toy.dm | 2 ++ code/modules/vending/magivend.dm | 2 ++ code/modules/vending/medical.dm | 2 ++ code/modules/vending/medical_wall.dm | 2 ++ code/modules/vending/megaseed.dm | 2 ++ code/modules/vending/modularpc.dm | 2 ++ code/modules/vending/nutrimax.dm | 4 +++- code/modules/vending/robotics.dm | 2 ++ code/modules/vending/security.dm | 2 ++ code/modules/vending/snack.dm | 2 ++ code/modules/vending/sovietsoda.dm | 4 +++- code/modules/vending/sustenance.dm | 2 ++ code/modules/vending/toys.dm | 2 ++ code/modules/vending/wardrobes.dm | 3 +++ code/modules/vending/youtool.dm | 2 ++ icons/obj/monitors.dmi | Bin 17892 -> 18908 bytes icons/obj/power.dmi | Bin 30291 -> 30501 bytes icons/obj/vending.dmi | Bin 113419 -> 120054 bytes icons/obj/wallmounts.dmi | Bin 4414 -> 4690 bytes 37 files changed, 109 insertions(+), 5 deletions(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index 48b96c8948f7..aadbfa88a035 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index fafbbc3225c7..863ade0a5012 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -49,6 +49,7 @@ #define O_LIGHTING_VISUAL_PLANE 11 #define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE" +#define EMISSIVE_LAYER 13 #define EMISSIVE_PLANE 13 /// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas. #define EMISSIVE_RENDER_PLATE 14 diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 99b5a4987ec9..9a25df359b09 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -29,6 +29,8 @@ light_power = 0 light_range = 7 light_color = "#ff3232" + //Trick to get the glowing overlay visible from a distance + luminosity = 1 /// 1 = will auto detect fire, 0 = no auto var/detecting = 1 @@ -92,10 +94,13 @@ . += "fire_[GLOB.security_level]" SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", layer, plane, dir) SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", layer, EMISSIVE_PLANE, dir) + . += emissive_appearance(icon, "fire_level_e", src, alpha = src.alpha) else . += "fire_[SEC_LEVEL_GREEN]" SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", layer, plane, dir) SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", layer, EMISSIVE_PLANE, dir) + . += emissive_appearance(icon, "fire_level_e", src, alpha = src.alpha) + set_light(l_color = LIGHT_COLOR_BLUE) var/area/A = src.loc A = A.loc @@ -108,10 +113,14 @@ . += "fire_emagged" SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", layer, plane, dir) SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", layer, EMISSIVE_PLANE, dir) + . += emissive_appearance(icon, "fire_alerting_e", src, alpha = src.alpha) + set_light(l_color = LIGHT_COLOR_RED) else . += "fire_on" SSvis_overlays.add_vis_overlay(src, icon, "fire_on", layer, plane, dir) SSvis_overlays.add_vis_overlay(src, icon, "fire_on", layer, EMISSIVE_PLANE, dir) + . += emissive_appearance(icon, "fire_alerting_e", src, alpha = src.alpha) + set_light(l_color = LIGHT_COLOR_RED) /obj/machinery/firealarm/emp_act(severity) . = ..() diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 66d75d7e3125..16f0459abe58 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -86,6 +86,8 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/update_overlays() . = ..() + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + luminosity = 0 if(opened) layer = BELOW_OBJ_LAYER if(is_animating_door) @@ -105,6 +107,9 @@ GLOBAL_LIST_EMPTY(lockers) if(welded) . += icon_welded if(secure && !broken) + //Overlay is similar enough for both that we can use the same mask for both + luminosity = 1 + SSvis_overlays.add_vis_overlay(src, icon, "locked", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha) if(locked) . += "locked" else diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index 87f510ce3c10..e93b30dd9af8 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -92,6 +92,8 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/forcecrit = 0 var/num_shards = 7 var/list/pinned_mobs = list() + light_power = 0.5 + light_range = MINIMUM_USEFUL_LIGHT_RANGE /** @@ -185,6 +187,9 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C /// how many items have been inserted in a vendor var/loaded_items = 0 + ///Name of lighting mask for the vending machine + var/light_mask + /// used for narcing on underages var/obj/item/radio/alertradio @@ -270,12 +275,24 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C . = ..() if(stat & BROKEN) icon_state = "[initial(icon_state)]-broken" + set_light(0) return if(powered()) icon_state = initial(icon_state) + set_light(1.4) else icon_state = "[initial(icon_state)]-off" + set_light(0) + +/obj/machinery/vending/update_overlays() + . = ..() + if(!light_mask) + return + + SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + if(!(stat & BROKEN) && powered()) + SSvis_overlays.add_vis_overlay(src, icon, light_mask, EMISSIVE_LAYER, EMISSIVE_PLANE) /obj/machinery/vending/obj_break(damage_flag) diff --git a/code/modules/vending/assist.dm b/code/modules/vending/assist.dm index 3a5c4c0bb1c4..a710699ae542 100644 --- a/code/modules/vending/assist.dm +++ b/code/modules/vending/assist.dm @@ -13,8 +13,11 @@ product_ads = "Only the finest!;Have some tools.;The most robust equipment.;The finest gear in space!" default_price = 10 extra_price = 50 + light_mask = "generic-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = NO_FREEBIES /obj/item/vending_refill/assist machine_name = "Vendomat" icon_state = "refill_engi" + diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm index 2cd504b0cbc7..d61713292d39 100644 --- a/code/modules/vending/autodrobe.dm +++ b/code/modules/vending/autodrobe.dm @@ -232,6 +232,8 @@ /obj/item/clothing/mask/yogs/richard = 1) //yogs end refill_canister = /obj/item/vending_refill/autodrobe default_price = 50 + light_mask="theater-light-mask" + light_color = LIGHT_COLOR_BLUE extra_price = 75 payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/boozeomat.dm b/code/modules/vending/boozeomat.dm index 06b9519e5fc7..e9eb31b62131 100644 --- a/code/modules/vending/boozeomat.dm +++ b/code/modules/vending/boozeomat.dm @@ -48,6 +48,8 @@ req_access = list(ACCESS_BAR) refill_canister = /obj/item/vending_refill/boozeomat default_price = 20 + light_mask = "boozeomat-light-mask" + light_color = LIGHT_COLOR_BLUE extra_price = 50 payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/cartridge.dm b/code/modules/vending/cartridge.dm index dd08f9011069..2d719dda31c2 100644 --- a/code/modules/vending/cartridge.dm +++ b/code/modules/vending/cartridge.dm @@ -10,6 +10,8 @@ default_price = 50 extra_price = 100 payment_department = ACCOUNT_SRV + light_mask="cart-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/item/vending_refill/cart machine_name = "PTech" diff --git a/code/modules/vending/cigarette.dm b/code/modules/vending/cigarette.dm index e86c6985e87d..31c7053a6d79 100644 --- a/code/modules/vending/cigarette.dm +++ b/code/modules/vending/cigarette.dm @@ -22,6 +22,8 @@ refill_canister = /obj/item/vending_refill/cigarette default_price = 10 extra_price = 50 + light_mask = "cigs-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/machinery/vending/cigarette/syndicate diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index dc53821bdcba..e3046000e24a 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -216,6 +216,8 @@ refill_canister = /obj/item/vending_refill/clothing default_price = 50 extra_price = 75 + light_mask = "wardrobe-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = NO_FREEBIES /obj/machinery/vending/clothing/canLoadItem(obj/item/I,mob/user) diff --git a/code/modules/vending/coffee.dm b/code/modules/vending/coffee.dm index 007135a5ef80..8afc43e7423c 100644 --- a/code/modules/vending/coffee.dm +++ b/code/modules/vending/coffee.dm @@ -11,6 +11,8 @@ refill_canister = /obj/item/vending_refill/coffee default_price = 10 extra_price = 25 + light_mask = "coffee-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/coffee machine_name = "Solar's Best Hot Drinks" diff --git a/code/modules/vending/cola.dm b/code/modules/vending/cola.dm index ba76ed700420..ae616c386d13 100644 --- a/code/modules/vending/cola.dm +++ b/code/modules/vending/cola.dm @@ -46,36 +46,50 @@ /obj/machinery/vending/cola/blue icon_state = "Cola_Machine" + light_mask = "cola-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/black icon_state = "cola_black" + light_mask = "cola-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/red icon_state = "red_cola" name = "\improper Space Cola Vendor" desc = "It vends cola, in space." product_slogans = "Cola in space!" + light_mask = "red_cola-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/space_up icon_state = "space_up" name = "\improper Space-up! Vendor" desc = "Indulge in an explosion of flavor." product_slogans = "Space-up! Like a hull breach in your mouth." + light_mask = "space_up-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/starkist icon_state = "starkist" name = "\improper Star-kist Vendor" desc = "The taste of a star in liquid form." product_slogans = "Drink the stars! Star-kist!" + light_mask = "starkist-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/sodie icon_state = "soda" + light_mask = "soda-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/pwr_game icon_state = "pwr_game" name = "\improper Pwr Game Vendor" desc = "You want it, we got it. Brought to you in partnership with Vlad's Salads." product_slogans = "The POWER that gamers crave! PWR GAME!" + light_mask = "pwr_game-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/shamblers name = "\improper Shambler's Vendor" @@ -91,6 +105,8 @@ /obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 10) product_slogans = "~Shake me up some of that Shambler's Juice!~" product_ads = "Refreshing!;Jyrbv dv lg jfdv fw kyrk Jyrdscvi'j Alztv!;Over 1 trillion souls drank!;Thirsty? Nyp efk uizeb kyv uribevjj?;Kyv Jyrdscvi uizebj kyv ezxyk!;Drink up!;Krjkp." + light_mask = "shamblers-light-mask" + light_color = LIGHT_COLOR_BLUE /obj/machinery/vending/cola/shamblers/prison products = list(/obj/item/reagent_containers/food/drinks/soda_cans/shamblers = 80) diff --git a/code/modules/vending/dinnerware.dm b/code/modules/vending/dinnerware.dm index ee2ac944ee1d..b073ae8925cd 100644 --- a/code/modules/vending/dinnerware.dm +++ b/code/modules/vending/dinnerware.dm @@ -28,6 +28,8 @@ refill_canister = /obj/item/vending_refill/dinnerware default_price = 5 extra_price = 50 + light_mask = "dinnerware-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/dinnerware diff --git a/code/modules/vending/engineering.dm b/code/modules/vending/engineering.dm index 0dbc4254676d..eb5ed6cefec4 100644 --- a/code/modules/vending/engineering.dm +++ b/code/modules/vending/engineering.dm @@ -30,8 +30,10 @@ refill_canister = /obj/item/vending_refill/engineering default_price = 50 extra_price = 60 + light_mask = "engi-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_ENG /obj/item/vending_refill/engineering machine_name = "Robco Tool Maker" - icon_state = "refill_engi" \ No newline at end of file + icon_state = "refill_engi" diff --git a/code/modules/vending/engivend.dm b/code/modules/vending/engivend.dm index b04c44f6e54d..6369d8a82dec 100644 --- a/code/modules/vending/engivend.dm +++ b/code/modules/vending/engivend.dm @@ -27,6 +27,8 @@ refill_canister = /obj/item/vending_refill/engivend default_price = 20 extra_price = 50 + light_mask = "engivend-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_ENG /obj/item/vending_refill/engivend diff --git a/code/modules/vending/games.dm b/code/modules/vending/games.dm index 2ea25268a052..9b66dad95693 100644 --- a/code/modules/vending/games.dm +++ b/code/modules/vending/games.dm @@ -24,6 +24,8 @@ refill_canister = /obj/item/vending_refill/games default_price = 10 extra_price = 25 + light_mask = "games-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/games diff --git a/code/modules/vending/liberation.dm b/code/modules/vending/liberation.dm index d500661b5821..2c18d040d754 100644 --- a/code/modules/vending/liberation.dm +++ b/code/modules/vending/liberation.dm @@ -30,4 +30,6 @@ resistance_flags = FIRE_PROOF default_price = 50 extra_price = 100 - payment_department = ACCOUNT_SEC \ No newline at end of file + light_mask = "liberation-light-mask" + light_color = LIGHT_COLOR_BLUE + payment_department = ACCOUNT_SEC diff --git a/code/modules/vending/liberation_toy.dm b/code/modules/vending/liberation_toy.dm index 141df9a93cae..d91daf5af144 100644 --- a/code/modules/vending/liberation_toy.dm +++ b/code/modules/vending/liberation_toy.dm @@ -29,4 +29,6 @@ refill_canister = /obj/item/vending_refill/donksoft default_price = 25 extra_price = 50 + light_mask = "donksoft-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/magivend.dm b/code/modules/vending/magivend.dm index 016b06d9bae9..f10b9852c70a 100644 --- a/code/modules/vending/magivend.dm +++ b/code/modules/vending/magivend.dm @@ -18,4 +18,6 @@ resistance_flags = FIRE_PROOF default_price = 25 extra_price = 50 + light_color = LIGHT_COLOR_BLUE + light_mask = "magivend-light-mask" payment_department = ACCOUNT_SRV diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index d646b9e628ca..83b2b14491b0 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -43,6 +43,8 @@ refill_canister = /obj/item/vending_refill/medical default_price = 25 extra_price = 100 + light_color = LIGHT_COLOR_BLUE + light_mask = "med-light-mask" payment_department = ACCOUNT_MED /obj/item/vending_refill/medical diff --git a/code/modules/vending/medical_wall.dm b/code/modules/vending/medical_wall.dm index ffcc66dd08c6..67a6d3a7d334 100644 --- a/code/modules/vending/medical_wall.dm +++ b/code/modules/vending/medical_wall.dm @@ -18,6 +18,8 @@ refill_canister = /obj/item/vending_refill/wallmed default_price = 25 extra_price = 100 + light_mask = "wallmed-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_MED /obj/item/vending_refill/wallmed diff --git a/code/modules/vending/megaseed.dm b/code/modules/vending/megaseed.dm index b26cc8daebc0..3d55ddbebd24 100644 --- a/code/modules/vending/megaseed.dm +++ b/code/modules/vending/megaseed.dm @@ -63,6 +63,8 @@ refill_canister = /obj/item/vending_refill/hydroseeds default_price = 10 extra_price = 50 + light_mask = "seeds-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/hydroseeds diff --git a/code/modules/vending/modularpc.dm b/code/modules/vending/modularpc.dm index b44b4ce5a651..1b3425963500 100644 --- a/code/modules/vending/modularpc.dm +++ b/code/modules/vending/modularpc.dm @@ -26,6 +26,8 @@ refill_canister = /obj/item/vending_refill/modularpc default_price = 30 extra_price = 250 + light_color = LIGHT_COLOR_BLUE + light_mask = "modular-light-mask" payment_department = ACCOUNT_SCI /obj/item/vending_refill/modularpc diff --git a/code/modules/vending/nutrimax.dm b/code/modules/vending/nutrimax.dm index d3741f7f8529..66d4d34f83a8 100644 --- a/code/modules/vending/nutrimax.dm +++ b/code/modules/vending/nutrimax.dm @@ -19,8 +19,10 @@ refill_canister = /obj/item/vending_refill/hydronutrients default_price = 10 extra_price = 50 + light_mask = "nutri-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/hydronutrients machine_name = "NutriMax" - icon_state = "refill_plant" \ No newline at end of file + icon_state = "refill_plant" diff --git a/code/modules/vending/robotics.dm b/code/modules/vending/robotics.dm index e49d45141ef1..864811785a3e 100644 --- a/code/modules/vending/robotics.dm +++ b/code/modules/vending/robotics.dm @@ -17,6 +17,8 @@ default_price = 50 extra_price = 75 payment_department = ACCOUNT_SCI + light_color = LIGHT_COLOR_BLUE + light_mask = "robotics-light-mask" /obj/item/vending_refill/robotics machine_name = "Robotech Deluxe" diff --git a/code/modules/vending/security.dm b/code/modules/vending/security.dm index ed5bf1b84d89..f28f4c87ad0f 100644 --- a/code/modules/vending/security.dm +++ b/code/modules/vending/security.dm @@ -27,6 +27,8 @@ refill_canister = /obj/item/vending_refill/security default_price = 100 extra_price = 150 + light_mask = "sec-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SEC /obj/machinery/vending/security/pre_throw(obj/item/I) diff --git a/code/modules/vending/snack.dm b/code/modules/vending/snack.dm index 33ad829b4c9a..e40f8963c560 100644 --- a/code/modules/vending/snack.dm +++ b/code/modules/vending/snack.dm @@ -23,6 +23,8 @@ default_price = 20 extra_price = 30 payment_department = ACCOUNT_SRV + light_color = LIGHT_COLOR_BLUE + light_mask = "snack-light-mask" input_display_header = "Chef's Food Selection" /obj/item/vending_refill/snack diff --git a/code/modules/vending/sovietsoda.dm b/code/modules/vending/sovietsoda.dm index 01832df2855a..599ed04a9bbc 100644 --- a/code/modules/vending/sovietsoda.dm +++ b/code/modules/vending/sovietsoda.dm @@ -9,8 +9,10 @@ refill_canister = /obj/item/vending_refill/sovietsoda default_price = 1 extra_price = 1 + light_mask = "soviet-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = NO_FREEBIES /obj/item/vending_refill/sovietsoda machine_name = "BODA" - icon_state = "refill_cola" \ No newline at end of file + icon_state = "refill_cola" diff --git a/code/modules/vending/sustenance.dm b/code/modules/vending/sustenance.dm index 266a58e10ab0..4004bf67a870 100644 --- a/code/modules/vending/sustenance.dm +++ b/code/modules/vending/sustenance.dm @@ -14,6 +14,8 @@ refill_canister = /obj/item/vending_refill/sustenance default_price = 0 extra_price = 0 + light_color = LIGHT_COLOR_BLUE + light_mask = "snack-light-mask" payment_department = NO_FREEBIES /obj/item/vending_refill/sustenance diff --git a/code/modules/vending/toys.dm b/code/modules/vending/toys.dm index 92a1419fea2e..8125f581d8a9 100644 --- a/code/modules/vending/toys.dm +++ b/code/modules/vending/toys.dm @@ -35,6 +35,8 @@ refill_canister = /obj/item/vending_refill/donksoft default_price = 25 extra_price = 50 + light_mask = "donksoft-light-mask" + light_color = LIGHT_COLOR_BLUE payment_department = ACCOUNT_SRV /obj/item/vending_refill/donksoft diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm index 97e8716b0b14..baa0e924006c 100644 --- a/code/modules/vending/wardrobes.dm +++ b/code/modules/vending/wardrobes.dm @@ -6,6 +6,9 @@ extra_price = 75 payment_department = NO_FREEBIES input_display_header = "Returned Clothing" + light_mask = "wardrobe-light-mask" + light_color = LIGHT_COLOR_BLUE + /obj/machinery/vending/wardrobe/canLoadItem(obj/item/I,mob/user) if(I.type in products) diff --git a/code/modules/vending/youtool.dm b/code/modules/vending/youtool.dm index 4d90076586e9..159984db340e 100644 --- a/code/modules/vending/youtool.dm +++ b/code/modules/vending/youtool.dm @@ -24,4 +24,6 @@ resistance_flags = FIRE_PROOF default_price = 20 extra_price = 80 + light_color = LIGHT_COLOR_BLUE + light_mask = "tool-light-mask" payment_department = ACCOUNT_ENG diff --git a/icons/obj/monitors.dmi b/icons/obj/monitors.dmi index 06e2f8782ab04c878d87734d284be87935603add..860a11a75ed5e57cb08276254325ae7fe103ee5c 100644 GIT binary patch literal 18908 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 literal 17892 zcmcJ%bzGEf*ETwUfP$3LEe0qJDj+d~f+!$hk{k`x0eS5$A`(v27`kZsEa~;Pz)*3=J)Rd?wSSdgt5Y^Ks3NJt)q9)*# zaghwzBRgDm8`wzldZq26VCHPu zxo==@3n)_K$#?12+bmib`hbxzgx{IJ<5`<9!@f`zbQuLRQ7<1F)F* z%^S32g)g%Nl*Q{^9y5Qqz?gNV_K30Y)6+S5;@Hh)-CvXP#B3AY#aASraGT4alTamo zn5&cN!S6-c)f3&)k~rr^-!_v|pL9QbMzhMR(gc5KRorNe^RyMZ_acm@cA|nj)hysD z$FsxQ%}39?W|3jFS0tuu?tV&{OpkEtF)t}%y0pMT~X=DR>m zPr|d&6QBRE?Dlrgj?~Y)S9B&IKU{Sx5&1TCc0b#l;!Nq-E+OpvN<&s{)+@K>UTr+I zcQ1Q!$AyXJt7TlZafOW{k37|-n`oTrzAADcwZ`3ir!O_>tln_d!KnsrzT=BX8pL`a zJx#jbUQtj`D7{VLMHUhg5)e}Yx_`goPK{bq_;H4j2&_gFR?{6rxT#5V7uYQfU3JVq z4bO{59`c*m&CiA(Uwl|O)N-m*pJI=+7tBu&#CX5Q^nQZ%c~B3b!Z^l-A6nYHdyU_Y zM`fblrmrvAZd(+4pIyy7V~>1R&@-}vfb?@{CCV9ydS2dngVh+vnB)5p2`ubaDpCC* znBI6;4`;?jgu1&Bl&@TmMD0N4H1X)s?YVN%m_hWKv#b?(JnXxo2X5AWPZ#A~>m9zw zY;NHTM%r_s-GedS!I)K{ZCcCKZn^SEX**277w4BmAlT7r^t)pmjxZBRc2kLv zjq*GYy@{Y~&K^AEOV&(yH)>-Oa356x#qd6ZQ|836s_dgvhY%)4{>tYk-v%IdhVq2}fap%3ndhMAfH_pz{3 z!+_Dk3s`j@sqOiS6~r?P?Amhrs2S~)+?z>oy#e}^L3D44Ng>f33^iUa9jmT8l8<}# z{lJ$qu=IBP`Idlw<@BDl7Os6XjU(6s-v>_UZ2f?d*1CvUeFfUynhx?jp6EJh9U`}6 zK<=at{vK=7ba8h*k#^?X+dq*;Ti^|3cm)#S;(;;n^=m^j%D0l_FqI#lHc6o+u7GKA z;~&Q|-}4nq51PHaI<&w*?Dhqf^i>MyAQ#RcE9x!f19+}6Bnj!I(jv;mbTPJ`DSh1gEu(R zn9=BwYSM2^(Vg+#6VE8y8I5E(weGCS#-Pu{2(S7O-hE*AK13aM^azwZQ53>bBq|!# zxs+@8LM*A=Cvw!W4jvoN5MSu4db4e? z(1U&5myWSGg*Rb?6-8majS!+u{UP9?&Idku!QAD-KcVq2#0=)#VP_}Tlwj?fAfwTZ zk^D^7BwR?A6Lr(1&y20}TV#3|=4T>71euP*7!QCq&1h8;3dRd1=<4F#2(>k8?Uu&_ ztDwuMo@rd2_p0->_1s8$SARKa^{z9`^5KIFV4Pco?qflwdhi)q>7}mON&sLrjod4)7aCk(kIoim8za1b#Fbn9yZOGq1R{Fj!lB&h0((GSV0

    Mc{(!=G^?Hbl2Rbtj7Y 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

    8x0rShtl&|Po6!*zUhNX7@uEx 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

    KF;ME#u(*Km6cZJ(sKOIEtWmwl-F^= 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 OfSan?DtSn=SN{k63WwDI literal 113419 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 z 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�b7+ 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 literal 4414 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 Date: Tue, 5 Dec 2023 14:44:00 -0500 Subject: [PATCH 114/144] Updates barsign and fucks everything up --- _maps/map_files/generic/CentCom.dmm | 33 +- code/__DEFINES/directional.dm | 37 ++ code/datums/components/wall_mounted.dm | 59 ++ code/game/atoms_movable.dm | 8 + code/game/machinery/barsigns.dm | 487 ++++++++++++++++ code/game/objects/structures/barsigns.dm | 682 +++++++++++------------ icons/obj/barsigns.dmi | Bin 159072 -> 210663 bytes yogstation.dme | 2 + 8 files changed, 939 insertions(+), 369 deletions(-) create mode 100644 code/datums/components/wall_mounted.dm create mode 100644 code/game/machinery/barsigns.dm diff --git a/_maps/map_files/generic/CentCom.dmm b/_maps/map_files/generic/CentCom.dmm index 60a5237310a9..79566761613e 100644 --- a/_maps/map_files/generic/CentCom.dmm +++ b/_maps/map_files/generic/CentCom.dmm @@ -14882,9 +14882,6 @@ /turf/open/floor/carpet/black, /area/centcom/holding) "aFc" = ( -/obj/structure/sign/barsign{ - pixel_y = 32 - }, /obj/structure/chair/stool, /turf/open/floor/carpet/black, /area/centcom/holding) @@ -16347,22 +16344,8 @@ /turf/open/floor/holofloor, /area/holodeck/rec_center/basketball) "aHM" = ( -/obj/structure/chair, -/obj/effect/landmark/thunderdome/observe, -/obj/structure/sign/barsign{ - pixel_y = 32 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, -/turf/open/floor/plasteel/dark, +/obj/machinery/barsign, +/turf/closed/indestructible/riveted, /area/tdome/tdomeobserve) "aHN" = ( /obj/structure/chair, @@ -16647,9 +16630,6 @@ pixel_x = -3; pixel_y = 5 }, -/obj/structure/sign/barsign{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -16698,9 +16678,6 @@ pixel_y = 5 }, /obj/structure/table/wood, -/obj/structure/sign/barsign{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -69586,7 +69563,7 @@ aEp aEp aEp aEp -aHM +aHN aHW aHN aIl @@ -72413,7 +72390,7 @@ aGP aGK aGP aEp -aHM +aHN aHW aHN aIl @@ -73445,7 +73422,7 @@ aHf aHf aHf aIo -aEp +aHM aIL aIZ aIZ diff --git a/code/__DEFINES/directional.dm b/code/__DEFINES/directional.dm index 85d746a43882..83d8ce01d0a8 100644 --- a/code/__DEFINES/directional.dm +++ b/code/__DEFINES/directional.dm @@ -4,7 +4,44 @@ // #define EAST 4 // #define WEST 8 +/// North direction as a string "[1]" #define TEXT_NORTH "[NORTH]" +/// South direction as a string "[2]" #define TEXT_SOUTH "[SOUTH]" +/// East direction as a string "[4]" #define TEXT_EAST "[EAST]" +/// West direction as a string "[8]" #define TEXT_WEST "[WEST]" + +//dir macros +///Returns true if the dir is diagonal, false otherwise +#define ISDIAGONALDIR(d) (d&(d-1)) +///True if the dir is north or south, false therwise +#define NSCOMPONENT(d) (d&(NORTH|SOUTH)) +///True if the dir is east/west, false otherwise +#define EWCOMPONENT(d) (d&(EAST|WEST)) +///Flips the dir for north/south directions +#define NSDIRFLIP(d) (d^(NORTH|SOUTH)) +///Flips the dir for east/west directions +#define EWDIRFLIP(d) (d^(EAST|WEST)) + +/// Inverse direction, taking into account UP|DOWN if necessary. +#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) + +/// Create directional subtypes for a path to simplify mapping. +#define MAPPING_DIRECTIONAL_HELPERS(path, offset) ##path/directional/north {\ + dir = NORTH; \ + pixel_y = offset; \ +} \ +##path/directional/south {\ + dir = SOUTH; \ + pixel_y = -offset; \ +} \ +##path/directional/east {\ + dir = EAST; \ + pixel_x = offset; \ +} \ +##path/directional/west {\ + dir = WEST; \ + pixel_x = -offset; \ +} diff --git a/code/datums/components/wall_mounted.dm b/code/datums/components/wall_mounted.dm new file mode 100644 index 000000000000..335f306f4f7c --- /dev/null +++ b/code/datums/components/wall_mounted.dm @@ -0,0 +1,59 @@ +// This element should be applied to wall-mounted machines/structures, so that if the wall it's "hanging" from is broken or deconstructed, the wall-hung structure will deconstruct. +/datum/component/wall_mounted + dupe_mode = COMPONENT_DUPE_ALLOWED + /// The wall our object is currently linked to. + var/turf/hanging_wall_turf + /// Callback to the parent's proc to call on the linked object when the wall disappear's or changes. + var/datum/callback/on_drop + +/datum/component/wall_mounted/Initialize(target_wall, on_drop_callback) + . = ..() + if(!isobj(parent)) + return COMPONENT_INCOMPATIBLE + if(!isturf(target_wall)) + return COMPONENT_INCOMPATIBLE + hanging_wall_turf = target_wall + on_drop = on_drop_callback + +/datum/component/wall_mounted/RegisterWithParent() + RegisterSignal(hanging_wall_turf, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine)) + RegisterSignal(parent, COMSIG_PARENT_QDELETING, PROC_REF(on_linked_destroyed)) + +/datum/component/wall_mounted/UnregisterFromParent() + UnregisterSignal(hanging_wall_turf, list(COMSIG_PARENT_EXAMINE, COMSIG_TURF_CHANGE)) + UnregisterSignal(parent, list(COMSIG_PARENT_QDELETING, COMSIG_MOVABLE_MOVED)) + hanging_wall_turf = null + +/** + * Basic reference handling if the hanging/linked object is destroyed first. + */ +/datum/component/wall_mounted/proc/on_linked_destroyed() + SIGNAL_HANDLER + if(!QDELING(src)) + qdel(src) + +/** + * When the wall is examined, explains that it's supporting the linked object. + */ +/datum/component/wall_mounted/proc/on_examine(datum/source, mob/user, list/examine_list) + SIGNAL_HANDLER + examine_list += span_notice("\The [hanging_wall_turf] is currently supporting [span_bold("[parent]")]. Deconstruction or excessive damage would cause it to [span_bold("fall to the ground")].") + +/** + * Checks object direction and then verifies if there's a wall in that direction. Finally, applies a wall_mounted component to the object. + * + * @param directional If TRUE, will use the direction of the object to determine the wall to attach to. If FALSE, will use the object's loc. + * @param custom_drop_callback If set, will use this callback instead of the default deconstruct callback. + */ +/obj/proc/find_and_hang_on_wall(directional = TRUE, custom_drop_callback) + if(istype(get_area(src), /area/shuttle)) + return FALSE //For now, we're going to keep the component off of shuttles to avoid the turf changing issue. We'll hit that later really; + var/turf/attachable_wall + if(directional) + attachable_wall = get_step(src, dir) + else + attachable_wall = loc ///Pull from the curent object loc + if(!iswallturf(attachable_wall)) + return FALSE//Nothing to latch onto, or not the right thing. + src.AddComponent(/datum/component/wall_mounted, attachable_wall, custom_drop_callback) + return TRUE diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 2b8d625a76a6..67607e1d09c2 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1205,3 +1205,11 @@ /// Ought to work turf_mask.color = list(255,255,255,0, 255,255,255,0, 255,255,255,0, 0,0,0,0, 0,0,0,255) underlay_appearance.overlays += turf_mask + +/atom/movable/update_overlays() + var/list/overlays = ..() + var/emissive_block = update_emissive_block() + if(emissive_block) + // Emissive block should always go at the beginning of the list + overlays.Insert(1, emissive_block) + return overlays diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm new file mode 100644 index 000000000000..1842a2dfbbaf --- /dev/null +++ b/code/game/machinery/barsigns.dm @@ -0,0 +1,487 @@ +/obj/machinery/barsign // All Signs are 64 by 32 pixels, they take two tiles + name = "bar sign" + desc = "A bar sign which has not been initialized, somehow. Complain at a coder!" + icon = 'icons/obj/barsigns.dmi' + icon_state = "empty" + req_access = list(ACCESS_BAR) + max_integrity = 500 + integrity_failure = 0.5 + /// Selected barsign being used + var/datum/barsign/chosen_sign + /// Do we attempt to rename the area we occupy when the chosen sign is changed? + var/change_area_name = FALSE + /// What kind of sign do we drop upon being disassembled? + var/disassemble_result = /obj/item/wallframe/barsign + light_color = LIGHT_COLOR_BLUE + +/datum/armor/sign_barsign + melee = 20 + bullet = 20 + laser = 20 + energy = 100 + fire = 50 + acid = 50 + +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) + +/obj/machinery/barsign/Initialize(mapload) + . = ..() + //Roundstart/map specific barsigns "belong" in their area and should be renaming it, signs created from wallmounts will not. + change_area_name = mapload + set_sign(new /datum/barsign/hiddensigns/signoff) + find_and_hang_on_wall() + +/obj/machinery/barsign/proc/set_sign(datum/barsign/sign) + if(!istype(sign)) + return + + if(change_area_name && sign.rename_area) + rename_area(src, sign.name) + + chosen_sign = sign + update_appearance() + +/obj/machinery/barsign/update_icon_state() + if(!(stat & BROKEN) && (!(stat & NOPOWER) || stat & EMPED) && chosen_sign && chosen_sign.icon_state) + icon_state = chosen_sign.icon_state + else + icon_state = "empty" + + return ..() + +/obj/machinery/barsign/update_desc() + . = ..() + + if(chosen_sign && chosen_sign.desc) + desc = chosen_sign.desc + +/obj/machinery/barsign/update_name() + . = ..() + if(chosen_sign && chosen_sign.rename_area) + name = "[initial(name)] ([chosen_sign.name])" + else + name = "[initial(name)]" + +/obj/machinery/barsign/update_overlays() + . = ..() + + if(((stat & NOPOWER) && !(stat & EMPED)) || (stat & BROKEN)) + return + + if(chosen_sign && chosen_sign.light_mask) + . += emissive_appearance(icon, "[chosen_sign.icon_state]-light-mask", src, alpha = src.alpha) + +/obj/machinery/barsign/update_appearance(updates=ALL) + . = ..() + if(stat & (NOPOWER|BROKEN)) + set_light(0) + return + if(chosen_sign && chosen_sign.neon_color) + set_light(MINIMUM_USEFUL_LIGHT_RANGE, 0.7, chosen_sign.neon_color) + +/obj/machinery/barsign/proc/set_sign_by_name(sign_name) + for(var/datum/barsign/sign as anything in subtypesof(/datum/barsign)) + if(initial(sign.name) == sign_name) + var/new_sign = new sign + set_sign(new_sign) + +/obj/machinery/barsign/deconstruct(disassembled = TRUE) + if(!(flags_1 & NODECONSTRUCT_1)) + if(disassembled) + new disassemble_result(drop_location()) + else + new /obj/item/stack/sheet/metal(drop_location(), 2) + new /obj/item/stack/cable_coil(drop_location(), 2) + + qdel(src) + +/obj/machinery/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) + switch(damage_type) + if(BRUTE) + playsound(src.loc, 'sound/effects/glasshit.ogg', 75, TRUE) + if(BURN) + playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE) + +/obj/machinery/barsign/attack_ai(mob/user) + return attack_hand(user) + +/obj/machinery/barsign/attack_hand(mob/user, list/modifiers) + . = ..() + if(.) + return + if(!allowed(user)) + balloon_alert(user, "access denied!") + return + if(stat & (NOPOWER|BROKEN|EMPED)) + balloon_alert(user, "controls are unresponsive!") + return + pick_sign(user) + +/obj/machinery/barsign/screwdriver_act(mob/living/user, obj/item/tool) + tool.play_tool_sound(src) + panel_open = !panel_open + if(panel_open) + balloon_alert(user, "panel opened") + set_sign(new /datum/barsign/hiddensigns/signoff) + return TOOL_ACT_TOOLTYPE_SUCCESS + + balloon_alert(user, "panel closed") + + if(stat & (NOPOWER|BROKEN) || !chosen_sign) + set_sign(new /datum/barsign/hiddensigns/signoff) + else + set_sign(chosen_sign) + + return TOOL_ACT_TOOLTYPE_SUCCESS + +/obj/machinery/barsign/wrench_act(mob/living/user, obj/item/tool) + . = ..() + if(!panel_open) + balloon_alert(user, "open the panel first!") + return FALSE + + tool.play_tool_sound(src) + if(!do_after(user, (10 SECONDS), target = src)) + return FALSE + + tool.play_tool_sound(src) + deconstruct(disassembled = TRUE) + return TOOL_ACT_TOOLTYPE_SUCCESS + + +/obj/machinery/barsign/attackby(obj/item/attacking_item, mob/user) + + if(istype(attacking_item, /obj/item/areaeditor/blueprints) && !change_area_name) + if(!panel_open) + balloon_alert(user, "open the panel first!") + return TRUE + + change_area_name = TRUE + balloon_alert(user, "sign registered") + return TRUE + + return ..() + + +/obj/machinery/barsign/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + set_sign(new /datum/barsign/hiddensigns/empbarsign) + +/obj/machinery/barsign/emag_act(mob/user, obj/item/card/emag/emag_card) + if(stat & (NOPOWER|BROKEN|EMPED)) + balloon_alert(user, "controls are unresponsive!") + return FALSE + + balloon_alert(user, "illegal barsign loaded") + addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 10 SECONDS) + return TRUE + +/// Timer proc, called after ~10 seconds after [emag_act], since [emag_act] returns a value and cannot sleep +/obj/machinery/barsign/proc/finish_emag_act() + set_sign(new /datum/barsign/hiddensigns/syndibarsign) + +/obj/machinery/barsign/proc/pick_sign(mob/user) + var/picked_name = tgui_input_list(user, "Available Signage", "Bar Sign", sort_list(get_bar_names())) + if(isnull(picked_name)) + return + set_sign_by_name(picked_name) + SSblackbox.record_feedback("tally", "barsign_picked", 1, chosen_sign.type) + +/proc/get_bar_names() + var/list/names = list() + for(var/d in subtypesof(/datum/barsign)) + var/datum/barsign/D = d + if(!initial(D.hidden)) + names += initial(D.name) + . = names + +/datum/barsign + /// User-visible name of the sign. + var/name + /// Icon state associated with this sign + var/icon_state + /// Description shown in the sign's examine text. + var/desc + /// Hidden from list of selectable options. + var/hidden = FALSE + /// Rename the area when this sign is selected. + var/rename_area = TRUE + /// If a barsign has a light mask for emission effects + var/light_mask + /// The emission color of the neon light + var/neon_color + +/datum/barsign/New() + if(!desc) + desc = "It displays \"[name]\"." + +// Specific bar signs. + +/datum/barsign/maltesefalcon + name = "Maltese Falcon" + icon_state = "maltesefalcon" + desc = "The Maltese Falcon, Space Bar and Grill." + neon_color = "#5E8EAC" + +/datum/barsign/thebark + name = "The Bark" + icon_state = "thebark" + desc = "Ian's bar of choice." + neon_color = "#f7a604" + +/datum/barsign/harmbaton + name = "The Harmbaton" + icon_state = "theharmbaton" + desc = "A great dining experience for both security members and assistants." + neon_color = "#ff7a4d" + +/datum/barsign/thesingulo + name = "The Singulo" + icon_state = "thesingulo" + desc = "Where people go that'd rather not be called by their name." + neon_color = "#E600DB" + +/datum/barsign/thedrunkcarp + name = "The Drunk Carp" + icon_state = "thedrunkcarp" + desc = "Don't drink and swim." + neon_color = "#a82196" + +/datum/barsign/scotchservinwill + name = "Scotch Servin Willy's" + icon_state = "scotchservinwill" + desc = "Willy sure moved up in the world from clown to bartender." + neon_color = "#fee4bf" + +/datum/barsign/officerbeersky + name = "Officer Beersky's" + icon_state = "officerbeersky" + desc = "Man eat a dong, these drinks are great." + neon_color = "#16C76B" + +/datum/barsign/thecavern + name = "The Cavern" + icon_state = "thecavern" + desc = "Fine drinks while listening to some fine tunes." + neon_color = "#0fe500" + +/datum/barsign/theouterspess + name = "The Outer Spess" + icon_state = "theouterspess" + desc = "This bar isn't actually located in outer space." + neon_color = "#30f3cc" + +/datum/barsign/slipperyshots + name = "Slippery Shots" + icon_state = "slipperyshots" + desc = "Slippery slope to drunkeness with our shots!" + neon_color = "#70DF00" + +/datum/barsign/thegreytide + name = "The Grey Tide" + icon_state = "thegreytide" + desc = "Abandon your toolboxing ways and enjoy a lazy beer!" + neon_color = "#00F4D6" + +/datum/barsign/honkednloaded + name = "Honked 'n' Loaded" + icon_state = "honkednloaded" + desc = "Honk." + neon_color = "#FF998A" + +/datum/barsign/le_cafe_silencieux + name = "Le Café Silencieux" + icon_state = "le_cafe_silencieux" + desc = "..." + neon_color = "#ffffff" + +/datum/barsign/thenest + name = "The Nest" + icon_state = "thenest" + desc = "A good place to retire for a drink after a long night of crime fighting." + neon_color = "#4d6796" + +/datum/barsign/thecoderbus + name = "The Coderbus" + icon_state = "thecoderbus" + desc = "A very controversial bar known for its wide variety of constantly-changing drinks." + neon_color = "#ffffff" + +/datum/barsign/theadminbus + name = "The Adminbus" + icon_state = "theadminbus" + desc = "An establishment visited mainly by space-judges. It isn't bombed nearly as much as court hearings." + neon_color = "#ffffff" + +/datum/barsign/oldcockinn + name = "The Old Cock Inn" + icon_state = "oldcockinn" + desc = "Something about this sign fills you with despair." + neon_color = "#a4352b" + +/datum/barsign/thewretchedhive + name = "The Wretched Hive" + icon_state = "thewretchedhive" + desc = "Legally obligated to instruct you to check your drinks for acid before consumption." + neon_color = "#26b000" + +/datum/barsign/robustacafe + name = "The Robusta Cafe" + icon_state = "robustacafe" + desc = "Holder of the 'Most Lethal Barfights' record 5 years uncontested." + neon_color = "#c45f7a" + +/datum/barsign/emergencyrumparty + name = "The Emergency Rum Party" + icon_state = "emergencyrumparty" + desc = "Recently relicensed after a long closure." + neon_color = "#f90011" + +/datum/barsign/combocafe + name = "The Combo Cafe" + icon_state = "combocafe" + desc = "Renowned system-wide for their utterly uncreative drink combinations." + neon_color = "#33ca40" + +/datum/barsign/vladssaladbar + name = "Vlad's Salad Bar" + icon_state = "vladssaladbar" + desc = "Under new management. Vlad was always a bit too trigger happy with that shotgun." + neon_color = "#306900" + +/datum/barsign/theshaken + name = "The Shaken" + icon_state = "theshaken" + desc = "This establishment does not serve stirred drinks." + neon_color = "#dcd884" + +/datum/barsign/thealenath + name = "The Ale' Nath" + icon_state = "thealenath" + desc = "All right, buddy. I think you've had EI NATH. Time to get a cab." + neon_color = "#ed0000" + +/datum/barsign/thealohasnackbar + name = "The Aloha Snackbar" + icon_state = "alohasnackbar" + desc = "A tasteful, inoffensive tiki bar sign." + neon_color = "" + +/datum/barsign/thenet + name = "The Net" + icon_state = "thenet" + desc = "You just seem to get caught up in it for hours." + neon_color = "#0e8a00" + +/datum/barsign/maidcafe + name = "Maid Cafe" + icon_state = "maidcafe" + desc = "Welcome back, master!" + neon_color = "#ff0051" + +/datum/barsign/the_lightbulb + name = "The Lightbulb" + icon_state = "the_lightbulb" + desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." + neon_color = "#faff82" + +/datum/barsign/goose + name = "The Loose Goose" + icon_state = "goose" + desc = "Drink till you puke and/or break the laws of reality!" + neon_color = "#00cc33" + +/datum/barsign/maltroach + name = "Maltroach" + icon_state = "maltroach" + desc = "Mothroaches politely greet you into the bar, or are they greeting eachother?" + neon_color = "#649e8a" + +/datum/barsign/rock_bottom + name = "Rock Bottom" + icon_state = "rock-bottom" + desc = "When it feels like you're stuck in a pit, might as well have a drink." + neon_color = "#aa2811" + +/datum/barsign/orangejuice + name = "Oranges' Juicery" + icon_state = "orangejuice" + desc = "For those who wish to be optimally tactful to the non-alcoholic population." + neon_color = COLOR_ORANGE + +/datum/barsign/tearoom + name = "Little Treats Tea Room" + icon_state = "little_treats" + desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos." + neon_color = LIGHT_COLOR_ORANGE + light_mask = "little_treats-light-mask" + +/datum/barsign/assembly_line + name = "The Assembly Line" + icon_state = "the-assembly-line" + desc = "Where every drink is masterfully crafted with industrial efficiency!" + neon_color = "#ffffff" + +/datum/barsign/bargonia + name = "Bargonia" + icon_state = "bargonia" + desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!" + neon_color = COLOR_WHITE + +// Hidden signs list below this point + +/datum/barsign/hiddensigns + hidden = TRUE + +/datum/barsign/hiddensigns/empbarsign + name = "EMP'd" + icon_state = "empbarsign" + desc = "Something has gone very wrong." + rename_area = FALSE + +/datum/barsign/hiddensigns/syndibarsign + name = "Syndi Cat" + icon_state = "syndibarsign" + desc = "Syndicate or die." + neon_color = "#ff0000" + +/datum/barsign/hiddensigns/signoff + name = "Off" + icon_state = "empty" + desc = "This sign doesn't seem to be on." + rename_area = FALSE + light_mask = FALSE + +// For other locations that aren't in the main bar +/obj/machinery/barsign/all_access + req_access = null + disassemble_result = /obj/item/wallframe/barsign/all_access + +MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign/all_access, 32) + +/obj/item/wallframe/barsign + name = "bar sign frame" + desc = "Used to help draw the rabble into your bar. Some assembly required." + icon = 'icons/obj/wallmounts.dmi' + icon_state = "barsign" + result_path = /obj/machinery/barsign + pixel_shift = 32 + +/obj/item/wallframe/barsign/Initialize(mapload) + . = ..() + desc += " Can be registered with a set of [span_bold("station blueprints")] to associate the sign with the area it occupies." + +/obj/item/wallframe/barsign/try_build(turf/on_wall, mob/user) + . = ..() + if(!.) + return . + + if(isopenturf(get_step(on_wall, EAST))) //This takes up 2 tiles so we want to make sure we have two tiles to hang it from. + balloon_alert(user, "needs more support!") + return FALSE + +/obj/item/wallframe/barsign/all_access + desc = "Used to help draw the rabble into your bar. Some assembly required. This one doesn't have an access lock." + result_path = /obj/machinery/barsign/all_access diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 0f0697d3cd5b..e8604b563d7b 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -1,348 +1,348 @@ -/obj/structure/sign/barsign // All Signs are 64 by 32 pixels, they take two tiles - name = "bar sign" - desc = "A bar sign which has not been initialized, somehow. Complain at a coder!" - icon = 'icons/obj/barsigns.dmi' - icon_state = "empty" - req_access = list(ACCESS_BAR) - max_integrity = 500 - integrity_failure = 250 - armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) - buildable_sign = 0 - - var/panel_open = FALSE - var/datum/barsign/chosen_sign - -/obj/structure/sign/barsign/Initialize(mapload) - . = ..() - set_sign(new /datum/barsign/hiddensigns/signoff) - -/obj/structure/sign/barsign/proc/set_sign(datum/barsign/sign) - if(!istype(sign)) - return - - icon_state = sign.icon - - if(sign.name) - name = "[initial(name)] ([sign.name])" - else - name = "[initial(name)]" - - if(sign.desc) - desc = sign.desc - - if(sign.rename_area && sign.name) - rename_area(src, sign.name) - - return sign - -/obj/structure/sign/barsign/proc/set_sign_by_name(sign_name) - for(var/d in subtypesof(/datum/barsign)) - var/datum/barsign/D = d - if(initial(D.name) == sign_name) - var/new_sign = new D - return set_sign(new_sign) - -/obj/structure/sign/barsign/obj_break(damage_flag) - if(!broken && !(flags_1 & NODECONSTRUCT_1)) - broken = TRUE - -/obj/structure/sign/barsign/deconstruct(disassembled = TRUE) - new /obj/item/stack/sheet/metal(drop_location(), 2) - new /obj/item/stack/cable_coil(drop_location(), 2) - qdel(src) - -/obj/structure/sign/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) - switch(damage_type) - if(BRUTE) - playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1) - if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - -/obj/structure/sign/barsign/attack_ai(mob/user) - return attack_hand(user) - -/obj/structure/sign/barsign/attack_hand(mob/user) - . = ..() - if(.) - return - if(!allowed(user)) - to_chat(user, span_info("Access denied.")) - return - if(broken) - to_chat(user, "The controls seem unresponsive.") - return - pick_sign(user) - -/obj/structure/sign/barsign/attackby(obj/item/I, mob/user) - if(I.tool_behaviour == TOOL_SCREWDRIVER) - if(!panel_open) - to_chat(user, span_notice("You open the maintenance panel.")) - set_sign(new /datum/barsign/hiddensigns/signoff) - panel_open = TRUE - else - to_chat(user, span_notice("You close the maintenance panel.")) - if(!broken) - if(!chosen_sign) - set_sign(new /datum/barsign/hiddensigns/signoff) - else - set_sign(chosen_sign) - else - set_sign(new /datum/barsign/hiddensigns/empbarsign) - panel_open = FALSE - - else if(istype(I, /obj/item/stack/cable_coil) && panel_open) - var/obj/item/stack/cable_coil/C = I - if(!broken) - to_chat(user, span_warning("This sign is functioning properly!")) - return - - if(C.use(2)) - to_chat(user, span_notice("You replace the burnt wiring.")) - broken = FALSE - else - to_chat(user, span_warning("You need at least two lengths of cable!")) - else - return ..() - - -/obj/structure/sign/barsign/emp_act(severity) - . = ..() - if(. & EMP_PROTECT_SELF) - return - set_sign(new /datum/barsign/hiddensigns/empbarsign) - broken = TRUE - -/obj/structure/sign/barsign/emag_act(mob/user, obj/item/card/emag/emag_card) - if(broken) - to_chat(user, span_warning("Nothing interesting happens!")) - return FALSE - to_chat(user, span_notice("You load an illegal barsign into the memory buffer...")) - addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 10 SECONDS) - return TRUE - -/obj/structure/sign/barsign/proc/finish_emag_act() - if(QDELETED(src)) - return - chosen_sign = set_sign(new /datum/barsign/hiddensigns/syndibarsign) - -/obj/structure/sign/barsign/proc/pick_sign(mob/user) - var/picked_name = input(user, "Available Signage", "Bar Sign", name) as null|anything in get_bar_names() - if(!picked_name) - return - chosen_sign = set_sign_by_name(picked_name) - SSblackbox.record_feedback("tally", "barsign_picked", 1, chosen_sign.type) - -/proc/get_bar_names() - var/list/names = list() - for(var/d in subtypesof(/datum/barsign)) - var/datum/barsign/D = d - if(initial(D.name) && !initial(D.hidden)) - names += initial(D.name) - . = names - -/datum/barsign - var/name = "Name" - var/icon = "Icon" - var/desc = "desc" - var/hidden = FALSE - var/rename_area = TRUE - -/datum/barsign/New() - if(!desc) - desc = "It displays \"[name]\"." - -// Specific bar signs. - -/datum/barsign/maltesefalcon - name = "Maltese Falcon" - icon = "maltesefalcon" - desc = "The Maltese Falcon, Space Bar and Grill." - -/datum/barsign/thebark - name = "The Bark" - icon = "thebark" - desc = "Ian's bar of choice." - -/datum/barsign/harmbaton - name = "The Harmbaton" - icon = "theharmbaton" - desc = "A great dining experience for both security members and assistants." - -/datum/barsign/thesingulo - name = "The Singulo" - icon = "thesingulo" - desc = "Where people go that'd rather not be called by their name." - -/datum/barsign/thedrunkcarp - name = "The Drunk Carp" - icon = "thedrunkcarp" - desc = "Don't drink and swim." - -/datum/barsign/scotchservinwill - name = "Scotch Servin Willy's" - icon = "scotchservinwill" - desc = "Willy sure moved up in the world from clown to bartender." - -/datum/barsign/officerbeersky - name = "Officer Beersky's" - icon = "officerbeersky" - desc = "Man eat a dong, these drinks are great." - -/datum/barsign/thecavern - name = "The Cavern" - icon = "thecavern" - desc = "Fine drinks while listening to some fine tunes." - -/datum/barsign/theouterspess - name = "The Outer Spess" - icon = "theouterspess" - desc = "This bar isn't actually located in outer space." - -/datum/barsign/slipperyshots - name = "Slippery Shots" - icon = "slipperyshots" - desc = "Slippery slope to drunkenness with our shots!" - -/datum/barsign/thegreytide - name = "The Grey Tide" - icon = "thegreytide" - desc = "Abandon your toolboxing ways and enjoy a lazy beer!" - -/datum/barsign/honkednloaded - name = "Honked 'n' Loaded" - icon = "honkednloaded" - desc = "Honk." - -/datum/barsign/thenest - name = "The Nest" - icon = "thenest" - desc = "A good place to retire for a drink after a long night of crime fighting." - -/datum/barsign/thecoderbus - name = "The Coderbus" - icon = "thecoderbus" - desc = "A very controversial bar known for its wide variety of constantly-changing drinks." - -/datum/barsign/theadminbus - name = "The Adminbus" - icon = "theadminbus" - desc = "An establishment visited mainly by space-judges. It isn't bombed nearly as much as court hearings." - -/datum/barsign/oldcockinn - name = "The Old Cock Inn" - icon = "oldcockinn" - desc = "Something about this sign fills you with despair." - -/datum/barsign/thewretchedhive - name = "The Wretched Hive" - icon = "thewretchedhive" - desc = "Legally obligated to instruct you to check your drinks for acid before consumption." - -/datum/barsign/robustacafe - name = "The Robusta Cafe" - icon = "robustacafe" - desc = "Holder of the 'Most Lethal Barfights' record 5 years uncontested." - -/datum/barsign/emergencyrumparty - name = "The Emergency Rum Party" - icon = "emergencyrumparty" - desc = "Recently relicensed after a long closure." - -/datum/barsign/combocafe - name = "The Combo Cafe" - icon = "combocafe" - desc = "Renowned system-wide for their utterly uncreative drink combinations." - -/datum/barsign/vladssaladbar - name = "Vlad's Salad Bar" - icon = "vladssaladbar" - desc = "Under new management. Vlad was always a bit too trigger happy with that shotgun." - -/datum/barsign/theshaken - name = "The Shaken" - icon = "theshaken" - desc = "This establishment does not serve stirred drinks." - -/datum/barsign/thealenath - name = "The Ale' Nath" - icon = "thealenath" - desc = "All right, buddy. I think you've had EI NATH. Time to get a cab." - -/datum/barsign/thealohasnackbar - name = "The Aloha Snackbar" - icon = "alohasnackbar" - desc = "A tasteful, inoffensive tiki bar sign." - -/datum/barsign/thenet - name = "The Net" - icon = "thenet" - desc = "You just seem to get caught up in it for hours." - -/datum/barsign/maidcafe - name = "Maid Cafe" - icon = "maidcafe" - desc = "Welcome back, master!" - -/datum/barsign/the_lightbulb - name = "The Lightbulb" - icon = "the_lightbulb" - desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." - -/datum/barsign/thegoose - name = "The Goose" - icon = "thegoose" - desc = "A nice place to hang loose and relax, while enjoying some electrifying drinks." - -/datum/barsign/tearoom - name = "Little Treats Tea Room" - icon = "little_treats" - desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos." - -/datum/barsign/le_cafe_silencieux - name = "Le Café Silencieux" - icon = "le_cafe_silencieux" - desc = "..." - -/datum/barsign/maltroach - name = "Maltroach" - icon = "maltroach" - desc = "Mothroaches politely greet you into the bar, or are they greeting eachother?" - -/datum/barsign/rock_bottom - name = "Rock Bottom" - icon = "rock-bottom" - desc = "When it feels like you're stuck in a pit, might as well have a drink." - -/datum/barsign/assembly_line - name = "The Assembly Line" - icon = "the-assembly-line" - desc = "Where every drink is masterfully crafted with industrial efficiency!" - -/datum/barsign/bargonia - name = "Bargonia" - icon = "bargonia" - desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!" +// /obj/structure/sign/barsign // All Signs are 64 by 32 pixels, they take two tiles +// name = "bar sign" +// desc = "A bar sign which has not been initialized, somehow. Complain at a coder!" +// icon = 'icons/obj/barsigns.dmi' +// icon_state = "empty" +// req_access = list(ACCESS_BAR) +// max_integrity = 500 +// integrity_failure = 250 +// armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) +// buildable_sign = 0 + +// var/panel_open = FALSE +// var/datum/barsign/chosen_sign + +// // /obj/structure/sign/barsign/Initialize(mapload) +// // . = ..() +// // set_sign(new /datum/barsign/hiddensigns/signoff) + +// /obj/structure/sign/barsign/proc/set_sign(datum/barsign/sign) +// if(!istype(sign)) +// return + +// icon_state = sign.icon + +// if(sign.name) +// name = "[initial(name)] ([sign.name])" +// else +// name = "[initial(name)]" + +// if(sign.desc) +// desc = sign.desc + +// if(sign.rename_area && sign.name) +// rename_area(src, sign.name) + +// return sign + +// /obj/structure/sign/barsign/proc/set_sign_by_name(sign_name) +// for(var/d in subtypesof(/datum/barsign)) +// var/datum/barsign/D = d +// if(initial(D.name) == sign_name) +// var/new_sign = new D +// return set_sign(new_sign) + +// /obj/structure/sign/barsign/obj_break(damage_flag) +// if(!broken && !(flags_1 & NODECONSTRUCT_1)) +// broken = TRUE + +// /obj/structure/sign/barsign/deconstruct(disassembled = TRUE) +// new /obj/item/stack/sheet/metal(drop_location(), 2) +// new /obj/item/stack/cable_coil(drop_location(), 2) +// qdel(src) + +// /obj/structure/sign/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) +// switch(damage_type) +// if(BRUTE) +// playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1) +// if(BURN) +// playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + +// /obj/structure/sign/barsign/attack_ai(mob/user) +// return attack_hand(user) + +// /obj/structure/sign/barsign/attack_hand(mob/user) +// . = ..() +// if(.) +// return +// if(!allowed(user)) +// to_chat(user, span_info("Access denied.")) +// return +// if(broken) +// to_chat(user, "The controls seem unresponsive.") +// return +// pick_sign(user) + +// /obj/structure/sign/barsign/attackby(obj/item/I, mob/user) +// if(I.tool_behaviour == TOOL_SCREWDRIVER) +// if(!panel_open) +// to_chat(user, span_notice("You open the maintenance panel.")) +// set_sign(new /datum/barsign/hiddensigns/signoff) +// panel_open = TRUE +// else +// to_chat(user, span_notice("You close the maintenance panel.")) +// if(!broken) +// if(!chosen_sign) +// set_sign(new /datum/barsign/hiddensigns/signoff) +// else +// set_sign(chosen_sign) +// else +// set_sign(new /datum/barsign/hiddensigns/empbarsign) +// panel_open = FALSE + +// else if(istype(I, /obj/item/stack/cable_coil) && panel_open) +// var/obj/item/stack/cable_coil/C = I +// if(!broken) +// to_chat(user, span_warning("This sign is functioning properly!")) +// return + +// if(C.use(2)) +// to_chat(user, span_notice("You replace the burnt wiring.")) +// broken = FALSE +// else +// to_chat(user, span_warning("You need at least two lengths of cable!")) +// else +// return ..() + + +// /obj/structure/sign/barsign/emp_act(severity) +// . = ..() +// if(. & EMP_PROTECT_SELF) +// return +// set_sign(new /datum/barsign/hiddensigns/empbarsign) +// // broken = TRUE + +// /obj/structure/sign/barsign/emag_act(mob/user, obj/item/card/emag/emag_card) +// if(broken) +// to_chat(user, span_warning("Nothing interesting happens!")) +// return FALSE +// to_chat(user, span_notice("You load an illegal barsign into the memory buffer...")) +// addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 10 SECONDS) +// return TRUE + +// /obj/structure/sign/barsign/proc/finish_emag_act() +// if(QDELETED(src)) +// return +// chosen_sign = set_sign(new /datum/barsign/hiddensigns/syndibarsign) + +// /obj/structure/sign/barsign/proc/pick_sign(mob/user) +// var/picked_name = input(user, "Available Signage", "Bar Sign", name) as null|anything in get_bar_names() +// if(!picked_name) +// return +// chosen_sign = set_sign_by_name(picked_name) +// SSblackbox.record_feedback("tally", "barsign_picked", 1, chosen_sign.type) + +// /proc/get_bar_names() +// var/list/names = list() +// for(var/d in subtypesof(/datum/barsign)) +// var/datum/barsign/D = d +// if(initial(D.name) && !initial(D.hidden)) +// names += initial(D.name) +// . = names + +// /datum/barsign +// var/name = "Name" +// var/icon = "Icon" +// var/desc = "desc" +// var/hidden = FALSE +// var/rename_area = TRUE + +// /datum/barsign/New() +// if(!desc) +// desc = "It displays \"[name]\"." + +// // Specific bar signs. + +// /datum/barsign/maltesefalcon +// name = "Maltese Falcon" +// icon = "maltesefalcon" +// desc = "The Maltese Falcon, Space Bar and Grill." + +// /datum/barsign/thebark +// name = "The Bark" +// icon = "thebark" +// desc = "Ian's bar of choice." + +// /datum/barsign/harmbaton +// name = "The Harmbaton" +// icon = "theharmbaton" +// desc = "A great dining experience for both security members and assistants." + +// /datum/barsign/thesingulo +// name = "The Singulo" +// icon = "thesingulo" +// desc = "Where people go that'd rather not be called by their name." + +// /datum/barsign/thedrunkcarp +// name = "The Drunk Carp" +// icon = "thedrunkcarp" +// desc = "Don't drink and swim." + +// /datum/barsign/scotchservinwill +// name = "Scotch Servin Willy's" +// icon = "scotchservinwill" +// desc = "Willy sure moved up in the world from clown to bartender." + +// /datum/barsign/officerbeersky +// name = "Officer Beersky's" +// icon = "officerbeersky" +// desc = "Man eat a dong, these drinks are great." + +// /datum/barsign/thecavern +// name = "The Cavern" +// icon = "thecavern" +// desc = "Fine drinks while listening to some fine tunes." + +// /datum/barsign/theouterspess +// name = "The Outer Spess" +// icon = "theouterspess" +// desc = "This bar isn't actually located in outer space." + +// /datum/barsign/slipperyshots +// name = "Slippery Shots" +// icon = "slipperyshots" +// desc = "Slippery slope to drunkenness with our shots!" + +// /datum/barsign/thegreytide +// name = "The Grey Tide" +// icon = "thegreytide" +// desc = "Abandon your toolboxing ways and enjoy a lazy beer!" + +// /datum/barsign/honkednloaded +// name = "Honked 'n' Loaded" +// icon = "honkednloaded" +// desc = "Honk." + +// /datum/barsign/thenest +// name = "The Nest" +// icon = "thenest" +// desc = "A good place to retire for a drink after a long night of crime fighting." + +// /datum/barsign/thecoderbus +// name = "The Coderbus" +// icon = "thecoderbus" +// desc = "A very controversial bar known for its wide variety of constantly-changing drinks." + +// /datum/barsign/theadminbus +// name = "The Adminbus" +// icon = "theadminbus" +// desc = "An establishment visited mainly by space-judges. It isn't bombed nearly as much as court hearings." + +// /datum/barsign/oldcockinn +// name = "The Old Cock Inn" +// icon = "oldcockinn" +// desc = "Something about this sign fills you with despair." + +// /datum/barsign/thewretchedhive +// name = "The Wretched Hive" +// icon = "thewretchedhive" +// desc = "Legally obligated to instruct you to check your drinks for acid before consumption." + +// /datum/barsign/robustacafe +// name = "The Robusta Cafe" +// icon = "robustacafe" +// desc = "Holder of the 'Most Lethal Barfights' record 5 years uncontested." + +// /datum/barsign/emergencyrumparty +// name = "The Emergency Rum Party" +// icon = "emergencyrumparty" +// desc = "Recently relicensed after a long closure." + +// /datum/barsign/combocafe +// name = "The Combo Cafe" +// icon = "combocafe" +// desc = "Renowned system-wide for their utterly uncreative drink combinations." + +// /datum/barsign/vladssaladbar +// name = "Vlad's Salad Bar" +// icon = "vladssaladbar" +// desc = "Under new management. Vlad was always a bit too trigger happy with that shotgun." + +// /datum/barsign/theshaken +// name = "The Shaken" +// icon = "theshaken" +// desc = "This establishment does not serve stirred drinks." + +// /datum/barsign/thealenath +// name = "The Ale' Nath" +// icon = "thealenath" +// desc = "All right, buddy. I think you've had EI NATH. Time to get a cab." + +// /datum/barsign/thealohasnackbar +// name = "The Aloha Snackbar" +// icon = "alohasnackbar" +// desc = "A tasteful, inoffensive tiki bar sign." + +// /datum/barsign/thenet +// name = "The Net" +// icon = "thenet" +// desc = "You just seem to get caught up in it for hours." + +// /datum/barsign/maidcafe +// name = "Maid Cafe" +// icon = "maidcafe" +// desc = "Welcome back, master!" + +// /datum/barsign/the_lightbulb +// name = "The Lightbulb" +// icon = "the_lightbulb" +// desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." + +// /datum/barsign/thegoose +// name = "The Goose" +// icon = "thegoose" +// desc = "A nice place to hang loose and relax, while enjoying some electrifying drinks." + +// /datum/barsign/tearoom +// name = "Little Treats Tea Room" +// icon = "little_treats" +// desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos." + +// /datum/barsign/le_cafe_silencieux +// name = "Le Café Silencieux" +// icon = "le_cafe_silencieux" +// desc = "..." + +// /datum/barsign/maltroach +// name = "Maltroach" +// icon = "maltroach" +// desc = "Mothroaches politely greet you into the bar, or are they greeting eachother?" + +// /datum/barsign/rock_bottom +// name = "Rock Bottom" +// icon = "rock-bottom" +// desc = "When it feels like you're stuck in a pit, might as well have a drink." + +// /datum/barsign/assembly_line +// name = "The Assembly Line" +// icon = "the-assembly-line" +// desc = "Where every drink is masterfully crafted with industrial efficiency!" + +// /datum/barsign/bargonia +// name = "Bargonia" +// icon = "bargonia" +// desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!" -/datum/barsign/hiddensigns - hidden = TRUE +// /datum/barsign/hiddensigns +// hidden = TRUE -//Hidden signs list below this point +// //Hidden signs list below this point -/datum/barsign/hiddensigns/empbarsign - name = null - icon = "empbarsign" - desc = "Something has gone very wrong." - rename_area = FALSE +// /datum/barsign/hiddensigns/empbarsign +// name = null +// icon = "empbarsign" +// desc = "Something has gone very wrong." +// rename_area = FALSE -/datum/barsign/hiddensigns/syndibarsign - name = "Syndi Cat" - icon = "syndibarsign" - desc = "Syndicate or die." +// /datum/barsign/hiddensigns/syndibarsign +// name = "Syndi Cat" +// icon = "syndibarsign" +// desc = "Syndicate or die." -/datum/barsign/hiddensigns/signoff - name = null - icon = "empty" - desc = "This sign doesn't seem to be on." - rename_area = FALSE +// /datum/barsign/hiddensigns/signoff +// name = null +// icon = "empty" +// desc = "This sign doesn't seem to be on." +// rename_area = FALSE diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index cbcd50e99d0ac1016b6ea5a2e0da4980dcbbaafb..5b0e52673269849c0a11032032bbb0c997b15471 100644 GIT binary patch literal 210663 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%0D*}k~J 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%0AdSKB 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�)3B&)+j1wXF<+1+7S(x5 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 z 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

    {cY+KJ*^}aJFLdDq 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 O4bPca8ke7OiTXb;WZ>NZ literal 159072 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 z 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

    {cY+KJ*^}aJFLdDq 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 O4bPca8ke7OiTXb;WZ>NZ From 543605e80a8665d21162ddb6d5a6fa604f80d37e Mon Sep 17 00:00:00 2001 From: Chubbygummibear Date: Wed, 6 Dec 2023 19:57:57 -0800 Subject: [PATCH 123/144] forgive me cowboy. also fuck diagonals --- code/__DEFINES/colors.dm | 2 + code/__DEFINES/layers.dm | 7 +- code/__HELPERS/icon_smoothing.dm | 6 +- code/__HELPERS/lighting.dm | 6 +- code/_onclick/hud/fullscreen.dm | 7 +- code/_onclick/hud/render_plate.dm | 2 +- code/controllers/admin.dm | 2 +- code/game/area/areas.dm | 2 +- code/game/atoms_movable.dm | 189 +++++++++++------- code/game/machinery/_machinery.dm | 1 + code/game/machinery/barsigns.dm | 1 - code/game/machinery/computer/_computer.dm | 45 +++-- code/game/machinery/computer/law.dm | 2 +- code/game/machinery/doors/airlock.dm | 3 +- code/game/machinery/doors/door.dm | 1 + code/game/machinery/firealarm.dm | 72 ++++--- code/game/machinery/lightswitch.dm | 58 +++--- .../machinery/porta_turret/portable_turret.dm | 1 + code/game/objects/effects/misc.dm | 1 + code/game/objects/structures.dm | 1 + .../structures/crates_lockers/closets.dm | 45 +++-- code/game/objects/structures/statues.dm | 1 + code/game/objects/structures/watercloset.dm | 38 ++-- code/game/objects/structures/window.dm | 2 +- code/game/turfs/closed.dm | 1 + code/game/turfs/space/space.dm | 4 +- code/game/turfs/space/transit.dm | 2 +- code/game/turfs/turf.dm | 5 +- code/modules/lighting/lighting_object.dm | 6 +- code/modules/mining/lavaland/ruins/gym.dm | 1 + code/modules/mob/living/carbon/alien/alien.dm | 1 + .../mob/living/carbon/carbon_defines.dm | 1 + .../living/silicon/ai/freelook/cameranet.dm | 139 ++++++++----- .../mob/living/silicon/ai/freelook/chunk.dm | 116 ++++++----- .../modules/mob/living/silicon/robot/robot.dm | 4 +- .../computers/item/computer.dm | 50 ++--- .../modular_computers/hardware/card_slot.dm | 3 +- code/modules/power/apc.dm | 104 +++++----- code/modules/power/solar.dm | 1 + code/modules/power/tracker.dm | 1 + code/modules/projectiles/projectile.dm | 1 + code/modules/unit_tests/focus_only_tests.dm | 6 + code/modules/vehicles/_vehicle.dm | 1 + code/modules/vending/_vending.dm | 22 +- icons/effects/alphacolors.dmi | Bin 641 -> 654 bytes icons/effects/lighting_object.dmi | Bin 1893 -> 1899 bytes 46 files changed, 556 insertions(+), 408 deletions(-) diff --git a/code/__DEFINES/colors.dm b/code/__DEFINES/colors.dm index b6fbca4f6dce..ac767ac5e016 100644 --- a/code/__DEFINES/colors.dm +++ b/code/__DEFINES/colors.dm @@ -231,6 +231,8 @@ #define LIGHT_COLOR_LAVA "#C48A18" /// Bright, non-saturated red. Leaning slightly towards pink for visibility. rgb(250, 100, 75) #define LIGHT_COLOR_FLARE "#FA644B" +/// Vivid red. Leans a bit darker to accentuate red colors and leave other channels a bit dry. rgb(200, 25, 25) +#define LIGHT_COLOR_INTENSE_RED "#C81919" /// Weird color, between yellow and green, very slimy. rgb(175, 200, 75) #define LIGHT_COLOR_SLIME_LAMP "#AFC84B" /// Extremely diluted yellow, close to skin color (for some reason). rgb(250, 225, 175) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 863ade0a5012..57d0eb01291c 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -75,6 +75,9 @@ ///Pipecrawling images #define PIPECRAWL_IMAGES_PLANE 20 +///AI Camera Static +#define CAMERA_STATIC_PLANE 21 + ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else #define HIGH_GAME_PLANE 22 @@ -87,10 +90,6 @@ /// Plane for balloon text (text that fades up) #define BALLOON_CHAT_PLANE 31 -///AI Camera Static -- YOG -#define CAMERA_STATIC_LAYER 40 -#define CAMERA_STATIC_PLANE 40 - //-------------------- HUD --------------------- //HUD layer defines #define HUD_PLANE 40 diff --git a/code/__HELPERS/icon_smoothing.dm b/code/__HELPERS/icon_smoothing.dm index 41b9d266c59e..2b00c7c4db39 100644 --- a/code/__HELPERS/icon_smoothing.dm +++ b/code/__HELPERS/icon_smoothing.dm @@ -156,13 +156,11 @@ /turf/closed/wall/diagonal_smooth(adjacencies) adjacencies = reverse_ndir(..()) if(adjacencies) - var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, plane = FLOOR_PLANE) + var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, offset_spokesman = src, plane = FLOOR_PLANE) var/list/U = list(underlay_appearance) if(fixed_underlay) if(fixed_underlay["space"]) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = SPACE_ICON_STATE - underlay_appearance.plane = PLANE_SPACE + generate_space_underlay(underlay_appearance, src) else underlay_appearance.icon = fixed_underlay["icon"] underlay_appearance.icon_state = fixed_underlay["icon_state"] diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index 206d0b7058f0..96087ba17377 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -7,8 +7,10 @@ var/alpha_ratio = alpha/255 appearance.color = _EMISSIVE_COLOR(alpha_ratio) - // if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace - // stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") + //Test to make sure emissives with broken or missing icon states are created + if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) + if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace + stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") return appearance diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 44448a99468a..dea8b8806d2b 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -14,6 +14,9 @@ if (client && screen.should_show_to(src)) screen.update_for_view(client.view) client.screen += screen + + if(screen.needs_offsetting) + SET_PLANE_EXPLICIT(screen, PLANE_TO_TRUE(screen.plane), src) return screen @@ -67,6 +70,7 @@ var/view = 7 var/severity = 0 var/show_when_dead = FALSE + var/needs_offsetting = TRUE /atom/movable/screen/fullscreen/proc/update_for_view(client_view) if (screen_loc == "CENTER-7,CENTER-7" && view != client_view) @@ -186,15 +190,16 @@ icon_state = "flash" screen_loc = "WEST,SOUTH to EAST,NORTH" plane = LIGHTING_PLANE + layer = LIGHTING_ABOVE_ALL blend_mode = BLEND_OVERLAY show_when_dead = TRUE + needs_offsetting = FALSE //Provides darkness to the back of the lighting plane /atom/movable/screen/fullscreen/lighting_backdrop/lit invisibility = INVISIBILITY_LIGHTING layer = BACKGROUND_LAYER+21 color = "#000" - show_when_dead = TRUE //Provides whiteness in case you don't see lights so everything is still visible /atom/movable/screen/fullscreen/lighting_backdrop/unlit diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index 584d8b4275d9..a50bd33ce52d 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -280,7 +280,7 @@ emissive.remove_filter("lighting_mask") // We max alpha here, so our darkness is actually.. dark // Can't do it before cause it fucks with the filter - add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset)) + add_relay_to(GET_NEW_PLANE(RENDER_PLANE_GAME, offset), relay_color = list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,1)) ///render plate for OOC stuff like ghosts, hud-screen effects, etc /atom/movable/screen/plane_master/rendering_plate/non_game diff --git a/code/controllers/admin.dm b/code/controllers/admin.dm index 524e568b8f56..2c01e55f2626 100644 --- a/code/controllers/admin.dm +++ b/code/controllers/admin.dm @@ -1,7 +1,7 @@ // Clickable stat() button. /obj/effect/statclick name = "Initializing..." - blocks_emissive = NONE + blocks_emissive = EMISSIVE_BLOCK_NONE var/target INITIALIZE_IMMEDIATE(/obj/effect/statclick) diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 1e4f2d754cd6..fbac7a5be042 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -623,7 +623,7 @@ GLOBAL_LIST_EMPTY(teleportlocs) /area/proc/power_change() for(var/obj/machinery/M in src) // for each machine in the area M.power_change() // reverify power status (to update icons etc.) - update_appearance(UPDATE_ICON) + update_appearance() /** * Return the usage of power per channel diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 67607e1d09c2..9a8f477e2a2a 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -1,5 +1,8 @@ /atom/movable layer = OBJ_LAYER + glide_size = 8 + appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE + var/last_move = null var/last_move_time = 0 var/anchored = FALSE @@ -31,8 +34,7 @@ var/atom/movable/moving_from_pull //attempt to resume grab after moving instead of before. var/list/client_mobs_in_contents // This contains all the client mobs within this container var/list/acted_explosions //for explosion dodging - glide_size = 8 - appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE + var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc. var/atom/movable/pulling @@ -50,9 +52,9 @@ /// Either FALSE, [EMISSIVE_BLOCK_GENERIC], or [EMISSIVE_BLOCK_UNIQUE] - var/blocks_emissive = FALSE + var/blocks_emissive = EMISSIVE_BLOCK_NONE ///Internal holder for emissive blocker object, do not use directly use blocks_emissive - var/atom/movable/emissive_blocker/em_block + var/atom/movable/render_step/emissive_blocker/em_block /// The degree of thermal insulation that mobs in list/contents have from the external environment, between 0 and 1 var/contents_thermal_insulation = 0 @@ -64,20 +66,68 @@ ///Highest-intensity light affecting us, which determines our visibility. var/affecting_dynamic_lumi = 0 +/mutable_appearance/emissive_blocker + +/mutable_appearance/emissive_blocker/New() + . = ..() + // Need to do this here because it's overriden by the parent call + color = EM_BLOCK_COLOR + plane = EMISSIVE_PLANE + appearance_flags = EMISSIVE_APPEARANCE_FLAGS /atom/movable/Initialize(mapload, ...) . = ..() - switch(blocks_emissive) - if(EMISSIVE_BLOCK_GENERIC) - update_emissive_block() - if(EMISSIVE_BLOCK_UNIQUE) +#ifdef UNIT_TESTS + if(explosion_block && !HAS_TRAIT(src, TRAIT_BLOCKING_EXPLOSIVES)) + stack_trace("[type] blocks explosives, but does not have the managing element applied") +#endif + +#if EMISSIVE_BLOCK_GENERIC != 0 + #error EMISSIVE_BLOCK_GENERIC is expected to be 0 to faciliate a weird optimization hack where we rely on it being the most common. + #error Read the comment in code/game/atoms_movable.dm for details. +#endif + + // This one is incredible. + // `if (x) else { /* code */ }` is surprisingly fast, and it's faster than a switch, which is seemingly not a jump table. + // From what I can tell, a switch case checks every single branch individually, although sane, is slow in a hot proc like this. + // So, we make the most common `blocks_emissive` value, EMISSIVE_BLOCK_GENERIC, 0, getting to the fast else branch quickly. + // If it fails, then we can check over every value it can be (here, EMISSIVE_BLOCK_UNIQUE is the only one that matters). + // This saves several hundred milliseconds of init time. + if (blocks_emissive) + if (blocks_emissive == EMISSIVE_BLOCK_UNIQUE) render_target = ref(src) - em_block = new(src, render_target) - vis_contents += em_block + em_block = new(null, src) + overlays += em_block + if(managed_overlays) + if(islist(managed_overlays)) + managed_overlays += em_block + else + managed_overlays = list(managed_overlays, em_block) + else + managed_overlays = em_block + else + var/static/mutable_appearance/emissive_blocker/blocker = new() + blocker.icon = icon + blocker.icon_state = icon_state + blocker.dir = dir + blocker.appearance_flags |= appearance_flags + //blocker.plane = GET_NEW_PLANE(EMISSIVE_PLANE, PLANE_TO_OFFSET(plane)) + // Ok so this is really cursed, but I want to set with this blocker cheaply while + // Still allowing it to be removed from the overlays list later + // So I'm gonna flatten it, then insert the flattened overlay into overlays AND the managed overlays list, directly + // I'm sorry + var/mutable_appearance/flat = blocker.appearance + overlays += flat + if(managed_overlays) + if(islist(managed_overlays)) + managed_overlays += flat + else + managed_overlays = list(managed_overlays, flat) + else + managed_overlays = flat if(opacity) AddElement(/datum/element/light_blocking) - switch(light_system) if(MOVABLE_LIGHT) AddComponent(/datum/component/overlay_lighting) @@ -149,6 +199,65 @@ else return fast_emissive_blocker(src) +/// Generates a space underlay for a turf +/// This provides proper lighting support alongside just looking nice +/// Accepts the appearance to make "spaceish", and the turf we're doing this for +/proc/generate_space_underlay(mutable_appearance/underlay_appearance, turf/generate_for) + underlay_appearance.icon = 'icons/turf/space.dmi' + underlay_appearance.icon_state = "0" + SET_PLANE(underlay_appearance, PLANE_SPACE, generate_for) + if(!generate_for.render_target) + generate_for.render_target = ref(generate_for) + var/atom/movable/render_step/emissive_blocker/em_block = new(null, generate_for) + underlay_appearance.overlays += em_block + // We used it because it's convienient and easy, but it's gotta go now or it'll hang refs + QDEL_NULL(em_block) + // We're gonna build a light, and mask it with the base turf's appearance + // grab a 32x32 square of it + // I would like to use GLOB.starbright_overlays here + // But that breaks down for... some? reason. I think recieving a render relay breaks keep_together or something + // So we're just gonna accept that this'll break with starlight color changing. hardly matters since this is really only for offset stuff, but I'd love to fix it someday + var/mutable_appearance/light = new(GLOB.starlight_objects[GET_TURF_PLANE_OFFSET(generate_for) + 1]) + light.render_target = "" + light.appearance_flags |= KEEP_TOGETHER + // Now apply a copy of the turf, set to multiply + // This will multiply against our light, so we only light up the bits that aren't "on" the wall + var/mutable_appearance/mask = new(generate_for.appearance) + mask.blend_mode = BLEND_MULTIPLY + mask.render_target = "" + mask.pixel_x = 0 + mask.pixel_y = 0 + mask.pixel_w = 0 + mask.pixel_z = 0 + mask.transform = null + mask.underlays = list() // Begone foul lighting overlay + SET_PLANE(mask, FLOAT_PLANE, generate_for) + mask.layer = FLOAT_LAYER + + // Bump the opacity to full, will this work? + mask.color = list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,255, 0,0,0,0) + light.overlays += mask + underlay_appearance.overlays += light + + // Now, we're going to make a copy of the mask. Instead of using it to multiply against our light + // We're going to use it to multiply against the turf lighting plane. Going to mask away the turf light + // And rely on LIGHTING_MASK_LAYER to ensure we mask ONLY that bit + var/mutable_appearance/turf_mask = new(mask.appearance) + SET_PLANE(turf_mask, LIGHTING_PLANE, generate_for) + turf_mask.layer = LIGHTING_MASK_LAYER + /// Any color becomes white. Anything else is black, and it's fully opaque + /// Ought to work + turf_mask.color = list(255,255,255,0, 255,255,255,0, 255,255,255,0, 0,0,0,0, 0,0,0,255) + underlay_appearance.overlays += turf_mask + +/atom/movable/update_overlays() + var/list/overlays = ..() + var/emissive_block = update_emissive_block() + if(emissive_block) + // Emissive block should always go at the beginning of the list + overlays.Insert(1, emissive_block) + return overlays + /atom/movable/proc/can_zFall(turf/source, levels = 1, turf/target, direction) if(!direction) direction = DOWN @@ -1155,61 +1264,3 @@ currently_z_moving = max(currently_z_moving, new_z_moving_value) return currently_z_moving > old_z_moving_value -/// Generates a space underlay for a turf -/// This provides proper lighting support alongside just looking nice -/// Accepts the appearance to make "spaceish", and the turf we're doing this for -/proc/generate_space_underlay(mutable_appearance/underlay_appearance, turf/generate_for) - underlay_appearance.icon = 'icons/turf/space.dmi' - underlay_appearance.icon_state = "space" - SET_PLANE(underlay_appearance, PLANE_SPACE, generate_for) - if(!generate_for.render_target) - generate_for.render_target = ref(generate_for) - var/atom/movable/render_step/emissive_blocker/em_block = new(null, generate_for) - underlay_appearance.overlays += em_block - // We used it because it's convienient and easy, but it's gotta go now or it'll hang refs - QDEL_NULL(em_block) - // We're gonna build a light, and mask it with the base turf's appearance - // grab a 32x32 square of it - // I would like to use GLOB.starbright_overlays here - // But that breaks down for... some? reason. I think recieving a render relay breaks keep_together or something - // So we're just gonna accept that this'll break with starlight color changing. hardly matters since this is really only for offset stuff, but I'd love to fix it someday - var/mutable_appearance/light = new(GLOB.starlight_objects[GET_TURF_PLANE_OFFSET(generate_for) + 1]) - light.render_target = "" - light.appearance_flags |= KEEP_TOGETHER - // Now apply a copy of the turf, set to multiply - // This will multiply against our light, so we only light up the bits that aren't "on" the wall - var/mutable_appearance/mask = new(generate_for.appearance) - mask.blend_mode = BLEND_MULTIPLY - mask.render_target = "" - mask.pixel_x = 0 - mask.pixel_y = 0 - mask.pixel_w = 0 - mask.pixel_z = 0 - mask.transform = null - mask.underlays = list() // Begone foul lighting overlay - SET_PLANE(mask, FLOAT_PLANE, generate_for) - mask.layer = FLOAT_LAYER - - // Bump the opacity to full, will this work? - mask.color = list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,255, 0,0,0,0) - light.overlays += mask - underlay_appearance.overlays += light - - // Now, we're going to make a copy of the mask. Instead of using it to multiply against our light - // We're going to use it to multiply against the turf lighting plane. Going to mask away the turf light - // And rely on LIGHTING_MASK_LAYER to ensure we mask ONLY that bit - var/mutable_appearance/turf_mask = new(mask.appearance) - SET_PLANE(turf_mask, LIGHTING_PLANE, generate_for) - turf_mask.layer = LIGHTING_MASK_LAYER - /// Any color becomes white. Anything else is black, and it's fully opaque - /// Ought to work - turf_mask.color = list(255,255,255,0, 255,255,255,0, 255,255,255,0, 0,0,0,0, 0,0,0,255) - underlay_appearance.overlays += turf_mask - -/atom/movable/update_overlays() - var/list/overlays = ..() - var/emissive_block = update_emissive_block() - if(emissive_block) - // Emissive block should always go at the beginning of the list - overlays.Insert(1, emissive_block) - return overlays diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index 8a017d1be4f5..3960ef4f6ddc 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -95,6 +95,7 @@ Class Procs: anchored = TRUE interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/stat = 0 var/use_power = IDLE_POWER_USE diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm index 53edc780a79c..f65c784142ee 100644 --- a/code/game/machinery/barsigns.dm +++ b/code/game/machinery/barsigns.dm @@ -72,7 +72,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) return if(chosen_sign && chosen_sign.light_mask) - SSvis_overlays.add_vis_overlay(src, icon, light_mask, EMISSIVE_LAYER, EMISSIVE_PLANE) . += emissive_appearance(icon, "[chosen_sign.icon_state]-light-mask", src) /obj/machinery/barsign/update_appearance(updates=ALL) diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index a52037615b75..d4ad71aa8e3a 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -10,16 +10,21 @@ integrity_failure = 100 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 40, ACID = 20) clicksound = "keyboard" - light_system = STATIC_LIGHT - light_range = 2 - light_power = 1 - light_on = TRUE + /// How bright we are when turned on. + var/brightness_on = 1 + /// Icon_state of the keyboard overlay. var/icon_keyboard = "generic_key" + /// Should we render an unique icon for the keyboard when off? + var/keyboard_change_icon = TRUE + /// Icon_state of the emissive screen overlay. var/icon_screen = "generic" - var/clockwork = FALSE - var/time_to_scewdrive = 20 + /// Time it takes to deconstruct with a screwdriver. + var/time_to_unscrew = 2 SECONDS + /// Are we authenticated to use this? Used by things like comms console, security and medical data, and apc controller. var/authenticated = FALSE + var/clockwork = FALSE + /obj/machinery/computer/Initialize(mapload, obj/item/circuitboard/C) . = ..() if(mapload) @@ -86,17 +91,23 @@ /obj/machinery/computer/update_overlays() . = ..() - if(stat & NOPOWER) - . += "[icon_keyboard]_off" - return - . += icon_keyboard + if(icon_keyboard) + if(keyboard_change_icon && (stat & NOPOWER)) + . += "[icon_keyboard]_off" + else + . += icon_keyboard - // This whole block lets screens ignore lighting and be visible even in the darkest room - var/overlay_state = icon_screen if(stat & BROKEN) - overlay_state = "[icon_state]_broken" - . += mutable_appearance(icon, overlay_state) - . += emissive_appearance(icon, icon_screen, src) + . += mutable_appearance(icon, "[icon_state]_broken") + return // If we don't do this broken computers glow in the dark. + + if(stat & NOPOWER) // Your screen can't be on if you've got no damn charge + return + + // This lets screens ignore lighting and be visible even in the darkest room + if(icon_screen) + . += mutable_appearance(icon, icon_screen) + . += emissive_appearance(icon, icon_screen, src) /obj/machinery/computer/power_change() . = ..() @@ -105,14 +116,14 @@ if(stat & NOPOWER) set_light_on(FALSE) else - set_light_on(TRUE) + set_light_on(brightness_on) /obj/machinery/computer/screwdriver_act(mob/living/user, obj/item/I) if(..()) return TRUE if(circuit && !(flags_1&NODECONSTRUCT_1)) to_chat(user, span_notice("You start to disconnect the monitor...")) - if(I.use_tool(src, user, time_to_scewdrive, volume=50)) + if(I.use_tool(src, user, time_to_unscrew, volume=50)) deconstruct(TRUE, user) return TRUE diff --git a/code/game/machinery/computer/law.dm b/code/game/machinery/computer/law.dm index 1d94d7aaa442..c2457531d61b 100644 --- a/code/game/machinery/computer/law.dm +++ b/code/game/machinery/computer/law.dm @@ -5,7 +5,7 @@ icon_screen = "command" var/obj/item/gps/internal/ai_upload/embedded_gps var/obj/item/gps/internal/ai_upload/embedded_gps_type = /obj/item/gps/internal/ai_upload - time_to_scewdrive = 60 + time_to_unscrew = 6 SECONDS /obj/item/gps/internal/ai_upload icon_state = null diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index fcb931fa2f4a..345c410881b4 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -70,7 +70,8 @@ ) interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN - + blocks_emissive = EMISSIVE_BLOCK_NONE + /// How much are wires secured var/security_level = 0 /// If 1, AI control is disabled until the AI hacks back in and disables the lock. If 2, the AI has bypassed the lock. If -1, the control is enabled but the AI had bypassed it earlier, so if it is disabled again the AI would have no trouble getting back in. diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm index 4d298a074a71..171f0c510fc7 100644 --- a/code/game/machinery/doors/door.dm +++ b/code/game/machinery/doors/door.dm @@ -15,6 +15,7 @@ damage_deflection = 10 interaction_flags_atom = INTERACT_ATOM_UI_INTERACT + blocks_emissive = EMISSIVE_BLOCK_UNIQUE /// TRUE means density will be set as soon as the door begins to close var/air_tight = FALSE diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index 9a25df359b09..d946d60f8ffc 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -26,8 +26,8 @@ power_channel = AREA_USAGE_ENVIRON resistance_flags = FIRE_PROOF - light_power = 0 - light_range = 7 + light_power = 1 + light_range = 1.6 light_color = "#ff3232" //Trick to get the glowing overlay visible from a distance luminosity = 1 @@ -56,7 +56,7 @@ panel_open = TRUE pixel_x = (dir & 3)? 0 : (dir == 4 ? -24 : 24) pixel_y = (dir & 3)? (dir ==1 ? -24 : 24) : 0 - update_appearance(UPDATE_ICON) + update_appearance() myarea = get_area(src) LAZYADD(myarea.firealarms, src) radio = new(src) @@ -84,42 +84,40 @@ /obj/machinery/firealarm/update_overlays() . = ..() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(stat & (NOPOWER|BROKEN)) return - . += "fire_overlay" - if(is_station_level(z)) - . += "fire_[GLOB.security_level]" - SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "fire_[GLOB.security_level]", layer, EMISSIVE_PLANE, dir) - . += emissive_appearance(icon, "fire_level_e", src, alpha = src.alpha) + var/current_level = GLOB.security_level + . += mutable_appearance(icon, "fire_[GLOB.security_level]") + . += emissive_appearance(icon, "fire_[GLOB.security_level]", src) + switch(current_level) + if(SEC_LEVEL_GREEN) + set_light(l_color = LIGHT_COLOR_BLUEGREEN) + if(SEC_LEVEL_BLUE) + set_light(l_color = LIGHT_COLOR_ELECTRIC_CYAN) + if(SEC_LEVEL_RED) + set_light(l_color = LIGHT_COLOR_FLARE) + if(SEC_LEVEL_DELTA) + set_light(l_color = LIGHT_COLOR_INTENSE_RED) else - . += "fire_[SEC_LEVEL_GREEN]" - SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "fire_[SEC_LEVEL_GREEN]", layer, EMISSIVE_PLANE, dir) - . += emissive_appearance(icon, "fire_level_e", src, alpha = src.alpha) + . += mutable_appearance(icon, "fire_[SEC_LEVEL_GREEN]") + . += emissive_appearance(icon, "fire_[SEC_LEVEL_GREEN]", src) set_light(l_color = LIGHT_COLOR_BLUE) var/area/A = src.loc A = A.loc if(!A.fire && !A.delta_light) - . += "fire_off" - SSvis_overlays.add_vis_overlay(src, icon, "fire_off", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "fire_off", layer, EMISSIVE_PLANE, dir) + . += mutable_appearance(icon, "fire_off") + . += emissive_appearance(icon, "fire_off", src) else if(obj_flags & EMAGGED) - . += "fire_emagged" - SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "fire_emagged", layer, EMISSIVE_PLANE, dir) - . += emissive_appearance(icon, "fire_alerting_e", src, alpha = src.alpha) + . += mutable_appearance(icon, "fire_emagged") + . += emissive_appearance(icon, "fire_emagged", src) set_light(l_color = LIGHT_COLOR_RED) else - . += "fire_on" - SSvis_overlays.add_vis_overlay(src, icon, "fire_on", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "fire_on", layer, EMISSIVE_PLANE, dir) - . += emissive_appearance(icon, "fire_alerting_e", src, alpha = src.alpha) + . += mutable_appearance(icon, "fire_on") + . += emissive_appearance(icon, "fire_on", src) set_light(l_color = LIGHT_COLOR_RED) /obj/machinery/firealarm/emp_act(severity) @@ -135,7 +133,7 @@ if(obj_flags & EMAGGED) return FALSE obj_flags |= EMAGGED - update_appearance(UPDATE_ICON) + update_appearance() if(user) user.visible_message(span_warning("Sparks fly out of [src]!"), span_notice("You emag [src], disabling its thermal sensors.")) @@ -214,7 +212,7 @@ W.play_tool_sound(src) panel_open = !panel_open to_chat(user, span_notice("The wires have been [panel_open ? "exposed" : "unexposed"].")) - update_appearance(UPDATE_ICON) + update_appearance() return if(panel_open) @@ -247,7 +245,7 @@ W.play_tool_sound(src) new /obj/item/stack/cable_coil(user.loc, 5) to_chat(user, span_notice("You cut the wires from \the [src].")) - update_appearance(UPDATE_ICON) + update_appearance() return else if(W.force) //hit and turn it on @@ -265,7 +263,7 @@ coil.use(5) buildstage = 2 to_chat(user, span_notice("You wire \the [src].")) - update_appearance(UPDATE_ICON) + update_appearance() return else if(W.tool_behaviour == TOOL_CROWBAR) @@ -280,14 +278,14 @@ to_chat(user, span_notice("You pry out the circuit.")) new /obj/item/electronics/firealarm(user.loc) buildstage = 0 - update_appearance(UPDATE_ICON) + update_appearance() return if(0) if(istype(W, /obj/item/electronics/firealarm)) to_chat(user, span_notice("You insert the circuit.")) qdel(W) buildstage = 1 - update_appearance(UPDATE_ICON) + update_appearance() return else if(istype(W, /obj/item/electroadaptive_pseudocircuit)) @@ -297,7 +295,7 @@ user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \ span_notice("You adapt a fire alarm circuit and slot it into the assembly.")) buildstage = 1 - update_appearance(UPDATE_ICON) + update_appearance() return else if(W.tool_behaviour == TOOL_WRENCH) @@ -323,7 +321,7 @@ user.visible_message(span_notice("[user] fabricates a circuit and places it into [src]."), \ span_notice("You adapt a fire alarm circuit and slot it into the assembly.")) buildstage = 1 - update_appearance(UPDATE_ICON) + update_appearance() return TRUE return FALSE @@ -362,11 +360,11 @@ if(fire == !!light_power) return // do nothing if we're already active if(fire) - set_light(l_power = 0.8) - update_appearance(UPDATE_ICON) + set_light(l_power = 3) + update_appearance() else - set_light(l_power = 0) - update_appearance(UPDATE_ICON) + set_light(l_power = 1) + update_appearance() /* * Return of the Return of the Party button diff --git a/code/game/machinery/lightswitch.dm b/code/game/machinery/lightswitch.dm index 2c93e617313a..3830ecb17ec3 100644 --- a/code/game/machinery/lightswitch.dm +++ b/code/game/machinery/lightswitch.dm @@ -62,8 +62,8 @@ desc = "Make dark." power_channel = AREA_USAGE_LIGHT - light_power = 0 - light_range = 7 + ///Range of the light emitted when powered, but off + var/light_on_range = 1 /// Set this to a string, path, or area instance to control that area /// instead of the switch's location. @@ -86,7 +86,7 @@ if(mapload) construction_state = LIGHT_CONSTRUCTED - update_appearance(UPDATE_ICON) + update_appearance() if(mapload) return INITIALIZE_HINT_LATELOAD return INITIALIZE_HINT_NORMAL @@ -99,25 +99,39 @@ return turn_off() +/obj/machinery/light_switch/update_appearance(updates=ALL) + . = ..() + luminosity = (stat & NOPOWER) ? 0 : 1 + +/obj/machinery/light_switch/update_icon_state() + set_light(area.lightswitch ? 0 : light_on_range) + switch(construction_state) + if(LIGHT_BARE) + icon_state = "light-b" + if(LIGHT_WIRE) + icon_state = "light-w" + if(LIGHT_CONSTRUCTED) + icon_state = "light-c" + + return ..() + /obj/machinery/light_switch/update_overlays() . = ..() if(stat & (NOPOWER|BROKEN)) return if(construction_state != LIGHT_CONSTRUCTED) return - if(area.lightswitch) - . += "light1" - else - . += "light0" + . += mutable_appearance(icon, "[area.lightswitch ? "light1" : "light0"]") + . += emissive_appearance(icon, "[area.lightswitch ? "light1" : "light0"]", src) /obj/machinery/light_switch/proc/turn_off() if(!area.lightswitch) return area.lightswitch = FALSE - area.update_icon() + area.update_appearance() for(var/obj/machinery/light_switch/L in area) - L.update_icon() + L.update_appearance() area.power_change() @@ -125,10 +139,10 @@ if(area.lightswitch) return area.lightswitch = TRUE - area.update_icon() + area.update_appearance() for(var/obj/machinery/light_switch/L in area) - L.update_icon() + L.update_appearance() area.power_change() @@ -146,11 +160,10 @@ . = ..() area.lightswitch = !area.lightswitch - area.update_appearance(UPDATE_ICON) play_click_sound("button") for(var/obj/machinery/light_switch/L in area) - L.update_appearance(UPDATE_ICON) + L.update_appearance() area.power_change() @@ -161,7 +174,7 @@ if(istype(c) && c.use(1)) to_chat(user, span_notice("You insert wiring into [src].")) construction_state = LIGHT_WIRE - update_appearance(UPDATE_ICON) + update_appearance() return if(W.tool_behaviour == TOOL_WRENCH) W.play_tool_sound(src) @@ -174,7 +187,7 @@ to_chat(user, span_notice("You cut the wires out.")) new /obj/item/stack/cable_coil(loc, 1) construction_state = LIGHT_BARE - update_appearance(UPDATE_ICON) + update_appearance() return if(panel_open && is_wire_tool(W)) wires.interact(user) @@ -184,7 +197,7 @@ to_chat(user, span_notice("You screw the cover on.")) panel_open = FALSE construction_state = LIGHT_CONSTRUCTED - update_appearance(UPDATE_ICON) + update_appearance() return if(LIGHT_CONSTRUCTED) if(W.tool_behaviour == TOOL_SCREWDRIVER) @@ -192,21 +205,10 @@ to_chat(user, span_notice("You take the cover off.")) panel_open = TRUE construction_state = LIGHT_WIRE - update_appearance(UPDATE_ICON) + update_appearance() return return ..() -/obj/machinery/light_switch/update_icon_state() - . = ..() - switch(construction_state) - if(LIGHT_BARE) - icon_state = "light-b" - if(LIGHT_WIRE) - icon_state = "light-w" - if(LIGHT_CONSTRUCTED) - icon_state = "light-c" - - /obj/machinery/light_switch/power_change() if(area == get_area(src)) return ..() diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm index 75e316392d43..466411473c78 100644 --- a/code/game/machinery/porta_turret/portable_turret.dm +++ b/code/game/machinery/porta_turret/portable_turret.dm @@ -9,6 +9,7 @@ icon = 'icons/obj/turrets.dmi' icon_state = "turretCover" base_icon_state = "standard" + blocks_emissive = EMISSIVE_BLOCK_UNIQUE layer = OBJ_LAYER invisibility = INVISIBILITY_OBSERVER //the turret is invisible if it's inside its cover density = TRUE diff --git a/code/game/objects/effects/misc.dm b/code/game/objects/effects/misc.dm index 9e64edab098d..0086228f3d94 100644 --- a/code/game/objects/effects/misc.dm +++ b/code/game/objects/effects/misc.dm @@ -77,6 +77,7 @@ light_color = "#FFFFFF" light_system = MOVABLE_LIGHT light_range = MINIMUM_USEFUL_LIGHT_RANGE + blocks_emissive = EMISSIVE_BLOCK_NONE mouse_opacity = MOUSE_OPACITY_TRANSPARENT /obj/effect/dummy/lighting_obj/Initialize(mapload, range, power, color, duration) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index 9dd4ff9c89a1..0366d3874365 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -4,6 +4,7 @@ max_integrity = 300 interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT layer = BELOW_OBJ_LAYER + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/broken = 0 //similar to machinery's stat BROKEN diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index 16f0459abe58..75136c9095e9 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -17,6 +17,7 @@ GLOBAL_LIST_EMPTY(lockers) max_integrity = 200 integrity_failure = 50 armor = list(MELEE = 20, BULLET = 10, LASER = 10, ENERGY = 0, BOMB = 10, BIO = 0, RAD = 0, FIRE = 70, ACID = 60) + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/breakout_time = 1200 var/message_cooldown var/can_weld_shut = TRUE @@ -33,6 +34,7 @@ GLOBAL_LIST_EMPTY(lockers) var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable. var/anchorable = TRUE var/icon_welded = "welded" + var/icon_broken = "sparking" /// Protection against weather that being inside of it provides. var/list/weather_protection = null /// How close being inside of the thing provides complete pressure safety. Must be between 0 and 1! @@ -56,7 +58,7 @@ GLOBAL_LIST_EMPTY(lockers) if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents . = INITIALIZE_HINT_LATELOAD - update_appearance(UPDATE_ICON) + update_appearance() PopulateContents() var/static/list/loc_connections = list( COMSIG_ATOM_MAGICALLY_UNLOCKED = PROC_REF(on_magic_unlock), @@ -84,10 +86,16 @@ GLOBAL_LIST_EMPTY(lockers) update_appearance() . = TRUE +/obj/structure/closet/update_appearance(updates=ALL) + . = ..() + if(opened || broken || !secure) + luminosity = 0 + return + luminosity = 1 + /obj/structure/closet/update_overlays() . = ..() - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) - luminosity = 0 + //SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(opened) layer = BELOW_OBJ_LAYER if(is_animating_door) @@ -106,14 +114,17 @@ GLOBAL_LIST_EMPTY(lockers) . += "[icon_state]_door" if(welded) . += icon_welded - if(secure && !broken) + if(broken && secure) + . += mutable_appearance(icon, icon_broken, alpha = alpha) + . += emissive_appearance(icon, icon_broken, src, alpha = alpha) + return + if(broken || !secure) + return //Overlay is similar enough for both that we can use the same mask for both - luminosity = 1 - SSvis_overlays.add_vis_overlay(src, icon, "locked", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha) - if(locked) - . += "locked" - else - . += "unlocked" + //luminosity = 1 + //SSvis_overlays.add_vis_overlay(src, icon, "locked", EMISSIVE_LAYER, EMISSIVE_PLANE, dir, alpha) + . += emissive_appearance(icon, "locked", src, alpha = src.alpha) + . += locked ? "locked" : "unlocked" /obj/structure/closet/proc/animate_door(closing = FALSE) if(!door_anim_time) @@ -143,7 +154,7 @@ GLOBAL_LIST_EMPTY(lockers) /obj/structure/closet/proc/end_door_animation() is_animating_door = FALSE vis_contents -= door_obj - update_appearance(UPDATE_ICON) + update_appearance() /obj/structure/closet/proc/get_door_transform(angle) var/matrix/M = matrix() @@ -222,7 +233,7 @@ GLOBAL_LIST_EMPTY(lockers) density = FALSE dump_contents() animate_door(FALSE) - update_appearance(UPDATE_ICON) + update_appearance() update_airtightness() return 1 @@ -275,7 +286,7 @@ GLOBAL_LIST_EMPTY(lockers) opened = FALSE density = TRUE animate_door(TRUE) - update_appearance(UPDATE_ICON) + update_appearance() update_airtightness() close_storage(user) return TRUE @@ -349,7 +360,7 @@ GLOBAL_LIST_EMPTY(lockers) user.visible_message(span_notice("[user] [welded ? "welds shut" : "unwelded"] \the [src]."), span_notice("You [welded ? "weld" : "unwelded"] \the [src] with \the [W]."), span_italics("You hear welding.")) - update_appearance(UPDATE_ICON) + update_appearance() else if(W.tool_behaviour == TOOL_WRENCH && anchorable) if(isinspace() && !anchored) return @@ -525,7 +536,7 @@ GLOBAL_LIST_EMPTY(lockers) locked = !locked user.visible_message(span_notice("[user] [locked ? null : "un"]locks [src]."), span_notice("You [locked ? null : "un"]lock [src].")) - update_appearance(UPDATE_ICON) + update_appearance() else if(!silent) to_chat(user, span_notice("Access Denied")) else if(secure && broken) @@ -540,7 +551,7 @@ GLOBAL_LIST_EMPTY(lockers) playsound(src, "sparks", 50, 1) broken = TRUE locked = FALSE - update_appearance(UPDATE_ICON) + update_appearance() return TRUE /obj/structure/closet/get_remote_view_fullscreens(mob/user) @@ -557,7 +568,7 @@ GLOBAL_LIST_EMPTY(lockers) if(secure && !broken && !(. & EMP_PROTECT_SELF)) if(prob(5 * severity)) locked = !locked - update_appearance(UPDATE_ICON) + update_appearance() if(prob(2 * severity) && !opened) if(!locked) open() diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm index 30862146bfb1..7ae13941e176 100644 --- a/code/game/objects/structures/statues.dm +++ b/code/game/objects/structures/statues.dm @@ -15,6 +15,7 @@ var/material_drop_type = /obj/item/stack/sheet/metal var/impressiveness = 15 CanAtmosPass = ATMOS_PASS_DENSITY + blocks_emissive = EMISSIVE_BLOCK_UNIQUE /obj/structure/statue/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm index c1050969b625..424517cfbfbe 100644 --- a/code/game/objects/structures/watercloset.dm +++ b/code/game/objects/structures/watercloset.dm @@ -387,26 +387,34 @@ opacity = FALSE density = FALSE var/open = TRUE + /// if it can be seen through when closed + var/opaque_closed = FALSE + +/obj/structure/curtain/Initialize(mapload) + // see-through curtains should let emissives shine through + if(!opaque_closed) + blocks_emissive = EMISSIVE_BLOCK_NONE + return ..() /obj/structure/curtain/proc/toggle() open = !open - update_appearance(UPDATE_ICON) - -/obj/structure/curtain/update_icon_state() - . = ..() - if(!open) - icon_state = "closed" - layer = WALL_OBJ_LAYER - density = TRUE - open = FALSE - set_opacity(TRUE) - - else - icon_state = "open" + if(open) layer = SIGN_LAYER - density = FALSE - open = TRUE + SET_PLANE_IMPLICIT(src, GAME_PLANE) + set_density(FALSE) set_opacity(FALSE) + else + layer = WALL_OBJ_LAYER + SET_PLANE_IMPLICIT(src, GAME_PLANE_UPPER) + set_density(TRUE) + if(opaque_closed) + set_opacity(TRUE) + + update_appearance() + +/obj/structure/curtain/update_icon_state() + icon_state = "[open ? "open" : "closed"]" + return ..() /obj/structure/curtain/attackby(obj/item/W, mob/user) if (istype(W, /obj/item/toy/crayon)) diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index d4a01fd2a175..6726248bf79d 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -325,7 +325,7 @@ //This proc is used to update the icons of nearby windows. /obj/structure/window/proc/update_nearby_icons() - update_appearance(UPDATE_ICON) + update_appearance() if(smooth) queue_smooth_neighbors(src) diff --git a/code/game/turfs/closed.dm b/code/game/turfs/closed.dm index 114bcd368b51..07e3ca8f1869 100644 --- a/code/game/turfs/closed.dm +++ b/code/game/turfs/closed.dm @@ -1,5 +1,6 @@ /turf/closed layer = CLOSED_TURF_LAYER + plane = WALL_PLANE opacity = TRUE density = TRUE blocks_air = TRUE diff --git a/code/game/turfs/space/space.dm b/code/game/turfs/space/space.dm index e5ce5053fad7..d9dac63995ee 100644 --- a/code/game/turfs/space/space.dm +++ b/code/game/turfs/space/space.dm @@ -98,8 +98,8 @@ GLOBAL_LIST_EMPTY(starlight) stack_trace("Warning: [src]([type]) initialized multiple times!") flags_1 |= INITIALIZED_1 - var/area/A = loc - if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) + var/area/our_area = loc + if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(our_area)) add_overlay(/obj/effect/fullbright) if (light_system == STATIC_LIGHT && light_power && light_range) diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 39d0c255272a..3ab965eb643e 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -8,7 +8,7 @@ /turf/open/space/transit/Initialize(mapload) . = ..() - update_appearance(UPDATE_ICON) + update_appearance() RegisterSignal(src, COMSIG_TURF_RESERVATION_RELEASED, PROC_REF(launch_contents)) /turf/open/space/transit/Destroy() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 9173c4486564..0a817e55332b 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -2,6 +2,7 @@ GLOBAL_LIST_EMPTY(station_turfs) /turf icon = 'icons/turf/floors.dmi' + vis_flags = VIS_INHERIT_ID // Important for interaction with and visualization of openspace. level = 1 luminosity = 1 @@ -92,8 +93,8 @@ GLOBAL_LIST_EMPTY(station_turfs) for(var/atom/movable/AM in src) Entered(AM) - var/area/A = loc - if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(A)) + var/area/our_area = loc + if(!IS_DYNAMIC_LIGHTING(src) && IS_DYNAMIC_LIGHTING(our_area)) add_overlay(/obj/effect/fullbright) if(requires_activation) diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index b51ec1c2a299..4a26ae86279e 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -15,7 +15,7 @@ return . = ..() - current_underlay = mutable_appearance(LIGHTING_ICON, "atransparent", source.z, source, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) + current_underlay = mutable_appearance(LIGHTING_ICON, "transparent", source.z, source, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) affected_turf = source if (affected_turf.lighting_object) @@ -88,12 +88,12 @@ if((rr & gr & br & ar) && (rg + gg + bg + ag + rb + gb + bb + ab == 8)) //anything that passes the first case is very likely to pass the second, and addition is a little faster in this case affected_turf.underlays -= current_underlay - current_underlay.icon_state = "atransparent" + current_underlay.icon_state = "lighting_transparent" current_underlay.color = null affected_turf.underlays += current_underlay else if(!set_luminosity) affected_turf.underlays -= current_underlay - current_underlay.icon_state = "adark" + current_underlay.icon_state = "lighting_dark" current_underlay.color = null affected_turf.underlays += current_underlay else diff --git a/code/modules/mining/lavaland/ruins/gym.dm b/code/modules/mining/lavaland/ruins/gym.dm index 54d4a61cabf5..0ecbf2db6693 100644 --- a/code/modules/mining/lavaland/ruins/gym.dm +++ b/code/modules/mining/lavaland/ruins/gym.dm @@ -24,6 +24,7 @@ desc = "Just looking at this thing makes you feel tired." density = TRUE anchored = TRUE + blocks_emissive = EMISSIVE_BLOCK_UNIQUE var/icon_state_inuse /obj/structure/weightmachine/proc/AnimateMachine(mob/living/user) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index b11914cd7329..5250deb93416 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -10,6 +10,7 @@ initial_language_holder = /datum/language_holder/alien bubble_icon = "alien" type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno + blocks_emissive = EMISSIVE_BLOCK_UNIQUE var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie var/has_fine_manipulation = 0 diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm index 3e46bd2d5f20..39c2d4f18ec9 100644 --- a/code/modules/mob/living/carbon/carbon_defines.dm +++ b/code/modules/mob/living/carbon/carbon_defines.dm @@ -4,6 +4,7 @@ possible_a_intents = list(INTENT_HELP, INTENT_HARM) hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD) has_limbs = 1 + blocks_emissive = EMISSIVE_BLOCK_NONE held_items = list(null, null) /// List of /obj/item/organ in the mob. /// They don't go in the contents for some reason I don't want to know. diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index 91345e031a87..cf4f9fca9fcb 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -1,3 +1,7 @@ +// CAMERA NET +// +// The datum containing all the chunks. + GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -5,38 +9,54 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/cameras = list() + var/list/obj/machinery/camera/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - // The object used for the clickable stat() button. - var/obj/effect/statclick/statclick - ///The image given to the effect in vis_contents on AI clients - var/image/obscured + + /// List of images cloned by all chunk static images put onto turfs cameras cant see + /// Indexed by the plane offset to use + var/list/image/obscured_images /datum/cameranet/New() - obscured = new('icons/effects/cameravis.dmi') - obscured.plane = CAMERA_STATIC_PLANE - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE + obscured_images = list() + update_offsets(SSmapping.max_plane_offset) + RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) + +/datum/cameranet/proc/update_offsets(new_offset) + for(var/i in length(obscured_images) to new_offset) + var/image/obscured = new('icons/effects/cameravis.dmi') + SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE + obscured_images += obscured + +/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) + SIGNAL_HANDLER + update_offsets(new_offset) /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + if(GET_LOWEST_STACK_OFFSET(z) != 0) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + return chunks["[x],[y],[lowest.z]"] + return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) - var/key = "[x],[y],[z]" + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) + var/turf/lowest = get_lowest_turf(locate(x, y, z)) + var/key = "[x],[y],[lowest.z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, z) + chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) -/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. +/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -47,21 +67,18 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() + //Get the eye's turf in case it's located in an object like a mecha + var/turf/eye_turf = get_turf(eye) if(eye.loc) - var/x_value = eye.x - var/y_value = eye.y - var/z_value = eye.z - // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) - + var/x1 = max(1, eye_turf.x - static_range) + var/y1 = max(1, eye_turf.y - static_range) + var/x2 = min(world.maxx, eye_turf.x + static_range) + var/y2 = min(world.maxy, eye_turf.y + static_range) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, z_value) + visibleChunks |= getCameraChunk(x, y, eye_turf.z) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -72,7 +89,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -93,10 +110,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) - if(c.can_use()) - majorChunkChange(c, 1) +/** + * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. + * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement + * to change the time between static updates. +*/ +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) + if(updating_camera.can_use()) + majorChunkChange(updating_camera, 1, update_delay_buffer) /** * Never access this proc directly!!!! @@ -104,37 +125,52 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. + * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement + * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice) - if(!c) - return +/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) + if(QDELETED(c) && choice == 1) + CRASH("Tried to add a qdeleting camera to the net") var/turf/T = get_turf(c) if(T) - var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras -= c + chunk.cameras["[T.z]"] -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras |= c - chunk.hasChanged() + chunk.cameras["[T.z]"] |= c + chunk.hasChanged(update_delay_buffer = update_delay_buffer) + +/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] +/// For use in sensitive code, be careful with it +/datum/cameranet/proc/bareMajorChunkChange(turf/changed) + var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) + var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) + var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) + var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) + for(var/y = y1; y <= y2; y += CHUNK_SIZE) + var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) + chunk?.hasChanged() /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) + if(!position) + return return checkTurfVis(position) - /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -142,22 +178,25 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/stat_entry() - if(!statclick) - statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) - - stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) +/datum/cameranet/proc/getTurfVis(turf/position) + RETURN_TYPE(/datum/camerachunk) + var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + if(!chunk) + return FALSE + if(chunk.changed) + chunk.hasChanged(1) // Update now, no matter if it's visible or not. + if(chunk.visibleTurfs[position]) + return chunk /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR + appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT - layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index abf891b011ac..fca64a1e1681 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -11,20 +11,21 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid + ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs + ///list of all turfs, associative with that turf's static image + ///turf -> /image var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() - ///images created to represent obscured turfs - var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/z = 0 + var/lower_z + var/upper_z /// Add an AI eye to the chunk, then update if changed. /datum/camerachunk/proc/add(mob/camera/aiEye/eye) @@ -55,28 +56,33 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. + * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and + * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because + * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0) +/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/datum/camerachunk/proc/update() +/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below +/datum/camerachunk/proc/update(partial_update = FALSE) var/list/updated_visible_turfs = list() - for(var/obj/machinery/camera/current_camera as anything in cameras) - if(!current_camera || !current_camera.can_use()) - continue + for(var/z_level in lower_z to upper_z) + for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -91,31 +97,24 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] - if(!static_image_to_deallocate) + var/image/static_image = obscuredTurfs[visible_turf] + if(!static_image) continue - static_image_to_deallocate.loc = null - active_static_images -= static_image_to_deallocate - inactive_static_images += static_image_to_deallocate - + active_static_images -= static_image obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] - if(!static_image_to_allocate) - stack_trace("somehow a camera chunk ran out of static images!") + var/image/static_image = turfs[obscured_turf] + if(!static_image) + stack_trace("somehow a camera chunk used a turf it didn't contain!!") break - obscuredTurfs[obscured_turf] = static_image_to_allocate - static_image_to_allocate.loc = obscured_turf - - inactive_static_images -= static_image_to_allocate - active_static_images += static_image_to_allocate - + obscuredTurfs[obscured_turf] = static_image + active_static_images += static_image visibleTurfs = updated_visible_turfs changed = FALSE @@ -127,39 +126,52 @@ client.images += active_static_images + /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, z) - x &= ~(CHUNK_SIZE - 1) - y &= ~(CHUNK_SIZE - 1) +/datum/camerachunk/New(x, y, lower_z) + x = GET_CHUNK_COORD(x) + y = GET_CHUNK_COORD(y) src.x = x src.y = y - src.z = z + src.lower_z = lower_z + var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) + src.upper_z = upper_turf.z - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) - if(camera.can_use()) - cameras += camera + for(var/z_level in lower_z to upper_z) + var/list/local_cameras = list() + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(camera.can_use()) + local_cameras += camera - for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) - turfs[t] = t + for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) + if(sillycone.builtInCamera?.can_use()) + local_cameras += sillycone.builtInCamera - for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured) - for(var/obj/machinery/camera/camera as anything in cameras) - if(!camera || !camera.can_use()) - continue + cameras["[z_level]"] = local_cameras + + var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level) + 1] + var/turf/chunk_corner = locate(x, y, z_level) + for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself + var/image/our_image = new /image(mirror_from) + our_image.loc = lad + turfs[lad] = our_image + + for(var/obj/machinery/camera/camera as anything in local_cameras) + if(!camera) + continue + + if(!camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = inactive_static_images[inactive_static_images.len] - new_static.loc = obscured_turf + var/image/new_static = turfs[obscured_turf] active_static_images += new_static - inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME -#undef CHUNK_SIZE diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 36cd6b981425..5245db86dbca 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -9,8 +9,8 @@ designation = "Default" ///used for displaying the prefix & getting the current module of cyborg has_limbs = 1 hud_type = /datum/hud/robot - blocks_emissive = EMISSIVE_BLOCK_GENERIC - light_system = MOVABLE_LIGHT + blocks_emissive = EMISSIVE_BLOCK_UNIQUE + light_system = MOVABLE_LIGHT_DIRECTIONAL light_on = FALSE var/custom_name = "" diff --git a/code/modules/modular_computers/computers/item/computer.dm b/code/modules/modular_computers/computers/item/computer.dm index 18a00b5e236f..e2cd3fd4170a 100644 --- a/code/modules/modular_computers/computers/item/computer.dm +++ b/code/modules/modular_computers/computers/item/computer.dm @@ -268,35 +268,23 @@ . += get_modular_computer_parts_examine(user) -/obj/item/modular_computer/update_icon(updates=ALL) +/obj/item/modular_computer/update_icon_state() + if(!icon_state_powered || !icon_state_unpowered) //no valid icon, don't update. + return ..() + icon_state = enabled ? icon_state_powered : icon_state_unpowered + return ..() + +/obj/item/modular_computer/update_overlays() . = ..() - if(!physical) + var/init_icon = initial(icon) + if(!init_icon) return - SSvis_overlays.remove_vis_overlay(physical, physical.managed_vis_overlays) - var/program_overlay = "" - var/is_broken = obj_integrity <= integrity_failure - if(overlay_skin) - program_overlay = "[overlay_skin]-" - if(!enabled) - if(use_power() && !isnull(icon_state_screensaver)) - program_overlay += icon_state_screensaver - else - icon_state = icon_state_unpowered - else - icon_state = icon_state_powered - if(is_broken) - program_overlay += "bsod" - else - if(active_program) - program_overlay += active_program.program_icon_state ? "[active_program.program_icon_state]" : "[icon_state_menu]" - else - program_overlay += icon_state_menu - - SSvis_overlays.add_vis_overlay(physical, physical.icon, program_overlay, physical.layer, physical.plane, physical.dir) - SSvis_overlays.add_vis_overlay(physical, physical.icon, program_overlay, physical.layer, EMISSIVE_PLANE, physical.dir) - if(is_broken) - SSvis_overlays.add_vis_overlay(physical, physical.icon, "broken", physical.layer, physical.plane, physical.dir) + if(enabled) + . += active_program ? mutable_appearance(init_icon, active_program.program_icon_state) : mutable_appearance(init_icon, icon_state_menu) + if(obj_integrity <= integrity_failure) + . += mutable_appearance(init_icon, "bsod") + . += mutable_appearance(init_icon, "broken") /obj/item/modular_computer/equipped() . = ..() @@ -345,7 +333,7 @@ else to_chat(user, span_notice("You press the power button and start up \the [src].")) enabled = TRUE - update_appearance(UPDATE_ICON) + update_appearance() play_computer_sound(startup_sound, get_clamped_volume(), FALSE) ui_interact(user) else // Unpowered @@ -487,7 +475,7 @@ var/mob/user = usr if(user && istype(user)) ui_interact(user) // Re-open the UI on this computer. It should show the main screen now. - update_appearance(UPDATE_ICON) + update_appearance() // Returns 0 for No Signal, 1 for Low Signal and 2 for Good Signal. 3 is for wired connection (always-on) /obj/item/modular_computer/proc/get_ntnet_status(specific_action = 0) @@ -503,7 +491,7 @@ var/obj/item/computer_hardware/network_card/network_card = all_components[MC_NET] return SSnetworks.station_network.add_log(text, network_card) -/obj/item/modular_computer/proc/shutdown_computer(loud = 1) +/obj/item/modular_computer/proc/shutdown_computer(loud = TRUE) kill_program(forced = TRUE) for(var/datum/computer_file/program/P in idle_threads) P.kill_program(forced = TRUE) @@ -511,8 +499,8 @@ if(loud) physical.visible_message(span_notice("\The [src] shuts down.")) enabled = FALSE - update_appearance(UPDATE_ICON) play_computer_sound(shutdown_sound, get_clamped_volume(), FALSE) + update_appearance() /** * Toggles the computer's flashlight, if it has one. @@ -524,7 +512,7 @@ if(!has_light) return FALSE set_light_on(!light_on) - update_appearance(UPDATE_ICON) + update_appearance() return TRUE /** diff --git a/code/modules/modular_computers/hardware/card_slot.dm b/code/modules/modular_computers/hardware/card_slot.dm index f0d10f749525..807c43d78b64 100644 --- a/code/modules/modular_computers/hardware/card_slot.dm +++ b/code/modules/modular_computers/hardware/card_slot.dm @@ -77,7 +77,7 @@ if(ishuman(user)) var/mob/living/carbon/human/H = user H.sec_hud_set_ID() - + holder.update_appearance() return TRUE @@ -93,6 +93,7 @@ to_chat(user, "You remove the card from \the [src].") playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE) + holder.update_appearance() return TRUE /obj/item/computer_hardware/card_slot/attackby(obj/item/I, mob/living/user) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 215bfb7fab95..b7555ca63918 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -69,7 +69,7 @@ dir_amount = 4\ ) - var/lon_range = 1.5 + var/light_on_range = 1.5 var/area/area var/areastring = null var/obj/item/stock_parts/cell/cell @@ -230,7 +230,7 @@ /obj/machinery/power/apc/handle_atom_del(atom/A) if(A == cell) cell = null - update_appearance(UPDATE_ICON) + update_appearance() updateUsrDialog() /obj/machinery/power/apc/proc/make_terminal() @@ -265,7 +265,7 @@ make_terminal() addtimer(CALLBACK(src, PROC_REF(update)), 5) - update_appearance(UPDATE_ICON) + update_appearance() /obj/machinery/power/apc/examine(mob/user) . = ..() @@ -323,8 +323,11 @@ cell = best_cell W.play_rped_sound() -/obj/machinery/power/apc/update_icon(updates) - updates = check_updates() +/obj/machinery/power/apc/update_appearance(updates = check_updates()) + icon_update_needed = FALSE + if(!updates) + return + . = ..() // And now, separately for cleanness, the lighting changing if(update_state & UPSTATE_ALLGOOD) @@ -335,15 +338,13 @@ light_color = LIGHT_COLOR_BLUE if(APC_FULLY_CHARGED) light_color = LIGHT_COLOR_GREEN - set_light(lon_range) + set_light(light_on_range) else if(update_state & UPSTATE_BLUESCREEN) light_color = LIGHT_COLOR_BLUE - set_light(lon_range) + set_light(light_on_range) else set_light(0) - icon_update_needed = FALSE - // update the APC icon to show the three base states // also add overlays for indicator lights /obj/machinery/power/apc/update_icon_state() @@ -374,21 +375,20 @@ /obj/machinery/power/apc/update_overlays() . = ..() if(!(update_state & UPSTATE_ALLGOOD)) - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + return - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(!(stat & (BROKEN|MAINT)) && update_state & UPSTATE_ALLGOOD) - SSvis_overlays.add_vis_overlay(src, icon, "apcox-[locked]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apcox-[locked]", layer, EMISSIVE_PLANE, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco3-[charging]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco3-[charging]", layer, EMISSIVE_PLANE, dir) + . += mutable_appearance(icon, "apcox-[locked]") + . += emissive_appearance(icon, "apcox-[locked]", src) + . += mutable_appearance(icon, "apco3-[charging]") + . += emissive_appearance(icon, "apco3-[charging]", src) if(operating) - SSvis_overlays.add_vis_overlay(src, icon, "apco0-[equipment]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco0-[equipment]", layer, EMISSIVE_PLANE, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco1-[lighting]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco1-[lighting]", layer, EMISSIVE_PLANE, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco2-[environ]", layer, plane, dir) - SSvis_overlays.add_vis_overlay(src, icon, "apco2-[environ]", layer, EMISSIVE_PLANE, dir) + . += mutable_appearance(icon, "apco0-[equipment]") + . += emissive_appearance(icon, "apco0-[equipment]", src) + . += mutable_appearance(icon, "apco1-[lighting]") + . += emissive_appearance(icon, "apco1-[lighting]", src) + . += mutable_appearance(icon, "apco2-[environ]") + . += emissive_appearance(icon, "apco2-[environ]", src) /obj/machinery/power/apc/proc/check_updates() var/last_update_state = update_state @@ -515,7 +515,7 @@ else if (opened!=APC_COVER_REMOVED) opened = APC_COVER_CLOSED coverlocked = TRUE //closing cover relocks it - update_appearance(UPDATE_ICON) + update_appearance() return else if (!(stat & BROKEN)) if(coverlocked && !(stat & MAINT)) // locked... @@ -526,7 +526,7 @@ return else opened = APC_COVER_OPENED - update_appearance(UPDATE_ICON) + update_appearance() return else W.play_tool_sound(src) @@ -535,7 +535,7 @@ W.play_tool_sound(src) to_chat(user, span_notice("You pry the broken cover off of [src].")) opened = APC_COVER_REMOVED - update_appearance(UPDATE_ICON) + update_appearance() return /obj/machinery/power/apc/screwdriver_act(mob/living/user, obj/item/W) @@ -547,10 +547,10 @@ user.visible_message("[user] removes \the [cell] from [src]!",span_notice("You remove \the [cell].")) var/turf/T = get_turf(user) cell.forceMove(T) - cell.update_appearance(UPDATE_ICON) + cell.update_appearance() cell = null charging = APC_NOT_CHARGING - update_appearance(UPDATE_ICON) + update_appearance() return else switch (has_electronics) @@ -567,14 +567,14 @@ else to_chat(user, span_warning("There is nothing to secure!")) return - update_appearance(UPDATE_ICON) + update_appearance() else if(obj_flags & EMAGGED) to_chat(user, span_warning("The interface is broken!")) return else panel_open = !panel_open to_chat(user, span_notice("The wires have been [panel_open ? "exposed" : "unexposed"].")) - update_appearance(UPDATE_ICON) + update_appearance() /obj/machinery/power/apc/wirecutter_act(mob/living/user, obj/item/W) if (terminal && opened) @@ -623,7 +623,7 @@ "[user.name] has inserted the power cell to [src.name]!",\ span_notice("You insert the power cell.")) chargecount = 0 - update_appearance(UPDATE_ICON) + update_appearance() else if (W.GetID()) togglelock(user) else if (istype(W, /obj/item/stack/cable_coil) && opened) @@ -701,7 +701,7 @@ chargecount = 0 user.visible_message(span_notice("[user] fabricates a weak power cell and places it into [src]."), \ span_warning("Your [P.name] whirrs with strain as you create a weak power cell and place it into [src]!")) - update_appearance(UPDATE_ICON) + update_appearance() else to_chat(user, span_warning("[src] has both electronics and a cell.")) return @@ -716,7 +716,7 @@ to_chat(user, span_notice("You replace missing APC's cover.")) qdel(W) opened = APC_COVER_OPENED - update_appearance(UPDATE_ICON) + update_appearance() return if (has_electronics) to_chat(user, span_warning("You cannot repair this APC until you remove the electronics still inside!")) @@ -730,7 +730,7 @@ obj_integrity = max_integrity if (opened==APC_COVER_REMOVED) opened = APC_COVER_OPENED - update_appearance(UPDATE_ICON) + update_appearance() else if(istype(W, /obj/item/clockwork/integration_cog) && is_servant_of_ratvar(user)) if(integration_cog) to_chat(user, span_warning("This APC already has a cog.")) @@ -739,7 +739,7 @@ user.visible_message(span_warning("[user] slices [src]'s cover lock, and it swings wide open!"), \ span_alloy("You slice [src]'s cover lock apart with [W], and the cover swings open.")) opened = APC_COVER_OPENED - update_appearance(UPDATE_ICON) + update_appearance() else user.visible_message(span_warning("[user] presses [W] into [src]!"), \ span_alloy("You hold [W] in place within [src], and it slowly begins to warm up...")) @@ -756,7 +756,7 @@ playsound(src, 'sound/machines/clockcult/steam_whoosh.ogg', 50, FALSE) opened = APC_COVER_CLOSED locked = FALSE - update_appearance(UPDATE_ICON) + update_appearance() return else if(istype(W, /obj/item/apc_powercord)) return //because we put our fancy code in the right places, and this is all in the powercord's afterattack() @@ -812,7 +812,7 @@ chargecount = 0 user.visible_message(span_notice("[user] fabricates a weak power cell and places it into [src]."), \ span_warning("Your [the_rcd.name] whirrs with strain as you create a weak power cell and place it into [src]!")) - update_appearance(UPDATE_ICON) + update_appearance() return TRUE else to_chat(user, span_warning("[src] has both electronics and a cell.")) @@ -832,7 +832,7 @@ if((allowed(usr) && !wires.is_cut(WIRE_IDSCAN) && !malfhack) || integration_cog) locked = !locked to_chat(user, span_notice("You [ locked ? "lock" : "unlock"] the APC interface.")) - update_appearance(UPDATE_ICON) + update_appearance() updateUsrDialog() else to_chat(user, span_warning("Access denied.")) @@ -843,10 +843,10 @@ return last_light_switch = world.time area.lightswitch = !area.lightswitch - area.update_appearance(UPDATE_ICON) + area.update_appearance() for(var/obj/machinery/light_switch/L in area) - L.update_appearance(UPDATE_ICON) + L.update_appearance() area.power_change() @@ -876,7 +876,7 @@ opened = APC_COVER_REMOVED coverlocked = FALSE visible_message(span_warning("The APC cover is knocked down!")) - update_appearance(UPDATE_ICON) + update_appearance() /obj/machinery/power/apc/emag_act(mob/user, obj/item/card/emag/emag_card) if((obj_flags & EMAGGED) || malfhack) @@ -895,7 +895,7 @@ obj_flags |= EMAGGED locked = FALSE to_chat(user, span_notice("You emag the APC interface.")) - update_appearance(UPDATE_ICON) + update_appearance() return TRUE // attack with hand - remove cell (if cover open) or interact with the APC @@ -912,10 +912,10 @@ if(cell) user.visible_message("[user] removes \the [cell] from [src]!",span_notice("You remove \the [cell].")) user.put_in_hands(cell) - cell.update_appearance(UPDATE_ICON) + cell.update_appearance() src.cell = null charging = APC_NOT_CHARGING - src.update_appearance(UPDATE_ICON) + src.update_appearance() return if((stat & MAINT) && !opened) //no board; no interface return @@ -1064,7 +1064,7 @@ to_chat(usr, "The APC does not respond to the command.") else locked = !locked - update_appearance(UPDATE_ICON) + update_appearance() . = TRUE if("cover") coverlocked = !coverlocked @@ -1076,20 +1076,20 @@ chargemode = !chargemode if(!chargemode) charging = APC_NOT_CHARGING - update_appearance(UPDATE_ICON) + update_appearance() . = TRUE if("channel") if(params["eqp"]) equipment = setsubsystem(text2num(params["eqp"])) - update_appearance(UPDATE_ICON) + update_appearance() update() else if(params["lgt"]) lighting = setsubsystem(text2num(params["lgt"])) - update_appearance(UPDATE_ICON) + update_appearance() update() else if(params["env"]) environ = setsubsystem(text2num(params["env"])) - update_appearance(UPDATE_ICON) + update_appearance() update() . = TRUE if("overload") @@ -1107,7 +1107,7 @@ malfvacate() if("reboot") failure_timer = 0 - update_appearance(UPDATE_ICON) + update_appearance() update() if("emergency_lighting") emergency_lights = !emergency_lights @@ -1132,7 +1132,7 @@ add_hiddenprint(user) log_combat(user, src, "turned [operating ? "on" : "off"]") update() - update_appearance(UPDATE_ICON) + update_appearance() /obj/machinery/power/apc/proc/malfhack(mob/living/silicon/ai/malf) if(!istype(malf)) @@ -1273,7 +1273,7 @@ /obj/machinery/power/apc/process() if(icon_update_needed) - update_appearance(UPDATE_ICON) + update_appearance() if(stat & (BROKEN|MAINT)) return if(!area.requires_power) @@ -1448,7 +1448,7 @@ if(APC_RESET_EMP) equipment = 3 environ = 3 - update_appearance(UPDATE_ICON) + update_appearance() update() // damage and destruction acts @@ -1464,7 +1464,7 @@ lighting = 0 equipment = 0 environ = 0 - update_appearance(UPDATE_ICON) + update_appearance() update() addtimer(CALLBACK(src, PROC_REF(reset), APC_RESET_EMP), (6 * severity) SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 49c3ec5f7170..82412f16069c 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -214,6 +214,7 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' w_class = WEIGHT_CLASS_BULKY // Pretty big! anchored = FALSE + blocks_emissive = EMISSIVE_BLOCK_UNIQUE var/tracker = 0 var/glass_type = null var/multiplier = 1 diff --git a/code/modules/power/tracker.dm b/code/modules/power/tracker.dm index ec2bc2e82197..5aaa474a3c5f 100644 --- a/code/modules/power/tracker.dm +++ b/code/modules/power/tracker.dm @@ -10,6 +10,7 @@ icon_state = "tracker" density = TRUE use_power = NO_POWER_USE + blocks_emissive = EMISSIVE_BLOCK_UNIQUE max_integrity = 250 integrity_failure = 0.2 diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index f8c23aa21917..47a101e41893 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -13,6 +13,7 @@ mouse_opacity = MOUSE_OPACITY_TRANSPARENT movement_type = FLYING wound_bonus = CANT_WOUND // can't wound by default + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/hitsound = 'sound/weapons/pierce.ogg' var/hitsound_wall = "" diff --git a/code/modules/unit_tests/focus_only_tests.dm b/code/modules/unit_tests/focus_only_tests.dm index 426a236ab4bd..ba6d827b7f0a 100644 --- a/code/modules/unit_tests/focus_only_tests.dm +++ b/code/modules/unit_tests/focus_only_tests.dm @@ -6,6 +6,12 @@ /// and you will only test the check for invalid overlays in appearance building. /datum/unit_test/focus_only +/// Checks that every created emissive has a valid icon_state +/datum/unit_test/focus_only/invalid_emissives + +/// Checks that every overlay passed into build_appearance_list exists in the icon +/datum/unit_test/focus_only/invalid_overlays + /// Checks that every created emissive has a valid icon_state /datum/unit_test/focus_only/multiple_space_initialization diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 0fe04abfd05a..836fcd5035c2 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -7,6 +7,7 @@ armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 0, BOMB = 30, BIO = 0, RAD = 0, FIRE = 60, ACID = 60) density = TRUE anchored = FALSE + blocks_emissive = EMISSIVE_BLOCK_GENERIC var/list/mob/occupants //mob = bitflags of their control level. var/max_occupants = 1 var/max_drivers = 1 diff --git a/code/modules/vending/_vending.dm b/code/modules/vending/_vending.dm index e93b30dd9af8..96927a06ac2e 100644 --- a/code/modules/vending/_vending.dm +++ b/code/modules/vending/_vending.dm @@ -92,7 +92,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C var/forcecrit = 0 var/num_shards = 7 var/list/pinned_mobs = list() - light_power = 0.5 + light_power = 0.7 light_range = MINIMUM_USEFUL_LIGHT_RANGE @@ -271,28 +271,28 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C else ..() -/obj/machinery/vending/update_icon_state() +/obj/machinery/vending/update_appearance(updates=ALL) . = ..() if(stat & BROKEN) - icon_state = "[initial(icon_state)]-broken" set_light(0) return + set_light(powered() ? MINIMUM_USEFUL_LIGHT_RANGE : 0) - if(powered()) - icon_state = initial(icon_state) - set_light(1.4) - else - icon_state = "[initial(icon_state)]-off" - set_light(0) +/obj/machinery/vending/update_icon_state() + if(stat & BROKEN) + icon_state = "[initial(icon_state)]-broken" + return ..() + icon_state = "[initial(icon_state)][powered() ? null : "-off"]" + return ..() /obj/machinery/vending/update_overlays() . = ..() if(!light_mask) return - SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) + //SSvis_overlays.remove_vis_overlay(src, managed_vis_overlays) if(!(stat & BROKEN) && powered()) - SSvis_overlays.add_vis_overlay(src, icon, light_mask, EMISSIVE_LAYER, EMISSIVE_PLANE) + . += emissive_appearance(icon, light_mask, src) /obj/machinery/vending/obj_break(damage_flag) diff --git a/icons/effects/alphacolors.dmi b/icons/effects/alphacolors.dmi index c3dbcaee39be41c346cc2b5f39183d2aa24b9cf2..f3241ba010d9a0fb2ebbc6dba88be3f3102a2399 100644 GIT binary patch literal 654 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRStE)mHN?cNllZ!G7N;32F7#J$% zOr3a;>yQCY+xfG>Q{HNAI$QZgNqSRrb-UMNsTrY{Ufj4HE!)AK>ZNyI{@YSqj>EU7?Jp6ifZo1dnjI`3MC}vv4`%D0_2G!K3L9FT{V` zys{_u&DkFZTm@g}u1a?K?``(kB0G7@|NI0`nNL=;eZ|e}Vt5u$k9_~YV_%GNd&u?N zuQi8cJ2`UOB`?WmFfcIA^K@|xshIQj%0^!nM*-J^k}hl<%##%+6kMoc=`EejocKWT zq26>?>GfKT_m2g?f1SsBt9q~RyZe86-v9UQv-jyU_Gc($>JWCA!|;ejK)u0&@d&4a z9~nYBj_#xl9-QC#zrPat>TLRS1u%gzc)I$ztaD0e F0swdo^1c87 literal 641 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRS%c?>mN?cNllZ!G7N;32F7#J$% zOzm^zI%FW?a{cFWiCei7qh1?HXHL|6Bdhe&tWoNzy4K#k-Ay|JR_&Io_&h^qciH`~ z8GN#LBNy#w$+)t5(v`!vpDft8(!=swvv+alNtHIYX%jcaDVbbb;+J&J=DB!*O#UCq zRi2S@XIXl8t>{`+5zTu@rmnEtr+dbRzyBM*p4^yo+O=9p_|a94_Ak9>FMi{lGx$FPded^E8e^7qIPQGcV&e(oFs{f&MUHkWV_2b{8-z6L7|91#Ej delta 53 zcmV-50LuUC4&@GzBmsJnC0!*FONtWniVG5pQu9g(D^5u)%EqNiS;5uM1?)%w=;1J3 LpX#hyv8}!aJlz*` From 8248523bf938c7c38194671040192cb54af53cb5 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 6 Dec 2023 23:32:41 -0500 Subject: [PATCH 124/144] oops we need this apparently --- code/__DEFINES/traits.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 6f9b8e46ec68..9d5262de697d 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -515,3 +515,5 @@ #define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent" /// This mob overrides certian SSlag_switch measures with this special trait #define TRAIT_BYPASS_MEASURES "bypass_lagswitch_measures" +/// This movable atom has the explosive block element +#define TRAIT_BLOCKING_EXPLOSIVES "blocking_explosives" From f7ac1bf5958141bae987a81740b810917e1beb6f Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 10 Dec 2023 23:49:08 -0500 Subject: [PATCH 125/144] adds this back it was gone somehow --- code/datums/chatmessage.dm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index 5694bfa0fd08..f8d158943a29 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -20,6 +20,10 @@ #define CHAT_LAYER_MAX_Z (CHAT_LAYER_MAX - CHAT_LAYER) / CHAT_LAYER_Z_STEP /// The dimensions of the chat message icons #define CHAT_MESSAGE_ICON_SIZE 9 +///Base layer of chat elements +#define CHAT_LAYER 1 +///Highest possible layer of chat elements +#define CHAT_LAYER_MAX 2 /** * # Chat Message Overlay From 4ccaf40ed1378cb11f46e41bcd5f8e3c99ab0e4c Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Sun, 10 Dec 2023 23:58:05 -0500 Subject: [PATCH 126/144] bye bye motion alarm ueaefa --- code/game/atoms_movable.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 9a8f477e2a2a..e15a0bba1ea8 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -77,10 +77,10 @@ /atom/movable/Initialize(mapload, ...) . = ..() -#ifdef UNIT_TESTS - if(explosion_block && !HAS_TRAIT(src, TRAIT_BLOCKING_EXPLOSIVES)) - stack_trace("[type] blocks explosives, but does not have the managing element applied") -#endif +// #ifdef UNIT_TESTS +// if(explosion_block && !HAS_TRAIT(src, TRAIT_BLOCKING_EXPLOSIVES)) +// stack_trace("[type] blocks explosives, but does not have the managing element applied") +// #endif -- who cares #if EMISSIVE_BLOCK_GENERIC != 0 #error EMISSIVE_BLOCK_GENERIC is expected to be 0 to faciliate a weird optimization hack where we rely on it being the most common. From 0a62e1861276eb3da27ff674ab922c0975f459e5 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 00:04:12 -0500 Subject: [PATCH 127/144] bye bitch --- code/__HELPERS/lighting.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index 96087ba17377..2bcaab5761bd 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -8,9 +8,9 @@ appearance.color = _EMISSIVE_COLOR(alpha_ratio) //Test to make sure emissives with broken or missing icon states are created - if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) - if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace - stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") + // if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) + // if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace + // stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") -- fuck this too return appearance From b23b35074fd39fffb7d151a55ae4eb7850dd4a1e Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 02:07:10 -0500 Subject: [PATCH 128/144] step 1: fix the Ai step 2: fix the static --- _maps/_basemap.dm | 2 +- .../living/silicon/ai/freelook/cameranet.dm | 22 ++-- .../mob/living/silicon/ai/freelook/chunk.dm | 116 ++++++++---------- 3 files changed, 63 insertions(+), 77 deletions(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index aadbfa88a035..48b96c8948f7 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index cf4f9fca9fcb..dab9cca3f6b6 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -125,30 +125,28 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) * It will also add the atom to the cameras list if you set the choice to 1. * Setting the choice to 0 will remove the camera from the chunks. * If you want to update the chunks around an object, without adding/removing a camera, use choice 2. - * update_delay_buffer is passed all the way to hasChanged() from portable camera updates on movement - * to change the time between static updates. */ -/datum/cameranet/proc/majorChunkChange(atom/c, choice, update_delay_buffer) - if(QDELETED(c) && choice == 1) - CRASH("Tried to add a qdeleting camera to the net") +/datum/cameranet/proc/majorChunkChange(atom/c, choice) + if(!c) + return var/turf/T = get_turf(c) if(T) - var/x1 = max(1, T.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, T.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) + var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1) for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z) if(chunk) if(choice == 0) // Remove the camera. - chunk.cameras["[T.z]"] -= c + chunk.cameras -= c else if(choice == 1) // You can't have the same camera in the list twice. - chunk.cameras["[T.z]"] |= c - chunk.hasChanged(update_delay_buffer = update_delay_buffer) + chunk.cameras |= c + chunk.hasChanged() /// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] /// For use in sensitive code, be careful with it diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index fca64a1e1681..c2178a5be5ba 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -11,21 +11,20 @@ ///turfs our cameras can see inside our grid var/list/visibleTurfs = list() ///cameras that can see into our grid - ///indexed by the z level of the camera var/list/cameras = list() - ///list of all turfs, associative with that turf's static image - ///turf -> /image + ///list of all turfs var/list/turfs = list() ///camera mobs that can see turfs in our grid var/list/seenby = list() + ///images created to represent obscured turfs + var/list/inactive_static_images = list() ///images currently in use on obscured turfs. var/list/active_static_images = list() var/changed = FALSE var/x = 0 var/y = 0 - var/lower_z - var/upper_z + var/z = 0 /// Add an AI eye to the chunk, then update if changed. /datum/camerachunk/proc/add(mob/camera/aiEye/eye) @@ -56,33 +55,28 @@ /** * Updates the chunk, makes sure that it doesn't update too much. If the chunk isn't being watched it will * instead be flagged to update the next time an AI Eye moves near it. - * update_delay_buffer is used for cameras that are moving around, which are cyborg inbuilt cameras and - * mecha onboard cameras. This buffer should be usually lower than UPDATE_BUFFER_TIME because - * otherwise a moving camera can run out of its own view before updating static. */ -/datum/camerachunk/proc/hasChanged(update_now = 0, update_delay_buffer = UPDATE_BUFFER_TIME) +/datum/camerachunk/proc/hasChanged(update_now = 0) if(seenby.len || update_now) - addtimer(CALLBACK(src, PROC_REF(update)), update_delay_buffer, TIMER_UNIQUE) + addtimer(CALLBACK(src, PROC_REF(update)), UPDATE_BUFFER_TIME, TIMER_UNIQUE) else changed = TRUE /// The actual updating. It gathers the visible turfs from cameras and puts them into the appropiate lists. -/// Accepts an optional partial_update argument, that blocks any calls out to chunks that could affect us, like above or below -/datum/camerachunk/proc/update(partial_update = FALSE) +/datum/camerachunk/proc/update() var/list/updated_visible_turfs = list() - for(var/z_level in lower_z to upper_z) - for(var/obj/machinery/camera/current_camera as anything in cameras["[z_level]"]) - if(!current_camera || !current_camera.can_use()) - continue + for(var/obj/machinery/camera/current_camera as anything in cameras) + if(!current_camera || !current_camera.can_use()) + continue - var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), z_level) - if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) - continue + var/turf/point = locate(src.x + (CHUNK_SIZE / 2), src.y + (CHUNK_SIZE / 2), src.z) + if(get_dist(point, current_camera) > CHUNK_SIZE + (CHUNK_SIZE / 2)) + continue - for(var/turf/vis_turf in current_camera.can_see()) - if(turfs[vis_turf]) - updated_visible_turfs[vis_turf] = vis_turf + for(var/turf/vis_turf in current_camera.can_see()) + if(turfs[vis_turf]) + updated_visible_turfs[vis_turf] = vis_turf ///new turfs that we couldnt see last update but can now var/list/newly_visible_turfs = updated_visible_turfs - visibleTurfs @@ -97,24 +91,31 @@ client.images -= active_static_images for(var/turf/visible_turf as anything in newly_visible_turfs) - var/image/static_image = obscuredTurfs[visible_turf] - if(!static_image) + var/image/static_image_to_deallocate = obscuredTurfs[visible_turf] + if(!static_image_to_deallocate) continue - active_static_images -= static_image + static_image_to_deallocate.loc = null + active_static_images -= static_image_to_deallocate + inactive_static_images += static_image_to_deallocate + obscuredTurfs -= visible_turf for(var/turf/obscured_turf as anything in newly_obscured_turfs) if(obscuredTurfs[obscured_turf] || istype(obscured_turf, /turf/open/ai_visible)) continue - var/image/static_image = turfs[obscured_turf] - if(!static_image) - stack_trace("somehow a camera chunk used a turf it didn't contain!!") + var/image/static_image_to_allocate = inactive_static_images[length(inactive_static_images)] + if(!static_image_to_allocate) + stack_trace("somehow a camera chunk ran out of static images!") break - obscuredTurfs[obscured_turf] = static_image - active_static_images += static_image + obscuredTurfs[obscured_turf] = static_image_to_allocate + static_image_to_allocate.loc = obscured_turf + + inactive_static_images -= static_image_to_allocate + active_static_images += static_image_to_allocate + visibleTurfs = updated_visible_turfs changed = FALSE @@ -126,52 +127,39 @@ client.images += active_static_images - /// Create a new camera chunk, since the chunks are made as they are needed. -/datum/camerachunk/New(x, y, lower_z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) +/datum/camerachunk/New(x, y, z) + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) src.x = x src.y = y - src.lower_z = lower_z - var/turf/upper_turf = get_highest_turf(locate(x, y, lower_z)) - src.upper_z = upper_turf.z - - for(var/z_level in lower_z to upper_z) - var/list/local_cameras = list() - for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(camera.can_use()) - local_cameras += camera - - for(var/mob/living/silicon/sillycone in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z_level))) - if(sillycone.builtInCamera?.can_use()) - local_cameras += sillycone.builtInCamera + src.z = z + for(var/obj/machinery/camera/camera in urange(CHUNK_SIZE, locate(x + (CHUNK_SIZE / 2), y + (CHUNK_SIZE / 2), z))) + if(camera.can_use()) + cameras += camera - cameras["[z_level]"] = local_cameras + for(var/turf/t as anything in block(locate(max(x, 1), max(y, 1), z), locate(min(x + CHUNK_SIZE - 1, world.maxx), min(y + CHUNK_SIZE - 1, world.maxy), z))) + turfs[t] = t - var/image/mirror_from = GLOB.cameranet.obscured_images[GET_Z_PLANE_OFFSET(z_level) + 1] - var/turf/chunk_corner = locate(x, y, z_level) - for(var/turf/lad as anything in CORNER_BLOCK(chunk_corner, CHUNK_SIZE, CHUNK_SIZE)) //we use CHUNK_SIZE for width and height here as it handles subtracting 1 from those two parameters by itself - var/image/our_image = new /image(mirror_from) - our_image.loc = lad - turfs[lad] = our_image + for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses + inactive_static_images += new/image(GLOB.cameranet.obscured_images) - for(var/obj/machinery/camera/camera as anything in local_cameras) - if(!camera) - continue - - if(!camera.can_use()) - continue + for(var/obj/machinery/camera/camera as anything in cameras) + if(!camera || !camera.can_use()) + continue - for(var/turf/vis_turf in camera.can_see()) - if(turfs[vis_turf]) - visibleTurfs[vis_turf] = vis_turf + for(var/turf/vis_turf in camera.can_see()) + if(turfs[vis_turf]) + visibleTurfs[vis_turf] = vis_turf for(var/turf/obscured_turf as anything in turfs - visibleTurfs) - var/image/new_static = turfs[obscured_turf] + var/image/new_static = inactive_static_images[inactive_static_images.len] + new_static.loc = obscured_turf active_static_images += new_static + inactive_static_images -= new_static obscuredTurfs[obscured_turf] = new_static #undef UPDATE_BUFFER_TIME +#undef CHUNK_SIZE From 8ea7f17358bef63a44638a9fd5a443b2a728d577 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:21:55 -0500 Subject: [PATCH 129/144] fixes Ai camera view chubby please god find some other way to fix corner tile lighting --- code/__DEFINES/layers.dm | 3 +- .../living/silicon/ai/freelook/cameranet.dm | 115 +++++++----------- .../mob/living/silicon/ai/freelook/chunk.dm | 2 +- 3 files changed, 45 insertions(+), 75 deletions(-) diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 57d0eb01291c..b5abc1b25025 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -76,7 +76,8 @@ #define PIPECRAWL_IMAGES_PLANE 20 ///AI Camera Static -#define CAMERA_STATIC_PLANE 21 +#define CAMERA_STATIC_PLANE 40 +#define CAMERA_STATIC_LAYER 40 ///Anything that wants to be part of the game plane, but also wants to draw above literally everything else #define HIGH_GAME_PLANE 22 diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index dab9cca3f6b6..efd4184eee1f 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,6 +2,8 @@ // // The datum containing all the chunks. +#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. + GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) /datum/cameranet @@ -9,54 +11,38 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) var/name = "Camera Net" /// The cameras on the map, no matter if they work or not. Updated in obj/machinery/camera.dm by New() and Del(). - var/list/obj/machinery/camera/cameras = list() + var/list/cameras = list() /// The chunks of the map, mapping the areas that the cameras can see. var/list/chunks = list() var/ready = 0 - - /// List of images cloned by all chunk static images put onto turfs cameras cant see - /// Indexed by the plane offset to use - var/list/image/obscured_images + // The object used for the clickable stat() button. + var/obj/effect/statclick/statclick + ///The image given to the effect in vis_contents on AI clients + var/image/obscured /datum/cameranet/New() - obscured_images = list() - update_offsets(SSmapping.max_plane_offset) - RegisterSignal(SSmapping, COMSIG_PLANE_OFFSET_INCREASE, PROC_REF(on_offset_growth)) - -/datum/cameranet/proc/update_offsets(new_offset) - for(var/i in length(obscured_images) to new_offset) - var/image/obscured = new('icons/effects/cameravis.dmi') - SET_PLANE_W_SCALAR(obscured, CAMERA_STATIC_PLANE, i) - obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART - obscured.override = TRUE - obscured_images += obscured - -/datum/cameranet/proc/on_offset_growth(datum/source, old_offset, new_offset) - SIGNAL_HANDLER - update_offsets(new_offset) + obscured = new('icons/effects/cameravis.dmi') + obscured.plane = CAMERA_STATIC_PLANE + obscured.appearance_flags = RESET_TRANSFORM | RESET_ALPHA | RESET_COLOR | KEEP_APART + obscured.override = TRUE /// Checks if a chunk has been Generated in x, y, z. /datum/cameranet/proc/chunkGenerated(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - if(GET_LOWEST_STACK_OFFSET(z) != 0) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - return chunks["[x],[y],[lowest.z]"] - + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) return chunks["[x],[y],[z]"] // Returns the chunk in the x, y, z. // If there is no chunk, it creates a new chunk and returns that. /datum/cameranet/proc/getCameraChunk(x, y, z) - x = GET_CHUNK_COORD(x) - y = GET_CHUNK_COORD(y) - var/turf/lowest = get_lowest_turf(locate(x, y, z)) - var/key = "[x],[y],[lowest.z]" + x &= ~(CHUNK_SIZE - 1) + y &= ~(CHUNK_SIZE - 1) + var/key = "[x],[y],[z]" . = chunks[key] if(!.) - chunks[key] = . = new /datum/camerachunk(x, y, lowest.z) + chunks[key] = . = new /datum/camerachunk(x, y, z) -/// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set. +/// Updates what the ai_eye can see. It is recommended you use this when the ai_eye moves or it's location is set. /datum/cameranet/proc/visibility(list/moved_eyes, client/C, list/other_eyes, use_static = TRUE) if(!islist(moved_eyes)) moved_eyes = moved_eyes ? list(moved_eyes) : list() @@ -67,18 +53,21 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/mob/camera/aiEye/eye as anything in moved_eyes) var/list/visibleChunks = list() - //Get the eye's turf in case it's located in an object like a mecha - var/turf/eye_turf = get_turf(eye) if(eye.loc) + var/x_value = eye.x + var/y_value = eye.y + var/z_value = eye.z + // 0xf = 15 var/static_range = eye.static_visibility_range - var/x1 = max(1, eye_turf.x - static_range) - var/y1 = max(1, eye_turf.y - static_range) - var/x2 = min(world.maxx, eye_turf.x + static_range) - var/y2 = min(world.maxy, eye_turf.y + static_range) + var/x1 = max(0, x_value - static_range) & ~(CHUNK_SIZE - 1) + var/y1 = max(0, y_value - static_range) & ~(CHUNK_SIZE - 1) + var/x2 = min(world.maxx, x_value + static_range) & ~(CHUNK_SIZE - 1) + var/y2 = min(world.maxy, y_value + static_range) & ~(CHUNK_SIZE - 1) + for(var/x = x1; x <= x2; x += CHUNK_SIZE) for(var/y = y1; y <= y2; y += CHUNK_SIZE) - visibleChunks |= getCameraChunk(x, y, eye_turf.z) + visibleChunks |= getCameraChunk(x, y, z_value) var/list/remove = eye.visibleCameraChunks - visibleChunks var/list/add = visibleChunks - eye.visibleCameraChunks @@ -89,7 +78,7 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) for(var/datum/camerachunk/chunk as anything in add) chunk.add(eye) -/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. +/// Updates the chunks that the turf is located in. Use this when obstacles are destroyed or when doors open. /datum/cameranet/proc/updateVisibility(atom/A, opacity_check = 1) if(!SSticker || (opacity_check && !A.opacity)) return @@ -110,14 +99,10 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) if(c.can_use()) majorChunkChange(c, 1) -/** - * Used for Cyborg/mecha cameras. Since portable cameras can be in ANY chunk. - * update_delay_buffer is passed all the way to hasChanged() from their camera updates on movement - * to change the time between static updates. -*/ -/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/updating_camera, update_delay_buffer) - if(updating_camera.can_use()) - majorChunkChange(updating_camera, 1, update_delay_buffer) +/// Used for Cyborg cameras. Since portable cameras can be in ANY chunk. +/datum/cameranet/proc/updatePortableCamera(obj/machinery/camera/c) + if(c.can_use()) + majorChunkChange(c, 1) /** * Never access this proc directly!!!! @@ -148,27 +133,14 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) chunk.cameras |= c chunk.hasChanged() -/// A faster, turf only version of [/datum/cameranet/proc/majorChunkChange] -/// For use in sensitive code, be careful with it -/datum/cameranet/proc/bareMajorChunkChange(turf/changed) - var/x1 = max(1, changed.x - (CHUNK_SIZE / 2)) - var/y1 = max(1, changed.y - (CHUNK_SIZE / 2)) - var/x2 = min(world.maxx, changed.x + (CHUNK_SIZE / 2)) - var/y2 = min(world.maxy, changed.y + (CHUNK_SIZE / 2)) - for(var/x = x1; x <= x2; x += CHUNK_SIZE) - for(var/y = y1; y <= y2; y += CHUNK_SIZE) - var/datum/camerachunk/chunk = chunkGenerated(x, y, changed.z) - chunk?.hasChanged() - /// Will check if a mob is on a viewable turf. Returns 1 if it is, otherwise returns 0. /datum/cameranet/proc/checkCameraVis(mob/living/target) var/turf/position = get_turf(target) - if(!position) - return return checkTurfVis(position) + /datum/cameranet/proc/checkTurfVis(turf/position) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) + var/datum/camerachunk/chunk = chunkGenerated(position.x, position.y, position.z) if(chunk) if(chunk.changed) chunk.hasChanged(1) // Update now, no matter if it's visible or not. @@ -176,25 +148,22 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) return TRUE return FALSE -/datum/cameranet/proc/getTurfVis(turf/position) - RETURN_TYPE(/datum/camerachunk) - var/datum/camerachunk/chunk = getCameraChunk(position.x, position.y, position.z) - if(!chunk) - return FALSE - if(chunk.changed) - chunk.hasChanged(1) // Update now, no matter if it's visible or not. - if(chunk.visibleTurfs[position]) - return chunk +/datum/cameranet/proc/stat_entry() + if(!statclick) + statclick = new/obj/effect/statclick/debug(null, "Initializing...", src) + + stat(name, statclick.update("Cameras: [GLOB.cameranet.cameras.len] | Chunks: [GLOB.cameranet.chunks.len]")) /obj/effect/overlay/camera_static name = "static" icon = null icon_state = null anchored = TRUE // should only appear in vis_contents, but to be safe - appearance_flags = RESET_TRANSFORM | TILE_BOUND | LONG_GLIDE + appearance_flags = RESET_TRANSFORM | TILE_BOUND | RESET_COLOR // this combination makes the static block clicks to everything below it, // without appearing in the right-click menu for non-AI clients mouse_opacity = MOUSE_OPACITY_ICON invisibility = INVISIBILITY_ABSTRACT + layer = CAMERA_STATIC_LAYER plane = CAMERA_STATIC_PLANE diff --git a/code/modules/mob/living/silicon/ai/freelook/chunk.dm b/code/modules/mob/living/silicon/ai/freelook/chunk.dm index c2178a5be5ba..abf891b011ac 100644 --- a/code/modules/mob/living/silicon/ai/freelook/chunk.dm +++ b/code/modules/mob/living/silicon/ai/freelook/chunk.dm @@ -144,7 +144,7 @@ turfs[t] = t for(var/turf in turfs)//one for each 16x16 = 256 turfs this camera chunk encompasses - inactive_static_images += new/image(GLOB.cameranet.obscured_images) + inactive_static_images += new/image(GLOB.cameranet.obscured) for(var/obj/machinery/camera/camera as anything in cameras) if(!camera || !camera.can_use()) From 83800709f2427cff4a12fd261d92199e1dbcc076 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:30:39 -0500 Subject: [PATCH 130/144] updates some maps barsigns I think I forgot one or two --- _maps/map_files/AsteroidStation/AsteroidStation.dmm | 13 ++++--------- _maps/map_files/GaxStation/GaxStation.dmm | 2 +- _maps/map_files/IceMeta/IceMeta.dmm | 11 ++++------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/_maps/map_files/AsteroidStation/AsteroidStation.dmm b/_maps/map_files/AsteroidStation/AsteroidStation.dmm index e21554301c0c..083aa613c571 100644 --- a/_maps/map_files/AsteroidStation/AsteroidStation.dmm +++ b/_maps/map_files/AsteroidStation/AsteroidStation.dmm @@ -29665,14 +29665,9 @@ /turf/open/floor/plasteel, /area/storage/primary) "iFj" = ( -/obj/structure/sign/barsign{ - pixel_y = 32 - }, -/obj/effect/turf_decal/trimline/neutral/filled/line/lower{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/central) +/obj/machinery/barsign, +/turf/closed/wall, +/area/crew_quarters/bar) "iFF" = ( /obj/effect/turf_decal/trimline/neutral/filled/line/lower{ dir = 1 @@ -100472,8 +100467,8 @@ xWW xWW xWW xWW -aFi iFj +rkk hoR sIx asr diff --git a/_maps/map_files/GaxStation/GaxStation.dmm b/_maps/map_files/GaxStation/GaxStation.dmm index 8e4c7ef0450f..8be526a7c622 100644 --- a/_maps/map_files/GaxStation/GaxStation.dmm +++ b/_maps/map_files/GaxStation/GaxStation.dmm @@ -23940,7 +23940,7 @@ /turf/open/floor/carpet, /area/hallway/secondary/entry) "lLC" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign/all_access, /turf/closed/wall, /area/crew_quarters/bar) "lLV" = ( diff --git a/_maps/map_files/IceMeta/IceMeta.dmm b/_maps/map_files/IceMeta/IceMeta.dmm index 51e70fab4101..b84088643383 100644 --- a/_maps/map_files/IceMeta/IceMeta.dmm +++ b/_maps/map_files/IceMeta/IceMeta.dmm @@ -33617,12 +33617,9 @@ /turf/open/floor/plasteel, /area/teleporter) "jPu" = ( -/obj/structure/sign/barsign{ - pixel_y = -32 - }, -/obj/effect/turf_decal/trimline/green/filled/line/lower, -/turf/open/floor/plasteel, -/area/hallway/primary/starboard) +/obj/machinery/barsign/all_access, +/turf/closed/wall, +/area/crew_quarters/bar) "jPy" = ( /obj/structure/closet/secure_closet/brig{ id = "Cell 1"; @@ -117341,8 +117338,8 @@ rkO bjd eHK lFl +bJD jPu -rfi nYc lgH ptc From 94c16408351c08376470368d213e4e7256b9c37a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:42:40 -0500 Subject: [PATCH 131/144] oh yeah forgot this --- code/modules/mob/living/silicon/ai/freelook/cameranet.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm index efd4184eee1f..5c23d7f61142 100644 --- a/code/modules/mob/living/silicon/ai/freelook/cameranet.dm +++ b/code/modules/mob/living/silicon/ai/freelook/cameranet.dm @@ -2,7 +2,7 @@ // // The datum containing all the chunks. -#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. +// #define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc.. GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new) From 10e005ff17a2248bddd9909456954f507000363b Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 10:49:08 -0500 Subject: [PATCH 132/144] forgot donut woops --- _maps/map_files/DonutStation/DonutStation.dmm | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/_maps/map_files/DonutStation/DonutStation.dmm b/_maps/map_files/DonutStation/DonutStation.dmm index 2895b1bb47eb..51cb85755413 100644 --- a/_maps/map_files/DonutStation/DonutStation.dmm +++ b/_maps/map_files/DonutStation/DonutStation.dmm @@ -34382,9 +34382,6 @@ /turf/open/floor/plasteel, /area/quartermaster/miningdock) "oNx" = ( -/obj/structure/sign/barsign{ - pixel_y = 32 - }, /obj/machinery/door/poddoor/shutters/preopen{ id = "barshutters"; name = "bar shutters" @@ -46086,6 +46083,10 @@ }, /turf/open/floor/plasteel/dark/telecomms, /area/ai_monitored/turret_protected/ai) +"tPB" = ( +/obj/machinery/barsign, +/turf/closed/wall, +/area/crew_quarters/bar) "tPF" = ( /turf/open/floor/plasteel/white, /area/science/mixing) @@ -87656,7 +87657,7 @@ vDp wLr gxy jgR -gxy +tPB oNx rsE wuu From 89312040590dae865bc62bddc8d1138d92c07e4d Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Mon, 11 Dec 2023 11:07:29 -0500 Subject: [PATCH 133/144] who invented bar templaces lol --- _maps/RandomRuins/StationRuins/BoxStation/bar_arcade.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_box.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_casino.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_cheese.dmm | 6 +++--- _maps/RandomRuins/StationRuins/BoxStation/bar_citadel.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_clock.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_conveyor.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_diner.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_disco.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_grassy.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_irish.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_purple.dmm | 6 +++--- _maps/RandomRuins/StationRuins/BoxStation/bar_spacious.dmm | 2 +- _maps/RandomRuins/StationRuins/BoxStation/bar_trek.dmm | 2 +- 14 files changed, 18 insertions(+), 18 deletions(-) diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_arcade.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_arcade.dmm index 50167344080f..343ea1a24865 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_arcade.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_arcade.dmm @@ -448,7 +448,7 @@ /turf/open/floor/plasteel/cafeteria, /area/crew_quarters/kitchen) "dh" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dt" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_box.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_box.dmm index 0ae6910b7a8c..04c7b444b03a 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_box.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_box.dmm @@ -1197,7 +1197,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "dh" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "ge" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_casino.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_casino.dmm index 7e40e14c98d0..e327ce97fc68 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_casino.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_casino.dmm @@ -785,7 +785,7 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "dg" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "ge" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_cheese.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_cheese.dmm index 62b732bf11b5..fb3ba1a0b846 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_cheese.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_cheese.dmm @@ -736,7 +736,7 @@ /turf/open/floor/wood, /area/crew_quarters/bar) "dh" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dI" = ( @@ -1219,7 +1219,7 @@ bh bh aU aB -ag +dh "} (7,1,1) = {" ag @@ -1267,7 +1267,7 @@ aB aB aB Ju -dh +ag "} (10,1,1) = {" KK diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_citadel.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_citadel.dmm index 1bf21d92ca9a..3ccbc8a5c77b 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_citadel.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_citadel.dmm @@ -603,7 +603,7 @@ /turf/open/floor/plasteel/showroomfloor, /area/crew_quarters/kitchen) "ro" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "rP" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_clock.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_clock.dmm index d019e7d27b13..6a87a142dcdc 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_clock.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_clock.dmm @@ -791,7 +791,7 @@ /turf/open/floor/bronze/reebe, /area/crew_quarters/bar) "Fv" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall/mineral/bronze, /area/crew_quarters/bar) "FU" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_conveyor.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_conveyor.dmm index 786c1bbe7a3f..7db333968801 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_conveyor.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_conveyor.dmm @@ -782,7 +782,7 @@ /turf/open/floor/plasteel/vaporwave, /area/crew_quarters/bar) "cG" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "cH" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_diner.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_diner.dmm index 5319ea420ab6..168dc992917f 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_diner.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_diner.dmm @@ -845,7 +845,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "dj" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dH" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_disco.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_disco.dmm index de6b47d1c6e8..283977691fa1 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_disco.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_disco.dmm @@ -552,7 +552,7 @@ /turf/open/floor/plating, /area/crew_quarters/bar) "bN" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "bO" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_grassy.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_grassy.dmm index f620996e42dc..6893cee2dfb0 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_grassy.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_grassy.dmm @@ -278,7 +278,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "dg" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dU" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_irish.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_irish.dmm index 1d713fde9c43..defb3486f0c2 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_irish.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_irish.dmm @@ -1543,7 +1543,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "dc" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "du" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_purple.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_purple.dmm index 1a10636d1d4e..a955736cce23 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_purple.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_purple.dmm @@ -1166,7 +1166,7 @@ /turf/open/floor/plasteel/dark, /area/crew_quarters/bar) "dF" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dJ" = ( @@ -1741,7 +1741,7 @@ aw aw df Mr -dF +ab "} (10,1,1) = {" WM @@ -1757,7 +1757,7 @@ bz bz df ar -ab +dF "} (11,1,1) = {" ab diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_spacious.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_spacious.dmm index 531092b0368f..722ce8d9b84b 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_spacious.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_spacious.dmm @@ -761,7 +761,7 @@ /turf/open/floor/plasteel, /area/crew_quarters/bar) "cu" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "cz" = ( diff --git a/_maps/RandomRuins/StationRuins/BoxStation/bar_trek.dmm b/_maps/RandomRuins/StationRuins/BoxStation/bar_trek.dmm index 73fecfed1623..4a3817c3d013 100644 --- a/_maps/RandomRuins/StationRuins/BoxStation/bar_trek.dmm +++ b/_maps/RandomRuins/StationRuins/BoxStation/bar_trek.dmm @@ -964,7 +964,7 @@ /turf/open/floor/mineral/titanium/blue, /area/crew_quarters/bar) "df" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "dD" = ( From a376aa8b18ae4c0d23642e51f90a758aec1347fe Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 13 Dec 2023 20:12:05 -0500 Subject: [PATCH 134/144] yeah this --- _maps/map_files/YogStation/YogStation.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/map_files/YogStation/YogStation.dmm b/_maps/map_files/YogStation/YogStation.dmm index cf2d166b1393..081a2fbdf607 100644 --- a/_maps/map_files/YogStation/YogStation.dmm +++ b/_maps/map_files/YogStation/YogStation.dmm @@ -73261,7 +73261,7 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "xSX" = ( -/obj/structure/sign/barsign, +/obj/machinery/barsign, /turf/closed/wall, /area/crew_quarters/bar) "xTe" = ( From b517ee22fcf417709c11fa45268e3923024a2dc2 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 13 Dec 2023 20:22:52 -0500 Subject: [PATCH 135/144] whatever ok --- yogstation.dme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yogstation.dme b/yogstation.dme index e92c6d5c2ae0..89e337afa787 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -2145,8 +2145,8 @@ #include "code\modules\client\preferences\assets.dm" #include "code\modules\client\preferences\auto_fit_viewport.dm" #include "code\modules\client\preferences\balloon_alerts.dm" -#include "code\modules\client\preferences\clerk_choice.dm" #include "code\modules\client\preferences\chapel_choice.dm" +#include "code\modules\client\preferences\clerk_choice.dm" #include "code\modules\client\preferences\clothing.dm" #include "code\modules\client\preferences\credits.dm" #include "code\modules\client\preferences\donor.dm" From 111c4d68ba5cadda788080ad5fc95205ce1307e6 Mon Sep 17 00:00:00 2001 From: Byemoh Date: Fri, 22 Dec 2023 17:00:56 -0600 Subject: [PATCH 136/144] breaks a bunch of shit have fun --- code/game/machinery/computer/camera.dm | 27 +++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 0f1821fde21f..bee4bd7d7055 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -18,6 +18,8 @@ var/atom/movable/screen/map_view/cam_screen /// All the plane masters that need to be applied. var/atom/movable/screen/background/cam_background + var/list/cam_plane_masters + var/renderLighting = TRUE interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT @@ -33,7 +35,21 @@ network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.generate_view(map_name) + cam_screen.name = "screen" + cam_screen.assigned_map = map_name + cam_screen.del_on_map_removal = FALSE + cam_screen.screen_loc = "[map_name]:1,1" + /* + cam_plane_masters = list() + for(var/plane in subtypesof(/atom/movable/screen/plane_master)) + var/atom/movable/screen/instance = new plane() + if (!renderLighting && instance.plane == LIGHTING_PLANE) + instance.alpha = 100 + instance.assigned_map = map_name + instance.del_on_map_removal = FALSE + instance.screen_loc = "[map_name]:CENTER" + cam_plane_masters += instance + */ cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE @@ -65,7 +81,10 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - cam_screen.display_to(user) + //cam_screen.display_to(user) + user.client.register_map_obj(cam_screen) + for(var/plane in cam_plane_masters) + user.client.register_map_obj(plane) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) @@ -134,14 +153,16 @@ // If we're not forcing an update for some reason and the cameras are in the same location, // we don't need to update anything. // Most security cameras will end here as they're not moving. + /* if(last_camera_turf == new_cam_turf) return + */ // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. last_camera_turf = new_cam_turf //Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present - var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf) + var/list/visible_things = range(active_camera.view_range, new_cam_turf) for(var/turf/visible_turf in visible_things) visible_turfs += visible_turf From 8312466a76213bdb6ac1a72817e941d04c2be414 Mon Sep 17 00:00:00 2001 From: Byemoh Date: Fri, 22 Dec 2023 20:27:32 -0600 Subject: [PATCH 137/144] Revert "breaks a bunch of shit have fun" This reverts commit 111c4d68ba5cadda788080ad5fc95205ce1307e6. --- code/game/machinery/computer/camera.dm | 27 +++----------------------- 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index bee4bd7d7055..0f1821fde21f 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -18,8 +18,6 @@ var/atom/movable/screen/map_view/cam_screen /// All the plane masters that need to be applied. var/atom/movable/screen/background/cam_background - var/list/cam_plane_masters - var/renderLighting = TRUE interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT @@ -35,21 +33,7 @@ network += lowertext(i) // Initialize map objects cam_screen = new - cam_screen.name = "screen" - cam_screen.assigned_map = map_name - cam_screen.del_on_map_removal = FALSE - cam_screen.screen_loc = "[map_name]:1,1" - /* - cam_plane_masters = list() - for(var/plane in subtypesof(/atom/movable/screen/plane_master)) - var/atom/movable/screen/instance = new plane() - if (!renderLighting && instance.plane == LIGHTING_PLANE) - instance.alpha = 100 - instance.assigned_map = map_name - instance.del_on_map_removal = FALSE - instance.screen_loc = "[map_name]:CENTER" - cam_plane_masters += instance - */ + cam_screen.generate_view(map_name) cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE @@ -81,10 +65,7 @@ playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE) use_power(active_power_usage) // Register map objects - //cam_screen.display_to(user) - user.client.register_map_obj(cam_screen) - for(var/plane in cam_plane_masters) - user.client.register_map_obj(plane) + cam_screen.display_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) @@ -153,16 +134,14 @@ // If we're not forcing an update for some reason and the cameras are in the same location, // we don't need to update anything. // Most security cameras will end here as they're not moving. - /* if(last_camera_turf == new_cam_turf) return - */ // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. last_camera_turf = new_cam_turf //Here we gather what's visible from the camera's POV based on its view_range and xray modifier if present - var/list/visible_things = range(active_camera.view_range, new_cam_turf) + var/list/visible_things = active_camera.isXRay(ignore_malf_upgrades = TRUE) ? range(active_camera.view_range, new_cam_turf) : view(active_camera.view_range, new_cam_turf) for(var/turf/visible_turf in visible_things) visible_turfs += visible_turf From 4c8b1f698c0140d4d0a752a1606be6d5984912d0 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 28 Dec 2023 09:29:33 -0500 Subject: [PATCH 138/144] adjusts cryo eye blur ye --- code/game/machinery/cryopod.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index ec8b87cbeae2..1f9ff2b07e32 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -454,7 +454,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) if(prob(90)) sleepyhead.adjust_drowsiness(rand(3 SECONDS, 10 SECONDS)) if(prob(75)) - sleepyhead.blur_eyes(rand(3, 6)) + sleepyhead.adjust_eye_bur(rand(3, 6)) //so much worse if(prob(66)) sleepyhead.adjust_disgust(rand(25,35)) From ff314a631c26f4e815a4a0652f8016df87f3af6d Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Thu, 28 Dec 2023 10:13:19 -0500 Subject: [PATCH 139/144] you ever just spell blur wrong --- code/game/machinery/cryopod.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 1f9ff2b07e32..f7720655fa93 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -454,7 +454,7 @@ GLOBAL_VAR_INIT(cryopods_enabled, FALSE) if(prob(90)) sleepyhead.adjust_drowsiness(rand(3 SECONDS, 10 SECONDS)) if(prob(75)) - sleepyhead.adjust_eye_bur(rand(3, 6)) + sleepyhead.adjust_eye_blur(rand(3, 6)) //so much worse if(prob(66)) sleepyhead.adjust_disgust(rand(25,35)) From f301064ecf2ff96b937d9ce4ac6f717afce052da Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:55:56 -0500 Subject: [PATCH 140/144] Nah, I'd port it Fixes cameras --- _maps/_basemap.dm | 2 +- _maps/map_files/debug/runtimestation.dmm | 6 ++++- code/_onclick/hud/map_view.dm | 4 +++- code/_onclick/hud/plane_master.dm | 5 ++-- code/_onclick/hud/plane_master_group.dm | 4 +++- code/_onclick/hud/render_plate.dm | 14 ++++++++---- code/game/machinery/camera/camera.dm | 8 +++---- code/game/machinery/computer/camera.dm | 29 +++++++++++++++++++++--- code/modules/mob/living/carbon/carbon.dm | 4 ---- code/modules/surgery/organs/eyes.dm | 2 -- 10 files changed, 55 insertions(+), 23 deletions(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index 48b96c8948f7..aadbfa88a035 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index be101576b003..7a4e2178dda5 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -2665,6 +2665,10 @@ /obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/medical/chemistry) +"vT" = ( +/obj/machinery/computer/security, +/turf/open/floor/plating, +/area/storage/primary) "wb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -8652,7 +8656,7 @@ dl gg ez dB -dl +vT dl dl dx diff --git a/code/_onclick/hud/map_view.dm b/code/_onclick/hud/map_view.dm index bc304f20f8a1..79e4d7ae10bc 100644 --- a/code/_onclick/hud/map_view.dm +++ b/code/_onclick/hud/map_view.dm @@ -14,6 +14,8 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) // Weakrefs of all our hud viewers -> a weakref to the hud datum they last used var/list/datum/weakref/viewers_to_huds = list() + var/datum/plane_master_group/popup/pop_planes + /atom/movable/screen/map_view/Destroy() for(var/datum/weakref/client_ref in viewers_to_huds) var/client/our_client = client_ref.resolve() @@ -48,7 +50,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/map_view) return our_hud.get_plane_group(PLANE_GROUP_POPUP_WINDOW(src)) // Generate a new plane group for this case - var/datum/plane_master_group/popup/pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) + pop_planes = new(PLANE_GROUP_POPUP_WINDOW(src), assigned_map) viewers_to_huds[client_ref] = WEAKREF(show_to.hud_used) pop_planes.attach_to(show_to.hud_used) diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index 13f94fa9f5aa..9cb3c06b71f1 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -63,8 +63,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master) /// If this plane master is outside of our visual bounds right now var/is_outside_bounds = FALSE + var/relay_loc_debug = "CENTER" -/atom/movable/screen/plane_master/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset = 0) +/atom/movable/screen/plane_master/Initialize(mapload, datum/hud/hud_owner, datum/plane_master_group/home, offset = 0, relay_loc_override = null) . = ..() src.offset = offset true_alpha = alpha @@ -77,7 +78,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master) stack_trace("Plane master created without a description. Document how your thing works so people will know in future, and we can display it in the debug menu") if(start_hidden) hide_plane(home.our_hud?.mymob) - generate_render_relays() + generate_render_relays(relay_loc_override) /atom/movable/screen/plane_master/Destroy() if(home) diff --git a/code/_onclick/hud/plane_master_group.dm b/code/_onclick/hud/plane_master_group.dm index 1205b871fd81..6a0e39322d30 100644 --- a/code/_onclick/hud/plane_master_group.dm +++ b/code/_onclick/hud/plane_master_group.dm @@ -13,6 +13,7 @@ var/active_offset = 0 /// What, if any, submap we render onto var/map = "" + var/relay_loc_override = null /datum/plane_master_group/New(key, map = "") . = ..() @@ -84,7 +85,7 @@ for(var/plane_offset in starting_offset to ending_offset) if(plane_offset != 0 && !initial(mytype.allows_offsetting)) continue - var/atom/movable/screen/plane_master/instance = new mytype(null, null, src, plane_offset) + var/atom/movable/screen/plane_master/instance = new mytype(null, null, src, plane_offset, relay_loc_override) plane_masters["[instance.plane]"] = instance prep_plane_instance(instance) @@ -170,6 +171,7 @@ /// If you wanna try someday feel free, but I can't manage it /datum/plane_master_group/popup + relay_loc_override = "LEFT,TOP" // /datum/plane_master_group/popup/transform_lower_turfs(datum/hud/source, new_offset, use_scale = TRUE) // return ..(source, new_offset, FALSE) diff --git a/code/_onclick/hud/render_plate.dm b/code/_onclick/hud/render_plate.dm index a50bd33ce52d..a8fac41d07c6 100644 --- a/code/_onclick/hud/render_plate.dm +++ b/code/_onclick/hud/render_plate.dm @@ -299,8 +299,8 @@ * * name for debugging purposes * Other vars such as alpha will automatically be applied with the render source */ -/atom/movable/screen/plane_master/proc/generate_render_relays() - var/relay_loc = "CENTER" +/atom/movable/screen/plane_master/proc/generate_render_relays(relay_loc_override) + var/relay_loc = relay_loc_override ? relay_loc_override : "CENTER" // If we're using a submap (say for a popup window) make sure we draw onto it if(home?.map) relay_loc = "[home.map]:[relay_loc]" @@ -319,12 +319,12 @@ /// Creates a connection between this plane master and the passed in plane /// Helper for out of system code, shouldn't be used in this file /// Build system to differenchiate between generated and non generated render relays -/atom/movable/screen/plane_master/proc/add_relay_to(target_plane, blend_override, relay_layer, relay_color) +/atom/movable/screen/plane_master/proc/add_relay_to(target_plane, blend_override, relay_layer, relay_color, relay_loc) if(get_relay_to(target_plane)) return render_relay_planes += target_plane var/client/display_lad = home?.our_hud?.mymob?.canon_client - var/atom/movable/render_plane_relay/relay = generate_relay_to(target_plane, show_to = display_lad, blend_override = blend_override, relay_layer = relay_layer) + var/atom/movable/render_plane_relay/relay = generate_relay_to(target_plane, relay_loc = relay_loc, show_to = display_lad, blend_override = blend_override, relay_layer = relay_layer) relay.color = relay_color /proc/get_plane_master_render_base(name) @@ -384,3 +384,9 @@ return relay return null + +/atom/movable/screen/plane_master/proc/remove_all_relays() + for(var/atom/movable/render_plane_relay/relay in relays) + remove_relay_from(relay.plane) + + relays_generated = FALSE diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 292b13f2cd91..f7ee0cce9b84 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -96,7 +96,7 @@ if(mapload && is_station_level(z) && prob(3) && !start_active) toggle_cam() else //this is handled by toggle_camera, so no need to update it twice. - update_appearance(UPDATE_ICON) + update_appearance() /obj/machinery/camera/Destroy() if(can_use()) @@ -146,14 +146,14 @@ return if(!(. & EMP_PROTECT_SELF)) if(prob(15 * severity)) - update_appearance(UPDATE_ICON) + update_appearance() var/list/previous_network = network network = list() GLOB.cameranet.removeCamera(src) stat |= EMPED set_light(0) emped = emped+1 //Increase the number of consecutive EMP's - update_appearance(UPDATE_ICON) + update_appearance() var/thisemp = emped //Take note of which EMP this proc is for spawn(900) if(loc) //qdel limbo @@ -161,7 +161,7 @@ if(emped == thisemp) //Only fix it if the camera hasn't been EMP'd again network = previous_network stat &= ~EMPED - update_appearance(UPDATE_ICON) + update_appearance() if(can_use()) GLOB.cameranet.addCamera(src) emped = 0 //Resets the consecutive EMP count diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 0f1821fde21f..ae5c81f9f8ba 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -19,6 +19,13 @@ /// All the plane masters that need to be applied. var/atom/movable/screen/background/cam_background + var/datum/plane_master_group/popup/pop_planes + + var/list/cam_plane_masters + + var/size_x = 0 + var/size_y = 0 + interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON|INTERACT_MACHINE_REQUIRES_SIGHT /obj/machinery/computer/security/Initialize(mapload) @@ -34,12 +41,25 @@ // Initialize map objects cam_screen = new cam_screen.generate_view(map_name) + pop_planes = cam_screen.pop_planes + cam_plane_masters = list() + //subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/rendering_plate + // for(var/plane in subtypesof(/atom/movable/screen/plane_master) - /atom/movable/screen/plane_master/rendering_plate) + // var/atom/movable/screen/plane_master/instance = new plane() + // instance.assigned_map = map_name + // instance.del_on_map_removal = FALSE + // instance.screen_loc = "[map_name]:CENTER" + // cam_plane_masters += instance + cam_background = new cam_background.assigned_map = map_name cam_background.del_on_map_removal = FALSE + + /obj/machinery/computer/security/Destroy() QDEL_NULL(cam_screen) + QDEL_LIST(cam_plane_masters) QDEL_NULL(cam_background) return ..() @@ -66,6 +86,9 @@ use_power(active_power_usage) // Register map objects cam_screen.display_to(user) + // user.client.register_map_obj(cam_screen) + // for(var/atom/movable/screen/plane_master/instance in cam_plane_masters) + // instance.show_to(user) user.client.register_map_obj(cam_background) // Open UI ui = new(user, src, "CameraConsole", name) @@ -107,7 +130,7 @@ . = ..() if(.) return - + if(action == "switch_camera") var/obj/machinery/camera/selected_camera = locate(params["camera"]) in GLOB.cameranet.cameras active_camera = selected_camera @@ -148,8 +171,8 @@ //Get coordinates for a rectangle area that contains the turfs we see so we can then clear away the static in the resulting rectangle area var/list/bbox = get_bbox_of_atoms(visible_turfs) - var/size_x = bbox[3] - bbox[1] + 1 - var/size_y = bbox[4] - bbox[2] + 1 + size_x = bbox[3] - bbox[1] + 1 + size_y = bbox[4] - bbox[2] + 1 cam_screen.vis_contents = visible_turfs cam_background.icon_state = "clear" diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8fee7edfffcc..03536d25cff7 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -571,16 +571,12 @@ lighting_color_cutoffs = list(lighting_cutoff_red, lighting_cutoff_green, lighting_cutoff_blue) sight = initial(sight) see_infrared = initial(see_infrared) - lighting_alpha = initial(lighting_alpha) var/obj/item/organ/eyes/E = getorganslot(ORGAN_SLOT_EYES) if(!E) update_tint() else see_invisible = E.see_invisible - see_in_dark = E.see_in_dark sight |= E.sight_flags - if(!isnull(E.lighting_alpha)) - lighting_alpha = E.lighting_alpha if(istype(E, /obj/item/organ/eyes/ethereal) && client) //special view range ethereal eyes client.view_size.resetToDefault(getScreenSize(client.prefs.read_preference(/datum/preference/toggle/widescreen))) client.view_size.addTo("2x2") diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 73a0a077c834..1a98633c3a53 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -502,8 +502,6 @@ desc = "It turned out they had them after all!" sight_flags = SEE_MOBS color_cutoffs = list(25, 5, 42) - lighting_alpha = LIGHTING_PLANE_ALPHA_NV_TRAIT - see_in_dark = 5 /obj/item/organ/eyes/ethereal name = "fractal eyes" From 9902aeb980ebe6b29c9ab5f99b6da042e44893de Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 5 Jan 2024 09:56:15 -0500 Subject: [PATCH 141/144] remove basemap --- _maps/_basemap.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/_basemap.dm b/_maps/_basemap.dm index aadbfa88a035..48b96c8948f7 100644 --- a/_maps/_basemap.dm +++ b/_maps/_basemap.dm @@ -1,4 +1,4 @@ -#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. +//#define LOWMEMORYMODE //uncomment this to load centcom and runtime station and thats it. #include "map_files\generic\CentCom.dmm" From 10cb52235fee13f5268d826ecf426032b108b2de Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 5 Jan 2024 10:00:01 -0500 Subject: [PATCH 142/144] removes runtimestation changes oops --- _maps/map_files/debug/runtimestation.dmm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/_maps/map_files/debug/runtimestation.dmm b/_maps/map_files/debug/runtimestation.dmm index 7a4e2178dda5..be101576b003 100644 --- a/_maps/map_files/debug/runtimestation.dmm +++ b/_maps/map_files/debug/runtimestation.dmm @@ -2665,10 +2665,6 @@ /obj/machinery/door/airlock/public/glass, /turf/open/floor/plasteel, /area/medical/chemistry) -"vT" = ( -/obj/machinery/computer/security, -/turf/open/floor/plating, -/area/storage/primary) "wb" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -8656,7 +8652,7 @@ dl gg ez dB -vT +dl dl dl dx From 7f45cc84dbcf51163c7f15b7e75f4ec323013244 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 5 Jan 2024 13:36:46 -0500 Subject: [PATCH 143/144] Up[dates all of thhis --- code/_onclick/hud/parallax.dm | 17 +++++++++++++---- icons/obj/wallmounts.dmi | Bin 4690 -> 4612 bytes .../code/modules/jungleland/jungle_datums.dm | 10 +++++----- .../modules/jungleland/jungle_structures.dm | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/code/_onclick/hud/parallax.dm b/code/_onclick/hud/parallax.dm index 3643d7848834..c9e1f580399f 100755 --- a/code/_onclick/hud/parallax.dm +++ b/code/_onclick/hud/parallax.dm @@ -15,10 +15,16 @@ C.parallax_layers_cached = list() C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_1(null, src) C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_2(null, src) - if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, src) - else - C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, src) + if(!GLOB.minetype) + stack_trace("GLOB.minetype wasn't set when creating parallax! uh oh!!") + + if(GLOB.minetype == MINETYPE_LAVALAND) + if(HAS_TRAIT(SSstation, STATION_TRAIT_MOONSCORCH)) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/moonscorch(null, C.view) + else + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet(null, C.view) + if(GLOB.minetype == MINETYPE_JUNGLE) + C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/planet/jungle(null, C.view) if(SSparallax.random_layer) C.parallax_layers_cached += new SSparallax.random_layer.type(null, src, FALSE, SSparallax.random_layer) C.parallax_layers_cached += new /atom/movable/screen/parallax_layer/layer_3(null, src) @@ -340,6 +346,9 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/parallax_layer) speed = 3 layer = 30 +/atom/movable/screen/parallax_layer/planet/jungle + icon_state = "jungleland" + /atom/movable/screen/parallax_layer/planet/moonscorch icon_state = "rheus_moon" diff --git a/icons/obj/wallmounts.dmi b/icons/obj/wallmounts.dmi index 43601b49844c062cc5c356ab6ff1d4016f62c6ef..2e392b221d95b508f2c3e7d4c55e6df15bf2d23d 100644 GIT binary patch literal 4612 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 literal 4690 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 diff --git a/yogstation/code/modules/jungleland/jungle_datums.dm b/yogstation/code/modules/jungleland/jungle_datums.dm index 477ea44f8a09..3145ab49c532 100644 --- a/yogstation/code/modules/jungleland/jungle_datums.dm +++ b/yogstation/code/modules/jungleland/jungle_datums.dm @@ -11,7 +11,7 @@ screen_loc = "CENTER-9,CENTER-7" appearance_flags = TILE_BOUND layer = ABOVE_OPEN_TURF_LAYER - plane = BLACKNESS_PLANE + plane = DEFAULT_PLANE alpha = 0 //we animate it ourselves //wall trip @@ -21,7 +21,7 @@ screen_loc = "CENTER-9,CENTER-7" appearance_flags = TILE_BOUND layer = BELOW_MOB_LAYER - plane = BLACKNESS_PLANE + plane = DEFAULT_PLANE alpha = 0 //we animate it ourselves // reagents @@ -111,7 +111,7 @@ if(!L.hud_used || !L.client) return - var/atom/movable/screen/plane_master/game_world/game_plane = L.hud_used.plane_masters["[GAME_PLANE]"] + var/atom/movable/screen/plane_master/game_plane = L.hud_used.plane_masters["[GAME_PLANE]"] var/atom/movable/screen/plane_master/floor/floor_plane = L.hud_used.plane_masters["[FLOOR_PLANE]"] cached_screen = L.overlay_fullscreen("polycybin_trip",/atom/movable/screen/fullscreen/trip) @@ -134,7 +134,7 @@ L.clear_fullscreen("polycybin_gtrip") -/datum/reagent/jungle/polybycin/proc/update_filters(mob/living/L) +/datum/reagent/jungle/polybycin/proc/update_jungle_filters(mob/living/L) if(!L.client) return @@ -243,7 +243,7 @@ /datum/reagent/toxin/meduracha/on_mob_life(mob/living/carbon/M) M.damageoverlaytemp = 60 M.update_damage_hud() - M.blur_eyes(3) + M.adjust_eye_blur(3) return ..() /datum/reagent/quinine diff --git a/yogstation/code/modules/jungleland/jungle_structures.dm b/yogstation/code/modules/jungleland/jungle_structures.dm index 366bf7d4d5c7..095b5cad2c1f 100644 --- a/yogstation/code/modules/jungleland/jungle_structures.dm +++ b/yogstation/code/modules/jungleland/jungle_structures.dm @@ -152,7 +152,7 @@ L.set_blindness(20) SEND_SIGNAL(L,COMSIG_JUNGLELAND_TAR_CURSE_PROC) else - L.set_blurriness(20) + L.set_eye_blur(20) return ..() /obj/effect/timed_attack/tar_priest/tendril replace_icon_state = "tar_shade_tendril" From 76a406128a68eec0bc850627e5dcadd2d0b861cb Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Fri, 5 Jan 2024 13:47:23 -0500 Subject: [PATCH 144/144] Meaningless update to fix gax --- code/modules/client/preferences/ambient_occlusion.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/client/preferences/ambient_occlusion.dm b/code/modules/client/preferences/ambient_occlusion.dm index cf8bf28c1e56..ebadc64451ce 100644 --- a/code/modules/client/preferences/ambient_occlusion.dm +++ b/code/modules/client/preferences/ambient_occlusion.dm @@ -8,3 +8,4 @@ /// Backdrop for the game world plane. for(var/atom/movable/screen/plane_master/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(GAME_PLANE)) plane_master.show_to(client.mob) +

    kuQcd^$;0m7Zysw5M-BcjUGaikr=Xv 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 Date: Tue, 5 Dec 2023 16:13:45 -0500 Subject: [PATCH 115/144] Fixes barsigns breaks all lights and updates barsigns to be machines and not structures We will address this in a later patch --- code/datums/mutable_appearance.dm | 53 +++- code/game/machinery/barsigns.dm | 17 +- code/game/objects/structures/barsigns.dm | 348 ----------------------- yogstation.dme | 1 - 4 files changed, 47 insertions(+), 372 deletions(-) delete mode 100644 code/game/objects/structures/barsigns.dm diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index f248da2a7323..c066b96cea41 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -4,18 +4,45 @@ // Mutable appearances are children of images, just so you know. -/mutable_appearance/New() +// Mutable appearances erase template vars on new, because they accept an appearance to copy as an arg +// If we have nothin to copy, we set the float plane +/mutable_appearance/New(mutable_appearance/to_copy) ..() - plane = FLOAT_PLANE // No clue why this is 0 by default yet images are on FLOAT_PLANE - // And yes this does have to be in the constructor, BYOND ignores it if you set it as a normal var + if(!to_copy) + plane = FLOAT_PLANE -// Helper similar to image() -/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE) - var/mutable_appearance/MA = new() - MA.icon = icon - MA.icon_state = icon_state - MA.layer = layer - MA.plane = plane - MA.alpha = alpha - MA.appearance_flags |= appearance_flags - return MA +/** Helper similar to image() + * + * icon - Our appearance's icon + * icon_state - Our appearance's icon state + * layer - Our appearance's layer + * atom/offset_spokesman - An atom to use as reference for the z position of this appearance. + * Only required if a plane is passed in. If this is not passed in we accept offset_const as a substitute + * plane - The plane to use for the appearance. If this is not FLOAT_PLANE we require context for the offset to use + * alpha - Our appearance's alpha + * appearance_flags - Our appearance's appearance_flags + * offset_const - A constant to offset our plane by, so it renders on the right "z layer" +**/ +/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, atom/offset_spokesman, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, offset_const) + var/mutable_appearance/appearance = new() + appearance.icon = icon + appearance.icon_state = icon_state + appearance.layer = layer + appearance.alpha = alpha + appearance.appearance_flags |= appearance_flags + if(plane != FLOAT_PLANE) + // You need to pass in some non null object to reference + if(isatom(offset_spokesman)) + // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be + // Not passing ANYTHING in, key difference + SET_PLANE_EXPLICIT(appearance, plane, offset_spokesman) + // That or I'll let you pass in a static offset. Don't be stupid now + else if(!isnull(offset_const)) + SET_PLANE_W_SCALAR(appearance, plane, offset_const) + // otherwise if you're setting plane you better have the guts to back it up + else + stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") + else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) + stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") + + return appearance diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm index 1842a2dfbbaf..b3172c518943 100644 --- a/code/game/machinery/barsigns.dm +++ b/code/game/machinery/barsigns.dm @@ -13,6 +13,8 @@ /// What kind of sign do we drop upon being disassembled? var/disassemble_result = /obj/item/wallframe/barsign light_color = LIGHT_COLOR_BLUE + /// If barsign has a lighting mask + var/light_mask = FALSE /datum/armor/sign_barsign melee = 20 @@ -64,12 +66,14 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) /obj/machinery/barsign/update_overlays() . = ..() - + + . += emissive_appearance(icon, "[chosen_sign.icon_state]-light-mask", src) if(((stat & NOPOWER) && !(stat & EMPED)) || (stat & BROKEN)) return if(chosen_sign && chosen_sign.light_mask) - . += emissive_appearance(icon, "[chosen_sign.icon_state]-light-mask", src, alpha = src.alpha) + SSvis_overlays.add_vis_overlay(src, icon, light_mask, EMISSIVE_LAYER, EMISSIVE_PLANE) + . += emissive_appearance(icon, "[chosen_sign.icon_state]-light-mask", src) /obj/machinery/barsign/update_appearance(updates=ALL) . = ..() @@ -209,7 +213,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) /// Rename the area when this sign is selected. var/rename_area = TRUE /// If a barsign has a light mask for emission effects - var/light_mask + var/light_mask = TRUE /// The emission color of the neon light var/neon_color @@ -405,18 +409,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) desc = "When it feels like you're stuck in a pit, might as well have a drink." neon_color = "#aa2811" -/datum/barsign/orangejuice - name = "Oranges' Juicery" - icon_state = "orangejuice" - desc = "For those who wish to be optimally tactful to the non-alcoholic population." - neon_color = COLOR_ORANGE - /datum/barsign/tearoom name = "Little Treats Tea Room" icon_state = "little_treats" desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos." neon_color = LIGHT_COLOR_ORANGE - light_mask = "little_treats-light-mask" /datum/barsign/assembly_line name = "The Assembly Line" diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm deleted file mode 100644 index e8604b563d7b..000000000000 --- a/code/game/objects/structures/barsigns.dm +++ /dev/null @@ -1,348 +0,0 @@ -// /obj/structure/sign/barsign // All Signs are 64 by 32 pixels, they take two tiles -// name = "bar sign" -// desc = "A bar sign which has not been initialized, somehow. Complain at a coder!" -// icon = 'icons/obj/barsigns.dmi' -// icon_state = "empty" -// req_access = list(ACCESS_BAR) -// max_integrity = 500 -// integrity_failure = 250 -// armor = list(MELEE = 20, BULLET = 20, LASER = 20, ENERGY = 100, BOMB = 0, BIO = 0, RAD = 0, FIRE = 50, ACID = 50) -// buildable_sign = 0 - -// var/panel_open = FALSE -// var/datum/barsign/chosen_sign - -// // /obj/structure/sign/barsign/Initialize(mapload) -// // . = ..() -// // set_sign(new /datum/barsign/hiddensigns/signoff) - -// /obj/structure/sign/barsign/proc/set_sign(datum/barsign/sign) -// if(!istype(sign)) -// return - -// icon_state = sign.icon - -// if(sign.name) -// name = "[initial(name)] ([sign.name])" -// else -// name = "[initial(name)]" - -// if(sign.desc) -// desc = sign.desc - -// if(sign.rename_area && sign.name) -// rename_area(src, sign.name) - -// return sign - -// /obj/structure/sign/barsign/proc/set_sign_by_name(sign_name) -// for(var/d in subtypesof(/datum/barsign)) -// var/datum/barsign/D = d -// if(initial(D.name) == sign_name) -// var/new_sign = new D -// return set_sign(new_sign) - -// /obj/structure/sign/barsign/obj_break(damage_flag) -// if(!broken && !(flags_1 & NODECONSTRUCT_1)) -// broken = TRUE - -// /obj/structure/sign/barsign/deconstruct(disassembled = TRUE) -// new /obj/item/stack/sheet/metal(drop_location(), 2) -// new /obj/item/stack/cable_coil(drop_location(), 2) -// qdel(src) - -// /obj/structure/sign/barsign/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0) -// switch(damage_type) -// if(BRUTE) -// playsound(src.loc, 'sound/effects/glasshit.ogg', 75, 1) -// if(BURN) -// playsound(src.loc, 'sound/items/welder.ogg', 100, 1) - -// /obj/structure/sign/barsign/attack_ai(mob/user) -// return attack_hand(user) - -// /obj/structure/sign/barsign/attack_hand(mob/user) -// . = ..() -// if(.) -// return -// if(!allowed(user)) -// to_chat(user, span_info("Access denied.")) -// return -// if(broken) -// to_chat(user, "The controls seem unresponsive.") -// return -// pick_sign(user) - -// /obj/structure/sign/barsign/attackby(obj/item/I, mob/user) -// if(I.tool_behaviour == TOOL_SCREWDRIVER) -// if(!panel_open) -// to_chat(user, span_notice("You open the maintenance panel.")) -// set_sign(new /datum/barsign/hiddensigns/signoff) -// panel_open = TRUE -// else -// to_chat(user, span_notice("You close the maintenance panel.")) -// if(!broken) -// if(!chosen_sign) -// set_sign(new /datum/barsign/hiddensigns/signoff) -// else -// set_sign(chosen_sign) -// else -// set_sign(new /datum/barsign/hiddensigns/empbarsign) -// panel_open = FALSE - -// else if(istype(I, /obj/item/stack/cable_coil) && panel_open) -// var/obj/item/stack/cable_coil/C = I -// if(!broken) -// to_chat(user, span_warning("This sign is functioning properly!")) -// return - -// if(C.use(2)) -// to_chat(user, span_notice("You replace the burnt wiring.")) -// broken = FALSE -// else -// to_chat(user, span_warning("You need at least two lengths of cable!")) -// else -// return ..() - - -// /obj/structure/sign/barsign/emp_act(severity) -// . = ..() -// if(. & EMP_PROTECT_SELF) -// return -// set_sign(new /datum/barsign/hiddensigns/empbarsign) -// // broken = TRUE - -// /obj/structure/sign/barsign/emag_act(mob/user, obj/item/card/emag/emag_card) -// if(broken) -// to_chat(user, span_warning("Nothing interesting happens!")) -// return FALSE -// to_chat(user, span_notice("You load an illegal barsign into the memory buffer...")) -// addtimer(CALLBACK(src, PROC_REF(finish_emag_act)), 10 SECONDS) -// return TRUE - -// /obj/structure/sign/barsign/proc/finish_emag_act() -// if(QDELETED(src)) -// return -// chosen_sign = set_sign(new /datum/barsign/hiddensigns/syndibarsign) - -// /obj/structure/sign/barsign/proc/pick_sign(mob/user) -// var/picked_name = input(user, "Available Signage", "Bar Sign", name) as null|anything in get_bar_names() -// if(!picked_name) -// return -// chosen_sign = set_sign_by_name(picked_name) -// SSblackbox.record_feedback("tally", "barsign_picked", 1, chosen_sign.type) - -// /proc/get_bar_names() -// var/list/names = list() -// for(var/d in subtypesof(/datum/barsign)) -// var/datum/barsign/D = d -// if(initial(D.name) && !initial(D.hidden)) -// names += initial(D.name) -// . = names - -// /datum/barsign -// var/name = "Name" -// var/icon = "Icon" -// var/desc = "desc" -// var/hidden = FALSE -// var/rename_area = TRUE - -// /datum/barsign/New() -// if(!desc) -// desc = "It displays \"[name]\"." - -// // Specific bar signs. - -// /datum/barsign/maltesefalcon -// name = "Maltese Falcon" -// icon = "maltesefalcon" -// desc = "The Maltese Falcon, Space Bar and Grill." - -// /datum/barsign/thebark -// name = "The Bark" -// icon = "thebark" -// desc = "Ian's bar of choice." - -// /datum/barsign/harmbaton -// name = "The Harmbaton" -// icon = "theharmbaton" -// desc = "A great dining experience for both security members and assistants." - -// /datum/barsign/thesingulo -// name = "The Singulo" -// icon = "thesingulo" -// desc = "Where people go that'd rather not be called by their name." - -// /datum/barsign/thedrunkcarp -// name = "The Drunk Carp" -// icon = "thedrunkcarp" -// desc = "Don't drink and swim." - -// /datum/barsign/scotchservinwill -// name = "Scotch Servin Willy's" -// icon = "scotchservinwill" -// desc = "Willy sure moved up in the world from clown to bartender." - -// /datum/barsign/officerbeersky -// name = "Officer Beersky's" -// icon = "officerbeersky" -// desc = "Man eat a dong, these drinks are great." - -// /datum/barsign/thecavern -// name = "The Cavern" -// icon = "thecavern" -// desc = "Fine drinks while listening to some fine tunes." - -// /datum/barsign/theouterspess -// name = "The Outer Spess" -// icon = "theouterspess" -// desc = "This bar isn't actually located in outer space." - -// /datum/barsign/slipperyshots -// name = "Slippery Shots" -// icon = "slipperyshots" -// desc = "Slippery slope to drunkenness with our shots!" - -// /datum/barsign/thegreytide -// name = "The Grey Tide" -// icon = "thegreytide" -// desc = "Abandon your toolboxing ways and enjoy a lazy beer!" - -// /datum/barsign/honkednloaded -// name = "Honked 'n' Loaded" -// icon = "honkednloaded" -// desc = "Honk." - -// /datum/barsign/thenest -// name = "The Nest" -// icon = "thenest" -// desc = "A good place to retire for a drink after a long night of crime fighting." - -// /datum/barsign/thecoderbus -// name = "The Coderbus" -// icon = "thecoderbus" -// desc = "A very controversial bar known for its wide variety of constantly-changing drinks." - -// /datum/barsign/theadminbus -// name = "The Adminbus" -// icon = "theadminbus" -// desc = "An establishment visited mainly by space-judges. It isn't bombed nearly as much as court hearings." - -// /datum/barsign/oldcockinn -// name = "The Old Cock Inn" -// icon = "oldcockinn" -// desc = "Something about this sign fills you with despair." - -// /datum/barsign/thewretchedhive -// name = "The Wretched Hive" -// icon = "thewretchedhive" -// desc = "Legally obligated to instruct you to check your drinks for acid before consumption." - -// /datum/barsign/robustacafe -// name = "The Robusta Cafe" -// icon = "robustacafe" -// desc = "Holder of the 'Most Lethal Barfights' record 5 years uncontested." - -// /datum/barsign/emergencyrumparty -// name = "The Emergency Rum Party" -// icon = "emergencyrumparty" -// desc = "Recently relicensed after a long closure." - -// /datum/barsign/combocafe -// name = "The Combo Cafe" -// icon = "combocafe" -// desc = "Renowned system-wide for their utterly uncreative drink combinations." - -// /datum/barsign/vladssaladbar -// name = "Vlad's Salad Bar" -// icon = "vladssaladbar" -// desc = "Under new management. Vlad was always a bit too trigger happy with that shotgun." - -// /datum/barsign/theshaken -// name = "The Shaken" -// icon = "theshaken" -// desc = "This establishment does not serve stirred drinks." - -// /datum/barsign/thealenath -// name = "The Ale' Nath" -// icon = "thealenath" -// desc = "All right, buddy. I think you've had EI NATH. Time to get a cab." - -// /datum/barsign/thealohasnackbar -// name = "The Aloha Snackbar" -// icon = "alohasnackbar" -// desc = "A tasteful, inoffensive tiki bar sign." - -// /datum/barsign/thenet -// name = "The Net" -// icon = "thenet" -// desc = "You just seem to get caught up in it for hours." - -// /datum/barsign/maidcafe -// name = "Maid Cafe" -// icon = "maidcafe" -// desc = "Welcome back, master!" - -// /datum/barsign/the_lightbulb -// name = "The Lightbulb" -// icon = "the_lightbulb" -// desc = "A cafe popular among moths and moffs. Once shut down for a week after the bartender used mothballs to protect her spare uniforms." - -// /datum/barsign/thegoose -// name = "The Goose" -// icon = "thegoose" -// desc = "A nice place to hang loose and relax, while enjoying some electrifying drinks." - -// /datum/barsign/tearoom -// name = "Little Treats Tea Room" -// icon = "little_treats" -// desc = "A delightfully relaxing tearoom for all the fancy lads in the cosmos." - -// /datum/barsign/le_cafe_silencieux -// name = "Le Café Silencieux" -// icon = "le_cafe_silencieux" -// desc = "..." - -// /datum/barsign/maltroach -// name = "Maltroach" -// icon = "maltroach" -// desc = "Mothroaches politely greet you into the bar, or are they greeting eachother?" - -// /datum/barsign/rock_bottom -// name = "Rock Bottom" -// icon = "rock-bottom" -// desc = "When it feels like you're stuck in a pit, might as well have a drink." - -// /datum/barsign/assembly_line -// name = "The Assembly Line" -// icon = "the-assembly-line" -// desc = "Where every drink is masterfully crafted with industrial efficiency!" - -// /datum/barsign/bargonia -// name = "Bargonia" -// icon = "bargonia" -// desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!" - -// /datum/barsign/hiddensigns -// hidden = TRUE - -// //Hidden signs list below this point - - - -// /datum/barsign/hiddensigns/empbarsign -// name = null -// icon = "empbarsign" -// desc = "Something has gone very wrong." -// rename_area = FALSE - -// /datum/barsign/hiddensigns/syndibarsign -// name = "Syndi Cat" -// icon = "syndibarsign" -// desc = "Syndicate or die." - -// /datum/barsign/hiddensigns/signoff -// name = null -// icon = "empty" -// desc = "This sign doesn't seem to be on." -// rename_area = FALSE diff --git a/yogstation.dme b/yogstation.dme index 4d43645ddaf0..fdc92c96e4ba 100644 --- a/yogstation.dme +++ b/yogstation.dme @@ -1418,7 +1418,6 @@ #include "code\game\objects\items\two_handed\spears.dm" #include "code\game\objects\structures\aliens.dm" #include "code\game\objects\structures\artstuff.dm" -#include "code\game\objects\structures\barsigns.dm" #include "code\game\objects\structures\bedsheet_bin.dm" #include "code\game\objects\structures\catwalk.dm" #include "code\game\objects\structures\crateshelf.dm" From 37f2c3dc804edc9eeec1e3526ce7dc29ea3ee6df Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:18:05 -0500 Subject: [PATCH 116/144] not sure who changed that oh well --- code/__DEFINES/directional.dm | 12 ------------ code/datums/chatmessage.dm | 5 ----- code/game/machinery/computer/_computer.dm | 2 +- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/code/__DEFINES/directional.dm b/code/__DEFINES/directional.dm index 83d8ce01d0a8..bfde544b4471 100644 --- a/code/__DEFINES/directional.dm +++ b/code/__DEFINES/directional.dm @@ -13,18 +13,6 @@ /// West direction as a string "[8]" #define TEXT_WEST "[WEST]" -//dir macros -///Returns true if the dir is diagonal, false otherwise -#define ISDIAGONALDIR(d) (d&(d-1)) -///True if the dir is north or south, false therwise -#define NSCOMPONENT(d) (d&(NORTH|SOUTH)) -///True if the dir is east/west, false otherwise -#define EWCOMPONENT(d) (d&(EAST|WEST)) -///Flips the dir for north/south directions -#define NSDIRFLIP(d) (d^(NORTH|SOUTH)) -///Flips the dir for east/west directions -#define EWDIRFLIP(d) (d^(EAST|WEST)) - /// Inverse direction, taking into account UP|DOWN if necessary. #define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) diff --git a/code/datums/chatmessage.dm b/code/datums/chatmessage.dm index dc30f4bfb7f4..e985de6c63dc 100644 --- a/code/datums/chatmessage.dm +++ b/code/datums/chatmessage.dm @@ -26,11 +26,6 @@ /// The number of z-layer 'slices' usable by the chat message layering #define CHAT_LAYER_MAX_Z (CHAT_LAYER_MAX - CHAT_LAYER) / CHAT_LAYER_Z_STEP -///Base layer of chat elements -#define CHAT_LAYER 1 -///Highest possible layer of chat elements -#define CHAT_LAYER_MAX 2 - /** * # Chat Message Overlay * diff --git a/code/game/machinery/computer/_computer.dm b/code/game/machinery/computer/_computer.dm index 74ef4595c574..a52037615b75 100644 --- a/code/game/machinery/computer/_computer.dm +++ b/code/game/machinery/computer/_computer.dm @@ -96,7 +96,7 @@ if(stat & BROKEN) overlay_state = "[icon_state]_broken" . += mutable_appearance(icon, overlay_state) - . += mutable_appearance(icon, overlay_state, layer, EMISSIVE_PLANE) + . += emissive_appearance(icon, icon_screen, src) /obj/machinery/computer/power_change() . = ..() From 2347a80b64ee510a9e4ab989fe4a186cb894209a Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:21:54 -0500 Subject: [PATCH 117/144] yeah this got moved --- code/__HELPERS/unsorted.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 6dee2a345fba..93e35e863139 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -41,9 +41,6 @@ else if(x<0) .+=360 -//Better performant than an artisanal proc and more reliable than Turn(). From TGMC. -#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) ) - //Returns location. Returns null if no location was found. /proc/get_teleport_loc(turf/location,mob/target,distance = 1, density = FALSE, errorx = 0, errory = 0, eoffsetx = 0, eoffsety = 0) /* From 5e9ed26c8250c1e6fa50e633d2e691ec2a11af16 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:45:50 -0500 Subject: [PATCH 118/144] this needs updating yeah --- code/game/machinery/mindmachine.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/mindmachine.dm b/code/game/machinery/mindmachine.dm index 80ccfd1f7ba6..b1b578674af1 100644 --- a/code/game/machinery/mindmachine.dm +++ b/code/game/machinery/mindmachine.dm @@ -105,7 +105,7 @@ if(stat & BROKEN) overlay_state = "[icon_state]_broken" . += mutable_appearance(icon, overlay_state) - . += mutable_appearance(icon, overlay_state, layer, EMISSIVE_PLANE) + . += emissive_appearance(icon, icon_screen, src) /obj/machinery/mindmachine_hub/RefreshParts() // 2 matter bins. Reduce failure chance by 5 per tier. Results in 30 (tier 1) to 0 (tier 4). From e7a726b27aa6bdf8472a780d323dea5b3806df62 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Tue, 5 Dec 2023 23:56:46 -0500 Subject: [PATCH 119/144] turns off the carbon monoxide alarm duh --- code/datums/mutable_appearance.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/datums/mutable_appearance.dm b/code/datums/mutable_appearance.dm index c066b96cea41..aa69c510d8d0 100644 --- a/code/datums/mutable_appearance.dm +++ b/code/datums/mutable_appearance.dm @@ -40,9 +40,9 @@ else if(!isnull(offset_const)) SET_PLANE_W_SCALAR(appearance, plane, offset_const) // otherwise if you're setting plane you better have the guts to back it up - else - stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") - else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) - stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") + // else + // stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps") + // else if(!isnull(offset_spokesman) && !isatom(offset_spokesman)) + // stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes") return appearance From ca752c2a8cbaa7733d9bf93b95a06f83c2c0a1bb Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 6 Dec 2023 00:26:02 -0500 Subject: [PATCH 120/144] FIXES IT YES thank you biome --- code/modules/lighting/lighting_object.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm index 49b3ec20e454..b51ec1c2a299 100644 --- a/code/modules/lighting/lighting_object.dm +++ b/code/modules/lighting/lighting_object.dm @@ -15,7 +15,7 @@ return . = ..() - current_underlay = mutable_appearance(LIGHTING_ICON, "atransparent", source.z, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) + current_underlay = mutable_appearance(LIGHTING_ICON, "atransparent", source.z, source, LIGHTING_PLANE, 255, RESET_COLOR | RESET_ALPHA | RESET_TRANSFORM) affected_turf = source if (affected_turf.lighting_object) From 0f556560e0251d3630aaa1ec21baba8503ae02ba Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 6 Dec 2023 00:36:07 -0500 Subject: [PATCH 121/144] turns this off too yeah --- code/__HELPERS/lighting.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index 5e5924abc8d2..206d0b7058f0 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -7,8 +7,8 @@ var/alpha_ratio = alpha/255 appearance.color = _EMISSIVE_COLOR(alpha_ratio) - if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace - stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") + // if(icon_state && !icon_exists(icon, icon_state, scream = FALSE)) //Scream set to False so we can have a custom stack_trace + // stack_trace("An emissive appearance was added with non-existant icon_state \"[icon_state]\" in [icon]!") return appearance From ee2d847dc4579d318e7803606728912e7e69dc08 Mon Sep 17 00:00:00 2001 From: cowbot92 <75333826+cowbot92@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:21:34 -0500 Subject: [PATCH 122/144] more barsigns for later --- code/game/machinery/barsigns.dm | 18 ++++++++++++++++++ icons/obj/barsigns.dmi | Bin 210663 -> 268262 bytes 2 files changed, 18 insertions(+) diff --git a/code/game/machinery/barsigns.dm b/code/game/machinery/barsigns.dm index b3172c518943..53edc780a79c 100644 --- a/code/game/machinery/barsigns.dm +++ b/code/game/machinery/barsigns.dm @@ -427,6 +427,24 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/barsign, 32) desc = "The warehouse yearns for a higher calling... so Supply has declared BARGONIA!" neon_color = COLOR_WHITE +/datum/barsign/cult_cove + name = "Cult Cove" + icon_state = "cult-cove" + desc = "Nar'Sie's favourite retreat" + neon_color = COLOR_RED + +/datum/barsign/neon_flamingo + name = "Neon Flamingo" + icon_state = "neon-flamingo" + desc = "A bus for all but the flamboyantly challenged." + neon_color = COLOR_PINK + +/datum/barsign/slowdive + name = "Slowdive" + icon_state = "slowdive" + desc = "First stop out of hell, last stop before heaven." + neon_color = COLOR_RED + // Hidden signs list below this point /datum/barsign/hiddensigns diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi index 5b0e52673269849c0a11032032bbb0c997b15471..584395f14644a3fd50776ca3357f1c082e268229 100644 GIT binary patch literal 268262 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 literal 210663 zcma&N1ymbR*Y_JBK(In^DDEx=ic5gt#i3Zy;x47QySoN=N+}d5P@uRKmliMXUR-n2 z=l$OMefM2=-E~)1)?{YRoS8G(NA~{jU$nZaJPsx~CIA4yQB;uC1OQN_5MKZY4RIvG z`1UOTfHLo+t>+2Bd>>*8VS>;wRK!N%TpCoJ;diTA#hJ^mo|EmZ5et8B4)QRV?_ zNHL%n zBHrn(>?JyB9ObF_mKxt}i25Du@?1zi7jx?!FQ1Qiq$pdI=*U*2#)FAoPn^Qt7>Usm zRd>AZIvqrYHKHvVV~C{`?e!0QV!b~%4)Idk+NUocPf|EmhoIZS*aI z(5IxoGR)1!m0r92kVd6F40RI7at37K_^#m7kW7|CI5qz{@}%Mgp)jOB77a6l(%{wc z*Xd&6p?e*+56m!jULq@BNhPKiHezC&A|3>KE~Zl66C#2SKDihTSomWvPk};xQWGV{ zm|A5$cgU};WPDC1=P4Im{%TB5EL-G_Xp^#IO^A^0Gp!NuyhsCVN(GM!*Ujvv&vnT7 z{UWpe;{dOjqW>y)D8}D+{1aaY2Mrrvp%6p)N9v8tpSxt~pF)=t+nGB6+_J0+QD2*z6pAqWkczjyfo|;@O8r<`6&Kv3*h`hfv zDmUCXwD`Kr1Pp~pM4m*FxIMR@coCc5-hvns|ysi52b@{yuS92CRqnmv= zzBk)w($aW_dF+qLKQdYD8Z0&8?BZlM$K+lV6yny>`{)xlVKRI+FTrv_qjwMQpRC?9 z)%3IJ3}&Y^anG)gv>J{z9CQ2{-~Xv4DUz&*jH<*1cs&QqzGyC%o|yBuyS7#$F3Z*F z@wx9c^M@bvh-0{js(eBVAuS2-Chc1%r;YMyF!G}Ko9pJqVoFaJl0<*mmvxJsMvS}S z`svlc)(ufNIO2}t7<~C4Ih3@d%5Ion@H^pvl;CwIpcSR;7ab(&;k_d1vuZfL=b3u_ ztAkghHHLEa{6c}g_)JF|Avt$OZiZ$A<6H7}FuA5U+ARj^f&Tp|CAy<0Gz|?KNA#mZ zX=UHnTprJ6^MkQLyy%xT<3>l>@*3`T1)J*4%cp+_OU>1?QE_DGjv3xNDFuDX*|ERe zym7yLJhZ$gK?VdEn>(TG0su4sMOlcp7wo9RJB{MX`{tplta*RoZ9G5yn2kKX0u37W zfJSI?rfC<}YoXx|;}h{HDb>*{@AUQ^5qX!ti|yaO4te7U-nQ4f`h~>f@CpS*)BZLc zH3y<$(Avw8A5SafbolywUVSS0vU@7bN2o9#UoW&TieTM zS-NBe2K@iMX~mmT?g0GneZ<*R>s|q(L-+WOOM|V?3r4Z;ualoUTaur-UqI!8l>U#4 zHJ|mQBj3&PJh)-fbQx*_TX~ZHQ?P(sA9?SoD2Zi7(<jG9m$3N&{p%zRGHcS|ImoRjvydvXk?4=XI7X>Xy*Y zcKV$rKd=<;PXEOHRDjh6=abAm!42>GOl>IGJHm#G_#LJNyzB8dgdRqIVgHq4m5z8y z9U*AfzYWD*=P4KB7?I$^DQ>uI##?7WLeYI&M@i>F3jimgtFXMXfcT8EGj)#KOIM;7hyOGT#d)up@DYZ`>w zIuOXPkzh7HDG0l_J=!kcCh3x3BSjKOl zeAE)*tv@b%-`&f%UUdmtXJevze8X9^kwyNUEf&IR`1fJlX9-2srf>E?h(Jn>iX{C+H>w12gUvLWzz8E znCRxcbQ9j=))k}P*b#xxfyUgkWkKG`hqM@!6|Owmmil-NA3Vn4{{&VgdQ0JbZt4U6EKfTz#iQ5ttN`fCgz1&9KQFn~%&)fNgev(}l zo)%?^yG_0NTUhjvh3JOL^RzhtFMxTlSEIEAi~6|6tW#)MKZ2A=6+f8BumqV(`^Qr2 z*puJIhuQ^hAj8>OSvGxfB9ALJw)Wr)SF|hI7+2-Ne&aC-5z*X zNIpvlLo+UX&08H*cz%-yU-OA?b?6M2zg1W-3J#|r+9jn^$`V4JoUD}HbQXnI9JZ2# zJXKHHm?L3+pdjeL#y1ONV7+2O1?cDY`2{-MeBgB_N&vcEE7>_oKP)OoGzA3sm z9)E;L41W%M#crR6P022LD{n}c$>;zux|w&^zQUet`1q1`O|0&?e)kA$g0NTB{B~hk z8)vm~-?WA&VyCHhPKVEnzw29nfBJEk(LTpz{oh?oEfa2u`N)AUynrIr|CmrbG3787 zQ)Mw|btIvGbPzmZG~RUo@ha|0|Jdl__(H=Pm9|uTa1n^ ze2Mnka=alS58R|%uq0-^Dtp40EI=Ilj)g;BM~vfXaY$Zc=y`?yoOaJ9>jGfxuc0=Gu z27Po1F+!2TBLOco;}cQ&37{5XHosRP0BWRm=(~?xx71Q3#yjq;&QbpDBf=i{7@ENa z$E>vv0`dt!JBP_hyFE+bnFi}xf9?2DG4YmY!Q=R}A zNLLWq4I_1g-Ki_rFflyC*1uB2s^u%JjE_Y?~ye%8`ZSQ0}D&})3Bo0 z2~*oi`B+2pW;Ds;+22O<{fWag zPbS9yMpU&5co`rEWsLES$cH0R17F_^JliJsvF0e)(J(0GdQ;lorR}XmjlCh=Ua1Ra zqGwHj@@3;<>(0{d)8*N%eap&Hz?TB5ai_L-tF0#mR8+Z#gbvnG>YN_9Ez~k6^(Vp0 zyTsqsTI|Uw7%w zfbB#adv*1I%R%Jf@7UN!|F%8v)AhzZo9IMnbP``zha``qYippc3Cl{vFtky1hj!w5 zQs^aa1ZzDe}3qkYoLjfgO_39!^hwC z1j@3mqTH)3dB{Zh6?wgLe`I$*P3$;KyuM=-Q)8Zn+m^!1;N049Wh8#|j7hz?y*;tP zXsxqGppqbXmbH}Ft}VJo73|TIT`M+rQ3f@i#2Wokd84M|)^$)!S}xg8SsaP(nu$9~_`_F5c>atM<6%k1H(RM2KN zW8pDXKo&T>ZG7#z+f;4{9Fwo2mu~*BLoAtRZe8071(UDpbg=m+9_XaD{2{!1*1i3^ zBj&jTTs(EAe3?7m7|^^&8oS_iMu42*jye&06NE&Fj16WSW?@}I`GQ%F{aP-qFYWY{ zn9_!K6C5l}tHA6WL(i`s8Zyp%f4)|f=Xp?B5&|$5L)a9P3iU48`y_A=_A9Y%#wOxh5QnQk7df<4z_we813puNNu&(WhQE z5n*Ng$8-6hR=U=5{Oz~c|JDZ6aFTq)SR{h6Tr8gVZys-D;NuZ{@0D0dCqr>BZP zWY^bw+%MzS>H0jVfQn{ly$o2dW*GCoNBgw)jaS7K+yN(O2T9U?aT!M8h>K-tc7C4m zPq;8>-Pvjo-4&5h5$62ULq)myzI+BbJSg0#TWiBHgx@6}X(J94!=qRh_F0h^L21`e2$r7+h8{DOg#~nYb2|R^my1#=oQjF87$j5TJ(lndA< z12YD}y4Y?-dxGX2H4U4`bvWg(aDZKOQ1A1isbmr8AbtM1>VGi~&MWyuugrK+l$v za`R1FS$?3u@3%=?5|;lIX~g<;{q`^?HR^f!xu3ho-gk{$OT*i7B5Myrzo()<1LM(m z6Lv@_`PoKInLlsus^VvcT7c{5bKYs$gQxJ3N&36j%Q4p+XuC#jw-^f{HgjEcJWEa< zQxh)^$~hVTD7iN`AJ1#8=efIG2`A>wxs?A_dp#B)QcTGSnd*rtZ>%fkITgot82@pa zDQI0_jTmNIJ~&`xn0(7~F1Xnq+dQ=&DHD98fNLdSWf^Gp-d6vN{WP4Egv}q%6U2>b!7$v`3#iTA8D2#KGKU=A*^&7=CGf5 zgHuzsMc{ZsJnJ+hj|-u3kn4d0URerTj_rGaOt%z&zHbBBkB@I-(L7^75-FrWVY`@u zjJ01wRcRi19d>VF)0zvl=?Y@bqy~ zAqYUuCgG=@4Ig7@pbgM%fFbNL7~qeMtfbrc>B=Bdl}N|yytpWt0TMP8SL^(`Zvu?u z+mFF_ARry0&9u>goX+U+H3>1wkNJUxezN$(tOeUDK5%BxY>1%=<$KX8FV`g^=^y)T z4ia$3`6_%&JUbY|haCB$8q^$DZcil$mUG&VvU&>j$CwYqkZ}{YfnLpkgJ}?f0q!Ts zxhI5W+A_TL`OZhV!sTZ$sB?TQOs^c<&E=um3ex0lA(HsnEWf)eG80%cG-*V)_uiGj zl9@HY>U=T3-hyOmMpZY=I@tSeXTD#pd2UqfqA9nYrWtQ0Zsi#&?p?7+FNQTXA~?tu z@V!IYM@_?;?a`yWuk9Eq$2s3$wVrNA<&@Db@jDE!hhUDF0gtz5>jLnXR$1alw6B8sT`CGKo!g?{>1wZeV4B6KD@5sz zyF{=^;P1$M!3`(kC`yIaSW;52k&Ea{GwNt-hDSsML$Y|7g$FPaG?Y1~Fro^#*8;zQ zT%=0R%qC+8SY(#_2CIrvbPe=|F?HQpFKnOyj18}I3!2I@vPvlkUP*H^KrVWkZ0h_@$MQ!NeGJ2#NrQIrxfyjX4NcvbuHGBm`I?+)sm|O{fn- z``HTzd_QY2l&zGSj8zJwML3d$(MmZseTkW69JH!wKwdv>4H=wYR(>ubN-pN$wQY0B z(i>mwSf+8ed=OQNtYVUR60LR(NH5&e4r8q%oY<~%?C~Wjqf*#e*onUCbp^d-+ilsc zxT0U5$^$3TGQNaiRcSJsfsGZBJpd90(kNzNYC%;JUcjAX<658F0AP6F_eJMw6gcvK z4O8VZV^rQN4Yx96@S`C>75~XXuXT$*$*LLTo0i#s-iNiYU-Ru7qmQ0+v=-2n0Q%QV zEx9R{hWPinGj(7LTPEnMxeEa!Q!c(eiTKf!rPC%sH*1KV-eBP7w`Sese;$Kq@^it` zb0)G45=s~w`{_8-8r;!=%CwPSG?u1J9 zSEny;?@<~AUK2iljfsTcS5*-v>L-K{-oNxKk*8-tca%vlyvK0mO-XL5-+}H z3Z1L$r>3#K@H$g}!}->YlCvg)4t3J)ypu_+o&LV6w-=)*g#j8TB%&^Z%C6s|nK7e4 zfP@UJ1U9Vc#4w0ZX=`1oq?i|{Pbxp(kxVipGmtUK5tU$D^-b7`HS#8cWMKe9%RV}_5sZXVn=mCohW4zjIir_KAE5+CX%=E7Gnu>5HWMEY( zJ`quHa4?N3%&vO3^a=2(HD<8?g_w4-X&P|2rgFjx*@-d4?$n}0ROa8#JMXrqF7Z1oq_dS~`E{GH>sCtL>{ zlof}Ct3fX7@_KoP2*)0)qPySA(!1^24++^+YE1qT+Gkv4MWppJ*}9S>EKJe_4k7QU zf)RVT{qn&EdK=b7d((bG)RQ%lQoAyS_5K8{nFKm}m!RMRyL+T(X{DH}hTQuhEul+fCwM}v61%twr z9187g7kWWA;kR{RzesNv26KXaX;WCeG@t^G9OeRbgG2h66WQTMTIFesv!*IB5bY^WIIA|Ig~eEv3gpqi0FqI zRSB##$1_4mE`*T0E=#v|3v(wsB$7mud7rk&MeY_a2%VdaEg)oeMp_^qbxxb>8C|b$ zTWnBtv?Nc4g4r^rK!ULP97XYW-N5ppc1ezbCPP(e1}5LOZyH#2Qii)CsAttKJ@pB2 z)p-8WH4JUXH3i{gMf1fdi5y(GWz>iD^G^n$<6`NLG8+BVNSIWkE|FDGrFrUHKDvpf zfzx_wLQ$;uM;!bC`%x3|4qIqWri`BesFXOk#+szSQE%i>v>YMLK4QFWD@o*WP#yyk z{!XSTkxk7Ge(gFN*QVxgS28U9A(j$S(%W-_QvA@%2vRnBZH+OcYvPV?=5?|O{mV)F z?k8A#5li`j;~*aUs_QeuD49=0FZD7LzVq*TIv!9jjm!}89v^4gC3Z>OQ?QfI zN;oCr;fO9aK#Ihrj$5FfA_#L4Z|;y~4)v#=h%WCkOrPcaixK_XIQLq3Tw*uB_-=aR zc>m(A4y(iy@{2Vf!26=_2B}HDL*;dz^Y?LhXId`lI!HsVB~00-EF9t5&?yk$_@yA` zD{z#1R7d;x=|V5QOb&uL zYs@7?vi9LJF!Tt_KW(rhc;nYNQh`!Z)1Y9E^M*W;XINWHToeCv94<8yoBA1n1qY@W zUE&py8$JME`rB=Aw1?_>O6s(4UyV)^4bj%357HkOiV0&r4$Bn*bcUT zUo-)u93#Yl84n3(|6ruTJInh~jNU_!^%Ei_O#d_@zudrUzba|Zm6ZME)Jy2y_5$yq z-O}#TV64AFb4=;{(x$`r)}h#ip(e?K4oQbfMM?ibqcWM6~Ib<@`gTIlbB+PD4@E+21}-(4}p9 zee2 z(Xy=4E>%JJ&h}w$)#XRu?+@CTbggAwhQ-D2jwn7RQY2@NOZW=h4wtv@R!cdPNOpF9 z;3x~E6Vie+iBx1=xSK)y_j=TfY9NK1(4q`GwzFa+WxYPiN=RWJwwoAZjyT;{6mC+%uf?FEr&JdM)Wo} z(9U*E(mRfTf3e8GVP%m|AfO`$rxGB1`T-t! z@b)f$>St4!SE!)I6pzBI0+EdREYwC#2xH{Da*PnwBmdVF9}xxSXLMe51uzQGY#e{b zXv&_Y2`*W}RU*w{Ri!sVJ#YQfcpr`)q`Fg|!H$?>KJdGc&EXfO^JsL*gbDGckb<=R zyw0YFeF|F~a@^{uO>@ujUt$!kL*$ulb-mxJw}fohm=odf|CM)Oz__(Bk7Cdu^r)UZ zE6QqH(_LrO4+9t+-COrQ2l5ziSvbh@mXL9Bnb9`8zkE9l6=)i@Mk?t$pBk#nMsW$z zYVXfQ#3ayTZA)%mXN2g& zD$8lH@?=n`nLwrsXDm}=#{0MTnV7rA0oil4Z8Ortp9-YW6F$aw4(z{`M1A+sy4F%H zzDbst)R(l`q!(Y0p$u{l-;le9_sC%u5_CCoj}PlQe|$wbm!)y^Yw6gp*8QMo(*u;r zNGNF?GD=l4U#wEW<6K@(Lisge1rtn^V@(;EPdx$;+<$RnkK}Nt$Rb{Vhr2u_zP%ye z0IiKuZ;qNaufKkR?d2Dwn$g+rJ8i{)n%;&t*U9_tC>4D)OeDe)K@1{f9p+83igP1Z zYl7L8IZBHQYSb9`9+QwX9#%HJF~;Tb<2~($$hkY=2_A)z0J@_s@dS5rZXyuBc^}#P zAf|&Bm;iKTj;zBPQH%39qu(3;YV`_K$=zrkX#h97z5>;+@Bf_(Fo19*$ZPwRgGjs* zE?~?F-4B;8N&dhp3tIci5~ARrEN13$ZaJat16VcXSTT4~2-oRLY{#tDpe@=hM**!; z7S;V(i93cp2yYAED>UIfJ~N?NOQ#_Is}Z4J&_D&y-Z1F(@%U3%aDO?Iui-?Dz-OII zQV}=uugXe{a8Avfg@KF@N^a|*Z9lnz# z8Iqsfa3qakF4wrk$$rCjOU&&3y@|^|kt3BQ`Bz5DIG=BAtg=|pj8$E+iKyx0@R*f8 zw@Oyi*qvY-Jzt~H5Ptic$Uoi1dyiL{9U>W9SrV%1w4nv8Dvuz(k52BBp$HA=d1Qvi zWYWCh=nBmw-kB1~JVO6t$}GV~YCgNXfxM&D%eg%I%SeX)&CWGCkyqu0q<65^2z3>!xLD@z(?6RhD8d|2k}Wkz~6c z&9N}U9v;$_!~UrJFG+cIJbWvVHApr2D+!l1a@)KO<&xIs%6-lAh{)H$&p(VVVmeMx z!`{s{HXkEbxF`I2s|5D=UMKs;`XN~KyZd(;``t=Vd8 zCE4%VM;pY{@Tnt(e;&5?lmBkWVn?C|_w*^^G5<8azMyXJD{ygyJY49&J+HT4vVU8B zL%PK51HO&s86wYU2ZfVXTJkNa-vg83&0x; z7&G!Aq&e9fM*Y&iHMJ%^S#aTk(;?k7og1C%lj;i7DgvKJWl-<;pfZ+Jc^+Sp!j*~{ z6pG#Q31AkuG89t1%BUArmP8^VSTS{o+oER;YI@e?&UyC|K5JI8RF=j*dDMm7HS!f$ z%ATk6#D?^w`bE+o(T~zplkuXvlIyEQiN@d~`c41<60~x}6ek6xm!oTd+rD%RYe`1S znZm%6qYWN#_NJ0-dQ5|l0YX_WbHIfVVEUulv-$Y^DG?IYt}D=(CSxB?N^L=TSXmKl za4>aF0Ns4s-ZkL`1DnGvlLGG56#*Dh{U<h7#B8((9srBxgx9a(LXzdZR=&78tQp zlX^p%<8C>Qk66sYYSi@Y!)@4LbibYFPE7wtBuJX?tpe@EJ6B>x*OQCg4$gGd4^7dO zPVRs6ESxiQK^uhPFyG5o9Y@dH)Kl27Za_ZHKY{320d7Ky@UZsy&D2bqWi^^TynXvB zKfs)g>*w-5z4Bo8+Ist+rdd z5$DH{-|(r`@1OQ-I$U`RBK`V);}BDD-6NMoEaAS=nPo0_{qySjVtGgZhRnx{Bgf+_ zG*L;h7JaDTWn@c!;!H1C3eO_VDhJ`P>yP523H3PN;^4g(^c5Q7b=o54x7%9>h_{dP zx=%==Ru*OJ7`^`VjVLsine1 zK~U{4X71fU&4Mm=>rvpeP?wh22=Q}{84yD=dvAic`i@8NYsfFJa}p|#o5HmmT28;GNR=~Ksm^^m+ z(~-O-Adj@Lu-KF)O3f52YJslc2?g6t;BBfjGc<-NCrgd}T@5o7vD}~?2f=fx`J}>1 zU{>7nHWox7z(McSfN?zLr$T!|ec&XHZxOz4lhs3gIAcIx!Q`v-68F4Ru=ro?I4*P; zRQWFkwbN7UIIH#4NCIN>lk{NVRxMBe6A&)#JI`9qLucwAPia9d|qlRk2FI-PTLq36`BG18x5 z*_k!vv6Y{nVT9s4RQU+$5P7E_wk<`p@+jKdC#*yrxCVIH8ZH#@XY+&cwym}{;SQ1j z%Pm=X0g^FLLc^dphDHIagMu*{g2l;E7*E8p>;J+n!<|9VEv$rM9q*lA92&7}2w(dM zx6njxWu*;&>L1Q?4wTEuL0W?rVm%G>!@u-E3UG(4dK3Y@TpR=qG$|z>udUf@{D)CG zPRB?M=W|%JdqP8dkH44tSy2hTY|#sK1=qOV$Eep%$hGWE(Wq60DbyF-jWZ5E9*U6D zMXE9QR8Vk$pvh6Ukj7U^F~GXeK)T_Vw;Jb#MKhS%fC@!?rk_~qR>+kvsn$2mp7V9d zUlqqQZV5~)&~w(TY5L6)$kQT;P2dX4bBCaKX`D|-{3K$DGk3`$^i{WRe?GiC*SBOu z4_8I`a5)njY!=gn`PPLov;L2YV=Y~9W-4q=I6y9r5HnH*Zf~<3B8?J4&)`)*Yeh6> zJ!{DjryFv+&&Qt2-esqoQ}u`yg;#{=qEUn1$tDQl*tb1e4l|EIL|MJ%MI{;R|~;AmG((L;eTZ=&upKg1TqKCKSir;$|o|gg)(U5TXlpu~&}DY@*Rb zNn>}PD}G^q3!K-k2c~;y&tDq3GYt`~2vE*(Hi0z%qoR72!nv^#TD?cgR?Gm$j@ThA zB{oZ|n@fqfhgIERcOHvG7&>LnVmU>BA+WWFwM}~ZZ47H$h)coJM$iy?9J0_`>E_RQ*?VYR3B=R&(_cbmon5 z(<)WEeq~a!VT|98>N6*u?PG9$w!iqh=Y{$LzVT&k_R2mao6_LJTbg)& zo-S~LJB$VGv@X|vAxMr$etzPUSbRuGj~oz3iYP<_cv{lX*eFLdtjHUN&dpnlkh$n_ z_@{>;*Qs>SFtDm?gmO!am56Y!@QX9i@e3vqfxQ}tCD9sWGI9;b>Lb+qsq1su>n}9c z7+Q+rn3!e}=cbdRO89+3!@OD`Ls{uL#9RDP%0D*}k~J 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%0AdSKB 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�)3B&)+j1wXF<+1+7S(x5 zwD2p+{zjh8eouPxU-eYN$YqnS$$BS_#Y5-njG>RdVwk;CuigC+T#3KGJI`1J znQ<>~1{cmz1x=u?0&?&;csK56!CEg4dAGi(j@5k?nd4IJCvHRh5IIe7zFh-ZPIgVY zNE?n#C1XaCUyhE~=XU*2ie^r}{H)TrS_~+1%d+nTZ$1QuUoWT>Sg}hS4t|}ALpMAh z*Iq)Weyy35{>1R6prz6)oNai_jN4peM;1Gnzt%em6^l^vzhpJS-o_HqH_X@CbRRY_ z+b`TLSWU=Sc$?!UIOuVSQvR~$ZO>k5)8f%M2@S+YY+S$o0oH4N^8O0B0MPI#q&N^$ zdX!Or4!ZzPp{}EpqgT3b@lb1hpG94a4vxstkShh`-`fAhe{fl|%6aroqCm`{>e}Uy z1;P(*iqKC9Jp6MoI>p+3O-0a9PBfTSu~fjiVn{)2zbXo-gq83#jXxE!6IE$56~k67 z4!NleCJYZXt$5-zf>8#0lfKwS{52Rm{)DxVo4Eu|Sntk!h>Q>O#*#3eRJ3)${|${d z+7`HH-lzw>L|i(Q#vg@~_LPAC8aMr+-qMbz3(aZ&jf)E(lcg2?|Er}OBJdlh{_ihF z?L;Z09T_^*ejomLGb-+|-A9;!Pf(2F)CdcRB6ZupM9{*GDg2$y4yOkUJK#3`4Yv_; z&sZq@E5mp*47u2Q$y7uDnpI?Ep#3LX{*QVel66~cyxVYrkXp%j(blhI+Pe~w({v5K_*Fb*Eh*2(@aI9TK` zalya@T?GsON{z(U%(2NoF;NE>+zj~N{#}Cv;623h%y2`-e*leiJBs3=p~g*uGrB!w z_`73e;mhLtr@Bb^rtdZ;aP8tP0*SD5D*F7-gd^Mgc6aJ6;B!XY)qp>o`?pO0@b3m5 zyLf5y|0AxG$H`T^E>)P#jr3y5N^^!*`|@AbG$LLPDjeZTD@EV#z=#^U2cIqSu2ued zxNyv&%s{azjm9#<^9zsE1GLGU0u65+#@7i`Wo>=@D?6S>Gvg3aHs`EEIx$%9tE)(f z@8BaqbCu&t3w+fkDTOx%mJwm_X7W4F1y#I0Z%pBwFf`N0;_>5LaUB?ujJvnyauf(>;wf@Qi`f_b9s?cd>bJqGN!NJBC1#>!@kyP3N%OEUI-oS@N)_<(?)43)w zx;Dv=1QQsp?md{V<$2XlN0Z-`Q|jd26{zTZBxvLN+0~vtUL(w` zC5JuVb-V7?aWY3H3#cEyDJTgRG4~Dm`SuO(=8UjSC#TXJ_*IdjGdFA=iMB6fsa_AedK>HPg*98$8mIAA|Zff&v7GE|McK3 zjt|Xr*GEmOikGalMzO;tH%C!t=?gEtbz&o>-jhqGJE{Nt$XX?45GV!4*EqgbQ8~#~ zb)boo*CNwYDRJ+hgqGgdsHW?z3rXRqEvwO|>Uon@LoK)ghHRyPM}z)V^Hq+%Dc`$# zeM3vTaH0ji6mXqD7~G|#7B4{v*y3*+TAy8fW@PaBf>gr^3}9bW9k!bTQ#>MR@bNi9s#=kmImD9)tqgPpL_E2P^={ysO7>%$e>R_qLD)*>133^qD87 z3~&@C(|x7tFAB))UAB_=Wk=Sf@{p@0K}~pLuu`CI1rUetpI_u-G0@Ob?9p~9&U_)- zYQ6}EO);WW_z0FCxr#JsxU0E}j5e;sX!e;t^9vT`I5lvQe(_nb9rEi^bv!>8&~B$S-G_5ZY!_46mj>VZ-3>;G&BN2~Bx047btfMoa8DR|RQI3em6bZ+ACNUldIYvTcg zPH(;v)PZt&i{7_*HbV-E_-kYzT8TnLhcY79I=sOano@xA&xm>i-(ae%ZU%(n2i~F$ zYW23~CU8!IO^LZx({Kg1>Ann`diUF|;X^{5pI9B=dk!P5RFAuE2OuIW0Y3=^%$}!u zQmsPEiuI>A))fe+BReG&89gVVI%3H-PXM7lM;!RIRDbnqsFVqG;rP-AE!89fggjoPJIkLZt7kGOA67fyM6I#LRqJG4H6 zuV8c1;s|g?C`HM{{8J0S&ffyJl{R>aK9PA~jzbe!ZJk8KM{-mhLczXEsIjUTc;7z)0Tdb3cIE#(ed zAaS;}Av=kWOpXgpqn1A+i!JJEdT$6F-Q`;$fP^M^(9|Xzpco!OcH@|}HRSjjQsI*o zWOI1ZaEs1td`Ozohzq>O5USn9g$g2)XgP9>XOZ;q2t~p(+_21Tn857F+Tvz(LI~_v za4qw+%XNCm1a^5`%at=KMMQhUV9^cMbKP|rOpZvIc^X-A#?el))>QKU zbG>hdz=DrIr;H^YAnCETk%K2SO*Hg`XI-WQwc(xysm5@WjmQ4;$=t@V$${RKoja!! zI(mz|GH!UHT8rkzb&_nT@Hq&B|uLF?A~NC%^)Zg z7u_Uf={?}9rRU!3`Se?yxeM2G)@nOA)3O|)bd%|j=jgXnprx|EY?%21H6d!3c%qBZ z&@c5yP$<%IGmAm|Fk$8AvN+Ri@+e4C!o}%DV#JH}|3}t)z%|i*`NN?Jf)W%df)qtS zM2gaDKtu!)P!yCF5fP;K4xuBWpwcW<5s`-yiu4kiAfQy~CG^lkO#(?~{)5l{cHeh5 z`J^!1OeW`kPe1oujtY762$fyAh6vH5m>#nYdaF=7l_@}a9f`BbaQ=^Ob^Uy2BNNIf z?+b9N)2OJBZMKh0NL?vd&F>ccviV#LbRS=2QxhX zemnpBel=vpe)Kw>r2O-zcR-z?pIUr~^HM=a-hll4*Op5Yh*7%x=}iGXmB+~aH7K9q zv-F$4xmu=Fj^W-(a{bB;_GS$cgTE2&-yc}c_#S{3F}D8gC?IS5{1c1s6SvN#^!97o zyWC&eK{ z8lv=4gY|-;Kb|8hSETF@ed@--)@LuR`SupOfqrl0`j0bvN=oY5lMhc6P$SedOdY5B zq3BZek1s= zY=c&ESjoFA>R92(s-KW~;r`00q5oEw%+5|=8?aFfs!OYxT%R}PQ~0kE9VC_YHB^m) zN_IDH-Wz3kjr5+pFRdo8^>;}0Z^#5Q^44hm>y3BFXcC!~RLr+vSJkvP`PQy5%&#Md zeA%wk>}i^eWu@eZxx%LgTa(0UXzk$ABgadEXD>r;KA+{fPo#o-Ugeo2Pd26w;DJHN zOKL9E)?&gDtgJ#gSD_}>FyW3L(w!e6@4o*WnyUIepX-6jIhVCB=OBtXki4Sa$rpClG!^ zLd=)Xs_p2{u6x!=8@(B@qSJRK*X~H$|Mj(_g!Jvz!+kWN^pxxnls|hAQMrrey($_K zf3##9Dkb~-1a9pn%t|v;Y@kQYxnm+4AQMur_?PsN9|rl_|9Q&kp_YFtlm;)i%_C1R?HdF5mUB#J5NFLFPw8b!#93ON4Ia9e^>Q+ih_Y*eoz9PC0($ zc~wYyANienM}0eoYX8v8Vwy0n|F@ec)6L^H-s1ne$0!rMt>*u2Q%YOqO5UIho4XbT zcan;#raxjEH>$)(Z0?h~Py78Zx4kL!quZz84aJo7N_s|kV`O|i&(_Rs5-A;%`Mc5QoB(E*SU&PBVWtL`(ecQxp>qwN8-ZBP%^w)pB}JeH zJIzPtlM%q<75)zg^BAQj&=BhxU}y?U-U0`SY3fa2UL%pl6@bD8ysq`7KB>c(w?6a+ zMW=~z0vk(Mf^q172L+-KV*e+YFe||0`#ZU#WW8zSeI02K7HXRp%oQ|Ugu}=O(vLLY$0^|~Jsp85S6X6RYgu7it1?nECsWg6Of&tnr7VR5TZM5n zF!f-tm9#c5>OMs-{%xq@EauX%KWsHl1jp>kG7qO2J@gX5Q+lsr_wgb8-5DXC$i_7+ z)p8QGpY!*tu))MB1AzI^(qo_7c{d7B&A`VaXI3TtTEeds7u4 z&C?}5KJvEl4>9VP!ztII+qrt%Brc57)@g`kFuy67ee;B+R0~zo1%7SS-3_j-!OYQ% z6uIx|M{)oH<52|TZ)gN8(Sez(G@# zudq!#`qi@(bE^Z3RI2Q>Tc>|RY!hU0wmk1Pnc1wv_qZGq6_yNv;kB$ik^tfWie@!q zJY9@KHiE%QDQxc)1?x5|k!RWt5}YyVQ28r9d|)0g%D+E%)SDs5U)Y>UmhierxTp_1wx{0?&y+;A{wSe${ZNa4&Lz7XXPos zv1!VJ>=4@EFw+qCz#kv~M0B_dLs;8b0$q`m*DvMr8IjFJUxHd$F!xJE_Givg&j0-{ zWLN!N!cq0-PZTFbV%=Z8;@d<;2vV7XZG8S0<@DCj>?#@S$He)`$L}|!`X(!k$EX! zReD$hwp@yUf4K|fny0VGrh{dkA+n8{Uj6`H`s}Oa>8KSE|&fScP9 zgAQHHf`iC|^~a4E^4@6+h`tYN)+PLAq(W$*=G~b|EnqALU~?fQgIqCo;BgH3yCqxz zpkvR1xh)&*riADAJs-L}zKec!6hwnoqYB!~WT+6Z?v!xNgLgP(Pzyiwn#F)>TIgmN ztoJ1ZT*nkxIWi zEA;MelqWNpz-nJ8MFLaJtbxlobhet9lkk@}$WyQ^v4sb=PnRNOP%;=#zK+P5&M29AX1_H!M?HPaYs~e344O)I48w$b`_t2* zC#2t<<#Ztq*Y_n06MIib-nkC)hluQTUgdz>%pP7sV-l(Ncsr;bPc`566d2QuUh@y(Nz61aW(3^9{igXJQKh<+uvIAVS4X9b1WR^Y z*T_e`7r3!d6)yM^a^{yRMl*ZC71yA%c%Xqe-yx|~gh*$^_LJ4N0W={b0W*8gE#A@> zqEtx6$U`UMKSAe1fZaN`C8hH|~vZ zKGR z6AjH!xReFZ;Tvs4frFSP1x%^*L4HMh;x zLx$fbS1}F%sbM193jLKtOzh=D)SUqElYJm)`Zt>0v5nUUg3l=g0}<~7xA;a6+Ps_C z`QU8=>knhgMd8FKwZI)|h)hT+Cs7NWdIz~b?TRd%dFKP0?EdclJNoff%y%`7;90Zb z$s}Q{?R8QDD_DzskqJ^HVNL!x>aFKU4a;v6bjOxa$9ueOANaMy_Q$a2NMeO(5ivZMHpHf&l@Dscw=)pr{^s0XDRt~|a9too08N1@&O6OO zC_&0oO|}d)NAAj@rpmYPq!xBm5ZBvq>fbps$$cg>8Jq8j3F~dac;ptKN=}O+b%0Cc zhy7Dwiw8Q&j3W8Lnp_+HOo)i8-81f6&l8U#h{wSvAL_xW*@7FZ021N_k@0De<8Qvn zoiemAHC({o-XmJv`oPhJ(XEJ6^XZ@LonWYXz`I_KW^xbc`I0LUzlFA^O`31U?X2@2LnD}> zhzT61CPtep~zC8%MqhO)GuyOkRn) zAfIRX?mU;5@-+un!QIByg=%@-yiE@0!p#Z)YX@jz+;oKh=Wjyrq1C?41rwEJ^`FSWD7m%!(j6G(gS;Q_nU<3&Rlb}Ep+_~ZCkmG2k$ z>Kv*aQ^zV5JPU)(NMPLgB*{vTQNF#sRICivyLdd^#F|F$R7u-Z+^mp8Xo~{Nh3(J@>hD7+JB;E0_~~WHl|kC zI+H}yU*dwP>hYhpn$^#ilVcgdcSJk+s%M_Jc@-%vPJT?xy9T{7kL-4qgH7WFuC1OaisPV`%KQ;Y9 z>m6jp>ir=9fNqWI?h*BHDMQ!hqi{Er_Y9a#nmkcpm?VETiHh`JOb&B9TDtU~nEHR6 zfUht0+IuA79yUjQsF>_HC%uyiNyUIKEA-InwiRlk!%Uv?#lw3k<(sScZ(ka9oc}Qh zzBAlBi(v%VVGh^zkX@7%q{WazSn{Ej4p0>wP*2rbzVmp4tcQzq<#WL6L}5@Q)%x99 zF1L{(uvBzVw7L3r*4hFHCz)rNb4ec7>8euY_6$NzV+8Ya@eYPYatHofY+DphmhQQ* zo{Qh`=WjvT+!iQ75Xh!ZqX@++`k+Ye_#Pm|(z*jk@jd|=K8#`}1D}AJYO7_KoeTH7 z8=+1sEo!@GJQ(E0z8V4z5Z4DJ`gDok?V#c*qfHB$%BsujovlxK%(u5%ns30>C!y)E z-tR;#{>U%x%~-#}kjJX&AP(MB(-@-vsx;dfE3*!z>9{44WG2|2h~l01{F$)BmXqBJ zc_$rc2h+9|+VXiJt8I%Rx465S5elvR3NvCp!H!}NWW(=YbE4$cb@LeqQ`P+@W^UqE zYhMLwSj2R+qkx3DL)Kc!GW^CEE?c+1^ep$M{rRgnr@kbfq0(fNV-rY z#`iS1hN4C6urvV}{6aPXq~{b-#0I(B;SC>K@9f6;I>{NRVaHW;0a5fJJApsTxeEOD z9koU`$jbp_bISwDge=RWr9r6HJ;3!}J!JSAT91ifpvEv_20u~Av(5M!r!2gJH`AMs zP7{!(ZV0}%uZyTSH)+A_VgQK2yNclIs&8)Ei76lRqWiAfO+=L#X2yb<4N?gSpMOrE zuD{d0)_n2e`Qr-ot&2~L=ub*9U(Wh`!*=n+2=lQT^zXwtp5kxyP9}o%Mi;6>XPK%m z(`ZW`?@AEwK4qzNTIo#W#W!zYO2>cU6AXs#6TOIgX&1$nhM%@!yHhOkV^h;Xxkn@&uts7fl@xYtsMI}jyQ%W>ht!u|G z#0#f-xIOJ;ddtlWlLGHB!Pn_NR-I`P5^JGk*4P=T>`nc2q)z0#Mcv^h@Ut;}k3VA) zYIi`_?k_84n`_=|5n4BaoytU|p{UhgbBqK?Dm&y}4lH=DnoN|cLR4XLW()|usvn

  • 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