use crate::item::Item; use crate::game; use bevy::prelude::*; #[derive(Component)] #[require(Sprite)] pub struct Tile { pub id: u32, pub opaque: bool, } impl Default for Tile { fn default() -> Self { Self { id: 1, opaque: true, } } } #[derive(Component)] #[require(Tile)] pub struct FloorTile { pub walkable: bool, pub astar_weight: u8, } impl Default for FloorTile { fn default() -> Self { Self { walkable: true, astar_weight: 1, } } } #[derive(Component)] pub struct WallTile { pub tile: Tile, pub solid: bool, pub embrasure: bool, // Arrowslit, crenelle, grate, cage etc } #[derive(Component)] #[require(Tile)] pub struct HasWater { pub height : u8, pub astarmultiplier: f32, pub swimmable: bool, } #[derive(Component)] pub struct DoorTile { pub tile: Tile, pub open: bool, pub locked: bool, } #[derive(Resource, Default)] pub struct CameraMoved(pub bool); // Modify camera_z_movement pub fn camera_z_movement( keyboard_input: Res>, mut z_index: ResMut, mut camera_moved: ResMut, ) { camera_moved.0 = false; if keyboard_input.pressed(KeyCode::ShiftLeft) { z_index.0 -= 1.0; z_index.0 = z_index.0.clamp(-39.0, 5.0); camera_moved.0 = true; } if keyboard_input.pressed(KeyCode::ShiftRight) { z_index.0 += 1.0; z_index.0 = z_index.0.clamp(-39.0, 5.0); camera_moved.0 = true; } } pub fn tile_sprite_occlusion( mut query: Query<(&mut Visibility, &Transform, &Tile), With>, tile_query: Query<(&Transform, &Tile)>, z_index: ResMut, ) { use std::collections::HashMap; // Build spatial lookup let tile_map: HashMap<(i32, i32, i32), &Tile> = tile_query .iter() .map(|(transform, tile)| { ( ( transform.translation.x.round() as i32, transform.translation.y.round() as i32, transform.translation.z.round() as i32, ), tile, ) }) .collect(); query .par_iter_mut() .for_each(|(mut visibility, transform, _)| { *visibility = Visibility::Hidden; // Early exit for above camera layer if transform.translation.z > z_index.0 { return; } let pos = ( transform.translation.x.round() as i32, transform.translation.y.round() as i32, transform.translation.z.round() as i32, ); // Check for any opaque tiles above the current tile for z_offset in 1..=100 { // Adjust the max height of the check if needed let above_pos = (pos.0, pos.1, pos.2 + z_offset); // look up until camera height if above_pos.2 <= z_index.0 as i32 { // get any tiles if let Some(neighbor_tile) = tile_map.get(&above_pos) { // If there's an opaque tile above, hide the current tile if neighbor_tile.opaque { return; // No need to check further; the tile should remain hidden } } } } // Check all neighbors around the tile for x_offset in -1..=1 { for y_offset in -1..=1 { for z_offset in -1..=1 { if x_offset == 0 && y_offset == 0 && z_offset == 0 { continue; } let neighbor_pos = (pos.0 + x_offset, pos.1 + y_offset, pos.2 + z_offset); if let Some(neighbor_tile) = tile_map.get(&neighbor_pos) { // id == 0 is sky if neighbor_tile.id == 0 { *visibility = Visibility::Visible; break; } } } } } }); } pub fn tile_item_sprite_update( time: Res