Critical fixes: - fog_state: guard _compute_bounds() against all-invalid tiles (negative Rect2i crash) - fog_shader: read Camera2D zoom dynamically instead of hardcoded Vector2(2,2) - world_radial: set custom_minimum_size in _ready() from spoke geometry Warnings: - fog.gdshader: tighten PERIPHERAL_LOW 0.15→0.55 to match D-059 peripheral band - Extract color_for_entity_kind() to Constants.gd, decouple CursorRenderer from EntityRenderer Documentation: shallow copy assumption, gradual decay TODO, tween guard rationale, fade timing rationale, ToggleInsert TODO, monologue consume-once, hover offset safety, v6 fixture gap TODO. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
62 lines
2.2 KiB
GDScript
62 lines
2.2 KiB
GDScript
extends Node2D
|
|
|
|
## Fog overlay controller — manages ColorRect + shader uniforms for D-059 fog.
|
|
## Reads textures from FogState autoload, positions rect to cover viewport.
|
|
## Architecture: docs/architecture/fog-shader-spec.md
|
|
|
|
var _fog_rect: ColorRect
|
|
var _shader_mat: ShaderMaterial
|
|
|
|
const TILE_SIZE := float(Constants.TILE_SIZE)
|
|
|
|
|
|
func _ready() -> void:
|
|
# Create the fog overlay ColorRect
|
|
_fog_rect = ColorRect.new()
|
|
_fog_rect.name = "FogRect"
|
|
add_child(_fog_rect)
|
|
|
|
# Load shader and create material
|
|
var shader := load("res://shaders/fog.gdshader") as Shader
|
|
_shader_mat = ShaderMaterial.new()
|
|
_shader_mat.shader = shader
|
|
_fog_rect.material = _shader_mat
|
|
|
|
# Create seamless noise texture for fog animation
|
|
var noise := FastNoiseLite.new()
|
|
noise.noise_type = FastNoiseLite.TYPE_PERLIN
|
|
noise.frequency = 0.03
|
|
var noise_tex := NoiseTexture2D.new()
|
|
noise_tex.noise = noise
|
|
noise_tex.width = 256
|
|
noise_tex.height = 256
|
|
noise_tex.seamless = true
|
|
_shader_mat.set_shader_parameter("noise_tex", noise_tex)
|
|
_shader_mat.set_shader_parameter("tile_size", TILE_SIZE)
|
|
|
|
print("FogShader: Initialized (D-059 5-layer)")
|
|
|
|
|
|
func update_fog() -> void:
|
|
# 1. Update FogState textures from GameState
|
|
FogState.update_from_state()
|
|
|
|
# 2. Position ColorRect to cover the current viewport
|
|
var vp_size := get_viewport().get_visible_rect().size
|
|
var cam := get_viewport().get_camera_2d()
|
|
var zoom := cam.zoom if cam else Vector2(2.0, 2.0)
|
|
var camera_pos := GameState.player_position * TILE_SIZE
|
|
var half_view := vp_size / (2.0 * zoom)
|
|
_fog_rect.position = camera_pos - half_view
|
|
_fog_rect.size = vp_size / zoom
|
|
|
|
# 3. Update shader uniforms
|
|
_shader_mat.set_shader_parameter("visibility_tex", FogState.visibility_texture)
|
|
_shader_mat.set_shader_parameter("exploration_tex", FogState.exploration_texture)
|
|
_shader_mat.set_shader_parameter("zone_tint_tex", FogState.zone_tint_texture)
|
|
_shader_mat.set_shader_parameter("rect_pos", _fog_rect.position)
|
|
_shader_mat.set_shader_parameter("rect_sz", _fog_rect.size)
|
|
_shader_mat.set_shader_parameter("map_offset", Vector2(FogState.map_bounds.position))
|
|
_shader_mat.set_shader_parameter("map_size", Vector2(FogState.map_bounds.size))
|
|
_shader_mat.set_shader_parameter("time", Time.get_ticks_msec() / 1000.0)
|