Compare commits
2 Commits
f6855ff727
...
3a6ede0428
Author | SHA1 | Date | |
---|---|---|---|
3a6ede0428 | |||
b1a11de050 |
|
@ -8,7 +8,7 @@ steps:
|
||||||
commands:
|
commands:
|
||||||
- rustup component add clippy rustfmt
|
- rustup component add clippy rustfmt
|
||||||
- apt-get update -qq
|
- apt-get update -qq
|
||||||
- apt-get install -qqy llvm-dev libclang-dev clang libspeechd-dev pkg-config libx11-dev libasound2-dev libudev-dev libxcb-xfixes0-dev libwayland-dev libxkbcommon-dev libvulkan-dev cmake
|
- apt-get install -qqy llvm-dev libspeechd-dev pkg-config libx11-dev libasound2-dev libudev-dev libxcb-xfixes0-dev libwayland-dev libxkbcommon-dev libvulkan-dev cmake
|
||||||
- cargo fmt --check
|
- cargo fmt --check
|
||||||
- cargo test --no-default-features --features=speech_dispatcher_0_10
|
- cargo test --no-default-features --features=speech_dispatcher_0_10
|
||||||
- cargo clippy --no-default-features --features=speech_dispatcher_0_10
|
- cargo clippy --no-default-features --features=speech_dispatcher_0_10
|
||||||
|
|
17
Cargo.toml
17
Cargo.toml
|
@ -8,11 +8,12 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
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]
|
[dependencies.bevy]
|
||||||
version = "0.8"
|
version = "0.9"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = [
|
features = [
|
||||||
"bevy_gilrs",
|
"bevy_gilrs",
|
||||||
|
@ -25,18 +26,18 @@ features = [
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
backtrace = "0.3"
|
backtrace = "0.3"
|
||||||
bevy_rapier2d = "0.17"
|
bevy_rapier2d = "0.19"
|
||||||
bevy_synthizer = { git = "https://labs.lightsout.games/projects/bevy_synthizer" }
|
bevy_synthizer = "0.1"
|
||||||
bevy_tts = { version = "0.1", default-features = false, features = ["tolk"] }
|
bevy_tts = { version = "0.2", default-features = false, features = ["tolk"] }
|
||||||
coord_2d = "0.3"
|
coord_2d = "0.3"
|
||||||
futures-lite = "1"
|
futures-lite = "1"
|
||||||
gilrs = "0.9"
|
gilrs = "0.10"
|
||||||
here_be_dragons = "0.2"
|
here_be_dragons = "0.2"
|
||||||
leafwing_input_manager = { git = "https://github.com/leafwing-studios/leafwing-input-manager", branch = "dev" }
|
leafwing-input-manager = "0.7"
|
||||||
maze_generator = "2"
|
maze_generator = "2"
|
||||||
once_cell = "1"
|
once_cell = "1"
|
||||||
pathfinding = "3"
|
pathfinding = "4"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
sentry = "0.27"
|
sentry = "0.29"
|
||||||
serde = "1"
|
serde = "1"
|
||||||
shadowcast = "0.8"
|
shadowcast = "0.8"
|
33
src/core.rs
33
src/core.rs
|
@ -7,11 +7,11 @@ use std::{
|
||||||
sync::RwLock,
|
sync::RwLock,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{ecs::query::WorldQuery, prelude::*, utils::FloatOrd};
|
use bevy::{app::PluginGroupBuilder, ecs::query::WorldQuery, prelude::*, utils::FloatOrd};
|
||||||
use bevy_rapier2d::{
|
use bevy_rapier2d::{
|
||||||
parry::query::{closest_points, distance, ClosestPoints},
|
parry::query::{closest_points, distance, ClosestPoints},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rapier::{math::Isometry, prelude::AABB},
|
rapier::{math::Isometry, prelude::Aabb},
|
||||||
};
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
@ -143,7 +143,7 @@ impl Sub for Angle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Reflect)]
|
||||||
pub enum MovementDirection {
|
pub enum MovementDirection {
|
||||||
North,
|
North,
|
||||||
NorthNortheast,
|
NorthNortheast,
|
||||||
|
@ -222,8 +222,10 @@ impl Display for MovementDirection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Component, Clone, Copy, Default, Debug, Eq, PartialEq, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
pub enum CardinalDirection {
|
pub enum CardinalDirection {
|
||||||
|
#[default]
|
||||||
North,
|
North,
|
||||||
East,
|
East,
|
||||||
South,
|
South,
|
||||||
|
@ -570,7 +572,7 @@ impl GlobalTransformExt for GlobalTransform {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, PartialEq)]
|
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, PartialEq)]
|
||||||
pub struct Area(pub AABB);
|
pub struct Area(pub Aabb);
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
@ -642,7 +644,7 @@ fn setup(core_config: Res<CoreConfig>) {
|
||||||
*mode = core_config.relative_direction_mode;
|
*mode = core_config.relative_direction_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Resource, Clone, Copy, Debug)]
|
||||||
pub struct CoreConfig {
|
pub struct CoreConfig {
|
||||||
pub relative_direction_mode: RelativeDirectionMode,
|
pub relative_direction_mode: RelativeDirectionMode,
|
||||||
pub pixels_per_unit: u8,
|
pub pixels_per_unit: u8,
|
||||||
|
@ -678,11 +680,12 @@ impl<RapierUserData: 'static + WorldQuery + Send + Sync> Plugin for CorePlugin<R
|
||||||
app.insert_resource(CoreConfig::default());
|
app.insert_resource(CoreConfig::default());
|
||||||
}
|
}
|
||||||
let config = *app.world.get_resource::<CoreConfig>().unwrap();
|
let config = *app.world.get_resource::<CoreConfig>().unwrap();
|
||||||
app.add_plugin(RapierPhysicsPlugin::<RapierUserData>::pixels_per_meter(
|
app.register_type::<CardinalDirection>()
|
||||||
config.pixels_per_unit as f32,
|
.add_plugin(RapierPhysicsPlugin::<RapierUserData>::pixels_per_meter(
|
||||||
))
|
config.pixels_per_unit as f32,
|
||||||
.add_startup_system(setup)
|
))
|
||||||
.add_system(sync_config);
|
.add_startup_system(setup)
|
||||||
|
.add_system(sync_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,10 +700,10 @@ impl<RapierUserData> Default for CorePlugins<RapierUserData> {
|
||||||
impl<RapierUserData: 'static + WorldQuery + Send + Sync> PluginGroup
|
impl<RapierUserData: 'static + WorldQuery + Send + Sync> PluginGroup
|
||||||
for CorePlugins<RapierUserData>
|
for CorePlugins<RapierUserData>
|
||||||
{
|
{
|
||||||
fn build(&mut self, group: &mut bevy::app::PluginGroupBuilder) {
|
fn build(self) -> PluginGroupBuilder {
|
||||||
group
|
PluginGroupBuilder::start::<Self>()
|
||||||
.add(crate::bevy_tts::TtsPlugin)
|
.add(crate::bevy_tts::TtsPlugin)
|
||||||
.add(crate::bevy_synthizer::SynthizerPlugin)
|
.add(crate::bevy_synthizer::SynthizerPlugin::default())
|
||||||
.add(CorePlugin::<RapierUserData>::default());
|
.add(CorePlugin::<RapierUserData>::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,9 @@ use std::{panic, thread};
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Resource)]
|
||||||
|
struct Guard(sentry::ClientInitGuard);
|
||||||
|
|
||||||
pub fn error_handler(In(result): In<Result<(), Box<dyn Error>>>) {
|
pub fn error_handler(In(result): In<Result<(), Box<dyn Error>>>) {
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
error!("{}", e);
|
error!("{}", e);
|
||||||
|
@ -44,7 +47,7 @@ fn init_panic_handler() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Resource, Clone, Debug, Default)]
|
||||||
pub struct ErrorConfig {
|
pub struct ErrorConfig {
|
||||||
pub sentry_dsn: Option<String>,
|
pub sentry_dsn: Option<String>,
|
||||||
pub version: Option<String>,
|
pub version: Option<String>,
|
||||||
|
@ -57,7 +60,7 @@ impl Plugin for ErrorPlugin {
|
||||||
init_panic_handler();
|
init_panic_handler();
|
||||||
if let Some(config) = app.world.get_resource::<ErrorConfig>() {
|
if let Some(config) = app.world.get_resource::<ErrorConfig>() {
|
||||||
if let Some(dsn) = &config.sentry_dsn {
|
if let Some(dsn) = &config.sentry_dsn {
|
||||||
let release = config.version.clone().unwrap_or_else(|| "".to_string());
|
let release = config.version.clone().unwrap_or_default();
|
||||||
let guard = sentry::init((
|
let guard = sentry::init((
|
||||||
dsn.as_str(),
|
dsn.as_str(),
|
||||||
sentry::ClientOptions {
|
sentry::ClientOptions {
|
||||||
|
@ -65,7 +68,7 @@ impl Plugin for ErrorPlugin {
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
app.insert_resource(guard);
|
app.insert_resource(Guard(guard));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,9 @@ pub struct Exploring(pub (f32, f32));
|
||||||
impl_pointlike_for_tuple_component!(Exploring);
|
impl_pointlike_for_tuple_component!(Exploring);
|
||||||
|
|
||||||
#[derive(Component, Clone, Debug, Default, Deref, DerefMut)]
|
#[derive(Component, Clone, Debug, Default, Deref, DerefMut)]
|
||||||
pub struct FocusedExplorationType<T>(pub Option<T>);
|
pub struct FocusedExplorationType<T>(pub Option<T>)
|
||||||
|
where
|
||||||
|
T: Component + Default;
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
@ -57,7 +59,7 @@ fn exploration_type_change<T, S>(
|
||||||
features: Query<&T>,
|
features: Query<&T>,
|
||||||
) -> Result<(), Box<dyn Error>>
|
) -> Result<(), Box<dyn Error>>
|
||||||
where
|
where
|
||||||
T: Component + Copy + Ord,
|
T: Component + Default + Copy + Ord,
|
||||||
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
||||||
{
|
{
|
||||||
for (actions, visible, mut focused) in explorers.iter_mut() {
|
for (actions, visible, mut focused) in explorers.iter_mut() {
|
||||||
|
@ -123,7 +125,7 @@ fn exploration_type_focus<T, S>(
|
||||||
features: Query<(Entity, &Transform, &T)>,
|
features: Query<(Entity, &Transform, &T)>,
|
||||||
) -> Result<(), Box<dyn Error>>
|
) -> Result<(), Box<dyn Error>>
|
||||||
where
|
where
|
||||||
T: Component + PartialEq,
|
T: Component + Default + PartialEq,
|
||||||
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
||||||
{
|
{
|
||||||
for (entity, actions, visible_entities, focused_type, exploring) in explorers.iter() {
|
for (entity, actions, visible_entities, focused_type, exploring) in explorers.iter() {
|
||||||
|
@ -181,7 +183,7 @@ fn exploration_type_changed_announcement<T>(
|
||||||
>,
|
>,
|
||||||
) -> Result<(), Box<dyn Error>>
|
) -> Result<(), Box<dyn Error>>
|
||||||
where
|
where
|
||||||
T: Component + Copy + Into<String>,
|
T: Component + Default + Copy + Into<String>,
|
||||||
{
|
{
|
||||||
for (focused, changed) in focused.iter() {
|
for (focused, changed) in focused.iter() {
|
||||||
if changed.is_added() {
|
if changed.is_added() {
|
||||||
|
@ -367,7 +369,7 @@ fn cleanup(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Resource, Clone, Debug)]
|
||||||
pub struct ExplorationConfig<S> {
|
pub struct ExplorationConfig<S> {
|
||||||
pub exploration_control_states: Vec<S>,
|
pub exploration_control_states: Vec<S>,
|
||||||
}
|
}
|
||||||
|
@ -411,16 +413,17 @@ where
|
||||||
.clone();
|
.clone();
|
||||||
app.register_type::<ExplorationFocused>()
|
app.register_type::<ExplorationFocused>()
|
||||||
.register_type::<Mappable>()
|
.register_type::<Mappable>()
|
||||||
|
.register_type::<Explorable>()
|
||||||
.add_plugin(InputManagerPlugin::<ExplorationAction>::default())
|
.add_plugin(InputManagerPlugin::<ExplorationAction>::default())
|
||||||
.add_system(exploration_changed_announcement::<T, D>.chain(error_handler));
|
.add_system(exploration_changed_announcement::<T, D>.pipe(error_handler));
|
||||||
if config.exploration_control_states.is_empty() {
|
if config.exploration_control_states.is_empty() {
|
||||||
app.add_system(exploration_focus::<S, D>)
|
app.add_system(exploration_focus::<S, D>)
|
||||||
.add_system(exploration_type_focus::<T, S>.chain(error_handler))
|
.add_system(exploration_type_focus::<T, S>.pipe(error_handler))
|
||||||
.add_system(exploration_type_change::<T, S>.chain(error_handler))
|
.add_system(exploration_type_change::<T, S>.pipe(error_handler))
|
||||||
.add_system(navigate_to_explored::<S, D>)
|
.add_system(navigate_to_explored::<S, D>)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
exploration_type_changed_announcement::<T>.chain(error_handler),
|
exploration_type_changed_announcement::<T>.pipe(error_handler),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let states = config.exploration_control_states;
|
let states = config.exploration_control_states;
|
||||||
|
@ -428,11 +431,11 @@ where
|
||||||
app.add_system_set(
|
app.add_system_set(
|
||||||
SystemSet::on_update(state.clone())
|
SystemSet::on_update(state.clone())
|
||||||
.with_system(exploration_focus::<S, D>)
|
.with_system(exploration_focus::<S, D>)
|
||||||
.with_system(exploration_type_focus::<T, S>.chain(error_handler))
|
.with_system(exploration_type_focus::<T, S>.pipe(error_handler))
|
||||||
.with_system(exploration_type_change::<T, S>.chain(error_handler))
|
.with_system(exploration_type_change::<T, S>.pipe(error_handler))
|
||||||
.with_system(navigate_to_explored::<S, D>)
|
.with_system(navigate_to_explored::<S, D>)
|
||||||
.with_system(
|
.with_system(
|
||||||
exploration_type_changed_announcement::<T>.chain(error_handler),
|
exploration_type_changed_announcement::<T>.pipe(error_handler),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.add_system_set(SystemSet::on_exit(state).with_system(cleanup));
|
.add_system_set(SystemSet::on_exit(state).with_system(cleanup));
|
||||||
|
|
|
@ -17,7 +17,7 @@ impl Log {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component, Clone, Debug)]
|
#[derive(Component, Clone, Debug, Reflect)]
|
||||||
pub struct LogEntry {
|
pub struct LogEntry {
|
||||||
pub time: Instant,
|
pub time: Instant,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
@ -33,7 +33,7 @@ impl From<String> for LogEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup(mut commands: Commands) {
|
fn setup(mut commands: Commands) {
|
||||||
commands.spawn().insert(Log::default());
|
commands.spawn(Log::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_log(
|
fn read_log(
|
||||||
|
@ -59,7 +59,8 @@ pub struct LogPlugin;
|
||||||
|
|
||||||
impl Plugin for LogPlugin {
|
impl Plugin for LogPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(setup)
|
app.register_type::<LogEntry>()
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, read_log.chain(error_handler));
|
.add_startup_system(setup)
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, read_log.pipe(error_handler));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
53
src/map.rs
53
src/map.rs
|
@ -78,7 +78,7 @@ impl ITileType for Tile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Resource, Clone, Debug, Default)]
|
||||||
pub struct MapConfig {
|
pub struct MapConfig {
|
||||||
pub start_revealed: bool,
|
pub start_revealed: bool,
|
||||||
}
|
}
|
||||||
|
@ -151,22 +151,22 @@ impl<D: Clone + Default> MapFilter<D> for GridBuilder {
|
||||||
if field.has_passage(&North) {
|
if field.has_passage(&North) {
|
||||||
let x = x_offset + half_width;
|
let x = x_offset + half_width;
|
||||||
let y = y_offset + self.room_height;
|
let y = y_offset + self.room_height;
|
||||||
map.set_tile(x as usize, y as usize, Tile::floor());
|
map.set_tile(x, y, Tile::floor());
|
||||||
}
|
}
|
||||||
if field.has_passage(&South) {
|
if field.has_passage(&South) {
|
||||||
let x = x_offset + half_width;
|
let x = x_offset + half_width;
|
||||||
let y = y_offset;
|
let y = y_offset;
|
||||||
map.set_tile(x as usize, y as usize, Tile::floor());
|
map.set_tile(x, y, Tile::floor());
|
||||||
}
|
}
|
||||||
if field.has_passage(&East) {
|
if field.has_passage(&East) {
|
||||||
let x = x_offset + self.room_width;
|
let x = x_offset + self.room_width;
|
||||||
let y = y_offset + half_height;
|
let y = y_offset + half_height;
|
||||||
map.set_tile(x as usize, y as usize, Tile::floor());
|
map.set_tile(x, y, Tile::floor());
|
||||||
}
|
}
|
||||||
if field.has_passage(&West) {
|
if field.has_passage(&West) {
|
||||||
let x = x_offset;
|
let x = x_offset;
|
||||||
let y = y_offset + half_height;
|
let y = y_offset + half_height;
|
||||||
map.set_tile(x as usize, y as usize, Tile::floor());
|
map.set_tile(x, y, Tile::floor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,14 +198,17 @@ 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 =
|
let id = commands
|
||||||
commands
|
.spawn((
|
||||||
.spawn_bundle(TransformBundle::from_transform(
|
TransformBundle::from_transform(Transform::from_xyz(
|
||||||
Transform::from_xyz(x as f32 + 0.5, y as f32 + 0.5, 0.),
|
x as f32 + 0.5,
|
||||||
))
|
y as f32 + 0.5,
|
||||||
.insert(Collider::cuboid(0.5, 0.5))
|
0.,
|
||||||
.insert(MapObstruction)
|
)),
|
||||||
.id();
|
Collider::cuboid(0.5, 0.5),
|
||||||
|
MapObstruction,
|
||||||
|
))
|
||||||
|
.id();
|
||||||
if tile.blocks_visibility() {
|
if tile.blocks_visibility() {
|
||||||
commands.entity(id).insert(Visible::opaque());
|
commands.entity(id).insert(Visible::opaque());
|
||||||
}
|
}
|
||||||
|
@ -223,16 +226,18 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
|
||||||
Isometry2::new(Vector2::new(room.center().x(), room.center().y()), 0.);
|
Isometry2::new(Vector2::new(room.center().x(), room.center().y()), 0.);
|
||||||
let aabb = shape.raw.compute_aabb(&position);
|
let aabb = shape.raw.compute_aabb(&position);
|
||||||
let id = commands
|
let id = commands
|
||||||
.spawn_bundle(TransformBundle::from_transform(Transform::from_xyz(
|
.spawn((
|
||||||
position.translation.x,
|
TransformBundle::from_transform(Transform::from_xyz(
|
||||||
position.translation.y,
|
position.translation.x,
|
||||||
0.,
|
position.translation.y,
|
||||||
)))
|
0.,
|
||||||
.insert(shape)
|
)),
|
||||||
.insert(Sensor)
|
shape,
|
||||||
.insert(ActiveEvents::COLLISION_EVENTS)
|
Sensor,
|
||||||
.insert(Area(aabb))
|
ActiveEvents::COLLISION_EVENTS,
|
||||||
.insert(Zone)
|
Area(aabb),
|
||||||
|
Zone,
|
||||||
|
))
|
||||||
.id();
|
.id();
|
||||||
commands.entity(map_entity).push_children(&[id]);
|
commands.entity(map_entity).push_children(&[id]);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +286,7 @@ fn spawn_portals<D: 'static + Clone + Default + Send + Sync>(
|
||||||
}
|
}
|
||||||
for (x, y) in portals {
|
for (x, y) in portals {
|
||||||
let portal = commands
|
let portal = commands
|
||||||
.spawn_bundle(PortalBundle {
|
.spawn(PortalBundle {
|
||||||
transform: Transform::from_translation(Vec3::new(x, y, 0.)),
|
transform: Transform::from_translation(Vec3::new(x, y, 0.)),
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
|
|
|
@ -49,19 +49,22 @@ pub struct RotationSpeed(pub Angle);
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct Speed(pub f32);
|
pub struct Speed(pub f32);
|
||||||
|
|
||||||
#[derive(Component, Deref, DerefMut)]
|
#[derive(Deref, DerefMut)]
|
||||||
struct SnapTimer(Timer);
|
struct SnapTimer(Timer);
|
||||||
|
|
||||||
impl Default for SnapTimer {
|
impl Default for SnapTimer {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(Timer::from_seconds(0.2, false))
|
Self(Timer::from_seconds(0.2, TimerMode::Once))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Resource, Default, Deref, DerefMut)]
|
||||||
|
struct SnapTimers(HashMap<Entity, SnapTimer>);
|
||||||
|
|
||||||
fn movement_controls<S>(
|
fn movement_controls<S>(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
config: Res<NavigationConfig<S>>,
|
config: Res<NavigationConfig<S>>,
|
||||||
snap_timers: Res<HashMap<Entity, SnapTimer>>,
|
snap_timers: Res<SnapTimers>,
|
||||||
mut query: Query<(
|
mut query: Query<(
|
||||||
Entity,
|
Entity,
|
||||||
&mut ActionState<NavigationAction>,
|
&mut ActionState<NavigationAction>,
|
||||||
|
@ -118,13 +121,13 @@ fn movement_controls<S>(
|
||||||
.axis_pair = Some(DualAxisData::from_xy(v));
|
.axis_pair = Some(DualAxisData::from_xy(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if actions.released(NavigationAction::Move) {
|
if actions.released(NavigationAction::Move)
|
||||||
if actions.axis_pair(NavigationAction::Move).is_some() {
|
&& actions.axis_pair(NavigationAction::Move).is_some()
|
||||||
actions.press(NavigationAction::SetLinearVelocity);
|
{
|
||||||
actions
|
actions.press(NavigationAction::SetLinearVelocity);
|
||||||
.action_data_mut(NavigationAction::SetLinearVelocity)
|
actions
|
||||||
.axis_pair = None;
|
.action_data_mut(NavigationAction::SetLinearVelocity)
|
||||||
}
|
.axis_pair = None;
|
||||||
}
|
}
|
||||||
if actions.pressed(NavigationAction::SetLinearVelocity) {
|
if actions.pressed(NavigationAction::SetLinearVelocity) {
|
||||||
if let Some(pair) = actions.axis_pair(NavigationAction::SetLinearVelocity) {
|
if let Some(pair) = actions.axis_pair(NavigationAction::SetLinearVelocity) {
|
||||||
|
@ -167,7 +170,7 @@ fn movement_controls<S>(
|
||||||
|
|
||||||
fn snap(
|
fn snap(
|
||||||
mut tts: ResMut<Tts>,
|
mut tts: ResMut<Tts>,
|
||||||
mut snap_timers: ResMut<HashMap<Entity, SnapTimer>>,
|
mut snap_timers: ResMut<SnapTimers>,
|
||||||
mut query: Query<
|
mut query: Query<
|
||||||
(
|
(
|
||||||
Entity,
|
Entity,
|
||||||
|
@ -210,7 +213,7 @@ fn snap(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_snap_timers(time: Res<Time>, mut snap_timers: ResMut<HashMap<Entity, SnapTimer>>) {
|
fn tick_snap_timers(time: Res<Time>, mut snap_timers: ResMut<SnapTimers>) {
|
||||||
for timer in snap_timers.values_mut() {
|
for timer in snap_timers.values_mut() {
|
||||||
timer.tick(time.delta());
|
timer.tick(time.delta());
|
||||||
}
|
}
|
||||||
|
@ -336,7 +339,7 @@ fn log_area_descriptions<S, A>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Resource, Clone, Debug)]
|
||||||
pub struct NavigationConfig<S> {
|
pub struct NavigationConfig<S> {
|
||||||
pub forward_movement_factor: f32,
|
pub forward_movement_factor: f32,
|
||||||
pub backward_movement_factor: f32,
|
pub backward_movement_factor: f32,
|
||||||
|
@ -383,14 +386,15 @@ where
|
||||||
.get_resource::<NavigationConfig<S>>()
|
.get_resource::<NavigationConfig<S>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
app.init_resource::<HashMap<Entity, SnapTimer>>()
|
app.init_resource::<SnapTimers>()
|
||||||
.register_type::<MaxSpeed>()
|
.register_type::<MaxSpeed>()
|
||||||
.register_type::<RotationSpeed>()
|
.register_type::<RotationSpeed>()
|
||||||
|
.register_type::<Speed>()
|
||||||
.add_plugin(InputManagerPlugin::<NavigationAction>::default())
|
.add_plugin(InputManagerPlugin::<NavigationAction>::default())
|
||||||
.add_system_to_stage(CoreStage::PreUpdate, update_direction)
|
.add_system_to_stage(CoreStage::PreUpdate, update_direction)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_direction)
|
.add_system_to_stage(CoreStage::PostUpdate, remove_direction)
|
||||||
.add_system(tick_snap_timers)
|
.add_system(tick_snap_timers)
|
||||||
.add_system(speak_direction.chain(error_handler))
|
.add_system(speak_direction.pipe(error_handler))
|
||||||
.add_system(add_speed)
|
.add_system(add_speed)
|
||||||
.add_system(limit_speed)
|
.add_system(limit_speed)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_speed)
|
.add_system_to_stage(CoreStage::PostUpdate, remove_speed)
|
||||||
|
@ -402,14 +406,14 @@ where
|
||||||
.label(MOVEMENT_CONTROLS)
|
.label(MOVEMENT_CONTROLS)
|
||||||
.after(limit_speed),
|
.after(limit_speed),
|
||||||
)
|
)
|
||||||
.add_system(snap.chain(error_handler).before(MOVEMENT_CONTROLS));
|
.add_system(snap.pipe(error_handler).before(MOVEMENT_CONTROLS));
|
||||||
} else {
|
} else {
|
||||||
let states = config.movement_control_states;
|
let states = config.movement_control_states;
|
||||||
for state in states {
|
for state in states {
|
||||||
app.add_system_set(
|
app.add_system_set(
|
||||||
SystemSet::on_update(state)
|
SystemSet::on_update(state)
|
||||||
.with_system(movement_controls::<S>.label(MOVEMENT_CONTROLS))
|
.with_system(movement_controls::<S>.label(MOVEMENT_CONTROLS))
|
||||||
.with_system(snap.chain(error_handler).before(MOVEMENT_CONTROLS)),
|
.with_system(snap.pipe(error_handler).before(MOVEMENT_CONTROLS)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl CostMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_modifier(&mut self, x: usize, y: usize, cost: f32) {
|
pub fn set_modifier(&mut self, x: usize, y: usize, cost: f32) {
|
||||||
let idx = (y as usize) * self.width + (x as usize);
|
let idx = y * self.width + x;
|
||||||
self.costs[idx] = cost;
|
self.costs[idx] = cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,8 @@ fn find_path_for_shape(
|
||||||
&start.i32(),
|
&start.i32(),
|
||||||
|p| {
|
|p| {
|
||||||
let mut successors: Vec<((i32, i32), u32)> = vec![];
|
let mut successors: Vec<((i32, i32), u32)> = vec![];
|
||||||
let x = p.0 as i32;
|
let x = p.0;
|
||||||
let y = p.1 as i32;
|
let y = p.1;
|
||||||
let exits = vec![
|
let exits = vec![
|
||||||
((x - 1, y), 1.),
|
((x - 1, y), 1.),
|
||||||
((x + 1, y), 1.),
|
((x + 1, y), 1.),
|
||||||
|
@ -325,7 +325,11 @@ pub struct PathfindingPlugin;
|
||||||
|
|
||||||
impl Plugin for PathfindingPlugin {
|
impl Plugin for PathfindingPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_system(calculate_path)
|
app.register_type::<Destination>()
|
||||||
|
.register_type::<NoPath>()
|
||||||
|
.register_type::<Path>()
|
||||||
|
.register_type::<CostMap>()
|
||||||
|
.add_system(calculate_path)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_destination)
|
.add_system_to_stage(CoreStage::PostUpdate, remove_destination)
|
||||||
.add_system(poll_tasks)
|
.add_system(poll_tasks)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, negotiate_path);
|
.add_system_to_stage(CoreStage::PostUpdate, negotiate_path);
|
||||||
|
|
|
@ -8,10 +8,11 @@ use crate::{
|
||||||
sound::SoundIcon,
|
sound::SoundIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Default)]
|
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
struct Behind;
|
struct Behind;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Resource, Clone, Copy, Debug)]
|
||||||
pub struct PitchShiftConfig {
|
pub struct PitchShiftConfig {
|
||||||
pub downshift_behind: bool,
|
pub downshift_behind: bool,
|
||||||
pub downshift: f64,
|
pub downshift: f64,
|
||||||
|
@ -63,10 +64,10 @@ fn tag_behind(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
#[derive(Resource, Clone, Debug, Default, Deref, DerefMut)]
|
||||||
struct LastIconPitch(HashMap<Entity, f64>);
|
struct LastIconPitch(HashMap<Entity, f64>);
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
#[derive(Resource, Clone, Debug, Default, Deref, DerefMut)]
|
||||||
struct LastSoundPitch(HashMap<Entity, f64>);
|
struct LastSoundPitch(HashMap<Entity, f64>);
|
||||||
|
|
||||||
fn behind_added(
|
fn behind_added(
|
||||||
|
@ -158,7 +159,8 @@ pub struct PitchShiftPlugin;
|
||||||
|
|
||||||
impl Plugin for PitchShiftPlugin {
|
impl Plugin for PitchShiftPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<PitchShiftConfig>()
|
app.register_type::<Behind>()
|
||||||
|
.init_resource::<PitchShiftConfig>()
|
||||||
.init_resource::<LastIconPitch>()
|
.init_resource::<LastIconPitch>()
|
||||||
.init_resource::<LastSoundPitch>()
|
.init_resource::<LastSoundPitch>()
|
||||||
.add_system_to_stage(CoreStage::PreUpdate, tag_behind)
|
.add_system_to_stage(CoreStage::PreUpdate, tag_behind)
|
||||||
|
|
|
@ -12,7 +12,8 @@ use crate::{
|
||||||
visibility::{VisibilityChanged, Visible, VisibleEntities},
|
visibility::{VisibilityChanged, Visible, VisibleEntities},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component, Clone, Debug)]
|
#[derive(Component, Clone, Debug, Reflect)]
|
||||||
|
#[reflect(Component)]
|
||||||
pub struct SoundIcon {
|
pub struct SoundIcon {
|
||||||
pub buffer: Handle<Buffer>,
|
pub buffer: Handle<Buffer>,
|
||||||
pub gain: f64,
|
pub gain: f64,
|
||||||
|
@ -27,7 +28,7 @@ impl Default for SoundIcon {
|
||||||
buffer: default(),
|
buffer: default(),
|
||||||
gain: 1.,
|
gain: 1.,
|
||||||
pitch: 1.,
|
pitch: 1.,
|
||||||
interval: Some(Timer::from_seconds(seconds, true)),
|
interval: Some(Timer::from_seconds(seconds, TimerMode::Repeating)),
|
||||||
};
|
};
|
||||||
if let Some(ref mut interval) = icon.interval {
|
if let Some(ref mut interval) = icon.interval {
|
||||||
let seconds = Duration::from_secs_f32(seconds - 0.1);
|
let seconds = Duration::from_secs_f32(seconds - 0.1);
|
||||||
|
@ -71,7 +72,7 @@ fn update<S>(
|
||||||
) where
|
) where
|
||||||
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
||||||
{
|
{
|
||||||
if !(*config).states.is_empty() && !config.states.contains(state.current()) {
|
if !config.states.is_empty() && !config.states.contains(state.current()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for visible in viewers.iter() {
|
for visible in viewers.iter() {
|
||||||
|
@ -166,7 +167,7 @@ fn reset_timer_on_visibility_gain(
|
||||||
if let Ok(children) = children.get(*viewed) {
|
if let Ok(children) = children.get(*viewed) {
|
||||||
for child in children.iter() {
|
for child in children.iter() {
|
||||||
if icons.get(*child).is_ok() {
|
if icons.get(*child).is_ok() {
|
||||||
targets.push(&*child);
|
targets.push(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +183,7 @@ fn reset_timer_on_visibility_gain(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Resource, Clone, Debug, Default)]
|
||||||
pub struct SoundIconConfig<S> {
|
pub struct SoundIconConfig<S> {
|
||||||
pub states: Vec<S>,
|
pub states: Vec<S>,
|
||||||
}
|
}
|
||||||
|
@ -200,7 +201,8 @@ where
|
||||||
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
|
||||||
{
|
{
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_system(added)
|
app.register_type::<SoundIcon>()
|
||||||
|
.add_system(added)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, update::<S>)
|
.add_system_to_stage(CoreStage::PostUpdate, update::<S>)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
CoreStage::PostUpdate,
|
CoreStage::PostUpdate,
|
||||||
|
|
|
@ -4,7 +4,8 @@ use bevy_synthizer::{Listener, Sound};
|
||||||
|
|
||||||
use crate::{commands::RunIfExistsExt, core::GlobalTransformExt};
|
use crate::{commands::RunIfExistsExt, core::GlobalTransformExt};
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug)]
|
#[derive(Component, Default, Reflect, Clone, Copy, Debug)]
|
||||||
|
#[reflect(Component)]
|
||||||
pub struct Volumetric;
|
pub struct Volumetric;
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
|
@ -41,7 +42,7 @@ fn update(
|
||||||
fn removed(mut commands: Commands, removed: RemovedComponents<Volumetric>) {
|
fn removed(mut commands: Commands, removed: RemovedComponents<Volumetric>) {
|
||||||
for entity in removed.iter() {
|
for entity in removed.iter() {
|
||||||
commands.run_if_exists(entity, |mut entity| {
|
commands.run_if_exists(entity, |mut entity| {
|
||||||
entity.insert_bundle(TransformBundle::default());
|
entity.insert(TransformBundle::default());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,10 +51,11 @@ pub struct VolumetricPlugin;
|
||||||
|
|
||||||
impl Plugin for VolumetricPlugin {
|
impl Plugin for VolumetricPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_system_to_stage(
|
app.register_type::<Volumetric>()
|
||||||
CoreStage::PostUpdate,
|
.add_system_to_stage(
|
||||||
update.before(TransformSystem::TransformPropagate),
|
CoreStage::PostUpdate,
|
||||||
)
|
update.before(TransformSystem::TransformPropagate),
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, removed);
|
)
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, removed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -354,7 +354,7 @@ fn remove_visible(
|
||||||
&viewer_entity,
|
&viewer_entity,
|
||||||
&mut visible_entities,
|
&mut visible_entities,
|
||||||
start,
|
start,
|
||||||
&*rapier_context,
|
&rapier_context,
|
||||||
&visible,
|
&visible,
|
||||||
&obstructions,
|
&obstructions,
|
||||||
&mut changed,
|
&mut changed,
|
||||||
|
@ -422,7 +422,7 @@ fn log_visible(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let VisibilityChanged::Lost { viewed, .. } = event {
|
} else if let VisibilityChanged::Lost { viewed, .. } = event {
|
||||||
recently_lost.insert(*viewed, Timer::from_seconds(2., false));
|
recently_lost.insert(*viewed, Timer::from_seconds(2., TimerMode::Once));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user