steel_core/entity/ai/walk/
settings.rs1use super::{BlockPos, FluidState, Mob, PathType, PathfindingMalus, WorldAabb, fast_floor};
2
3#[derive(Debug, Clone)]
4pub struct MobPathSettings {
5 entity_width: i32,
6 entity_height: i32,
7 entity_depth: i32,
8 mob_position_vec: glam::DVec3,
9 mob_position: BlockPos,
10 bounding_box: WorldAabb,
11 on_ground: bool,
12 in_water: bool,
13 can_stand_on_fluid: fn(FluidState) -> bool,
14 max_up_step: f32,
15 max_fall_distance: i32,
16 malus: [f32; PathType::COUNT],
17 can_pass_doors: bool,
18 can_open_doors: bool,
19 can_float: bool,
20 can_walk_over_fences: bool,
21}
22
23impl MobPathSettings {
24 #[must_use]
25 pub fn from_mob<M: Mob + ?Sized>(mob: &M) -> Self {
26 let bounding_box = mob.bounding_box();
27 let mut malus = [0.0; PathType::COUNT];
28 for path_type in PathType::ALL {
29 malus[path_type.index()] = mob.get_pathfinding_malus(path_type);
30 }
31
32 let navigation = mob.mob_base().navigation().lock();
33 let can_float = navigation.can_float();
34 let can_open_doors = navigation.can_open_doors();
35 let can_walk_over_fences = navigation.can_walk_over_fences();
36 drop(navigation);
37
38 Self {
39 entity_width: fast_floor(bounding_box.width() + 1.0),
40 entity_height: fast_floor(bounding_box.height() + 1.0),
41 entity_depth: fast_floor(bounding_box.width() + 1.0),
42 mob_position_vec: mob.position(),
43 mob_position: mob.block_position(),
44 bounding_box,
45 on_ground: mob.on_ground(),
46 in_water: mob.is_in_water(),
47 can_stand_on_fluid: |_| false,
48 max_up_step: mob.max_up_step(),
49 max_fall_distance: mob.max_fall_distance(),
50 malus,
51 can_pass_doors: true,
52 can_open_doors,
53 can_float,
54 can_walk_over_fences,
55 }
56 }
57
58 #[must_use]
59 pub fn new(
60 entity_width: i32,
61 entity_height: i32,
62 entity_depth: i32,
63 mob_position: BlockPos,
64 pathfinding_malus: &PathfindingMalus,
65 ) -> Self {
66 let width = entity_width.max(1);
67 let height = entity_height.max(1);
68 let depth = entity_depth.max(1);
69 let center_x = f64::from(mob_position.x()) + 0.5;
70 let center_z = f64::from(mob_position.z()) + 0.5;
71 let bounding_box = WorldAabb::new(
72 center_x - f64::from(width) * 0.5,
73 f64::from(mob_position.y()),
74 center_z - f64::from(depth) * 0.5,
75 center_x + f64::from(width) * 0.5,
76 f64::from(mob_position.y()) + f64::from(height),
77 center_z + f64::from(depth) * 0.5,
78 );
79 let mut malus = [0.0; PathType::COUNT];
80 for path_type in PathType::ALL {
81 malus[path_type.index()] = pathfinding_malus.get(path_type);
82 }
83
84 Self {
85 entity_width: width,
86 entity_height: height,
87 entity_depth: depth,
88 mob_position_vec: glam::DVec3::new(center_x, f64::from(mob_position.y()), center_z),
89 mob_position,
90 bounding_box,
91 on_ground: true,
92 in_water: false,
93 can_stand_on_fluid: |_| false,
94 max_up_step: 0.6,
95 max_fall_distance: 3,
96 malus,
97 can_pass_doors: true,
98 can_open_doors: false,
99 can_float: false,
100 can_walk_over_fences: false,
101 }
102 }
103
104 #[must_use]
105 pub const fn with_can_pass_doors(mut self, can_pass_doors: bool) -> Self {
106 self.can_pass_doors = can_pass_doors;
107 self
108 }
109
110 #[must_use]
111 pub const fn with_can_open_doors(mut self, can_open_doors: bool) -> Self {
112 self.can_open_doors = can_open_doors;
113 self
114 }
115
116 #[must_use]
117 pub const fn with_can_float(mut self, can_float: bool) -> Self {
118 self.can_float = can_float;
119 self
120 }
121
122 #[must_use]
123 pub const fn with_can_walk_over_fences(mut self, can_walk_over_fences: bool) -> Self {
124 self.can_walk_over_fences = can_walk_over_fences;
125 self
126 }
127
128 #[must_use]
129 pub const fn with_max_up_step(mut self, max_up_step: f32) -> Self {
130 self.max_up_step = max_up_step;
131 self
132 }
133
134 #[must_use]
135 pub const fn with_max_fall_distance(mut self, max_fall_distance: i32) -> Self {
136 self.max_fall_distance = max_fall_distance;
137 self
138 }
139
140 #[must_use]
141 pub const fn with_on_ground(mut self, on_ground: bool) -> Self {
142 self.on_ground = on_ground;
143 self
144 }
145
146 #[must_use]
147 pub const fn with_in_water(mut self, in_water: bool) -> Self {
148 self.in_water = in_water;
149 self
150 }
151
152 #[must_use]
153 pub const fn with_can_stand_on_fluid(
154 mut self,
155 can_stand_on_fluid: fn(FluidState) -> bool,
156 ) -> Self {
157 self.can_stand_on_fluid = can_stand_on_fluid;
158 self
159 }
160
161 #[must_use]
162 pub const fn entity_width(&self) -> i32 {
163 self.entity_width
164 }
165
166 #[must_use]
167 pub const fn entity_height(&self) -> i32 {
168 self.entity_height
169 }
170
171 #[must_use]
172 pub const fn entity_depth(&self) -> i32 {
173 self.entity_depth
174 }
175
176 #[must_use]
177 pub const fn mob_position(&self) -> BlockPos {
178 self.mob_position
179 }
180
181 #[must_use]
182 pub const fn mob_position_vec(&self) -> glam::DVec3 {
183 self.mob_position_vec
184 }
185
186 #[must_use]
187 pub const fn bounding_box(&self) -> WorldAabb {
188 self.bounding_box
189 }
190
191 #[must_use]
192 pub const fn on_ground(&self) -> bool {
193 self.on_ground
194 }
195
196 #[must_use]
197 pub const fn in_water(&self) -> bool {
198 self.in_water
199 }
200
201 #[must_use]
202 pub fn can_stand_on_fluid(&self, fluid_state: FluidState) -> bool {
203 (self.can_stand_on_fluid)(fluid_state)
204 }
205
206 #[must_use]
207 pub const fn max_up_step(&self) -> f32 {
208 self.max_up_step
209 }
210
211 #[must_use]
212 pub const fn max_fall_distance(&self) -> i32 {
213 self.max_fall_distance
214 }
215
216 #[must_use]
217 pub const fn pathfinding_malus(&self, path_type: PathType) -> f32 {
218 self.malus[path_type.index()]
219 }
220
221 #[must_use]
222 pub const fn can_pass_doors(&self) -> bool {
223 self.can_pass_doors
224 }
225
226 #[must_use]
227 pub const fn can_open_doors(&self) -> bool {
228 self.can_open_doors
229 }
230
231 #[must_use]
232 pub const fn can_float(&self) -> bool {
233 self.can_float
234 }
235
236 #[must_use]
237 pub const fn can_walk_over_fences(&self) -> bool {
238 self.can_walk_over_fences
239 }
240}