Fix bunches of bugs and simplify map plugin.

This commit is contained in:
Nolan Darilek 2024-08-17 11:51:46 -04:00
parent 0accbb4789
commit 03d963bed4

View File

@ -82,8 +82,7 @@ impl ITileType for Tile {
pub struct PortalBundle { pub struct PortalBundle {
pub portal: Portal, pub portal: Portal,
pub mappable: Mappable, pub mappable: Mappable,
pub transform: Transform, pub transform: TransformBundle,
pub global_transform: GlobalTransform,
} }
#[derive(Bundle, Clone, Default)] #[derive(Bundle, Clone, Default)]
@ -91,8 +90,75 @@ pub struct MapBundle<D: 'static + Clone + Default + Send + Sync> {
pub map: Map<D>, pub map: Map<D>,
pub spawn_colliders: SpawnColliders, pub spawn_colliders: SpawnColliders,
pub spawn_portals: SpawnPortals, pub spawn_portals: SpawnPortals,
pub transform: Transform, pub transform: TransformBundle,
pub global_transform: GlobalTransform, }
#[derive(Bundle, Clone, Debug)]
pub struct TileBundle {
pub transform: TransformBundle,
pub collider: Collider,
pub rigid_body: RigidBody,
pub active_collision_types: ActiveCollisionTypes,
pub map_obstruction: MapObstruction,
}
impl Default for TileBundle {
fn default() -> Self {
Self {
transform: default(),
collider: Collider::cuboid(0.5, 0.5),
rigid_body: RigidBody::Fixed,
active_collision_types: ActiveCollisionTypes::default()
| ActiveCollisionTypes::KINEMATIC_STATIC
| ActiveCollisionTypes::DYNAMIC_STATIC,
map_obstruction: MapObstruction,
}
}
}
impl TileBundle {
pub fn new(x: i32, y: i32) -> Self {
Self {
transform: Transform::from_xyz(x as f32 + 0.5, y as f32 + 0.5, 0.).into(),
..default()
}
}
}
#[derive(Bundle, Clone, Debug)]
pub struct ZoneBundle {
pub collider: Collider,
pub transform: TransformBundle,
pub area: Area,
pub zone: Zone,
pub sensor: Sensor,
pub active_events: ActiveEvents,
}
impl ZoneBundle {
fn new(collider: Collider, position: (f32, f32)) -> Self {
let point = Isometry2::new(Vector2::new(position.0, position.1), 0.);
let aabb = collider.raw.compute_aabb(&point);
Self {
collider,
area: Area(aabb),
transform: Transform::from_translation(Vec3::new(position.0, position.1, 0.)).into(),
zone: default(),
sensor: default(),
active_events: ActiveEvents::COLLISION_EVENTS,
}
}
}
impl From<&MRect> for ZoneBundle {
fn from(rect: &MRect) -> Self {
let collider = Collider::cuboid(
rect.width() as f32 / 2. + 0.5,
rect.height() as f32 / 2. + 0.5,
);
let position = (rect.center().x(), rect.center().y());
Self::new(collider, position)
}
} }
pub struct GridBuilder { pub struct GridBuilder {
@ -125,14 +191,13 @@ impl<D: Clone + Default> MapFilter<D> for GridBuilder {
if let Ok(maze) = if let Ok(maze) =
generator.generate(self.width_in_rooms as i32, self.height_in_rooms as i32) generator.generate(self.width_in_rooms as i32, self.height_in_rooms as i32)
{ {
let total_height = (self.room_height + 1) * self.height_in_rooms + 1; let total_height = self.room_height * self.height_in_rooms + self.height_in_rooms + 1;
let half_width = self.room_width / 2; let half_width = self.room_width / 2;
let half_height = self.room_height / 2; let half_height = self.room_height / 2;
for y in 0..self.height_in_rooms { for y in 0..self.height_in_rooms {
for x in 0..self.width_in_rooms { for x in 0..self.width_in_rooms {
let x_offset = x * (self.room_width + 1); let x_offset = x * (self.room_width + 1);
let y_offset = let y_offset = total_height - (y + 1) * (self.room_height + 1) - 1;
total_height - (y * (self.room_height + 1)) - self.room_height - 2;
let room = MRect::new_i32( let room = MRect::new_i32(
x_offset as i32 + 1, x_offset as i32 + 1,
y_offset as i32 + 1, y_offset as i32 + 1,
@ -190,21 +255,7 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
for x in 0..map.width { for x in 0..map.width {
if let Some(tile) = map.at(x, y) { if let Some(tile) = map.at(x, y) {
if tile.blocks_motion() { if tile.blocks_motion() {
let id = commands let id = commands.spawn(TileBundle::new(x as i32, y as i32)).id();
.spawn((
RigidBody::Fixed,
TransformBundle::from_transform(Transform::from_xyz(
x as f32 + 0.5,
y as f32 + 0.5,
0.,
)),
Collider::cuboid(0.5, 0.5),
ActiveCollisionTypes::default()
| ActiveCollisionTypes::KINEMATIC_STATIC
| ActiveCollisionTypes::DYNAMIC_STATIC,
MapObstruction,
))
.id();
if tile.blocks_visibility() { if tile.blocks_visibility() {
commands.entity(id).insert(Visible::opaque()); commands.entity(id).insert(Visible::opaque());
} }
@ -214,26 +265,8 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
} }
} }
for room in &map.rooms { for room in &map.rooms {
let shape = Collider::cuboid(
(room.width() / 2) as f32 + 0.5,
(room.height() / 2) as f32 + 0.5,
);
let position =
Isometry2::new(Vector2::new(room.center().x(), room.center().y()), 0.);
let aabb = shape.raw.compute_aabb(&position);
commands.entity(map_entity).with_children(|parent| { commands.entity(map_entity).with_children(|parent| {
parent.spawn(( parent.spawn(ZoneBundle::from(room));
TransformBundle::from_transform(Transform::from_xyz(
position.translation.x,
position.translation.y,
0.,
)),
shape,
Sensor,
ActiveEvents::COLLISION_EVENTS,
Area(aabb),
Zone,
));
}); });
} }
} }
@ -248,21 +281,19 @@ fn spawn_portals<D: 'static + Clone + Default + Send + Sync>(
if **spawn_portals { if **spawn_portals {
commands.entity(map_entity).remove::<SpawnPortals>(); commands.entity(map_entity).remove::<SpawnPortals>();
let mut portals: Vec<(f32, f32)> = vec![]; let mut portals: Vec<(f32, f32)> = vec![];
for x in 1..map.width { for x in 0..map.width {
for y in 1..map.height { for y in 0..map.height {
let mut spawn_portal = false;
if map.get_available_exits(x, y).len() > 2 {
let idx = (x, y).to_index(map.width); let idx = (x, y).to_index(map.width);
if map.tiles[idx].is_walkable() let mut spawn_portal = false;
&& (x > 1 && map.tiles[idx - 1].is_walkable()) if map.get_available_exits(x, y).len() > 2 && map.tiles[idx].is_walkable() {
if (x > 1 && map.tiles[idx - 1].is_walkable())
&& (x < map.width - 2 && map.tiles[idx + 1].is_walkable()) && (x < map.width - 2 && map.tiles[idx + 1].is_walkable())
&& (y > 1 && map.tiles[idx - map.width].is_blocked()) && (y > 1 && map.tiles[idx - map.width].is_blocked())
&& (y < map.height - 2 && map.tiles[idx + map.width].is_blocked()) && (y < map.height - 2 && map.tiles[idx + map.width].is_blocked())
{ {
spawn_portal = true; spawn_portal = true;
} }
if map.tiles[idx].is_walkable() if (x > 1 && map.tiles[idx - 1].is_blocked())
&& (x > 1 && map.tiles[idx - 1].is_blocked())
&& (x < map.width - 2 && map.tiles[idx + 1].is_blocked()) && (x < map.width - 2 && map.tiles[idx + 1].is_blocked())
&& (y > 1 && map.tiles[idx - map.width].is_walkable()) && (y > 1 && map.tiles[idx - map.width].is_walkable())
&& (y < map.height - 2 && map.tiles[idx + map.width].is_walkable()) && (y < map.height - 2 && map.tiles[idx + map.width].is_walkable())
@ -282,7 +313,7 @@ fn spawn_portals<D: 'static + Clone + Default + Send + Sync>(
for (x, y) in portals { for (x, y) in portals {
commands.entity(map_entity).with_children(|parent| { commands.entity(map_entity).with_children(|parent| {
parent.spawn(PortalBundle { parent.spawn(PortalBundle {
transform: Transform::from_translation(Vec3::new(x, y, 0.)), transform: Transform::from_translation(Vec3::new(x, y, 0.)).into(),
..default() ..default()
}); });
}); });