Ports large object transparency from TGMC (#21508)

Ports https://github.com/tgstation/TerraGov-Marine-Corps/pull/3528
Credit goes to original coders. This PR makes large objects transparent
when something important is behind it.

For now the list of large objects and the things make them transparent
by using this component as follows:

Large objects:

- Trees
- Cranes
- Old shipping containers (new ones doesn't allow anything to go behind
it)

The things make them transparent:
- Mobs
- Carts
- Portable generators
- Nuke

## Images


https://github.com/user-attachments/assets/a4f8ddfc-0fde-4b2d-8bd8-d15e1c6e8e0b

### Asset Licenses
The following assets that **have not** been created by myself are
included in this PR:

| Path | Original Author | License |
| --- | --- | --- |
| code/datums/components/large_object_transparency.dm | nemvar (TGMC) |
AGPLv3 |
This commit is contained in:
Kano
2025-10-30 16:57:04 +00:00
committed by GitHub
parent 3067cb65a5
commit ae68667372
14 changed files with 161 additions and 4 deletions
+1
View File
@@ -472,6 +472,7 @@
#include "code\datums\components\_component.dm"
#include "code\datums\components\connect_mob_behalf.dm"
#include "code\datums\components\drift.dm"
#include "code\datums\components\large_object_transparency.dm"
#include "code\datums\components\leanable.dm"
#include "code\datums\components\local_network.dm"
#include "code\datums\components\orbiter.dm"
+6
View File
@@ -15,11 +15,17 @@
// /atom signals
/// Called from atom/Initialize() of target: (atom/target)
#define COMSIG_ATOM_INITIALIZED_ON "atom_initialized_on"
// /area signals
#define COMSIG_AREA_FIRE_ALARM "fire_alarm"
// /turf signals
/// From base of turf/ChangeTurf(): (path)
#define COMSIG_TURF_CHANGE "turf_change"
// /atom/movable signals
#define COMSIG_MOVABLE_HEAR "movable_hear"
+6
View File
@@ -66,6 +66,11 @@ GLOBAL_LIST_INIT(mimic_defines, list("ZM_MIMIC_BELOW",
///Shuttle transition will delete this.
#define MOVABLE_FLAG_DEL_SHUTTLE FLAG(3)
// Atom flags
/// Use when this shouldn't be obscured by large icons.
#define CRITICAL_ATOM FLAG(20)
// Obj flags
/// Can this object be rotated?
@@ -109,3 +114,4 @@ GLOBAL_LIST_INIT(mimic_defines, list("ZM_MIMIC_BELOW",
#define ITEM_FLAG_NO_MOVE FLAG(12)
/// Can be used for surgery, giving the "You're not sure what you can do with this." message if no surgery is available.
#define ITEM_FLAG_SURGERY FLAG(13)
@@ -0,0 +1,116 @@
///Makes large icons partially see through if high priority atoms are behind them.
/datum/component/large_transparency
/// 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
/// Atom's original mouse opacity, cached for restoring
var/initial_mouse_opacity
var/list/registered_turfs
var/amounthidden = 0
/datum/component/large_transparency/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
var/atom/at = parent
if(isnull(_initial_alpha))
initial_alpha = at.alpha
else
initial_alpha = _initial_alpha
target_alpha = _target_alpha
toggle_click = _toggle_click
initial_mouse_opacity = at.mouse_opacity
registered_turfs = list()
/datum/component/large_transparency/Destroy()
registered_turfs.Cut()
return ..()
/datum/component/large_transparency/RegisterWithParent()
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(OnMove))
RegisterWithTurfs()
/datum/component/large_transparency/UnregisterFromParent()
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
UnregisterFromTurfs()
/datum/component/large_transparency/proc/RegisterWithTurfs()
var/turf/current_tu = get_turf(parent)
if(!current_tu)
return
var/turf/lowleft_tu = locate(clamp(current_tu.x + x_offset, 0, world.maxx), clamp(current_tu.y + y_offset, 0, world.maxy), current_tu.z)
var/turf/upright_tu = locate(min(lowleft_tu.x + x_size, world.maxx), min(lowleft_tu.y + y_size, world.maxy), current_tu.z)
registered_turfs = block(lowleft_tu, upright_tu) //small problems with z level edges but nothing gamebreaking.
//register the signals
for(var/regist_tu in registered_turfs)
if(!regist_tu)
continue
RegisterSignals(regist_tu, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_INITIALIZED_ON), PROC_REF(objectEnter))
RegisterSignal(regist_tu, COMSIG_ATOM_EXITED, PROC_REF(objectLeave))
RegisterSignal(regist_tu, COMSIG_TURF_CHANGE, PROC_REF(OnTurfChange))
for(var/thing in regist_tu)
var/atom/check_atom = thing
if(!(check_atom.atom_flags & CRITICAL_ATOM))
continue
amounthidden++
if(amounthidden)
reduceAlpha()
/datum/component/large_transparency/proc/UnregisterFromTurfs()
var/list/signal_list = list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED, COMSIG_TURF_CHANGE, COMSIG_ATOM_INITIALIZED_ON)
for(var/regist_tu in registered_turfs)
UnregisterSignal(regist_tu, signal_list)
registered_turfs.Cut()
/datum/component/large_transparency/proc/OnMove()
SIGNAL_HANDLER
amounthidden = 0
restoreAlpha()
UnregisterFromTurfs()
RegisterWithTurfs()
/datum/component/large_transparency/proc/OnTurfChange()
SIGNAL_HANDLER
addtimer(CALLBACK(src, PROC_REF(OnMove)), 1, TIMER_UNIQUE|TIMER_OVERRIDE) //*pain
/datum/component/large_transparency/proc/objectEnter(datum/source, atom/enterer)
SIGNAL_HANDLER
if(!(enterer.atom_flags & CRITICAL_ATOM))
return
if(!amounthidden)
reduceAlpha()
amounthidden++
/datum/component/large_transparency/proc/objectLeave(datum/source, atom/leaver, direction)
SIGNAL_HANDLER
if(!(leaver.atom_flags & CRITICAL_ATOM))
return
amounthidden = max(0, amounthidden - 1)
if(!amounthidden)
restoreAlpha()
/datum/component/large_transparency/proc/reduceAlpha()
var/atom/par_atom = parent
par_atom.alpha = target_alpha
if(toggle_click)
par_atom.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
/datum/component/large_transparency/proc/restoreAlpha()
var/atom/par_atom = parent
par_atom.alpha = initial_alpha
if(toggle_click)
par_atom.mouse_opacity = initial_mouse_opacity
@@ -129,19 +129,22 @@
reagents.maximum_volume += max(LAZYACCESS(reagents_to_add, v) - REAGENTS_FREE_SPACE(reagents), 0)
reagents.add_reagent(v, LAZYACCESS(reagents_to_add, v), LAZYACCESS(reagent_data, v))
if (light_power && light_range)
if(light_power && light_range)
update_light()
if (opacity && isturf(loc))
if(loc)
SEND_SIGNAL(loc, COMSIG_ATOM_INITIALIZED_ON, src) // used for large_object_transparency component
if(isturf(loc) && opacity)
var/turf/T = loc
T.has_opaque_atom = TRUE // No need to recalculate it in this case, it's guaranteed to be on afterwards anyways.
#ifdef AO_USE_LIGHTING_OPACITY
if (!mapload)
if(!mapload)
T.regenerate_ao()
#endif
if (update_icon_on_init)
if(update_icon_on_init)
SSicon_update.add_to_queue(src)
//Finally an aurora snowflake code that matters,
@@ -10,6 +10,7 @@
/mob/living
atom_flags = CRITICAL_ATOM
var/instability = 0
var/last_instability = 0 // Used to calculate instability delta.
var/last_instability_event = null // most recent world.time that something bad happened due to instability.
+2
View File
@@ -6,6 +6,8 @@ GLOBAL_VAR(bomb_set)
icon = 'icons/obj/nuke.dmi'
icon_state = "idle"
density = 1
atom_flags = CRITICAL_ATOM
var/deployable = 0
var/extended = 0
var/lighthack = 0
@@ -8,6 +8,7 @@ ABSTRACT_TYPE(/obj/structure/cart)
build_amt = 15
material = DEFAULT_WALL_MATERIAL
slowdown = 0
atom_flags = CRITICAL_ATOM
var/movesound = 'sound/effects/roll.ogg'
var/driving
var/mob/living/pulling
+4
View File
@@ -45,3 +45,7 @@
density = TRUE
layer = 9
pixel_x = -16
/obj/structure/crane/Initialize()
. = ..()
AddComponent(/datum/component/large_transparency)
+4
View File
@@ -416,6 +416,10 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
density = TRUE
layer = ABOVE_HUMAN_LAYER
/obj/structure/shipping_container_old/Initialize()
. = ..()
AddComponent(/datum/component/large_transparency)
/obj/effect/overlay/container_logo
name = "Hephaestus Industries emblem"
icon = 'icons/obj/structure/industrial/shipping_containers_old.dmi'
+1
View File
@@ -60,6 +60,7 @@
var/old_is_open = is_open()
var/list/old_resources = resources ? resources.Copy() : null
SEND_SIGNAL(src, COMSIG_TURF_CHANGE, path)
changing_turf = TRUE
if(connections)
@@ -13,6 +13,10 @@
var/stumptype = /obj/structure/flora/stump //stump to make when chopped
var/static/list/fall_forbid = list(/obj/structure/flora, /obj/effect, /obj/structure/bonfire, /obj/structure/pit)
/obj/structure/flora/tree/Initialize()
. = ..()
AddComponent(/datum/component/large_transparency)
/obj/structure/flora/tree/proc/update_desc()
desc = initial(desc)
switch(chop_health / max_chop_health)
+1
View File
@@ -7,6 +7,7 @@
var/base_icon = "portgen0"
density = TRUE
anchored = FALSE
atom_flags = CRITICAL_ATOM
var/active = FALSE
var/power_gen = 5000
@@ -0,0 +1,7 @@
author: Kano
delete-after: True
changes:
- qol: "Ported large object transparency from TGMC, allowing to see some things hiding behind large icons."