#efficient way to check if there are any blocks or any entities in a radius?
63 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
I just need to constantly check if there are any blocks or entities in a radius from this entity
since I want the entity later to explode if there is anything near
level.getEntitiesOfClass(class, aabb) gets you an iterable List<T extends class> of entities inside the AABB
You can import net.minecraft.world.phys.AABB and instantiate it with 2 BlockPos' of opposite corners of whatever cube size you want
I recommend importing let $LivingEntity = Java.loadClass('net.minecraft.world.entity.LivingEntity') and then just passing $LivingEntity as the class, unless you want higher control
Blocks can get a bit messy...
For this, I recommend using BlockPos::betweenClosed(x1,y1,z1,x2,y2,z2) which is optimized for large searching large areas, by using MutableBlockPos. But there's some large caveats to keep in mind. The resulting BlockPos' instances can only be used within the iteration loop, unless you specifically convert the BlockPos using .toImmutable() as the referenced blockpos will switch through each following position within the search radius
Also: the x1,y1,z1,x2,y2,z2 have to be passed based on size. x1 must be less than x2, y1 must be less than y2 and z1 must be less than z2
oh my
also; I heavily recommend only searching every so often. Searching once every second for entities is near imperceptible for most players, and is an instant 20x better performance
Searching blocks (which will be the bigger performance loss) once every 5s is an instant 100x performance
hmm
actually now when I think about it
could I not just idk increase the entity hitbox aswell
not sure if I can live edit it tho
it might also increase the model size tho
hmm
iirc larger hitbox doesn't really make it performant than doing AABB
The game still needs to do the physics anyway, and perhaps on a gametick basis
Btw, AABB is built in kubejs so you can directly use AABB.of and not need to do Java.loadclass for it
hmm
.tick(entity => {
let level = entity.level
console.log(entity.age)
if (entity.age > 20 && entity.age % 20 == 0) {
let fuze = entity.getSyncedData("Fuze")
let RADIUS = entity.getSyncedData("FuzeValue") || 10
console.log(fuze, RADIUS)
if (fuze === "proximity_fuze") {
let x = entity.x
let y = entity.y
let z = entity.z
let foundBlock = false
outerLoop:
for (let dx = -RADIUS; dx <= RADIUS; dx++) {
for (let dy = -RADIUS; dy <= RADIUS; dy++) {
for (let dz = -RADIUS; dz <= RADIUS; dz++) {
let block = level.getBlock(x + dx, y + dy, z + dz)
if (block.id !== "minecraft:air") {
foundBlock = true
break outerLoop
}
}
}
}
if (foundBlock) {
entity.remove("discarded")
I currently have this, which is extremely laggy.
idk how to use the provided ideas
you are checking if any block block except air exists in radius.... that should break the loop in like 6 attempts max...
Try this and see if performance is better
.tick(entity => {
let level = entity.level
console.log(entity.age)
if(entity.age > 20 && entity.age % 20 == 0){
let fuze = entity.getSyncedData('Fuze')
let RADIUS = entity.getSyncedData('FuzeValue') || 10
console.log(fuze, RADIUS)
if(fuze === "proximity_fuze"){
let center = entity.blockPosition()
let lessercorner = center.north(RADIUS).west(RADIUS).below(RADIUS)
let greatercorner = center.south(RADIUS).east(RADIUS).above(RADIUS)
let targets = $BlockPos.betweenClosedStream(lessercorner, greatercorner)
.filter(bpos => {
level.getBlock(bpos).id !== "minecraft:air"
})
.toArray()
if(targets.length > 0)
entity.remove("discarded")
}
}
(north/west/below are negative directions, south/east/above being positive. shouldn't matter for the betweenClosedStream(BlockPos, BlockPos) overload, but still...)
hmm
problem
the proximity fuze has max of 32 blocks for whatever reason
which
is a lot
maybe if I can minimize the amount of blocks to check
maybe just a hollow shell or something
I have no idea how create big cannons did it
is that even open sourced
Does the bomb move? or is it affected by gravity?
it moves
it's a projectile with a model
I thought about increasing the projectile hitbox
but idk bout performance
Well, an idea is to separate blockpos to check into several groups and only check a group in 1 tick. Just like I did it in the previous "block degradation" thread
Or you can try the raycast way
should be fine with 6 (all cuboid directions) or even just 5 and skip "behind"
The 4 cardinal can also have a lesser range as they're less likely to trigger
hmm
I prob need more rays than that tbh
I would probably do diagonal too
25 rays seems like a lot idk
let result = level.clip(new $ClipContext(
ORIGIN,
TO,
$ClipContext.Block.COLLIDER,
$ClipContext.Fluid.NONE,
entity
))
if (result) { // how do I check again
hitSomething = true
break
}
I forgot how to check
const $HitResult$Type = Java.loadClass("net.minecraft.world.phys.HitResult$Type")
something with this
forgot
if (result.type == HitResult$Type.MISS) { // how do I check again
hitSomething = true
break
}
this maybe
well
with a !
I guess
if(!result.type.equals($HitResult$Type.MISS))