diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 4d7a26858a2..c9140515a06 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -36,10 +36,11 @@ #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 -#define POINT_PLANE 5 +#define PARTICLE_WEATHER_PLANE 2 +#define AREA_PLANE 3 +#define MASSIVE_OBJ_PLANE 4 +#define GHOST_PLANE 5 +#define POINT_PLANE 6 //---------- LIGHTING ------------- /// Normal 1 per turf dynamic lighting objects diff --git a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm index 094371cc9e6..b5dc090c9aa 100644 --- a/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm +++ b/code/_onclick/hud/rendering/plane_masters/plane_master_subtypes.dm @@ -316,17 +316,40 @@ 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." + name = "Non-Particle Weather" + documentation = "Holds the main tiling 32x32 sprites of weather. We mask against walls that are on the edge of weather effects. Used when the player has particle weather disabled." plane = WEATHER_PLANE start_hidden = TRUE critical = PLANE_CRITICAL_DISPLAY + /// Is this a particle variant? + var/particle_weather = FALSE /atom/movable/screen/plane_master/weather/set_home(datum/plane_master_group/home) . = ..() if(!.) return - home.AddComponent(/datum/component/hide_weather_planes, src) + home.AddComponent(/datum/component/hide_weather_planes, src, particle_weather) + +/atom/movable/screen/plane_master/weather/proc/update_state(mob/mymob) + if(!istype(mymob)) + return + + // If the client wants particle weather, only show the PARTICLE_WEATHER_PLANE, otherwise only show the normal WEATHER_PLANE + if (mymob.canon_client?.prefs?.read_preference(/datum/preference/toggle/particle_weather) != particle_weather) + hide_from(mymob) + else + show_to(mymob) + +/atom/movable/screen/plane_master/weather/show_to(mob/mymob) + // Only show ourselves if the player wants it + if (mymob.canon_client?.prefs?.read_preference(/datum/preference/toggle/particle_weather) == particle_weather) + return ..() + +/atom/movable/screen/plane_master/weather/particle + name = "Particle Weather" + documentation = "Holds the main tiling 32x32 sprites of weather. Used when the player has particle weather enabled." + plane = PARTICLE_WEATHER_PLANE + particle_weather = TRUE /atom/movable/screen/plane_master/weather_mask name = "Weather Mask" diff --git a/code/_onclick/hud/rendering/render_plate.dm b/code/_onclick/hud/rendering/render_plate.dm index 11979dde2ac..7dd681d378c 100644 --- a/code/_onclick/hud/rendering/render_plate.dm +++ b/code/_onclick/hud/rendering/render_plate.dm @@ -84,6 +84,27 @@ . = ..() // We can actually do this just fine as we do not render anything onto ourselves but our particles add_filter("weather_mask", 1, alpha_mask_filter(render_source = OFFSET_RENDER_TARGET(WEATHER_MASK_RENDER_TARGET, offset))) + +/atom/movable/screen/plane_master/rendering_plate/particle_weather/set_home(datum/plane_master_group/home) + . = ..() + if(!.) + return + home.AddComponent(/datum/component/hide_weather_planes, src, TRUE) + RegisterSignal(home, COMSIG_GROUP_HUD_CHANGED, PROC_REF(hud_changed)) + update_state(home.our_hud?.mymob) + +/atom/movable/screen/plane_master/rendering_plate/particle_weather/proc/hud_changed(datum/source, datum/hud/old_hud, datum/hud/new_hud) + SIGNAL_HANDLER + update_state(new_hud?.mymob) + +/// Updates ourselves based on our mob's preferences state +/atom/movable/screen/plane_master/rendering_plate/particle_weather/proc/update_state(mob/mymob) + SSweather.particle_planemasters -= src + vis_contents.Cut() + + if(!istype(mymob) || !mymob.canon_client?.prefs?.read_preference(/datum/preference/toggle/particle_weather)) + return + SSweather.particle_planemasters += src // And add all ongoing weather to ourselves for (var/holder_offset, holder_list in SSweather.particle_holders) @@ -95,12 +116,6 @@ SSweather.particle_planemasters -= src return ..() -/atom/movable/screen/plane_master/rendering_plate/particle_weather/set_home(datum/plane_master_group/home) - . = ..() - if(!.) - return - home.AddComponent(/datum/component/hide_weather_planes, src, TRUE) - /atom/movable/screen/plane_master/rendering_plate/particle_weather/emissive name = "Emissive Particle Weather" documentation = "Secondary particle weather plane for emissive parts of weather, which is additionally rendered onto the emissive plane after being masked." diff --git a/code/datums/weather/particle_weather.dm b/code/datums/weather/particle_weather.dm index 7ac48e4ae36..1c7f385b092 100644 --- a/code/datums/weather/particle_weather.dm +++ b/code/datums/weather/particle_weather.dm @@ -16,6 +16,8 @@ /// How often can we change our severity? /// Don't set this too low or it'll look jank var/severity_cooldown = 5 SECONDS + /// Alpha of the area overlay when the particle weather pref is enabled + var/particle_weather_alpha = 255 /// Current weather severity var/severity = 0 @@ -101,9 +103,15 @@ /datum/weather/particle/generate_overlay_cache() . = ..() + if (stage == END_STAGE) return + // Change alpha of overlays on the particle weather plane + for(var/mutable_appearance/overlay as anything in .) + if (PLANE_TO_TRUE(overlay.plane) == PARTICLE_WEATHER_PLANE) + overlay.alpha = particle_weather_alpha + for (var/offset in 0 to SSmapping.max_plane_offset) . += mutable_appearance('icons/effects/weather_overlay.dmi', "weather_overlay", overlay_layer, null, WEATHER_MASK_PLANE, offset_const = offset) diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index de0d5cfc057..36260744241 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -76,8 +76,9 @@ /// 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 = WEATHER_PLANE + /// Planes for the overlay + /// Base visuals should always render to both particle and non-particle planes as to work regardless of the toggle + var/list/overlay_planes = list(WEATHER_PLANE, PARTICLE_WEATHER_PLANE) /// Used by mobs (or movables containing mobs, such as enviro bags) to prevent them from being affected by the weather. var/immunity_type /// If this bit of weather should also draw an overlay that's uneffected by lighting onto the area @@ -586,9 +587,12 @@ glow_overlay.color = weather_color gen_overlay_cache += glow_overlay - var/mutable_appearance/new_weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, alpha = weather_alpha, offset_const = offset) - new_weather_overlay.color = weather_color - gen_overlay_cache += new_weather_overlay + // By default we render ourselves to both particle and non-particle weather, as those are mutually exclusive + // So that particle weather can have full alpha overlays when the pref is disabled, but partially transparent overlays when its enabled + for (var/overlay_plane in overlay_planes) + var/mutable_appearance/new_weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, alpha = weather_alpha, offset_const = offset) + new_weather_overlay.color = weather_color + gen_overlay_cache += new_weather_overlay return gen_overlay_cache diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm index ae12115e367..16d04c8e19b 100644 --- a/code/datums/weather/weather_types/ash_storm.dm +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -7,7 +7,7 @@ emissive_type = /particles/weather/ash_storm/embers min_severity = 60 optimal_severity = 80 - weather_alpha = 100 + particle_weather_alpha = 100 wind_sign = -1 // Always blows left to sync with the animated overlays telegraph_message = span_boldwarning("An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter.") diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm index 2dcbbed0aa7..536c3461a2b 100644 --- a/code/datums/weather/weather_types/floor_is_lava.dm +++ b/code/datums/weather/weather_types/floor_is_lava.dm @@ -19,7 +19,7 @@ target_trait = ZTRAIT_STATION overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only - overlay_plane = FLOOR_PLANE + overlay_planes = list(FLOOR_PLANE) immunity_type = TRAIT_LAVA_IMMUNE /// We don't draw on walls, so this ends up lookin weird /// Can't really use like, the emissive system here because I am not about to make diff --git a/code/modules/client/preferences/particle_weather.dm b/code/modules/client/preferences/particle_weather.dm new file mode 100644 index 00000000000..a9185eb5d13 --- /dev/null +++ b/code/modules/client/preferences/particle_weather.dm @@ -0,0 +1,15 @@ +/// Whether or not to toggle ambient occlusion, the shadows around people +/datum/preference/toggle/particle_weather + category = PREFERENCE_CATEGORY_GAME_PREFERENCES + savefile_key = "particle_weather" + savefile_identifier = PREFERENCE_PLAYER + +/datum/preference/toggle/particle_weather/apply_to_client(client/client, value) + for(var/atom/movable/screen/plane_master/rendering_plate/particle_weather/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(RENDER_PLANE_PARTICLE_WEATHER)) + plane_master.update_state(client.mob) + + for(var/atom/movable/screen/plane_master/weather/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(WEATHER_PLANE)) + plane_master.update_state(client.mob) + + for(var/atom/movable/screen/plane_master/weather/plane_master as anything in client.mob?.hud_used?.get_true_plane_masters(PARTICLE_WEATHER_PLANE)) + plane_master.update_state(client.mob) diff --git a/tgstation.dme b/tgstation.dme index 68072b4f464..a26c769c843 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4139,6 +4139,7 @@ #include "code\modules\client\preferences\paint_color.dm" #include "code\modules\client\preferences\parallax.dm" #include "code\modules\client\preferences\paraplegic.dm" +#include "code\modules\client\preferences\particle_weather.dm" #include "code\modules\client\preferences\pda.dm" #include "code\modules\client\preferences\persistent_scars.dm" #include "code\modules\client\preferences\phobia.dm" diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/particle_weather.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/particle_weather.tsx new file mode 100644 index 00000000000..cf4824e6ddb --- /dev/null +++ b/tgui/packages/tgui/interfaces/PreferencesMenu/preferences/features/game_preferences/particle_weather.tsx @@ -0,0 +1,9 @@ +import { CheckboxInput, type FeatureToggle } from '../base'; + +export const particle_weather: FeatureToggle = { + name: 'Enable fancy (particle) weather (AMD GPU incompatible)', + category: 'GAMEPLAY', + description: + 'Enable fancy particle weather. Incompatible with AMD GPUs and will cause heavy lag on them due to a BYOND bug.', + component: CheckboxInput, +};