spring_ai_rs/ai_interface/callback/
cheat.rs1use std::error::Error;
2
3use spring_ai_sys::COMMAND_TO_ID_ENGINE;
4
5use crate::{
6 ai_interface::{
7 callback::{
8 command::{
9 command_data::{
10 cheats::{
11 GiveMeNewUnitCheatCommandData, GiveMeResourceCheatCommandData,
12 SetMyIncomeMultiplierCheatCommandData,
13 },
14 CommandData,
15 },
16 command_topic::CommandTopic,
17 },
18 engine::handle_command,
19 resource::Resource,
20 unit::Unit,
21 unit_def::UnitDef,
22 },
23 AIInterface,
24 },
25 get_callback,
26};
27
28#[derive(Debug, Copy, Clone)]
29pub struct Cheat {
30 ai_id: i32,
31}
32
33#[derive(Debug, Copy, Clone)]
34pub struct CheatAll {
35 status: bool,
36 will_desync: bool,
37}
38
39impl AIInterface {
40 pub fn cheat(&self) -> Cheat {
41 Cheat { ai_id: self.ai_id }
42 }
43}
44
45impl Cheat {
46 pub fn enable(&self) -> Result<(), Box<dyn Error>> {
47 let set_cheat = get_callback!(self.ai_id, Cheats_setEnabled)?;
48 unsafe { set_cheat(self.ai_id, true) };
49 Ok(())
50 }
51
52 pub fn enable_event(&self) -> Result<(), Box<dyn Error>> {
53 let set_cheat_event = get_callback!(self.ai_id, Cheats_setEventsEnabled)?;
54 unsafe { set_cheat_event(self.ai_id, true) };
55 Ok(())
56 }
57
58 pub fn disable(&self) -> Result<(), Box<dyn Error>> {
59 let set_cheat = get_callback!(self.ai_id, Cheats_setEnabled)?;
60 unsafe { set_cheat(self.ai_id, false) };
61 Ok(())
62 }
63
64 pub fn disable_event(&self) -> Result<(), Box<dyn Error>> {
65 let set_cheat_event = get_callback!(self.ai_id, Cheats_setEventsEnabled)?;
66 unsafe { set_cheat_event(self.ai_id, false) };
67 Ok(())
68 }
69
70 pub fn status(&self) -> Result<bool, Box<dyn Error>> {
71 let get_cheat = get_callback!(self.ai_id, Cheats_isEnabled)?;
72 Ok(unsafe { get_cheat(self.ai_id) })
73 }
74
75 pub fn will_desync(&self) -> Result<bool, Box<dyn Error>> {
76 let is_passive = get_callback!(self.ai_id, Cheats_isOnlyPassive)?;
77 Ok(unsafe { is_passive(self.ai_id) })
78 }
79
80 pub fn give_unit(&self, unit_def: UnitDef, position: [f32; 3]) -> Result<Unit, String> {
81 let mut command_c_data = GiveMeNewUnitCheatCommandData {
82 unit_def_id: unit_def.def_id,
83 position,
84 }
85 .c_data();
86
87 handle_command(
88 self.ai_id,
89 COMMAND_TO_ID_ENGINE,
90 -1,
91 CommandTopic::CheatsGiveMeNewUnit.into(),
92 &mut command_c_data,
93 )?;
94
95 Ok(Unit {
96 ai_id: self.ai_id,
97 unit_id: command_c_data.ret_newUnitId,
98 })
99 }
100
101 pub fn give_resource(&self, resource: Resource, amount: f32) -> Result<(), String> {
102 let mut command_data = GiveMeResourceCheatCommandData {
103 resource_id: resource.resource_id,
104 amount,
105 };
106
107 handle_command(
108 self.ai_id,
109 COMMAND_TO_ID_ENGINE,
110 -1,
111 CommandTopic::CallLuaRules.into(),
112 &mut command_data.c_data(),
113 )?;
114
115 Ok(())
116 }
117
118 pub fn set_income_multiplier(&self, factor: f32) -> Result<(), String> {
119 let mut command_data = SetMyIncomeMultiplierCheatCommandData { factor };
120
121 handle_command(
122 self.ai_id,
123 COMMAND_TO_ID_ENGINE,
124 -1,
125 CommandTopic::CallLuaRules.into(),
126 &mut command_data.c_data(),
127 )?;
128
129 Ok(())
130 }
131
132 pub fn all(&self) -> Result<CheatAll, Box<dyn Error>> {
133 Ok(CheatAll {
134 status: self.status()?,
135 will_desync: self.will_desync()?,
136 })
137 }
138}