mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
Weather planes from The Wallening to fix multi-z weather overlays (#86733)
## About The Pull Request I started doing this for Yogstation, but ended up doing all my testing on TG code since there's more debug tools to use, and @LemonInTheDark said I should upstream it when I was done. So I'm just gonna start here. The whole point of this is to stop multi-z maps from stacking weather overlay effects like  Old pic I know, but you get the point Now it behaves as expected https://github.com/user-attachments/assets/6d737eae-2493-4b48-8870-e4ac73dcbbeb https://github.com/user-attachments/assets/b253aa97-c90d-4049-a97d-940b0ec386d0 <details> <summary>Note: this does not fix the issue of areas out of your view not updating their appearance. 90% sure that's a Byond™️ issue</summary> https://github.com/user-attachments/assets/3db5ce28-2623-4d3e-a5f4-bd561d96010a </details> ## Why It's Good For The Game Isolating weather to its own planes is good for having better control over how it behaves. Since weather overlays are tied to areas it makes them kinda hacky to begin with, but this is a step in reigning them in. ## Changelog 🆑 fix: fixed multi-z weather overlays stacking and not hiding overlays above you /🆑
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
/// 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() : (new_z)
|
||||
#define COMSIG_HUD_Z_CHANGED "hud_z_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() : ()
|
||||
|
||||
2
code/__DEFINES/dcs/signals/signals_plane_master_group.dm
Normal file
2
code/__DEFINES/dcs/signals/signals_plane_master_group.dm
Normal file
@@ -0,0 +1,2 @@
|
||||
/// from /datum/plane_master_group/proc/set_hud(): (datum/hud/new_hud)
|
||||
#define COMSIG_GROUP_HUD_CHANGED "group_hud_changed"
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#define DEFAULT_PLANE 0 //Marks out the default plane, even if we don't use it
|
||||
|
||||
#define WEATHER_PLANE 1
|
||||
#define AREA_PLANE 2
|
||||
#define MASSIVE_OBJ_PLANE 3
|
||||
#define GHOST_PLANE 4
|
||||
@@ -65,6 +66,8 @@
|
||||
///Things that should render ignoring lighting
|
||||
#define ABOVE_LIGHTING_PLANE 17
|
||||
|
||||
#define WEATHER_GLOW_PLANE 18
|
||||
|
||||
///---------------- MISC -----------------------
|
||||
|
||||
///Pipecrawling images
|
||||
|
||||
@@ -198,6 +198,7 @@ GLOBAL_LIST_INIT(available_ui_styles, list(
|
||||
SIGNAL_HANDLER
|
||||
update_parallax_pref() // If your eye changes z level, so should your parallax prefs
|
||||
var/turf/eye_turf = get_turf(eye)
|
||||
SEND_SIGNAL(src, COMSIG_HUD_Z_CHANGED, eye_turf.z)
|
||||
var/new_offset = GET_TURF_PLANE_OFFSET(eye_turf)
|
||||
if(current_plane_offset == new_offset)
|
||||
return
|
||||
|
||||
@@ -24,10 +24,23 @@
|
||||
build_plane_masters(0, SSmapping.max_plane_offset)
|
||||
|
||||
/datum/plane_master_group/Destroy()
|
||||
orphan_hud()
|
||||
set_hud(null)
|
||||
QDEL_LIST_ASSOC_VAL(plane_masters)
|
||||
return ..()
|
||||
|
||||
/datum/plane_master_group/proc/set_hud(datum/hud/new_hud)
|
||||
if(new_hud == our_hud)
|
||||
return
|
||||
if(our_hud)
|
||||
our_hud.master_groups -= key
|
||||
hide_hud()
|
||||
our_hud = new_hud
|
||||
if(new_hud)
|
||||
our_hud.master_groups[key] = src
|
||||
show_hud()
|
||||
build_planes_offset(our_hud, active_offset)
|
||||
SEND_SIGNAL(src, COMSIG_GROUP_HUD_CHANGED, our_hud)
|
||||
|
||||
/// 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])
|
||||
@@ -42,18 +55,11 @@
|
||||
relay_loc = "1,1"
|
||||
rebuild_plane_masters()
|
||||
|
||||
our_hud = viewing_hud
|
||||
set_hud(viewing_hud)
|
||||
our_hud.master_groups[key] = src
|
||||
show_hud()
|
||||
build_planes_offset(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()
|
||||
|
||||
@@ -243,6 +243,18 @@
|
||||
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/weather
|
||||
name = "Weather"
|
||||
documentation = "Holds the main tiling 32x32 sprites of weather. We mask against walls that are on the edge of weather effects."
|
||||
plane = WEATHER_PLANE
|
||||
start_hidden = TRUE
|
||||
|
||||
/atom/movable/screen/plane_master/weather/set_home(datum/plane_master_group/home)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
home.AddComponent(/datum/component/hide_weather_planes, src)
|
||||
|
||||
/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."
|
||||
@@ -285,6 +297,18 @@
|
||||
documentation = "Anything on the game plane that needs a space to draw on that will be above the lighting plane.\
|
||||
<br>Mostly little alerts and effects, also sometimes contains things that are meant to look as if they glow."
|
||||
|
||||
/atom/movable/screen/plane_master/weather_glow
|
||||
name = "Weather Glow"
|
||||
documentation = "Holds the glowing parts of the main tiling 32x32 sprites of weather."
|
||||
plane = WEATHER_GLOW_PLANE
|
||||
start_hidden = TRUE
|
||||
|
||||
/atom/movable/screen/plane_master/weather_glow/set_home(datum/plane_master_group/home)
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
home.AddComponent(/datum/component/hide_weather_planes, src)
|
||||
|
||||
/**
|
||||
* Handles emissive overlays and emissive blockers.
|
||||
*/
|
||||
|
||||
@@ -345,7 +345,7 @@
|
||||
if(!.)
|
||||
return
|
||||
|
||||
RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight))
|
||||
RegisterSignal(mymob, COMSIG_MOB_SIGHT_CHANGE, PROC_REF(handle_sight), override = TRUE)
|
||||
handle_sight(mymob, mymob.sight, NONE)
|
||||
|
||||
/atom/movable/screen/plane_master/rendering_plate/light_mask/hide_from(mob/oldmob)
|
||||
|
||||
136
code/datums/components/hide_weather_planes.dm
Normal file
136
code/datums/components/hide_weather_planes.dm
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Component that manages a list of plane masters that are dependent on weather
|
||||
* Force hides/shows them depending on the weather activity of their z stack
|
||||
* Transparency is achieved by manipulating the alpha of the planes that are visible
|
||||
* Applied to the plane master group that owns them
|
||||
*/
|
||||
/datum/component/hide_weather_planes
|
||||
dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
|
||||
var/list/datum/weather/active_weather = list()
|
||||
var/list/atom/movable/screen/plane_master/plane_masters = list()
|
||||
|
||||
/datum/component/hide_weather_planes/Initialize(atom/movable/screen/plane_master/care_about)
|
||||
if(!istype(parent, /datum/plane_master_group))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
var/datum/plane_master_group/home = parent
|
||||
plane_masters += care_about
|
||||
RegisterSignal(care_about, COMSIG_QDELETING, PROC_REF(plane_master_deleted))
|
||||
|
||||
var/list/starting_signals = list()
|
||||
var/list/ending_signals = list()
|
||||
for(var/datum/weather/weather_type as anything in typesof(/datum/weather))
|
||||
starting_signals += COMSIG_WEATHER_TELEGRAPH(weather_type)
|
||||
ending_signals += COMSIG_WEATHER_END(weather_type)
|
||||
|
||||
RegisterSignals(SSdcs, starting_signals, PROC_REF(weather_started))
|
||||
RegisterSignals(SSdcs, ending_signals, PROC_REF(weather_finished))
|
||||
|
||||
if(home.our_hud)
|
||||
attach_hud(home.our_hud)
|
||||
else
|
||||
RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(new_hud_attached))
|
||||
|
||||
/datum/component/hide_weather_planes/Destroy(force)
|
||||
hide_planes()
|
||||
active_weather = null
|
||||
plane_masters = null
|
||||
return ..()
|
||||
|
||||
/datum/component/hide_weather_planes/InheritComponent(datum/component/new_comp, i_am_original, atom/movable/screen/plane_master/care_about)
|
||||
if(!i_am_original)
|
||||
return
|
||||
var/datum/plane_master_group/home = parent
|
||||
var/mob/our_lad = home.our_hud?.mymob
|
||||
var/our_offset = GET_TURF_PLANE_OFFSET(our_lad)
|
||||
plane_masters += care_about
|
||||
RegisterSignal(care_about, COMSIG_QDELETING, PROC_REF(plane_master_deleted))
|
||||
if(length(active_weather))
|
||||
//If there's weather to care about we unhide our new plane and adjust its alpha
|
||||
care_about.unhide_plane(our_lad)
|
||||
|
||||
if(care_about.offset >= our_offset)
|
||||
care_about.enable_alpha()
|
||||
else
|
||||
care_about.disable_alpha()
|
||||
else
|
||||
care_about.hide_plane(our_lad)
|
||||
|
||||
/datum/component/hide_weather_planes/proc/new_hud_attached(datum/source, datum/hud/new_hud)
|
||||
SIGNAL_HANDLER
|
||||
attach_hud(new_hud)
|
||||
|
||||
/datum/component/hide_weather_planes/proc/attach_hud(datum/hud/new_hud)
|
||||
RegisterSignal(new_hud, COMSIG_HUD_Z_CHANGED, PROC_REF(z_changed))
|
||||
var/mob/eye = new_hud?.mymob?.client?.eye
|
||||
var/turf/eye_location = get_turf(eye)
|
||||
z_changed(new_hud, eye_location?.z)
|
||||
|
||||
/datum/component/hide_weather_planes/proc/plane_master_deleted(atom/movable/screen/plane_master/source)
|
||||
SIGNAL_HANDLER
|
||||
plane_masters -= source
|
||||
|
||||
/**
|
||||
* Unhides the relevant planes for the weather to be visible and manipulated.
|
||||
* Also updates the alpha of the planes so enabled planes are either fully opaque or fully transparent
|
||||
*/
|
||||
/datum/component/hide_weather_planes/proc/display_planes()
|
||||
var/datum/plane_master_group/home = parent
|
||||
var/mob/our_lad = home.our_hud?.mymob
|
||||
var/our_offset = GET_TURF_PLANE_OFFSET(our_lad)
|
||||
for(var/atom/movable/screen/plane_master/weather_concious as anything in plane_masters)
|
||||
//If the plane is hidden, unhide it
|
||||
if(weather_concious.force_hidden)
|
||||
weather_concious.unhide_plane(our_lad)
|
||||
|
||||
//Now we update the alpha of the plane based on our offset. Weather above us (lower offset) are transparent, weather at or below us (higher offset) are opaque.
|
||||
if(weather_concious.offset >= our_offset)
|
||||
weather_concious.enable_alpha()
|
||||
else
|
||||
weather_concious.disable_alpha()
|
||||
|
||||
///Hides the planes from the mob when no weather is occuring
|
||||
/datum/component/hide_weather_planes/proc/hide_planes()
|
||||
var/datum/plane_master_group/home = parent
|
||||
var/mob/our_lad = home.our_hud?.mymob
|
||||
for(var/atom/movable/screen/plane_master/weather_concious as anything in plane_masters)
|
||||
weather_concious.hide_plane(our_lad)
|
||||
|
||||
/datum/component/hide_weather_planes/proc/z_changed(datum/source, new_z)
|
||||
SIGNAL_HANDLER
|
||||
active_weather = list()
|
||||
if(!SSmapping.initialized)
|
||||
return
|
||||
|
||||
var/list/connected_levels = SSmapping.get_connected_levels(new_z)
|
||||
for(var/datum/weather/active as anything in SSweather.processing)
|
||||
if(length(connected_levels & active.impacted_z_levels))
|
||||
active_weather += WEAKREF(active)
|
||||
|
||||
if(length(active_weather))
|
||||
display_planes()
|
||||
else
|
||||
hide_planes()
|
||||
|
||||
/datum/component/hide_weather_planes/proc/weather_started(datum/source, datum/weather/starting)
|
||||
SIGNAL_HANDLER
|
||||
var/datum/plane_master_group/home = parent
|
||||
var/mob/eye = home.our_hud?.mymob?.client?.eye
|
||||
var/turf/viewing_from = get_turf(eye)
|
||||
if(!viewing_from)
|
||||
return
|
||||
|
||||
var/list/connected_levels = SSmapping.get_connected_levels(viewing_from)
|
||||
if(length(connected_levels & starting.impacted_z_levels))
|
||||
active_weather += WEAKREF(starting)
|
||||
|
||||
if(!length(active_weather))
|
||||
return
|
||||
display_planes()
|
||||
|
||||
/datum/component/hide_weather_planes/proc/weather_finished(datum/source, datum/weather/stopping)
|
||||
SIGNAL_HANDLER
|
||||
active_weather -= WEAKREF(stopping)
|
||||
|
||||
if(length(active_weather))
|
||||
return
|
||||
hide_planes()
|
||||
@@ -59,7 +59,7 @@
|
||||
/// Since it's above everything else, this is the layer used by default.
|
||||
var/overlay_layer = AREA_LAYER
|
||||
/// Plane for the overlay
|
||||
var/overlay_plane = AREA_PLANE
|
||||
var/overlay_plane = WEATHER_PLANE
|
||||
/// If the weather has no purpose other than looks
|
||||
var/aesthetic = FALSE
|
||||
/// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather.
|
||||
@@ -99,7 +99,7 @@
|
||||
/datum/weather/proc/telegraph()
|
||||
if(stage == STARTUP_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type))
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_TELEGRAPH(type), src)
|
||||
stage = STARTUP_STAGE
|
||||
var/list/affectareas = list()
|
||||
for(var/V in get_areas(area_type))
|
||||
@@ -129,14 +129,14 @@
|
||||
/datum/weather/proc/start()
|
||||
if(stage >= MAIN_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type))
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_START(type), src)
|
||||
stage = MAIN_STAGE
|
||||
update_areas()
|
||||
send_alert(weather_message, weather_sound)
|
||||
if(!perpetual)
|
||||
addtimer(CALLBACK(src, PROC_REF(wind_down)), weather_duration)
|
||||
for(var/area/impacted_area as anything in impacted_areas)
|
||||
SEND_SIGNAL(impacted_area, COMSIG_WEATHER_BEGAN_IN_AREA(type))
|
||||
SEND_SIGNAL(impacted_area, COMSIG_WEATHER_BEGAN_IN_AREA(type), src)
|
||||
|
||||
/**
|
||||
* Weather enters the winding down phase, stops effects
|
||||
@@ -148,7 +148,7 @@
|
||||
/datum/weather/proc/wind_down()
|
||||
if(stage >= WIND_DOWN_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type))
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_WINDDOWN(type), src)
|
||||
stage = WIND_DOWN_STAGE
|
||||
update_areas()
|
||||
send_alert(end_message, end_sound)
|
||||
@@ -164,12 +164,12 @@
|
||||
/datum/weather/proc/end()
|
||||
if(stage == END_STAGE)
|
||||
return
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type))
|
||||
SEND_GLOBAL_SIGNAL(COMSIG_WEATHER_END(type), src)
|
||||
stage = END_STAGE
|
||||
SSweather.processing -= src
|
||||
update_areas()
|
||||
for(var/area/impacted_area as anything in impacted_areas)
|
||||
SEND_SIGNAL(impacted_area, COMSIG_WEATHER_ENDED_IN_AREA(type))
|
||||
SEND_SIGNAL(impacted_area, COMSIG_WEATHER_ENDED_IN_AREA(type), src)
|
||||
|
||||
// handles sending all alerts
|
||||
/datum/weather/proc/send_alert(alert_msg, alert_sfx)
|
||||
@@ -260,12 +260,12 @@
|
||||
// I prefer it to creating 2 extra plane masters however, so it's a cost I'm willing to pay
|
||||
// LU
|
||||
if(use_glow)
|
||||
var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, null, ABOVE_LIGHTING_PLANE, 100, offset_const = offset)
|
||||
var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, null, WEATHER_GLOW_PLANE, 100, offset_const = offset)
|
||||
glow_overlay.color = weather_color
|
||||
gen_overlay_cache += glow_overlay
|
||||
|
||||
var/mutable_appearance/weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, offset_const = offset)
|
||||
weather_overlay.color = weather_color
|
||||
gen_overlay_cache += weather_overlay
|
||||
var/mutable_appearance/new_weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, offset_const = offset)
|
||||
new_weather_overlay.color = weather_color
|
||||
gen_overlay_cache += new_weather_overlay
|
||||
|
||||
return gen_overlay_cache
|
||||
|
||||
@@ -344,6 +344,7 @@
|
||||
#include "code\__DEFINES\dcs\signals\signals_operating_computer.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_operatives.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_painting.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_plane_master_group.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_proxmonitor.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_radiation.dm"
|
||||
#include "code\__DEFINES\dcs\signals\signals_reagent.dm"
|
||||
@@ -1134,6 +1135,7 @@
|
||||
#include "code\datums\components\heart_eater.dm"
|
||||
#include "code\datums\components\heirloom.dm"
|
||||
#include "code\datums\components\hide_highest_offset.dm"
|
||||
#include "code\datums\components\hide_weather_planes.dm"
|
||||
#include "code\datums\components\holderloving.dm"
|
||||
#include "code\datums\components\igniter.dm"
|
||||
#include "code\datums\components\infective.dm"
|
||||
|
||||
Reference in New Issue
Block a user