#InventoryChange Event Doesnt seem to save edits to a item

65 messages · Page 1 of 1 (latest)

simple mango
#

When listening to the event and modifying the nbt of an item, it seems to reset after the event occurs.
Could i have some assistance on what is wrong?

From my testing it seems related to the noLoop part of my code. However as what im doing is changing NBT of an item, it is required otherwise a infinite loop occurs.

let noLoop = true;
PlayerEvents.inventoryChanged(e => {
    noLoop = !noLoop;
    if (noLoop) return;

    let {item, item: {nbt: {itemModifier}}, player, level} = e;
    if (itemModifier == undefined) {
        // global.ModifierHandler.newModifier(item, level); // What i am to do, but to simplify i did the below
        item.nbt.merge({"test": 1});
        player.tell(item.nbt) // This Shows The change as actually happening, but changes do not reflect in game.
    };
});
```First Image is what the base Nbt of the item is, second is the output of player.tell, and third is the final result of the item.
simple idolBOT
#

Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!

dry spireBOT
#

You can find your KubeJS server log in /minecraft/logs/kubejs/server.log.
If you are on 1.18 or below it will be called server.txt.
Please send it if asked, as it contains helpful information.

simple mango
#

It contains nothing ¯_(ツ)_/¯

vivid arch
#

So whats wrong with it exactly?

simple mango
dry spireBOT
#

Paste version of server.log from @simple mango

simple mango
#

the code is to add nbt to the item when it is picked up, however, it only adds it within the event, then resets when leaving

vivid arch
#

Wow thats a lot of warns

vivid arch
simple mango
#

just recipes, i dont know how to fix that

vivid arch
#

Because I have the same issue

simple mango
#

but i need the loop stopper otherwise i get an infinite loop

vivid arch
#

You can check if the NBT already exists, and if it does, it won't do the other stuff

simple mango
#

well it doesnt work explicitly, nbt is not added

vivid arch
#

huh

simple mango
#

if i use global.ModifierHandler.newModifier(item, level); which i intend to use, it applies a modifier

#

and that can be seen, but as its in a infinite loop, it just adds new ones

#

as it only sees the item pre inventory change

#

inventory change -> doesnt have the nbt -> applies modifier (seen in nbt) -> loops to start -> nbt is not here -> repeat

#

the code i use works as i use it on a right click event on a block, works just fine

#
/**
 * 
 * @param {Internal.BlockRightClickedEventJS} e 
 */
global.ModifierReroll = (e) => {
    let {item, player, level, block} = e;
    let itemCopy = e.item.copy();
    if (!e || !player || !item || player.isFake()) return;
    if (!(item.hasTag("kubejs:armour") || item.hasTag("kubejs:weapons") || item.hasTag("forge:tools"))) return;

    let value = new ItemValueCalculator().getItemValue(item);
    let bankAccount = $Numismatics.BANK.getAccount(player.uuid);
    if (bankAccount && bankAccount.deduct(value)) {
        player.tell([Text.gray("Rerolling "), Text.gold(stringTitle(`${itemCopy.displayName.string}`)), Text.gray(` For: ${value}¤`)]);
        global.ModifierHandler.newModifier(item, level)
        block.playersInRadius.playSound("eeeabsmobs:giant_axe_hit", 1, 2);
    } else player.tell(Text.red("Insufficient Balance In Bank Account."));
    e.cancel();
};
``` this code
#

only other issue i could find was #1059074311836663838 message but they just use a different event, but as i cant quite pinpoint where the item is to come from as it would apply to many events (crafting, pickup, mob loot, dungeon loot etc) i would think that inventorychange would be the best location to get it

dry spireBOT
#

[➤](#1059074311836663838 message)

PlayerEvents.inventoryChanged((event) => {
    const { item } = event

    const validTool = item.tags.toList().some((tag) => {
        return tag.toString().includes("cave_collapse:mining_tools")
    })

    if (!validTool) return

    const hasUnbreaking = item
        .getAllEnchantments()
        .keySet()
        .some((a) => a.descriptionId === "enchantment.minecraft.unbreaking")

    if (hasUnbreaking && Number(item.nbt["CollapsingTool"]) === 1) {
        item.nbt["CollapsingTool"] = false
        return
    }

    if (
        !hasUnbreaking &&
        (item.nbt["CollapsingTool"] === undefined ||
            Number(item.nbt["CollapsingTool"]) === 0)
    ) {
        item.nbt["CollapsingTool"] = true
        return
    }
})

My script here waits for the inventory change event and should add or remove nbt tags to the item that changed depending on if it meets some conditions.

For some reason this causes an infinite loop and my item's NBT is never set.

My guess is that setting the nbt causes an inventory changed event itself and it's never able to set the nbt. So I'm curious how I should set the NBT in this scenario then.

Thanks

vivid arch
# simple mango

The unknown recipe stuff was annoying me, so I started this:

ServerEvents.highPriorityData(event => {
    // for TFMG
    ['mesh_concrete'].forEach(item => {
        event.addJson(`tfmg:recipes/${item}`, {
            type: "minecraft:crafting_shaped",
            conditions: [
                { type: "forge:false"}
            ]
        })
    })

    // for biomesoplenty
    ['rose_quartz_chunk'].forEach(item => {
        event.addJson(`biomesoplenty:recipes/${item}`, {
            type: "create:item_application",
            conditions: [
                { type: "forge:false"}
            ]
        })
    })
})

it just needs more items and stuff

#

I'm getting someone else to help with you issue

simple mango
#

thanks 🙂

#

if i make it give me an item via ```js
let noLoop = true;
PlayerEvents.inventoryChanged(e => {
noLoop = !noLoop;
if (noLoop) return;

let {item, item: {nbt: {itemModifier}}, player, level} = e;
if (itemModifier == undefined) {
    // global.ModifierHandler.newModifier(item, level);
    item.nbt.merge({"test": 1});
    player.tell(item.nbt)
    player.give(item)
};

});

manic karma
#

I would say that changing items nbt on inv change itself is very cursed

#

was this your first option?

simple mango
blissful oyster
#

what is the end effect you want to achieve

simple mango
#

im only doing this as the mod itself doesnt provide the ability for multiple types of modifier, so i do that myself, and then i also have to essentially give the modifier some how myself

blissful oyster
simple mango
#

player obtains a item, a modifier is applied to it if it doesnt have one already. no matter the method of obtaining

#

the modifier is essentially applied within nbt, hence the need to modify it

blissful oyster
#

just modify the ways they obtain it
its a lot easier

#

loot tables and recipes should be all you need

simple mango
#

would i essentially need to make a low priority script that modifies this as i already modify recipes for some weapons etc that has an output that is not nbt compatible

blissful oyster
#

you cant modify already modified recipes

simple mango
#

thats an issue then

blissful oyster
#

what recipe doesnt support nbt outputs?

simple mango
#

am i incorrect in the thought that create sequenced and/or Hephaestus forge recipes aren't? as if it is then im wrong and it should be simple

blissful oyster
#

isnt hepahestus the fabric port of tinkers

simple mango
#

no forbidden and arcanus

manic karma
#

btw back on topic of modifiers, you can just use normal methods to add those modifiers, don't need to work with raw nbt

simple mango
#

im not using the base pools in the mod, so that doesnt work for me. im using a cursed workaround to get closer to terraria

#

by that i mean that the code i linked wont work as i dont use curio_pool / tool_pool to store modifiers for items

simple mango
# manic karma btw back on topic of modifiers, you can just use normal methods to add those mod...

and i am using their methods, just that inventory change doesnt let it save: ```js
/**

  • @param {Internal.ItemStack} item
    */
    modifierHandler.prototype.rollModifier = function(item, level) {
    for (let entry of this.modifierPools.entries()) {
    let [key, pool] = entry;
    if (pool.isApplicable.test(item)) {
    return pool.roll(level.random)
    };
    };
    return null;
    };

modifierHandler.prototype.newModifier = function(item, level) {
$ModifierHandler.setModifier(item, this.rollModifier(item, level));
}```

blissful oyster
simple mango
#

ill give it a try, thanks for the help 🙂

blissful oyster
#

and for loot u can use LootJS

dry spireBOT
#

LootJS is an addon for KubeJS that allows modifying loot from all sources dynamically (much nicer than loot tables)!
It also supports removing loot added by mods, unlike KubeJS' current loot table events.

simple mango
#

in relation to a recipe, is there any method to get the level? as js Utils.server.getLevel("minecraft:overworld").random returns ```js
Error in 'ServerEvents.recipes': TypeError: Cannot call method "getLevel" of null

#

im trying to use it in js result.withNBT(`itemModifier:${global.ModifierHandler.rollModifier(result, Utils.server.getLevel("minecraft:overworld").random).name}`) where result is the output of a create sequenced recipe

blissful oyster
#

server isnt available when recipes load

#

why do you want to change the output every server load

simple mango
#

not quite, the modifiers are random, and i would like to apply a random modifier each time it is crafted. rereading my code, and it is not quite what i wanted.

#

and as the recipes are not from a shapeless or shaped recipe i cannot use modifyResult

blissful oyster
#

ah, yeah..

#

you might have to go with the inventory changed even then, though it wont be particularly nice

simple mango
#

yea and its still not exactly what i wanted, ill prob just chill with just making the player obtain the modifier via my other method (clicking the smithing table)

#

thanks for the effort 🙂