Fix bunches of bugs and simplify map plugin.
This commit is contained in:
parent
0accbb4789
commit
03d963bed4
131
src/map.rs
131
src/map.rs
|
@ -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()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user