From 1fcb46ae0c054d14088278a99e4d4429938f84b2 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 3 Apr 2023 18:36:33 +0100 Subject: [PATCH] Made merchants advertise wares --- common/src/rtsim.rs | 3 ++- rtsim/src/ai/mod.rs | 15 +++++++++------ rtsim/src/rule/npc_ai.rs | 24 ++++++++++++++++++++++++ server/src/sys/agent/behavior_tree.rs | 1 + 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/common/src/rtsim.rs b/common/src/rtsim.rs index 887cfadab9..e2dc656221 100644 --- a/common/src/rtsim.rs +++ b/common/src/rtsim.rs @@ -222,7 +222,8 @@ pub enum NpcActivity { #[derive(Clone, Debug)] pub enum NpcAction { Greet(Actor), - // TODO: Use some sort of structured, language-independent value that frontends can translate instead + // TODO: Use some sort of structured, language-independent value that frontends can translate + // instead Say(Cow<'static, str>), } diff --git a/rtsim/src/ai/mod.rs b/rtsim/src/ai/mod.rs index 3de71dc85d..9bf321728e 100644 --- a/rtsim/src/ai/mod.rs +++ b/rtsim/src/ai/mod.rs @@ -124,11 +124,11 @@ pub trait Action: Any + Send + Sync { /// go_on_an_adventure().repeat().stop_if(|ctx| ctx.npc.age > 111.0) /// ``` #[must_use] - fn stop_if bool>(self, f: F) -> StopIf + fn stop_if bool + Clone>(self, f: F) -> StopIf where Self: Sized, { - StopIf(self, f) + StopIf(self, f.clone(), f) } /// Map the completion value of this action to something else. @@ -704,10 +704,10 @@ where /// See [`Action::stop_if`]. #[derive(Copy, Clone)] -pub struct StopIf(A, F); +pub struct StopIf(A, F, F); -impl, F: FnMut(&mut NpcCtx) -> bool + Send + Sync + 'static, R> Action> - for StopIf +impl, F: FnMut(&mut NpcCtx) -> bool + Clone + Send + Sync + 'static, R> + Action> for StopIf { fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) } @@ -715,7 +715,10 @@ impl, F: FnMut(&mut NpcCtx) -> bool + Send + Sync + 'static, R> Act fn backtrace(&self, bt: &mut Vec) { self.0.backtrace(bt); } - fn reset(&mut self) { self.0.reset(); } + fn reset(&mut self) { + self.0.reset(); + self.1 = self.2.clone(); + } fn tick(&mut self, ctx: &mut NpcCtx) -> ControlFlow> { if (self.1)(ctx) { diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index 86bc1c6218..056ea5aee2 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -469,6 +469,7 @@ fn socialize() -> impl Action { just(|ctx| ctx.controller.do_dance()) .repeat() .stop_if(timeout(6.0)) + .debug(|| "dancing") .map(|_| ()) .boxed() } else { @@ -644,6 +645,29 @@ fn villager(visiting_site: SiteId) -> impl Action { .map(|_| ()), ); } + } else if matches!(ctx.npc.profession, Some(Profession::Merchant)) + && thread_rng().gen_bool(0.8) + { + return casual( + just(|ctx| { + ctx.controller.say( + *[ + "All my goods are of the highest quality!", + "Does anybody want to buy my wares?", + "I've got the best offers in town.", + "Looking for supplies? I've got you covered.", + ] + .iter() + .choose(&mut thread_rng()) + .unwrap(), + ) // Can't fail + }) + .then(idle().repeat().stop_if(timeout(8.0))) + .repeat() + .stop_if(timeout(60.0)) + .debug(|| "sell wares") + .map(|_| ()), + ); } // If nothing else needs doing, walk between plazas and socialize diff --git a/server/src/sys/agent/behavior_tree.rs b/server/src/sys/agent/behavior_tree.rs index e1a51b40f0..e258bb2e00 100644 --- a/server/src/sys/agent/behavior_tree.rs +++ b/server/src/sys/agent/behavior_tree.rs @@ -506,6 +506,7 @@ fn handle_rtsim_actions(bdata: &mut BehaviorData) -> bool { } }, NpcAction::Say(msg) => { + bdata.controller.push_utterance(UtteranceKind::Greeting); bdata.agent_data.chat_npc(msg, &mut bdata.event_emitter); }, }