Compare commits

...

2 Commits

Author SHA1 Message Date
3a6ede0428 Update CI configuration.
Some checks failed
continuous-integration/drone/push Build is failing
2022-12-19 14:10:21 -06:00
b1a11de050 Upgrade to Bevy 0.9. 2022-12-19 14:08:31 -06:00
13 changed files with 138 additions and 108 deletions

View File

@ -8,7 +8,7 @@ steps:
commands:
- rustup component add clippy rustfmt
- 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 test --no-default-features --features=speech_dispatcher_0_10
- cargo clippy --no-default-features --features=speech_dispatcher_0_10

View File

@ -8,11 +8,12 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
speech_dispatcher_0_9 = ["bevy_tts/speech_dispatcher_0_9"]
speech_dispatcher_0_10 = ["bevy_tts/speech_dispatcher_0_10"]
speech_dispatcher_0_11 = ["bevy_tts/speech_dispatcher_0_11"]
[dependencies.bevy]
version = "0.8"
version = "0.9"
default-features = false
features = [
"bevy_gilrs",
@ -25,18 +26,18 @@ features = [
[dependencies]
backtrace = "0.3"
bevy_rapier2d = "0.17"
bevy_synthizer = { git = "https://labs.lightsout.games/projects/bevy_synthizer" }
bevy_tts = { version = "0.1", default-features = false, features = ["tolk"] }
bevy_rapier2d = "0.19"
bevy_synthizer = "0.1"
bevy_tts = { version = "0.2", default-features = false, features = ["tolk"] }
coord_2d = "0.3"
futures-lite = "1"
gilrs = "0.9"
gilrs = "0.10"
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"
once_cell = "1"
pathfinding = "3"
pathfinding = "4"
rand = "0.8"
sentry = "0.27"
sentry = "0.29"
serde = "1"
shadowcast = "0.8"

View File

@ -7,11 +7,11 @@ use std::{
sync::RwLock,
};
use bevy::{ecs::query::WorldQuery, prelude::*, utils::FloatOrd};
use bevy::{app::PluginGroupBuilder, ecs::query::WorldQuery, prelude::*, utils::FloatOrd};
use bevy_rapier2d::{
parry::query::{closest_points, distance, ClosestPoints},
prelude::*,
rapier::{math::Isometry, prelude::AABB},
rapier::{math::Isometry, prelude::Aabb},
};
use once_cell::sync::Lazy;
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 {
North,
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 {
#[default]
North,
East,
South,
@ -570,7 +572,7 @@ impl GlobalTransformExt for GlobalTransform {
}
#[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)]
#[reflect(Component)]
@ -642,7 +644,7 @@ fn setup(core_config: Res<CoreConfig>) {
*mode = core_config.relative_direction_mode;
}
#[derive(Clone, Copy, Debug)]
#[derive(Resource, Clone, Copy, Debug)]
pub struct CoreConfig {
pub relative_direction_mode: RelativeDirectionMode,
pub pixels_per_unit: u8,
@ -678,7 +680,8 @@ impl<RapierUserData: 'static + WorldQuery + Send + Sync> Plugin for CorePlugin<R
app.insert_resource(CoreConfig::default());
}
let config = *app.world.get_resource::<CoreConfig>().unwrap();
app.add_plugin(RapierPhysicsPlugin::<RapierUserData>::pixels_per_meter(
app.register_type::<CardinalDirection>()
.add_plugin(RapierPhysicsPlugin::<RapierUserData>::pixels_per_meter(
config.pixels_per_unit as f32,
))
.add_startup_system(setup)
@ -697,10 +700,10 @@ impl<RapierUserData> Default for CorePlugins<RapierUserData> {
impl<RapierUserData: 'static + WorldQuery + Send + Sync> PluginGroup
for CorePlugins<RapierUserData>
{
fn build(&mut self, group: &mut bevy::app::PluginGroupBuilder) {
group
fn build(self) -> PluginGroupBuilder {
PluginGroupBuilder::start::<Self>()
.add(crate::bevy_tts::TtsPlugin)
.add(crate::bevy_synthizer::SynthizerPlugin)
.add(CorePlugin::<RapierUserData>::default());
.add(crate::bevy_synthizer::SynthizerPlugin::default())
.add(CorePlugin::<RapierUserData>::default())
}
}

View File

@ -4,6 +4,9 @@ use std::{panic, thread};
use backtrace::Backtrace;
use bevy::prelude::*;
#[derive(Resource)]
struct Guard(sentry::ClientInitGuard);
pub fn error_handler(In(result): In<Result<(), Box<dyn Error>>>) {
if let Err(e) = result {
error!("{}", e);
@ -44,7 +47,7 @@ fn init_panic_handler() {
}));
}
#[derive(Clone, Debug, Default)]
#[derive(Resource, Clone, Debug, Default)]
pub struct ErrorConfig {
pub sentry_dsn: Option<String>,
pub version: Option<String>,
@ -57,7 +60,7 @@ impl Plugin for ErrorPlugin {
init_panic_handler();
if let Some(config) = app.world.get_resource::<ErrorConfig>() {
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((
dsn.as_str(),
sentry::ClientOptions {
@ -65,7 +68,7 @@ impl Plugin for ErrorPlugin {
..default()
},
));
app.insert_resource(guard);
app.insert_resource(Guard(guard));
}
}
}

View File

@ -41,7 +41,9 @@ pub struct Exploring(pub (f32, f32));
impl_pointlike_for_tuple_component!(Exploring);
#[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)]
#[reflect(Component)]
@ -57,7 +59,7 @@ fn exploration_type_change<T, S>(
features: Query<&T>,
) -> Result<(), Box<dyn Error>>
where
T: Component + Copy + Ord,
T: Component + Default + Copy + Ord,
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
{
for (actions, visible, mut focused) in explorers.iter_mut() {
@ -123,7 +125,7 @@ fn exploration_type_focus<T, S>(
features: Query<(Entity, &Transform, &T)>,
) -> Result<(), Box<dyn Error>>
where
T: Component + PartialEq,
T: Component + Default + PartialEq,
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
{
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>>
where
T: Component + Copy + Into<String>,
T: Component + Default + Copy + Into<String>,
{
for (focused, changed) in focused.iter() {
if changed.is_added() {
@ -367,7 +369,7 @@ fn cleanup(
}
}
#[derive(Clone, Debug)]
#[derive(Resource, Clone, Debug)]
pub struct ExplorationConfig<S> {
pub exploration_control_states: Vec<S>,
}
@ -411,16 +413,17 @@ where
.clone();
app.register_type::<ExplorationFocused>()
.register_type::<Mappable>()
.register_type::<Explorable>()
.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() {
app.add_system(exploration_focus::<S, D>)
.add_system(exploration_type_focus::<T, S>.chain(error_handler))
.add_system(exploration_type_change::<T, S>.chain(error_handler))
.add_system(exploration_type_focus::<T, S>.pipe(error_handler))
.add_system(exploration_type_change::<T, S>.pipe(error_handler))
.add_system(navigate_to_explored::<S, D>)
.add_system_to_stage(
CoreStage::PostUpdate,
exploration_type_changed_announcement::<T>.chain(error_handler),
exploration_type_changed_announcement::<T>.pipe(error_handler),
);
} else {
let states = config.exploration_control_states;
@ -428,11 +431,11 @@ where
app.add_system_set(
SystemSet::on_update(state.clone())
.with_system(exploration_focus::<S, D>)
.with_system(exploration_type_focus::<T, S>.chain(error_handler))
.with_system(exploration_type_change::<T, S>.chain(error_handler))
.with_system(exploration_type_focus::<T, S>.pipe(error_handler))
.with_system(exploration_type_change::<T, S>.pipe(error_handler))
.with_system(navigate_to_explored::<S, D>)
.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));

View File

@ -17,7 +17,7 @@ impl Log {
}
}
#[derive(Component, Clone, Debug)]
#[derive(Component, Clone, Debug, Reflect)]
pub struct LogEntry {
pub time: Instant,
pub message: String,
@ -33,7 +33,7 @@ impl From<String> for LogEntry {
}
fn setup(mut commands: Commands) {
commands.spawn().insert(Log::default());
commands.spawn(Log::default());
}
fn read_log(
@ -59,7 +59,8 @@ pub struct LogPlugin;
impl Plugin for LogPlugin {
fn build(&self, app: &mut App) {
app.add_startup_system(setup)
.add_system_to_stage(CoreStage::PostUpdate, read_log.chain(error_handler));
app.register_type::<LogEntry>()
.add_startup_system(setup)
.add_system_to_stage(CoreStage::PostUpdate, read_log.pipe(error_handler));
}
}

View File

@ -78,7 +78,7 @@ impl ITileType for Tile {
}
}
#[derive(Clone, Debug, Default)]
#[derive(Resource, Clone, Debug, Default)]
pub struct MapConfig {
pub start_revealed: bool,
}
@ -151,22 +151,22 @@ impl<D: Clone + Default> MapFilter<D> for GridBuilder {
if field.has_passage(&North) {
let x = x_offset + half_width;
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) {
let x = x_offset + half_width;
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) {
let x = x_offset + self.room_width;
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) {
let x = x_offset;
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,13 +198,16 @@ fn spawn_colliders<D: 'static + Clone + Default + Send + Sync>(
for x in 0..map.width {
if let Some(tile) = map.at(x, y) {
if tile.blocks_motion() {
let id =
commands
.spawn_bundle(TransformBundle::from_transform(
Transform::from_xyz(x as f32 + 0.5, y as f32 + 0.5, 0.),
let id = commands
.spawn((
TransformBundle::from_transform(Transform::from_xyz(
x as f32 + 0.5,
y as f32 + 0.5,
0.,
)),
Collider::cuboid(0.5, 0.5),
MapObstruction,
))
.insert(Collider::cuboid(0.5, 0.5))
.insert(MapObstruction)
.id();
if tile.blocks_visibility() {
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.);
let aabb = shape.raw.compute_aabb(&position);
let id = commands
.spawn_bundle(TransformBundle::from_transform(Transform::from_xyz(
.spawn((
TransformBundle::from_transform(Transform::from_xyz(
position.translation.x,
position.translation.y,
0.,
)))
.insert(shape)
.insert(Sensor)
.insert(ActiveEvents::COLLISION_EVENTS)
.insert(Area(aabb))
.insert(Zone)
)),
shape,
Sensor,
ActiveEvents::COLLISION_EVENTS,
Area(aabb),
Zone,
))
.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 {
let portal = commands
.spawn_bundle(PortalBundle {
.spawn(PortalBundle {
transform: Transform::from_translation(Vec3::new(x, y, 0.)),
..default()
})

View File

@ -49,19 +49,22 @@ pub struct RotationSpeed(pub Angle);
#[reflect(Component)]
pub struct Speed(pub f32);
#[derive(Component, Deref, DerefMut)]
#[derive(Deref, DerefMut)]
struct SnapTimer(Timer);
impl Default for SnapTimer {
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>(
mut commands: Commands,
config: Res<NavigationConfig<S>>,
snap_timers: Res<HashMap<Entity, SnapTimer>>,
snap_timers: Res<SnapTimers>,
mut query: Query<(
Entity,
&mut ActionState<NavigationAction>,
@ -118,14 +121,14 @@ fn movement_controls<S>(
.axis_pair = Some(DualAxisData::from_xy(v));
}
}
if actions.released(NavigationAction::Move) {
if actions.axis_pair(NavigationAction::Move).is_some() {
if actions.released(NavigationAction::Move)
&& actions.axis_pair(NavigationAction::Move).is_some()
{
actions.press(NavigationAction::SetLinearVelocity);
actions
.action_data_mut(NavigationAction::SetLinearVelocity)
.axis_pair = None;
}
}
if actions.pressed(NavigationAction::SetLinearVelocity) {
if let Some(pair) = actions.axis_pair(NavigationAction::SetLinearVelocity) {
velocity.linvel = pair.into();
@ -167,7 +170,7 @@ fn movement_controls<S>(
fn snap(
mut tts: ResMut<Tts>,
mut snap_timers: ResMut<HashMap<Entity, SnapTimer>>,
mut snap_timers: ResMut<SnapTimers>,
mut query: Query<
(
Entity,
@ -210,7 +213,7 @@ fn snap(
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() {
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 forward_movement_factor: f32,
pub backward_movement_factor: f32,
@ -383,14 +386,15 @@ where
.get_resource::<NavigationConfig<S>>()
.unwrap()
.clone();
app.init_resource::<HashMap<Entity, SnapTimer>>()
app.init_resource::<SnapTimers>()
.register_type::<MaxSpeed>()
.register_type::<RotationSpeed>()
.register_type::<Speed>()
.add_plugin(InputManagerPlugin::<NavigationAction>::default())
.add_system_to_stage(CoreStage::PreUpdate, update_direction)
.add_system_to_stage(CoreStage::PostUpdate, remove_direction)
.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(limit_speed)
.add_system_to_stage(CoreStage::PostUpdate, remove_speed)
@ -402,14 +406,14 @@ where
.label(MOVEMENT_CONTROLS)
.after(limit_speed),
)
.add_system(snap.chain(error_handler).before(MOVEMENT_CONTROLS));
.add_system(snap.pipe(error_handler).before(MOVEMENT_CONTROLS));
} else {
let states = config.movement_control_states;
for state in states {
app.add_system_set(
SystemSet::on_update(state)
.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)),
);
}
}

View File

@ -59,7 +59,7 @@ impl CostMap {
}
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;
}
}
@ -109,8 +109,8 @@ fn find_path_for_shape(
&start.i32(),
|p| {
let mut successors: Vec<((i32, i32), u32)> = vec![];
let x = p.0 as i32;
let y = p.1 as i32;
let x = p.0;
let y = p.1;
let exits = vec![
((x - 1, y), 1.),
((x + 1, y), 1.),
@ -325,7 +325,11 @@ pub struct PathfindingPlugin;
impl Plugin for PathfindingPlugin {
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(poll_tasks)
.add_system_to_stage(CoreStage::PostUpdate, negotiate_path);

View File

@ -8,10 +8,11 @@ use crate::{
sound::SoundIcon,
};
#[derive(Component, Clone, Copy, Debug, Default)]
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
#[reflect(Component)]
struct Behind;
#[derive(Clone, Copy, Debug)]
#[derive(Resource, Clone, Copy, Debug)]
pub struct PitchShiftConfig {
pub downshift_behind: bool,
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>);
#[derive(Clone, Debug, Default, Deref, DerefMut)]
#[derive(Resource, Clone, Debug, Default, Deref, DerefMut)]
struct LastSoundPitch(HashMap<Entity, f64>);
fn behind_added(
@ -158,7 +159,8 @@ pub struct PitchShiftPlugin;
impl Plugin for PitchShiftPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<PitchShiftConfig>()
app.register_type::<Behind>()
.init_resource::<PitchShiftConfig>()
.init_resource::<LastIconPitch>()
.init_resource::<LastSoundPitch>()
.add_system_to_stage(CoreStage::PreUpdate, tag_behind)

View File

@ -12,7 +12,8 @@ use crate::{
visibility::{VisibilityChanged, Visible, VisibleEntities},
};
#[derive(Component, Clone, Debug)]
#[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component)]
pub struct SoundIcon {
pub buffer: Handle<Buffer>,
pub gain: f64,
@ -27,7 +28,7 @@ impl Default for SoundIcon {
buffer: default(),
gain: 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 {
let seconds = Duration::from_secs_f32(seconds - 0.1);
@ -71,7 +72,7 @@ fn update<S>(
) where
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;
}
for visible in viewers.iter() {
@ -166,7 +167,7 @@ fn reset_timer_on_visibility_gain(
if let Ok(children) = children.get(*viewed) {
for child in children.iter() {
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 states: Vec<S>,
}
@ -200,7 +201,8 @@ where
S: 'static + Clone + Debug + Eq + Hash + Send + Sync,
{
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,

View File

@ -4,7 +4,8 @@ use bevy_synthizer::{Listener, Sound};
use crate::{commands::RunIfExistsExt, core::GlobalTransformExt};
#[derive(Component, Clone, Copy, Debug)]
#[derive(Component, Default, Reflect, Clone, Copy, Debug)]
#[reflect(Component)]
pub struct Volumetric;
fn update(
@ -41,7 +42,7 @@ fn update(
fn removed(mut commands: Commands, removed: RemovedComponents<Volumetric>) {
for entity in removed.iter() {
commands.run_if_exists(entity, |mut entity| {
entity.insert_bundle(TransformBundle::default());
entity.insert(TransformBundle::default());
});
}
}
@ -50,7 +51,8 @@ pub struct VolumetricPlugin;
impl Plugin for VolumetricPlugin {
fn build(&self, app: &mut App) {
app.add_system_to_stage(
app.register_type::<Volumetric>()
.add_system_to_stage(
CoreStage::PostUpdate,
update.before(TransformSystem::TransformPropagate),
)

View File

@ -354,7 +354,7 @@ fn remove_visible(
&viewer_entity,
&mut visible_entities,
start,
&*rapier_context,
&rapier_context,
&visible,
&obstructions,
&mut changed,
@ -422,7 +422,7 @@ fn log_visible(
}
}
} 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));
}
}
}