1use super::{as_tbl, coalition::Side, object::Object, warehouse::Warehouse, LuaVec3, String};
15use crate::{
16 object::{DcsObject, DcsOid},
17 wrapped_table, LuaEnv, MizLua, Sequence, wrapped_prim,
18};
19use anyhow::{bail, Result};
20use mlua::{prelude::*, Value};
21use serde_derive::{Serialize, Deserialize};
22use std::{marker::PhantomData, ops::Deref};
23
24wrapped_prim!(RunwayId, i64, Hash, Copy);
25wrapped_prim!(AirbaseId, i64, Hash, Copy);
26
27wrapped_table!(Runway, None);
28
29impl<'lua> Runway<'lua> {
30 pub fn id(&self) -> Result<RunwayId> {
31 Ok(self.t.raw_get("Name")?)
32 }
33
34 pub fn course(&self) -> Result<f64> {
35 Ok(self.t.raw_get("course")?)
36 }
37
38 pub fn position(&self) -> Result<LuaVec3> {
39 Ok(self.t.raw_get("position")?)
40 }
41
42 pub fn length(&self) -> Result<f64> {
43 Ok(self.t.raw_get("length")?)
44 }
45
46 pub fn width(&self) -> Result<f64> {
47 Ok(self.t.raw_get("width")?)
48 }
49}
50
51wrapped_table!(Parking, None);
52
53wrapped_table!(Airbase, Some("Airbase"));
54
55impl<'lua> Airbase<'lua> {
56 pub fn get_by_name(lua: MizLua<'lua>, name: String) -> Result<Self> {
57 let globals = lua.inner().globals();
58 let airbase: LuaTable = globals.raw_get("Airbase")?;
59 Ok(airbase.call_function("getByName", name)?)
60 }
61
62 pub fn is_exist(&self) -> Result<bool> {
63 Ok(self.t.call_method("isExist", ())?)
64 }
65
66 pub fn destroy(&self) -> Result<()> {
67 Ok(self.t.call_method("destroy", ())?)
68 }
69
70 pub fn get_desc(&self) -> Result<mlua::Table<'lua>> {
71 Ok(self.t.call_method("getDesc", ())?)
72 }
73
74 pub fn get_point(&self) -> Result<LuaVec3> {
75 Ok(self.t.call_method("getPoint", ())?)
76 }
77
78 pub fn get_callsign(&self) -> Result<String> {
79 Ok(self.t.call_method("getCallsign", ())?)
80 }
81
82 pub fn get_unit(&self, i: i64) -> Result<Object<'lua>> {
83 Ok(self.t.call_method("getUnit", i)?)
84 }
85
86 pub fn get_id(&self) -> Result<AirbaseId> {
87 Ok(self.t.call_method("getId", ())?)
88 }
89
90 pub fn get_parking(&self, available: bool) -> Result<Parking<'lua>> {
91 Ok(self.t.call_method("getParking", available)?)
92 }
93
94 pub fn get_runways(&self) -> Result<Sequence<'lua, Runway<'lua>>> {
95 Ok(self.t.call_method("getRunways", ())?)
96 }
97
98 pub fn get_tech_object_pos(&self, obj: String) -> Result<LuaVec3> {
99 Ok(self.t.call_method("getTechObjectPos", obj)?)
100 }
101
102 pub fn get_radio_silent_mode(&self) -> Result<bool> {
103 Ok(self.t.call_method("getRadioSilentMode", ())?)
104 }
105
106 pub fn set_radio_silent_mode(&self, on: bool) -> Result<()> {
107 Ok(self.t.call_method("setRadioSilentMode", on)?)
108 }
109
110 pub fn auto_capture(&self, on: bool) -> Result<()> {
111 Ok(self.t.call_method("autoCapture", on)?)
112 }
113
114 pub fn auto_capture_is_on(&self) -> Result<bool> {
115 Ok(self.t.call_method("autoCaptureIsOn", ())?)
116 }
117
118 pub fn set_coalition(&self, coa: Side) -> Result<()> {
119 Ok(self.t.call_method("setCoalition", coa)?)
120 }
121
122 pub fn get_warehouse(&self) -> Result<Warehouse<'lua>> {
123 Ok(self.t.call_method("getWarehouse", ())?)
124 }
125
126 pub fn as_object(&self) -> Result<Object<'lua>> {
127 Ok(Object::from_lua(Value::Table(self.t.clone()), self.lua)?)
128 }
129}
130
131#[derive(Debug, Clone)]
132pub struct ClassAirbase;
133
134impl<'lua> DcsObject<'lua> for Airbase<'lua> {
135 type Class = ClassAirbase;
136
137 fn get_instance(lua: MizLua<'lua>, id: &DcsOid<Self::Class>) -> Result<Self> {
138 let t = lua.inner().create_table()?;
139 t.set_metatable(Some(lua.inner().globals().raw_get(&**id.class)?));
140 t.raw_set("id_", id.id)?;
141 let t = Airbase {
142 t,
143 lua: lua.inner(),
144 };
145 if !t.is_exist()? {
146 bail!("{} is an invalid airbase", id.id)
147 }
148 Ok(t)
149 }
150
151 fn get_instance_dyn<T>(lua: MizLua<'lua>, id: &DcsOid<T>) -> Result<Self> {
152 id.check_implements(lua, "Airbase")?;
153 let id = DcsOid {
154 id: id.id,
155 class: id.class.clone(),
156 t: PhantomData,
157 };
158 Self::get_instance(lua, &id)
159 }
160
161 fn change_instance(self, id: &DcsOid<Self::Class>) -> Result<Self> {
162 self.raw_set("id_", id.id)?;
163 if !self.is_exist()? {
164 bail!("{} is an invalid airbase", id.id)
165 }
166 Ok(self)
167 }
168
169 fn change_instance_dyn<T>(self, id: &DcsOid<T>) -> Result<Self> {
170 id.check_implements(MizLua(self.lua), "Airbase")?;
171 self.t.raw_set("id_", id.id)?;
172 if !self.is_exist()? {
173 bail!("{} is an invalid airbase", id.id)
174 }
175 Ok(self)
176 }
177}