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;
import com.simibubi.create.foundation.advancement.AdvancementBehaviour;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import net.minecraft.core.BlockPos;
@ -44,6 +45,11 @@ public abstract class KineticBlock extends Block implements IRotate {
kineticTileEntity.preventSpeedUpdate = 2;
}
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
ITE.onRemove(pState, pLevel, pPos, pNewState);
}
@Override
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
public void setRemoved() {
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
public void remove() {
if (!level.isClientSide) {
if (hasNetwork())
getOrCreateNetwork().remove(this);
detachKinetics();
}
super.setRemovedNotDueToChunkUnload();
super.remove();
}
@Override

View File

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

View File

@ -112,8 +112,8 @@ public abstract class PortableStorageInterfaceTileEntity extends SmartTileEntity
}
@Override
public void setRemoved() {
super.setRemoved();
public void invalidate() {
super.invalidate();
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);
if (crafter != null) {
if (crafter.covered)
@ -121,9 +121,9 @@ public class MechanicalCrafterBlock extends HorizontalKineticBlock
ConnectedInputHandler.toggleConnection(worldIn, pos, otherPos);
}
worldIn.removeBlockEntity(pos);
}
super.onRemove(state, worldIn, pos, newState, isMoving);
}
public static Pointing pointingFromFacing(Direction pointingFace, Direction blockFacing) {

View File

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

View File

@ -47,17 +47,14 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
for (Direction d : Iterate.directions) {
if (d.getAxis() == state.getValue(AXIS))
continue;
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()) {
worldIn.removeBlockEntity(pos);
}
super.onRemove(state, worldIn, pos, newState, isMoving);
}
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.components.AssemblyOperatorUseContext;
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.core.BlockPos;
@ -61,20 +59,9 @@ public class DeployerBlock extends DirectionalAxisKineticBlock implements ITE<De
@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 -> {
if (te.player != null && !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);
}
if (!isMoving && !state.is(newState.getBlock()))
withTileEntityDo(worldIn, pos, DeployerTileEntity::discardPlayer);
super.onRemove(state, worldIn, pos, newState, isMoving);
}
@Override

View File

@ -434,9 +434,19 @@ public class DeployerTileEntity extends KineticTileEntity {
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
public void setRemoved() {
super.setRemoved();
public void invalidate() {
super.invalidate();
if (invHandler != null)
invHandler.invalidate();
}

View File

@ -36,14 +36,6 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
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
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {

View File

@ -84,6 +84,12 @@ public class EncasedFanTileEntity extends KineticTileEntity implements IAirCurre
return speed > 0 ? facing : facing.getOpposite();
}
@Override
public void remove() {
super.remove();
updateChute();
}
@Override
public boolean isSourceRemoved() {
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.relays.elementary.ICogWheel;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
@ -118,18 +117,6 @@ public class MillstoneBlock extends KineticBlock implements ITE<MillstoneTileEnt
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
public Axis getRotationAxis(BlockState state) {
return Axis.Y;

View File

@ -6,6 +6,7 @@ import java.util.Optional;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
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.AmbienceGroup;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -116,10 +117,17 @@ public class MillstoneTileEntity extends KineticTileEntity {
}
@Override
public void setRemoved() {
super.setRemoved();
public void invalidate() {
super.invalidate();
capability.invalidate();
}
@Override
public void destroy() {
super.destroy();
ItemHelper.dropContents(level, worldPosition, inputInv);
ItemHelper.dropContents(level, worldPosition, outputInv);
}
private void process() {
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.components.actors.DrillBlock;
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.core.BlockPos;
@ -102,16 +99,6 @@ public class SawBlock extends DirectionalAxisKineticBlock implements ITE<SawTile
: 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
public Class<SawTileEntity> getTileEntityClass() {
return SawTileEntity.class;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -157,11 +157,10 @@ public class PumpBlock extends DirectionalKineticBlock
@Override
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)
FluidPropagator.propagateChangedPipe(world, pos, state);
if (state.hasBlockEntity() && (blockTypeChanged || !newState.hasBlockEntity()))
world.removeBlockEntity(pos);
super.onRemove(state, world, pos, newState, isMoving);
}
@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.fluids.pipes.FluidPipeBlock;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType;
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();
}
@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
public Class<HosePulleyTileEntity> getTileEntityClass() {
return HosePulleyTileEntity.class;

View File

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

View File

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

View File

@ -90,11 +90,10 @@ public class FluidValveBlock extends DirectionalAxisKineticBlock
@Override
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)
FluidPropagator.propagateChangedPipe(world, pos, state);
if (state.hasBlockEntity() && (blockTypeChanged || !newState.hasBlockEntity()))
world.removeBlockEntity(pos);
super.onRemove(state, world, pos, newState, isMoving);
}
@Override

View File

@ -485,8 +485,8 @@ public class FluidTankTileEntity extends SmartTileEntity implements IHaveGoggleI
}
@Override
public void setRemoved() {
super.setRemoved();
public void invalidate() {
super.invalidate();
}
@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.tileEntity.TileEntityBehaviour;
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.Direction;
@ -170,15 +169,7 @@ public class BasinBlock extends Block implements ITE<BasinTileEntity>, IWrenchab
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
if (!state.hasBlockEntity() || state.getBlock() == newState.getBlock())
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);
ITE.onRemove(state, worldIn, pos, newState);
}
@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.HeatLevel;
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.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -193,22 +194,30 @@ public class BasinTileEntity extends SmartTileEntity implements IHaveGoggleInfor
visualizedOutputItems.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() {
getOperator().ifPresent(te -> te.basinRemoved = true);
}
@Override
public void setRemoved() {
public void invalidate() {
super.invalidate();
itemCapability.invalidate();
fluidCapability.invalidate();
super.setRemoved();
}
@Override
protected void setRemovedNotDueToChunkUnload() {
onEmptied();
super.setRemovedNotDueToChunkUnload();
}
@Nonnull

View File

@ -455,6 +455,8 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
@Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
super.onRemove(state, world, pos, newState, isMoving);
if (world.isClientSide)
return;
if (state.getBlock() == newState.getBlock())
@ -462,15 +464,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
if (isMoving)
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
for (boolean forward : Iterate.trueAndFalse) {
BlockPos currentPos = nextSegmentPosition(state, pos, forward);

View File

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

View File

@ -35,7 +35,6 @@ public abstract class AbstractSimpleShaftBlock extends AbstractShaftBlock implem
}
@Override
@SuppressWarnings("deprecation")
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
if (state != newState && !isMoving)
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
public void setRemoved() {
super.setRemoved();
public void invalidate() {
super.invalidate();
ToolboxHandler.onUnload(this);
}

View File

@ -1,7 +1,5 @@
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.mojang.blaze3d.vertex.PoseStack;
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.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
public class RedstoneLinkNetworkHandler {
@ -112,10 +111,7 @@ public class RedstoneLinkNetworkHandler {
iterator.remove();
continue;
}
if (!(world instanceof Level level) || !level.isLoaded(other.getLocation())) {
iterator.remove();
continue;
}
if (!withinRange(actor, other))
continue;

View File

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

View File

@ -3,8 +3,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
import java.util.List;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.block.ITE;
import net.minecraft.core.BlockPos;
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.level.Level;
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.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
@ -61,16 +59,7 @@ public class BrassTunnelBlock extends BeltTunnelBlock {
@Override
public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasBlockEntity() && (state.getBlock() != newState.getBlock() || !newState.hasBlockEntity())) {
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);
}
ITE.onRemove(state, level, pos, newState);
}
}

View File

@ -46,6 +46,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.item.ItemEntity;
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.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
@ -714,9 +715,16 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity implements IHave
}
@Override
public void setRemoved() {
public void invalidate() {
super.invalidate();
tunnelCapability.invalidate();
super.setRemoved();
}
@Override
public void destroy() {
super.destroy();
Block.popResource(level, worldPosition, stackToDistribute);
stackEnteredFrom = null;
}
@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.tileEntity.TileEntityBehaviour;
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 net.minecraft.core.BlockPos;
@ -132,14 +131,10 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
}
@Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
if (state.hasBlockEntity() && (differentBlock || !p_196243_4_.hasBlockEntity())) {
TileEntityBehaviour.destroy(world, pos, FilteringBehaviour.TYPE);
withTileEntityDo(world, pos, c -> c.onRemoved(state));
world.removeBlockEntity(pos);
}
if (p_196243_5_ || !differentBlock)
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
ITE.onRemove(state, world, pos, newState);
if (isMoving || state.is(newState.getBlock()))
return;
updateDiagonalNeighbour(state, world, pos);

View File

@ -509,10 +509,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
}
@Override
public void setRemoved() {
super.setRemoved();
public void invalidate() {
if (lazyHandler != null)
lazyHandler.invalidate();
super.invalidate();
}
@Override
@ -557,8 +557,10 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
return (Mth.clamp(motion, -maxItemSpeed, maxItemSpeed) + (motion <= 0 ? -gravity : 0)) / 20f;
}
public void onRemoved(BlockState chuteState) {
ChuteTileEntity targetChute = getTargetChute(chuteState);
@Override
public void destroy() {
super.destroy();
ChuteTileEntity targetChute = getTargetChute(getBlockState());
List<ChuteTileEntity> inputChutes = getInputChutes();
if (!item.isEmpty() && level != null)
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.item.ItemStack;
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.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
@ -199,7 +200,19 @@ public class DepotBehaviour extends TileEntityBehaviour {
}
@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)
lazyItemHandler.invalidate();
}

View File

@ -55,7 +55,7 @@ public class DepotBlock extends Block implements ITE<DepotTileEntity>, IWrenchab
@Override
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

View File

@ -125,12 +125,6 @@ public class EjectorBlock extends HorizontalKineticBlock implements ITE<EjectorT
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
public Axis getRotationAxis(BlockState state) {
return state.getValue(HORIZONTAL_FACING)

View File

@ -470,6 +470,12 @@ public class EjectorTileEntity extends KineticTileEntity {
return launcher.getGlobalVelocity(time, getFacing().getOpposite(), worldPosition)
.scale(.5f);
}
@Override
public void destroy() {
super.destroy();
dropFlyingItems();
}
public void dropFlyingItems() {
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.Create;
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.behaviour.belt.DirectBeltInputBehaviour;
@ -13,7 +12,6 @@ import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
@ -76,22 +74,6 @@ public class SharedDepotBlockMethods {
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) {
if (!(entityIn instanceof ItemEntity))
return;

View File

@ -128,13 +128,8 @@ public abstract class AbstractFunnelBlock extends Block implements ITE<FunnelTil
protected abstract Direction getFacing(BlockState state);
@Override
public void onRemove(BlockState p_196243_1_, Level p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_,
boolean p_196243_5_) {
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_);
}
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
ITE.onRemove(state, world, pos, newState);
}
@Override

View File

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

View File

@ -12,7 +12,6 @@ import com.simibubi.create.foundation.block.ITE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
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();
}
@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
public InteractionResult use(BlockState p_225533_1_, Level world, BlockPos pos, Player player,
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.world.item.ItemStack;
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.entity.BlockEntityType;
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)
.orElse(false);
}
@Override
public void destroy() {
super.destroy();
if (!heldItem.isEmpty())
Block.popResource(level, worldPosition, heldItem);
}
@Nullable
private ArmInteractionPoint getTargetedInteractionPoint() {

View File

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

View File

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

View File

@ -234,10 +234,10 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
}
@Override
public void remove() {
public void destroy() {
super.destroy();
if (edgePoint != null && !getWorld().isClientSide)
edgePoint.tileRemoved(getPos(), getTargetDirection() == AxisDirection.POSITIVE);
super.remove();
}
@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.content.contraptions.wrench.IWrenchable;
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.Direction;
@ -57,11 +55,8 @@ public class TrackObserverBlock extends Block implements ITE<TrackObserverTileEn
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) {
TileEntityBehaviour.destroy(pLevel, pPos, FilteringBehaviour.TYPE);
pLevel.removeBlockEntity(pPos);
}
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
ITE.onRemove(state, worldIn, pos, newState);
}
}

View File

@ -100,7 +100,7 @@ public class StationBlock extends Block implements ITE<StationTileEntity>, IWren
@Override
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

View File

@ -438,11 +438,10 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable
}
@Override
protected void setRemovedNotDueToChunkUnload() {
public void remove() {
assemblyAreas.get(level)
.remove(worldPosition);
super.setRemovedNotDueToChunkUnload();
super.remove();
}
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.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
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 {
@Override

View File

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

View File

@ -34,6 +34,21 @@ public interface ITE<T extends BlockEntity> extends EntityBlock {
.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) {
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.gson.JsonElement;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.ponder.PonderLocalization;
import com.simibubi.create.foundation.utility.FilesHelper;
import com.simibubi.create.foundation.utility.Lang;
import java.util.List;
public enum AllLangPartials implements ILangPartial {
ADVANCEMENTS("Advancements", AllAdvancements::provideLangEntries),

View File

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

View File

@ -33,6 +33,7 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
private boolean firstNbtRead = true;
protected int lazyTickRate;
protected int lazyTickCounter;
private boolean chunkUnloaded;
// Used for simulating this TE in a client-only setting
private boolean virtualMode;
@ -118,32 +119,37 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
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
public void onChunkUnloaded() {
super.onChunkUnloaded();
unloaded = true;
}
protected void setRemovedNotDueToChunkUnload() {
forEachBehaviour(TileEntityBehaviour::remove);
chunkUnloaded = true;
}
@Override
public void setRemoved() {
public final void 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
@ -186,7 +192,7 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
protected void removeBehaviour(BehaviourType<?> type) {
TileEntityBehaviour remove = behaviours.remove(type);
if (remove != null) {
remove.remove();
remove.unload();
}
}
@ -202,6 +208,10 @@ public abstract class SmartTileEntity extends CachedRenderBBTileEntity implement
public boolean isVirtual() {
return virtualMode;
}
public boolean isChunkUnloaded() {
return chunkUnloaded;
}
@Override
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() {}
}
public void destroy() {
}
/**
* Block destroyed or removed. Requires block to call ITE::onRemove
*/
public void destroy() {}
public void setLazyTickRate(int slowTickRate) {
this.lazyTickRate = slowTickRate;
@ -96,13 +98,6 @@ public abstract class TileEntityBehaviour {
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) {
if (te == null)
return null;

View File

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

View File

@ -19,6 +19,7 @@ import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
@ -115,8 +116,8 @@ public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinka
}
@Override
public void remove() {
super.remove();
public void unload() {
super.unload();
if (getWorld().isClientSide)
return;
getHandler().removeFromNetwork(getWorld(), this);
@ -208,7 +209,15 @@ public class LinkBehaviour extends TileEntityBehaviour implements IRedstoneLinka
@Override
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