diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 32f9a2a34..9480d7e04 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -119,7 +119,7 @@ public abstract class Contraption { public Optional> simplifiedEntityColliders; public AbstractContraptionEntity entity; - public CombinedInvWrapper inventory; + public ContraptionInvWrapper inventory; public CombinedTankWrapper fluidInventory; public AxisAlignedBB bounds; public BlockPos anchor; @@ -252,7 +252,7 @@ public abstract class Contraption { .stream() .map(MountedStorage::getItemHandler) .collect(Collectors.toList()); - inventory = new CombinedInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); + inventory = new ContraptionInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); List fluidHandlers = fluidStorage.values() .stream() @@ -341,7 +341,7 @@ public abstract class Contraption { // Bearings potentially create stabilized sub-contraptions if (AllBlocks.MECHANICAL_BEARING.has(state)) moveBearing(pos, frontier, visited, state); - + // WM Bearings attach their structure when moved if (AllBlocks.WINDMILL_BEARING.has(state)) moveWindmillBearing(pos, frontier, visited, state); @@ -739,7 +739,7 @@ public abstract class Contraption { for (MountedFluidStorage mountedStorage : fluidStorage.values()) fluidHandlers[index++] = mountedStorage.getFluidHandler(); - inventory = new CombinedInvWrapper(handlers); + inventory = new ContraptionInvWrapper(handlers); fluidInventory = new CombinedTankWrapper(fluidHandlers); if (nbt.contains("BoundsFront")) @@ -1053,8 +1053,10 @@ public abstract class Contraption { BlockFlags.IS_MOVING | BlockFlags.DEFAULT, 512); } - for (int i = 0; i < inventory.getSlots(); i++) - inventory.setStackInSlot(i, ItemStack.EMPTY); + for (int i = 0; i < inventory.getSlots(); i++) { + if (!inventory.isSlotExternal(i)) + inventory.setStackInSlot(i, ItemStack.EMPTY); + } for (int i = 0; i < fluidInventory.getTanks(); i++) fluidInventory.drain(fluidInventory.getFluidInTank(i), FluidAction.EXECUTE); @@ -1261,4 +1263,24 @@ public abstract class Contraption { return pos.equals(te.getPos()); } } + + public static class ContraptionInvWrapper extends CombinedInvWrapper { + protected final boolean isExternal; + + public ContraptionInvWrapper(boolean isExternal, IItemHandlerModifiable... itemHandler) { + super(itemHandler); + this.isExternal = isExternal; + } + + public ContraptionInvWrapper(IItemHandlerModifiable... itemHandler) { + this(false, itemHandler); + } + + public boolean isSlotExternal(int slot) { + if (isExternal) + return true; + IItemHandlerModifiable handler = getHandlerFromIndex(getIndexForSlot(slot)); + return handler instanceof ContraptionInvWrapper && ((ContraptionInvWrapper) handler).isSlotExternal(slot); + } + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java index 4d70938b2..dbdef7a30 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ControlledContraptionEntity.java @@ -34,6 +34,7 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { protected Axis rotationAxis; protected float prevAngle; protected float angle; + protected float angleDelta; public ControlledContraptionEntity(EntityType type, World world) { super(type, world); @@ -130,9 +131,10 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { public void setPositionAndRotationDirect(double x, double y, double z, float yw, float pt, int inc, boolean t) {} protected void tickContraption() { + angleDelta = angle - prevAngle; prevAngle = angle; tickActors(); - + if (controllerPos == null) return; if (!world.isBlockPresent(controllerPos)) @@ -171,7 +173,7 @@ public class ControlledContraptionEntity extends AbstractContraptionEntity { return false; if (!VecHelper.onSameAxis(blockInfo.pos, BlockPos.ZERO, facing.getAxis())) return false; - context.motion = Vector3d.of(facing.getDirectionVec()).scale(angle - prevAngle); + context.motion = Vector3d.of(facing.getDirectionVec()).scale(angleDelta / 360.0); context.relativeMotion = context.motion; int timer = context.data.getInt("StationaryTimer"); if (timer > 0) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java index 97b75e778..fae052d36 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/MountedContraption.java @@ -53,7 +53,7 @@ public class MountedContraption extends Contraption { protected ContraptionType getType() { return ContraptionType.MOUNTED; } - + @Override public boolean assemble(World world, BlockPos pos) throws AssemblyException { BlockState state = world.getBlockState(pos); @@ -61,17 +61,17 @@ public class MountedContraption extends Contraption { return false; if (!searchMovedStructure(world, pos, null)) return false; - + Axis axis = state.get(RAIL_SHAPE) == RailShape.EAST_WEST ? Axis.X : Axis.Z; addBlock(pos, Pair.of(new BlockInfo(pos, AllBlocks.MINECART_ANCHOR.getDefaultState() .with(BlockStateProperties.HORIZONTAL_AXIS, axis), null), null)); - + if (blocks.size() == 1) return false; - + return true; } - + @Override protected boolean addToInitialFrontier(World world, BlockPos pos, Direction direction, Queue frontier) { frontier.clear(); @@ -149,18 +149,18 @@ public class MountedContraption extends Contraption { protected boolean customBlockRemoval(IWorld world, BlockPos pos, BlockState state) { return AllBlocks.MINECART_ANCHOR.has(state); } - + @Override public boolean canBeStabilized(Direction facing, BlockPos localPos) { return true; } - + @Override public void addExtraInventories(Entity cart) { if (!(cart instanceof IInventory)) return; - IItemHandlerModifiable handlerFromInv = new InvWrapper((IInventory) cart); - inventory = new CombinedInvWrapper(handlerFromInv, inventory); + IItemHandlerModifiable handlerFromInv = new ContraptionInvWrapper(true, new InvWrapper((IInventory) cart)); + inventory = new ContraptionInvWrapper(handlerFromInv, inventory); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/MinecartCouplingItem.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/MinecartCouplingItem.java index d421c8fb1..66986c18d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/MinecartCouplingItem.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/train/MinecartCouplingItem.java @@ -4,6 +4,8 @@ import com.simibubi.create.AllItems; import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController; import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartController; +import com.simibubi.create.foundation.utility.Iterate; + import net.minecraft.entity.Entity; import net.minecraft.entity.item.minecart.AbstractMinecartEntity; import net.minecraft.entity.player.PlayerEntity; @@ -78,6 +80,11 @@ public class MinecartCouplingItem extends Item { if (event.getWorld().isRemote) return true; + for (boolean forward : Iterate.trueAndFalse) { + if (controller.hasContraptionCoupling(forward)) + couplings--; + } + CouplingHandler.status(player, "removed"); controller.decouple(); if (!player.isCreative()) diff --git a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java index f839edd24..58df85ed1 100644 --- a/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java +++ b/src/main/java/com/simibubi/create/content/schematics/SchematicWorld.java @@ -202,6 +202,9 @@ public class SchematicWorld extends WrappedWorld implements IServerWorld { return true; } + @Override + public void notifyBlockUpdate(BlockPos pos, BlockState oldState, BlockState newState, int flags) { } + @Override public ITickList getPendingBlockTicks() { return EmptyTickList.get(); @@ -233,4 +236,5 @@ public class SchematicWorld extends WrappedWorld implements IServerWorld { } throw new IllegalStateException("Cannot use IServerWorld#getWorld in a client environment"); } + } diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedChunkProvider.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedChunkProvider.java index 4bb1dfffa..dbc75fcfd 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedChunkProvider.java +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedChunkProvider.java @@ -6,6 +6,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; +import com.simibubi.create.foundation.utility.worldWrappers.chunk.EmptierChunk; import com.simibubi.create.foundation.utility.worldWrappers.chunk.WrappedChunk; import net.minecraft.util.math.BlockPos; @@ -52,11 +53,11 @@ public class WrappedChunkProvider extends AbstractChunkProvider { return getChunk(x, z); } - public WrappedChunk getChunk(int x, int z) { + public IChunk getChunk(int x, int z) { long pos = ChunkPos.asLong(x, z); - + if (chunks == null) - return null; + return new EmptierChunk(); return chunks.computeIfAbsent(pos, $ -> new WrappedChunk(world, x, z)); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedWorld.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedWorld.java index a5984048c..7f65c17e3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedWorld.java +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/WrappedWorld.java @@ -21,11 +21,14 @@ import net.minecraft.util.Direction; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.SectionPos; import net.minecraft.util.registry.DynamicRegistries; import net.minecraft.world.ITickList; import net.minecraft.world.World; import net.minecraft.world.biome.Biome; import net.minecraft.world.chunk.AbstractChunkProvider; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.lighting.WorldLightManager; import net.minecraft.world.storage.ISpawnWorldInfo; import net.minecraft.world.storage.MapData; @@ -51,12 +54,12 @@ public class WrappedWorld extends World { public World getWorld() { return world; } - + @Override public WorldLightManager getLightingProvider() { return world.getLightingProvider(); } - + @Override public BlockState getBlockState(@Nullable BlockPos pos) { return world.getBlockState(pos); diff --git a/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/EmptierChunk.java b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/EmptierChunk.java new file mode 100644 index 000000000..dae7595f3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/worldWrappers/chunk/EmptierChunk.java @@ -0,0 +1,82 @@ +package com.simibubi.create.foundation.utility.worldWrappers.chunk; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.fluid.FluidState; +import net.minecraft.fluid.Fluids; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.lighting.WorldLightManager; +import net.minecraft.world.server.ChunkHolder; + +import javax.annotation.Nullable; + +import java.util.List; +import java.util.function.Predicate; + +public class EmptierChunk extends Chunk { + + public EmptierChunk() { + super(null, null, null); + } + + public BlockState getBlockState(BlockPos p_180495_1_) { + return Blocks.VOID_AIR.getDefaultState(); + } + + @Nullable + public BlockState setBlockState(BlockPos p_177436_1_, BlockState p_177436_2_, boolean p_177436_3_) { + return null; + } + + public FluidState getFluidState(BlockPos p_204610_1_) { + return Fluids.EMPTY.getDefaultState(); + } + + @Nullable + public WorldLightManager getWorldLightManager() { + return null; + } + + public int getLightValue(BlockPos p_217298_1_) { + return 0; + } + + public void addEntity(Entity p_76612_1_) { } + + public void removeEntity(Entity p_76622_1_) { } + + public void removeEntityAtIndex(Entity p_76608_1_, int p_76608_2_) { } + + @Nullable + public TileEntity getTileEntity(BlockPos p_177424_1_, Chunk.CreateEntityType p_177424_2_) { + return null; + } + + public void addTileEntity(TileEntity p_150813_1_) { } + + public void addTileEntity(BlockPos p_177426_1_, TileEntity p_177426_2_) { } + + public void removeTileEntity(BlockPos p_177425_1_) { } + + public void markDirty() { } + + public void getEntitiesWithinAABBForEntity(@Nullable Entity p_177414_1_, AxisAlignedBB p_177414_2_, List p_177414_3_, Predicate p_177414_4_) { } + + public void getEntitiesOfTypeWithinAABB(Class p_177430_1_, AxisAlignedBB p_177430_2_, List p_177430_3_, Predicate p_177430_4_) { } + + public boolean isEmpty() { + return true; + } + + public boolean isEmptyBetween(int p_76606_1_, int p_76606_2_) { + return true; + } + + public ChunkHolder.LocationType getLocationType() { + return ChunkHolder.LocationType.BORDER; + } +}