Allow collider/portal spawning to be run separately.
This commit is contained in:
parent
e705451020
commit
3de4b69030
153
src/map.rs
153
src/map.rs
|
@ -34,6 +34,26 @@ pub struct MapObstruction;
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct Portal;
|
pub struct Portal;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deref, DerefMut, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct SpawnColliders(pub bool);
|
||||||
|
|
||||||
|
impl Default for SpawnColliders {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deref, DerefMut, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct SpawnPortals(pub bool);
|
||||||
|
|
||||||
|
impl Default for SpawnPortals {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait ITileType {
|
pub trait ITileType {
|
||||||
fn blocks_motion(&self) -> bool;
|
fn blocks_motion(&self) -> bool;
|
||||||
fn blocks_visibility(&self) -> bool;
|
fn blocks_visibility(&self) -> bool;
|
||||||
|
@ -51,7 +71,6 @@ impl ITileType for Tile {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MapConfig {
|
pub struct MapConfig {
|
||||||
pub autospawn_portals: bool,
|
|
||||||
pub describe_undescribed_areas: bool,
|
pub describe_undescribed_areas: bool,
|
||||||
pub speak_area_descriptions: bool,
|
pub speak_area_descriptions: bool,
|
||||||
pub start_revealed: bool,
|
pub start_revealed: bool,
|
||||||
|
@ -60,7 +79,6 @@ pub struct MapConfig {
|
||||||
impl Default for MapConfig {
|
impl Default for MapConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
autospawn_portals: true,
|
|
||||||
describe_undescribed_areas: false,
|
describe_undescribed_areas: false,
|
||||||
speak_area_descriptions: true,
|
speak_area_descriptions: true,
|
||||||
start_revealed: false,
|
start_revealed: false,
|
||||||
|
@ -94,6 +112,8 @@ impl Default for PortalBundle {
|
||||||
#[derive(Bundle, Clone, Default)]
|
#[derive(Bundle, Clone, Default)]
|
||||||
pub struct MapBundle {
|
pub struct MapBundle {
|
||||||
pub map: Map,
|
pub map: Map,
|
||||||
|
pub spawn_colliders: SpawnColliders,
|
||||||
|
pub spawn_portals: SpawnPortals,
|
||||||
pub children: Children,
|
pub children: Children,
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
|
@ -171,61 +191,67 @@ impl MapFilter for GridBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_map_colliders(mut commands: Commands, maps: Query<(Entity, &Map), Added<Map>>) {
|
fn spawn_colliders(
|
||||||
for (map_entity, map) in maps.iter() {
|
mut commands: Commands,
|
||||||
commands.entity(map_entity).insert_bundle(RigidBodyBundle {
|
maps: Query<(Entity, &Map, &SpawnColliders), Changed<SpawnColliders>>,
|
||||||
body_type: RigidBodyType::Static,
|
) {
|
||||||
..Default::default()
|
for (map_entity, map, spawn_colliders) in maps.iter() {
|
||||||
});
|
if **spawn_colliders {
|
||||||
for x in 0..map.width {
|
commands.entity(map_entity).remove::<SpawnColliders>();
|
||||||
for y in 0..map.height {
|
commands.entity(map_entity).insert_bundle(RigidBodyBundle {
|
||||||
let tile = map.at(x, y);
|
body_type: RigidBodyType::Static,
|
||||||
if tile.blocks_motion() {
|
..Default::default()
|
||||||
let id = commands
|
});
|
||||||
.spawn_bundle(ColliderBundle {
|
for x in 0..map.width {
|
||||||
shape: ColliderShape::cuboid(0.5, 0.5),
|
for y in 0..map.height {
|
||||||
..Default::default()
|
let tile = map.at(x, y);
|
||||||
})
|
if tile.blocks_motion() {
|
||||||
.insert(ColliderParent {
|
let id = commands
|
||||||
handle: map_entity.handle(),
|
.spawn_bundle(ColliderBundle {
|
||||||
pos_wrt_parent: Vec2::new(x as f32 + 0.5, y as f32 + 0.5).into(),
|
shape: ColliderShape::cuboid(0.5, 0.5),
|
||||||
})
|
..Default::default()
|
||||||
.insert(MapObstruction)
|
})
|
||||||
.id();
|
.insert(ColliderParent {
|
||||||
if tile.blocks_visibility() {
|
handle: map_entity.handle(),
|
||||||
commands.entity(id).insert(BlocksVisibility);
|
pos_wrt_parent: Vec2::new(x as f32 + 0.5, y as f32 + 0.5).into(),
|
||||||
|
})
|
||||||
|
.insert(MapObstruction)
|
||||||
|
.id();
|
||||||
|
if tile.blocks_visibility() {
|
||||||
|
commands.entity(id).insert(BlocksVisibility);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
for room in &map.rooms {
|
||||||
for room in &map.rooms {
|
let shape =
|
||||||
let shape =
|
ColliderShape::cuboid((room.width() / 2) as f32, (room.height() / 2) as f32);
|
||||||
ColliderShape::cuboid((room.width() / 2) as f32, (room.height() / 2) as f32);
|
let position = Vec2::new(room.center().x(), room.center().y()).into();
|
||||||
let position = Vec2::new(room.center().x(), room.center().y()).into();
|
commands
|
||||||
commands
|
.spawn_bundle(ColliderBundle {
|
||||||
.spawn_bundle(ColliderBundle {
|
collider_type: ColliderType::Sensor,
|
||||||
collider_type: ColliderType::Sensor,
|
shape: shape.clone(),
|
||||||
shape: shape.clone(),
|
flags: ActiveEvents::INTERSECTION_EVENTS.into(),
|
||||||
flags: ActiveEvents::INTERSECTION_EVENTS.into(),
|
..Default::default()
|
||||||
..Default::default()
|
})
|
||||||
})
|
.insert(ColliderParent {
|
||||||
.insert(ColliderParent {
|
handle: map_entity.handle(),
|
||||||
handle: map_entity.handle(),
|
pos_wrt_parent: position,
|
||||||
pos_wrt_parent: position,
|
})
|
||||||
})
|
.insert(shape.compute_aabb(&position))
|
||||||
.insert(shape.compute_aabb(&position))
|
.insert(AreaTag);
|
||||||
.insert(AreaTag);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn portal_spawner(
|
fn spawn_portals(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
map: Query<(Entity, &Map), Added<RigidBodyColliders>>,
|
map: Query<(Entity, &Map, &SpawnPortals), Changed<SpawnPortals>>,
|
||||||
config: Res<MapConfig>,
|
|
||||||
) {
|
) {
|
||||||
for (entity, map) in map.iter() {
|
for (entity, map, spawn_portals) in map.iter() {
|
||||||
if config.autospawn_portals {
|
if **spawn_portals {
|
||||||
|
commands.entity(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 1..map.width {
|
||||||
for y in 1..map.height {
|
for y in 1..map.height {
|
||||||
|
@ -267,6 +293,23 @@ fn portal_spawner(
|
||||||
coordinates,
|
coordinates,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
|
.id();
|
||||||
|
commands.entity(entity).push_children(&[portal]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_portal_colliders(
|
||||||
|
mut commands: Commands,
|
||||||
|
map: Query<(Entity, &SpawnColliders), With<Map>>,
|
||||||
|
portals: Query<(Entity, &Coordinates), Without<ColliderShape>>,
|
||||||
|
) {
|
||||||
|
for (map_entity, spawn_colliders) in map.iter() {
|
||||||
|
if **spawn_colliders {
|
||||||
|
for (portal_entity, coordinates) in portals.iter() {
|
||||||
|
commands
|
||||||
|
.entity(portal_entity)
|
||||||
.insert_bundle(ColliderBundle {
|
.insert_bundle(ColliderBundle {
|
||||||
collider_type: ColliderType::Sensor,
|
collider_type: ColliderType::Sensor,
|
||||||
shape: ColliderShape::cuboid(0.5, 0.5),
|
shape: ColliderShape::cuboid(0.5, 0.5),
|
||||||
|
@ -275,11 +318,10 @@ fn portal_spawner(
|
||||||
})
|
})
|
||||||
.insert(ColliderPositionSync::Discrete)
|
.insert(ColliderPositionSync::Discrete)
|
||||||
.insert(ColliderParent {
|
.insert(ColliderParent {
|
||||||
handle: entity.handle(),
|
handle: map_entity.handle(),
|
||||||
pos_wrt_parent: Vec2::new(x + 0.5, y + 0.5).into(),
|
pos_wrt_parent: Vec2::new(coordinates.x() + 0.5, coordinates.y() + 0.5)
|
||||||
})
|
.into(),
|
||||||
.id();
|
});
|
||||||
commands.entity(entity).push_children(&[portal]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -331,8 +373,9 @@ impl Plugin for MapPlugin {
|
||||||
}
|
}
|
||||||
let config = app.world().get_resource::<MapConfig>().unwrap().clone();
|
let config = app.world().get_resource::<MapConfig>().unwrap().clone();
|
||||||
app.register_type::<Portal>()
|
app.register_type::<Portal>()
|
||||||
.add_system(add_map_colliders.system())
|
.add_system(spawn_colliders.system())
|
||||||
.add_system(portal_spawner.system());
|
.add_system(spawn_portals.system())
|
||||||
|
.add_system(spawn_portal_colliders.system());
|
||||||
if config.speak_area_descriptions {
|
if config.speak_area_descriptions {
|
||||||
app.add_system_to_stage(CoreStage::PostUpdate, area_description.system());
|
app.add_system_to_stage(CoreStage::PostUpdate, area_description.system());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user