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}