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,
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, shred};
25use std::{any::Any, collections::VecDeque, marker::PhantomData, ops::ControlFlow};
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
80 pub dt: f32,
82 pub rng: ChaChaRng,
83 pub system_data: &'a NpcSystemData<'d>,
84}
85
86fn discrete_chance(dt: f64, chance_per_second: f64) -> f64 {
87 if dt <= 1.0 {
88 (dt * chance_per_second).clamp(0.0, 1.0)
89 } else {
90 let n_chance = 1.0 - chance_per_second.clamp(0.0, 1.0);
91 1.0 - n_chance.powf(dt)
92 }
93}
94
95#[test]
96fn test_discrete_chance() {
97 let p = discrete_chance(10.0, 0.2);
99 assert!((p - 0.89).abs() < 0.005);
100}
101
102impl NpcCtx<'_, '_> {
103 pub fn chance(&mut self, chance: f64) -> bool {
105 let p = discrete_chance(self.dt as f64, chance);
106 self.rng.gen_bool(p)
107 }
108}
109
110#[derive(SystemData)]
111pub struct NpcSystemData<'a> {
112 pub positions: ReadStorage<'a, comp::Pos>,
113 pub id_maps: Read<'a, IdMaps>,
114 pub server_constants: ReadExpect<'a, ServerConstants>,
115 pub weather_grid: ReadExpect<'a, WeatherGrid>,
116}
117
118pub trait Action<S = (), R = ()>: Any + Send + Sync {
138 fn is_same(&self, other: &Self) -> bool
146 where
147 Self: Sized;
148
149 fn dyn_is_same_sized(&self, other: &dyn Action<S, R>) -> bool
151 where
152 Self: Sized,
153 {
154 match (other as &dyn Any).downcast_ref::<Self>() {
155 Some(other) => self.is_same(other),
156 None => false,
157 }
158 }
159
160 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool;
162
163 fn backtrace(&self, bt: &mut Vec<String>);
166
167 fn reset(&mut self);
169
170 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R>;
172
173 #[must_use]
183 fn then<A1: Action<S, R1>, R1>(self, other: A1) -> Then<Self, A1, R>
184 where
185 Self: Sized,
186 {
187 Then {
188 a0: self,
189 a0_finished: false,
190 a1: other,
191 phantom: PhantomData,
192 }
193 }
194
195 #[must_use]
207 fn and_then<F, A1: Action<S, R1>, R1>(self, f: F) -> AndThen<Self, F, A1, R>
208 where
209 Self: Sized,
210 {
211 AndThen {
212 a0: self,
213 f,
214 a1: None,
215 phantom: PhantomData,
216 }
217 }
218
219 #[must_use]
228 fn repeat(self) -> Repeat<Self, R>
229 where
230 Self: Sized,
231 {
232 Repeat(self, PhantomData)
233 }
234
235 #[must_use]
244 fn stop_if<P: Predicate + Clone>(self, p: P) -> StopIf<Self, P>
245 where
246 Self: Sized,
247 {
248 StopIf(self, p.into())
249 }
250
251 #[must_use]
265 fn interrupt_with<
266 A1: Action<S, R1>,
267 R1,
268 F: Fn(&mut NpcCtx, &mut S) -> Option<A1> + Send + Sync + 'static,
269 >(
270 self,
271 f: F,
272 ) -> InterruptWith<Self, F, A1, R1>
273 where
274 Self: Sized,
275 {
276 InterruptWith {
277 a0: self,
278 f,
279 a1: None,
280 phantom: PhantomData,
281 }
282 }
283
284 #[must_use]
286 fn map<F: Fn(R, &mut S) -> R1, R1>(self, f: F) -> Map<Self, F, R>
287 where
288 Self: Sized,
289 {
290 Map(self, f, PhantomData)
291 }
292
293 #[must_use]
318 fn boxed(self) -> Box<dyn Action<S, R>>
319 where
320 Self: Sized,
321 {
322 Box::new(self)
323 }
324
325 #[must_use]
338 fn with_state<S0>(self, s: S) -> WithState<Self, S, S0>
339 where
340 Self: Sized,
341 S: Clone,
342 {
343 WithState(self, s.into(), PhantomData)
344 }
345
346 #[must_use]
358 fn map_state<S0, F>(self, f: F) -> MapState<Self, F, S, S0>
359 where
360 F: Fn(&mut S0) -> &mut S,
361 Self: Sized,
362 {
363 MapState(self, f, PhantomData)
364 }
365
366 #[must_use]
375 fn debug<F, T>(self, mk_info: F) -> Debug<Self, F, T>
376 where
377 Self: Sized,
378 {
379 Debug(self, mk_info, PhantomData)
380 }
381
382 #[must_use]
383 fn l<Rhs>(self) -> Either<Self, Rhs>
384 where
385 Self: Sized,
386 {
387 Either::Left(self)
388 }
389
390 #[must_use]
391 fn r<Lhs>(self) -> Either<Lhs, Self>
392 where
393 Self: Sized,
394 {
395 Either::Right(self)
396 }
397}
398
399impl<S: State, R: 'static> Action<S, R> for Box<dyn Action<S, R>> {
400 fn is_same(&self, other: &Self) -> bool { (**self).dyn_is_same(other) }
401
402 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool {
403 match (other as &dyn Any).downcast_ref::<Self>() {
404 Some(other) => self.is_same(other),
405 None => false,
406 }
407 }
408
409 fn backtrace(&self, bt: &mut Vec<String>) { (**self).backtrace(bt) }
410
411 fn reset(&mut self) { (**self).reset(); }
412
413 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
414 (**self).tick(ctx, state)
415 }
416}
417
418impl<S: State, R: 'static, A: Action<S, R>, B: Action<S, R>> Action<S, R> for Either<A, B> {
419 fn is_same(&self, other: &Self) -> bool {
420 match (self, other) {
421 (Either::Left(x), Either::Left(y)) => x.is_same(y),
422 (Either::Right(x), Either::Right(y)) => x.is_same(y),
423 _ => false,
424 }
425 }
426
427 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
428
429 fn backtrace(&self, bt: &mut Vec<String>) {
430 match self {
431 Either::Left(x) => x.backtrace(bt),
432 Either::Right(x) => x.backtrace(bt),
433 }
434 }
435
436 fn reset(&mut self) {
437 match self {
438 Either::Left(x) => x.reset(),
439 Either::Right(x) => x.reset(),
440 }
441 }
442
443 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
444 match self {
445 Either::Left(x) => x.tick(ctx, state),
446 Either::Right(x) => x.tick(ctx, state),
447 }
448 }
449}
450
451#[derive(Copy, Clone)]
455pub struct Now<F, A>(F, Option<A>);
456
457impl<
458 S: State,
459 R: Send + Sync + 'static,
460 F: Fn(&mut NpcCtx, &mut S) -> A + Send + Sync + 'static,
461 A: Action<S, R>,
462> Action<S, R> for Now<F, A>
463{
464 fn is_same(&self, _other: &Self) -> bool { true }
466
467 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
468
469 fn backtrace(&self, bt: &mut Vec<String>) {
470 if let Some(action) = &self.1 {
471 action.backtrace(bt);
472 } else {
473 bt.push("<thinking>".to_string());
474 }
475 }
476
477 fn reset(&mut self) { self.1 = None; }
478
479 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
481 (self.1.get_or_insert_with(|| (self.0)(ctx, state))).tick(ctx, state)
482 }
483}
484
485pub fn now<S, R, F, A: Action<S, R>>(f: F) -> Now<F, A>
498where
499 F: Fn(&mut NpcCtx, &mut S) -> A + Send + Sync + 'static,
500{
501 Now(f, None)
502}
503
504#[derive(Copy, Clone)]
508pub struct Until<F, A, R, R1>(F, Option<A>, PhantomData<(R, R1)>);
509
510impl<
511 S: State,
512 R: Send + Sync + 'static,
513 F: Fn(&mut NpcCtx, &mut S) -> ControlFlow<R1, A> + Send + Sync + 'static,
514 A: Action<S, R>,
515 R1: Send + Sync + 'static,
516> Action<S, R1> for Until<F, A, R, R1>
517{
518 fn is_same(&self, _other: &Self) -> bool { true }
520
521 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
522
523 fn backtrace(&self, bt: &mut Vec<String>) {
524 if let Some(action) = &self.1 {
525 action.backtrace(bt);
526 } else {
527 bt.push("<thinking>".to_string());
528 }
529 }
530
531 fn reset(&mut self) { self.1 = None; }
532
533 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
534 let action = match &mut self.1 {
535 Some(action) => action,
536 None => match (self.0)(ctx, state) {
537 ControlFlow::Continue(action) => self.1.insert(action),
538 ControlFlow::Break(b) => return ControlFlow::Break(b),
539 },
540 };
541
542 match action.tick(ctx, state) {
543 ControlFlow::Continue(()) => ControlFlow::Continue(()),
544 ControlFlow::Break(_) => {
545 self.1 = None;
546 ControlFlow::Continue(())
547 },
548 }
549 }
550}
551
552pub fn until<S, F, A: Action<S, R>, R, R1>(f: F) -> Until<F, A, R, R1>
553where
554 F: Fn(&mut NpcCtx, &mut S) -> ControlFlow<R1, A>,
555{
556 Until(f, None, PhantomData)
557}
558
559#[derive(Copy, Clone)]
563pub struct Just<F, R = ()>(F, PhantomData<R>);
564
565impl<S: State, R: Send + Sync + 'static, F: Fn(&mut NpcCtx, &mut S) -> R + Send + Sync + 'static>
566 Action<S, R> for Just<F, R>
567{
568 fn is_same(&self, _other: &Self) -> bool { true }
569
570 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
571
572 fn backtrace(&self, _bt: &mut Vec<String>) {}
573
574 fn reset(&mut self) {}
575
576 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
577 ControlFlow::Break((self.0)(ctx, state))
578 }
579}
580
581pub fn just<S: State, F, R: Send + Sync + 'static>(f: F) -> Just<F, R>
593where
594 F: Fn(&mut NpcCtx, &mut S) -> R + Send + Sync + 'static,
595{
596 Just(f, PhantomData)
597}
598
599#[derive(Copy, Clone)]
603pub struct Finish;
604
605impl<S: State> Action<S, ()> for Finish {
606 fn is_same(&self, _other: &Self) -> bool { true }
607
608 fn dyn_is_same(&self, other: &dyn Action<S, ()>) -> bool { self.dyn_is_same_sized(other) }
609
610 fn backtrace(&self, _bt: &mut Vec<String>) {}
611
612 fn reset(&mut self) {}
613
614 fn tick(&mut self, _ctx: &mut NpcCtx, _state: &mut S) -> ControlFlow<()> {
615 ControlFlow::Break(())
616 }
617}
618
619#[must_use]
638pub fn finish() -> Finish { Finish }
639
640pub type Priority = usize;
643
644pub const URGENT: Priority = 0;
645pub const IMPORTANT: Priority = 1;
646pub const CASUAL: Priority = 2;
647
648pub struct Node<S, R>(Box<dyn Action<S, R>>, Priority);
649
650#[must_use]
652pub fn urgent<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), URGENT) }
653
654#[must_use]
656pub fn important<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), IMPORTANT) }
657
658#[must_use]
660pub fn casual<S, A: Action<S, R>, R>(a: A) -> Node<S, R> { Node(Box::new(a), CASUAL) }
661
662pub struct Tree<S, F, R> {
664 next: F,
665 prev: Option<Node<S, R>>,
666 interrupt: bool,
667}
668
669impl<S: State, F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static, R: 'static>
670 Action<S, R> for Tree<S, F, R>
671{
672 fn is_same(&self, _other: &Self) -> bool { true }
673
674 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
675
676 fn backtrace(&self, bt: &mut Vec<String>) {
677 if let Some(prev) = &self.prev {
678 prev.0.backtrace(bt);
679 } else {
680 bt.push("<thinking>".to_string());
681 }
682 }
683
684 fn reset(&mut self) { self.prev = None; }
685
686 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
687 let new = (self.next)(ctx, state);
688
689 let prev = match &mut self.prev {
690 Some(prev) if prev.1 <= new.1 && (prev.0.dyn_is_same(&*new.0) || !self.interrupt) => {
691 prev
692 },
693 _ => self.prev.insert(new),
694 };
695
696 match prev.0.tick(ctx, state) {
697 ControlFlow::Continue(()) => ControlFlow::Continue(()),
698 ControlFlow::Break(r) => {
699 self.prev = None;
700 ControlFlow::Break(r)
701 },
702 }
703 }
704}
705
706#[must_use]
730pub fn choose<S: State, R: 'static, F>(f: F) -> impl Action<S, R>
731where
732 F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static,
733{
734 Tree {
735 next: f,
736 prev: None,
737 interrupt: false,
738 }
739}
740
741#[must_use]
765pub fn watch<S: State, R: 'static, F>(f: F) -> impl Action<S, R>
766where
767 F: Fn(&mut NpcCtx, &mut S) -> Node<S, R> + Send + Sync + 'static,
768{
769 Tree {
770 next: f,
771 prev: None,
772 interrupt: true,
773 }
774}
775
776#[derive(Copy, Clone)]
780pub struct Then<A0, A1, R0> {
781 a0: A0,
782 a0_finished: bool,
783 a1: A1,
784 phantom: PhantomData<R0>,
785}
786
787impl<
788 S: State,
789 A0: Action<S, R0>,
790 A1: Action<S, R1>,
791 R0: Send + Sync + 'static,
792 R1: Send + Sync + 'static,
793> Action<S, R1> for Then<A0, A1, R0>
794{
795 fn is_same(&self, other: &Self) -> bool {
796 self.a0.is_same(&other.a0) && self.a1.is_same(&other.a1)
797 }
798
799 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
800
801 fn backtrace(&self, bt: &mut Vec<String>) {
802 if self.a0_finished {
803 self.a1.backtrace(bt);
804 } else {
805 self.a0.backtrace(bt);
806 }
807 }
808
809 fn reset(&mut self) {
810 self.a0.reset();
811 self.a0_finished = false;
812 self.a1.reset();
813 }
814
815 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
816 if !self.a0_finished {
817 match self.a0.tick(ctx, state) {
818 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
819 ControlFlow::Break(_) => self.a0_finished = true,
820 }
821 }
822 self.a1.tick(ctx, state)
823 }
824}
825
826#[derive(Copy, Clone)]
830pub struct AndThen<A0, F, A1, R0> {
831 a0: A0,
832 f: F,
833 a1: Option<A1>,
834 phantom: PhantomData<R0>,
835}
836
837impl<
838 S: State,
839 A0: Action<S, R0>,
840 A1: Action<S, R1>,
841 R0: Send + Sync + 'static,
842 R1: Send + Sync + 'static,
843 F: Fn(R0) -> A1 + Send + Sync + 'static,
844> Action<S, R1> for AndThen<A0, F, A1, R0>
845{
846 fn is_same(&self, other: &Self) -> bool {
847 self.a0.is_same(&other.a0)
848 && match (&self.a1, &other.a1) {
849 (Some(a1_0), Some(a1_1)) => a1_0.is_same(a1_1),
850 _ => true,
851 }
852 }
853
854 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
855
856 fn backtrace(&self, bt: &mut Vec<String>) {
857 if let Some(a1) = &self.a1 {
858 a1.backtrace(bt);
859 } else {
860 self.a0.backtrace(bt);
861 }
862 }
863
864 fn reset(&mut self) {
865 self.a0.reset();
866 self.a1 = None;
867 }
868
869 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
870 let a1 = match &mut self.a1 {
871 None => match self.a0.tick(ctx, state) {
872 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
873 ControlFlow::Break(r) => self.a1.insert((self.f)(r)),
874 },
875 Some(a1) => a1,
876 };
877 a1.tick(ctx, state)
878 }
879}
880
881#[derive(Copy, Clone)]
885pub struct InterruptWith<A0, F, A1, R1> {
886 a0: A0,
887 f: F,
888 a1: Option<A1>,
889 phantom: PhantomData<R1>,
890}
891
892impl<
893 S: State,
894 A0: Action<S, R0>,
895 A1: Action<S, R1>,
896 F: Fn(&mut NpcCtx, &mut S) -> Option<A1> + Send + Sync + 'static,
897 R0: Send + Sync + 'static,
898 R1: Send + Sync + 'static,
899> Action<S, R0> for InterruptWith<A0, F, A1, R1>
900{
901 fn is_same(&self, other: &Self) -> bool { self.a0.is_same(&other.a0) }
902
903 fn dyn_is_same(&self, other: &dyn Action<S, R0>) -> bool { self.dyn_is_same_sized(other) }
904
905 fn backtrace(&self, bt: &mut Vec<String>) {
906 if let Some(a1) = &self.a1 {
907 bt.push("<interrupted>".to_string());
909 a1.backtrace(bt);
910 } else {
911 self.a0.backtrace(bt);
912 }
913 }
914
915 fn reset(&mut self) {
916 self.a0.reset();
917 self.a1 = None;
918 }
919
920 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R0> {
921 if let Some(new_a1) = (self.f)(ctx, state) {
922 self.a1 = Some(new_a1);
923 }
924
925 if let Some(a1) = &mut self.a1 {
926 match a1.tick(ctx, state) {
927 ControlFlow::Continue(()) => return ControlFlow::Continue(()),
928 ControlFlow::Break(_) => self.a1 = None,
929 }
930 }
931
932 self.a0.tick(ctx, state)
933 }
934}
935
936#[derive(Copy, Clone)]
940pub struct Repeat<A, R = ()>(A, PhantomData<R>);
941
942impl<S: State, R: Send + Sync + 'static, A: Action<S, R>> Action<S, !> for Repeat<A, R> {
943 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
944
945 fn dyn_is_same(&self, other: &dyn Action<S, !>) -> bool { self.dyn_is_same_sized(other) }
946
947 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
948
949 fn reset(&mut self) { self.0.reset(); }
950
951 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<!> {
952 match self.0.tick(ctx, state) {
953 ControlFlow::Continue(()) => ControlFlow::Continue(()),
954 ControlFlow::Break(_) => {
955 self.0.reset();
956 ControlFlow::Continue(())
957 },
958 }
959 }
960}
961
962#[derive(Copy, Clone)]
966pub struct Sequence<I, A, R = ()>(Resettable<I>, Option<A>, PhantomData<R>);
967
968impl<
969 S: State,
970 R: Send + Sync + 'static,
971 I: Iterator<Item = A> + Clone + Send + Sync + 'static,
972 A: Action<S, R>,
973> Action<S, ()> for Sequence<I, A, R>
974{
975 fn is_same(&self, _other: &Self) -> bool { true }
976
977 fn dyn_is_same(&self, other: &dyn Action<S, ()>) -> bool { self.dyn_is_same_sized(other) }
978
979 fn backtrace(&self, bt: &mut Vec<String>) {
980 if let Some(action) = &self.1 {
981 action.backtrace(bt);
982 } else {
983 bt.push("<thinking>".to_string());
984 }
985 }
986
987 fn reset(&mut self) {
988 self.0.reset();
989 self.1 = None;
990 }
991
992 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<()> {
993 let item = if let Some(prev) = &mut self.1 {
994 prev
995 } else {
996 match self.0.next() {
997 Some(next) => self.1.insert(next),
998 None => return ControlFlow::Break(()),
999 }
1000 };
1001
1002 if let ControlFlow::Break(_) = item.tick(ctx, state) {
1003 self.1 = None;
1004 }
1005
1006 ControlFlow::Continue(())
1007 }
1008}
1009
1010#[must_use]
1029pub fn seq<S, I, A, R>(iter: I) -> Sequence<I, A, R>
1030where
1031 I: Iterator<Item = A> + Clone,
1032 A: Action<S, R>,
1033{
1034 Sequence(iter.into(), None, PhantomData)
1035}
1036
1037#[derive(Copy, Clone)]
1041pub struct StopIf<A, P>(A, Resettable<P>);
1042
1043impl<S: State, A: Action<S, R>, P: Predicate + Clone + Send + Sync + 'static, R>
1044 Action<S, Option<R>> for StopIf<A, P>
1045{
1046 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1047
1048 fn dyn_is_same(&self, other: &dyn Action<S, Option<R>>) -> bool {
1049 self.dyn_is_same_sized(other)
1050 }
1051
1052 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1053
1054 fn reset(&mut self) {
1055 self.0.reset();
1056 self.1.reset();
1057 }
1058
1059 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<Option<R>> {
1060 if self.1.should(ctx) {
1061 ControlFlow::Break(None)
1062 } else {
1063 self.0.tick(ctx, state).map_break(Some)
1064 }
1065 }
1066}
1067
1068#[derive(Copy, Clone)]
1072pub struct Map<A, F, R>(A, F, PhantomData<R>);
1073
1074impl<
1075 S: State,
1076 A: Action<S, R>,
1077 F: Fn(R, &mut S) -> R1 + Send + Sync + 'static,
1078 R: Send + Sync + 'static,
1079 R1,
1080> Action<S, R1> for Map<A, F, R>
1081{
1082 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1083
1084 fn dyn_is_same(&self, other: &dyn Action<S, R1>) -> bool { self.dyn_is_same_sized(other) }
1085
1086 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt); }
1087
1088 fn reset(&mut self) { self.0.reset(); }
1089
1090 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R1> {
1091 self.0.tick(ctx, state).map_break(|t| (self.1)(t, state))
1092 }
1093}
1094
1095#[derive(Copy, Clone)]
1099pub struct Debug<A, F, T>(A, F, PhantomData<T>);
1100
1101impl<
1102 S: 'static,
1103 A: Action<S, R>,
1104 F: Fn() -> T + Send + Sync + 'static,
1105 R: Send + Sync + 'static,
1106 T: Send + Sync + std::fmt::Display + 'static,
1107> Action<S, R> for Debug<A, F, T>
1108{
1109 fn is_same(&self, other: &Self) -> bool { self.0.is_same(&other.0) }
1110
1111 fn dyn_is_same(&self, other: &dyn Action<S, R>) -> bool { self.dyn_is_same_sized(other) }
1112
1113 fn backtrace(&self, bt: &mut Vec<String>) {
1114 bt.push((self.1)().to_string());
1115 self.0.backtrace(bt);
1116 }
1117
1118 fn reset(&mut self) { self.0.reset(); }
1119
1120 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S) -> ControlFlow<R> {
1121 self.0.tick(ctx, state)
1122 }
1123}
1124
1125#[derive(Copy, Clone)]
1126pub struct WithState<A, S, S0>(A, Resettable<S>, PhantomData<S0>);
1127
1128impl<S0: State, S: State, R, A: Action<S, R>> Action<S0, R> for WithState<A, S, S0> {
1129 fn is_same(&self, other: &Self) -> bool
1130 where
1131 Self: Sized,
1132 {
1133 self.0.is_same(&other.0)
1134 }
1135
1136 fn dyn_is_same(&self, other: &dyn Action<S0, R>) -> bool { self.dyn_is_same_sized(other) }
1137
1138 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt) }
1139
1140 fn reset(&mut self) {
1141 self.0.reset();
1142 self.1.reset();
1143 }
1144
1145 fn tick(&mut self, ctx: &mut NpcCtx, _state: &mut S0) -> ControlFlow<R> {
1146 self.0.tick(ctx, &mut self.1.current)
1147 }
1148}
1149
1150#[derive(Copy, Clone)]
1151pub struct MapState<A, F, S, S0>(A, F, PhantomData<(S, S0)>);
1152
1153impl<S0: State, S: State, R, A: Action<S, R>, F: Fn(&mut S0) -> &mut S + Send + Sync + 'static>
1154 Action<S0, R> for MapState<A, F, S, S0>
1155{
1156 fn is_same(&self, other: &Self) -> bool
1157 where
1158 Self: Sized,
1159 {
1160 self.0.is_same(&other.0)
1161 }
1162
1163 fn dyn_is_same(&self, other: &dyn Action<S0, R>) -> bool { self.dyn_is_same_sized(other) }
1164
1165 fn backtrace(&self, bt: &mut Vec<String>) { self.0.backtrace(bt) }
1166
1167 fn reset(&mut self) { self.0.reset(); }
1168
1169 fn tick(&mut self, ctx: &mut NpcCtx, state: &mut S0) -> ControlFlow<R> {
1170 self.0.tick(ctx, (self.1)(state))
1171 }
1172}