1use super::{as_tbl, object::Object, unit::Unit};
15use crate::{cvt_err, object::{DcsObject, DcsOid}, simple_enum, wrapped_table, LuaEnv, MizLua};
16use anyhow::{bail, Result};
17use mlua::{prelude::*, Value};
18use serde::Deserialize;
19use serde_derive::Serialize;
20use std::{marker::PhantomData, ops::Deref};
21
22simple_enum!(WeaponFlag, u64, [
25 NoWeapon => 0,
26 LGB => 2,
27 TvGB => 4,
28 SNSGB => 8,
29 HEBomb => 16,
30 Penetrator => 32,
31 NapalmBomb => 64,
32 FAEBomb => 128,
33 ClusterBomb => 256,
34 Dispenser => 512,
35 CandleBomb => 1024,
36 ParachuteBomb => 2147483648,
37 GuidedBomb => 14,
38 AnyUnguidedBomb => 2147485680,
39 AnyBomb => 2147485694,
40 LightRocket => 2048,
41 MarkerRocket => 4096,
42 CandleRocket => 8192,
43 HeavyRocket => 16384,
44 AnyRocket => 30720,
45 AntiRadarMissile => 32768,
46 AntiShipMissile => 65536,
47 AntiTankMissile => 131072,
48 FireAndForgetASM => 262144,
49 LaserASM => 524288,
50 TeleASM => 1048576,
51 CruiseMissile => 2097152,
52 GuidedASM => 1572864,
53 TacticalASM => 1835008,
54 AnyASM => 4161536,
55 SRAAM => 4194304,
56 MRAAM => 8388608,
57 LRAAM => 16777216,
58 IRAAM => 33554432,
59 SARAAM => 67108864,
60 ARAAM => 134217728,
61 AnyAAM => 264241152,
62 AnyMissile => 268402688,
63 AnyAutonomousMissile => 36012032,
64 GunPod => 268435456,
65 BuiltInCannon => 536870912,
66 Cannons => 805306368,
67 AntiRadarMissile2 => 1073741824,
68 SmokeShell => 17179869184,
69 IlluminationShell => 34359738368,
70 MarkerShell => 51539607552,
71 SubmunitionDispenserShell => 68719476736,
72 GuidedShell => 137438953472,
73 ConventionalShell => 206963736576,
74 AnyShell => 258503344128,
75 Decoys => 8589934592,
76 Torpedo => 4294967296,
77 AnyAGWeapon => 2956984318,
78 AnyAAWeapon => 1069547520,
79 UnguidedWeapon => 2952822768,
80 GuidedWeapon => 268402702,
81 AnyWeapon => 3221225470,
82 MarkerWeapon => 13312,
83 ArmWeapon => 209379642366
84]);
85
86wrapped_table!(Weapon, Some("Weapon"));
87
88impl<'lua> Weapon<'lua> {
89 pub fn as_object(&self) -> Result<Object<'lua>> {
90 Ok(Object::from_lua(Value::Table(self.t.clone()), self.lua)?)
91 }
92
93 pub fn is_exist(&self) -> Result<bool> {
94 Ok(self.t.call_method("isExist", ())?)
95 }
96
97 pub fn get_name(&self) -> Result<String> {
98 Ok(self.t.call_method("getName", ())?)
99 }
100
101 pub fn get_type(&self) -> Result<String> {
102 Ok(self.t.call_method("getTypeName", ())?)
103 }
104
105 pub fn get_launcher(&self) -> Result<Unit<'lua>> {
106 Ok(self.t.call_method("getLauncher", ())?)
107 }
108
109 pub fn get_target(&self) -> Result<Option<Object<'lua>>> {
110 match self.t.call_method("getTarget", ())? {
111 Value::Nil => Ok(None),
112 v => Ok(Some(Object::from_lua(v, self.lua)?)),
113 }
114 }
115
116 pub fn get_desc(&self) -> Result<mlua::Table<'lua>> {
117 Ok(self.t.call_method("getDesc", ())?)
118 }
119}
120
121#[derive(Debug, Clone)]
122pub struct ClassWeapon;
123
124impl<'lua> DcsObject<'lua> for Weapon<'lua> {
125 type Class = ClassWeapon;
126
127 fn get_instance(lua: MizLua<'lua>, id: &DcsOid<Self::Class>) -> Result<Self> {
128 let t = lua.inner().create_table()?;
129 t.set_metatable(Some(lua.inner().globals().raw_get(&**id.class)?));
130 t.raw_set("id_", id.id)?;
131 let t = Weapon {
132 t,
133 lua: lua.inner(),
134 };
135 if !t.is_exist()? {
136 bail!("{} is an invalid weapon", id.id)
137 }
138 Ok(t)
139 }
140
141 fn get_instance_dyn<T>(lua: MizLua<'lua>, id: &DcsOid<T>) -> Result<Self> {
142 id.check_implements(lua, "Weapon")?;
143 let id = DcsOid {
144 id: id.id,
145 class: id.class.clone(),
146 t: PhantomData,
147 };
148 Self::get_instance(lua, &id)
149 }
150
151 fn change_instance(self, id: &DcsOid<Self::Class>) -> Result<Self> {
152 self.raw_set("id_", id.id)?;
153 if !self.is_exist()? {
154 bail!("{} is an invalid weapon", id.id)
155 }
156 Ok(self)
157 }
158
159 fn change_instance_dyn<T>(self, id: &DcsOid<T>) -> Result<Self> {
160 id.check_implements(MizLua(self.lua), "Weapon")?;
161 self.t.raw_set("id_", id.id)?;
162 if !self.is_exist()? {
163 bail!("{} is an invalid weapon", id.id)
164 }
165 Ok(self)
166 }
167}