use crate::settings::Settings;
#[derive(Debug, Clone, Default)]
pub struct Program {
pub settings: Option<Settings>,
pub global_variables: Vec<Variable>,
pub player_variables: Vec<Variable>,
pub subroutines: Vec<Subroutine>,
pub rules: Vec<Rule>,
}
impl Program {
pub fn new() -> Self {
Self::default()
}
pub fn global_variable(&mut self, variable: Variable) -> &mut Self {
self.global_variables.push(variable);
self
}
pub fn player_variable(&mut self, variable: Variable) -> &mut Self {
self.player_variables.push(variable);
self
}
pub fn subroutine(&mut self, subroutine: Subroutine) -> &mut Self {
self.subroutines.push(subroutine);
self
}
pub fn rule(&mut self, rule: Rule) -> &mut Self {
self.rules.push(rule);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Variable {
pub name: String,
pub index: Option<u32>,
}
impl Variable {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
index: None,
}
}
pub fn with_index(name: impl Into<String>, index: u32) -> Self {
Self {
name: name.into(),
index: Some(index),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Subroutine {
pub name: String,
pub index: Option<u32>,
}
impl Subroutine {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
index: None,
}
}
pub fn with_index(name: impl Into<String>, index: u32) -> Self {
Self {
name: name.into(),
index: Some(index),
}
}
}
#[derive(Debug, Clone)]
pub struct Rule {
pub name: String,
pub disabled: bool,
pub event: Event,
pub conditions: Vec<Condition>,
pub actions: Vec<Action>,
}
impl Rule {
pub fn new(name: impl Into<String>, event: Event) -> Self {
Self {
name: name.into(),
disabled: false,
event,
conditions: Vec::new(),
actions: Vec::new(),
}
}
pub fn condition(mut self, condition: impl Into<Condition>) -> Self {
self.conditions.push(condition.into());
self
}
pub fn action(mut self, action: Action) -> Self {
self.actions.push(action);
self
}
}
#[derive(Debug, Clone)]
pub struct Condition {
pub value: Value,
pub disabled: bool,
}
impl Condition {
pub fn new(value: Value) -> Self {
Self {
value,
disabled: false,
}
}
pub fn disabled(value: Value) -> Self {
Self {
value,
disabled: true,
}
}
}
impl From<Value> for Condition {
fn from(value: Value) -> Self {
Self::new(value)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Event {
Global,
EachPlayer,
EachPlayerWithFilters {
team: EventTeam,
target: EventTarget,
},
Player {
kind: PlayerEventKind,
team: EventTeam,
target: EventTarget,
},
Subroutine(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EventTeam {
All,
Team1,
Team2,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventTarget {
All,
Slot(u8),
Hero(String),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PlayerEventKind {
DealtDamage,
DealtFinalBlow,
DealtHealing,
DealtKnockback,
Died,
EarnedElimination,
Joined,
Left,
ReceivedHealing,
ReceivedKnockback,
TookDamage,
}
#[derive(Debug, Clone)]
pub enum Action {
SetGlobalVariable {
variable: String,
value: Value,
},
ModifyGlobalVariable {
variable: String,
op: ModifyOp,
value: Value,
},
SetPlayerVariable {
player: Value,
variable: String,
value: Value,
},
ModifyPlayerVariable {
player: Value,
variable: String,
op: ModifyOp,
value: Value,
},
AssignMember {
target: Value,
op: Option<ModifyOp>,
value: Value,
},
CallSubroutine {
subroutine: String,
},
If {
condition: Value,
},
ElseIf {
condition: Value,
},
Else,
While {
condition: Value,
},
ForGlobalVariable {
variable: String,
start: Value,
stop: Value,
step: Value,
},
ForPlayerVariable {
player: Value,
variable: String,
start: Value,
stop: Value,
step: Value,
},
End,
Disabled {
action: Box<Action>,
},
Call {
name: String,
args: Vec<Value>,
},
}
impl Action {
pub fn disabled(action: Action) -> Self {
Self::Disabled {
action: Box::new(action),
}
}
pub fn call(name: impl Into<String>, args: impl IntoIterator<Item = Value>) -> Self {
Self::Call {
name: name.into(),
args: args.into_iter().collect(),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModifyOp {
Add,
Subtract,
Multiply,
Divide,
Modulo,
Min,
Max,
RaiseToPower,
AppendToArray,
RemoveFromArray,
RemoveFromArrayByIndex,
}
#[derive(Debug, Clone)]
pub enum Value {
Number(f64),
String(String),
LocalizedString(String),
Bool(bool),
Null,
Array(Vec<Value>),
Vector {
x: Box<Value>,
y: Box<Value>,
z: Box<Value>,
},
Enum {
value_type: String,
value: String,
},
GlobalVariable(String),
PlayerVariable {
player: Box<Value>,
variable: String,
},
Subroutine(String),
EventPlayer,
Call {
name: String,
args: Vec<Value>,
},
}
impl Value {
pub fn number(value: f64) -> Self {
Self::Number(value)
}
pub fn string(value: impl Into<String>) -> Self {
Self::String(value.into())
}
pub fn global_variable(name: impl Into<String>) -> Self {
Self::GlobalVariable(name.into())
}
pub fn player_variable(player: Value, name: impl Into<String>) -> Self {
Self::PlayerVariable {
player: Box::new(player),
variable: name.into(),
}
}
pub fn call(name: impl Into<String>, args: impl IntoIterator<Item = Value>) -> Self {
Self::Call {
name: name.into(),
args: args.into_iter().collect(),
}
}
}