use bevy::prelude::*;
use crate::appearances::*;
use crate::bevy_ryot::map::MapTiles;
use crate::bevy_ryot::*;
use crate::position::TilePosition;
pub struct TileFlagPlugin<C: AppearanceAssets>(PhantomData<C>);
impl<C: AppearanceAssets> Default for TileFlagPlugin<C> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<C: AppearanceAssets> Plugin for TileFlagPlugin<C> {
fn build(&self, app: &mut App) {
app.init_resource::<Cache<TilePosition, TileFlags>>()
.add_systems(
Update,
update_tile_flag_cache::<C>.in_set(CacheSystems::UpdateCache),
);
}
}
#[derive(Debug, Clone, Component, Copy, Eq, PartialEq, Reflect)]
pub struct TileFlags {
pub walkable: bool,
pub blocks_sight: bool,
}
impl Default for TileFlags {
fn default() -> Self {
TileFlags {
walkable: true,
blocks_sight: false,
}
}
}
impl TileFlags {
pub fn for_appearance_flags(self, flags: Flags) -> Self {
TileFlags {
walkable: self.walkable && !is_true(flags.is_not_walkable),
blocks_sight: self.blocks_sight || is_true(flags.blocks_sight),
}
}
}
pub fn update_tile_flag_cache<C: AppearanceAssets>(
appearance_assets: Res<C>,
map_tiles: Res<MapTiles<Entity>>,
mut cache: ResMut<Cache<TilePosition, TileFlags>>,
q_updated_entities: Query<
&TilePosition,
Or<(
Changed<GameObjectId>,
Changed<Visibility>,
Changed<TilePosition>,
)>,
>,
q_object_and_visibility: Query<(&GameObjectId, Option<&Visibility>)>,
) {
let appearances = appearance_assets.prepared_appearances();
for pos in q_updated_entities.iter() {
let Some(tile) = map_tiles.get(pos) else {
continue;
};
cache.insert(
*pos,
tile.into_iter()
.fold(TileFlags::default(), |flags, (_, entity)| {
let Ok((object_id, visibility)) = q_object_and_visibility.get(entity) else {
return flags;
};
if visibility == Some(&Visibility::Hidden) {
return flags;
}
let appearance_flags = || -> Option<Flags> {
let (group, id) = object_id.as_group_and_id()?;
let appearance = appearances.get_for_group(group, id).cloned()?;
appearance.flags
};
let Some(appearance_flags) = appearance_flags() else {
return flags;
};
flags.for_appearance_flags(appearance_flags)
}),
);
}
}