Compare commits
2 Commits
1721dc98f8
...
bd899b9c8e
Author | SHA1 | Date | |
---|---|---|---|
bd899b9c8e | |||
f3d2778830 |
10
src/core.rs
10
src/core.rs
|
@ -8,7 +8,12 @@ use std::{
|
|||
};
|
||||
|
||||
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 rand::prelude::*;
|
||||
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)]
|
||||
#[reflect(Component)]
|
||||
pub struct Player;
|
||||
|
|
54
src/map.rs
54
src/map.rs
|
@ -4,7 +4,6 @@ use bevy::prelude::*;
|
|||
use bevy_rapier2d::{
|
||||
na::{Isometry2, Vector2},
|
||||
prelude::*,
|
||||
rapier::prelude::AABB,
|
||||
};
|
||||
pub use here_be_dragons::Map as MapgenMap;
|
||||
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 crate::{
|
||||
core::{Player, PointLike},
|
||||
core::{Area, PointLike},
|
||||
exploration::Mappable,
|
||||
log::Log,
|
||||
utils::target_and_other,
|
||||
visibility::Visible,
|
||||
};
|
||||
|
||||
#[derive(Component, Copy, Clone, Debug, Deref, DerefMut, PartialEq)]
|
||||
pub struct Area(pub AABB);
|
||||
|
||||
#[derive(Component, Clone, Default, Deref, DerefMut)]
|
||||
pub struct Map<D: 'static + Clone + Default + Send + Sync>(pub MapgenMap<D>);
|
||||
|
||||
|
@ -86,16 +80,12 @@ impl ITileType for Tile {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MapConfig {
|
||||
pub describe_undescribed_areas: bool,
|
||||
pub speak_area_descriptions: bool,
|
||||
pub start_revealed: bool,
|
||||
}
|
||||
|
||||
impl Default for MapConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
describe_undescribed_areas: false,
|
||||
speak_area_descriptions: true,
|
||||
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>);
|
||||
|
||||
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>() {
|
||||
app.insert_resource(MapConfig::default());
|
||||
}
|
||||
let config = app.world.get_resource::<MapConfig>().unwrap().clone();
|
||||
app.register_type::<Portal>()
|
||||
.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_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::{
|
||||
commands::RunIfExistsExt,
|
||||
core::{Angle, CardinalDirection, Player, GlobalTransformExt},
|
||||
core::{Angle, Area, CardinalDirection, GlobalTransformExt, Player},
|
||||
error::error_handler,
|
||||
exploration::{ExplorationFocused, Exploring},
|
||||
log::Log,
|
||||
pathfinding::Destination,
|
||||
utils::target_and_other,
|
||||
};
|
||||
|
||||
#[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)]
|
||||
pub struct NavigationConfig<S, A> {
|
||||
pub action_backward: Option<A>,
|
||||
|
@ -340,6 +386,8 @@ pub struct NavigationConfig<S, A> {
|
|||
pub strafe_movement_factor: f32,
|
||||
pub sprint_movement_factor: f32,
|
||||
pub movement_control_states: Vec<S>,
|
||||
pub describe_undescribed_areas: bool,
|
||||
pub log_area_descriptions: bool,
|
||||
}
|
||||
|
||||
impl<S, A> Default for NavigationConfig<S, A> {
|
||||
|
@ -361,6 +409,8 @@ impl<S, A> Default for NavigationConfig<S, A> {
|
|||
strafe_movement_factor: 1.,
|
||||
sprint_movement_factor: 3.,
|
||||
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(speak_direction.chain(error_handler))
|
||||
.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";
|
||||
if config.movement_control_states.is_empty() {
|
||||
app.add_system(movement_controls::<S, A>.label(MOVEMENT_CONTROLS))
|
||||
|
|
Loading…
Reference in New Issue
Block a user