Merge pull request #1903 from rdbtCVS/fix/clear-offhand-slot-order

🤖 Agent: Thanks rdbt! Checked against vanilla's Inventory order (armour FEET to HEAD, then the off hand) when items are cleared. Tested together with the other wave 1 contributor PRs on current main: fmt, clippy -D warnings and the horizon-client tests (1,120 lib tests and the rest) pass; the 114 harnesses the batch affects pass; lan_e2e anvil, grindstone, replant, instant_digging, digging, frames and leads pass with the host in-frame and on its server thread.
This commit is contained in:
Ludovic Marie
2026-10-26 02:14:29 +01:00
committed by GitHub
2 changed files with 23 additions and 3 deletions
+6 -3
View File
@@ -2501,12 +2501,14 @@ impl Game<'_> {
};
let max = Self::int(ctx, "maxCount").unwrap_or(-1);
let counting = max == 0;
// Inventory.clearOrCountMatchingItems: main, armor, crafting grid, carried.
// Inventory slots 0..40: main, armor feet to head, off hand;
// then clearOrCountMatchingItems visits the crafting grid and carried stack.
let mut removed = 0i32;
let mut budget = if max < 0 { i32::MAX } else { max };
let all = |g: &Self| -> Vec<Option<ItemStack>> {
let mut v: Vec<Option<ItemStack>> = g.inventory.clone();
v.extend(g.armor.iter().cloned());
v.extend(g.armor.iter().rev().cloned());
v.push(g.offhand.clone());
v.extend(g.craft_grid.iter().cloned());
v.push(g.carried.clone());
v
@@ -2520,7 +2522,8 @@ impl Game<'_> {
.collect();
let mut slots: Vec<&mut Option<ItemStack>> = Vec::new();
slots.extend(self.inventory.iter_mut());
slots.extend(self.armor.iter_mut());
slots.extend(self.armor.iter_mut().rev());
slots.push(&mut self.offhand);
slots.extend(self.craft_grid.iter_mut());
slots.push(&mut self.carried);
for (slot, matches) in slots.into_iter().zip(matching) {
+17
View File
@@ -182,6 +182,23 @@ def player_state():
cmd('/item modify entity @s weapon.mainhand {type:"minecraft:set_count",count:1}'),
cmd('/clear @s'),
cmd('/clear @s'),
# Inventory.clearOrCountMatchingItems visits the off hand as well as
# the main inventory, and consumes limited clears in inventory-slot order.
cmd('/item replace entity @s weapon.offhand with minecraft:shield'),
cmd('/clear @s minecraft:shield 0'),
cmd('/clear @s minecraft:shield 1'),
cmd('/clear @s minecraft:shield 0'),
cmd('/item replace entity @s weapon.offhand with minecraft:stone 5'),
cmd('/clear @s minecraft:stone 2'),
cmd('/clear @s minecraft:stone 0'),
cmd('/clear @s'),
cmd('/clear @s minecraft:stone 0'),
cmd('/item replace entity @s armor.head with minecraft:iron_helmet'),
cmd('/item replace entity @s armor.feet with minecraft:iron_boots'),
cmd('/clear @s * 1'),
cmd('/clear @s minecraft:iron_boots 0'),
cmd('/clear @s minecraft:iron_helmet 0'),
cmd('/clear @s'),
cmd('/attribute @s minecraft:max_health get'),
cmd('/attribute @s minecraft:max_health base get'),
cmd('/attribute @s minecraft:max_health base set 30'),