贺兰兰
如题,最好能直接给出代码BukkitAPI 版本是 1.16.4



天辉胡萝卜
Player#getLocation,然后沿y轴遍历查看是否是树叶(仍不能判断是否是树)

似乎没有更好的方法了

zhiqiu520
先沿y轴查看附近有没有木头
然后z轴往上叠加都是木头
然后在这个木头附近是不是有树叶
这是检测附近有没有树

贺兰兰
疾风暗影 发表于 2020-11-26 15:14
Player#getLocation,然后沿y轴遍历查看是否是树叶(仍不能判断是否是树)

似乎没有更好的方法了 ...

之前就是这么写的,但不太好

William_Shi
疾风暗影 发表于 2020-11-26 15:14
Player#getLocation,然后沿y轴遍历查看是否是树叶(仍不能判断是否是树)

似乎没有更好的方法了 ...

https://bukkit.windit.net/javado ... ctureGrowEvent.html

这个可以手动记录树
(甚至还包括了方块,https://bukkit.windit.net/javado ... nt.html#getBlocks--
但是不能检测有没有被砍,配合你的更好

贺兰兰
William_Shi 发表于 2020-11-26 19:02
https://bukkit.windit.net/javadoc/org/bukkit/event/world/StructureGrowEvent.html

这个可以手动记录 ...
  1. fun LivingEntity.isUnderTree(): Boolean {
  2.         val maxDistanceBetweenLogAndLeaves = 5
  3.         val treeLeavesNumberAtLeast = 6
  4.         val treeLogUpTo = 1
  5.         val treeLogDownTo = 1

  6.         val highestBlock = world.getHighestBlockAt(location)

  7.         if (highestBlock.y <= location.y) return false
  8.         if (!highestBlock.type.name.endsWith("LEAVES")) return false

  9.         val blockList = highestBlock.location.get3DBlocksAround(maxDistanceBetweenLogAndLeaves)
  10.         if (!blockList.stream().anyMatch { it.type.name.endsWith("LOG") }) return false
  11.         if (blockList.filter { it.type.name.endsWith("LEAVES") }.count() < treeLeavesNumberAtLeast) return false

  12.         val log = blockList.find { it.type.name.endsWith("LOG") }!!
  13.         if (!log.location.getYBlocks(treeLogUpTo, treeLogDownTo).all { it.type.name.endsWith("LEAVES") || it.type == log.type }) return false

  14.         return true
  15.     }


  16.     fun Location.get3DBlocksAround(radius: Int): List<Block> {
  17.         val blockList = mutableListOf<Block>()
  18.         val max = clone().add(radius.toDouble(), radius.toDouble(), radius.toDouble())
  19.         val min = clone().subtract(radius.toDouble(), radius.toDouble(), radius.toDouble())
  20.         for (loop_x in min.x.toInt()..max.x.toInt()) {
  21.             for (loop_y in min.y.toInt()..max.y.toInt()) {
  22.                 for (loop_z in min.z.toInt()..max.z.toInt()) {
  23.                     val block = Location(world, loop_x.toDouble(), loop_y.toDouble(), loop_z.toDouble()).block
  24.                     if (!block.type.name.endsWith("AIR"))
  25.                         blockList.add(block)
  26.                 }
  27.             }
  28.         }
  29.         return blockList
  30.     }

  31.     fun Location.getYBlocks(up: Int, down: Int): List<Block> {
  32.         val blockList = mutableListOf<Block>()
  33.         for (loop_y in (-down)..up) {
  34.             val block = clone().add(0.0, loop_y.toDouble(), 0.0).block
  35.             if (!block.type.name.endsWith("AIR"))
  36.                 blockList.add(block)
  37.         }
  38.         return blockList
  39.     }
复制代码

根据坛友的代码简单写了一个,判断起来应该没问题。就是小树和密集的树判断可能有问题

海螺螺
贺兰兰 发表于 2020-11-27 13:31
根据坛友的代码简单写了一个,判断起来应该没问题。就是小树和密集的树判断可能有问题 ...
  1.         if (org.bukkit.Tag.LEAVES.isTagged(location.getBlock().getType())) {
  2.             Location add = location.clone().add(0, 1, 0);
  3.             if (Tag.LOGS.isTagged(add.getBlock().getType())) {

  4.             }
  5.         }
复制代码

贺兰兰
海螺螺 发表于 2020-11-27 15:06

啊这,还可以这样

贺兰兰
本帖最后由 贺兰兰 于 2020-11-28 13:36 编辑

这个Tag是用来判断Material是那个Tag,还是说放块是否是原生的方块呢

洞穴夜莺
本帖最后由 洞穴夜莺 于 2020-11-28 19:26 编辑
贺兰兰 发表于 2020-11-28 13:16
这个Tag是用来判断Material是那个Tag,还是说放块是否是原生的方块呢

tag用来判断是否是某一类方块
LEAVES是原版的一个标签,含有各种类型的树叶方块
https://wiki.biligame.com/mc/%E6%A0%87%E7%AD%BE

下面是一段我自己写的Java代码,未经调试,仅供参考
  1. private final int[][] directions = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}};
  2.     private final int[][] logdirections = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {0, 0}};
  3.     private boolean isUnderTree(Location loc, HashSet<Location> searched){
  4.         if(searched.contains(loc))
  5.             return false;
  6.         searched.add(loc.clone());//添加标记,防止重复搜索
  7.         if(loc.getY() >= 256)
  8.             return false;
  9.         BlockData current = loc.getBlock().getBlockData();
  10.         if(Tag.LOGS.isTagged(current.getMaterial())){//如果头顶上是树干
  11.             for(int[] offset : directions) {//找一找有没有树叶
  12.                 BlockData data = loc.clone().add(offset[0], offset[1], offset[2]).getBlock().getBlockData();
  13.                 if (data instanceof Leaves && !((Leaves) data).isPersistent())
  14.                     return true;
  15.             }
  16.             for(int[] offset : logdirections){//处理歪脖子树的情况
  17.                 if(isUnderTree(loc.add(offset[0], 1, offset[1]), searched))
  18.                     return true;
  19.             }
  20.         }else if(current instanceof Leaves && !((Leaves) current).isPersistent()){
  21.             return true;
  22.         }
  23.         return false;
  24.     }

  25.     public boolean isUnderTree(Location loc){
  26.         while(!loc.getBlock().getType().isSolid() && loc.getY() < 256)//稍微修改了一下,这个东西放这里好一点
  27.             loc.add(0, 1, 0);
  28.         return isUnderTree(loc, new HashSet<>());
  29.     }
复制代码

贺兰兰
洞穴夜莺 发表于 2020-11-28 13:58
tag用来判断是否是某一类方块
LEAVES是原版的一个标签,含有各种类型的树叶方块
https://wiki.biligame.co ...

“//如果头顶上是树干”头顶上怎么会有树干

第一页 上一页 下一页 最后一页