diff --git a/common/src/rtsim.rs b/common/src/rtsim.rs index 1c0fbc55e6..eb5913c1aa 100644 --- a/common/src/rtsim.rs +++ b/common/src/rtsim.rs @@ -216,6 +216,7 @@ pub enum NpcActivity { Gather(&'static [ChunkResource]), // TODO: Generalise to other entities? What kinds of animals? HuntAnimals, + Dance, } #[derive(Clone, Copy, Debug)] diff --git a/rtsim/src/data/npc.rs b/rtsim/src/data/npc.rs index fcfe4dbd50..880e989e46 100644 --- a/rtsim/src/data/npc.rs +++ b/rtsim/src/data/npc.rs @@ -66,7 +66,9 @@ impl Controller { pub fn do_hunt_animals(&mut self) { self.activity = Some(NpcActivity::HuntAnimals); } - pub fn do_greet(&mut self, actor: Actor) { self.actions.push(NpcAction::Greet(actor)); } + pub fn do_dance(&mut self) { self.activity = Some(NpcActivity::Dance); } + + pub fn greet(&mut self, actor: Actor) { self.actions.push(NpcAction::Greet(actor)); } } pub struct Brain { diff --git a/rtsim/src/rule/npc_ai.rs b/rtsim/src/rule/npc_ai.rs index 7bc95ade9c..e59d4aeb97 100644 --- a/rtsim/src/rule/npc_ai.rs +++ b/rtsim/src/rule/npc_ai.rs @@ -454,19 +454,25 @@ fn timeout(time: f64) -> impl FnMut(&mut NpcCtx) -> bool + Clone + Send + Sync { } fn socialize() -> impl Action { - just(|ctx| { + now(|ctx| { let mut rng = thread_rng(); // TODO: Bit odd, should wait for a while after greeting - if thread_rng().gen_bool(0.0003) { - if let Some(other) = ctx - .state - .data() - .npcs - .nearby(ctx.npc.wpos.xy(), 8.0) - .choose(&mut rng) - { - ctx.controller.do_greet(other); - } + if thread_rng().gen_bool(0.0003) && let Some(other) = ctx + .state + .data() + .npcs + .nearby(ctx.npc.wpos.xy(), 8.0) + .choose(&mut rng) + { + just(move |ctx| ctx.controller.greet(other)).boxed() + } else if thread_rng().gen_bool(0.0003) { + just(|ctx| ctx.controller.do_dance()) + .repeat() + .stop_if(timeout(6.0)) + .map(|_| ()) + .boxed() + } else { + idle().boxed() } }) } diff --git a/rtsim/src/rule/simulate_npcs.rs b/rtsim/src/rule/simulate_npcs.rs index cc78c17142..f59f1cb037 100644 --- a/rtsim/src/rule/simulate_npcs.rs +++ b/rtsim/src/rule/simulate_npcs.rs @@ -249,7 +249,8 @@ impl Rule for SimulateNpcs { Some( NpcActivity::Goto(_, _) | NpcActivity::Gather(_) - | NpcActivity::HuntAnimals, + | NpcActivity::HuntAnimals + | NpcActivity::Dance, ) => {}, None => {}, } @@ -276,7 +277,11 @@ impl Rule for SimulateNpcs { .with_z(0.0); } }, - Some(NpcActivity::Gather(_) | NpcActivity::HuntAnimals) => { + Some( + NpcActivity::Gather(_) + | NpcActivity::HuntAnimals + | NpcActivity::Dance, + ) => { // TODO: Maybe they should walk around randomly // when gathering resources? }, diff --git a/server/agent/src/action_nodes.rs b/server/agent/src/action_nodes.rs index f555cc887f..a3498cd2e4 100644 --- a/server/agent/src/action_nodes.rs +++ b/server/agent/src/action_nodes.rs @@ -349,6 +349,10 @@ impl<'a> AgentData<'a> { controller.push_action(ControlAction::Dance); break 'activity; // Don't fall through to idle wandering }, + Some(NpcActivity::Dance) => { + controller.push_action(ControlAction::Dance); + break 'activity; // Don't fall through to idle wandering + }, Some(NpcActivity::HuntAnimals) => { if rng.gen::() < 0.1 { self.choose_target(