1use std::fmt::{Debug, Display};
2
3use crate::common::range::FloatRange;
4
5use super::{super::ty::NBTCompoundTypeContents, Gamemode};
6
7#[derive(Clone, PartialEq)]
8pub struct TargetSelector {
9 pub selector: SelectorType,
10 pub params: Vec<SelectorParameter>,
11}
12
13impl TargetSelector {
14 pub fn new(selector: SelectorType) -> Self {
15 Self::with_params(selector, Vec::new())
16 }
17
18 pub fn with_params(selector: SelectorType, params: Vec<SelectorParameter>) -> Self {
19 Self { selector, params }
20 }
21
22 pub fn is_blank_this(&self) -> bool {
23 matches!(self.selector, SelectorType::This) && self.params.is_empty()
24 }
25
26 pub fn is_value_eq(&self, other: &Self) -> bool {
27 self.selector == other.selector && self.params == other.params
28 }
29
30 pub fn is_single_type(&self) -> bool {
32 self.selector.is_single_type()
33 || matches!(self.selector, SelectorType::AllEntities | SelectorType::AllPlayers if self.params.contains(&SelectorParameter::Limit(1)))
34 }
35
36 pub fn is_player_type(&self) -> bool {
38 self.selector.is_player_type()
39 || matches!(self.selector, SelectorType::AllEntities if self.params.contains(&SelectorParameter::Type { ty: "player".into(), invert: false }))
40 }
41
42 pub fn relies_on_position(&self) -> bool {
43 matches!(self.selector, SelectorType::NearestPlayer)
44 | self
45 .params
46 .iter()
47 .any(|x| matches!(x, SelectorParameter::Distance { .. }))
48 }
49
50 pub fn relies_on_executor(&self) -> bool {
51 matches!(self.selector, SelectorType::This)
52 }
53}
54
55impl Debug for TargetSelector {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 write!(f, "{}", self.selector.codegen_str())?;
58 if !self.params.is_empty() {
59 write!(f, "[")?;
60 for (i, param) in self.params.iter().enumerate() {
61 write!(f, "{param:?}")?;
62 if i != self.params.len() - 1 {
63 write!(f, ",")?;
64 }
65 }
66 write!(f, "]")?;
67 }
68 Ok(())
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq)]
73pub enum SelectorType {
74 This,
75 NearestPlayer,
76 RandomPlayer,
77 AllPlayers,
78 AllEntities,
79}
80
81impl SelectorType {
82 pub fn codegen_str(&self) -> &'static str {
83 match self {
84 Self::This => "@s",
85 Self::NearestPlayer => "@p",
86 Self::RandomPlayer => "@r",
87 Self::AllPlayers => "@a",
88 Self::AllEntities => "@e",
89 }
90 }
91
92 pub fn is_single_type(&self) -> bool {
94 matches!(self, Self::This | Self::NearestPlayer | Self::RandomPlayer)
95 }
96
97 pub fn is_player_type(&self) -> bool {
99 matches!(
100 self,
101 Self::NearestPlayer | Self::AllPlayers | Self::RandomPlayer
102 )
103 }
104}
105
106#[derive(Debug, Clone, PartialEq)]
107pub enum SelectorParameter {
108 Distance {
109 range: FloatRange,
110 },
111 Type {
112 ty: String,
113 invert: bool,
114 },
115 Tag {
116 tag: String,
117 invert: bool,
118 },
119 NoTags,
120 Predicate {
121 predicate: String,
122 invert: bool,
123 },
124 Gamemode {
125 gamemode: Gamemode,
126 invert: bool,
127 },
128 Name {
129 name: String,
130 invert: bool,
131 },
132 NBT {
133 nbt: NBTCompoundTypeContents,
134 invert: bool,
135 },
136 Limit(u32),
137 Sort(SelectorSort),
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub enum SelectorSort {
142 Nearest,
143 Furthest,
144 Random,
145 Arbitrary,
146}
147
148impl Display for SelectorSort {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 write!(
151 f,
152 "{}",
153 match self {
154 Self::Nearest => "nearest",
155 Self::Furthest => "furthest",
156 Self::Random => "random",
157 Self::Arbitrary => "arbitrary",
158 }
159 )
160 }
161}
162
163#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct UUID(String);
165
166#[derive(Clone, PartialEq, Eq)]
167pub enum AttributeType {
168 Add,
169 Multiply,
170 MultiplyBase,
171}
172
173impl Debug for AttributeType {
174 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
175 write!(
176 f,
177 "{}",
178 match self {
179 Self::Add => "add",
180 Self::Multiply => "multiply",
181 Self::MultiplyBase => "multiply_base",
182 }
183 )
184 }
185}
186
187#[derive(Clone, PartialEq, Eq)]
188pub enum EffectDuration {
189 Seconds(i32),
190 Infinite,
191}
192
193impl Debug for EffectDuration {
194 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195 write!(
196 f,
197 "{}",
198 match self {
199 Self::Seconds(seconds) => seconds.to_string(),
200 Self::Infinite => "infinite".into(),
201 }
202 )
203 }
204}
205
206impl EffectDuration {
207 pub fn is_default(&self) -> bool {
208 matches!(self, Self::Seconds(amt) if *amt == 30)
209 }
210}