dcso3/
land.rs

1/*
2Copyright 2024 Eric Stokes.
3
4This file is part of dcso3.
5
6dcso3 is free software: you can redistribute it and/or modify it under
7the terms of the MIT License.
8
9dcso3 is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE.
12*/
13
14use super::{as_tbl, cvt_err, LuaVec3};
15use crate::{record_perf, simple_enum, wrapped_table, LuaEnv, LuaVec2, MizLua, Sequence};
16use anyhow::Result;
17use mlua::{prelude::*, Value};
18use na::Vector2;
19use serde_derive::{Deserialize, Serialize};
20use std::ops::Deref;
21
22simple_enum!(SurfaceType, u8, [
23    Land => 1,
24    ShallowWater => 2,
25    Water => 3,
26    Road => 4,
27    Runway => 5
28]);
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
31pub enum RoadType {
32    Road,
33    Rail,
34}
35
36wrapped_table!(Land, None);
37
38impl<'lua> Land<'lua> {
39    pub fn singleton(lua: MizLua<'lua>) -> Result<Self> {
40        Ok(lua.inner().globals().raw_get("land")?)
41    }
42
43    pub fn get_height(&self, p: LuaVec2) -> Result<f64> {
44        Ok(record_perf!(land_get_height, self.t.call_function("getHeight", p)?))
45    }
46
47    pub fn get_surface_height_with_seabed(&self, p: LuaVec2) -> Result<(f64, f64)> {
48        Ok(self.t.call_function("getSurfaceHeightWithSeabed", p)?)
49    }
50
51    pub fn get_surface_type(&self, p: LuaVec2) -> Result<SurfaceType> {
52        Ok(self.t.call_function("getSurfaceType", p)?)
53    }
54
55    pub fn is_visible(&self, origin: LuaVec3, destination: LuaVec3) -> Result<bool> {
56        Ok(record_perf!(land_is_visible, self.t.call_function("isVisible", (origin, destination))?))
57    }
58
59    pub fn get_ip(&self, origin: LuaVec3, direction: LuaVec3, distance: f64) -> Result<LuaVec3> {
60        Ok(self
61            .t
62            .call_function("getIP", (origin, direction, distance))?)
63    }
64
65    pub fn get_profile(&self, origin: LuaVec3, destination: LuaVec3) -> Result<Sequence<'lua, LuaVec3>> {
66        Ok(self.t.call_function("profile", (origin, destination))?)
67    }
68
69    pub fn get_closest_point_on_roads(&self, typ: RoadType, from: LuaVec2) -> Result<LuaVec2> {
70        let typ = match typ {
71            RoadType::Road => "roads",
72            RoadType::Rail => "railroads",
73        };
74        let (x, y) = self
75            .t
76            .call_function("getClosestPointOnRoads", (typ, from.x, from.y))?;
77        Ok(LuaVec2(Vector2::new(x, y)))
78    }
79
80    pub fn find_path_on_roads(
81        &self,
82        typ: RoadType,
83        origin: LuaVec2,
84        destination: LuaVec2,
85    ) -> Result<Sequence<'lua, LuaVec2>> {
86        let typ = match typ {
87            RoadType::Road => "roads",
88            RoadType::Rail => "rails",
89        };
90        Ok(self.t.call_function(
91            "findPathOnRoads",
92            (typ, origin.x, origin.y, destination.x, destination.y),
93        )?)
94    }
95}