From 07265abdf2c11e90fde101a94f17f773a88cbfca Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Sun, 31 Jul 2022 23:24:12 +0100 Subject: [PATCH] Makes trees transparent if important objects are hiding behind them (#18627) * tree! * Update code/modules/admin/verbs/freeze.dm * yeet * steel review, animate transparency * more critical items * charlie review * charlie --- code/__DEFINES/dcs/signals.dm | 2 + code/__DEFINES/flags.dm | 8 +- .../components/largeobjecttransparency.dm | 105 ++++++++++++++++++ code/game/atoms.dm | 5 +- code/game/gamemodes/blob/theblob.dm | 1 + code/game/gamemodes/nuclear/nuclearbomb.dm | 2 +- code/game/machinery/syndicatebomb.dm | 1 + code/game/objects/effects/spiders.dm | 1 + code/game/objects/structures/aliens.dm | 1 + code/game/objects/structures/flora.dm | 13 +++ code/game/turfs/simulated/floor/misc_floor.dm | 3 +- code/modules/admin/verbs/freeze.dm | 2 + .../awaymissions/mission_code/beach.dm | 6 +- .../living/carbon/alien/special/facehugger.dm | 1 + code/modules/power/supermatter/supermatter.dm | 2 +- paradise.dme | 1 + 16 files changed, 143 insertions(+), 11 deletions(-) create mode 100644 code/datums/components/largeobjecttransparency.dm diff --git a/code/__DEFINES/dcs/signals.dm b/code/__DEFINES/dcs/signals.dm index f9c1ede5634..518005d9b31 100644 --- a/code/__DEFINES/dcs/signals.dm +++ b/code/__DEFINES/dcs/signals.dm @@ -174,6 +174,8 @@ #define COMSIG_ATOM_ORBIT_STOP "atom_orbit_stop" ///from base of atom/hitby(atom/movable/AM, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum) #define COMSIG_ATOM_HITBY "atom_hitby" +/// Called from atom/Initialize() of target: (atom/target) +#define COMSIG_ATOM_INITIALIZED_ON "atom_initialized_on" ///////////////// ///from base of atom/attack_ghost(): (mob/dead/observer/ghost) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index 62b6b9c8a23..5529100a5f2 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -2,11 +2,11 @@ #define NONE 0 //FLAGS BITMASK -#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. +#define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. #define NODROP 2 // This flag makes it so that an item literally cannot be removed at all, or at least that's how it should be. Only deleted. #define NOBLUDGEON 4 // when an item has this it produces no "X has been hit by Y with Z" message with the default handler #define AIRTIGHT 8 // mask allows internals -#define HANDSLOW 16 // If an item has this flag, it will slow you to carry it +#define HANDSLOW 16 // If an item has this flag, it will slow you to carry it #define CONDUCT 32 // conducts electricity (metal etc.) #define ABSTRACT 64 // for all things that are technically items but used for various different stuff, made it 128 because it could conflict with other flags other way #define ON_BORDER 128 // item has priority to check when entering or leaving @@ -75,7 +75,9 @@ /// Prevents shuttles from deleting the item #define IMMUNE_TO_SHUTTLECRUSH_2 (1<<16) /// Prevents malf AI animate + overload ability -#define NO_MALF_EFFECT_2 (1<<17) +#define NO_MALF_EFFECT_2 (1<<17) +/// Use when this shouldn't be obscured by large icons. +#define CRITICAL_ATOM_2 (1<<18) //Reagent flags #define REAGENT_NOREACT 1 diff --git a/code/datums/components/largeobjecttransparency.dm b/code/datums/components/largeobjecttransparency.dm new file mode 100644 index 00000000000..ff10a64d02a --- /dev/null +++ b/code/datums/components/largeobjecttransparency.dm @@ -0,0 +1,105 @@ +///Makes large icons partially see through if high priority atoms are behind them. +/datum/component/largetransparency + //Can be positive or negative. Determines how far away from parent the first registered turf is. + var/x_offset + var/y_offset + //Has to be positive or 0. + var/x_size + var/y_size + //The alpha values this switches in between. + var/initial_alpha + var/target_alpha + //if this is supposed to prevent clicks if it's transparent. + var/toggle_click + var/list/registered_turfs + var/amounthidden = 0 + +/datum/component/largetransparency/Initialize(_x_offset = 0, _y_offset = 1, _x_size = 0, _y_size = 1, _initial_alpha = null, _target_alpha = 140, _toggle_click = TRUE) + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE + x_offset = _x_offset + y_offset = _y_offset + x_size = _x_size + y_size = _y_size + if(isnull(_initial_alpha)) + var/atom/at = parent + initial_alpha = at.alpha + else + initial_alpha = _initial_alpha + target_alpha = _target_alpha + toggle_click = _toggle_click + registered_turfs = list() + + +/datum/component/largetransparency/Destroy() + registered_turfs.Cut() + return ..() + +/datum/component/largetransparency/RegisterWithParent() + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/OnMove) + RegisterWithTurfs() + +/datum/component/largetransparency/UnregisterFromParent() + UnregisterSignal(parent, COMSIG_MOVABLE_MOVED) + UnregisterFromTurfs() + +/datum/component/largetransparency/proc/RegisterWithTurfs() + var/turf/current_turf = get_turf(parent) + if(!current_turf) + return + var/turf/lowleft_turf = locate(clamp(current_turf.x + x_offset, 0, world.maxx), clamp(current_turf.y + y_offset, 0, world.maxy), current_turf.z) + var/turf/upright_turf = locate(min(lowleft_turf.x + x_size, world.maxx), min(lowleft_turf.y + y_size, world.maxy), current_turf.z) + registered_turfs = block(lowleft_turf, upright_turf) //small problems with z level edges due to object size offsets, but nothing truly problematic. + //register the signals + for(var/registered_turf in registered_turfs) + RegisterSignal(registered_turf, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_INITIALIZED_ON), .proc/objectEnter) + RegisterSignal(registered_turf, COMSIG_ATOM_EXITED, .proc/objectLeave) + RegisterSignal(registered_turf, COMSIG_TURF_CHANGE, .proc/OnTurfChange) + for(var/thing in registered_turf) + var/atom/check_atom = thing + if(!(check_atom.flags_2 & CRITICAL_ATOM_2)) + continue + amounthidden++ + if(amounthidden) + reduceAlpha() + +/datum/component/largetransparency/proc/UnregisterFromTurfs() + var/list/signal_list = list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED, COMSIG_TURF_CHANGE, COMSIG_ATOM_INITIALIZED_ON) + for(var/registered_turf in registered_turfs) + UnregisterSignal(registered_turf, signal_list) + registered_turfs.Cut() + +/datum/component/largetransparency/proc/OnMove() + amounthidden = 0 + restoreAlpha() + UnregisterFromTurfs() + RegisterWithTurfs() + +/datum/component/largetransparency/proc/OnTurfChange() + addtimer(CALLBACK(src, .proc/OnMove), 0, TIMER_UNIQUE|TIMER_OVERRIDE) //*pain + +/datum/component/largetransparency/proc/objectEnter(datum/source, atom/enterer) + if(!(enterer.flags_2 & CRITICAL_ATOM_2)) + return + if(!amounthidden) + reduceAlpha() + amounthidden++ + +/datum/component/largetransparency/proc/objectLeave(datum/source, atom/leaver) + if(!(leaver.flags_2 & CRITICAL_ATOM_2)) + return + amounthidden = max(0, amounthidden - 1) + if(!amounthidden) + restoreAlpha() + +/datum/component/largetransparency/proc/reduceAlpha() + var/atom/parent_atom = parent + animate(parent_atom, alpha = target_alpha, 0.5 SECONDS) + if(toggle_click) + parent_atom.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + +/datum/component/largetransparency/proc/restoreAlpha() + var/atom/parent_atom = parent + animate(parent_atom, alpha = initial_alpha, 0.5 SECONDS) + if(toggle_click) + parent_atom.mouse_opacity = MOUSE_OPACITY_OPAQUE diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 1db152a98ec..1a79d599de2 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -123,7 +123,7 @@ T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guranteed to be on afterwards anyways. if(loc) - loc.InitializedOn(src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs. + SEND_SIGNAL(loc, COMSIG_ATOM_INITIALIZED_ON, src) // Used for poolcontroller / pool to improve performance greatly. However it also open up path to other usage of observer pattern on turfs. ComponentInitialize() @@ -146,9 +146,6 @@ /atom/proc/ComponentInitialize() return -/atom/proc/InitializedOn(atom/A) // Proc for when something is initialized on a atom - Optional to call. Useful for observer pattern etc. - return - /atom/proc/onCentcom() . = FALSE var/turf/T = get_turf(src) diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 048d478a080..0e281b8ec44 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -9,6 +9,7 @@ anchored = TRUE max_integrity = 30 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, RAD = 0, FIRE = 80, ACID = 70) + flags_2 = CRITICAL_ATOM_2 var/point_return = 0 //How many points the blob gets back when it removes a blob of that type. If less than 0, blob cannot be removed. var/health_timestamp = 0 var/brute_resist = 0.5 //multiplies brute damage by this diff --git a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm index 5f3cd7484ae..3dc05d4c829 100644 --- a/code/game/gamemodes/nuclear/nuclearbomb.dm +++ b/code/game/gamemodes/nuclear/nuclearbomb.dm @@ -18,7 +18,7 @@ GLOBAL_VAR(bomb_set) icon_state = "nuclearbomb0" density = TRUE resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF - flags_2 = NO_MALF_EFFECT_2 + flags_2 = NO_MALF_EFFECT_2 | CRITICAL_ATOM_2 anchored = TRUE var/extended = TRUE var/lighthack = FALSE diff --git a/code/game/machinery/syndicatebomb.dm b/code/game/machinery/syndicatebomb.dm index 39f58b1e43e..e871b841328 100644 --- a/code/game/machinery/syndicatebomb.dm +++ b/code/game/machinery/syndicatebomb.dm @@ -11,6 +11,7 @@ density = FALSE layer = BELOW_MOB_LAYER //so people can't hide it and it's REALLY OBVIOUS resistance_flags = FIRE_PROOF | ACID_PROOF + flags_2 = CRITICAL_ATOM_2 var/datum/wires/syndicatebomb/wires = null var/minimum_timer = 90 diff --git a/code/game/objects/effects/spiders.dm b/code/game/objects/effects/spiders.dm index 07b1b00dda2..24c9f1850eb 100644 --- a/code/game/objects/effects/spiders.dm +++ b/code/game/objects/effects/spiders.dm @@ -60,6 +60,7 @@ ///Was this egg laid by a xenobiology mob? Used for mob capping var/xenobiology_spawned = FALSE var/list/faction = list("spiders") + flags_2 = CRITICAL_ATOM_2 /obj/structure/spider/eggcluster/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index dc22df206bb..e25c6480b32 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -204,6 +204,7 @@ integrity_failure = 5 var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive layer = MOB_LAYER + flags_2 = CRITICAL_ATOM_2 /obj/structure/alien/egg/grown status = GROWN diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm index 1937ba8e008..8b2c3e11282 100644 --- a/code/game/objects/structures/flora.dm +++ b/code/game/objects/structures/flora.dm @@ -10,6 +10,10 @@ pixel_x = -16 layer = 9 +//Adds the transparency component, exists to be overridden for different args. +/obj/structure/flora/tree/ComponentInitialize() + AddComponent(/datum/component/largetransparency) + /obj/structure/flora/tree/pine name = "pine tree" icon = 'icons/obj/flora/pinetrees.dmi' @@ -28,6 +32,9 @@ icon = 'icons/obj/flora/deadtrees.dmi' icon_state = "tree_1" +/obj/structure/flora/tree/dead/ComponentInitialize() + AddComponent(/datum/component/largetransparency, 0, 1, 0, 0) + /obj/structure/flora/tree/dead/Initialize(mapload) . = ..() icon_state = "tree_[rand(1, 6)]" @@ -53,11 +60,17 @@ icon_state = "[icon_state][rand(1, 6)]" . = ..() +/obj/structure/flora/tree/jungle/ComponentInitialize() + AddComponent(/datum/component/largetransparency, -1, 1, 2, 2) + /obj/structure/flora/tree/jungle/small pixel_y = 0 pixel_x = -32 icon = 'icons/obj/flora/jungletreesmall.dmi' +/obj/structure/flora/tree/jungle/small/ComponentInitialize() + AddComponent(/datum/component/largetransparency) + //grass /obj/structure/flora/grass name = "grass" diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 8711bf96f99..02fdc02c5d5 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -100,6 +100,7 @@ var/image/overlay_image = image('icons/misc/beach.dmi', icon_state = "water5", layer = ABOVE_MOB_LAYER) overlay_image.plane = GAME_PLANE overlays += overlay_image + RegisterSignal(src, COMSIG_ATOM_INITIALIZED_ON, .proc/InitializedOn) /turf/simulated/floor/beach/water/Entered(atom/movable/AM, atom/OldLoc) . = ..() @@ -115,7 +116,7 @@ if(ismob(AM)) linkedcontroller.mobinpool -= AM -/turf/simulated/floor/beach/water/InitializedOn(atom/A) +/turf/simulated/floor/beach/water/proc/InitializedOn(atom/A) if(!linkedcontroller) return if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday diff --git a/code/modules/admin/verbs/freeze.dm b/code/modules/admin/verbs/freeze.dm index 545de7b3ec9..bb100fab76e 100644 --- a/code/modules/admin/verbs/freeze.dm +++ b/code/modules/admin/verbs/freeze.dm @@ -29,6 +29,8 @@ GLOBAL_LIST_EMPTY(frozen_atom_list) // A list of admin-frozen atoms. var/frozen = null /// Used for keeping track of previous sleeping value with admin freeze. var/admin_prev_sleeping = 0 + /// Flag to enable these making trees semi-transparent if behind them + flags_2 = CRITICAL_ATOM_2 /mob/living/admin_Freeze(client/admin, skip_overlays = FALSE, mech = null) if(!istype(admin)) diff --git a/code/modules/awaymissions/mission_code/beach.dm b/code/modules/awaymissions/mission_code/beach.dm index e41a7addee0..1a56754cb31 100644 --- a/code/modules/awaymissions/mission_code/beach.dm +++ b/code/modules/awaymissions/mission_code/beach.dm @@ -88,6 +88,10 @@ heavyfootstep = FOOTSTEP_WATER smoothing_groups = list(SMOOTH_GROUP_BEACH_WATER) +/turf/simulated/floor/beach/away/water/Initialize(mapload) + . = ..() + RegisterSignal(src, COMSIG_ATOM_INITIALIZED_ON, .proc/InitializedOn) + /turf/simulated/floor/beach/away/water/Entered(atom/movable/AM, atom/OldLoc) . = ..() if(!linkedcontroller) @@ -102,7 +106,7 @@ if(ismob(AM)) linkedcontroller.mobinpool -= AM -/turf/simulated/floor/beach/away/water/InitializedOn(atom/A) +/turf/simulated/floor/beach/away/water/proc/InitializedOn(atom/A) if(!linkedcontroller) return if(istype(A, /obj/effect/decal/cleanable)) // Better a typecheck than looping through thousands of turfs everyday diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 264b4e33080..27565b080ea 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -16,6 +16,7 @@ throw_range = 5 tint = 3 flags = AIRTIGHT + flags_2 = CRITICAL_ATOM_2 flags_cover = MASKCOVERSMOUTH | MASKCOVERSEYES layer = MOB_LAYER max_integrity = 100 diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 45913d69493..86c937ece70 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -85,7 +85,7 @@ icon_state = "darkmatter" density = TRUE anchored = TRUE - flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 | IMMUNE_TO_SHUTTLECRUSH_2 | NO_MALF_EFFECT_2 + flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 | IMMUNE_TO_SHUTTLECRUSH_2 | NO_MALF_EFFECT_2 | CRITICAL_ATOM_2 light_range = 4 resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF | FREEZE_PROOF base_icon_state = "darkmatter" diff --git a/paradise.dme b/paradise.dme index 9c8a6a9ca50..a330b00a9ef 100644 --- a/paradise.dme +++ b/paradise.dme @@ -347,6 +347,7 @@ #include "code\datums\components\emissive_blocker.dm" #include "code\datums\components\footstep.dm" #include "code\datums\components\label.dm" +#include "code\datums\components\largeobjecttransparency.dm" #include "code\datums\components\material_container.dm" #include "code\datums\components\orbiter.dm" #include "code\datums\components\paintable.dm"