MONKEY (skybox): zoneSkyboxes cvar, Advanced Graphics row, skybox- capture scenarios
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
88ceb9d2c2
commit
bd1c6de9f8
@@ -24,6 +24,7 @@ behind each constant.
|
||||
| Moon shadows | at night the same shadow rig re-aims at the moon and casts a faint shadow; dims only the night sky term, never point lights | `moonShadowStrength` |
|
||||
| Ground-effect spells | Flamestrike, Rain of Fire, Consecration, Flare and fire traps light the ground for their duration; frost and nature areas stay dark | `spellLightGain` |
|
||||
| Volumetric fog | near-field haze that converges on the zone fog colour (clear within 10 yd, full by 150 yd; mistier at dawn and in bad weather, faint indoors) and sun/moon light shafts through gaps, sampled from the shadow map; own fullscreen pass after the main pass (`benilla-app/src/volumetric_fog.rs`) | Advanced Graphics → Volumetric Fog (Off/Low/High), cvar `volumetricFog`, env `WOW_VOLFOG=0\|1\|2` |
|
||||
| Zone skyboxes | the painted sky a zone's `LightParams` names (clear-weather slot, storm slot lerped by the storm blend) for the living, fading in by the Light sphere falloff with the modern client's crossfade (ghost > WMO > zone); extended `LightSkybox.dbc` flags `0x1` day cycle, `0x2` keep sun/moon/stars/clouds, `0x4` fog-colour horizon cone, plus a celestial second model; every skybox now plays its bones, texture transforms, colour and alpha tracks (`benilla-world/src/skybox.rs`, `skybox_anim.rs`, `benilla-formats/src/light/skybox.rs`) | Advanced Graphics → Zone Skyboxes, cvar `zoneSkyboxes` (0 Off default, 1 On; High = 1), env `WOW_ZONE_SKYBOXES=0\|1` |
|
||||
| Night and interior level | global dimming of the night sky term and of interior ambient | `nightGain`, `interiorGain`, `interiorBakeFloor` |
|
||||
|
||||
Players reach all of it from **Options -> Advanced Graphics** (a Lighting Quality preset Off / Low / Medium / High plus the individual rows; Off is the original client look). The dev build has a panel for all of it: **Ctrl+Shift+D → Lighting & shadows**, with Dim / Default /
|
||||
|
||||
@@ -495,6 +495,8 @@
|
||||
-- MONKEY (volumetric fog): localised atmospheric quality row.
|
||||
volumetricFog = "Volumetric Fog",
|
||||
fogOff = "Off",
|
||||
-- MONKEY (skybox): the zone skybox row.
|
||||
zoneSkyboxes = "Zone Skyboxes",
|
||||
waterQuality = "Water Quality",
|
||||
waterClassic = "Classic",
|
||||
waterEnhanced = "Enhanced",
|
||||
@@ -534,6 +536,12 @@
|
||||
-- MONKEY (volumetric fog): explain cost and the shadow-map dependency.
|
||||
VOLUMETRIC_FOG =
|
||||
"Off disables volumetric fog. Low adds nearby haze and sun or moon shafts with fewer steps; High uses more steps for smoother shafts. Mist is heavier at dawn and in bad weather, and subtle indoors. Shafts require shadows; with shadows off only haze remains.",
|
||||
-- MONKEY (skybox): what the zone skybox row changes.
|
||||
ZONE_SKYBOXES =
|
||||
"Draws the painted sky a zone's lighting names, as later expansions do: "
|
||||
.. "the volcanic sky of the Burning Steppes, the alien sky of the Blasted Lands "
|
||||
.. "and the starry night over Mount Hyjal, fading in at the zone's edge. "
|
||||
.. "Off keeps the original client's sky everywhere but ghost and dungeon skies. Nearly free.",
|
||||
WATER_QUALITY =
|
||||
"Classic is the original client's water. Enhanced adds soft shorelines, "
|
||||
.. "animated foam around shores and objects, moving wave highlights, sky reflection "
|
||||
@@ -619,6 +627,8 @@
|
||||
-- MONKEY (volumetric fog): Russian atmospheric quality row.
|
||||
volumetricFog = "Объёмный туман",
|
||||
fogOff = "Выкл",
|
||||
-- MONKEY (skybox): the zone skybox row.
|
||||
zoneSkyboxes = "Небосводы зон",
|
||||
waterQuality = "Качество воды",
|
||||
waterClassic = "Классическое",
|
||||
waterEnhanced = "Улучшенное",
|
||||
@@ -660,6 +670,12 @@
|
||||
-- MONKEY (volumetric fog): localised effect and cost explanation.
|
||||
VOLUMETRIC_FOG =
|
||||
"Выкл отключает объёмный туман. Низкое добавляет дымку вблизи и лучи солнца или луны с меньшим числом шагов; Высокое использует больше шагов для более плавных лучей. Туман гуще на рассвете и в непогоду, а в помещениях слабее. Для лучей нужны тени; без теней остаётся только дымка.",
|
||||
-- MONKEY (skybox): what the zone skybox row changes.
|
||||
ZONE_SKYBOXES =
|
||||
"Рисует нарисованное небо, заданное освещением зоны, как в поздних дополнениях: "
|
||||
.. "вулканическое небо Пылающих степей, чужое небо Выжженных земель "
|
||||
.. "и звёздную ночь над горой Хиджал, с плавным появлением на границе зоны. "
|
||||
.. "«Выкл.» оставляет небо оригинального клиента везде, кроме неба призрака и подземелий. Почти бесплатно.",
|
||||
WATER_QUALITY =
|
||||
"«Классическое» — вода оригинального клиента. «Улучшенное» добавляет плавные переходы у берегов, "
|
||||
.. "анимированную пену у берегов и вокруг объектов, подвижные блики на волнах, отражение неба "
|
||||
@@ -2602,11 +2618,23 @@
|
||||
})
|
||||
</OnLoad></Scripts>
|
||||
</Frame>
|
||||
<Frame name="$parentRowCharacterShadows" inherits="OptionsCheckboxRowTemplate">
|
||||
<!-- MONKEY (skybox): the zone skybox switch. -->
|
||||
<Frame name="$parentRowZoneSkyboxes" inherits="OptionsCheckboxRowTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentRowVolumetricFog" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentRowVolumetricFog" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
|
||||
</Anchors>
|
||||
<Scripts><OnLoad>
|
||||
OptionsRow_OnLoad(self, "zoneSkyboxes",
|
||||
BENILLA_ADVGFX.zoneSkyboxes,
|
||||
"BENILLA_TOOLTIP_ZONE_SKYBOXES")
|
||||
</OnLoad></Scripts>
|
||||
</Frame>
|
||||
<Frame name="$parentRowCharacterShadows" inherits="OptionsCheckboxRowTemplate">
|
||||
<Anchors>
|
||||
<Anchor point="TOPLEFT" relativeTo="$parentRowZoneSkyboxes" relativePoint="BOTTOMLEFT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
|
||||
<Anchor point="TOPRIGHT" relativeTo="$parentRowZoneSkyboxes" relativePoint="BOTTOMRIGHT"><Offset><AbsDimension x="0" y="-9"/></Offset></Anchor>
|
||||
</Anchors>
|
||||
<Scripts><OnLoad>
|
||||
OptionsRow_OnLoad(self, "characterShadows",
|
||||
BENILLA_ADVGFX.characterShadows,
|
||||
|
||||
@@ -1378,6 +1378,72 @@ pub(super) const ON_DEMAND: &[Scenario] = &[
|
||||
look: LAVA_RIVER_LOOK,
|
||||
minute: 0,
|
||||
ui: None,
|
||||
}, // MONKEY (skybox): zone skyboxes (run with `WOW_ZONE_SKYBOXES=1`) and the two stock skybox
|
||||
// lanes. Karazahn40 (Turtle map 814) is the one stock sphere naming a clear-slot skybox
|
||||
// (Light 553, HellfireSkyBox); the zone shots need the sky patch.
|
||||
Scenario {
|
||||
name: "skybox-karazhan-noon",
|
||||
map: Some(814),
|
||||
eye: SKYBOX_KZ_EYE,
|
||||
look: SKYBOX_KZ_LOOK,
|
||||
minute: 720,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-karazhan-night",
|
||||
map: Some(814),
|
||||
eye: SKYBOX_KZ_EYE,
|
||||
look: SKYBOX_KZ_LOOK,
|
||||
minute: 0,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-steppes-noon",
|
||||
map: Some(MAP_AZEROTH),
|
||||
eye: SKYBOX_STEPPES_EYE,
|
||||
look: SKYBOX_STEPPES_LOOK,
|
||||
minute: 720,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-steppes-night",
|
||||
map: Some(MAP_AZEROTH),
|
||||
eye: SKYBOX_STEPPES_EYE,
|
||||
look: SKYBOX_STEPPES_LOOK,
|
||||
minute: 0,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-blasted-noon",
|
||||
map: Some(MAP_AZEROTH),
|
||||
eye: SKYBOX_BLASTED_EYE,
|
||||
look: SKYBOX_BLASTED_LOOK,
|
||||
minute: 720,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-blasted-night",
|
||||
map: Some(MAP_AZEROTH),
|
||||
eye: SKYBOX_BLASTED_EYE,
|
||||
look: SKYBOX_BLASTED_LOOK,
|
||||
minute: 0,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-hyjal-noon",
|
||||
map: Some(MAP_KALIMDOR),
|
||||
eye: SKYBOX_HYJAL_EYE,
|
||||
look: SKYBOX_HYJAL_LOOK,
|
||||
minute: 720,
|
||||
ui: None,
|
||||
},
|
||||
Scenario {
|
||||
name: "skybox-hyjal-night",
|
||||
map: Some(MAP_KALIMDOR),
|
||||
eye: SKYBOX_HYJAL_EYE,
|
||||
look: SKYBOX_HYJAL_LOOK,
|
||||
minute: 0,
|
||||
ui: None,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1482,6 +1548,17 @@ pub(crate) fn ui_opted_in() -> bool {
|
||||
std::env::var("WOW_CAPTURE_UI").as_deref() == Ok("1") || scenario_declares_ui()
|
||||
}
|
||||
|
||||
// MONKEY (skybox): the skybox shots, eye just above the ground at a sphere's centre, pitched up so
|
||||
// the upper frame is sky.
|
||||
const SKYBOX_KZ_EYE: [f32; 3] = [-6474.0, -2912.0, 40.0];
|
||||
const SKYBOX_KZ_LOOK: [f32; 3] = [-6300.0, -2800.0, 95.0];
|
||||
const SKYBOX_STEPPES_EYE: [f32; 3] = [-7979.0, -2571.0, 260.0];
|
||||
const SKYBOX_STEPPES_LOOK: [f32; 3] = [-7800.0, -2450.0, 320.0];
|
||||
const SKYBOX_BLASTED_EYE: [f32; 3] = [-11300.0, -3073.0, 30.0];
|
||||
const SKYBOX_BLASTED_LOOK: [f32; 3] = [-11120.0, -2960.0, 90.0];
|
||||
const SKYBOX_HYJAL_EYE: [f32; 3] = [4637.0, -4461.0, 1060.0];
|
||||
const SKYBOX_HYJAL_LOOK: [f32; 3] = [4800.0, -4350.0, 1120.0];
|
||||
|
||||
#[cfg(test)]
|
||||
mod ui_opt_in_tests {
|
||||
use super::*;
|
||||
|
||||
@@ -921,6 +921,12 @@ pub(crate) const REGISTERED: &[Registered] = &[
|
||||
),
|
||||
// MONKEY (volumetric fog): saved live tier; capture override stays session-only.
|
||||
ours("volumetricFog", "1", "benilla's own: near-field volumetric fog, 0 Off / 1 Low / 2 High"),
|
||||
// MONKEY (skybox): the living player's zone skybox from `LightParams`; High sets 1.
|
||||
ours(
|
||||
"zoneSkyboxes",
|
||||
"0",
|
||||
"benilla's own: draw the zone skybox LightParams names for the living, 0 Off / 1 On; the reference draws a DBC skybox only for the ghost",
|
||||
),
|
||||
ours(
|
||||
"waterQuality",
|
||||
"1",
|
||||
|
||||
@@ -105,12 +105,14 @@ pub(super) fn world_section(ui: &mut egui::Ui, world: &mut WorldReadout) {
|
||||
// 4-second crossfade (== the interior-fog blend, one number): `w 0.00` beside a name means
|
||||
// the flood published a skybox the crossfade hasn't engaged — faithful standing outside
|
||||
// the gate, not a resolve bug.
|
||||
match world.skybox.0.as_deref() {
|
||||
Some(path) => {
|
||||
// MONKEY (skybox): the heaviest layer of the weighted list, at its own weight.
|
||||
match world.skybox.primary() {
|
||||
Some(layer) => {
|
||||
let path = layer.path.as_str();
|
||||
let leaf = path.rsplit('\\').next().unwrap_or(path);
|
||||
line.push_str(&format!(
|
||||
" · skybox {leaf} w {:.2}",
|
||||
world.skybox_weight.0
|
||||
" · skybox {leaf} w {:.2} (stand-down {:.2})",
|
||||
layer.weight, world.skybox_weight.0
|
||||
));
|
||||
}
|
||||
None => line.push_str(" · sky gradient"),
|
||||
|
||||
@@ -245,6 +245,8 @@ impl PluginGroup for GamePlugins {
|
||||
.add(crate::dynamic_interior::DynamicInteriorPlugin)
|
||||
// MONKEY (volumetric fog): bridge the live setting to Bevy.
|
||||
.add(crate::volumetric_fog::VolumetricFogPlugin)
|
||||
// MONKEY (skybox): bridge the zone-skybox setting to the world lane.
|
||||
.add(crate::zone_skybox::ZoneSkyboxPlugin)
|
||||
// The realmlist (decision 1667) — the logon address the login screen edits. Same reason as
|
||||
// VideoPlugin above: it is a CVar knob, so its resource has to exist before `load_config`.
|
||||
.add(crate::realmlist::RealmlistPlugin)
|
||||
|
||||
@@ -74,6 +74,8 @@ mod doodad_events;
|
||||
/// MONKEY (dynamic interiors): the cvar → benilla-world bridge for the fixture-lit interior lane.
|
||||
// MONKEY (volumetric fog): optional near-field atmosphere plugin.
|
||||
mod volumetric_fog;
|
||||
// MONKEY (skybox): the zoneSkyboxes cvar bridge.
|
||||
mod zone_skybox;
|
||||
mod dynamic_interior;
|
||||
mod entities;
|
||||
mod fishing_line;
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
//! MONKEY (skybox): the `zoneSkyboxes` cvar's bridge to [`benilla_world::skybox::ZoneSkyboxes`].
|
||||
//! `WOW_ZONE_SKYBOXES=0|1` overrides it for the session, which is how a hermetic capture (no config
|
||||
//! file, registry defaults) turns the lane on.
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
/// The session override, read once.
|
||||
#[derive(Resource, Clone, Copy)]
|
||||
struct ZoneSkyboxOverride(Option<bool>);
|
||||
|
||||
pub(crate) struct ZoneSkyboxPlugin;
|
||||
|
||||
impl Plugin for ZoneSkyboxPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
let forced = std::env::var("WOW_ZONE_SKYBOXES")
|
||||
.ok()
|
||||
.and_then(|v| v.trim().parse::<u8>().ok())
|
||||
.map(|v| v != 0);
|
||||
app.insert_resource(ZoneSkyboxOverride(forced))
|
||||
.add_observer(on_cvar)
|
||||
.add_systems(Startup, apply_override);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_override(
|
||||
forced: Res<ZoneSkyboxOverride>,
|
||||
zone: Option<ResMut<benilla_world::skybox::ZoneSkyboxes>>,
|
||||
) {
|
||||
if let (Some(on), Some(mut zone)) = (forced.0, zone) {
|
||||
zone.set_if_neq(benilla_world::skybox::ZoneSkyboxes(on));
|
||||
}
|
||||
}
|
||||
|
||||
fn on_cvar(
|
||||
ev: On<crate::cvars::CvarChanged>,
|
||||
forced: Res<ZoneSkyboxOverride>,
|
||||
zone: Option<ResMut<benilla_world::skybox::ZoneSkyboxes>>,
|
||||
) {
|
||||
if !ev.is("zoneSkyboxes") || forced.0.is_some() {
|
||||
return;
|
||||
}
|
||||
if let Some(mut zone) = zone {
|
||||
zone.set_if_neq(benilla_world::skybox::ZoneSkyboxes(ev.flag()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user