mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 02:56:17 -10:00
feat(mods): adjust computed world fog color
Co-Authored-By: Codex <[email protected]>
This commit is contained in:
1 parent
885e287a2e
commit
e0d42f6719
4 files changed
+93
No files matched your search
@@ -1331,6 +1331,17 @@ impl Game<'_> {
|
||||
pub(super) fn native_zoom(&self, zoom: &mut Option<NativeZoom>) {
|
||||
let _ = zoom;
|
||||
}
|
||||
/// Computed world fog RGB, after ordinary effects and before upload. Title panoramas skip it.
|
||||
/// Only finite RGB components in 0..=1 are accepted; alpha and distances stay unchanged.
|
||||
pub(super) fn native_compute_fog_color(
|
||||
&self,
|
||||
partial: f32,
|
||||
camera: [f64; 3],
|
||||
fog_type: horizon_client::fog::FogType,
|
||||
rgb: &mut [f32; 3],
|
||||
) {
|
||||
let _ = (partial, camera, fog_type, rgb);
|
||||
}
|
||||
/// The camera shake native mods ask for in this frame, `partial` ticks
|
||||
/// past the last tick (0 to 1): add your pitch, yaw and roll in degrees
|
||||
/// and your offset in blocks, along the camera's right, up and back, to
|
||||
|
||||
@@ -140,8 +140,27 @@ impl Game<'_> {
|
||||
if !self.settings.horizon.fog {
|
||||
horizon_client::fog::clear_distance_fog(&mut fog, &input);
|
||||
}
|
||||
if self.title.is_none() {
|
||||
fog.color =
|
||||
self.native_fog_color_now(self.clock.fraction() as f32, at, fog_type, fog.color);
|
||||
}
|
||||
fog
|
||||
}
|
||||
fn native_fog_color_now(
|
||||
&self,
|
||||
partial: f32,
|
||||
camera: [f64; 3],
|
||||
fog_type: FogType,
|
||||
color: [f32; 4],
|
||||
) -> [f32; 4] {
|
||||
let mut rgb = [color[0], color[1], color[2]];
|
||||
self.native_compute_fog_color(partial, camera, fog_type, &mut rgb);
|
||||
if rgb.iter().all(|v| v.is_finite() && (0.0..=1.0).contains(v)) {
|
||||
[rgb[0], rgb[1], rgb[2], color[3]]
|
||||
} else {
|
||||
color
|
||||
}
|
||||
}
|
||||
/// `FogRenderer.computeFogColor`'s night vision brightenFactor:
|
||||
/// `GameRenderer.nightVisionScale`, but not while Darkness is on.
|
||||
fn fog_night_vision(&self) -> f32 {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
"""Run the actual fog color dispatch with a fake mod, without a GPU/window."""
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from test_world_input_capture import method
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class ComputeFogColorHookTests(unittest.TestCase):
|
||||
@unittest.skipUnless(shutil.which("rustc"), "requires Rust")
|
||||
def test_rgb_override_fallback_and_alpha(self):
|
||||
source = (ROOT / "crates/horizon-client/src/game/render_tick.rs").read_text(encoding="utf-8")
|
||||
actual = method(source, "native_fog_color_now")
|
||||
frame = method(source.replace("pub(super) fn", "fn"), "frame_fog")
|
||||
self.assertIn("if self.title.is_none() { fog.color = self.native_fog_color_now", " ".join(frame.split()))
|
||||
fixture = r"""
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum FogType { Atmospheric, Water, Lava, PowderSnow }
|
||||
struct Game { replacement: Option<[f32; 3]> }
|
||||
impl Game {
|
||||
fn native_compute_fog_color(&self, partial: f32, camera: [f64; 3],
|
||||
_kind: FogType, rgb: &mut [f32; 3]) {
|
||||
assert_eq!((partial, camera, *rgb), (0.25, [1.0, 2.0, 3.0], [0.2, 0.4, 0.6]));
|
||||
if let Some(value) = self.replacement { *rgb = value; }
|
||||
}
|
||||
METHOD
|
||||
}
|
||||
#[test]
|
||||
fn all_environments_valid_invalid_and_unchanged() {
|
||||
let original = [0.2, 0.4, 0.6, 0.75];
|
||||
for kind in [FogType::Atmospheric, FogType::Water, FogType::Lava, FogType::PowderSnow] {
|
||||
for (replacement, expected) in [(None, original),
|
||||
(Some([0.0, 1.0, 0.5]), [0.0, 1.0, 0.5, 0.75]),
|
||||
(Some([f32::NAN, 0.0, 0.0]), original),
|
||||
(Some([0.0, f32::INFINITY, 0.0]), original),
|
||||
(Some([0.0, 0.0, -0.1]), original),
|
||||
(Some([1.1, 0.0, 0.0]), original)] {
|
||||
assert_eq!(Game { replacement }.native_fog_color_now(0.25, [1.0, 2.0, 3.0], kind, original), expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
""".replace("METHOD", actual)
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
src, exe = Path(folder) / "fog.rs", Path(folder) / "fog.exe"
|
||||
src.write_text(fixture, encoding="utf-8")
|
||||
subprocess.run(["rustc", "--edition=2024", "--test", str(src), "-o", str(exe)], check=True)
|
||||
subprocess.run([str(exe)], check=True)
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"name": "compute_fog_color",
|
||||
"target": "horizon_client::game::native_hooks::Game<'_>::native_compute_fog_color",
|
||||
"neoforge": "ViewportEvent.ComputeFogColor",
|
||||
"side": "client"
|
||||
}
|
||||
],
|
||||
"rust_summary": "a computed fog color hook (`native_compute_fog_color`).",
|
||||
"doc_summary": "`native_compute_fog_color(partial, camera, fog_type, rgb)` adjusts the final world fog RGB after normal biome, weather and effect calculation and before GPU upload. Camera is its world position; fog_type distinguishes atmosphere, water, lava and powder snow. Only finite components in 0..=1 are accepted; invalid requests retain the original RGB. Alpha and all distance fields are unchanged. Title panoramas skip this hook. Bundles need \"hooks\": @API:compute_fog_color@."
|
||||
}
|
||||
Reference in new issue
Block a user