Files
dorf/src/world/tiles/tilemap.rs
T
2025-09-14 18:48:50 +01:00

99 lines
3.2 KiB
Rust

use bevy::prelude::*;
use bevy_platform::collections::hash_map::HashMap;
use crate::{entities::item::Item, game};
#[derive(Resource, Default, Clone)]
pub struct TileMap {
pub floor_tiles: HashMap<IVec3, (i32, bool, bool, bool, i32, [u32; 8])>, //id, canStandIn, canStandOn, visiblyTransparent, astar_weight, visible_range
pub fixture_tiles: HashMap<IVec3, (i32, bool, bool, [u32; 8])>, // id, canStandIn, canStandOn, visible_range
pub item_tiles: HashMap<IVec3, Vec<u32>>, // Entity.id's of items on this tile
}
#[derive(Resource)]
pub struct ItemRotationTimer {
timer: Timer,
current_indices: HashMap<IVec3, usize>,
}
impl Default for ItemRotationTimer {
fn default() -> Self {
Self {
timer: Timer::from_seconds(0.4f32, TimerMode::Repeating),
current_indices: HashMap::default(),
}
}
}
pub fn item_tile_management_system(
time: Res<Time>,
mut tilemap: ResMut<TileMap>,
mut rotation_timer: ResMut<ItemRotationTimer>,
z_index: Res<game::ZIndex>,
mut visibility_query: Query<&mut Visibility, With<Item>>,
) {
println!(
"{} items accross {} tiles",
visibility_query.iter().count(),
tilemap.item_tiles.len()
);
rotation_timer.timer.tick(time.delta());
let mut tiles_to_remove = Vec::new();
let mut tiles_with_items = Vec::new();
for (position, items) in tilemap.item_tiles.iter() {
if items.is_empty() {
tiles_to_remove.push(*position);
} else {
tiles_with_items.push((*position, items.clone()));
}
}
for position in tiles_to_remove {
tilemap.item_tiles.remove(&position);
rotation_timer.current_indices.remove(&position);
}
if rotation_timer.timer.just_finished() {
for (position, items) in tiles_with_items {
if position.z > z_index.0 as i32 {
continue;
}
if items.len() <= 1 {
if let Some(&entity_id) = items.first() {
let entity = Entity::from_raw(entity_id);
if let Ok(mut visibility) = visibility_query.get_mut(entity) {
*visibility = Visibility::Visible;
}
}
continue;
}
let current_index = rotation_timer
.current_indices
.get(&position)
.copied()
.unwrap_or(0);
if let Some(&current_entity_id) = items.get(current_index) {
let current_entity = Entity::from_raw(current_entity_id);
if let Ok(mut visibility) = visibility_query.get_mut(current_entity) {
*visibility = Visibility::Hidden;
}
}
let next_index = (current_index + 1) % items.len();
if let Some(&next_entity_id) = items.get(next_index) {
let next_entity = Entity::from_raw(next_entity_id);
if let Ok(mut visibility) = visibility_query.get_mut(next_entity) {
*visibility = Visibility::Visible;
}
}
rotation_timer.current_indices.insert(position, next_index);
}
}
}