1use super::as_tbl;
15use crate::{
16 airbase::Airbase, cvt_err, lua_err, simple_enum, wrapped_table, LuaEnv, MizLua, String,
17};
18use anyhow::Result;
19use mlua::{prelude::*, Value};
20use serde_derive::{Deserialize, Serialize};
21use std::ops::Deref;
22
23simple_enum!(LiquidType, u8, [
24 JetFuel => 0,
25 Avgas => 1,
26 MW50 => 2,
27 Diesel => 3
28]);
29
30impl LiquidType {
31 pub const ALL: [LiquidType; 4] = [Self::Avgas, Self::Diesel, Self::JetFuel, Self::MW50];
32}
33
34wrapped_table!(ItemInventory, None);
35
36impl<'lua> ItemInventory<'lua> {
37 pub fn item(&self, name: &str) -> Result<u32> {
38 Ok(self.t.raw_get(name)?)
39 }
40
41 pub fn for_each<F: FnMut(String, u32) -> Result<()>>(&self, mut f: F) -> Result<()> {
42 Ok(self.t.for_each(|k, v| f(k, v).map_err(lua_err))?)
43 }
44}
45
46wrapped_table!(LiquidInventory, None);
47
48impl<'lua> LiquidInventory<'lua> {
49 pub fn item(&self, name: LiquidType) -> Result<u32> {
50 Ok(self.t.raw_get(name)?)
51 }
52
53 pub fn for_each<F: FnMut(LiquidType, u32) -> Result<()>>(&self, mut f: F) -> Result<()> {
54 Ok(self.t.for_each(|k, v| f(k, v).map_err(lua_err))?)
55 }
56}
57
58wrapped_table!(Inventory, None);
59
60impl<'lua> Inventory<'lua> {
61 pub fn weapons(&self) -> Result<ItemInventory<'lua>> {
62 Ok(self.t.raw_get("weapon")?)
63 }
64
65 pub fn aircraft(&self) -> Result<ItemInventory<'lua>> {
66 Ok(self.t.raw_get("aircraft")?)
67 }
68
69 pub fn liquids(&self) -> Result<LiquidInventory<'lua>> {
70 Ok(self.t.raw_get("liquids")?)
71 }
72
73 pub fn is_unlimited(&self) -> Result<bool> {
74 Ok(self.weapons()?.is_empty() && self.aircraft()?.is_empty() && self.liquids()?.is_empty())
75 }
76}
77
78#[derive(Debug, Clone, Copy)]
79pub enum WSFixedWingCategory {
80 Fighters,
81 FastBombers,
82 Interceptors,
83 Bombers,
84 MiscSupport,
85 Attack,
86 Other(i32),
87 None,
88}
89
90#[derive(Debug, Clone, Copy)]
91pub enum WSAircraftCategory {
92 FixedWing(WSFixedWingCategory),
93 Helicopters,
94 Droptank,
95 Other(i32),
96 None,
97}
98
99#[derive(Debug, Clone, Copy)]
100pub enum WSCategory {
101 Aircraft(WSAircraftCategory),
102 Vehicles,
103 Ships,
104 Weapons,
105 Other(i32),
106 None,
107}
108
109impl WSCategory {
110 pub fn is_aircraft(&self) -> bool {
111 match self {
112 Self::Aircraft(WSAircraftCategory::FixedWing(_))
113 | Self::Aircraft(WSAircraftCategory::Helicopters) => true,
114 Self::Aircraft(WSAircraftCategory::Droptank)
115 | Self::Aircraft(WSAircraftCategory::Other(_))
116 | Self::Aircraft(WSAircraftCategory::None)
117 | Self::None
118 | Self::Ships
119 | Self::Vehicles
120 | Self::Weapons
121 | Self::Other(_) => false,
122 }
123 }
124
125 pub fn is_fixedwing(&self) -> bool {
126 match self {
127 Self::Aircraft(WSAircraftCategory::FixedWing(_)) => true,
128 Self::Aircraft(WSAircraftCategory::Helicopters)
129 | Self::Aircraft(WSAircraftCategory::None)
130 | Self::Aircraft(WSAircraftCategory::Droptank)
131 | Self::Aircraft(WSAircraftCategory::Other(_))
132 | Self::None
133 | Self::Ships
134 | Self::Vehicles
135 | Self::Weapons
136 | Self::Other(_) => false,
137 }
138 }
139
140 pub fn is_helicopter(&self) -> bool {
141 match self {
142 Self::Aircraft(WSAircraftCategory::Helicopters) => true,
143 Self::Aircraft(WSAircraftCategory::FixedWing(_))
144 | Self::Aircraft(WSAircraftCategory::None)
145 | Self::Aircraft(WSAircraftCategory::Droptank)
146 | Self::Aircraft(WSAircraftCategory::Other(_))
147 | Self::None
148 | Self::Ships
149 | Self::Vehicles
150 | Self::Weapons
151 | Self::Other(_) => false,
152 }
153 }
154
155 pub fn is_weapon(&self) -> bool {
156 match self {
157 Self::Weapons => true,
158 Self::Aircraft(_) | Self::None | Self::Ships | Self::Vehicles | Self::Other(_) => false,
159 }
160 }
161
162 pub fn is_vehicle(&self) -> bool {
163 match self {
164 Self::Vehicles => true,
165 Self::Aircraft(_) | Self::None | Self::Ships | Self::Weapons | Self::Other(_) => false,
166 }
167 }
168
169 pub fn is_ship(&self) -> bool {
170 match self {
171 Self::Ships => true,
172 Self::Aircraft(_) | Self::None | Self::Weapons | Self::Vehicles | Self::Other(_) => {
173 false
174 }
175 }
176 }
177}
178
179wrapped_table!(WSType, None);
180
181impl<'lua> WSType<'lua> {
182 pub fn category(&self) -> Result<WSCategory> {
183 match self.t.raw_get(1)? {
184 0 => Ok(WSCategory::None),
185 1 => match self.t.raw_get(2)? {
186 0 => Ok(WSCategory::Aircraft(WSAircraftCategory::None)),
187 1 => Ok(WSCategory::Aircraft(WSAircraftCategory::FixedWing(
188 match self.t.raw_get(3)? {
189 0 => WSFixedWingCategory::None,
190 1 => WSFixedWingCategory::Fighters,
191 2 => WSFixedWingCategory::FastBombers,
192 3 => WSFixedWingCategory::Interceptors,
193 4 => WSFixedWingCategory::Bombers,
194 5 => WSFixedWingCategory::MiscSupport,
195 6 => WSFixedWingCategory::Attack,
196 n => WSFixedWingCategory::Other(n),
197 },
198 ))),
199 2 => Ok(WSCategory::Aircraft(WSAircraftCategory::Helicopters)),
200 3 => Ok(WSCategory::Aircraft(WSAircraftCategory::Droptank)),
201 n => Ok(WSCategory::Aircraft(WSAircraftCategory::Other(n))),
202 },
203 2 => Ok(WSCategory::Vehicles),
204 3 => Ok(WSCategory::Ships),
205 4 => Ok(WSCategory::Weapons),
206 n => Ok(WSCategory::Other(n)),
207 }
208 }
209}
210
211wrapped_table!(ResourceMap, None);
212
213impl<'lua> ResourceMap<'lua> {
214 pub fn for_each<F: FnMut(String, WSType) -> Result<()>>(&self, mut f: F) -> Result<()> {
215 Ok(self.t.for_each(|k, v| f(k, v).map_err(lua_err))?)
216 }
217}
218
219#[derive(Debug, Clone)]
220pub enum WarehouseItem<'lua> {
221 Name(String),
222 Typ(WSType<'lua>),
223}
224
225impl<'lua> IntoLua<'lua> for WarehouseItem<'lua> {
226 fn into_lua(self, lua: &'lua Lua) -> LuaResult<Value<'lua>> {
227 match self {
228 Self::Name(s) => s.into_lua(lua),
229 Self::Typ(t) => Ok(Value::Table(t.t)),
230 }
231 }
232}
233
234impl<'lua> From<String> for WarehouseItem<'lua> {
235 fn from(value: String) -> Self {
236 Self::Name(value)
237 }
238}
239
240impl<'lua> From<WSType<'lua>> for WarehouseItem<'lua> {
241 fn from(value: WSType<'lua>) -> Self {
242 Self::Typ(value)
243 }
244}
245
246wrapped_table!(Warehouse, Some("Warehouse"));
247
248impl<'lua> Warehouse<'lua> {
249 pub fn get_by_name(lua: MizLua<'lua>, name: String) -> Result<Self> {
250 let wh: LuaTable = lua.inner().globals().raw_get("Warehouse")?;
251 Ok(wh.call_function("getByName", name)?)
252 }
253
254 pub fn get_resource_map(lua: MizLua<'lua>) -> Result<ResourceMap<'lua>> {
255 let wh: LuaTable = lua.inner().globals().raw_get("Warehouse")?;
256 Ok(wh.call_function("getResourceMap", ())?)
257 }
258
259 pub fn add_item<T: Into<WarehouseItem<'lua>>>(&self, item: T, count: u32) -> Result<()> {
260 Ok(self
261 .t
262 .call_method("addItem", (Into::<WarehouseItem>::into(item), count))?)
263 }
264
265 pub fn remove_item<T: Into<WarehouseItem<'lua>>>(&self, item: T, count: u32) -> Result<()> {
266 Ok(self
267 .t
268 .call_method("removeItem", (Into::<WarehouseItem>::into(item), count))?)
269 }
270
271 pub fn set_item<T: Into<WarehouseItem<'lua>>>(&self, item: T, count: u32) -> Result<()> {
272 Ok(self
273 .t
274 .call_method("setItem", (Into::<WarehouseItem>::into(item), count))?)
275 }
276
277 pub fn get_item_count<T: Into<WarehouseItem<'lua>>>(&self, item: T) -> Result<u32> {
278 Ok(self
279 .t
280 .call_method("getItemCount", Into::<WarehouseItem>::into(item))?)
281 }
282
283 pub fn add_liquid(&self, typ: LiquidType, count: u32) -> Result<()> {
284 Ok(self.t.call_method("addLiquid", (typ, count))?)
285 }
286
287 pub fn remove_liquid(&self, typ: LiquidType, count: u32) -> Result<()> {
288 Ok(self.t.call_method("removeLiquid", (typ, count))?)
289 }
290
291 pub fn get_liquid_amount(&self, typ: LiquidType) -> Result<u32> {
292 Ok(self.t.call_method("getLiquidAmount", typ)?)
293 }
294
295 pub fn set_liquid_amount(&self, typ: LiquidType, count: u32) -> Result<()> {
296 Ok(self.t.call_method("setLiquidAmount", (typ, count))?)
297 }
298
299 pub fn get_inventory(&self, filter: Option<String>) -> Result<Inventory<'lua>> {
300 Ok(self.t.call_method("getInventory", filter)?)
301 }
302
303 pub fn get_owner(&self) -> Result<Airbase> {
304 Ok(self.t.call_method("getOwner", ())?)
305 }
306
307 pub fn whid(&self) -> Result<String> {
308 Ok(self.t.raw_get("whid_")?)
309 }
310}