1use crate::settings::Settings;
4
5#[derive(Debug, Clone, Default)]
7pub struct Program {
8 pub settings: Option<Settings>,
9 pub global_variables: Vec<Variable>,
10 pub player_variables: Vec<Variable>,
11 pub subroutines: Vec<Subroutine>,
12 pub rules: Vec<Rule>,
13}
14
15impl Program {
16 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn global_variable(&mut self, variable: Variable) -> &mut Self {
21 self.global_variables.push(variable);
22 self
23 }
24
25 pub fn player_variable(&mut self, variable: Variable) -> &mut Self {
26 self.player_variables.push(variable);
27 self
28 }
29
30 pub fn subroutine(&mut self, subroutine: Subroutine) -> &mut Self {
31 self.subroutines.push(subroutine);
32 self
33 }
34
35 pub fn rule(&mut self, rule: Rule) -> &mut Self {
36 self.rules.push(rule);
37 self
38 }
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct Variable {
44 pub name: String,
45 pub index: Option<u32>,
47}
48
49impl Variable {
50 pub fn new(name: impl Into<String>) -> Self {
51 Self {
52 name: name.into(),
53 index: None,
54 }
55 }
56
57 pub fn with_index(name: impl Into<String>, index: u32) -> Self {
58 Self {
59 name: name.into(),
60 index: Some(index),
61 }
62 }
63}
64
65#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct Subroutine {
68 pub name: String,
69 pub index: Option<u32>,
71}
72
73impl Subroutine {
74 pub fn new(name: impl Into<String>) -> Self {
75 Self {
76 name: name.into(),
77 index: None,
78 }
79 }
80
81 pub fn with_index(name: impl Into<String>, index: u32) -> Self {
82 Self {
83 name: name.into(),
84 index: Some(index),
85 }
86 }
87}
88
89#[derive(Debug, Clone)]
91pub struct Rule {
92 pub name: String,
93 pub disabled: bool,
94 pub event: Event,
95 pub conditions: Vec<Condition>,
96 pub actions: Vec<Action>,
97}
98
99impl Rule {
100 pub fn new(name: impl Into<String>, event: Event) -> Self {
101 Self {
102 name: name.into(),
103 disabled: false,
104 event,
105 conditions: Vec::new(),
106 actions: Vec::new(),
107 }
108 }
109
110 pub fn condition(mut self, condition: impl Into<Condition>) -> Self {
111 self.conditions.push(condition.into());
112 self
113 }
114
115 pub fn action(mut self, action: Action) -> Self {
116 self.actions.push(action);
117 self
118 }
119}
120
121#[derive(Debug, Clone)]
123pub struct Condition {
124 pub value: Value,
125 pub disabled: bool,
126}
127
128impl Condition {
129 pub fn new(value: Value) -> Self {
130 Self {
131 value,
132 disabled: false,
133 }
134 }
135
136 pub fn disabled(value: Value) -> Self {
137 Self {
138 value,
139 disabled: true,
140 }
141 }
142}
143
144impl From<Value> for Condition {
145 fn from(value: Value) -> Self {
146 Self::new(value)
147 }
148}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
152pub enum Event {
153 Global,
154 EachPlayer,
155 EachPlayerWithFilters {
156 team: EventTeam,
157 target: EventTarget,
158 },
159 Player {
160 kind: PlayerEventKind,
161 team: EventTeam,
162 target: EventTarget,
163 },
164 Subroutine(String),
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq)]
168pub enum EventTeam {
169 All,
170 Team1,
171 Team2,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq)]
175pub enum EventTarget {
176 All,
177 Slot(u8),
178 Hero(String),
179}
180
181#[derive(Debug, Clone, Copy, PartialEq, Eq)]
182pub enum PlayerEventKind {
183 DealtDamage,
184 DealtFinalBlow,
185 DealtHealing,
186 DealtKnockback,
187 Died,
188 EarnedElimination,
189 Joined,
190 Left,
191 ReceivedHealing,
192 ReceivedKnockback,
193 TookDamage,
194}
195
196#[derive(Debug, Clone)]
199pub enum Action {
200 SetGlobalVariable {
201 variable: String,
202 value: Value,
203 },
204 ModifyGlobalVariable {
205 variable: String,
206 op: ModifyOp,
207 value: Value,
208 },
209 SetPlayerVariable {
210 player: Value,
211 variable: String,
212 value: Value,
213 },
214 ModifyPlayerVariable {
215 player: Value,
216 variable: String,
217 op: ModifyOp,
218 value: Value,
219 },
220 AssignMember {
221 target: Value,
222 op: Option<ModifyOp>,
223 value: Value,
224 },
225 CallSubroutine {
226 subroutine: String,
227 },
228 If {
229 condition: Value,
230 },
231 ElseIf {
232 condition: Value,
233 },
234 Else,
235 While {
236 condition: Value,
237 },
238 ForGlobalVariable {
239 variable: String,
240 start: Value,
241 stop: Value,
242 step: Value,
243 },
244 ForPlayerVariable {
245 player: Value,
246 variable: String,
247 start: Value,
248 stop: Value,
249 step: Value,
250 },
251 End,
252 Disabled {
253 action: Box<Action>,
254 },
255 Call {
256 name: String,
257 args: Vec<Value>,
258 },
259}
260
261impl Action {
262 pub fn disabled(action: Action) -> Self {
263 Self::Disabled {
264 action: Box::new(action),
265 }
266 }
267
268 pub fn call(name: impl Into<String>, args: impl IntoIterator<Item = Value>) -> Self {
269 Self::Call {
270 name: name.into(),
271 args: args.into_iter().collect(),
272 }
273 }
274}
275
276#[derive(Debug, Clone, Copy, PartialEq, Eq)]
278pub enum ModifyOp {
279 Add,
280 Subtract,
281 Multiply,
282 Divide,
283 Modulo,
284 Min,
285 Max,
286 RaiseToPower,
287 AppendToArray,
288 RemoveFromArray,
289 RemoveFromArrayByIndex,
290}
291
292#[derive(Debug, Clone)]
294pub enum Value {
295 Number(f64),
296 String(String),
297 LocalizedString(String),
298 Bool(bool),
299 Null,
300 Array(Vec<Value>),
301 Vector {
302 x: Box<Value>,
303 y: Box<Value>,
304 z: Box<Value>,
305 },
306 Enum {
307 value_type: String,
308 value: String,
309 },
310 GlobalVariable(String),
311 PlayerVariable {
312 player: Box<Value>,
313 variable: String,
314 },
315 Subroutine(String),
316 EventPlayer,
317 Call {
318 name: String,
319 args: Vec<Value>,
320 },
321}
322
323impl Value {
324 pub fn number(value: f64) -> Self {
325 Self::Number(value)
326 }
327
328 pub fn string(value: impl Into<String>) -> Self {
329 Self::String(value.into())
330 }
331
332 pub fn global_variable(name: impl Into<String>) -> Self {
333 Self::GlobalVariable(name.into())
334 }
335
336 pub fn player_variable(player: Value, name: impl Into<String>) -> Self {
337 Self::PlayerVariable {
338 player: Box::new(player),
339 variable: name.into(),
340 }
341 }
342
343 pub fn call(name: impl Into<String>, args: impl IntoIterator<Item = Value>) -> Self {
344 Self::Call {
345 name: name.into(),
346 args: args.into_iter().collect(),
347 }
348 }
349}