This commit is contained in:
parent
f3d2778830
commit
bd899b9c8e
10
src/core.rs
10
src/core.rs
|
@ -8,7 +8,12 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::{core::FloatOrd, ecs::query::WorldQuery, prelude::*};
|
use bevy::{core::FloatOrd, ecs::query::WorldQuery, prelude::*};
|
||||||
use bevy_rapier2d::{na, parry::query::ClosestPoints, prelude::*, rapier::math::Isometry};
|
use bevy_rapier2d::{
|
||||||
|
na,
|
||||||
|
parry::query::ClosestPoints,
|
||||||
|
prelude::*,
|
||||||
|
rapier::{math::Isometry, prelude::AABB},
|
||||||
|
};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -528,6 +533,9 @@ impl GlobalTransformExt for GlobalTransform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, PartialEq)]
|
||||||
|
pub struct Area(pub AABB);
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
#[derive(Component, Clone, Copy, Debug, Default, Reflect)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct Player;
|
pub struct Player;
|
||||||
|
|
54
src/map.rs
54
src/map.rs
|
@ -4,7 +4,6 @@ use bevy::prelude::*;
|
||||||
use bevy_rapier2d::{
|
use bevy_rapier2d::{
|
||||||
na::{Isometry2, Vector2},
|
na::{Isometry2, Vector2},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rapier::prelude::AABB,
|
|
||||||
};
|
};
|
||||||
pub use here_be_dragons::Map as MapgenMap;
|
pub use here_be_dragons::Map as MapgenMap;
|
||||||
use here_be_dragons::{geometry::Rect as MRect, MapFilter, Tile};
|
use here_be_dragons::{geometry::Rect as MRect, MapFilter, Tile};
|
||||||
|
@ -12,16 +11,11 @@ use maze_generator::{prelude::*, recursive_backtracking::RbGenerator};
|
||||||
use rand::prelude::StdRng;
|
use rand::prelude::StdRng;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::{Player, PointLike},
|
core::{Area, PointLike},
|
||||||
exploration::Mappable,
|
exploration::Mappable,
|
||||||
log::Log,
|
|
||||||
utils::target_and_other,
|
|
||||||
visibility::Visible,
|
visibility::Visible,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, PartialEq)]
|
|
||||||
pub struct Area(pub AABB);
|
|
||||||
|
|
||||||
#[derive(Component, Clone, Default, Deref, DerefMut)]
|
#[derive(Component, Clone, Default, Deref, DerefMut)]
|
||||||
pub struct Map<D: 'static + Clone + Default + Send + Sync>(pub MapgenMap<D>);
|
pub struct Map<D: 'static + Clone + Default + Send + Sync>(pub MapgenMap<D>);
|
||||||
|
|
||||||
|
@ -86,16 +80,12 @@ impl ITileType for Tile {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MapConfig {
|
pub struct MapConfig {
|
||||||
pub describe_undescribed_areas: bool,
|
|
||||||
pub speak_area_descriptions: bool,
|
|
||||||
pub start_revealed: bool,
|
pub start_revealed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MapConfig {
|
impl Default for MapConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
describe_undescribed_areas: false,
|
|
||||||
speak_area_descriptions: true,
|
|
||||||
start_revealed: false,
|
start_revealed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,44 +314,6 @@ fn spawn_portal_colliders<D: 'static + Clone + Default + Send + Sync>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn area_description(
|
|
||||||
mut events: EventReader<CollisionEvent>,
|
|
||||||
areas: Query<(&Area, Option<&Name>)>,
|
|
||||||
players: Query<&Player>,
|
|
||||||
config: Res<MapConfig>,
|
|
||||||
mut log: Query<&mut Log>,
|
|
||||||
) {
|
|
||||||
for event in events.iter() {
|
|
||||||
let (entity1, entity2, started) = match event {
|
|
||||||
CollisionEvent::Started(collider1, collider2, _) => (collider1, collider2, true),
|
|
||||||
CollisionEvent::Stopped(collider1, collider2, _) => (collider1, collider2, false),
|
|
||||||
};
|
|
||||||
if let Some((area, other)) = target_and_other(*entity1, *entity2, &|v| areas.get(v).is_ok())
|
|
||||||
{
|
|
||||||
if players.get(other).is_ok() {
|
|
||||||
if let Ok((aabb, area_name)) = areas.get(area) {
|
|
||||||
let name = if let Some(name) = area_name {
|
|
||||||
Some(name.to_string())
|
|
||||||
} else if config.describe_undescribed_areas {
|
|
||||||
Some(format!("{}-by-{} area", aabb.extents().x, aabb.extents().y))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
if let Some(name) = name {
|
|
||||||
if let Ok(mut log) = log.get_single_mut() {
|
|
||||||
if started {
|
|
||||||
log.push(format!("Entering {name}."));
|
|
||||||
} else {
|
|
||||||
log.push(format!("Leaving {name}."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MapPlugin<D: 'static + Clone + Default + Send + Sync>(PhantomData<D>);
|
pub struct MapPlugin<D: 'static + Clone + Default + Send + Sync>(PhantomData<D>);
|
||||||
|
|
||||||
impl<D: 'static + Clone + Default + Send + Sync> Default for MapPlugin<D> {
|
impl<D: 'static + Clone + Default + Send + Sync> Default for MapPlugin<D> {
|
||||||
|
@ -375,13 +327,9 @@ impl<D: 'static + Clone + Default + Send + Sync> Plugin for MapPlugin<D> {
|
||||||
if !app.world.contains_resource::<MapConfig>() {
|
if !app.world.contains_resource::<MapConfig>() {
|
||||||
app.insert_resource(MapConfig::default());
|
app.insert_resource(MapConfig::default());
|
||||||
}
|
}
|
||||||
let config = app.world.get_resource::<MapConfig>().unwrap().clone();
|
|
||||||
app.register_type::<Portal>()
|
app.register_type::<Portal>()
|
||||||
.add_system_to_stage(CoreStage::PreUpdate, spawn_colliders::<D>)
|
.add_system_to_stage(CoreStage::PreUpdate, spawn_colliders::<D>)
|
||||||
.add_system_to_stage(CoreStage::PreUpdate, spawn_portals::<D>)
|
.add_system_to_stage(CoreStage::PreUpdate, spawn_portals::<D>)
|
||||||
.add_system_to_stage(CoreStage::PreUpdate, spawn_portal_colliders::<D>);
|
.add_system_to_stage(CoreStage::PreUpdate, spawn_portal_colliders::<D>);
|
||||||
if config.speak_area_descriptions {
|
|
||||||
app.add_system_to_stage(CoreStage::PostUpdate, area_description);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,12 @@ use bevy_tts::Tts;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
commands::RunIfExistsExt,
|
commands::RunIfExistsExt,
|
||||||
core::{Angle, CardinalDirection, GlobalTransformExt, Player},
|
core::{Angle, Area, CardinalDirection, GlobalTransformExt, Player},
|
||||||
error::error_handler,
|
error::error_handler,
|
||||||
exploration::{ExplorationFocused, Exploring},
|
exploration::{ExplorationFocused, Exploring},
|
||||||
|
log::Log,
|
||||||
pathfinding::Destination,
|
pathfinding::Destination,
|
||||||
|
utils::target_and_other,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
#[derive(Component, Clone, Copy, Debug, Deref, DerefMut, Reflect)]
|
||||||
|
@ -322,6 +324,50 @@ fn remove_speed(removed: RemovedComponents<Speed>, mut query: Query<&mut Velocit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn log_area_descriptions<S, A>(
|
||||||
|
mut events: EventReader<CollisionEvent>,
|
||||||
|
areas: Query<(&Area, Option<&Name>)>,
|
||||||
|
players: Query<&Player>,
|
||||||
|
config: Res<NavigationConfig<S, A>>,
|
||||||
|
mut log: Query<&mut Log>,
|
||||||
|
) where
|
||||||
|
S: 'static + Send + Sync,
|
||||||
|
A: 'static + Send + Sync,
|
||||||
|
{
|
||||||
|
if !config.log_area_descriptions {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for event in events.iter() {
|
||||||
|
let (entity1, entity2, started) = match event {
|
||||||
|
CollisionEvent::Started(collider1, collider2, _) => (collider1, collider2, true),
|
||||||
|
CollisionEvent::Stopped(collider1, collider2, _) => (collider1, collider2, false),
|
||||||
|
};
|
||||||
|
if let Some((area, other)) = target_and_other(*entity1, *entity2, &|v| areas.get(v).is_ok())
|
||||||
|
{
|
||||||
|
if players.get(other).is_ok() {
|
||||||
|
if let Ok((aabb, area_name)) = areas.get(area) {
|
||||||
|
let name = if let Some(name) = area_name {
|
||||||
|
Some(name.to_string())
|
||||||
|
} else if config.describe_undescribed_areas {
|
||||||
|
Some(format!("{}-by-{} area", aabb.extents().x, aabb.extents().y))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(name) = name {
|
||||||
|
if let Ok(mut log) = log.get_single_mut() {
|
||||||
|
if started {
|
||||||
|
log.push(format!("Entering {name}."));
|
||||||
|
} else {
|
||||||
|
log.push(format!("Leaving {name}."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct NavigationConfig<S, A> {
|
pub struct NavigationConfig<S, A> {
|
||||||
pub action_backward: Option<A>,
|
pub action_backward: Option<A>,
|
||||||
|
@ -340,6 +386,8 @@ pub struct NavigationConfig<S, A> {
|
||||||
pub strafe_movement_factor: f32,
|
pub strafe_movement_factor: f32,
|
||||||
pub sprint_movement_factor: f32,
|
pub sprint_movement_factor: f32,
|
||||||
pub movement_control_states: Vec<S>,
|
pub movement_control_states: Vec<S>,
|
||||||
|
pub describe_undescribed_areas: bool,
|
||||||
|
pub log_area_descriptions: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, A> Default for NavigationConfig<S, A> {
|
impl<S, A> Default for NavigationConfig<S, A> {
|
||||||
|
@ -361,6 +409,8 @@ impl<S, A> Default for NavigationConfig<S, A> {
|
||||||
strafe_movement_factor: 1.,
|
strafe_movement_factor: 1.,
|
||||||
sprint_movement_factor: 3.,
|
sprint_movement_factor: 3.,
|
||||||
movement_control_states: vec![],
|
movement_control_states: vec![],
|
||||||
|
describe_undescribed_areas: false,
|
||||||
|
log_area_descriptions: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,7 +446,8 @@ where
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_direction)
|
.add_system_to_stage(CoreStage::PostUpdate, remove_direction)
|
||||||
.add_system(speak_direction.chain(error_handler))
|
.add_system(speak_direction.chain(error_handler))
|
||||||
.add_system(add_speed)
|
.add_system(add_speed)
|
||||||
.add_system_to_stage(CoreStage::PostUpdate, remove_speed);
|
.add_system_to_stage(CoreStage::PostUpdate, remove_speed)
|
||||||
|
.add_system_to_stage(CoreStage::PostUpdate, log_area_descriptions::<S, A>);
|
||||||
const MOVEMENT_CONTROLS: &str = "MOVEMENT_CONTROLS";
|
const MOVEMENT_CONTROLS: &str = "MOVEMENT_CONTROLS";
|
||||||
if config.movement_control_states.is_empty() {
|
if config.movement_control_states.is_empty() {
|
||||||
app.add_system(movement_controls::<S, A>.label(MOVEMENT_CONTROLS))
|
app.add_system(movement_controls::<S, A>.label(MOVEMENT_CONTROLS))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user