minecraft_command_types/command/
execute.rs

1use crate::block::BlockState;
2use crate::column_position::ColumnPosition;
3use crate::command::data::DataTarget;
4use crate::command::enums::axis::Axis;
5use crate::command::enums::bossbar_store_type::BossbarStoreType;
6use crate::command::enums::entity_anchor::EntityAnchor;
7use crate::command::enums::heightmap::Heightmap;
8use crate::command::enums::if_blocks_mode::IfBlocksMode;
9use crate::command::enums::numeric_snbt_type::NumericSNBTType;
10use crate::command::enums::relation::Relation;
11use crate::command::enums::store_type::StoreType;
12use crate::command::item_source::ItemSource;
13use crate::command::{Command, PlayerScore};
14use crate::coordinate::Coordinates;
15use crate::entity_selector::EntitySelector;
16use crate::item::ItemPredicate;
17use crate::nbt_path::NbtPath;
18use crate::range::{FloatRange, IntegerRange};
19use crate::resource_location::ResourceLocation;
20use crate::rotation::Rotation;
21use minecraft_command_types_derive::HasMacro;
22use ordered_float::NotNan;
23use std::collections::BTreeSet;
24use std::fmt::{Display, Formatter};
25use strum::Display;
26
27#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
28pub enum Facing {
29    Position(Coordinates),
30    Entity(EntitySelector, EntityAnchor),
31}
32
33impl Display for Facing {
34    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35        match self {
36            Facing::Position(coords) => coords.fmt(f),
37            Facing::Entity(selector, anchor) => write!(f, "entity {} {}", selector, anchor),
38        }
39    }
40}
41
42#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
43pub enum Positioned {
44    Position(Coordinates),
45    As(EntitySelector),
46    Over(Heightmap),
47}
48
49impl Display for Positioned {
50    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
51        match self {
52            Positioned::Position(coords) => coords.fmt(f),
53            Positioned::As(selector) => write!(f, "as {}", selector),
54            Positioned::Over(heightmap) => write!(f, "over {}", heightmap),
55        }
56    }
57}
58
59#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
60pub enum Rotated {
61    Rotation(Rotation),
62    As(EntitySelector),
63}
64
65impl Display for Rotated {
66    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
67        match self {
68            Rotated::Rotation(rotation) => rotation.fmt(f),
69            Rotated::As(selector) => write!(f, "as {}", selector),
70        }
71    }
72}
73
74#[derive(Display, Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
75pub enum ScoreComparisonOperator {
76    #[strum(serialize = "<")]
77    LessThan,
78    #[strum(serialize = "<=")]
79    LessThanOrEqualTo,
80    #[strum(serialize = "=")]
81    EqualTo,
82    #[strum(serialize = ">")]
83    GreaterThan,
84    #[strum(serialize = ">=")]
85    GreaterThanOrEqualTo,
86}
87
88#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
89pub enum ScoreComparison {
90    Range(IntegerRange),
91    Score(ScoreComparisonOperator, PlayerScore),
92}
93
94impl Display for ScoreComparison {
95    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
96        match self {
97            ScoreComparison::Range(range) => write!(f, "matches {}", range),
98            ScoreComparison::Score(operator, right) => {
99                write!(f, "{} {}", operator, right)
100            }
101        }
102    }
103}
104
105#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
106pub enum ExecuteIfSubcommand {
107    Biome(
108        Coordinates,
109        ResourceLocation,
110        Option<Box<ExecuteSubcommand>>,
111    ),
112    Block(Coordinates, BlockState, Option<Box<ExecuteSubcommand>>),
113    Blocks(
114        Coordinates,
115        Coordinates,
116        Coordinates,
117        IfBlocksMode,
118        Option<Box<ExecuteSubcommand>>,
119    ),
120    Data(DataTarget, NbtPath, Option<Box<ExecuteSubcommand>>),
121    Dimension(ResourceLocation, Option<Box<ExecuteSubcommand>>),
122    Entity(EntitySelector, Option<Box<ExecuteSubcommand>>),
123    Function(ResourceLocation, Box<ExecuteSubcommand>),
124    Items(
125        ItemSource,
126        String,
127        ItemPredicate,
128        Option<Box<ExecuteSubcommand>>,
129    ),
130    Loaded(ColumnPosition, Option<Box<ExecuteSubcommand>>),
131    Predicate(ResourceLocation, Option<Box<ExecuteSubcommand>>),
132    Score(PlayerScore, ScoreComparison, Option<Box<ExecuteSubcommand>>),
133    Stopwatch(ResourceLocation, FloatRange),
134}
135
136impl Display for ExecuteIfSubcommand {
137    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
138        match self {
139            ExecuteIfSubcommand::Biome(coords, id, next) => {
140                write!(f, "biome {} {}", coords, id)?;
141
142                if let Some(next_sub) = next {
143                    write!(f, " {}", next_sub)?;
144                }
145
146                Ok(())
147            }
148            ExecuteIfSubcommand::Block(coords, predicate, next) => {
149                write!(f, "block {} {}", coords, predicate)?;
150
151                if let Some(next_sub) = next {
152                    write!(f, " {}", next_sub)?;
153                }
154
155                Ok(())
156            }
157            ExecuteIfSubcommand::Blocks(start, end, dest, mode, next) => {
158                write!(f, "blocks {} {} {} {}", start, end, dest, mode)?;
159
160                if let Some(next_sub) = next {
161                    write!(f, " {}", next_sub)?;
162                }
163
164                Ok(())
165            }
166            ExecuteIfSubcommand::Data(target, path, next) => {
167                write!(f, "data {} {}", target, path)?;
168
169                if let Some(next_sub) = next {
170                    write!(f, " {}", next_sub)?;
171                }
172
173                Ok(())
174            }
175            ExecuteIfSubcommand::Dimension(id, next) => {
176                write!(f, "dimension {}", id)?;
177
178                if let Some(next_sub) = next {
179                    write!(f, " {}", next_sub)?;
180                }
181
182                Ok(())
183            }
184            ExecuteIfSubcommand::Entity(selector, next) => {
185                write!(f, "entity {}", selector)?;
186
187                if let Some(next_sub) = next {
188                    write!(f, " {}", next_sub)?;
189                }
190
191                Ok(())
192            }
193            ExecuteIfSubcommand::Function(id, next) => {
194                write!(f, "function {} {}", id, next)
195            }
196            ExecuteIfSubcommand::Items(source, slot, predicate, next) => {
197                write!(f, "items {} {} {}", source, slot, predicate)?;
198
199                if let Some(next_sub) = next {
200                    write!(f, " {}", next_sub)?;
201                }
202
203                Ok(())
204            }
205            ExecuteIfSubcommand::Loaded(coords, next) => {
206                write!(f, "loaded {}", coords)?;
207                if let Some(next_sub) = next {
208                    write!(f, " {}", next_sub)?;
209                }
210
211                Ok(())
212            }
213            ExecuteIfSubcommand::Predicate(id, next) => {
214                write!(f, "predicate {}", id)?;
215                if let Some(next_sub) = next {
216                    write!(f, " {}", next_sub)?;
217                }
218
219                Ok(())
220            }
221            ExecuteIfSubcommand::Score(score, comparison, next) => {
222                write!(f, "score {} {}", score, comparison)?;
223                if let Some(next_sub) = next {
224                    write!(f, " {}", next_sub)?;
225                }
226
227                Ok(())
228            }
229            ExecuteIfSubcommand::Stopwatch(location, range) => {
230                write!(f, "stopwatch {} {}", location, range)
231            }
232        }
233    }
234}
235
236#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
237pub enum ExecuteStoreSubcommand {
238    Block(
239        Coordinates,
240        NbtPath,
241        NumericSNBTType,
242        NotNan<f32>,
243        Box<ExecuteSubcommand>,
244    ),
245    Bossbar(ResourceLocation, BossbarStoreType, Box<ExecuteSubcommand>),
246    Entity(
247        EntitySelector,
248        NbtPath,
249        NumericSNBTType,
250        NotNan<f32>,
251        Box<ExecuteSubcommand>,
252    ),
253    Score(PlayerScore, Box<ExecuteSubcommand>),
254    Storage(
255        ResourceLocation,
256        NbtPath,
257        NumericSNBTType,
258        NotNan<f32>,
259        Box<ExecuteSubcommand>,
260    ),
261}
262
263impl Display for ExecuteStoreSubcommand {
264    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
265        match self {
266            ExecuteStoreSubcommand::Block(coords, path, num_type, scale, next) => {
267                write!(
268                    f,
269                    "block {} {} {} {} {}",
270                    coords, path, num_type, scale, next
271                )?;
272
273                Ok(())
274            }
275            ExecuteStoreSubcommand::Bossbar(id, store_type, next) => {
276                write!(f, "bossbar {} {} {}", id, store_type, next)?;
277
278                Ok(())
279            }
280            ExecuteStoreSubcommand::Entity(selector, path, num_type, scale, next) => {
281                write!(
282                    f,
283                    "entity {} {} {} {} {}",
284                    selector, path, num_type, scale, next
285                )?;
286
287                Ok(())
288            }
289            ExecuteStoreSubcommand::Score(score, next) => {
290                write!(f, "score {} {}", score, next)?;
291
292                Ok(())
293            }
294            ExecuteStoreSubcommand::Storage(id, path, num_type, scale, next) => {
295                write!(f, "storage {} {} {} {} {}", id, path, num_type, scale, next)?;
296
297                Ok(())
298            }
299        }
300    }
301}
302
303#[derive(Debug, Clone, Eq, PartialEq, Hash, HasMacro)]
304pub enum ExecuteSubcommand {
305    Align(BTreeSet<Axis>, Box<ExecuteSubcommand>),
306    Anchored(EntityAnchor, Box<ExecuteSubcommand>),
307    As(EntitySelector, Box<ExecuteSubcommand>),
308    At(EntitySelector, Box<ExecuteSubcommand>),
309    Facing(Facing, Box<ExecuteSubcommand>),
310    In(ResourceLocation, Box<ExecuteSubcommand>),
311    On(Relation, Box<ExecuteSubcommand>),
312    Positioned(Positioned, Box<ExecuteSubcommand>),
313    Rotated(Rotated, Box<ExecuteSubcommand>),
314    Summon(ResourceLocation, Box<ExecuteSubcommand>),
315    If(bool, ExecuteIfSubcommand),
316    Store(StoreType, ExecuteStoreSubcommand),
317    Run(Box<Command>),
318}
319
320impl Display for ExecuteSubcommand {
321    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
322        match self {
323            ExecuteSubcommand::Align(axes, next) => {
324                let axes_str: String = axes.iter().map(|a| a.to_string()).collect();
325                write!(f, "align {} {}", axes_str, next)?;
326
327                Ok(())
328            }
329            ExecuteSubcommand::Anchored(anchor, next) => {
330                write!(f, "anchored {} {}", anchor, next)?;
331
332                Ok(())
333            }
334            ExecuteSubcommand::As(selector, next) => {
335                write!(f, "as {} {}", selector, next)?;
336
337                Ok(())
338            }
339            ExecuteSubcommand::At(selector, next) => {
340                write!(f, "at {} {}", selector, next)?;
341
342                Ok(())
343            }
344            ExecuteSubcommand::Facing(facing, next) => {
345                write!(f, "facing {} {}", facing, next)?;
346
347                Ok(())
348            }
349            ExecuteSubcommand::In(dimension, next) => {
350                write!(f, "in {} {}", dimension, next)?;
351
352                Ok(())
353            }
354            ExecuteSubcommand::On(relation, next) => {
355                write!(f, "on {} {}", relation, next)?;
356
357                Ok(())
358            }
359            ExecuteSubcommand::Positioned(positioned, next) => {
360                write!(f, "positioned {} {}", positioned, next)?;
361
362                Ok(())
363            }
364            ExecuteSubcommand::Rotated(rotated, next) => {
365                write!(f, "rotated {} {}", rotated, next)?;
366
367                Ok(())
368            }
369            ExecuteSubcommand::Summon(entity_id, next) => {
370                write!(f, "summon {} {}", entity_id, next)?;
371
372                Ok(())
373            }
374            ExecuteSubcommand::If(is_inverted, subcommand) => {
375                let keyword = if *is_inverted { "unless" } else { "if" };
376
377                write!(f, "{} {}", keyword, subcommand)
378            }
379            ExecuteSubcommand::Store(store_type, subcommand) => {
380                write!(f, "store {} {}", store_type, subcommand)
381            }
382            ExecuteSubcommand::Run(command) => {
383                write!(f, "run {}", command)
384            }
385        }
386    }
387}