Destroy, Remove, Invalidate

- Dangerous restructuring of common behaviour during tile removal
- Fixed unloading Redstone Links querying their own chunk for tile entities
- Remove unused imports
This commit is contained in:
simibubi 2022-12-11 20:59:31 +01:00
parent 450359b212
commit c420048a88
64 changed files with 260 additions and 328 deletions

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.base; package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour; import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemDescription.Palette; import com.simibubi.create.foundation.item.ItemDescription.Palette;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -44,6 +45,11 @@ public abstract class KineticBlock extends Block implements IRotate {
kineticTileEntity.preventSpeedUpdate = 2; kineticTileEntity.preventSpeedUpdate = 2;
} }
} }
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
ITE.onRemove(pState, pLevel, pPos, pNewState);
}
@Override @Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) { public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {

View file

@ -184,18 +184,13 @@ public class KineticTileEntity extends SmartTileEntity implements IHaveGoggleInf
} }
@Override @Override
public void setRemoved() { public void remove() {
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
if (!level.isClientSide) { if (!level.isClientSide) {
if (hasNetwork()) if (hasNetwork())
getOrCreateNetwork().remove(this); getOrCreateNetwork().remove(this);
detachKinetics(); detachKinetics();
} }
super.setRemovedNotDueToChunkUnload(); super.remove();
} }
@Override @Override

View file

@ -73,10 +73,10 @@ public abstract class BlockBreakingKineticTileEntity extends KineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.invalidate();
if (!level.isClientSide && destroyProgress != 0) if (!level.isClientSide && destroyProgress != 0)
level.destroyBlockProgress(breakerId, breakingPos, -1); level.destroyBlockProgress(breakerId, breakingPos, -1);
super.setRemoved();
} }
@Override @Override

View file

@ -112,8 +112,8 @@ public abstract class PortableStorageInterfaceTileEntity extends SmartTileEntity
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
invalidateCapability(); invalidateCapability();
} }

View file

@ -95,7 +95,7 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
} }
} }
if (state.hasBlockEntity() && state.getBlock() != newState.getBlock()) { if (state.hasBlockEntity() && !state.is(newState.getBlock())) {
MechanicalCrafterTileEntity crafter = CrafterHelper.getCrafter(worldIn, pos); MechanicalCrafterTileEntity crafter = CrafterHelper.getCrafter(worldIn, pos);
if (crafter != null) { if (crafter != null) {
if (crafter.covered) if (crafter.covered)
@ -121,9 +121,9 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
ConnectedInputHandler.toggleConnection(worldIn, pos, otherPos); ConnectedInputHandler.toggleConnection(worldIn, pos, otherPos);
} }
worldIn.removeBlockEntity(pos);
} }
super.onRemove(state, worldIn, pos, newState, isMoving);
} }
public static Pointing pointingFromFacing(Direction pointingFace, Direction blockFacing) { public static Pointing pointingFromFacing(Direction pointingFace, Direction blockFacing) {

View file

@ -215,9 +215,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.invalidate();
invSupplier.invalidate(); invSupplier.invalidate();
super.setRemoved();
} }
public int getCountDownSpeed() { public int getCountDownSpeed() {

View file

@ -47,17 +47,14 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
for (Direction d : Iterate.directions) { for (Direction d : Iterate.directions) {
if (d.getAxis() == state.getValue(AXIS)) if (d.getAxis() == state.getValue(AXIS))
continue; continue;
if (AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(worldIn.getBlockState(pos.relative(d)))) if (AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(worldIn.getBlockState(pos.relative(d))))
worldIn.setBlockAndUpdate(pos.relative(d), Blocks.AIR.defaultBlockState()); worldIn.removeBlock(pos.relative(d), isMoving);
} }
if (state.hasBlockEntity() && state.getBlock() != newState.getBlock()) { super.onRemove(state, worldIn, pos, newState, isMoving);
worldIn.removeBlockEntity(pos);
}
} }
public void updateControllers(BlockState state, Level world, BlockPos pos, Direction side) { public void updateControllers(BlockState state, Level world, BlockPos pos, Direction side) {

View file

@ -8,8 +8,6 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.content.contraptions.components.AssemblyOperatorUseContext; import com.simibubi.create.content.contraptions.components.AssemblyOperatorUseContext;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -61,20 +59,9 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements ITE<De
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasBlockEntity() && state.getBlock() != newState.getBlock()) { if (!isMoving && !state.is(newState.getBlock()))
withTileEntityDo(worldIn, pos, te -> { withTileEntityDo(worldIn, pos, DeployerTileEntity::discardPlayer);
if (te.player != null && !isMoving) { super.onRemove(state, worldIn, pos, newState, isMoving);
te.player.getInventory()
.dropAll();
te.overflowItems.forEach(itemstack -> te.player.drop(itemstack, true, false));
te.player.discard();
te.player = null;
}
});
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeBlockEntity(pos);
}
} }
@Override @Override

View file

@ -434,9 +434,19 @@ public class DeployerTileEntity extends KineticTileEntity {
return super.createRenderBoundingBox().inflate(3); return super.createRenderBoundingBox().inflate(3);
} }
public void discardPlayer() {
if (player == null)
return;
player.getInventory()
.dropAll();
overflowItems.forEach(itemstack -> player.drop(itemstack, true, false));
player.discard();
player = null;
}
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
if (invHandler != null) if (invHandler != null)
invHandler.invalidate(); invHandler.invalidate();
} }

View file

@ -36,14 +36,6 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
blockUpdate(stateIn, worldIn, pos); blockUpdate(stateIn, worldIn, pos);
} }
@Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
if (state.hasBlockEntity() && (state.getBlock() != p_196243_4_.getBlock() || !p_196243_4_.hasBlockEntity())) {
withTileEntityDo(world, pos, EncasedFanTileEntity::updateChute);
world.removeBlockEntity(pos);
}
}
@Override @Override
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) { boolean isMoving) {

View file

@ -84,6 +84,12 @@ public class EncasedFanTileEntity extends KineticTileEntity implements IAirCurre
return speed > 0 ? facing : facing.getOpposite(); return speed > 0 ? facing : facing.getOpposite();
} }
@Override
public void remove() {
super.remove();
updateChute();
}
@Override @Override
public boolean isSourceRemoved() { public boolean isSourceRemoved() {
return remove; return remove;

View file

@ -5,7 +5,6 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.KineticBlock; import com.simibubi.create.content.contraptions.base.KineticBlock;
import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -118,18 +117,6 @@ public class MillstoneBlock extends KineticBlock implements ITE<MillstoneTileEnt
itemEntity.setItem(remainder); itemEntity.setItem(remainder);
} }
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasBlockEntity() && state.getBlock() != newState.getBlock()) {
withTileEntityDo(worldIn, pos, te -> {
ItemHelper.dropContents(worldIn, pos, te.inputInv);
ItemHelper.dropContents(worldIn, pos, te.outputInv);
});
worldIn.removeBlockEntity(pos);
}
}
@Override @Override
public Axis getRotationAxis(BlockState state) { public Axis getRotationAxis(BlockState state) {
return Axis.Y; return Axis.Y;

View file

@ -6,6 +6,7 @@ import java.util.Optional;
import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.sound.SoundScapes; import com.simibubi.create.foundation.sound.SoundScapes;
import com.simibubi.create.foundation.sound.SoundScapes.AmbienceGroup; import com.simibubi.create.foundation.sound.SoundScapes.AmbienceGroup;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -116,10 +117,17 @@ public class MillstoneTileEntity extends KineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
capability.invalidate(); capability.invalidate();
} }
@Override
public void destroy() {
super.destroy();
ItemHelper.dropContents(level, worldPosition, inputInv);
ItemHelper.dropContents(level, worldPosition, outputInv);
}
private void process() { private void process() {
RecipeWrapper inventoryIn = new RecipeWrapper(inputInv); RecipeWrapper inventoryIn = new RecipeWrapper(inputInv);

View file

@ -7,9 +7,6 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock;
import com.simibubi.create.content.contraptions.components.actors.DrillBlock; import com.simibubi.create.content.contraptions.components.actors.DrillBlock;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -102,16 +99,6 @@ public class SawBlock extends DirectionalAxisKineticBlock implements ITE<SawTile
: super.hasShaftTowards(world, pos, state, face); : super.hasShaftTowards(world, pos, state, face);
} }
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (!state.hasBlockEntity() || state.getBlock() == newState.getBlock())
return;
withTileEntityDo(worldIn, pos, te -> ItemHelper.dropContents(worldIn, pos, te.inventory));
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeBlockEntity(pos);
}
@Override @Override
public Class<SawTileEntity> getTileEntityClass() { public Class<SawTileEntity> getTileEntityClass() {
return SawTileEntity.class; return SawTileEntity.class;

View file

@ -255,9 +255,15 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.invalidate();
invProvider.invalidate(); invProvider.invalidate();
super.setRemoved(); }
@Override
public void destroy() {
super.destroy();
ItemHelper.dropContents(level, worldPosition, inventory);
} }
@Override @Override

View file

@ -134,11 +134,11 @@ public class SteamEngineTileEntity extends SmartTileEntity implements IHaveGoggl
} }
@Override @Override
protected void setRemovedNotDueToChunkUnload() { public void remove() {
PoweredShaftTileEntity shaft = getShaft(); PoweredShaftTileEntity shaft = getShaft();
if (shaft != null) if (shaft != null)
shaft.remove(worldPosition); shaft.remove(worldPosition);
super.setRemovedNotDueToChunkUnload(); super.remove();
} }
@Override @Override

View file

@ -193,8 +193,7 @@ public class WhistleBlock extends Block implements ITE<WhistleTileEntity>, IWren
@Override @Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) { public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) ITE.onRemove(pState, pLevel, pPos, pNewState);
pLevel.removeBlockEntity(pPos);
FluidTankBlock.updateBoilerState(pState, pLevel, pPos.relative(getAttachedDirection(pState))); FluidTankBlock.updateBoilerState(pState, pLevel, pPos.relative(getAttachedDirection(pState)));
} }

View file

@ -372,15 +372,10 @@ public class ClockworkBearingTileEntity extends KineticTileEntity
} }
@Override @Override
public void setRemoved() { public void remove() {
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
if (!level.isClientSide) if (!level.isClientSide)
disassemble(); disassemble();
super.setRemovedNotDueToChunkUnload(); super.remove();
} }
@Override @Override

View file

@ -59,15 +59,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity
} }
@Override @Override
public void setRemoved() { public void remove() {
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
if (!level.isClientSide) if (!level.isClientSide)
disassemble(); disassemble();
super.setRemovedNotDueToChunkUnload(); super.remove();
} }
@Override @Override

View file

@ -174,16 +174,11 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity
} }
@Override @Override
public void setRemoved() { public void remove() {
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
this.remove = true; this.remove = true;
if (!level.isClientSide) if (!level.isClientSide)
disassemble(); disassemble();
super.setRemovedNotDueToChunkUnload(); super.remove();
} }
@Override @Override

View file

@ -47,18 +47,17 @@ public class PulleyBlock extends HorizontalAxisKineticBlock implements ITE<Pulle
} }
} }
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.getBlock() != newState.getBlock()) { super.onRemove(state, worldIn, pos, newState, isMoving);
if (!worldIn.isClientSide) { if (state.is(newState.getBlock()))
BlockState below = worldIn.getBlockState(pos.below()); return;
if (below.getBlock() instanceof RopeBlockBase) if (worldIn.isClientSide)
worldIn.destroyBlock(pos.below(), true); return;
} BlockState below = worldIn.getBlockState(pos.below());
if (state.hasBlockEntity()) if (below.getBlock() instanceof RopeBlockBase)
worldIn.removeBlockEntity(pos); worldIn.destroyBlock(pos.below(), true);
} }
}
public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn, public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn,
BlockHitResult hit) { BlockHitResult hit) {

View file

@ -157,11 +157,10 @@ public class PumpBlock extends DirectionalKineticBlock
@Override @Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
boolean blockTypeChanged = state.getBlock() != newState.getBlock(); boolean blockTypeChanged = !state.is(newState.getBlock());
if (blockTypeChanged && !world.isClientSide) if (blockTypeChanged && !world.isClientSide)
FluidPropagator.propagateChangedPipe(world, pos, state); FluidPropagator.propagateChangedPipe(world, pos, state);
if (state.hasBlockEntity() && (blockTypeChanged || !newState.hasBlockEntity())) super.onRemove(state, world, pos, newState, isMoving);
world.removeBlockEntity(pos);
} }
@Override @Override

View file

@ -4,14 +4,12 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock; import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock; import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader; import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -71,18 +69,7 @@ public class HosePulleyBlock extends HorizontalKineticBlock implements ITE<HoseP
} }
return prefferedSide == null ? null : prefferedSide.getOpposite(); return prefferedSide == null ? null : prefferedSide.getOpposite();
} }
@Override
public void onRemove(BlockState p_196243_1_, Level world, BlockPos pos, BlockState p_196243_4_,
boolean p_196243_5_) {
if (p_196243_1_.hasBlockEntity()
&& (p_196243_1_.getBlock() != p_196243_4_.getBlock() || !p_196243_4_.hasBlockEntity())) {
TileEntityBehaviour.destroy(world, pos, FluidDrainingBehaviour.TYPE);
TileEntityBehaviour.destroy(world, pos, FluidFillingBehaviour.TYPE);
world.removeBlockEntity(pos);
}
}
@Override @Override
public Class<HosePulleyTileEntity> getTileEntityClass() { public Class<HosePulleyTileEntity> getTileEntityClass() {
return HosePulleyTileEntity.class; return HosePulleyTileEntity.class;

View file

@ -166,8 +166,8 @@ public class HosePulleyTileEntity extends KineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
capability.invalidate(); capability.invalidate();
} }

View file

@ -252,8 +252,8 @@ public class ItemDrainTileEntity extends SmartTileEntity implements IHaveGoggleI
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
for (LazyOptional<ItemDrainItemHandler> lazyOptional : itemHandlers.values()) for (LazyOptional<ItemDrainItemHandler> lazyOptional : itemHandlers.values())
lazyOptional.invalidate(); lazyOptional.invalidate();
} }

View file

@ -90,11 +90,10 @@ public class FluidValveBlock extends DirectionalAxisKineticBlock
@Override @Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
boolean blockTypeChanged = state.getBlock() != newState.getBlock(); boolean blockTypeChanged = !state.is(newState.getBlock());
if (blockTypeChanged && !world.isClientSide) if (blockTypeChanged && !world.isClientSide)
FluidPropagator.propagateChangedPipe(world, pos, state); FluidPropagator.propagateChangedPipe(world, pos, state);
if (state.hasBlockEntity() && (blockTypeChanged || !newState.hasBlockEntity())) super.onRemove(state, world, pos, newState, isMoving);
world.removeBlockEntity(pos);
} }
@Override @Override

View file

@ -485,8 +485,8 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
} }
@Override @Override

View file

@ -13,7 +13,6 @@ import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -170,15 +169,7 @@ public class BasinBlock extends Block implements ITE<BasinTileEntity>, IWrenchab
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (!state.hasBlockEntity() || state.getBlock() == newState.getBlock()) ITE.onRemove(state, worldIn, pos, newState);
return;
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
withTileEntityDo(worldIn, pos, te -> {
ItemHelper.dropContents(worldIn, pos, te.inputInventory);
ItemHelper.dropContents(worldIn, pos, te.outputInventory);
te.spoutputBuffer.forEach(is -> Block.popResource(worldIn, pos, is));
});
worldIn.removeBlockEntity(pos);
} }
@Override @Override

View file

@ -19,6 +19,7 @@ import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel; import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.fluid.CombinedTankWrapper; import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.item.SmartInventory;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -193,22 +194,30 @@ public class BasinTileEntity extends SmartTileEntity implements IHaveGoggleInfor
visualizedOutputItems.clear(); visualizedOutputItems.clear();
visualizedOutputFluids.clear(); visualizedOutputFluids.clear();
} }
@Override
public void destroy() {
super.destroy();
ItemHelper.dropContents(level, worldPosition, inputInventory);
ItemHelper.dropContents(level, worldPosition, outputInventory);
spoutputBuffer.forEach(is -> Block.popResource(level, worldPosition, is));
}
@Override
public void remove() {
super.remove();
onEmptied();
}
public void onEmptied() { public void onEmptied() {
getOperator().ifPresent(te -> te.basinRemoved = true); getOperator().ifPresent(te -> te.basinRemoved = true);
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.invalidate();
itemCapability.invalidate(); itemCapability.invalidate();
fluidCapability.invalidate(); fluidCapability.invalidate();
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
onEmptied();
super.setRemovedNotDueToChunkUnload();
} }
@Nonnull @Nonnull

View file

@ -455,6 +455,8 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
@Override @Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
super.onRemove(state, world, pos, newState, isMoving);
if (world.isClientSide) if (world.isClientSide)
return; return;
if (state.getBlock() == newState.getBlock()) if (state.getBlock() == newState.getBlock())
@ -462,15 +464,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
if (isMoving) if (isMoving)
return; return;
BlockEntity te = world.getBlockEntity(pos);
if (te instanceof BeltTileEntity) {
BeltTileEntity beltTileEntity = (BeltTileEntity) te;
if (beltTileEntity.isController())
beltTileEntity.getInventory()
.ejectAll();
world.removeBlockEntity(pos);
}
// Destroy chain // Destroy chain
for (boolean forward : Iterate.trueAndFalse) { for (boolean forward : Iterate.trueAndFalse) {
BlockPos currentPos = nextSegmentPosition(state, pos, forward); BlockPos currentPos = nextSegmentPosition(state, pos, forward);

View file

@ -192,8 +192,15 @@ public class BeltTileEntity extends KineticTileEntity {
} }
@Override @Override
public void setRemoved() { public void destroy() {
super.setRemoved(); super.destroy();
if (isController())
getInventory().ejectAll();
}
@Override
public void invalidate() {
super.invalidate();
itemHandler.invalidate(); itemHandler.invalidate();
} }

View file

@ -35,7 +35,6 @@ public abstract class AbstractSimpleShaftBlock extends AbstractShaftBlock implem
} }
@Override @Override
@SuppressWarnings("deprecation")
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
if (state != newState && !isMoving) if (state != newState && !isMoving)
removeBracket(world, pos, true).ifPresent(stack -> Block.popResource(world, pos, stack)); removeBracket(world, pos, true).ifPresent(stack -> Block.popResource(world, pos, stack));

View file

@ -87,8 +87,8 @@ public class ToolboxTileEntity extends SmartTileEntity implements MenuProvider,
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
ToolboxHandler.onUnload(this); ToolboxHandler.onUnload(this);
} }

View file

@ -1,7 +1,5 @@
package com.simibubi.create.content.curiosities.weapons; package com.simibubi.create.content.curiosities.weapons;
import static com.simibubi.create.content.curiosities.weapons.PotatoProjectileRenderMode.entityRandom;
import com.jozufozu.flywheel.util.transform.TransformStack; import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;

View file

@ -17,7 +17,6 @@ import com.simibubi.create.foundation.utility.WorldHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
public class RedstoneLinkNetworkHandler { public class RedstoneLinkNetworkHandler {
@ -112,10 +111,7 @@ public class RedstoneLinkNetworkHandler {
iterator.remove(); iterator.remove();
continue; continue;
} }
if (!(world instanceof Level level) || !level.isLoaded(other.getLocation())) {
iterator.remove();
continue;
}
if (!withinRange(actor, other)) if (!withinRange(actor, other))
continue; continue;

View file

@ -56,8 +56,8 @@ public class BeltTunnelTileEntity extends SmartTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
cap.invalidate(); cap.invalidate();
} }

View file

@ -3,8 +3,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
import java.util.List; import java.util.List;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -16,7 +15,6 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -61,16 +59,7 @@ public class BrassTunnelBlock extends BeltTunnelBlock {
@Override @Override
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasBlockEntity() && (state.getBlock() != newState.getBlock() || !newState.hasBlockEntity())) { ITE.onRemove(state, level, pos, newState);
TileEntityBehaviour.destroy(level, pos, FilteringBehaviour.TYPE);
withTileEntityDo(level, pos, te -> {
if (!(te instanceof BrassTunnelTileEntity btte))
return;
Block.popResource(level, pos, btte.stackToDistribute);
btte.stackEnteredFrom = null;
});
level.removeBlockEntity(pos);
}
} }
} }

View file

@ -46,6 +46,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -714,9 +715,16 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity implements IHave
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.invalidate();
tunnelCapability.invalidate(); tunnelCapability.invalidate();
super.setRemoved(); }
@Override
public void destroy() {
super.destroy();
Block.popResource(level, worldPosition, stackToDistribute);
stackEnteredFrom = null;
} }
@Override @Override

View file

@ -10,7 +10,6 @@ import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.block.render.ReducedDestroyEffects; import com.simibubi.create.foundation.block.render.ReducedDestroyEffects;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
@ -132,14 +131,10 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
} }
@Override @Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) { public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
boolean differentBlock = state.getBlock() != p_196243_4_.getBlock(); ITE.onRemove(state, world, pos, newState);
if (state.hasBlockEntity() && (differentBlock || !p_196243_4_.hasBlockEntity())) {
TileEntityBehaviour.destroy(world, pos, FilteringBehaviour.TYPE); if (isMoving || state.is(newState.getBlock()))
withTileEntityDo(world, pos, c -> c.onRemoved(state));
world.removeBlockEntity(pos);
}
if (p_196243_5_ || !differentBlock)
return; return;
updateDiagonalNeighbour(state, world, pos); updateDiagonalNeighbour(state, world, pos);

View file

@ -509,10 +509,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved();
if (lazyHandler != null) if (lazyHandler != null)
lazyHandler.invalidate(); lazyHandler.invalidate();
super.invalidate();
} }
@Override @Override
@ -557,8 +557,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
return (Mth.clamp(motion, -maxItemSpeed, maxItemSpeed) + (motion <= 0 ? -gravity : 0)) / 20f; return (Mth.clamp(motion, -maxItemSpeed, maxItemSpeed) + (motion <= 0 ? -gravity : 0)) / 20f;
} }
public void onRemoved(BlockState chuteState) { @Override
ChuteTileEntity targetChute = getTargetChute(chuteState); public void destroy() {
super.destroy();
ChuteTileEntity targetChute = getTargetChute(getBlockState());
List<ChuteTileEntity> inputChutes = getInputChutes(); List<ChuteTileEntity> inputChutes = getInputChutes();
if (!item.isEmpty() && level != null) if (!item.isEmpty() && level != null)
Containers.dropItemStack(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), item); Containers.dropItemStack(level, worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), item);

View file

@ -32,6 +32,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.world.Containers; import net.minecraft.world.Containers;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
@ -199,7 +200,19 @@ public class DepotBehaviour extends TileEntityBehaviour {
} }
@Override @Override
public void remove() { public void destroy() {
super.destroy();
Level level = getWorld();
BlockPos pos = getPos();
ItemHelper.dropContents(level, pos, processingOutputBuffer);
for (TransportedItemStack transportedItemStack : incoming)
Block.popResource(level, pos, transportedItemStack.stack);
if (!getHeldItemStack().isEmpty())
Block.popResource(level, pos, getHeldItemStack());
}
@Override
public void unload() {
if (lazyItemHandler != null) if (lazyItemHandler != null)
lazyItemHandler.invalidate(); lazyItemHandler.invalidate();
} }

View file

@ -55,7 +55,7 @@ public class DepotBlock extends Block implements ITE<DepotTileEntity>, IWrenchab
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
SharedDepotBlockMethods.onReplaced(state, worldIn, pos, newState, isMoving); ITE.onRemove(state, worldIn, pos, newState);
} }
@Override @Override

View file

@ -125,12 +125,6 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
return SharedDepotBlockMethods.onUse(state, world, pos, player, hand, ray); return SharedDepotBlockMethods.onUse(state, world, pos, player, hand, ray);
} }
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
withTileEntityDo(worldIn, pos, EjectorTileEntity::dropFlyingItems);
SharedDepotBlockMethods.onReplaced(state, worldIn, pos, newState, isMoving);
}
@Override @Override
public Axis getRotationAxis(BlockState state) { public Axis getRotationAxis(BlockState state) {
return state.getValue(HORIZONTAL_FACING) return state.getValue(HORIZONTAL_FACING)

View file

@ -470,6 +470,12 @@ public class EjectorTileEntity extends KineticTileEntity {
return launcher.getGlobalVelocity(time, getFacing().getOpposite(), worldPosition) return launcher.getGlobalVelocity(time, getFacing().getOpposite(), worldPosition)
.scale(.5f); .scale(.5f);
} }
@Override
public void destroy() {
super.destroy();
dropFlyingItems();
}
public void dropFlyingItems() { public void dropFlyingItems() {
for (IntAttached<ItemStack> intAttached : launchedItems) { for (IntAttached<ItemStack> intAttached : launchedItems) {

View file

@ -4,7 +4,6 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
@ -13,7 +12,6 @@ import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -76,22 +74,6 @@ public class SharedDepotBlockMethods {
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
} }
public static void onReplaced(BlockState state, Level worldIn, BlockPos pos, BlockState newState,
boolean isMoving) {
if (!state.hasBlockEntity() || state.getBlock() == newState.getBlock())
return;
DepotBehaviour behaviour = get(worldIn, pos);
if (behaviour == null)
return;
ItemHelper.dropContents(worldIn, pos, behaviour.processingOutputBuffer);
for (TransportedItemStack transportedItemStack : behaviour.incoming)
Containers.dropItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), transportedItemStack.stack);
if (!behaviour.getHeldItemStack()
.isEmpty())
Containers.dropItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), behaviour.getHeldItemStack());
worldIn.removeBlockEntity(pos);
}
public static void onLanded(BlockGetter worldIn, Entity entityIn) { public static void onLanded(BlockGetter worldIn, Entity entityIn) {
if (!(entityIn instanceof ItemEntity)) if (!(entityIn instanceof ItemEntity))
return; return;

View file

@ -128,13 +128,8 @@ public abstract class AbstractFunnelBlock extends Block implements ITE<FunnelTil
protected abstract Direction getFacing(BlockState state); protected abstract Direction getFacing(BlockState state);
@Override @Override
public void onRemove(BlockState p_196243_1_, Level p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_, public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
boolean p_196243_5_) { ITE.onRemove(state, world, pos, newState);
if (p_196243_1_.hasBlockEntity() && (p_196243_1_.getBlock() != p_196243_4_.getBlock() && !isFunnel(p_196243_4_)
|| !p_196243_4_.hasBlockEntity())) {
TileEntityBehaviour.destroy(p_196243_2_, p_196243_3_, FilteringBehaviour.TYPE);
p_196243_2_.removeBlockEntity(p_196243_3_);
}
} }
@Override @Override

View file

@ -36,8 +36,8 @@ public class CreativeCrateTileEntity extends CrateTileEntity {
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
if (itemHandler != null) if (itemHandler != null)
itemHandler.invalidate(); itemHandler.invalidate();
} }

View file

@ -12,7 +12,6 @@ import com.simibubi.create.foundation.block.ITE;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.Axis;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
@ -81,19 +80,6 @@ public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity>, ICogWh
return AllTileEntities.MECHANICAL_ARM.get(); return AllTileEntities.MECHANICAL_ARM.get();
} }
@Override
public void onRemove(BlockState p_196243_1_, Level world, BlockPos pos, BlockState p_196243_4_,
boolean p_196243_5_) {
if (p_196243_1_.hasBlockEntity()
&& (p_196243_1_.getBlock() != p_196243_4_.getBlock() || !p_196243_4_.hasBlockEntity())) {
withTileEntityDo(world, pos, te -> {
if (!te.heldItem.isEmpty())
Containers.dropItemStack(world, pos.getX(), pos.getY(), pos.getZ(), te.heldItem);
});
world.removeBlockEntity(pos);
}
}
@Override @Override
public InteractionResult use(BlockState p_225533_1_, Level world, BlockPos pos, Player player, public InteractionResult use(BlockState p_225533_1_, Level world, BlockPos pos, Player player,
InteractionHand p_225533_5_, BlockHitResult p_225533_6_) { InteractionHand p_225533_5_, BlockHitResult p_225533_6_) {

View file

@ -37,6 +37,7 @@ import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.JukeboxBlock; import net.minecraft.world.level.block.JukeboxBlock;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
@ -215,6 +216,13 @@ public class ArmTileEntity extends KineticTileEntity implements ITransformableTE
return hasLevel() && state.getOptionalValue(ArmBlock.CEILING) return hasLevel() && state.getOptionalValue(ArmBlock.CEILING)
.orElse(false); .orElse(false);
} }
@Override
public void destroy() {
super.destroy();
if (!heldItem.isEmpty())
Block.popResource(level, worldPosition, heldItem);
}
@Nullable @Nullable
private ArmInteractionPoint getTargetedInteractionPoint() { private ArmInteractionPoint getTargetedInteractionPoint() {

View file

@ -126,10 +126,7 @@ public class ContentObserverBlock extends HorizontalDirectionalBlock implements
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasBlockEntity() && state.getBlock() != newState.getBlock()) { ITE.onRemove(state, worldIn, pos, newState);
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
worldIn.removeBlockEntity(pos);
}
} }
@Override @Override

View file

@ -308,8 +308,7 @@ public class FlapDisplayBlock extends HorizontalKineticBlock
@Override @Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) { public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
pLevel.removeBlockEntity(pPos);
if (pIsMoving || pNewState.getBlock() == this) if (pIsMoving || pNewState.getBlock() == this)
return; return;
for (Direction d : Iterate.directionsInAxis(getConnectionAxis(pState))) { for (Direction d : Iterate.directionsInAxis(getConnectionAxis(pState))) {

View file

@ -234,10 +234,10 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
} }
@Override @Override
public void remove() { public void destroy() {
super.destroy();
if (edgePoint != null && !getWorld().isClientSide) if (edgePoint != null && !getWorld().isClientSide)
edgePoint.tileRemoved(getPos(), getTargetDirection() == AxisDirection.POSITIVE); edgePoint.tileRemoved(getPos(), getTargetDirection() == AxisDirection.POSITIVE);
super.remove();
} }
@Override @Override

View file

@ -3,8 +3,6 @@ package com.simibubi.create.content.logistics.trains.management.edgePoint.observ
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.wrench.IWrenchable; import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -57,11 +55,8 @@ public class TrackObserverBlock extends Block implements ITE<TrackObserverTileEn
} }
@Override @Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) { ITE.onRemove(state, worldIn, pos, newState);
TileEntityBehaviour.destroy(pLevel, pPos, FilteringBehaviour.TYPE);
pLevel.removeBlockEntity(pPos);
}
} }
} }

View file

@ -100,7 +100,7 @@ public class StationBlock extends Block implements ITE<StationTileEntity>, IWren
@Override @Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) { public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
SharedDepotBlockMethods.onReplaced(state, worldIn, pos, newState, isMoving); ITE.onRemove(state, worldIn, pos, newState);
} }
@Override @Override

View file

@ -438,11 +438,10 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
} }
@Override @Override
protected void setRemovedNotDueToChunkUnload() { public void remove() {
assemblyAreas.get(level) assemblyAreas.get(level)
.remove(worldPosition); .remove(worldPosition);
super.remove();
super.setRemovedNotDueToChunkUnload();
} }
public void assemble(UUID playerUUID) { public void assemble(UUID playerUUID) {

View file

@ -9,13 +9,12 @@ import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
public class StationUnloadedCondition extends ScheduleWaitCondition { public class StationUnloadedCondition extends ScheduleWaitCondition {
@Override @Override

View file

@ -269,15 +269,15 @@ public class TrackTileEntity extends SmartTileEntity implements ITransformableTE
} }
@Override @Override
public void setRemoved() { public void invalidate() {
super.setRemoved(); super.invalidate();
if (level.isClientSide) if (level.isClientSide)
removeFromCurveInteraction(); removeFromCurveInteraction();
} }
@Override @Override
protected void setRemovedNotDueToChunkUnload() { public void remove() {
super.setRemovedNotDueToChunkUnload(); super.remove();
for (BezierConnection connection : connections.values()) for (BezierConnection connection : connections.values())
manageFakeTracksAlong(connection, true); manageFakeTracksAlong(connection, true);

View file

@ -34,6 +34,21 @@ public interface ITE<T extends BlockEntity> extends EntityBlock {
.orElse(InteractionResult.PASS); .orElse(InteractionResult.PASS);
} }
/**
* if the ITE is bound to a SmartTileEntity, which implements destroy(),<br>
* call this method in BlockBehaviour::onRemove (replace super call)
*/
public static void onRemove(BlockState blockState, Level level, BlockPos pos, BlockState newBlockState) {
if (!blockState.hasBlockEntity())
return;
if (blockState.is(newBlockState.getBlock()) && newBlockState.hasBlockEntity())
return;
BlockEntity blockEntity = level.getBlockEntity(pos);
if (blockEntity instanceof SmartTileEntity ste)
ste.destroy();
level.removeBlockEntity(pos);
}
default Optional<T> getTileEntityOptional(BlockGetter world, BlockPos pos) { default Optional<T> getTileEntityOptional(BlockGetter world, BlockPos pos) {
return Optional.ofNullable(getTileEntity(world, pos)); return Optional.ofNullable(getTileEntity(world, pos));
} }

View file

@ -3,14 +3,10 @@ package com.simibubi.create.foundation.data;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.ponder.PonderLocalization; import com.simibubi.create.foundation.ponder.PonderLocalization;
import com.simibubi.create.foundation.utility.FilesHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import java.util.List;
public enum AllLangPartials implements ILangPartial { public enum AllLangPartials implements ILangPartial {
ADVANCEMENTS("Advancements", AllAdvancements::provideLangEntries), ADVANCEMENTS("Advancements", AllAdvancements::provideLangEntries),

View file

@ -5,8 +5,6 @@ import com.google.gson.JsonElement;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.FilesHelper; import com.simibubi.create.foundation.utility.FilesHelper;
import java.util.List;
public interface ILangPartial { public interface ILangPartial {
String getDisplay(); String getDisplay();

View file

@ -33,6 +33,7 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
private boolean firstNbtRead = true; private boolean firstNbtRead = true;
protected int lazyTickRate; protected int lazyTickRate;
protected int lazyTickCounter; protected int lazyTickCounter;
private boolean chunkUnloaded;
// Used for simulating this TE in a client-only setting // Used for simulating this TE in a client-only setting
private boolean virtualMode; private boolean virtualMode;
@ -118,32 +119,37 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
read(tag, false); read(tag, false);
} }
/*
* TODO: Remove this hack once this issue is resolved:
* https://github.com/MinecraftForge/MinecraftForge/issues/8302 Once the PR
* linked in the issue is accepted, we should use the new method for determining
* whether setRemoved was called due to a chunk unload or not, and remove this
* volatile workaround
*/
private boolean unloaded;
@Override @Override
public void onChunkUnloaded() { public void onChunkUnloaded() {
super.onChunkUnloaded(); super.onChunkUnloaded();
unloaded = true; chunkUnloaded = true;
}
protected void setRemovedNotDueToChunkUnload() {
forEachBehaviour(TileEntityBehaviour::remove);
} }
@Override @Override
public void setRemoved() { public final void setRemoved() {
super.setRemoved(); super.setRemoved();
if (!chunkUnloaded)
remove();
invalidate();
}
if (!unloaded) { /**
setRemovedNotDueToChunkUnload(); * Block destroyed or Chunk unloaded. Usually invalidates capabilities
} */
public void invalidate() {
forEachBehaviour(TileEntityBehaviour::unload);
}
/**
* Block destroyed or picked up by a contraption. Usually detaches kinetics
*/
public void remove() {}
/**
* Block destroyed or replaced. Requires Block to call ITE::onRemove
*/
public void destroy() {
forEachBehaviour(TileEntityBehaviour::destroy);
} }
@Override @Override
@ -186,7 +192,7 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
protected void removeBehaviour(BehaviourType<?> type) { protected void removeBehaviour(BehaviourType<?> type) {
TileEntityBehaviour remove = behaviours.remove(type); TileEntityBehaviour remove = behaviours.remove(type);
if (remove != null) { if (remove != null) {
remove.remove(); remove.unload();
} }
} }
@ -202,6 +208,10 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
public boolean isVirtual() { public boolean isVirtual() {
return virtualMode; return virtualMode;
} }
public boolean isChunkUnloaded() {
return chunkUnloaded;
}
@Override @Override
public boolean canPlayerUse(Player player) { public boolean canPlayerUse(Player player) {

View file

@ -61,13 +61,15 @@ public abstract class TileEntityBehaviour {
} }
public void remove() { /**
* Block destroyed or Chunk unloaded. Usually invalidates capabilities
*/
public void unload() {}
} /**
* Block destroyed or removed. Requires block to call ITE::onRemove
public void destroy() { */
public void destroy() {}
}
public void setLazyTickRate(int slowTickRate) { public void setLazyTickRate(int slowTickRate) {
this.lazyTickRate = slowTickRate; this.lazyTickRate = slowTickRate;
@ -96,13 +98,6 @@ public abstract class TileEntityBehaviour {
return get(te, type); return get(te, type);
} }
public static <T extends TileEntityBehaviour> void destroy(BlockGetter reader, BlockPos pos,
BehaviourType<T> type) {
T behaviour = get(reader.getBlockEntity(pos), type);
if (behaviour != null)
behaviour.destroy();
}
public static <T extends TileEntityBehaviour> T get(BlockEntity te, BehaviourType<T> type) { public static <T extends TileEntityBehaviour> T get(BlockEntity te, BehaviourType<T> type) {
if (te == null) if (te == null)
return null; return null;

View file

@ -136,8 +136,8 @@ public class SmartFluidTankBehaviour extends TileEntityBehaviour {
} }
@Override @Override
public void remove() { public void unload() {
super.remove(); super.unload();
capability.invalidate(); capability.invalidate();
} }

View file

@ -19,6 +19,7 @@ import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -115,8 +116,8 @@ public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinka
} }
@Override @Override
public void remove() { public void unload() {
super.remove(); super.unload();
if (getWorld().isClientSide) if (getWorld().isClientSide)
return; return;
getHandler().removeFromNetwork(getWorld(), this); getHandler().removeFromNetwork(getWorld(), this);
@ -208,7 +209,15 @@ public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinka
@Override @Override
public boolean isAlive() { public boolean isAlive() {
return !tileEntity.isRemoved() && getWorld().getBlockEntity(getPos()) == tileEntity; Level level = getWorld();
BlockPos pos = getPos();
if (tileEntity.isChunkUnloaded())
return false;
if (tileEntity.isRemoved())
return false;
if (!level.isLoaded(pos))
return false;
return level.getBlockEntity(pos) == tileEntity;
} }
@Override @Override