#If I have a position, how do I check what the block at that position is?

1 messages · Page 1 of 1 (latest)

craggy iron
#

I'm trying to create a script to change how bonemeal works on grass blocks, so I can modify which blocks are placed by it based on the biome it's used in. I'm not at the biome-checking point yet, but rather, at the beginning.

Surprisingly, the following code loads with "no errors", but obviously it doesn't work, or else I wouldn't be posting to support.

    let grass_blocks = ["minecraft:grass_block","botania:dry_grass","botania:golden_grass","botania:vivid_grass","botania:scorched_grass","botania:infused_grass","botania:mutated_grass","naturesaura:nether_grass","byg:lush_grass_block","byg:lush_grass_path","minecraft:crimson_nylium","minecraft:warped_nylium","byg:wailing_nylium","byg:sythian_nylium","byg:embur_nylium"]
    for (let i = 0; i <grass_blocks.length;i++) {
        if(event.block.id == grass_blocks[i] && event.item.id == "minecraft:bone_meal") {
            event.cancel()
            let attempts = 24
            for (let j = 0; j < attempts; j++) {
                let positional_attempts = 16
                let temppos = event.block.pos
                let airpos = temppos
                for (let k = 0; k < positional_attempts;k++){
                    temppos.x += Math.floor(Math.random()*3)-1
                    temppos.z += Math.floor(Math.random()*3)-1
                    let ychoices = [-1,0,0,0,0,1]
                    temppos.y += ychoices[Math.floor(Math.random()*6)]
                    
                    airpos = temppos
                    airpos.y += 1
                    if (temppos.block == grass_blocks[i] && airpos.block == "minecraft:air") break
                }
                if (temppos.block == grass_blocks[i] && airpos.block == "minecraft:air") {
                    //put block placement code here
                    console.log(temppos)
                }

            }
        }
    }
})```

I'm pretty sure temppos.block and airpos.block are incorrect, but how would I actually get the block at the positions of temppos and airpos?
copper craneBOT
#

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

slate harness
#

You can use event.level.getBlock(pos)

craggy iron
#

Sweet, if I use console.log(event.level.getBlock(temppos)), it tells me exactly what block is there.
Now I'm realizing, though, that for some reason I don't understand javascript enough, as

airpos.y += 1``` 
is adding 1 to the temppos.y as well. 
So the next question is, how to create a new MutableBlockPos I guess.
slate harness
#

new BlockPos(temppos) might work

craggy iron
#
    BlockPos(net.minecraft.core.Vec3i)
    BlockPos(net.minecraft.world.phys.Vec3) (server_scripts:script.js#146)```
OK, what does that mean?
slate harness
#

ah, that's annoying, ambiguous method means rhino can't figure out which of the java methods to use

craggy iron
#

Any way to disambiguate it?

slate harness
#

BlockPos['net.minecraft.core.Vec3i'](pos)

craggy iron
#

OK, will try that. Give it a second or 10 to reload...

#

[18:54:27] [ERR ] Error occurred while handling event 'block.right_click': Java class "net.minecraft.core.BlockPos" has no public instance field or method named "net.minecraft.core.Vec3i". (server_scripts:script.js#146)

slate harness
#

maybe, BlockPos['BlockPos(net.minecraft.core.Vec3i)'](pos)

#

never really ran into ambiguous constructors tbh

craggy iron
#

[19:01:09] [ERR ] Error occurred while handling event 'block.right_click': Java class "net.minecraft.core.BlockPos" has no public instance field or method named "BlockPos(net.minecraft.core.Vec3i)". (server_scripts:script.js#146)
Same error, basically.

slate harness
#

Probably easier to use the other constructor, new BlockPos(pos.x, pos.y, pos.z)

craggy iron
#

Well, that causes a different error now.

    let grass_blocks = ["minecraft:grass_block","botania:dry_grass","botania:golden_grass","botania:vivid_grass","botania:scorched_grass","botania:infused_grass","botania:mutated_grass","naturesaura:nether_grass","byg:lush_grass_block","byg:lush_grass_path","minecraft:crimson_nylium","minecraft:warped_nylium","byg:wailing_nylium","byg:sythian_nylium","byg:embur_nylium"]
    for (let i = 0; i <grass_blocks.length;i++) {
        if(event.block.id == grass_blocks[i] && event.item.id == "minecraft:bone_meal") {
            event.cancel()
            let attempts = 24
            for (let j = 0; j < attempts; j++) {
                let positional_attempts = 1
                let temppos = new BlockPos(event.block.pos.x,event.block.pos.y,event.block.pos.z)
                let airpos = new BlockPos(temppos.x,temppos.y,temppos.z)
                for (let k = 0; k < positional_attempts;k++){
                    let xzchoices = [-1,0,0,1]
                    temppos.x += xzchoices[Math.floor(Math.random()*xzchoices.length)]
                    temppos.z += xzchoices[Math.floor(Math.random()*xzchoices.length)]
                    let ychoices = [-1,0,0,0,0,1]
                    temppos.y += ychoices[Math.floor(Math.random()*ychoices.length)]
                    
                    airpos = new BlockPos(temppos.x,temppos.y,temppos.z)
                    airpos.y += 1
                    if (event.level.getBlock(temppos) == grass_blocks[i] && event.level.getBlock(airpos) == "minecraft:air") break
                }
                console.log(event.level.getBlock(temppos))
                console.log(temppos)
                console.log(airpos)
                if (event.level.getBlock(temppos) == grass_blocks[i] && event.level.getBlock(airpos) == "minecraft:air") {
                    //put block placement code here
                    console.log(temppos)
                }

            }
        }
    }
})```

And the error is 
```[19:11:21] [ERR  ] Error occurred while handling event 'block.right_click': Java class "net.minecraft.core.BlockPos" has no public instance field or method named "x". (server_scripts:script.js#150)```
#

So I guess now x is read-only, so I'm trying temppos = new BlockPos(temppos.x + xzchoices[Math.floor(Math.random()*xzchoices.length)],temppos.y + ychoices[Math.floor(Math.random()*ychoices.length)],temppos.z + xzchoices[Math.floor(Math.random()*xzchoices.length)])
as all one line

slate harness
#

Looks like you can call mutable() on a BlockPos to change it

#

new BlockPos(pos.x, pos.y, pos.z).mutable()

craggy iron
#

OK, if this doesn't work, I'll go back and try that.

#
[19:19:51] [INFO ] server_scripts:script.js:157: BlockPos{x=0, y=71, z=-1} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:158: BlockPos{x=0, y=72, z=-1} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:161: BlockPos{x=0, y=71, z=-1} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:156: minecraft:dirt [dev.latvian.mods.kubejs.level.BlockContainerJS]
[19:19:51] [INFO ] server_scripts:script.js:157: BlockPos{x=0, y=70, z=0} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:158: BlockPos{x=0, y=71, z=0} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:156: minecraft:grass_block[snowy=false] [dev.latvian.mods.kubejs.level.BlockContainerJS]
[19:19:51] [INFO ] server_scripts:script.js:157: BlockPos{x=1, y=71, z=0} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:158: BlockPos{x=1, y=72, z=0} [net.minecraft.core.BlockPos]
[19:19:51] [INFO ] server_scripts:script.js:161: BlockPos{x=1, y=71, z=0} [net.minecraft.core.BlockPos]```
Looks like it worked.
copper craneBOT
#

Ticket closed!

craggy iron
#

I'm just gonna comment so I don't lose this discussion now that my issue is resolved.

craggy iron
#

@slate harness You wouldn't happen to know how to get the biome at a blockPos, would you?

#

Actually, I figured that out. Now I need to convert Reference{ResourceKey[minecraft:worldgen/biome / biomesinjars:dead_land] into "biomesinjars:dead_land"

#

event.level.minecraftLevel.getBiome(airpos) is how I got the former.

slate harness
#

.location() should work

craggy iron
#

event.level.minecraftLevel.getBiome(airpos).location()?

slate harness
#

yeah

#

Returns the ResouceLocation from a ResouceKey

craggy iron
#

[21:07:50] [ERR ] Error occurred while handling event 'block.right_click': TypeError: Cannot find function location in object Reference{ResourceKey[minecraft:worldgen/biome / biomesoplenty:prairie]=net.minecraft.world.level.biome.Biome@6c675473}. (server_scripts:script.js#575) Agh, nope

#

So .location() didn't work

#

Should I open a new post for this issue I wonder?

slate harness
#

ah, it's event.level.minecraftLevel.getBiome(airpos).key().location()

craggy iron
#

[21:20:29] [INFO ] server_scripts:script.js:575: biomesoplenty:prairie
Yup, that worked.

#

One lest error, [21:23:52] [ERR ] Error occurred while handling event 'block.right_click': TypeError: Cannot find function setBlock in object ServerWorld:minecraft:overworld. (server_scripts:script.js#584)
with the line in question being event.level.setBlock(airpos,valid_block); I figured it wouldn't work, but I don't know what the actual command to set a block would be.

slate harness
#

You have to set it from the block, .getBlock(airpos).set(valid_block)

craggy iron
#

[21:29:39] [ERR ] Error occurred while handling event 'block.right_click': TypeError: Cannot find function setBlock in object minecraft:air. (server_scripts:script.js#584)
So that didn't quite work either.

#

Oh, wait

slate harness
#

yeah, I mistyped it the first time

craggy iron
#

.set, not .setBlock

#

OK, if this ultimately works, I should get some dead grass.

#

Huzzah!

#

Almost.

#

OK, the tall prairie grass looks a little odd

#

Hmm, how to add the NBT?

#

Or blockstate, or whatever.

slate harness
#

You can do .setBlockState() instead of .set()

#

or maybe in addition to

craggy iron
#

Do I do that after I .set()? IE, event.level.getBlock(airpos).set(valid_block) if (valid_block =="minecraft:tall_grass" || valid_block == "byg:tall_prarie_grass") { event.level.getBlock(new BlockPos(airpos.x,airpos.y+1,airpos.z)).set(valid_block).setBlockState(half=upper) }

#

Nope, that didn't work. Neither did event.level.getBlock(airpos).set(valid_block) if (valid_block =="minecraft:tall_grass" || valid_block == "byg:tall_prarie_grass") { tallpos = new BlockPos(airpos.x,airpos.y+1,airpos.z) event.level.getBlock(tallpos).set(valid_block) event.level.getBlock(tallpos).setBlockState(half=upper) }

slate harness
#

ah, apparently you can do it from set,

event.level.getBlock(tallpos).set(valid_block, {half:upper})
craggy iron
#

No errors but still no upper block.

#

Oh, I mispelled byg:tall_prairie_grass

#

And forgot a let

#

[21:49:14] [ERR ] Error occurred while handling event 'block.right_click': ReferenceError: "upper" is not defined. (server_scripts:script.js#587)
Maybe it's event.level.getBlock(tallpos).set(valid_block, {half:'upper'})?

#

Huzzah!

#

OK, so I don't have to manually add every potentially two-tall grass and flower to if (valid_block =="minecraft:tall_grass" || valid_block == "byg:tall_prairie_grass") {, is there some way of doing if (valid_block.has_state(half) {?

#

I think this for sure calls for a new thread