Article Categories
- Baldur's Gate 3
- Diablo
- Elder Scrolls
- General
- Hogwarts Legacy
- League of Legends
- Minecraft
- Pokemon Go
- Sims 4
- StarCraft
- Steam Platform
- Xbox Game Console
More Articles
Whats wrong with this custom blocks loot table? Its supposed to choose drop by testing for silk touch, but non-enchanted pick drops both options
I have a custom block that is supposed to be only obtainable using a Silk Touch pickaxe. If mined with a pickaxe without Silk Touch, it should drop end stone instead, and if mined with the wrong tool, it should drop nothing.
Instead, it drops the correct loot only when a Silk Touch pickaxe is used. When a regular pickaxe is used, it drops both itself and an end stone block; when mined with the wrong tool, the same thing happens.
From the official documentation, "Applying a condition to a pool allows you execute the entire pool based on the conditions defined." In my custom block's loot table, each pool has its own (mutually exclusive) condition, so I'm not sure what's causing multiple drops (which would imply matching both or possibly all 3 conditions, which should be impossible).
Here is the loot table .json file:.
{.
"pools": [.
// Give rhizome block if mined using a Silk Touch pickaxe.
{.
"condition": "query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe') && query.has_silk_touch",.
"rolls": 1,.
"entries": [.
{.
"type": "item",.
"name": "end:rhizome".
}.
].
},.
// Give end stone if mined with a pickaxe without Silk Touch.
{.
"condition": "query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe') && !query.has_silk_touch",.
"rolls": 1,.
"entries": [.
{.
"type": "item",.
"name": "minecraft:end_stone".
}.
].
},.
// Drop nothing if mined with anything other than a pickaxe.
{.
"condition": "!query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe')",.
"rolls": 1,.
"entries": [.
{.
"type": "empty".
}.
].
}.
].
}.
Rearranging the three pools does not change the result. So, it doesn't matter whether the "has silk touch" condition comes first or third: it's still the only one that works as intended.
I also tested swapping out the condition strings with condition arrays of the following form:.
"conditions": [.
{.
"condition": "same molang queries here".
}.
].
but the same problem was still happening.
Question from user Quack E. Duck at gaming.stackexchange.com.
Answer:
Here is a different way of accomplishing the same thing, without using conditions in the loot table:.
Loot table for the block: (set to a single, empty entry).
{.
"pools": [.
// A placeholder; the actual drop will be determined in main.js.
{.
"rolls": 1,.
"entries": [.
{.
"type": "empty".
}.
].
}.
].
}.
Script file (main.js; uses @minecraft/server version 1.10.0-beta): -- This is where we'll test for use of silk touch pickaxe vs. unenchanted pickaxe vs. no pickaxe.
import { world, system, ItemStack, ItemComponentTypes } from "@minecraft/server".
// For use inside the .playerBreakBlock event listener, for getting the broken block's former coordinates.
// Properties will be player names (type String); values will be Block objects.
var lastBlockHitByPlayer = {};.
world.afterEvents.entityHitBlock.subscribe(event => {.
// Keep a record of the last block the player hit.
if (event.damagingEntity.typeId === "minecraft:player") {.
lastBlockHitByPlayer[event.damagingEntity.name] = event.hitBlock;.
}.
});.
world.afterEvents.playerBreakBlock.subscribe(event => {.
if (event.brokenBlockPermutation.type.id === "end:rhizome") {.
const stack = event.itemStackAfterBreak;.
const player = event.player;.
// Block will drop rhizome if mined with a silk touch pickaxe (this happens automatically).
if (stack !== undefined && stack.typeId.includes("_pickaxe") && !stack.getComponent(ItemComponentTypes.Enchantable).hasEnchantment("silk_touch")) {.
// Drop regular end stone if the block is mined with a non-silk-touch pickaxe.
(async () => {.
// For .playerBreakBlock, there's no direct way to access the block's coordinates (because it isn't there anymore?). Instead, the coordinates.
// of the block that has just been broken should be the same as those of the most recent block which the player hit (since hitting the block - left click - is a prerequisite to breaking it).
await player.dimension.spawnItem(new ItemStack("minecraft:end_stone"), {x: lastBlockHitByPlayer[player.name].x, y: lastBlockHitByPlayer[player.name].y, z: lastBlockHitByPlayer[player.name].z});.
})();.
} // Otherwise, drop nothing.
}.
});.
With this method, the custom block drops the correct loot for each case.
Answer from user Quack E. Duck at gaming.stackexchange.com.
I have a custom block that is supposed to be only obtainable using a Silk Touch pickaxe. If mined with a pickaxe without Silk Touch, it should drop end stone instead, and if mined with the wrong tool, it should drop nothing.
Instead, it drops the correct loot only when a Silk Touch pickaxe is used. When a regular pickaxe is used, it drops both itself and an end stone block; when mined with the wrong tool, the same thing happens.
From the official documentation, "Applying a condition to a pool allows you execute the entire pool based on the conditions defined." In my custom block's loot table, each pool has its own (mutually exclusive) condition, so I'm not sure what's causing multiple drops (which would imply matching both or possibly all 3 conditions, which should be impossible).
Here is the loot table .json file:.
{.
"pools": [.
// Give rhizome block if mined using a Silk Touch pickaxe.
{.
"condition": "query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe') && query.has_silk_touch",.
"rolls": 1,.
"entries": [.
{.
"type": "item",.
"name": "end:rhizome".
}.
].
},.
// Give end stone if mined with a pickaxe without Silk Touch.
{.
"condition": "query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe') && !query.has_silk_touch",.
"rolls": 1,.
"entries": [.
{.
"type": "item",.
"name": "minecraft:end_stone".
}.
].
},.
// Drop nothing if mined with anything other than a pickaxe.
{.
"condition": "!query.equipped_item_any_tag('slot.weapon.mainhand', 'minecraft:is_pickaxe')",.
"rolls": 1,.
"entries": [.
{.
"type": "empty".
}.
].
}.
].
}.
Rearranging the three pools does not change the result. So, it doesn't matter whether the "has silk touch" condition comes first or third: it's still the only one that works as intended.
I also tested swapping out the condition strings with condition arrays of the following form:.
"conditions": [.
{.
"condition": "same molang queries here".
}.
].
but the same problem was still happening.
Question from user Quack E. Duck at gaming.stackexchange.com.
Answer:
Here is a different way of accomplishing the same thing, without using conditions in the loot table:.
Loot table for the block: (set to a single, empty entry).
{.
"pools": [.
// A placeholder; the actual drop will be determined in main.js.
{.
"rolls": 1,.
"entries": [.
{.
"type": "empty".
}.
].
}.
].
}.
Script file (main.js; uses @minecraft/server version 1.10.0-beta): -- This is where we'll test for use of silk touch pickaxe vs. unenchanted pickaxe vs. no pickaxe.
import { world, system, ItemStack, ItemComponentTypes } from "@minecraft/server".
// For use inside the .playerBreakBlock event listener, for getting the broken block's former coordinates.
// Properties will be player names (type String); values will be Block objects.
var lastBlockHitByPlayer = {};.
world.afterEvents.entityHitBlock.subscribe(event => {.
// Keep a record of the last block the player hit.
if (event.damagingEntity.typeId === "minecraft:player") {.
lastBlockHitByPlayer[event.damagingEntity.name] = event.hitBlock;.
}.
});.
world.afterEvents.playerBreakBlock.subscribe(event => {.
if (event.brokenBlockPermutation.type.id === "end:rhizome") {.
const stack = event.itemStackAfterBreak;.
const player = event.player;.
// Block will drop rhizome if mined with a silk touch pickaxe (this happens automatically).
if (stack !== undefined && stack.typeId.includes("_pickaxe") && !stack.getComponent(ItemComponentTypes.Enchantable).hasEnchantment("silk_touch")) {.
// Drop regular end stone if the block is mined with a non-silk-touch pickaxe.
(async () => {.
// For .playerBreakBlock, there's no direct way to access the block's coordinates (because it isn't there anymore?). Instead, the coordinates.
// of the block that has just been broken should be the same as those of the most recent block which the player hit (since hitting the block - left click - is a prerequisite to breaking it).
await player.dimension.spawnItem(new ItemStack("minecraft:end_stone"), {x: lastBlockHitByPlayer[player.name].x, y: lastBlockHitByPlayer[player.name].y, z: lastBlockHitByPlayer[player.name].z});.
})();.
} // Otherwise, drop nothing.
}.
});.
With this method, the custom block drops the correct loot for each case.
Answer from user Quack E. Duck at gaming.stackexchange.com.
Sona-Taric League Of Legends bot lane in Season 9
How can I activate an area of redstone all at once?
Starcraft II - How to play 1v1 on local LAN
Why does the Pokémon count show one more than the actual Pokémon I have?
Missing field guide page? Got the platinum trophy and everything says 100% completion? Hogwarts
How to set Steam to always choose the same launch option for a game?
Am I Locked Out? Romance Question
Do the tiles in Bounce n Trounce fall in a random order?
Are there any differences between the different releases of Donkey Kong for the NES?
in Teslagrad Where is this room located on the map?


