aa0307bb
是有现成的第三方API?(不过比起套用API,我更想知道原理

天辉胡萝卜
监听EntityExplodeEvent,有一个方法blockList​(),可以获取被tnt破坏的方块列表,替换为下落的沙子实体即可

aa0307bb
疾风暗影 发表于 2020-6-28 00:48
监听EntityExplodeEvent,有一个方法blockList​(),可以获取被tnt破坏的方块列表,替换为下落的沙子实体即 ...

“替换”是指遍历这个方块列表,获取每个方块的Location然后在相同的Location生成与该方块对应的掉落沙吗就行了吗?
如果是的话,有几个问题:
①所以不再需要自己去计算每个掉落沙的运动参数?
②因为我们没有去cancel这个EntityExplodeEvent,所以被炸掉的方块会照常消失。而且服务器对这些掉落沙的运动参数的计算是发生在“替换成掉落沙”这个过程之后?

天辉胡萝卜
aa0307bb 发表于 2020-6-28 01:38
“替换”是指遍历这个方块列表,获取每个方块的Location然后在相同的Location生成与该方块对应的掉落沙吗 ...

for(Block block : e.blockList())
{

float x = (float) -0.5 + (float) (Math.random() * ((0.5 - -0.5) + 1));
float y = (float) -1 + (float) (Math.random() * ((1 - -1) + 1));
float z = (float) -0.5 + (float) (Math.random() * ((0.5 - -0.5) + 1));
FallingBlock fb = block.getWorld().spawnFallingBlock(block.getLocation(), Material.SAND);


fb.setVelocity(new Vector(x, y, z));
block.setType(Material.AIR);

}

也就是先设成空气(移除),然后生成沙子,计算轨迹
计算公式自己调参数

凭印象写的,可能有小错

aa0307bb
疾风暗影 发表于 2020-6-28 01:53
for(Block block : e.blockList())
{

感谢!
问亿下:
①fb.setVelocity()设置的速度的单位是?(m/tick?)
②你用的是spawnFallingBlock(Location, Material, byte)
我想换成
spawnFallingBlock(Location, MaterialData)或者(好吧MaterialData是过时的)
spawnFallingBlock(Location, BlockData)
这第二个参数 BlockData该怎么填
③这里spawnFallingBlock(block.getLocation(), Material.SAND)设定掉落沙全是固定的沙子,
该如何替换成与block(取自for(Block block : e.blockList())循环)类型相同

天辉胡萝卜
blockdata是带有方块状态的量,比如带方向的铁砧,用Bukkit.createBlockdata创建

与block相同的话自己用getType获取对应的material

aa0307bb
疾风暗影 发表于 2020-6-28 04:47
blockdata是带有方块状态的量,比如带方向的铁砧,用Bukkit.createBlockdata创建

与block相同的话自己用ge ...

①似乎Bukkit.createBlockdata是1.12没有的(?
用↓这个曲线救国
block.getWorld().spawnFallingBlock(block.getLocation(), block.getType(), (byte) block.getTypeId());

但是发现会把草炸成枯死的灌木

②另外有没有什么办法让爆炸产生的掉落沙落地之后不变成方块(fb.isOnGround()?)
(仅限“爆炸产生的掉落沙”,其它事件产生的掉落沙正常变成方块)

天辉胡萝卜
aa0307bb 发表于 2020-6-28 12:54
①似乎Bukkit.createBlockdata是1.12没有的(?
用↓这个曲线救国

fallingBlock.setDropItem(false);

遇到问题请先查询javadoc

aa0307bb
疾风暗影 发表于 2020-6-28 13:08
fallingBlock.setDropItem(false);

遇到问题请先查询javadoc

查过了,但我问的是“不要变成方块”而不是“不要掉落物品”,这似乎找不到现成的API

天辉胡萝卜
aa0307bb 发表于 2020-6-28 13:20
查过了,但我问的是“不要变成方块”而不是“不要掉落物品”,这似乎找不到现成的API ...

https://minecraft.gamepedia.com/Falling_Block/ED

nms设置entity的time为接近600的值,time超过600会自动删除不留方块

aa0307bb
疾风暗影 发表于 2020-6-28 13:27
https://minecraft.gamepedia.com/Falling_Block/ED

nms设置entity的time为接近600的值,time超过600会 ...

fb.setTicksLived()也可以设置time
用“时长超过600tick”这个特性来实现的话,
太接近600 爆炸效果没怎样显示就没了
稍微小一点,爆炸效果有了但是那些炸得不高的掉落沙就变成方块了

我尝试过在监听器的for循环里把每个FallingSand加进一个列表
for(Block block : e.blockList()){
    ...
    PluginMain.fb_ls.add(fb);
}

再开一个每tick执行一次的任务用于监视这个插件创建的掉落沙,用isOnGround()判断掉落沙掉地上了,然后就fb.remove()来清除这个掉落沙
for(FallingBlock fb : PluginMain.fb_ls) {                       
                        if(fb.isOnGround()) {
                                fb.remove();
                                PluginMain.fb_ls.remove(fb);
                        }
}

但是行不通