#Fortune in a script. Along with Silk Touch and normal block item drop.

1 messages · Page 1 of 1 (latest)

bright prairie
#

Thought this might be useful to someone out there. Sure helped me a lot, Now i dont have to do these with loot tables.

import { world, ItemStack, GameMode } from "@minecraft/server";

const FORTUNE_DROPS = {
  "example:block_type": "example:drop_item",
};

function calcCountFromFortune(level) {
  return level === 0 ? 1 : (1 + Math.floor(Math.random() * (level + 1)));
}

world.afterEvents.playerBreakBlock.subscribe((ev) => {
  try {
    const preId = ev.brokenBlockPermutation?.type?.id;
    const dropTypeId = preId && FORTUNE_DROPS[preId];
    if (!dropTypeId) return;
    if (ev.player.getGameMode() === GameMode.Creative) return;
    const tool = ev.itemStackBeforeBreak ?? ev.itemStackAfterBreak;
    if (!tool) return;
    const ench = tool.getComponent("minecraft:enchantable");
    const silk = ench?.getEnchantment("silk_touch")?.level ?? 0;
    if (silk > 0) return;
    const fortune = ench?.getEnchantment("fortune")?.level ?? 0;
    const count = calcCountFromFortune(fortune);
    const stack = new ItemStack(dropTypeId, count);
    ev.dimension.spawnItem(stack, ev.block.location);
  } catch (e) {
    console.warn(`[fortune] ${e instanceof Error ? e.stack ?? e.message : String(e)}`);
  }
});
heavy maple
#

Looks good. Free to use?

bright prairie
solar tree
bright prairie
flint minnow
#

This is a very interesting and is probably useful, but I will continue using Loot Tables since it is working for what I need it to do. But if I need to do something else that this does or can do and can't do in the loot table, I might come and use it.

serene lake
# bright prairie Thought this might be useful to someone out there. Sure helped me a lot, Now i d...

I don't think the fortune function in this is completely accurate, just as a warning to anyone who might use this.

The bonus that fortune gives is between 1 and the level + 1, but you made two mistakes. First, the bonus isn't additive, it's multiplicative. If the bonus is 2, and the item is something like redstone (where the count is already 4), it would drop 8, not 5.

Second, the probability of each bonus value 1 to level + 1 isn't random with each bonus having an equal chance to occur. The chance to get a bonus multiplier of 1 is twice as much as the other values. For example, if you have Fortune 3, the chance of getting no extra drops (multiplier of 1) is 2/5, or 40%. For other bonuses (2x drops, 3x drops, and 4x drops), they each have a 20% chance.

bright prairie
# serene lake I don't think the fortune function in this is completely accurate, just as a war...

how about this? i think i have fixed those problems```js
import { world, ItemStack, GameMode } from "@minecraft/server";

const FORTUNE_DROPS = {
"example:block_type": "example:drop_item",
};

/**

  • Base (pre-Fortune) drop counts per ore.
  • If an ore isn't listed, it defaults to 1.
  • Example: if you want an ore to behave like redstone (base 4),
  • set it to 4 here.
    */
    const BASE_COUNTS = {
    // "example:block_type": 4,
    };

function rollFortuneMultiplier(level) {
if (!Number.isInteger(level) || level <= 0) return 1;
const roll = Math.floor(Math.random() * (level + 2));
return roll <= 1 ? 1 : roll;
}

world.afterEvents.playerBreakBlock.subscribe((ev) => {
try {
const preId = ev.brokenBlockPermutation?.type?.id;
const dropTypeId = preId && FORTUNE_DROPS[preId];
if (!dropTypeId) return;
if (ev.player.getGameMode() === GameMode.Creative) return;
const tool = ev.itemStackBeforeBreak ?? ev.itemStackAfterBreak;
const ench = tool?.getComponent("minecraft:enchantable");
const silk = ench?.getEnchantment("silk_touch")?.level ?? 0;
if (silk > 0) return;
const fortuneLevel = ench?.getEnchantment("fortune")?.level ?? 0;
const baseCount = BASE_COUNTS[preId] ?? 1;
const multiplier = rollFortuneMultiplier(fortuneLevel);
const total = Math.max(1, Math.trunc(baseCount * multiplier));
const stack = new ItemStack(dropTypeId, total);
ev.dimension.spawnItem(stack, ev.block.location);
} catch (e) {
console.warn([fortune] ${e instanceof Error ? e.stack ?? e.message : String(e)});
}
});