This commit is contained in:
Joshua Barretto 2023-01-01 16:59:12 +00:00
parent 558b5f7c3a
commit acecc62d40
7 changed files with 68 additions and 45 deletions

View File

@ -1,3 +1,4 @@
use crate::rule::npc_ai;
pub use common::rtsim::{NpcId, Profession}; pub use common::rtsim::{NpcId, Profession};
use common::{ use common::{
comp, comp,
@ -12,14 +13,16 @@ use slotmap::HopSlotMap;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
collections::VecDeque, collections::VecDeque,
ops::{ControlFlow, Deref, DerefMut, Generator, GeneratorState},
sync::{Arc, atomic::{AtomicPtr, Ordering}},
pin::Pin,
marker::PhantomData, marker::PhantomData,
ops::{ControlFlow, Deref, DerefMut, Generator, GeneratorState},
pin::Pin,
sync::{
atomic::{AtomicPtr, Ordering},
Arc,
},
}; };
use vek::*; use vek::*;
use world::{civ::Track, site::Site as WorldSite, util::RandomPerm}; use world::{civ::Track, site::Site as WorldSite, util::RandomPerm};
use crate::rule::npc_ai;
#[derive(Copy, Clone, Default)] #[derive(Copy, Clone, Default)]
pub enum NpcMode { pub enum NpcMode {
@ -160,7 +163,7 @@ impl TaskState {
pub unsafe trait Context { pub unsafe trait Context {
// TODO: Somehow we need to enforce this bound, I think? // TODO: Somehow we need to enforce this bound, I think?
// Hence, this trait is unsafe for now. // Hence, this trait is unsafe for now.
type Ty<'a>;// where for<'a> Self::Ty<'a>: 'a; type Ty<'a>; // where for<'a> Self::Ty<'a>: 'a;
} }
pub struct Data<C: Context>(Arc<AtomicPtr<()>>, PhantomData<C>); pub struct Data<C: Context>(Arc<AtomicPtr<()>>, PhantomData<C>);
@ -196,12 +199,7 @@ pub struct TaskBox<C: Context, A = ()> {
} }
impl<C: Context, A> TaskBox<C, A> { impl<C: Context, A> TaskBox<C, A> {
pub fn new(data: Data<C>) -> Self { pub fn new(data: Data<C>) -> Self { Self { task: None, data } }
Self {
task: None,
data,
}
}
#[must_use] #[must_use]
pub fn finish(&mut self, prio: Priority) -> ControlFlow<A> { pub fn finish(&mut self, prio: Priority) -> ControlFlow<A> {
@ -225,7 +223,12 @@ impl<C: Context, A> TaskBox<C, A> {
task: T, task: T,
) -> ControlFlow<A> { ) -> ControlFlow<A> {
let ty = TypeId::of::<T>(); let ty = TypeId::of::<T>();
if self.task.as_mut().filter(|(ty1, _, _)| *ty1 == ty).is_none() { if self
.task
.as_mut()
.filter(|(ty1, _, _)| *ty1 == ty)
.is_none()
{
self.task = Some((ty, Box::new(task), prio)); self.task = Some((ty, Box::new(task), prio));
}; };
@ -239,18 +242,19 @@ pub struct Brain<C: Context, A = ()> {
} }
impl<C: Context, A> Brain<C, A> { impl<C: Context, A> Brain<C, A> {
pub fn new<T: Generator<Data<C>, Yield = A, Return = !> + Unpin + Any + Send + Sync>(task: T) -> Self { pub fn new<T: Generator<Data<C>, Yield = A, Return = !> + Unpin + Any + Send + Sync>(
task: T,
) -> Self {
Self { Self {
task: Box::new(task), task: Box::new(task),
data: Data(Arc::new(AtomicPtr::new(std::ptr::null_mut())), PhantomData), data: Data(Arc::new(AtomicPtr::new(std::ptr::null_mut())), PhantomData),
} }
} }
pub fn tick( pub fn tick(&mut self, ctx_ref: &mut C::Ty<'_>) -> A {
&mut self, self.data
ctx_ref: &mut C::Ty<'_>, .0
) -> A { .store(ctx_ref as *mut C::Ty<'_> as *mut (), Ordering::SeqCst);
self.data.0.store(ctx_ref as *mut C::Ty<'_> as *mut (), Ordering::SeqCst);
match Pin::new(&mut self.task).resume(self.data.clone()) { match Pin::new(&mut self.task).resume(self.data.clone()) {
GeneratorState::Yielded(action) => { GeneratorState::Yielded(action) => {
self.data.0.store(std::ptr::null_mut(), Ordering::Release); self.data.0.store(std::ptr::null_mut(), Ordering::Release);

View File

@ -2,7 +2,10 @@ use std::{collections::VecDeque, hash::BuildHasherDefault};
use crate::{ use crate::{
data::{ data::{
npc::{Controller, Npc, NpcId, PathData, PathingMemory, Task, TaskState, CONTINUE, FINISH, TaskBox, Brain, Data, Context}, npc::{
Brain, Context, Controller, Data, Npc, NpcId, PathData, PathingMemory, Task, TaskBox,
TaskState, CONTINUE, FINISH,
},
Sites, Sites,
}, },
event::OnTick, event::OnTick,
@ -59,7 +62,7 @@ fn path_in_site(start: Vec2<i32>, end: Vec2<i32>, site: &site2::Site) -> PathRes
TileKind::Empty => 3.0, TileKind::Empty => 3.0,
TileKind::Hazard(_) => 50.0, TileKind::Hazard(_) => 50.0,
TileKind::Field => 8.0, TileKind::Field => 8.0,
TileKind::Plaza | TileKind::Road { .. } => 1.0, TileKind::Plaza | TileKind::Road { .. } | TileKind::Path => 1.0,
TileKind::Building TileKind::Building
| TileKind::Castle | TileKind::Castle
@ -640,7 +643,8 @@ TravelTo {
} }
*/ */
trait IsTask = core::ops::Generator<Data<NpcData<'static>>, Yield = (), Return = ()> + Any + Send + Sync; trait IsTask =
core::ops::Generator<Data<NpcData<'static>>, Yield = (), Return = ()> + Any + Send + Sync;
pub struct NpcData<'a> { pub struct NpcData<'a> {
ctx: &'a EventCtx<'a, NpcAi, OnTick>, ctx: &'a EventCtx<'a, NpcAi, OnTick>,
@ -689,7 +693,13 @@ pub fn brain() -> Brain<NpcData<'static>> {
PathResult::Path(path) => path, PathResult::Path(path) => path,
_ => return None, _ => return None,
}; };
println!("CHOSE PATH, len = {}, start = {:?}, end = {:?}\nnpc = {:?}", path.len(), start, end, d.npc_id); println!(
"CHOSE PATH, len = {}, start = {:?}, end = {:?}\nnpc = {:?}",
path.len(),
start,
end,
d.npc_id
);
Some((current_site.world_site?, path)) Some((current_site.world_site?, path))
}); });
@ -711,26 +721,37 @@ fn walk_path(site: Id<WorldSite>, path: Path<Vec2<i32>>) -> impl IsTask {
move |mut data: Data<NpcData>| { move |mut data: Data<NpcData>| {
for tile in path { for tile in path {
println!("TILE"); println!("TILE");
let wpos = data.with(|d| match &d.ctx.index.sites.get(site).kind { let wpos = data.with(|d| {
SiteKind::Refactor(site2) match &d.ctx.index.sites.get(site).kind {
| SiteKind::CliffTown(site2) SiteKind::Refactor(site2)
| SiteKind::DesertCity(site2) => Some(site2), | SiteKind::CliffTown(site2)
_ => None, | SiteKind::DesertCity(site2) => Some(site2),
} _ => None,
}
.expect("intrasite path should only be started on a site2 site") .expect("intrasite path should only be started on a site2 site")
.tile_center_wpos(tile) .tile_center_wpos(tile)
.as_() .as_()
+ 0.5); + 0.5
});
println!("Walking to next tile... tile wpos = {:?} npc wpos = {:?}", wpos, data.with(|d| d.npc.wpos)); println!(
"Walking to next tile... tile wpos = {:?} npc wpos = {:?}",
wpos,
data.with(|d| d.npc.wpos)
);
while data.with(|d| d.npc.wpos.xy().distance_squared(wpos) > 2.0) { while data.with(|d| d.npc.wpos.xy().distance_squared(wpos) > 2.0) {
data.with(|d| d.controller.goto = Some(( data.with(|d| {
wpos.with_z(d.ctx.world d.controller.goto = Some((
.sim() wpos.with_z(
.get_alt_approx(wpos.map(|e| e as i32)) d.ctx
.unwrap_or(0.0)), .world
1.0, .sim()
))); .get_alt_approx(wpos.map(|e| e as i32))
.unwrap_or(0.0),
),
1.0,
))
});
yield (); yield ();
} }
} }

View File

@ -267,7 +267,7 @@ impl<'a> System<'a> for Sys {
// Some( // Some(
// index // index
// .sites // .sites
// //
// .get(data.sites.get(path.end)?.world_site?) // .get(data.sites.get(path.end)?.world_site?)
// .name() // .name()
// .to_string(), // .to_string(),

View File

@ -2,8 +2,8 @@ pub mod behavior_tree;
pub use server_agent::{action_nodes, attack, consts, data, util}; pub use server_agent::{action_nodes, attack, consts, data, util};
use crate::sys::agent::{ use crate::sys::agent::{
behavior_tree::{BehaviorData, BehaviorTree}, behavior_tree::{BehaviorData, BehaviorTree},
data::{AgentData, ReadData}, data::{AgentData, ReadData},
}; };
use common::{ use common::{
comp::{ comp::{

View File

@ -1,4 +1,3 @@
use common::rtsim::RtSimEntity;
use common::{ use common::{
comp::{ comp::{
agent::{ agent::{
@ -10,6 +9,7 @@ use common::{
}, },
event::{Emitter, ServerEvent}, event::{Emitter, ServerEvent},
path::TraversalConfig, path::TraversalConfig,
rtsim::RtSimEntity,
}; };
use rand::{prelude::ThreadRng, thread_rng, Rng}; use rand::{prelude::ThreadRng, thread_rng, Rng};
use specs::{ use specs::{

View File

@ -15,9 +15,7 @@ use common::{
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use specs::saveload::Marker; use specs::saveload::Marker;
use crate::{ use crate::sys::agent::util::get_entity_by_id;
sys::agent::util::get_entity_by_id,
};
use super::{BehaviorData, BehaviorTree}; use super::{BehaviorData, BehaviorTree};

View File

@ -636,7 +636,7 @@ impl Scene {
Vec3::unit_z() * (up * viewpoint_scale - tilt.min(0.0).sin() * dist * 0.6) Vec3::unit_z() * (up * viewpoint_scale - tilt.min(0.0).sin() * dist * 0.6)
} else { } else {
self.figure_mgr self.figure_mgr
.viewpoint_offset(scene_data, scene_data.viewpoint_entity) * viewpoint_scale .viewpoint_offset(scene_data, scene_data.viewpoint_entity)
}; };
match self.camera.get_mode() { match self.camera.get_mode() {