mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Scanning the Far Lands for Rails
- Fixed basins not continuing their processing when items are extracted by funnel #1416 - Basins now accept full stacks for items thrown into the top manually - Fixed Smart Chutes not dropping filter items - Fixed Smart Chutes not updating attached diagonal chutes properly when removed - Fixed Server-side crash when coupling two minecarts from a glitched self-colliding pile
This commit is contained in:
parent
2fc26f1112
commit
f9d48386ca
10 changed files with 57 additions and 15 deletions
|
@ -101,6 +101,8 @@ public class DeployerMovementBehaviour extends MovementBehaviour {
|
||||||
if (!tag.getBoolean("Deployed"))
|
if (!tag.getBoolean("Deployed"))
|
||||||
return;
|
return;
|
||||||
SchematicWorld schematicWorld = SchematicInstances.get(world, filter);
|
SchematicWorld schematicWorld = SchematicInstances.get(world, filter);
|
||||||
|
if (schematicWorld == null)
|
||||||
|
return;
|
||||||
if (!schematicWorld.getBounds()
|
if (!schematicWorld.getBounds()
|
||||||
.isVecInside(pos.subtract(schematicWorld.anchor)))
|
.isVecInside(pos.subtract(schematicWorld.anchor)))
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -93,7 +93,10 @@ public class CouplingPhysics {
|
||||||
public static void softCollisionStep(World world, Couple<AbstractMinecartEntity> carts, double couplingLength) {
|
public static void softCollisionStep(World world, Couple<AbstractMinecartEntity> carts, double couplingLength) {
|
||||||
Couple<Float> maxSpeed = carts.map(AbstractMinecartEntity::getMaxCartSpeedOnRail);
|
Couple<Float> maxSpeed = carts.map(AbstractMinecartEntity::getMaxCartSpeedOnRail);
|
||||||
Couple<Boolean> canAddmotion = carts.map(MinecartSim2020::canAddMotion);
|
Couple<Boolean> canAddmotion = carts.map(MinecartSim2020::canAddMotion);
|
||||||
|
|
||||||
|
// Assuming Minecarts will never move faster than 1 block/tick
|
||||||
Couple<Vector3d> motions = carts.map(Entity::getMotion);
|
Couple<Vector3d> motions = carts.map(Entity::getMotion);
|
||||||
|
motions.replaceWithParams(VecHelper::clamp, Couple.create(1f, 1f));
|
||||||
Couple<Vector3d> nextPositions = carts.map(MinecartSim2020::predictNextPositionOf);
|
Couple<Vector3d> nextPositions = carts.map(MinecartSim2020::predictNextPositionOf);
|
||||||
|
|
||||||
Couple<RailShape> shapes = carts.mapWithContext((cart, current) -> {
|
Couple<RailShape> shapes = carts.mapWithContext((cart, current) -> {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.google.common.collect.Maps;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
|
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.content.contraptions.components.structureMovement.train.capability.MinecartController;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractRailBlock;
|
import net.minecraft.block.AbstractRailBlock;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -47,7 +48,7 @@ public class MinecartSim2020 {
|
||||||
|
|
||||||
public static Vector3d predictNextPositionOf(AbstractMinecartEntity cart) {
|
public static Vector3d predictNextPositionOf(AbstractMinecartEntity cart) {
|
||||||
Vector3d position = cart.getPositionVec();
|
Vector3d position = cart.getPositionVec();
|
||||||
Vector3d motion = cart.getMotion();
|
Vector3d motion = VecHelper.clamp(cart.getMotion(), 1f);
|
||||||
return position.add(motion);
|
return position.add(motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,8 +131,13 @@ public class BasinBlock extends Block implements ITE<BasinTileEntity>, IWrenchab
|
||||||
return;
|
return;
|
||||||
ItemEntity itemEntity = (ItemEntity) entityIn;
|
ItemEntity itemEntity = (ItemEntity) entityIn;
|
||||||
withTileEntityDo(worldIn, entityIn.getBlockPos(), te -> {
|
withTileEntityDo(worldIn, entityIn.getBlockPos(), te -> {
|
||||||
|
|
||||||
|
// Tossed items bypass the quarter-stack limit
|
||||||
|
te.inputInventory.withMaxStackSize(64);
|
||||||
ItemStack insertItem = ItemHandlerHelper.insertItem(te.inputInventory, itemEntity.getItem()
|
ItemStack insertItem = ItemHandlerHelper.insertItem(te.inputInventory, itemEntity.getItem()
|
||||||
.copy(), false);
|
.copy(), false);
|
||||||
|
te.inputInventory.withMaxStackSize(16);
|
||||||
|
|
||||||
if (insertItem.isEmpty()) {
|
if (insertItem.isEmpty()) {
|
||||||
itemEntity.remove();
|
itemEntity.remove();
|
||||||
if (!itemEntity.world.isRemote)
|
if (!itemEntity.world.isRemote)
|
||||||
|
|
|
@ -7,8 +7,11 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class BasinInventory extends SmartInventory {
|
public class BasinInventory extends SmartInventory {
|
||||||
|
|
||||||
|
private BasinTileEntity te;
|
||||||
|
|
||||||
public BasinInventory(int slots, BasinTileEntity te) {
|
public BasinInventory(int slots, BasinTileEntity te) {
|
||||||
super(slots, te, 16, true);
|
super(slots, te, 16, true);
|
||||||
|
this.te = te;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -19,5 +22,13 @@ public class BasinInventory extends SmartInventory {
|
||||||
return stack;
|
return stack;
|
||||||
return super.insertItem(slot, stack, simulate);
|
return super.insertItem(slot, stack, simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
|
ItemStack extractItem = super.extractItem(slot, amount, simulate);
|
||||||
|
if (!simulate && !extractItem.isEmpty())
|
||||||
|
te.notifyChangeOfContents();
|
||||||
|
return extractItem;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,8 @@ public class BasinTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
||||||
super(type);
|
super(type);
|
||||||
inputInventory = new BasinInventory(9, this);
|
inputInventory = new BasinInventory(9, this);
|
||||||
inputInventory.whenContentsChanged($ -> contentsChanged = true);
|
inputInventory.whenContentsChanged($ -> contentsChanged = true);
|
||||||
outputInventory = new BasinInventory(9, this).forbidInsertion();
|
outputInventory = new BasinInventory(9, this).forbidInsertion()
|
||||||
|
.withMaxStackSize(64);
|
||||||
areFluidsMoving = false;
|
areFluidsMoving = false;
|
||||||
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory));
|
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(inputInventory, outputInventory));
|
||||||
contentsChanged = true;
|
contentsChanged = true;
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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.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.BlockHelper;
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
public static boolean isOpenChute(BlockState state) {
|
public static boolean isOpenChute(BlockState state) {
|
||||||
return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isOpen(state);
|
return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isOpen(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isTransparentChute(BlockState state) {
|
public static boolean isTransparentChute(BlockState state) {
|
||||||
return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isTransparent(state);
|
return isChute(state) && ((AbstractChuteBlock) state.getBlock()).isTransparent(state);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +67,7 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
public boolean isOpen(BlockState state) {
|
public boolean isOpen(BlockState state) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransparent(BlockState state) {
|
public boolean isTransparent(BlockState state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -128,6 +129,7 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
|
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
|
||||||
boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
|
boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
|
||||||
if (state.hasTileEntity() && (differentBlock || !p_196243_4_.hasTileEntity())) {
|
if (state.hasTileEntity() && (differentBlock || !p_196243_4_.hasTileEntity())) {
|
||||||
|
TileEntityBehaviour.destroy(world, pos, FilteringBehaviour.TYPE);
|
||||||
withTileEntityDo(world, pos, c -> c.onRemoved(state));
|
withTileEntityDo(world, pos, c -> c.onRemoved(state));
|
||||||
world.removeTileEntity(pos);
|
world.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +142,10 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
BlockPos toUpdate = pos.up()
|
BlockPos toUpdate = pos.up()
|
||||||
.offset(direction);
|
.offset(direction);
|
||||||
BlockState stateToUpdate = world.getBlockState(toUpdate);
|
BlockState stateToUpdate = world.getBlockState(toUpdate);
|
||||||
BlockState updated = updateChuteState(stateToUpdate, world.getBlockState(toUpdate.up()), world, toUpdate);
|
if (!isChute(stateToUpdate))
|
||||||
|
continue;
|
||||||
|
BlockState updated = ((AbstractChuteBlock) stateToUpdate.getBlock()).updateChuteState(stateToUpdate,
|
||||||
|
world.getBlockState(toUpdate.up()), world, toUpdate);
|
||||||
if (stateToUpdate != updated && !world.isRemote)
|
if (stateToUpdate != updated && !world.isRemote)
|
||||||
world.setBlockState(toUpdate, updated);
|
world.setBlockState(toUpdate, updated);
|
||||||
}
|
}
|
||||||
|
@ -157,9 +162,11 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState p_220069_1_, World world, BlockPos pos, Block p_220069_4_,
|
public void neighborChanged(BlockState p_220069_1_, World world, BlockPos pos, Block p_220069_4_,
|
||||||
BlockPos neighbourPos, boolean p_220069_6_) {
|
BlockPos neighbourPos, boolean p_220069_6_) {
|
||||||
if (pos.down().equals(neighbourPos))
|
if (pos.down()
|
||||||
|
.equals(neighbourPos))
|
||||||
withTileEntityDo(world, pos, ChuteTileEntity::blockBelowChanged);
|
withTileEntityDo(world, pos, ChuteTileEntity::blockBelowChanged);
|
||||||
else if (pos.up().equals(neighbourPos))
|
else if (pos.up()
|
||||||
|
.equals(neighbourPos))
|
||||||
withTileEntityDo(world, pos, chute -> chute.capAbove = LazyOptional.empty());
|
withTileEntityDo(world, pos, chute -> chute.capAbove = LazyOptional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,13 +178,13 @@ public abstract class AbstractChuteBlock extends Block implements IWrenchable, I
|
||||||
BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
|
BlockHelper.addReducedDestroyEffects(state, world, pos, manager);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
||||||
ISelectionContext p_220053_4_) {
|
ISelectionContext p_220053_4_) {
|
||||||
return ChuteShapes.getShape(p_220053_1_);
|
return ChuteShapes.getShape(p_220053_1_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_,
|
public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_,
|
||||||
ISelectionContext p_220071_4_) {
|
ISelectionContext p_220071_4_) {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.logistics.block.chute;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
|
|
@ -35,12 +35,14 @@ public class SchematicInstances {
|
||||||
public static SchematicWorld get(World world, ItemStack schematic) {
|
public static SchematicWorld get(World world, ItemStack schematic) {
|
||||||
Cache<Integer, SchematicWorld> map = loadedSchematics.get(world);
|
Cache<Integer, SchematicWorld> map = loadedSchematics.get(world);
|
||||||
int hash = getHash(schematic);
|
int hash = getHash(schematic);
|
||||||
try {
|
SchematicWorld ifPresent = map.getIfPresent(hash);
|
||||||
return map.get(hash, () -> loadWorld(world, schematic));
|
if (ifPresent != null)
|
||||||
} catch (ExecutionException e) {
|
return ifPresent;
|
||||||
e.printStackTrace();
|
SchematicWorld loadWorld = loadWorld(world, schematic);
|
||||||
}
|
if (loadWorld == null)
|
||||||
return null;
|
return null;
|
||||||
|
map.put(hash, loadWorld);
|
||||||
|
return loadWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SchematicWorld loadWorld(World wrapped, ItemStack schematic) {
|
private static SchematicWorld loadWorld(World wrapped, ItemStack schematic) {
|
||||||
|
|
|
@ -18,6 +18,7 @@ public class SmartInventory extends RecipeWrapper
|
||||||
protected boolean extractionAllowed;
|
protected boolean extractionAllowed;
|
||||||
protected boolean insertionAllowed;
|
protected boolean insertionAllowed;
|
||||||
protected boolean stackNonStackables;
|
protected boolean stackNonStackables;
|
||||||
|
protected SyncedStackHandler wrapped;
|
||||||
protected int stackSize;
|
protected int stackSize;
|
||||||
|
|
||||||
public SmartInventory(int slots, SyncedTileEntity te) {
|
public SmartInventory(int slots, SyncedTileEntity te) {
|
||||||
|
@ -30,6 +31,13 @@ public class SmartInventory extends RecipeWrapper
|
||||||
insertionAllowed = true;
|
insertionAllowed = true;
|
||||||
extractionAllowed = true;
|
extractionAllowed = true;
|
||||||
this.stackSize = stackSize;
|
this.stackSize = stackSize;
|
||||||
|
wrapped = (SyncedStackHandler) inv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SmartInventory withMaxStackSize(int maxStackSize) {
|
||||||
|
stackSize = maxStackSize;
|
||||||
|
wrapped.stackSize = maxStackSize;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SmartInventory whenContentsChanged(Consumer<Integer> updateCallback) {
|
public SmartInventory whenContentsChanged(Consumer<Integer> updateCallback) {
|
||||||
|
|
Loading…
Reference in a new issue