Skip to main content

steel_core/entity/ai/goal/
restrict_sun.rs

1use super::selector::{Goal, GoalControls};
2use crate::entity::PathfinderMob;
3use crate::inventory::equipment::EquipmentSlot;
4
5pub struct RestrictSunGoal;
6
7impl RestrictSunGoal {
8    #[must_use]
9    pub(crate) const fn new() -> Self {
10        Self
11    }
12}
13
14impl Goal for RestrictSunGoal {
15    fn controls(&self) -> GoalControls {
16        GoalControls::EMPTY
17    }
18
19    fn can_use(&mut self, mob: &dyn PathfinderMob) -> bool {
20        let Some(world) = mob.level() else {
21            return false;
22        };
23
24        world.is_bright_outside() && !mob.has_item_in_slot(EquipmentSlot::Head)
25    }
26
27    fn start(&mut self, mob: &dyn PathfinderMob) {
28        mob.mob_base().navigation().lock().set_avoid_sun(true);
29    }
30
31    fn stop(&mut self, mob: &dyn PathfinderMob) {
32        mob.mob_base().navigation().lock().set_avoid_sun(false);
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use std::sync::Weak;
39
40    use glam::DVec3;
41    use steel_registry::{init_vanilla_registry, vanilla_entities};
42
43    use super::*;
44    use crate::entity::Mob as _;
45    use crate::entity::entities::PigEntity;
46
47    fn pig() -> PigEntity {
48        PigEntity::new(&vanilla_entities::PIG, 1, DVec3::ZERO, Weak::new())
49    }
50
51    #[test]
52    fn restrict_sun_goal_claims_no_controls_like_vanilla() {
53        let goal = RestrictSunGoal::new();
54
55        assert_eq!(goal.controls(), GoalControls::EMPTY);
56    }
57
58    #[test]
59    fn restrict_sun_goal_requires_world() {
60        init_vanilla_registry();
61        let mut goal = RestrictSunGoal::new();
62
63        assert!(!goal.can_use(&pig()));
64    }
65
66    #[test]
67    fn restrict_sun_goal_toggles_navigation_avoid_sun() {
68        init_vanilla_registry();
69        let mut goal = RestrictSunGoal::new();
70        let pig = pig();
71
72        assert!(!pig.mob_base().navigation().lock().avoid_sun());
73
74        goal.start(&pig);
75        assert!(pig.mob_base().navigation().lock().avoid_sun());
76
77        goal.stop(&pig);
78        assert!(!pig.mob_base().navigation().lock().avoid_sun());
79    }
80}