mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-09 10:39:46 -10:00
Merge pull request #3589 from d3grando/fix-3427
Commands: coordinate suggestions skip entities and offer the hit point
This commit is contained in:
4 files changed
+58
-2
No files matched your search
@@ -54,6 +54,9 @@ pub struct Registries {
|
||||
pub function_tags: Vec<String>,
|
||||
/// The block the source is looking at (relevant coordinates).
|
||||
pub target_block: Option<[i32; 3]>,
|
||||
/// `ClientSuggestionProvider.getAbsoluteCoordinates`: the exact point of
|
||||
/// that block hit, each coordinate as `%.2f` (`Locale.ROOT`).
|
||||
pub target_point: Option<[String; 3]>,
|
||||
/// Every registry's element and tag ids (`minecraft:item` -> ...), as
|
||||
/// the server's registry access and reloadable registries hold them.
|
||||
pub by_registry: BTreeMap<String, RegistryIds>,
|
||||
|
||||
@@ -428,8 +428,18 @@ impl Game<'_> {
|
||||
.collect();
|
||||
}
|
||||
/// The block the player is looking at, for coordinate suggestions.
|
||||
/// `ClientSuggestionProvider.getRelevantCoordinates` and
|
||||
/// `getAbsoluteCoordinates` read `Minecraft.hitResult` only when it is a
|
||||
/// block: an entity in front of the block leaves the `~` defaults.
|
||||
fn refresh_dynamic_registries(&mut self) {
|
||||
self.ui.registries.target_block = self.pick().map(|h| h.pos);
|
||||
let hit = if self.pick_entity_hit().is_some() {
|
||||
None
|
||||
} else {
|
||||
self.pick()
|
||||
};
|
||||
self.ui.registries.target_block = hit.as_ref().map(|h| h.pos);
|
||||
self.ui.registries.target_point =
|
||||
hit.map(|h| h.point.map(horizon_client::java_text::format_fixed2));
|
||||
// ClientPacketListener.getOnlinePlayerNames on a server.
|
||||
if let Some(names) = self.remote_online_names() {
|
||||
self.ui.registries.players = names;
|
||||
|
||||
@@ -798,7 +798,9 @@ fn java_split(s: &str) -> Vec<&str> {
|
||||
parts
|
||||
}
|
||||
/// SharedSuggestionProvider.suggestCoordinates / suggest2DCoordinates: the
|
||||
/// candidates `ty` parses completely.
|
||||
/// candidates `ty` parses completely. `relevant` arguments (block and column
|
||||
/// positions) offer the targeted block (`getRelevantCoordinates`), the others
|
||||
/// (`Vec3`, `Vec2`) the exact hit point (`getAbsoluteCoordinates`).
|
||||
fn suggest_coordinates(
|
||||
builder: &mut SuggestionsBuilder,
|
||||
reg: &Registries,
|
||||
@@ -811,6 +813,8 @@ fn suggest_coordinates(
|
||||
["^".into(), "^".into(), "^".into()]
|
||||
} else if let (true, Some(t)) = (relevant, reg.target_block) {
|
||||
[t[0].to_string(), t[1].to_string(), t[2].to_string()]
|
||||
} else if let (false, Some(p)) = (relevant, ®.target_point) {
|
||||
p.clone()
|
||||
} else {
|
||||
["~".into(), "~".into(), "~".into()]
|
||||
};
|
||||
|
||||
@@ -256,6 +256,45 @@ fn suggestions_like_vanilla() {
|
||||
assert_eq!(suggestions("time set 5"), ["d", "s", "t"]);
|
||||
assert!(suggestions("time set ").contains(&"minecraft:day".to_owned()));
|
||||
}
|
||||
/// ClientSuggestionProvider: block and column positions offer the targeted
|
||||
/// block (`getRelevantCoordinates`), `Vec3` and `Vec2` the exact hit point
|
||||
/// with two decimals (`getAbsoluteCoordinates`); with no block hit, `~`.
|
||||
#[test]
|
||||
fn coordinates_suggest_the_crosshair_block_or_hit_point() {
|
||||
let d = vanilla::dispatcher();
|
||||
let suggest = |reg: &Registries, input: &str| -> Vec<String> {
|
||||
let parse = d.parse(input, reg);
|
||||
d.suggestions(&parse, input.len(), reg)
|
||||
.1
|
||||
.into_iter()
|
||||
.map(|s| s.text)
|
||||
.collect()
|
||||
};
|
||||
let mut hit = reg();
|
||||
hit.target_block = Some([-29, 73, 8]);
|
||||
hit.target_point = Some(["-28.77".into(), "73.28".into(), "8.00".into()]);
|
||||
assert_eq!(suggest(&hit, "setblock "), ["-29", "-29 73", "-29 73 8"]);
|
||||
assert_eq!(
|
||||
suggest(&hit, "summon minecraft:pig "),
|
||||
["-28.77", "-28.77 73.28", "-28.77 73.28 8.00"]
|
||||
);
|
||||
assert_eq!(
|
||||
suggest(&hit, "summon minecraft:pig -28.77 "),
|
||||
["-28.77 73.28", "-28.77 73.28 8.00"]
|
||||
);
|
||||
// Vec2Argument: x and z.
|
||||
assert_eq!(
|
||||
suggest(&hit, "worldborder center "),
|
||||
["-28.77", "-28.77 8.00"]
|
||||
);
|
||||
// An entity in front of the block (or no hit): the defaults.
|
||||
let none = reg();
|
||||
assert_eq!(suggest(&none, "setblock "), ["~", "~ ~", "~ ~ ~"]);
|
||||
assert_eq!(
|
||||
suggest(&none, "summon minecraft:pig "),
|
||||
["~", "~ ~", "~ ~ ~"]
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn smart_usage_matches_brigadier() {
|
||||
let d = vanilla::dispatcher();
|
||||
|
||||
Reference in new issue
Block a user