minecraft 為了在區塊裝飾時預先處理沙子等下落方塊,故添加了本規則。(後續文章可能會使用 IF
來代指它 [瞬時下落 Instant Falling])
BlockFalling.java
public class BlockFalling extends Block {
public static boolean fallInstantly;
private void checkFallable(World worldIn, BlockPos pos) {
if (canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) {
int i = 32;
if (!fallInstantly && worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))) {
if (!worldIn.isRemote) {
EntityFallingBlock entityfallingblock = new EntityFallingBlock(worldIn, (double) pos.getX() + 0.5D,
(double) pos.getY(), (double) pos.getZ() + 0.5D, worldIn.getBlockState(pos));
this.onStartFalling(entityfallingblock);
worldIn.spawnEntity(entityfallingblock);
}
} else {
worldIn.setBlockToAir(pos); // 設定當前位置為空氣
BlockPos blockpos;
for (blockpos = pos.down(); canFallThrough(worldIn.getBlockState(blockpos)) // 判斷下方是否能下落 && blockpos.getY() > 0; blockpos = blockpos.down()) { // 若不能,則繼續往下找 ;
}
if (blockpos.getY() > 0) {
worldIn.setBlockState(blockpos.up(), this.getDefaultState()); // 設定上方為目前的方塊(注意這邊是使用 `getDefaultState()`) }
}
}
}
}
會在在區塊裝飾時短暫開啟該 flag,並在結束後關閉。
小知識下面的 code
上面有比較完整的~~
ChunkGeneratorOverworld.java
public void populate(int x, int z) {
BlockFalling.fallInstantly = true; // 一些裝飾邏輯
BlockFalling.fallInstantly = false; }
在裝飾時也會開啟 IF
,所以開法和 ITT
一樣。
ITT 開法
注意,IF 和 ITT 不同,IF 是全緯度影響的,也就是說你不管在哪個緯度開 IF,其他緯度也會受到影響
- 重啟服務器
- 重新加載之前未被加載過的區塊 (裝飾),注意這邊是任意緯度都可以(若要保留
ITT
請在另一個緯度加載)
開啟後由於有關於 BlockFalling
採用的是 worldIn.setBlockState(blockpos.up(), this.getDefaultState());
,方塊狀態會被重置成預設狀態,得任何基於狀態保存的方塊,都會變成預設值,例如:
- 紅沙 -> 一般沙子
- 壞掉的鐵砧 -> 沒壞的鐵砧
- 各色混泥土粉末 -> 白色混泥土粉末
龍蛋並非使用 BlockFalling
處理,而是有自己的邏輯:
BlockDragonEgg.java
public class BlockDragonEgg extends Block {
// ...
private void checkFall(World worldIn, BlockPos pos) {
if (BlockFalling.canFallThrough(worldIn.getBlockState(pos.down())) && pos.getY() >= 0) { // 設定當前位置為空氣 int i = 32;
if (!BlockFalling.fallInstantly && worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))) {
worldIn.spawnEntity(new EntityFallingBlock(worldIn, (double) ((float) pos.getX() + 0.5F), (double) pos.getY(),
(double) ((float) pos.getZ() + 0.5F), this.getDefaultState()));
} else {
worldIn.setBlockToAir(pos);
BlockPos blockpos;
for (blockpos = pos; BlockFalling.canFallThrough(worldIn.getBlockState(blockpos)) // 判斷下方是否能下落 && blockpos.getY() > 0; blockpos = blockpos.down()) { // 若不能,則繼續往下找 ;
}
if (blockpos.getY() > 0) {
worldIn.setBlockState(blockpos, this.getDefaultState(), 2); // 設定上方為目前的方塊(注意這邊是使用 `getDefaultState()`) }
}
}
}
}
由於代碼中有 bug worldIn.setBlockState(blockpos, this.getDefaultState(), 2);
,並沒有使用 blockpos.up()
,導致比預期少一低一格,所以龍蛋會覆蓋原本的方塊。
得在 IF
開啟時,下落的龍蛋能夠破獲各種方塊(包括但不限於基岩等)
破完之後建議用活塞推掉或是其他辦法讓它變成掉落物,建議不要右鍵或左鍵它,除非你想其他地方也被破掉
原版基於龍蛋弱加載破基岩也是基於這個 bug(由於上面的 worldIn.isAreaLoaded(pos.add(-32, -32, -32), pos.add(32, 32, 32))
為 false, 龍蛋使用和 fallInstantly 一樣的邏輯)
似乎沒有 ?!