azalea_core/
hit_result.rs

1use bevy_ecs::entity::Entity;
2
3use crate::{
4    direction::Direction,
5    position::{BlockPos, Vec3},
6};
7
8/// The block or entity that our player is looking at and can interact with.
9///
10/// If there's nothing, it'll be a [`BlockHitResult`] with `miss` set to true.
11#[derive(Debug, Clone, PartialEq)]
12pub enum HitResult {
13    Block(BlockHitResult),
14    Entity(EntityHitResult),
15}
16
17impl HitResult {
18    pub fn miss(&self) -> bool {
19        match self {
20            HitResult::Block(r) => r.miss,
21            _ => false,
22        }
23    }
24    pub fn location(&self) -> Vec3 {
25        match self {
26            HitResult::Block(r) => r.location,
27            HitResult::Entity(r) => r.location,
28        }
29    }
30
31    pub fn new_miss(location: Vec3, direction: Direction, block_pos: BlockPos) -> Self {
32        HitResult::Block(BlockHitResult {
33            location,
34            miss: true,
35            direction,
36            block_pos,
37            inside: false,
38            world_border: false,
39        })
40    }
41
42    pub fn is_block_hit_and_not_miss(&self) -> bool {
43        matches!(self, HitResult::Block(r) if !r.miss)
44    }
45
46    /// Returns the [`BlockHitResult`], if we were looking at a block and it
47    /// wasn't a miss.
48    pub fn as_block_hit_result_if_not_miss(&self) -> Option<&BlockHitResult> {
49        if let HitResult::Block(r) = self
50            && !r.miss
51        {
52            Some(r)
53        } else {
54            None
55        }
56    }
57}
58
59#[derive(Debug, Clone, PartialEq)]
60pub struct BlockHitResult {
61    pub location: Vec3,
62    pub miss: bool,
63
64    pub direction: Direction,
65    pub block_pos: BlockPos,
66    pub inside: bool,
67    pub world_border: bool,
68}
69impl BlockHitResult {
70    pub fn miss(location: Vec3, direction: Direction, block_pos: BlockPos) -> Self {
71        Self {
72            location,
73            miss: true,
74
75            direction,
76            block_pos,
77            inside: false,
78            world_border: false,
79        }
80    }
81
82    pub fn with_direction(&self, direction: Direction) -> Self {
83        Self { direction, ..*self }
84    }
85    pub fn with_position(&self, block_pos: BlockPos) -> Self {
86        Self { block_pos, ..*self }
87    }
88}
89
90#[derive(Debug, Clone, PartialEq)]
91pub struct EntityHitResult {
92    pub location: Vec3,
93    pub entity: Entity,
94}
95
96impl From<BlockHitResult> for HitResult {
97    fn from(value: BlockHitResult) -> Self {
98        HitResult::Block(value)
99    }
100}
101impl From<EntityHitResult> for HitResult {
102    fn from(value: EntityHitResult) -> Self {
103        HitResult::Entity(value)
104    }
105}