veloren_rtsim/ai/
predicate.rs1use rand::Rng;
2
3use super::NpcCtx;
4
5pub trait Predicate: Sized + Clone {
6 fn should(&mut self, ctx: &mut NpcCtx) -> bool;
7
8 fn chance(self, chance: f32) -> Chance<Self> {
9 Chance {
10 predicate: self,
11 chance,
12 }
13 }
14
15 fn time_hint(&self) -> Option<f32> { None }
17}
18
19#[derive(Clone, Copy)]
20pub struct Yes;
21
22impl Predicate for Yes {
23 fn should(&mut self, _ctx: &mut NpcCtx) -> bool { true }
24
25 fn time_hint(&self) -> Option<f32> { Some(0.0) }
26}
27
28#[derive(Clone)]
29pub struct EveryRange {
30 next: Option<f32>,
31 sample: std::ops::Range<f32>,
32}
33
34pub fn every_range(r: std::ops::Range<f32>) -> EveryRange {
35 EveryRange {
36 next: None,
37 sample: r,
38 }
39}
40
41impl Predicate for EveryRange {
42 fn should(&mut self, ctx: &mut NpcCtx) -> bool {
43 if let Some(ref mut next) = self.next {
44 *next -= ctx.dt;
45 if *next <= 0.0 {
46 *next += ctx.rng.gen_range(self.sample.clone());
47 true
48 } else {
49 false
50 }
51 } else {
52 self.next = Some(ctx.rng.gen_range(self.sample.clone()));
53 false
54 }
55 }
56
57 fn time_hint(&self) -> Option<f32> { self.next }
58}
59
60#[derive(Clone, Copy)]
61pub struct Chance<P> {
62 predicate: P,
63 chance: f32,
64}
65
66impl<P: Predicate> Predicate for Chance<P> {
67 fn should(&mut self, ctx: &mut NpcCtx) -> bool {
68 self.predicate.should(ctx) && ctx.rng.gen_bool(self.chance as f64)
69 }
70
71 fn time_hint(&self) -> Option<f32> { self.predicate.time_hint() }
72}
73
74impl<F: Fn(&mut NpcCtx) -> bool + Clone> Predicate for F {
75 fn should(&mut self, ctx: &mut NpcCtx) -> bool { self(ctx) }
76}
77
78pub fn timeout(time: f64) -> Timeout { Timeout { seconds_left: time } }
80
81#[derive(Clone, Copy)]
82pub struct Timeout {
83 seconds_left: f64,
84}
85
86impl Predicate for Timeout {
87 fn should(&mut self, ctx: &mut NpcCtx) -> bool {
88 self.seconds_left -= ctx.dt as f64;
89 self.seconds_left <= 0.0
90 }
91
92 fn time_hint(&self) -> Option<f32> { Some(self.seconds_left.max(0.0) as f32) }
93}