fix: correct boundary z-marking and tileset_index swap in recolor
Boundary: mark all z-levels where z_diff changed, not just 4 boundary indices. For multi-step scrolls, every z-level between min(old,new)-8 and max(old,new) inclusive needs recoloring. Also fixes last_z_change_dirty_count to use actual new_keys.len(). Recolor: update tileset_index alongside color so sky tile switch at t>=0.98 actually renders the sky texture, not sky-coloured grass. Cleanup: removed solid_bits (was unused after recolor fix).
This commit is contained in:
@@ -39,7 +39,6 @@ impl Default for TilemapChunkRegistry {
|
|||||||
|
|
||||||
#[derive(Resource, Default)]
|
#[derive(Resource, Default)]
|
||||||
pub struct TilemapChunkStates {
|
pub struct TilemapChunkStates {
|
||||||
pub solid_bits: HashMap<ChunkLayerKey, u64>,
|
|
||||||
pub underground_bits: HashMap<ChunkLayerKey, u64>,
|
pub underground_bits: HashMap<ChunkLayerKey, u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,17 +202,18 @@ fn populate_chunk_tiles(
|
|||||||
fn recolor_chunk_for_depth(
|
fn recolor_chunk_for_depth(
|
||||||
tile_data: &mut TilemapChunkTileData,
|
tile_data: &mut TilemapChunkTileData,
|
||||||
z_diff: i32,
|
z_diff: i32,
|
||||||
solid_bits: u64,
|
|
||||||
underground_bits: u64,
|
underground_bits: u64,
|
||||||
) {
|
) {
|
||||||
for (i, slot) in tile_data.0.iter_mut().enumerate() {
|
for (i, slot) in tile_data.0.iter_mut().enumerate() {
|
||||||
let Some(td) = slot else { continue };
|
let Some(td) = slot else { continue };
|
||||||
let is_underground = (underground_bits >> i) & 1 == 1;
|
let is_underground = (underground_bits >> i) & 1 == 1;
|
||||||
td.color = if is_underground {
|
if is_underground {
|
||||||
Color::BLACK
|
td.color = Color::BLACK;
|
||||||
} else {
|
} else {
|
||||||
tile_fade_color(td.tileset_index, z_diff)
|
let recomputed = tile_for_depth(td.tileset_index, z_diff);
|
||||||
};
|
td.tileset_index = recomputed.tileset_index;
|
||||||
|
td.color = recomputed.color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,7 +250,6 @@ pub fn spawn_tilemap_chunks(
|
|||||||
registry.entities.clear();
|
registry.entities.clear();
|
||||||
registry.dirty_keys.clear();
|
registry.dirty_keys.clear();
|
||||||
registry.z_change_keys.clear();
|
registry.z_change_keys.clear();
|
||||||
states.solid_bits.clear();
|
|
||||||
states.underground_bits.clear();
|
states.underground_bits.clear();
|
||||||
spawner.started = true;
|
spawner.started = true;
|
||||||
}
|
}
|
||||||
@@ -269,8 +268,6 @@ pub fn spawn_tilemap_chunks(
|
|||||||
|
|
||||||
let (tile_data, underground_bits) = if key.layer == LAYER_FLOOR {
|
let (tile_data, underground_bits) = if key.layer == LAYER_FLOOR {
|
||||||
let (tiles, ub) = populate_chunk_tiles(&tilemap, key.chunk_pos, key.z_index, camera_z);
|
let (tiles, ub) = populate_chunk_tiles(&tilemap, key.chunk_pos, key.z_index, camera_z);
|
||||||
let solid_bits = compute_solid_bits(&tiles);
|
|
||||||
states.solid_bits.insert(key, solid_bits);
|
|
||||||
states.underground_bits.insert(key, ub);
|
states.underground_bits.insert(key, ub);
|
||||||
(tiles, ub)
|
(tiles, ub)
|
||||||
} else {
|
} else {
|
||||||
@@ -317,18 +314,6 @@ pub fn spawn_tilemap_chunks(
|
|||||||
bench.populate_ms += now.elapsed().as_secs_f64() * 1000.0;
|
bench.populate_ms += now.elapsed().as_secs_f64() * 1000.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_solid_bits(tiles: &[Option<TileData>]) -> u64 {
|
|
||||||
let mut bits: u64 = 0;
|
|
||||||
for (i, slot) in tiles.iter().enumerate() {
|
|
||||||
if let Some(td) = slot {
|
|
||||||
if td.tileset_index != 0 {
|
|
||||||
bits |= 1u64 << i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bits
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_tilemap_chunk_visibility(
|
pub fn update_tilemap_chunk_visibility(
|
||||||
z_index: Res<ZIndex>,
|
z_index: Res<ZIndex>,
|
||||||
mut query: Query<(&ChunkLayerKey, &mut Visibility)>,
|
mut query: Query<(&ChunkLayerKey, &mut Visibility)>,
|
||||||
@@ -390,9 +375,8 @@ pub fn populate_tilemap_chunk_data(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let solid_bits = states.solid_bits.get(&key).copied().unwrap_or(0);
|
|
||||||
let underground_bits = states.underground_bits.get(&key).copied().unwrap_or(0);
|
let underground_bits = states.underground_bits.get(&key).copied().unwrap_or(0);
|
||||||
recolor_chunk_for_depth(&mut tile_data, z_diff, solid_bits, underground_bits);
|
recolor_chunk_for_depth(&mut tile_data, z_diff, underground_bits);
|
||||||
processed += 1;
|
processed += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,8 +416,6 @@ pub fn populate_tilemap_chunk_data(
|
|||||||
|
|
||||||
let (new_tiles, underground_bits) =
|
let (new_tiles, underground_bits) =
|
||||||
populate_chunk_tiles(&tilemap, key.chunk_pos, key.z_index, camera_z);
|
populate_chunk_tiles(&tilemap, key.chunk_pos, key.z_index, camera_z);
|
||||||
let solid_bits = compute_solid_bits(&new_tiles);
|
|
||||||
states.solid_bits.insert(key, solid_bits);
|
|
||||||
states.underground_bits.insert(key, underground_bits);
|
states.underground_bits.insert(key, underground_bits);
|
||||||
tile_data.0 = new_tiles;
|
tile_data.0 = new_tiles;
|
||||||
processed += 1;
|
processed += 1;
|
||||||
@@ -465,37 +447,28 @@ pub fn on_camera_z_changed(
|
|||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
|
||||||
let old_entered_idx = (old_camera_z as f32 + Z_BELOW) as usize;
|
let z_min = (new_camera_z.min(old_camera_z) - 8).max(0);
|
||||||
let old_exited_idx = ((old_camera_z - 8) as f32 + Z_BELOW) as usize;
|
let z_max = new_camera_z.max(old_camera_z);
|
||||||
let new_entered_idx = (new_camera_z as f32 + Z_BELOW) as usize;
|
|
||||||
let new_exited_idx = ((new_camera_z - 8) as f32 + Z_BELOW) as usize;
|
|
||||||
|
|
||||||
let mut count = 0;
|
|
||||||
|
|
||||||
let mut new_keys: Vec<ChunkLayerKey> = Vec::new();
|
let mut new_keys: Vec<ChunkLayerKey> = Vec::new();
|
||||||
|
|
||||||
for key in registry.entities.keys() {
|
for key in registry.entities.keys() {
|
||||||
if key.z_index == old_entered_idx
|
let tile_z = camera_z_for_z_index(key.z_index);
|
||||||
|| key.z_index == new_entered_idx
|
if tile_z >= z_min && tile_z <= z_max {
|
||||||
|| key.z_index == old_exited_idx
|
|
||||||
|| key.z_index == new_exited_idx
|
|
||||||
{
|
|
||||||
new_keys.push(*key);
|
new_keys.push(*key);
|
||||||
count += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bench.last_z_change_dirty_ms = now.elapsed().as_secs_f64() * 1000.0;
|
||||||
|
bench.last_z_change_dirty_count = new_keys.len();
|
||||||
|
|
||||||
if !new_keys.is_empty() {
|
if !new_keys.is_empty() {
|
||||||
registry.z_change_keys.clear();
|
registry.z_change_keys.clear();
|
||||||
for key in new_keys {
|
for key in new_keys {
|
||||||
registry.z_change_keys.insert(key);
|
registry.z_change_keys.insert(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bench.last_z_change_dirty_ms = now.elapsed().as_secs_f64() * 1000.0;
|
|
||||||
bench.last_z_change_dirty_count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn despawn_tilemap_chunks(
|
pub fn despawn_tilemap_chunks(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
chunk_map: Res<super::super::chunks::ChunkMap>,
|
chunk_map: Res<super::super::chunks::ChunkMap>,
|
||||||
@@ -511,7 +484,6 @@ pub fn despawn_tilemap_chunks(
|
|||||||
registry.entities.remove(key);
|
registry.entities.remove(key);
|
||||||
registry.dirty_keys.remove(key);
|
registry.dirty_keys.remove(key);
|
||||||
registry.z_change_keys.remove(key);
|
registry.z_change_keys.remove(key);
|
||||||
states.solid_bits.remove(key);
|
|
||||||
states.underground_bits.remove(key);
|
states.underground_bits.remove(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user