mirror of
https://github.com/Theta-Dev/ConstructionWand.git
synced 2025-10-15 20:53:34 +02:00
(iron bars, glass panes, redstone) The reason for this crash is that I precomputed the blockstates to be placed (which would be free standing poles when no blocks are present around them). Placing all blocks at once then causes lots of block updates which may crash the game (especially in MC1.15). So the solution is to calculate the blockstate directly before the placement.
77 lines
2.1 KiB
Java
77 lines
2.1 KiB
Java
package thetadev.constructionwand.wand.undo;
|
|
|
|
import net.minecraft.block.BlockState;
|
|
import net.minecraft.entity.player.PlayerEntity;
|
|
import net.minecraft.fluid.Fluids;
|
|
import net.minecraft.item.ItemStack;
|
|
import net.minecraft.util.math.BlockPos;
|
|
import net.minecraft.util.math.BlockRayTraceResult;
|
|
import net.minecraft.world.World;
|
|
import thetadev.constructionwand.basics.WandUtil;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
public class DestroySnapshot implements ISnapshot
|
|
{
|
|
private final BlockState block;
|
|
private final BlockPos pos;
|
|
|
|
public DestroySnapshot(BlockState block, BlockPos pos) {
|
|
this.pos = pos;
|
|
this.block = block;
|
|
}
|
|
|
|
@Nullable
|
|
public static DestroySnapshot get(World world, PlayerEntity player, BlockPos pos) {
|
|
if(!WandUtil.isBlockRemovable(world, player, pos)) return null;
|
|
|
|
return new DestroySnapshot(world.getBlockState(pos), pos);
|
|
}
|
|
|
|
@Override
|
|
public BlockPos getPos() {
|
|
return pos;
|
|
}
|
|
|
|
@Override
|
|
public BlockState getBlockState() {
|
|
return block;
|
|
}
|
|
|
|
@Override
|
|
public ItemStack getRequiredItems() {
|
|
return ItemStack.EMPTY;
|
|
}
|
|
|
|
@Override
|
|
public boolean execute(World world, PlayerEntity player, BlockRayTraceResult rayTraceResult) {
|
|
return WandUtil.removeBlock(world, player, block, pos);
|
|
}
|
|
|
|
@Override
|
|
public boolean canRestore(World world, PlayerEntity player) {
|
|
// Is position out of world?
|
|
if(!world.isBlockPresent(pos)) return false;
|
|
|
|
// Is block modifiable?
|
|
if(!world.isBlockModifiable(player, pos)) return false;
|
|
|
|
// Ignore blocks and entities when in creative
|
|
if(player.isCreative()) return true;
|
|
|
|
// Is block empty or fluid?
|
|
if(!world.isAirBlock(pos) && !world.getBlockState(pos).isReplaceable(Fluids.EMPTY)) return false;
|
|
|
|
return !WandUtil.entitiesCollidingWithBlock(world, block, pos);
|
|
}
|
|
|
|
@Override
|
|
public boolean restore(World world, PlayerEntity player) {
|
|
return WandUtil.placeBlock(world, player, block, pos, null);
|
|
}
|
|
|
|
@Override
|
|
public void forceRestore(World world) {
|
|
world.setBlockState(pos, block);
|
|
}
|
|
}
|