dcso3/
warehouse.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;
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}