Compare commits

...

5 Commits

7 changed files with 100 additions and 76 deletions

View File

@ -13,25 +13,14 @@ speech_dispatcher_0_9 = ["bevy_tts/speech_dispatcher_0_9"]
speech_dispatcher_0_10 = ["bevy_tts/speech_dispatcher_0_10"] speech_dispatcher_0_10 = ["bevy_tts/speech_dispatcher_0_10"]
speech_dispatcher_0_11 = ["bevy_tts/speech_dispatcher_0_11"] speech_dispatcher_0_11 = ["bevy_tts/speech_dispatcher_0_11"]
[dependencies.bevy]
version = "0.13"
default-features = false
features = [
"bevy_gilrs",
"bevy_winit",
"x11",
"wayland",
"multi-threaded",
"serialize",
]
[dependencies] [dependencies]
bevy_rapier2d = "0.25" bevy = "0.14"
bevy_synthizer = "0.6" bevy_rapier2d = "0.27"
bevy_tts = { version = "0.8", default-features = false, features = ["tolk"] } bevy_synthizer = "0.7"
bevy_tts = { version = "0.9", default-features = false, features = ["tolk"] }
coord_2d = "0.3" coord_2d = "0.3"
here_be_dragons = { version = "0.3", features = ["serde"] } here_be_dragons = { version = "0.3", features = ["serde"] }
leafwing-input-manager = "0.13" leafwing-input-manager = "0.14"
maze_generator = "2" maze_generator = "2"
once_cell = "1" once_cell = "1"
pathfinding = "4" pathfinding = "4"

View File

@ -6,7 +6,7 @@ use std::{
sync::RwLock, sync::RwLock,
}; };
use bevy::{app::PluginGroupBuilder, prelude::*, utils::FloatOrd}; use bevy::{app::PluginGroupBuilder, math::FloatOrd, prelude::*};
use bevy_rapier2d::{ use bevy_rapier2d::{
parry::query::{closest_points, distance, ClosestPoints}, parry::query::{closest_points, distance, ClosestPoints},
prelude::*, prelude::*,

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()
}); });
}); });

View File

@ -237,8 +237,10 @@ fn controls(
transform.yaw().radians(), transform.yaw().radians(),
vel, vel,
collider, collider,
1., ShapeCastOptions {
true, max_time_of_impact: 1.,
..default()
},
QueryFilter::new() QueryFilter::new()
.exclude_sensors() .exclude_sensors()
.exclude_collider(entity), .exclude_collider(entity),

View File

@ -312,8 +312,10 @@ fn negotiate_path(
transform.yaw().radians(), transform.yaw().radians(),
direction, direction,
collider, collider,
1., ShapeCastOptions {
true, max_time_of_impact: 1.,
..default()
},
QueryFilter::new() QueryFilter::new()
.exclude_sensors() .exclude_sensors()
.exclude_collider(entity), .exclude_collider(entity),
@ -404,7 +406,7 @@ impl Plugin for PathfindingPlugin {
.register_type::<Path>() .register_type::<Path>()
.register_type::<CostMap>() .register_type::<CostMap>()
.add_systems( .add_systems(
PreUpdate, FixedPreUpdate,
(poll_tasks, apply_deferred, negotiate_path).chain(), (poll_tasks, apply_deferred, negotiate_path).chain(),
) )
.add_systems( .add_systems(
@ -413,6 +415,6 @@ impl Plugin for PathfindingPlugin {
.chain() .chain()
.after(InputManagerSystem::Tick), .after(InputManagerSystem::Tick),
) )
.add_systems(PostUpdate, remove_destination); .add_systems(FixedPostUpdate, remove_destination);
} }
} }

View File

@ -26,7 +26,7 @@ fn tag_behind(
continue; continue;
} }
let v = transform.translation() - listener_transform.translation(); let v = transform.translation() - listener_transform.translation();
let dot = v.dot(listener_forward); let dot = v.dot(*listener_forward);
let is_behind = dot <= 0.; let is_behind = dot <= 0.;
if is_behind { if is_behind {
commands.entity(entity).insert(Behind); commands.entity(entity).insert(Behind);

View File

@ -430,13 +430,13 @@ impl<MapData: 'static + Clone + Default + Send + Sync> Plugin for VisibilityPlug
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_event::<VisibilityChanged>() app.add_event::<VisibilityChanged>()
.add_systems( .add_systems(
PreUpdate, FixedPreUpdate,
( (
add_visibility_indices::<MapData>, add_visibility_indices::<MapData>,
update_viewshed, update_viewshed,
update_revealed_tiles::<MapData>, update_revealed_tiles::<MapData>,
), ),
) )
.add_systems(PostUpdate, (log_visible, viewshed_removed, remove_visible)); .add_systems(FixedPostUpdate, (log_visible, viewshed_removed, remove_visible));
} }
} }