use std::{fmt, fmt::Display, rc::Rc};
use debris_llir::{
llir_nodes::WriteTarget,
minecraft_utils::{ScoreboardComparison, ScoreboardOperation},
};
use fmt::Formatter;
#[derive(Debug, Clone)]
pub enum MinecraftCommand {
ScoreboardSet {
player: ScoreboardPlayer,
value: i32,
},
ScoreboardSetEqual {
player1: ScoreboardPlayer,
player2: ScoreboardPlayer,
},
ScoreboardSetFromResult {
player: ScoreboardPlayer,
command: Box<MinecraftCommand>,
},
ScoreboardOperation {
player1: ScoreboardPlayer,
player2: ScoreboardPlayer,
operation: ScoreboardOperation,
},
ScoreboardOperationAdd {
player: ScoreboardPlayer,
value: i32,
},
Execute {
parts: Vec<ExecuteComponent>,
and_then: Option<Box<MinecraftCommand>>,
},
Function {
function: Rc<FunctionIdent>,
},
ScoreboardAdd {
name: Rc<str>,
criterion: ObjectiveCriterion,
json_name: Option<String>,
},
ScoreboardRemove {
name: Rc<str>,
},
RawCommand {
command: Rc<str>,
},
JsonMessage {
target: WriteTarget,
message: String,
},
}
#[derive(Debug, Clone)]
pub enum ExecuteComponent {
IfScoreRelation {
player1: ScoreboardPlayer,
player2: ScoreboardPlayer,
comparison: ScoreboardComparison,
},
IfScoreRange {
player: ScoreboardPlayer,
range: MinecraftRange,
},
}
impl ExecuteComponent {
pub fn is_condition(&self) -> bool {
match self {
ExecuteComponent::IfScoreRange { .. } | ExecuteComponent::IfScoreRelation { .. } => {
true
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum MinecraftRange {
Range { from: i32, to: i32 },
Minimum(i32),
Maximum(i32),
Equal(i32),
NotEqual(i32),
}
#[derive(Debug, Clone)]
pub struct ScoreboardPlayer {
pub player: Rc<str>,
pub scoreboard: Rc<str>,
}
impl fmt::Display for ScoreboardPlayer {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let player = self.player.as_ref();
let scoreboard = self.scoreboard.as_ref();
write!(f, "{player} {scoreboard}")
}
}
#[derive(Debug, Clone)]
pub enum ObjectiveCriterion {
Dummy,
}
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct FunctionIdent {
pub namespace: Rc<str>,
pub path: String,
pub is_collection: bool,
}
impl MinecraftRange {
pub fn from_operator(value: i32, operator: ScoreboardComparison) -> Self {
match operator {
ScoreboardComparison::Equal => MinecraftRange::Equal(value),
ScoreboardComparison::NotEqual => MinecraftRange::NotEqual(value),
ScoreboardComparison::Greater => {
MinecraftRange::Minimum(value.checked_add(1).expect("Invalid value"))
}
ScoreboardComparison::GreaterOrEqual => MinecraftRange::Minimum(value),
ScoreboardComparison::Less => {
MinecraftRange::Maximum(value.checked_sub(1).expect("Invalid value"))
}
ScoreboardComparison::LessOrEqual => MinecraftRange::Maximum(value),
}
}
}
impl Display for ObjectiveCriterion {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str(match self {
ObjectiveCriterion::Dummy => "dummy",
})
}
}
impl Display for FunctionIdent {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let prefix = if self.is_collection { "#" } else { "" };
let namespace = self.namespace.as_ref();
let path = self.path.as_str();
write!(f, "{prefix}{namespace}:{path}")
}
}