1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use crate::prelude::*;

use super::COLLISION_RESOLUTION;

pub fn raycast(
    origin: Vec2,
    end: Vec2,
    ignore_barriers: bool,
    ignore_actors: bool,
) -> Option<Vec2> {
    if origin.distance(end) > COLLISION_RESOLUTION {
        let map = storage::get::<Map>();
        let direction = end.sub(origin).normalize_or_zero();
        let collider = Collider::circle(0.0, 0.0, 1.0);
        let change = direction * COLLISION_RESOLUTION;
        let mut current = origin;
        while current.distance(end) > COLLISION_RESOLUTION {
            let collider = collider.with_offset(current);
            for (_, kind) in map.get_collisions(collider) {
                if !ignore_barriers || kind == CollisionKind::Solid {
                    return Some(current);
                }
            }
            if !ignore_actors {
                for actor in scene::find_nodes_by_type::<Actor>() {
                    if let Some(other_collider) = actor.body.get_offset_collider() {
                        if other_collider.contains(current) {
                            return Some(current);
                        }
                    }
                }
            }
            current += change;
        }
    }
    None
}