Skip to main content

steel_core/command/builtins/execute/
mod.rs

1//! Vanilla command execution context composition.
2
3mod condition;
4mod source;
5mod store;
6
7use steel_utils::{Identifier, translations};
8use text_components::TextComponent;
9
10use super::super::{
11    brigadier::{CommandNodeBuilder, CommandSyntaxError, NodeId},
12    execution::{CommandSource, SteelCommandContext, SteelCommandRuntime, literal},
13    registration::CommandRegistration,
14};
15use crate::command::storage::CommandStorage;
16use crate::scoreboard::{Scoreboard, ScoreboardObjective};
17
18pub(super) fn registration() -> CommandRegistration<CommandSource> {
19    CommandRegistration::new(Identifier::vanilla_static("execute"), command)
20}
21
22fn command(dispatcher_root: NodeId) -> CommandNodeBuilder<CommandSource, SteelCommandRuntime> {
23    literal("execute")
24        .then(literal("run").redirects(dispatcher_root))
25        .then(condition::conditionals("if", true))
26        .then(condition::conditionals("unless", false))
27        .then(source::as_operation())
28        .then(source::at_operation())
29        .then(
30            literal("store")
31                .then(store::target("result", true))
32                .then(store::target("success", false)),
33        )
34        .then(source::positioned_operation())
35        .then(source::rotated_operation())
36        .then(source::facing_operation())
37        .then(source::align_operation())
38        .then(source::anchored_operation())
39        .then(source::in_operation())
40        .then(source::summon_operation())
41        .then(source::on_relations())
42}
43
44fn source_scoreboard(
45    context: &SteelCommandContext<CommandSource>,
46) -> Result<&Scoreboard, CommandSyntaxError> {
47    let source = context.source();
48    source
49        .server()
50        .scoreboards
51        .get(source.world().domain())
52        .ok_or_else(|| {
53            CommandSyntaxError::dynamic(format!(
54                "Domain '{}' has no command scoreboard",
55                source.world().domain()
56            ))
57        })
58}
59
60fn source_command_storage(
61    context: &SteelCommandContext<CommandSource>,
62) -> Result<&CommandStorage, CommandSyntaxError> {
63    let source = context.source();
64    source
65        .server()
66        .command_storage
67        .get(source.world().domain())
68        .ok_or_else(|| {
69            CommandSyntaxError::dynamic(format!(
70                "Domain '{}' has no command storage",
71                source.world().domain()
72            ))
73        })
74}
75
76fn objective(
77    context: &SteelCommandContext<CommandSource>,
78    scoreboard: &Scoreboard,
79    name: &str,
80) -> Result<ScoreboardObjective, CommandSyntaxError> {
81    let objective_name = context.objective_name(name).ok_or_else(|| {
82        CommandSyntaxError::dynamic(format!(
83            "Parsed value for {name} is missing from the command context"
84        ))
85    })?;
86    scoreboard.objective(objective_name).ok_or_else(|| {
87        let message = translations::ARGUMENTS_OBJECTIVE_NOT_FOUND
88            .message([TextComponent::from(objective_name.to_owned())])
89            .component();
90        CommandSyntaxError::dynamic(message)
91    })
92}