use crate::app_state::overworld::tilemap::systems::TilemapCollider;
use crate::core::collision::Rect2DCollider;
use bevy::prelude::*;
use bevy_ecs_tiled::prelude::{TiledMap, TiledMapAsset, tiled};
#[derive(Component)]
pub struct ObjectCollider;
#[allow(dead_code)]
pub fn process_map_object_properties_system(
mut commands: Commands,
tiled_map_assets: Res<Assets<TiledMapAsset>>,
tiled_maps_query: Query<&TiledMap>,
existing_colliders: Query<&ObjectCollider>,
) {
let map_count = tiled_maps_query.iter().count();
let collider_count = existing_colliders.iter().count();
trace!(
"Object properties system running: {} maps, {} existing colliders",
map_count, collider_count
);
if !existing_colliders.is_empty() {
trace!("Object colliders already exist, skipping");
return;
}
for tiled_map_handle in tiled_maps_query.iter() {
trace!("Processing tiled map handle");
if let Some(tiled_map_asset) = tiled_map_assets.get(&tiled_map_handle.0) {
trace!("Found tiled map asset");
let tile_size = tiled_map_asset.map.tile_width as f32;
let tile_height = tiled_map_asset.map.tile_height as f32;
let map_width = tiled_map_asset.map.width as f32 * tile_size;
let map_height = tiled_map_asset.map.height as f32 * tile_height;
let center_offset_x = -map_width / 2.0;
let center_offset_y = -map_height / 2.0;
for layer in tiled_map_asset.map.layers() {
trace!("Processing layer: {}", layer.name);
if let Some(object_layer) = layer.as_object_layer() {
trace!(
"Processing object layer '{}' with {} objects",
layer.name,
object_layer.objects().count()
);
for object_data in object_layer.objects() {
trace!(
"Checking object '{}' at ({}, {}) with shape {:?}",
object_data.name, object_data.x, object_data.y, object_data.shape
);
if let Some(collision_value) = object_data.properties.get("collision") {
trace!("Found collision property: {:?}", collision_value);
if let tiled::PropertyValue::BoolValue(true) = collision_value {
trace!(
"Found collision object '{}' with collision=true",
object_data.name
);
if let tiled::ObjectShape::Rect { width, height } =
object_data.shape
{
let world_x = center_offset_x + object_data.x + width / 2.0;
let world_y = center_offset_y
+ (tiled_map_asset.map.height as f32 * tile_height
- object_data.y
- height / 2.0);
let size = Vec2::new(width, height);
trace!(
"Creating collision object '{}' at world pos ({}, {}) with size ({}, {})",
object_data.name, world_x, world_y, width, height
);
commands.spawn((
ObjectCollider,
TilemapCollider,
Rect2DCollider::new(size, Vec2::ZERO),
Transform::from_xyz(world_x, world_y, 0.0),
Visibility::Hidden, Name::new(format!("ObjectCollision_{}", object_data.name)),
));
} else {
trace!("Object '{}' is not a rectangle", object_data.name);
}
}
} else {
trace!("Object '{}' has no collision property", object_data.name);
}
}
} else {
trace!("Layer '{}' is not an object layer", layer.name);
}
}
break; } else {
trace!("Could not get tiled map asset");
}
}
}