1pub mod predicate;
2
3use predicate::Predicate;
4use rand::Rng;
5
6use crate::{
7 RtState,
8 data::{
9 ReportId, Sentiments,
10 npc::{Controller, Npc, NpcId},
11 },
12};
13use common::{
14 comp::{self, gizmos::RtsimGizmos},
15 resources::{Time, TimeOfDay},
16 rtsim::NpcInput,
17 shared_server_config::ServerConstants,
18 uid::IdMaps,
19 weather::WeatherGrid,
20};
21use hashbrown::HashSet;
22use itertools::Either;
23use rand_chacha::ChaChaRng;
24use specs::{Read, ReadExpect, ReadStorage, SystemData, WriteExpect, WriteStorage, shred};
25use std::{any::Any, collections::VecDeque, marker::PhantomData, ops::ControlFlow, sync::Mutex};
26use world::{IndexRef, World};
27
28pub trait State: Clone + Send + Sync + 'static {}
29
30impl<T: Clone + Send + Sync + 'static> State for T {}
31
32#[derive(Clone, Copy)]
33struct Resettable<T> {
34 original: T,
35 current: T,
36}
37
38impl<T: Clone> From<T> for Resettable<T> {
39 fn from(value: T) -> Self {
40 Self {
41 original: value.clone(),
42 current: value,
43 }
44 }
45}
46
47impl<T: Clone> Resettable<T> {
48 fn reset(&mut self) { self.current = self.original.clone(); }
49}
50
51impl<T> std::ops::Deref for Resettable<T> {
52 type Target = T;
53
54 fn deref(&self) -> &Self::Target { &self.current }
55}
56
57impl<T> std::ops::DerefMut for Resettable<T> {
58 fn deref_mut(&mut self) -> &mut Self::Target { &mut self.current }
59}
60
61pub struct NpcCtx<'a, 'd> {
65 pub state: &'a RtState,
66 pub world: &'a World,
67 pub index: IndexRef<'a>,
68
69 pub time_of_day: TimeOfDay,
70 pub time: Time,
71
72 pub npc_id: NpcId,
73 pub npc: &'a Npc,
74 pub controller: &'a mut Controller,
75 pub npc_dialogue: &'a mut VecDeque<(NpcId, Box<dyn Action<(), ()>>)>,
76 pub inbox: &'a mut VecDeque<NpcInput>, pub sentiments: &'a mut Sentiments,
78 pub known_reports: &'a mut HashSet<ReportId>,
79 pub gizmos: Option<&'a mut Vec<comp::gizmos::Gizmos>>,
80
81 pub dt: f32,
83 pub rng: ChaChaRng,
84 pub system_data: &'a NpcSystemData<'d>,
85}
86
87fn discrete_chance(dt: f64, chance_per_second: f64) -> f64 {
88 if dt <= 1.0 {
89 (dt * chance_per_second).clamp(0.0, 1.0)
90 } else {
91 let n_chance = 1.0 - chance_per_second.clamp(0.0, 1.0);
92 1.0 - n_chance.powf(dt)
93 }
94}
95
96#[test]
97fn test_discrete_chance() {
98 let p = discrete_chance(10.0, 0.2);
100 assert!((p - 0.89).abs() < 0.005);
101}
102
103impl NpcCtx<'_, '_> {
104 pub fn chance(&mut self, chance: f64) -> bool {
106 let p = discrete_chance(self.dt as f64, chance);
107 self.rng.random_bool(p)
108 }
109
110 pub fn gizmos(&mut self, gizmos: comp::gizmos::Gizmos) {
111 if let Some(gizmos_buffer) = self.gizmos.as_mut() {
112 gizmos_buffer.push(gizmos);
113 }
114 }
115}
116
117#[derive(SystemData)]
118pub struct NpcSystemData<'a> {
119 pub positions: ReadStorage<'a, comp::Pos>,
120 pub id_maps: Read<'a, IdMaps>,
121 pub server_constants: ReadExpect<'a, ServerConstants>,
122 pub weather_grid: ReadExpect<'a, WeatherGrid>,
123 pub rtsim_gizmos: WriteExpect<'a, RtsimGizmos>,
124 pub ability_map: ReadExpect<'a, comp::tool::AbilityMap>,
125 pub msm: ReadExpect<'a, comp::item::MaterialStatManifest>,
126 pub inventories: Mutex<WriteStorage<'a, comp::Inventory>>,
127}
128
129pub trait Action<S = (), R = ()>: Any + Send + Sync {
149 fn is_same(&self, other: &Self) -> bool
157 where
158 Self: Sized;
159
160 fn dyn_is_same_sized(&self, other: &dyn Action<S, R>) -> bool
162 where
163 Self: Sized,
164 {
165 match (other as &dyn Any).downcast_ref::<Self>() {
166 Some(other) => self.is_same(other),
167 None => false,
168 }
169 }
170
171 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool;
173
174 fn backtrace(&self, bt: &mut Vec<String>);
177
178 fn reset(&mut self);
180
181 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S);
186
187 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R>;
189
190 #[must_use]
200 fn then<A1: Action<S, R1>, R1>(self, other: A1) -> Then<Self, A1, R>
201 where
202 Self: Sized,
203 {
204 Then {
205 a0: self,
206 a0_finished: false,
207 a1: other,
208 phantom: PhantomData,
209 }
210 }
211
212 #[must_use]
224 fn and_then<F, A1: Action<S, R1>, R1>(self, f: F) -> AndThen<Self, F, A1, R>
225 where
226 Self: Sized,
227 {
228 AndThen {
229 a0: self,
230 f,
231 a1: None,
232 phantom: PhantomData,
233 }
234 }
235
236 #[must_use]
245 fn repeat(self) -> Repeat<Self, R>
246 where
247 Self: Sized,
248 {
249 Repeat(self, PhantomData)
250 }
251
252 #[must_use]
261 fn stop_if<P: Predicate + Clone>(self, p: P) -> StopIf<Self, P>
262 where
263 Self: Sized,
264 {
265 StopIf(self, p.into())
266 }
267
268 #[must_use]
270 fn when_cancelled<F: Fn(&mut NpcCtx) + Send + Sync + 'static>(
271 self,
272 f: F,
273 ) -> WhenCancelled<Self, F>
274 where
275 Self: Sized,
276 {
277 WhenCancelled(self, f)
278 }
279
280 #[must_use]
294 fn interrupt_with<
295 A1: Action<S, R1>,
296 R1,
297 F: Fn(&mut NpcCtx, &mut S) -> Option<A1> + Send + Sync + 'static,
298 >(
299 self,
300 f: F,
301 ) -> InterruptWith<Self, F, A1, R1>
302 where
303 Self: Sized,
304 {
305 InterruptWith {
306 a0: self,
307 f,
308 a1: None,
309 phantom: PhantomData,
310 }
311 }
312
313 #[must_use]
315 fn map<F: Fn(R, &mut S) -> R1, R1>(self, f: F) -> Map<Self, F, R>
316 where
317 Self: Sized,
318 {
319 Map(self, f, PhantomData)
320 }
321
322 #[must_use]
347 fn boxed(self) -> Box<dyn Action<S, R>>
348 where
349 Self: Sized,
350 {
351 Box::new(self)
352 }
353
354 #[must_use]
367 fn with_state<S0>(self, s: S) -> WithState<Self, S, S0>
368 where
369 Self: Sized,
370 S: Clone,
371 {
372 WithState(self, s.into(), PhantomData)
373 }
374
375 #[must_use]
387 fn map_state<S0, F>(self, f: F) -> MapState<Self, F, S, S0>
388 where
389 F: Fn(&mut S0) -> &mut S,
390 Self: Sized,
391 {
392 MapState(self, f, PhantomData)
393 }
394
395 #[must_use]
404 fn debug<F, T>(self, mk_info: F) -> Debug<Self, F, T>
405 where
406 Self: Sized,
407 {
408 Debug(self, mk_info, PhantomData)
409 }
410
411 #[must_use]
412 fn l<Rhs>(self) -> Either<Self, Rhs>
413 where
414 Self: Sized,
415 {
416 Either::Left(self)
417 }
418
419 #[must_use]
420 fn r<Lhs>(self) -> Either<Lhs, Self>
421 where
422 Self: Sized,
423 {
424 Either::Right(self)
425 }
426}
427
428impl<S: State, R: 'static> Action<S, R> for Box<dyn Action<S, R>> {
429 fn is_same(&self, other: &Self) -> bool { (**self).dyn_is_same(&**other) }
430
431 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool {
432 match (other as &dyn Any).downcast_ref::<Self>() {
433 Some(other) => self.is_same(other),
434 None => false,
435 }
436 }
437
438 fn backtrace(&self, bt: &mut Vec<String>) { (**self).backtrace(bt) }
439
440 fn reset(&mut self) { (**self).reset(); }
441
442 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) { (**self).on_cancel(ctx, state) }
443
444 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
445 (**self).tick(ctx, state)
446 }
447}
448
449impl<S: State, R: 'static, A: Action<S, R>, B: Action<S, R>> Action<S, R> for Either<A, B> {
450 fn is_same(&self, other: &Self) -> bool {
451 match (self, other) {
452 (Either::Left(x), Either::Left(y)) => x.is_same(y),
453 (Either::Right(x), Either::Right(y)) => x.is_same(y),
454 _ => false,
455 }
456 }
457
458 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
459
460 fn backtrace(&self, bt: &mut Vec<String>) {
461 match self {
462 Either::Left(x) => x.backtrace(bt),
463 Either::Right(x) => x.backtrace(bt),
464 }
465 }
466
467 fn reset(&mut self) {
468 match self {
469 Either::Left(x) => x.reset(),
470 Either::Right(x) => x.reset(),
471 }
472 }
473
474 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
475 match self {
476 Either::Left(x) => x.on_cancel(ctx, state),
477 Either::Right(x) => x.on_cancel(ctx, state),
478 }
479 }
480
481 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
482 match self {
483 Either::Left(x) => x.tick(ctx, state),
484 Either::Right(x) => x.tick(ctx, state),
485 }
486 }
487}
488
489#[derive(Copy, Clone)]
493pub struct Now<F, A>(F, Option<A>);
494
495impl<
496 S: State,
497 R: Send + Sync + 'static,
498 F: FnOnce(&mut NpcCtx, &mut S) -> A + Clone + Send + Sync + 'static,
499 A: Action<S, R>,
500> Action<S, R> for Now<F, A>
501{
502 fn is_same(&self, _other: &Self) -> bool { true }
504
505 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
506
507 fn backtrace(&self, bt: &mut Vec<String>) {
508 if let Some(action) = &self.1 {
509 action.backtrace(bt);
510 } else {
511 bt.push("<thinking>".to_string());
512 }
513 }
514
515 fn reset(&mut self) { self.1 = None; }
516
517 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
518 if let Some(x) = &mut self.1 {
519 x.on_cancel(ctx, state);
520 }
521 }
522
523 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
524 (self.1.get_or_insert_with(|| (self.0.clone())(ctx, state))).tick(ctx, state)
525 }
526}
527
528pub fn now<S, R, F, A: Action<S, R>>(f: F) -> Now<F, A>
541where
542 F: FnOnce(&mut NpcCtx, &mut S) -> A + Clone + Send + Sync + 'static,
543{
544 Now(f, None)
545}
546
547#[derive(Copy, Clone)]
551pub struct Until<F, A, R, R1>(F, Option<A>, PhantomData<(R, R1)>);
552
553impl<
554 S: State,
555 R: Send + Sync + 'static,
556 F: Fn(&mut NpcCtx, &mut S) -> ControlFlow<R1, A> + Send + Sync + 'static,
557 A: Action<S, R>,
558 R1: Send + Sync + 'static,
559> Action<S, R1> for Until<F, A, R, R1>
560{
561 fn is_same(&self, _other: &Self) -> bool { true }
563
564 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
565
566 fn backtrace(&self, bt: &mut Vec<String>) {
567 if let Some(action) = &self.1 {
568 action.backtrace(bt);
569 } else {
570 bt.push("<thinking>".to_string());
571 }
572 }
573
574 fn reset(&mut self) { self.1 = None; }
575
576 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
577 if let Some(x) = &mut self.1 {
578 x.on_cancel(ctx, state);
579 }
580 }
581
582 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
583 let action = match &mut self.1 {
584 Some(action) => action,
585 None => match (self.0)(ctx, state) {
586 ControlFlow::Continue(action) => self.1.insert(action),
587 ControlFlow::Break(b) => return ControlFlow::Break(b),
588 },
589 };
590
591 match action.tick(ctx, state) {
592 ControlFlow::Continue(()) => ControlFlow::Continue(()),
593 ControlFlow::Break(_) => {
594 self.1 = None;
595 ControlFlow::Continue(())
596 },
597 }
598 }
599}
600
601pub fn until<S, F, A: Action<S, R>, R, R1>(f: F) -> Until<F, A, R, R1>
602where
603 F: Fn(&mut NpcCtx, &mut S) -> ControlFlow<R1, A>,
604{
605 Until(f, None, PhantomData)
606}
607
608#[derive(Copy, Clone)]
612pub struct Just<F, R = ()>(F, PhantomData<R>);
613
614impl<S: State, R: Send + Sync + 'static, F: Fn(&mut NpcCtx, &mut S) -> R + Send + Sync + 'static>
615 Action<S, R> for Just<F, R>
616{
617 fn is_same(&self, _other: &Self) -> bool { true }
618
619 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
620
621 fn backtrace(&self, _bt: &mut Vec<String>) {}
622
623 fn reset(&mut self) {}
624
625 fn on_cancel(&mut self, _ctx: &mut NpcCtx, _state: &mut S) {}
626
627 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
628 ControlFlow::Break((self.0)(ctx, state))
629 }
630}
631
632pub fn just<S: State, F, R: Send + Sync + 'static>(f: F) -> Just<F, R>
644where
645 F: Fn(&mut NpcCtx, &mut S) -> R + Send + Sync + 'static,
646{
647 Just(f, PhantomData)
648}
649
650#[derive(Copy, Clone)]
654pub struct Finish;
655
656impl<S: State> Action<S, ()> for Finish {
657 fn is_same(&self, _other: &Self) -> bool { true }
658
659 fn dyn_is_same(&self, other: &dyn Action<S, ()>) -> bool { self.dyn_is_same_sized(other) }
660
661 fn backtrace(&self, _bt: &mut Vec<String>) {}
662
663 fn reset(&mut self) {}
664
665 fn on_cancel(&mut self, _ctx: &mut NpcCtx, _state: &mut S) {}
666
667 fn tick(&mut self, _ctx: &mut NpcCtx, _state: &mut S) -> ControlFlow<()> {
668 ControlFlow::Break(())
669 }
670}
671
672#[must_use]
691pub fn finish() -> Finish { Finish }
692
693pub type Priority = usize;
696
697pub const URGENT: Priority = 0;
698pub const IMPORTANT: Priority = 1;
699pub const CASUAL: Priority = 2;
700
701pub struct Node<S, R>(Box<dyn Action<S, R>>, Priority);
702
703#[must_use]
705pub fn urgent<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), URGENT) }
706
707#[must_use]
709pub fn important<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), IMPORTANT) }
710
711#[must_use]
713pub fn casual<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), CASUAL) }
714
715pub struct Tree<S, F, R> {
717 next: F,
718 prev: Option<Node<S, R>>,
719 interrupt: bool,
720}
721
722impl<S: State, F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static, R: 'static>
723 Action<S, R> for Tree<S, F, R>
724{
725 fn is_same(&self, _other: &Self) -> bool { true }
726
727 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
728
729 fn backtrace(&self, bt: &mut Vec<String>) {
730 if let Some(prev) = &self.prev {
731 prev.0.backtrace(bt);
732 } else {
733 bt.push("<thinking>".to_string());
734 }
735 }
736
737 fn reset(&mut self) { self.prev = None; }
738
739 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
740 if let Some(x) = &mut self.prev {
741 x.0.on_cancel(ctx, state);
742 }
743 }
744
745 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
746 let new = (self.next)(ctx, state);
747
748 let prev = match &mut self.prev {
749 Some(prev) if prev.1 <= new.1 && (prev.0.dyn_is_same(&*new.0) || !self.interrupt) => {
750 prev
751 },
752 _ => {
753 if let Some(mut prev) = self.prev.take() {
754 prev.0.on_cancel(ctx, state);
755 }
756 self.prev.insert(new)
757 },
758 };
759
760 match prev.0.tick(ctx, state) {
761 ControlFlow::Continue(()) => ControlFlow::Continue(()),
762 ControlFlow::Break(r) => {
763 self.prev = None;
764 ControlFlow::Break(r)
765 },
766 }
767 }
768}
769
770#[must_use]
794pub fn choose<S: State, R: 'static, F>(f: F) -> impl Action<S, R>
795where
796 F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static,
797{
798 Tree {
799 next: f,
800 prev: None,
801 interrupt: false,
802 }
803}
804
805#[must_use]
829pub fn watch<S: State, R: 'static, F>(f: F) -> impl Action<S, R>
830where
831 F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static,
832{
833 Tree {
834 next: f,
835 prev: None,
836 interrupt: true,
837 }
838}
839
840#[derive(Copy, Clone)]
844pub struct Then<A0, A1, R0> {
845 a0: A0,
846 a0_finished: bool,
847 a1: A1,
848 phantom: PhantomData<R0>,
849}
850
851impl<
852 S: State,
853 A0: Action<S, R0>,
854 A1: Action<S, R1>,
855 R0: Send + Sync + 'static,
856 R1: Send + Sync + 'static,
857> Action<S, R1> for Then<A0, A1, R0>
858{
859 fn is_same(&self, other: &Self) -> bool {
860 self.a0.is_same(&other.a0) && self.a1.is_same(&other.a1)
861 }
862
863 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
864
865 fn backtrace(&self, bt: &mut Vec<String>) {
866 if self.a0_finished {
867 self.a1.backtrace(bt);
868 } else {
869 self.a0.backtrace(bt);
870 }
871 }
872
873 fn reset(&mut self) {
874 self.a0.reset();
875 self.a0_finished = false;
876 self.a1.reset();
877 }
878
879 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
880 if !self.a0_finished {
881 self.a0.on_cancel(ctx, state)
882 } else {
883 self.a1.on_cancel(ctx, state);
884 }
885 }
886
887 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
888 if !self.a0_finished {
889 match self.a0.tick(ctx, state) {
890 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
891 ControlFlow::Break(_) => self.a0_finished = true,
892 }
893 }
894 self.a1.tick(ctx, state)
895 }
896}
897
898#[derive(Copy, Clone)]
902pub struct AndThen<A0, F, A1, R0> {
903 a0: A0,
904 f: F,
905 a1: Option<A1>,
906 phantom: PhantomData<R0>,
907}
908
909impl<
910 S: State,
911 A0: Action<S, R0>,
912 A1: Action<S, R1>,
913 R0: Send + Sync + 'static,
914 R1: Send + Sync + 'static,
915 F: FnOnce(R0) -> A1 + Clone + Send + Sync + 'static,
916> Action<S, R1> for AndThen<A0, F, A1, R0>
917{
918 fn is_same(&self, other: &Self) -> bool {
919 self.a0.is_same(&other.a0)
920 && match (&self.a1, &other.a1) {
921 (Some(a1_0), Some(a1_1)) => a1_0.is_same(a1_1),
922 _ => true,
923 }
924 }
925
926 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
927
928 fn backtrace(&self, bt: &mut Vec<String>) {
929 if let Some(a1) = &self.a1 {
930 a1.backtrace(bt);
931 } else {
932 self.a0.backtrace(bt);
933 }
934 }
935
936 fn reset(&mut self) {
937 self.a0.reset();
938 self.a1 = None;
939 }
940
941 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
942 if let Some(a1) = &mut self.a1 {
943 a1.on_cancel(ctx, state);
944 } else {
945 self.a0.on_cancel(ctx, state);
946 }
947 }
948
949 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
950 let a1 = match &mut self.a1 {
951 None => match self.a0.tick(ctx, state) {
952 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
953 ControlFlow::Break(r) => self.a1.insert((self.f.clone())(r)),
954 },
955 Some(a1) => a1,
956 };
957 a1.tick(ctx, state)
958 }
959}
960
961#[derive(Copy, Clone)]
965pub struct InterruptWith<A0, F, A1, R1> {
966 a0: A0,
967 f: F,
968 a1: Option<A1>,
969 phantom: PhantomData<R1>,
970}
971
972impl<
973 S: State,
974 A0: Action<S, R0>,
975 A1: Action<S, R1>,
976 F: Fn(&mut NpcCtx, &mut S) -> Option<A1> + Send + Sync + 'static,
977 R0: Send + Sync + 'static,
978 R1: Send + Sync + 'static,
979> Action<S, R0> for InterruptWith<A0, F, A1, R1>
980{
981 fn is_same(&self, other: &Self) -> bool { self.a0.is_same(&other.a0) }
982
983 fn dyn_is_same(&self, other: &dyn Action<S, R0>) -> bool { self.dyn_is_same_sized(other) }
984
985 fn backtrace(&self, bt: &mut Vec<String>) {
986 if let Some(a1) = &self.a1 {
987 bt.push("<interrupted>".to_string());
989 a1.backtrace(bt);
990 } else {
991 self.a0.backtrace(bt);
992 }
993 }
994
995 fn reset(&mut self) {
996 self.a0.reset();
997 self.a1 = None;
998 }
999
1000 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
1001 if let Some(x) = &mut self.a1 {
1002 x.on_cancel(ctx, state);
1003 }
1004 self.a0.on_cancel(ctx, state);
1005 }
1006
1007 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R0> {
1008 if let Some(new_a1) = (self.f)(ctx, state)
1009 && self.a1.as_ref().is_none_or(|a1| !a1.is_same(&new_a1))
1010 {
1011 self.a1 = Some(new_a1);
1012 }
1013
1014 if let Some(a1) = &mut self.a1 {
1015 match a1.tick(ctx, state) {
1016 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
1017 ControlFlow::Break(_) => self.a1 = None,
1018 }
1019 }
1020
1021 self.a0.tick(ctx, state)
1022 }
1023}
1024
1025#[derive(Copy, Clone)]
1029pub struct Repeat<A, R = ()>(A, PhantomData<R>);
1030
1031impl<S: State, R: Send + Sync + 'static, A: Action<S, R>> Action<S, !> for Repeat<A, R> {
1032 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1033
1034 fn dyn_is_same(&self, other: &dyn Action<S, !>) -> bool { self.dyn_is_same_sized(other) }
1035
1036 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1037
1038 fn reset(&mut self) { self.0.reset(); }
1039
1040 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) { self.0.on_cancel(ctx, state); }
1041
1042 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<!> {
1043 match self.0.tick(ctx, state) {
1044 ControlFlow::Continue(()) => ControlFlow::Continue(()),
1045 ControlFlow::Break(_) => {
1046 self.0.reset();
1047 ControlFlow::Continue(())
1048 },
1049 }
1050 }
1051}
1052
1053#[derive(Copy, Clone)]
1057pub struct Sequence<I, A, R = ()>(Resettable<I>, Option<A>, PhantomData<R>);
1058
1059impl<
1060 S: State,
1061 R: Send + Sync + 'static,
1062 I: Iterator<Item = A> + Clone + Send + Sync + 'static,
1063 A: Action<S, R>,
1064> Action<S, ()> for Sequence<I, A, R>
1065{
1066 fn is_same(&self, _other: &Self) -> bool { true }
1067
1068 fn dyn_is_same(&self, other: &dyn Action<S, ()>) -> bool { self.dyn_is_same_sized(other) }
1069
1070 fn backtrace(&self, bt: &mut Vec<String>) {
1071 if let Some(action) = &self.1 {
1072 action.backtrace(bt);
1073 } else {
1074 bt.push("<thinking>".to_string());
1075 }
1076 }
1077
1078 fn reset(&mut self) {
1079 self.0.reset();
1080 self.1 = None;
1081 }
1082
1083 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
1084 if let Some(x) = &mut self.1 {
1085 x.on_cancel(ctx, state);
1086 }
1087 }
1088
1089 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<()> {
1090 let item = if let Some(prev) = &mut self.1 {
1091 prev
1092 } else {
1093 match self.0.next() {
1094 Some(next) => self.1.insert(next),
1095 None => return ControlFlow::Break(()),
1096 }
1097 };
1098
1099 if let ControlFlow::Break(_) = item.tick(ctx, state) {
1100 self.1 = None;
1101 }
1102
1103 ControlFlow::Continue(())
1104 }
1105}
1106
1107#[must_use]
1126pub fn seq<S, I, A, R>(iter: I) -> Sequence<I, A, R>
1127where
1128 I: Iterator<Item = A> + Clone,
1129 A: Action<S, R>,
1130{
1131 Sequence(iter.into(), None, PhantomData)
1132}
1133
1134#[derive(Copy, Clone)]
1138pub struct StopIf<A, P>(A, Resettable<P>);
1139
1140impl<S: State, A: Action<S, R>, P: Predicate + Clone + Send + Sync + 'static, R>
1141 Action<S, Option<R>> for StopIf<A, P>
1142{
1143 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1144
1145 fn dyn_is_same(&self, other: &dyn Action<S, Option<R>>) -> bool {
1146 self.dyn_is_same_sized(other)
1147 }
1148
1149 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1150
1151 fn reset(&mut self) {
1152 self.0.reset();
1153 self.1.reset();
1154 }
1155
1156 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) { self.0.on_cancel(ctx, state); }
1157
1158 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<Option<R>> {
1159 if self.1.should(ctx) {
1160 self.0.on_cancel(ctx, state);
1161 ControlFlow::Break(None)
1162 } else {
1163 self.0.tick(ctx, state).map_break(Some)
1164 }
1165 }
1166}
1167
1168#[derive(Copy, Clone)]
1172pub struct WhenCancelled<A, F>(A, F);
1173
1174impl<S: State, A: Action<S, R>, F: Fn(&mut NpcCtx) + Clone + Send + Sync + 'static, R> Action<S, R>
1175 for WhenCancelled<A, F>
1176{
1177 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1178
1179 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
1180
1181 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1182
1183 fn reset(&mut self) { self.0.reset(); }
1184
1185 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) {
1186 self.0.on_cancel(ctx, state);
1187 (self.1)(ctx);
1188 }
1189
1190 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
1191 self.0.tick(ctx, state)
1192 }
1193}
1194
1195#[derive(Copy, Clone)]
1199pub struct Map<A, F, R>(A, F, PhantomData<R>);
1200
1201impl<
1202 S: State,
1203 A: Action<S, R>,
1204 F: Fn(R, &mut S) -> R1 + Send + Sync + 'static,
1205 R: Send + Sync + 'static,
1206 R1,
1207> Action<S, R1> for Map<A, F, R>
1208{
1209 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1210
1211 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
1212
1213 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1214
1215 fn reset(&mut self) { self.0.reset(); }
1216
1217 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) { self.0.on_cancel(ctx, state); }
1218
1219 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
1220 self.0.tick(ctx, state).map_break(|t| (self.1)(t, state))
1221 }
1222}
1223
1224#[derive(Copy, Clone)]
1228pub struct Debug<A, F, T>(A, F, PhantomData<T>);
1229
1230impl<
1231 S: 'static,
1232 A: Action<S, R>,
1233 F: Fn() -> T + Send + Sync + 'static,
1234 R: Send + Sync + 'static,
1235 T: Send + Sync + std::fmt::Display + 'static,
1236> Action<S, R> for Debug<A, F, T>
1237{
1238 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1239
1240 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
1241
1242 fn backtrace(&self, bt: &mut Vec<String>) {
1243 bt.push((self.1)().to_string());
1244 self.0.backtrace(bt);
1245 }
1246
1247 fn reset(&mut self) { self.0.reset(); }
1248
1249 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S) { self.0.on_cancel(ctx, state); }
1250
1251 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
1252 self.0.tick(ctx, state)
1253 }
1254}
1255
1256#[derive(Copy, Clone)]
1257pub struct WithState<A, S, S0>(A, Resettable<S>, PhantomData<S0>);
1258
1259impl<S0: State, S: State, R, A: Action<S, R>> Action<S0, R> for WithState<A, S, S0> {
1260 fn is_same(&self, other: &Self) -> bool
1261 where
1262 Self: Sized,
1263 {
1264 self.0.is_same(&other.0)
1265 }
1266
1267 fn dyn_is_same(&self, other: &dyn Action<S0, R>) -> bool { self.dyn_is_same_sized(other) }
1268
1269 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt) }
1270
1271 fn reset(&mut self) {
1272 self.0.reset();
1273 self.1.reset();
1274 }
1275
1276 fn on_cancel(&mut self, ctx: &mut NpcCtx, _state: &mut S0) {
1277 self.0.on_cancel(ctx, &mut self.1.current);
1278 }
1279
1280 fn tick(&mut self, ctx: &mut NpcCtx, _state: &mut S0) -> ControlFlow<R> {
1281 self.0.tick(ctx, &mut self.1.current)
1282 }
1283}
1284
1285#[derive(Copy, Clone)]
1286pub struct MapState<A, F, S, S0>(A, F, PhantomData<(S, S0)>);
1287
1288impl<S0: State, S: State, R, A: Action<S, R>, F: Fn(&mut S0) -> &mut S + Send + Sync + 'static>
1289 Action<S0, R> for MapState<A, F, S, S0>
1290{
1291 fn is_same(&self, other: &Self) -> bool
1292 where
1293 Self: Sized,
1294 {
1295 self.0.is_same(&other.0)
1296 }
1297
1298 fn dyn_is_same(&self, other: &dyn Action<S0, R>) -> bool { self.dyn_is_same_sized(other) }
1299
1300 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt) }
1301
1302 fn reset(&mut self) { self.0.reset(); }
1303
1304 fn on_cancel(&mut self, ctx: &mut NpcCtx, state: &mut S0) {
1305 self.0.on_cancel(ctx, (self.1)(state));
1306 }
1307
1308 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S0) -> ControlFlow<R> {
1309 self.0.tick(ctx, (self.1)(state))
1310 }
1311}