#Is it possible for me to remove the crafts from 4 mods and add all the items into a "Gacha" table?
21 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
Yes, possible:
- You can create custom commands
- You can make the command consume an item from the inventory
- You can make the command give a random plushie
how would I Go about doing this?
I would love to have different teirs to it, like X plushies are more common than X
Like Teir 1, 2, 3, 4, 5 for lest to most common
For demonstration, I'll write a script that consumes gold ingots from inventory and gives a random tool. This will take a while BTW
It's okay I just need a example n work from there!
So far, I made these:
- Command (refers to function inside
globalin startup scripts):
// Server script
ServerEvents.commandRegistry(event => {
const { commands: Commands, arguments: Arguments } = event
event.register(
Commands.literal('gacha').executes(ctx => global.command(ctx))
)
})
- Startup script (so it can be quickly reloaded with
/kubejs reload startup_scripts), includes weighted RNG that rolls rarity. TheweightedRNGfunction is well typed with JSDoc annotation, so if you use VSCode or any other editor that supports TS you can see that you will get one of the keys of the object provided that has weights
/** @import { $CommandContext } from "com.mojang.brigadier.context.CommandContext" */
/** @import { $CommandSourceStack } from "net.minecraft.commands.CommandSourceStack") */
const weightedRNG = (() => {
/** @type {Record<string, number>} */
let _weights
/** @type {[string, number][]} */
let _entries
/** @type {number} */
let _raritySum
/**
* @template {Record<string, number>} T
* @param {T} weights
* @returns {keyof T}
*/
return function weightedRNG(weights) {
if (_weights == undefined || _weights !== weights) {
_weights = weights
_raritySum = Object.values(_weights).reduce((a, b) => a + b)
_entries = Object.entries(_weights)
}
// An integer number between 1 and _raritySum, inclusive.
let randomNumber = Utils.random.nextInt(_raritySum) + 1
let index = -1
while (randomNumber > 0) {
index++
randomNumber -= _entries[index][1]
}
return _entries[index][0]
}
})()
/**
*
* @param {$CommandContext<$CommandSourceStack>} ctx
* @returns {integer}
*/
global.command = ctx => {
const { player } = ctx.source
const rolledRarity = weightedRNG({
common: 100,
uncommon: 50,
rare: 20,
epic: 10,
legendary: 2,
})
player.tell(rolledRarity)
// const slot = player.inventory.find('minecraft:gold_ingot') // Find gold in inventory
// if (slot == -1) return 0 // Return, if gold not found (`find` returns -1)
// const coinStack = player.inventory.getStackInSlot(slot) // Get the item stack at that slot
// coinStack.count--; // Reduce its size by 1
// player.tell(slot)
return 1
}
Ohhh okay I'm reading them rn
wait so is this a pure RNG system or actually gacha with possible pity? I'm a bit confused reading it all
Right now it appears to be pure RNG, but weighted. No pity system, that wasn't specified in the requirements. What KonSola5's script currently does is when a player runs the command, it generates a rarity, and tells the player that rarity in their chat log. That's all. So you have a 100/182 chance of rolling common, 50/182 chance of uncommon, etc. but no guarantees of X rarity in N spins.
They started writing the code to deduct the gold ingot, but it looks like it wasn't working so they commented that out.
You would have to add persistant data to the player for that. Which is possible too.
I implented a weighted RNG to which you can provide weights of rarities, the weight-related calculations will be memoized upon running the function
Could also use Utils.lazy to make a function that memoizes its output, but didn't think of that
Thank god, I wanted it purely randomized
Okay I will start to make a script myself and see how well it works
with this example
player.give can give the player an item
player.give(item)
Where item is anything that can be a representation of an item stack
And since I made the weighted RNG return a string corresponding to rarity, you can specify possible outputs in a JS object with arrays as values:
const rewards = {
common: ["minecraft:dirt", "minecraft:cobblestone"],
uncommon: ["minecraft:iron_ingot", "minecraft:bone_block"],
rare: ["minecraft:blaze_rod", "minecraft:lapis_block"],
epic: ["minecraft:diamond", "minecraft:music_disc_relic", "minecraft:music_disc_stal"],
legendary: ["minecraft:elytra", "minecraft:nether_star"],
}
const rarityRewards = rewards[rolledRarity];
player.give(rarityRewards[Utils.random.nextInt(rarityRewards.length)])