#How do I insert an item in a storage block?

49 messages · Page 1 of 1 (latest)

fringe magnet
#

I have a block entity but I can't figure out the API to insert items in it.

dreamy yachtBOT
#

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

sharp epoch
#

You could try to use ProbeJS to figure out the methods or tell us what BlockEntity it is so we can help

cold mothBOT
#

ProbeJS is an addon mod for KubeJS that generates typings files for VSCode, allowing VSCode to offer autocompletions for a ton of things!

Mod by @unkempt tangle

fringe magnet
#

ProbeJS appears to be 1.20.1 and I see you divided your support channels into two: 1.21.1 and before. Does that mean KubeJS went under significant changes after 1.20.1?

sharp epoch
sharp epoch
#

Anyway, here is an example script that inserts the players main hand item into a barrel on right click. if you want a specific slot, insertItem has an overload that takes a slot index from 0 as the first argument.
There are also setItem(slot, item) and getItem(slot) methods, use ProbeJS if you want to see all options (or try to work with console.log(Object.keys(barrelBlockEntity)), though that won't tell you anything about function arguments)

BlockEvents.rightClicked("minecraft:barrel", event => {
    if (event.hand != "MAIN_HAND" || event.player.mainHandItem.isEmpty()) return
    
    /**@type {$BarrelBlockEntity_} */
    let barrelBlockEntity = event.block.entity
    let remainder = barrelBlockEntity.insertItem(event.player.mainHandItem, false)
    event.player.setMainHandItem(remainder)
    event.cancel()
})
#

oh and the boolean as the last value is a parameter called "simulate" that mc uses on some methods to test if an operation would work/get that remainder itemstack before actually performing the operation.

fringe magnet
sharp epoch
#

I am sadly not aware of any way to do that

fringe magnet
sharp epoch
#

Yeah it doesn't seem like there is any way to even get a list of all loaded block entities, you can only check if a specific block position has an entity

#

yw!

sharp epoch
#

Forget about what i said, it is possible, just far from straight forward.

#
let $BarrelBlockEntity = Java.loadClass("net.minecraft.world.level.block.entity.BarrelBlockEntity")
let BarrelType = new $BarrelBlockEntity(new BlockPos(0,0,0), Blocks.BARREL.defaultBlockState()).type // dummy (i hate it)
BlockEvents.rightClicked("minecraft:barrel", event => {
    if (event.hand != "MAIN_HAND") return

    event.level.chunkSource.chunkMap.getChunks().forEach(chunkHolder => {
        /**@type {Map<$BlockPos_, $BlockEntity_>} */
        let BEMap = chunkHolder.getTickingChunk()?.blockEntities
        if (BEMap == null) return 

        for (let blockEntity of BEMap.values()) {
            if (blockEntity.type != BarrelType) continue //blockEntity instanceOf $BarrelBlockEntity does not work even though it really should
            console.log(blockEntity)
        }

    })
})
#

oh and probably try not to have this run too often, i'd assume it can get pretty resource expensive on a modded server

fringe magnet
#

The wiki doesn't cover a lot

sharp epoch
#

this was mostly me searching for "loadedChunks" in text in a 1.21.1 neoforge modding environment

#

which got me to ServerChunkCache.tickChunks(), from there i tried to figure out how i could get a ServerChunkCache object in kube (chunkSource is a ServerChunkCache object) and went the same way that method goes about iterating through chunks.

#

ah well ig the first thing i did was find that getBlockEntities() method on a ChunkAccess object

fringe magnet
#

I did code some mods in the past but where exactly did you search that?

#

For example where could I see what kind of methods a barrel entity have?

sharp epoch
#

If you set up a modding environment you most likely end up downloading the (deobufscated) source code for mc too
in IntelIJ you just press Ctrl+Shift+N and search for the file/method/text

#

just keep in mind that inheritance exists so e.g. BarrelBlockEntity has the methods from RandomizableContainerBlockEntity and so on

fringe magnet
#

Wait KubeJS is exactly the same as Minecraft? Damn this makes everything simpler

sharp epoch
#

sometimes - some things are wrappers for classes to make coding easier, but for those you can just look at the java code on the kubejs github
but yeah your js gets interpreted into java calls

fringe magnet
#

I'm extremely happy about learning this

#

Now everything works on the first try

#

Thank you so much!

#

I thought KubeJS redefined everything in its own way

fringe magnet
#

Does that make it any simpler?

sharp epoch
#

You'd need a mod for that. Barrels aren't ticking blockentities to begin with (or at least i think they aren't), and even if they were you'd need a mixin into the tick method which isn't possible with kube

fringe magnet
#

This is really making me scratch my head

#

@sharp epochTHANK YOU SO MUCH !!!!!!!!

fringe magnet
# sharp epoch You'd need a mod for that. Barrels aren't ticking blockentities to begin with (o...

I was actually asking this because I'm working on a kind of item duper where if you get a stack of something you can use barrels to farm it. This does generate the items but puts them in wrong barrels. It mistakes the generator barrels for other generator barrels. But it does not mistake them for regular barrels. I really don't know what I'm doing wrong here. I'm probably comparing the types wrong but I'm not exactly sure about that

ServerEvents.tick(event => {
  event.server.players.forEach(player => {
    const insertEveryXSeconds = 1;
    if (player.level.getDayTime() % (insertEveryXSeconds * 20)) {
      return;
    }
    player.level.chunkSource.chunkMap.getChunks().forEach(chunkHolder => {
      /**@type {Map<$BlockPos, $BlockEntity>} */
      let BEMap = chunkHolder.getTickingChunk()?.blockEntities
      if (BEMap == null) return 
      for (let blockEntity of BEMap.values()) {
          var blockPos = blockEntity.getBlockPos();
          let $BarrelBlockEntity = Java.loadClass("net.minecraft.world.level.block.entity.BarrelBlockEntity")
          let BarrelType = new $BarrelBlockEntity(new BlockPos(blockPos.x,blockPos.y,blockPos.z), Blocks.BARREL.defaultBlockState()).type // dummy (i hate it)
          if (blockEntity.type != BarrelType) continue //blockEntity instanceOf $BarrelBlockEntity does not work even though it really should
          const stack = blockEntity.getStackInSlot(0)
          const isFull = !stack.isEmpty() && stack.getCount() == stack.getMaxStackSize();
          if (isFull) {
            const item = stack.getItem();
            blockEntity.insertItem(item, false)
          }
      }
  })
  });
});

TLDR: This kind of understands which barrels need to generate items but when it comes to putting items in, it misplaces them

sharp epoch
#

it's a stupid bug with how Kube handles const, replace all your const with let and it will work

fringe magnet
#

My fault for writing safe code I guess 😔 Half an hour wasted there

sharp epoch
#

also don't loop over player like that, use LevelEvents.tick instead
and keep these lines above your loops, they can remain constants and kube isn't smart enough to optimize that out```
let $BarrelBlockEntity = Java.loadClass("net.minecraft.world.level.block.entity.BarrelBlockEntity")
let BarrelType = new $BarrelBlockEntity(new BlockPos(blockPos.x,blockPos.y,blockPos.z), Blocks.BARREL.defaultBlockState()).type

#

(otherwise you are running your code once per player for all barrels in the dimension)

#

oh and you can usually use event.server.tickCount % somevalue instead of needing DayTime, idk what dayTime returns for the end/nether

sharp epoch
fringe magnet
#

You may be the most helpful person I've seen this month

#

Wanna be friends?

sharp epoch