#Clearing a player's inventory on joining the game for the first time

33 messages · Page 1 of 1 (latest)

frank perch
#

So! I have an attempt at a script to clear a player's inventory with the /clear command, to try to remove the pile of mod-related books they start with. (There aren't mod configs to not generate them for a lot of them, unfortunately. :/ )

I'm using Decursio Stages to track if it's the first time joining, and after running the script, it adds the stage.

However, what I think is happening, is that the script runs when they join, and then the books are added after. Removing and re-adding the stage after this causes it to work correctly.

I tried adding a janky wait line to the script, but it doesn't seem to help.

Am I missing something obvious here?

const StageUtil = Java.loadClass('com.decursioteam.decursio_stages.utils.StageUtil')

PlayerEvents.loggedIn(event => {

    if (!StageUtil.hasStage(event.player, "starting inventory")) 
{
    let playerName = event.player.getName().getString(); 
    
    event.server.schedule(2000, () => {event.server.tell(`Welcome, ${playerName}!`);

        Utils.server.runCommandSilent(`clear ${playerName}`)
        Utils.server.runCommandSilent(`give ${playerName} minecraft:stone_sword`)
        Utils.server.runCommandSilent(`decstages add ${playerName} "starting inventory"`)
    });    
}
});
hearty heraldBOT
#

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

void minnow
#

iirc event.server.schedule() is based on seconds rather than ticks (use event.server.scheduleInTicks() if you want ticks), so your script will take half an hour to finish executing.

woeful creek
#

you should use the kubeJS methods to give the players items rather than running commands

#

sometimes commands can have unintended effects

void minnow
#

but yes, you can try if

event.player.inventory.clear()
event.player.give("minecraft:stone_sword")
//or
event.player.giveInHand("minecraft:stone_sword")

work any better than the commands.

woeful creek
#

On top of this, you could detect the inventory changed method and see if it has the book in it

#

then if it does run your logic

#

see if any of these 3 fixes work

#

if not, say and I'll try and figure something else out

pliant bane
#

to add on to this, I had a similar issue with Solar Craft's solar lexicon. in my trials, the book was being detected and the silent command to clear it was running, but the book still wasn't clearing. this was the solution I came up with: #1320104536676896778 message

shrewd locustBOT
#

[➤](#1320104536676896778 message)
Here's the final code:

PlayerEvents.loggedIn(event => {
    const { player, server } = event

    if (!player.persistentData.getBoolean("first_join")) {
        var timer = 0

        player.persistentData.putBoolean("first_join", true)

        server.scheduleRepeatingInTicks(4, (c) => {
            if (player.inventory.find("solarcraft:solar_lexicon") != -1 && timer < 100) { // Reschedule until book is gone and nonexistent
                timer = timer + 1
                event.server.runCommandSilent(`clear ${player.username} solarcraft:solar_lexicon`)
                c.reschedule()
            } else {
                c.clear()
            }
        })
    }
})
pliant bane
#

also, sometimes the book is actually a reward for a certain achievement, which is the case for mods like Simply Swords

#

@frank perch

#

in those cases, a simple datapack editing the achievement loot table is all you need

#

er... advancement

frank perch
# pliant bane also, sometimes the book is actually a reward for a certain achievement, which i...

This is amazing, and looks like exactly what I was looking for! (I feel like I also learned 3 new command options from reading this too lol; inventory.find I wasn't aware of, persistenData for the First Join, and then the option to use scheduleRepeatingInTicks.)

This was my janky attempt at it, which involved iterating through their whole inventory to check for the item. But it would only run once, and I was struggling with how to have it recursively reschedule itself without just making a forever loop lol.

const StageUtil = Java.loadClass('com.decursioteam.decursio_stages.utils.StageUtil')

PlayerEvents.loggedIn(event => {

    if (!StageUtil.hasStage(event.player, "starting inventory")) 
    {   let invCheck = false;
    for (let i = 0; i < 36; i++)
    {
        event.server.tell(`Slot item is: ${event.player.inventory.getStackInSlot(i).id}`);
        if (event.player.inventory.getStackInSlot(i).id == 'enigmaticlegacy:cursed_ring')
        {
            invCheck = true;
            if (invCheck == true){
                event.server.tell(`invCheck = ${invCheck}`);
                break}
            
        }
    };
    
    if (invCheck == true)
    {
        event.server.tell(`Welcome, ${playerName}!`);
        event.player.inventory.clear()
        event.player.give("minecraft:stone_sword")
        Utils.server.runCommandSilent(`decstages add ${playerName} "starting inventory"`)
    };

    };    
});

I'm going to try adapting yours! The Solarcraft Lexicon is a persistent issue for me too lol.

frank perch
#

So, after some questionable tampering, I have this:

const StageUtil = Java.loadClass('com.decursioteam.decursio_stages.utils.StageUtil')

PlayerEvents.loggedIn(event => {
    const { player, server } = event

    if (!StageUtil.hasStage(event.player, "starting inventory")) 
    {
        var timer = 0

        player.persistentData.putBoolean("first_join", true)

        server.scheduleRepeatingInTicks(60, (c) => {
            if (player.inventory.find('enigmaticlegacy:cursed_ring') != -1 && timer < 100) { // Reschedule until book is gone and nonexistent

                timer = timer + 1

                event.server.runCommandSilent(`clear ${player.username}`)
                c.reschedule()
            } else {
                c.clear()
            }
        })
    }
})

It works far better than mine, but doesn't seem to clear the player's hotbar on the first join. If you re-join, the inventory is cleared correctly. (If the item is present in inventory.)

I wonder if the Origins mod could be interfering? It pops up a screen to select your origin on first join... I'm going to try removing it to see. (It's not the Origins mod :/)

pliant bane
#

I see that you have enigmaticlegacy:cursed_ring in the code, and that can be removed upon first join via config

#

I feel like there are more items that can be disabled

#

also I see that you set scheduleRepeatingInTicks to 60 ticks, which is equivalent to 3 seconds

#

I put 4 in my code so it checks the inventory 5 times every second, or every 0.2 seconds

#

also, if there is more than one item given upon joining, then I believe some items are being added later than others 🤔

frank perch
# pliant bane tell me: what are *all* of the items that exist in the inventory upon first join...

This is the full list; I'm planning to give them via quests later:
Item.of('patchouli:guide_book', '{"patchouli:book":"caupona:book"}')

'dungeons_and_combat:combat_style_manual'

'solarcraft:solar_lexicon'

Item.of('patchouli:guide_book', '{"patchouli:book":"sosorgans:sos_organs_lexicon"}')

Item.of('patchouli:guide_book', '{"patchouli:book":"parcool:parcool_guide"}')

Item.of('patchouli:guide_book', '{"patchouli:book":"hexcasting:thehexbook"}')

Item.of('patchouli:guide_book', '{"patchouli:book":"irons_spellbooks:iss_guide_book"}')

Item.of('patchouli:guide_book', '{"patchouli:book":"footwork:combat_manual"}')

Item.of('patchouli:guide_book', '{"patchouli:book":"apotheosis:apoth_chronicle"}')

Item.of('silentgear:blueprint_package', '{silentlib.LootContainer:{LootTable:"silentgear:starter_blueprints"}}')

Item.of('pandora:pandora_necklace', '{PandoraCharms:[{Count:1b,id:"curseofpandora:curse_of_inertia"},{Count:1b,id:"curseofpandora:curse_of_proximity"},{Count:1b,id:"curseofpandora:curse_of_flesh"},{Count:1b,id:"curseofpandora:curse_of_metabolism"},{Count:1b,id:"curseofpandora:curse_of_tension"},{Count:1b,id:"curseofpandora:curse_of_prudence"},{Count:1b,id:"curseofpandora:curse_of_spell"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"},{Count:0b,id:"minecraft:air"}]}')

'enigmaticlegacy:cursed_ring'

Item.of('enigmaticlegacy:enigmatic_amulet', '{AssignedColor:0.1f,Inscription:"ColdComfort",ProperlyGranted:1b}')

'celestial_artifacts:heirloom_necklace'

'celestial_artifacts:catastrophe_scroll'

#

Item.of('wardance:manual', '{active1:"wardance:trample",active3:"wardance:curse_of_misfortune",active4:"wardance:decapitate",author:"Tesso Kanemochi, MBA",filtered_title:"Das Kapital",noUnlock:0b,pages:['{"text":"Money is king. Greed is good. Just don\'t lose it all in a blunder.\\n\\nTime is money. The faster you rush, the quicker {treasure;GOLD} will come to you.\\n\\n{Run;BOLD} your adversaries down quickly. You don\'t have time to waste on them."}','{"text":"\\n\\n{Luck;GOLD} can make or break a man\'s spirit. If yours is poor, consider just {blaming;LIGHT_PURPLE} someone else for it.\\n\\n{Joint ventures;GOLD} are often more successful. Just be sure {you get the credit;GOLD}, and {run fast;GOLD} if the markets crash."}','{"text":"\\n{Timeliness;BOLD} is the soul of an enterprise. Line your skills up for the perfect sales pitch.\\n\\nAre you really going to defile those graves for money? Of course you are."}'],passive1:"wardance:lady_luck",passive4:"wardance:selfish_mascot",passive5:"wardance:fatal_cadence",style:"wardance:gold_rush",title:"Das Kapital"}')

frank perch
frank perch
#

I made an ugly nuclear version that works:

const StageUtil = Java.loadClass('com.decursioteam.decursio_stages.utils.StageUtil')

PlayerEvents.loggedIn(event => 
{
    var timer = 0
    let air = Item.of('minecraft:air')
    let playerName = event.player.getName().getString();

    event.server.scheduleRepeatingInTicks(60, (c) => 
    {
    if (!StageUtil.hasStage(event.player, "starting inventory")) 
        {   
        for (let i = 0; i < 36; i++)
            {
            event.player.inventory.setStackInSlot(i, air);
            event.player.tell(`Timer ${timer}, i ${i}`);
            };
        };
        if (timer < 3)
        {
            timer = timer + 1
            c.reschedule();
        }
        else
        {
            event.player.tell(`Welcome, ${playerName}!`);
            event.player.give('minecraft:stone_sword');
            c.clear();
        }
    });

});

It works! Except for the else statement... I probably have the syntax wrong somewhere.

You were right though, some of those items are added after the initial ones, so the second or third wipe clears out the hotbar.

pliant bane
# frank perch This is the full list; I'm planning to give them via quests later: Item.of('patc...

ok here's what I found:

void minnow
#

the option for celestial artifacts should be part of a file called celestialartifacts-common.toml in config/celestial_configs/.

frank perch
#

Thanks guys! That's extremely helpful - I didn't consider that datapacks might be an option for a lot of those. Thank you for the specifics on the config files too!