mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-11-14 06:24:12 +01:00
Depot Implementation and Interaction
- Depots can now hold on to items similarly to belts - Item processing such as the press and bulk smelting now targets a Processing TE behaviour, rather than the belt only - The press and similar processing can no longer commence whenever there is a block with a collision shape between item and machine - Implemented item processing for Depots - Items can seamlessly traverse from belts to depots
This commit is contained in:
parent
9fe1d85199
commit
f7ad748a09
@ -72,6 +72,8 @@ import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverRe
|
|||||||
import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverTileEntity;
|
import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.depot.DepotRenderer;
|
||||||
|
import com.simibubi.create.content.logistics.block.depot.DepotTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterRenderer;
|
||||||
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterTileEntity;
|
import com.simibubi.create.content.logistics.block.diodes.AdjustableRepeaterTileEntity;
|
||||||
@ -219,6 +221,8 @@ public class AllTileEntities {
|
|||||||
public static final TileEntityEntry<CreativeCrateTileEntity> CREATIVE_CRATE =
|
public static final TileEntityEntry<CreativeCrateTileEntity> CREATIVE_CRATE =
|
||||||
register("creative_crate", CreativeCrateTileEntity::new, AllBlocks.CREATIVE_CRATE);
|
register("creative_crate", CreativeCrateTileEntity::new, AllBlocks.CREATIVE_CRATE);
|
||||||
|
|
||||||
|
public static final TileEntityEntry<DepotTileEntity> DEPOT =
|
||||||
|
register("depot", DepotTileEntity::new, AllBlocks.DEPOT);
|
||||||
public static final TileEntityEntry<RealityFunnelTileEntity> REALITY_FUNNEL = register("reality_funnel",
|
public static final TileEntityEntry<RealityFunnelTileEntity> REALITY_FUNNEL = register("reality_funnel",
|
||||||
RealityFunnelTileEntity::new, AllBlocks.REALITY_FUNNEL, AllBlocks.BELT_FUNNEL, AllBlocks.CHUTE_FUNNEL);
|
RealityFunnelTileEntity::new, AllBlocks.REALITY_FUNNEL, AllBlocks.BELT_FUNNEL, AllBlocks.CHUTE_FUNNEL);
|
||||||
public static final TileEntityEntry<PackagerTileEntity> PACKAGER =
|
public static final TileEntityEntry<PackagerTileEntity> PACKAGER =
|
||||||
@ -295,6 +299,7 @@ public class AllTileEntities {
|
|||||||
bind(FURNACE_ENGINE, EngineRenderer::new);
|
bind(FURNACE_ENGINE, EngineRenderer::new);
|
||||||
bind(ROTATION_SPEED_CONTROLLER, SpeedControllerRenderer::new);
|
bind(ROTATION_SPEED_CONTROLLER, SpeedControllerRenderer::new);
|
||||||
bind(PACKAGER, PackagerRenderer::new);
|
bind(PACKAGER, PackagerRenderer::new);
|
||||||
|
bind(DEPOT, DepotRenderer::new);
|
||||||
|
|
||||||
bind(CREATIVE_CRATE, SmartTileEntityRenderer::new);
|
bind(CREATIVE_CRATE, SmartTileEntityRenderer::new);
|
||||||
bind(REDSTONE_LINK, SmartTileEntityRenderer::new);
|
bind(REDSTONE_LINK, SmartTileEntityRenderer::new);
|
||||||
|
@ -7,11 +7,12 @@ import java.util.List;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.particle.AirFlowParticleData;
|
import com.simibubi.create.content.contraptions.particle.AirFlowParticleData;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.content.logistics.InWorldProcessing;
|
import com.simibubi.create.content.logistics.InWorldProcessing;
|
||||||
import com.simibubi.create.content.logistics.InWorldProcessing.Type;
|
import com.simibubi.create.content.logistics.InWorldProcessing.Type;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||||
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
@ -21,9 +22,7 @@ import net.minecraft.entity.EntityType;
|
|||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.entity.monster.EndermanEntity;
|
import net.minecraft.entity.monster.EndermanEntity;
|
||||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
@ -42,10 +41,10 @@ import net.minecraftforge.common.Tags;
|
|||||||
|
|
||||||
public class AirCurrent {
|
public class AirCurrent {
|
||||||
|
|
||||||
private static DamageSource damageSourceFire =
|
private static DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled()
|
||||||
new DamageSource("create.fan_fire").setDifficultyScaled().setFireDamage();
|
.setFireDamage();
|
||||||
private static DamageSource damageSourceLava =
|
private static DamageSource damageSourceLava = new DamageSource("create.fan_lava").setDifficultyScaled()
|
||||||
new DamageSource("create.fan_lava").setDifficultyScaled().setFireDamage();
|
.setFireDamage();
|
||||||
|
|
||||||
public final EncasedFanTileEntity source;
|
public final EncasedFanTileEntity source;
|
||||||
public AxisAlignedBB bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
public AxisAlignedBB bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||||
@ -54,7 +53,8 @@ public class AirCurrent {
|
|||||||
public boolean pushing;
|
public boolean pushing;
|
||||||
public float maxDistance;
|
public float maxDistance;
|
||||||
|
|
||||||
protected List<Pair<BeltTileEntity, InWorldProcessing.Type>> affectedBelts = new ArrayList<>();
|
protected List<Pair<TransportedItemStackHandlerBehaviour, InWorldProcessing.Type>> affectedItemHandlers =
|
||||||
|
new ArrayList<>();
|
||||||
protected List<Entity> caughtEntities = new ArrayList<>();
|
protected List<Entity> caughtEntities = new ArrayList<>();
|
||||||
|
|
||||||
public AirCurrent(EncasedFanTileEntity source) {
|
public AirCurrent(EncasedFanTileEntity source) {
|
||||||
@ -66,14 +66,16 @@ public class AirCurrent {
|
|||||||
Direction facing = direction;
|
Direction facing = direction;
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
float offset = pushing ? 0.5f : maxDistance + .5f;
|
float offset = pushing ? 0.5f : maxDistance + .5f;
|
||||||
Vec3d pos = VecHelper.getCenterOf(source.getPos()).add(new Vec3d(facing.getDirectionVec()).scale(offset));
|
Vec3d pos = VecHelper.getCenterOf(source.getPos())
|
||||||
|
.add(new Vec3d(facing.getDirectionVec()).scale(offset));
|
||||||
if (world.rand.nextFloat() < AllConfigs.CLIENT.fanParticleDensity.get())
|
if (world.rand.nextFloat() < AllConfigs.CLIENT.fanParticleDensity.get())
|
||||||
world.addParticle(new AirFlowParticleData(source.getPos()), pos.x, pos.y, pos.z, 0, 0, 0);
|
world.addParticle(new AirFlowParticleData(source.getPos()), pos.x, pos.y, pos.z, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Iterator<Entity> iterator = caughtEntities.iterator(); iterator.hasNext();) {
|
for (Iterator<Entity> iterator = caughtEntities.iterator(); iterator.hasNext();) {
|
||||||
Entity entity = iterator.next();
|
Entity entity = iterator.next();
|
||||||
if (!entity.getBoundingBox().intersects(bounds)) {
|
if (!entity.getBoundingBox()
|
||||||
|
.intersects(bounds)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -83,7 +85,8 @@ public class AirCurrent {
|
|||||||
|
|
||||||
float sneakModifier = entity.isSneaking() ? 4096f : 512f;
|
float sneakModifier = entity.isSneaking() ? 4096f : 512f;
|
||||||
float speed = Math.abs(source.getSpeed());
|
float speed = Math.abs(source.getSpeed());
|
||||||
double entityDistance = entity.getPositionVec().distanceTo(center);
|
double entityDistance = entity.getPositionVec()
|
||||||
|
.distanceTo(center);
|
||||||
float acceleration = (float) (speed / sneakModifier / (entityDistance / maxDistance));
|
float acceleration = (float) (speed / sneakModifier / (entityDistance / maxDistance));
|
||||||
Vec3d previousMotion = entity.getMotion();
|
Vec3d previousMotion = entity.getMotion();
|
||||||
float maxAcceleration = 5;
|
float maxAcceleration = 5;
|
||||||
@ -127,7 +130,8 @@ public class AirCurrent {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPLASHING:
|
case SPLASHING:
|
||||||
if (entity instanceof EndermanEntity || entity.getType() == EntityType.SNOW_GOLEM || entity.getType() == EntityType.BLAZE) {
|
if (entity instanceof EndermanEntity || entity.getType() == EntityType.SNOW_GOLEM
|
||||||
|
|| entity.getType() == EntityType.BLAZE) {
|
||||||
entity.attackEntityFrom(DamageSource.DROWN, 2);
|
entity.attackEntityFrom(DamageSource.DROWN, 2);
|
||||||
}
|
}
|
||||||
if (!entity.isBurning())
|
if (!entity.isBurning())
|
||||||
@ -145,7 +149,7 @@ public class AirCurrent {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tickBelts();
|
tickAffectedHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rebuild() {
|
public void rebuild() {
|
||||||
@ -158,7 +162,8 @@ public class AirCurrent {
|
|||||||
|
|
||||||
World world = source.getWorld();
|
World world = source.getWorld();
|
||||||
BlockPos start = source.getPos();
|
BlockPos start = source.getPos();
|
||||||
direction = source.getBlockState().get(BlockStateProperties.FACING);
|
direction = source.getBlockState()
|
||||||
|
.get(BlockStateProperties.FACING);
|
||||||
pushing = source.getAirFlowDirection() == direction;
|
pushing = source.getAirFlowDirection() == direction;
|
||||||
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
|
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
|
||||||
Vec3d planeVec = VecHelper.planeByNormal(directionVec);
|
Vec3d planeVec = VecHelper.planeByNormal(directionVec);
|
||||||
@ -190,15 +195,17 @@ public class AirCurrent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Vec3d offset : offsets) {
|
for (Vec3d offset : offsets) {
|
||||||
Vec3d rayStart =
|
Vec3d rayStart = VecHelper.getCenterOf(currentPos)
|
||||||
VecHelper.getCenterOf(currentPos).subtract(directionVec.scale(.5f + 1 / 32f)).add(offset);
|
.subtract(directionVec.scale(.5f + 1 / 32f))
|
||||||
|
.add(offset);
|
||||||
Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
|
Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
|
||||||
BlockRayTraceResult blockraytraceresult =
|
BlockRayTraceResult blockraytraceresult =
|
||||||
world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, state);
|
world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, state);
|
||||||
if (blockraytraceresult == null)
|
if (blockraytraceresult == null)
|
||||||
continue Outer;
|
continue Outer;
|
||||||
|
|
||||||
double distance = i - 1 + blockraytraceresult.getHitVec().distanceTo(rayStart);
|
double distance = i - 1 + blockraytraceresult.getHitVec()
|
||||||
|
.distanceTo(rayStart);
|
||||||
if (limitedDistance < distance)
|
if (limitedDistance < distance)
|
||||||
limitedDistance = (float) distance;
|
limitedDistance = (float) distance;
|
||||||
}
|
}
|
||||||
@ -244,68 +251,58 @@ public class AirCurrent {
|
|||||||
if (factor > 0)
|
if (factor > 0)
|
||||||
bounds = new AxisAlignedBB(start.offset(direction)).expand(scale);
|
bounds = new AxisAlignedBB(start.offset(direction)).expand(scale);
|
||||||
else {
|
else {
|
||||||
bounds = new AxisAlignedBB(start.offset(direction)).contract(scale.x, scale.y, scale.z).offset(scale);
|
bounds = new AxisAlignedBB(start.offset(direction)).contract(scale.x, scale.y, scale.z)
|
||||||
|
.offset(scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
findAffectedBelts();
|
findAffectedHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findEntities() {
|
public void findEntities() {
|
||||||
caughtEntities.clear();
|
caughtEntities.clear();
|
||||||
caughtEntities = source.getWorld().getEntitiesWithinAABBExcludingEntity(null, bounds);
|
caughtEntities = source.getWorld()
|
||||||
|
.getEntitiesWithinAABBExcludingEntity(null, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void findAffectedBelts() {
|
public void findAffectedHandlers() {
|
||||||
World world = source.getWorld();
|
World world = source.getWorld();
|
||||||
BlockPos start = source.getPos();
|
BlockPos start = source.getPos();
|
||||||
affectedBelts.clear();
|
affectedItemHandlers.clear();
|
||||||
for (int i = 0; i < maxDistance + 1; i++) {
|
for (int i = 0; i < maxDistance + 1; i++) {
|
||||||
Type type = getSegmentAt(i);
|
Type type = getSegmentAt(i);
|
||||||
if (type == null)
|
if (type == null)
|
||||||
continue;
|
continue;
|
||||||
BlockPos pos = start.offset(direction, i);
|
|
||||||
TileEntity te = world.getTileEntity(pos);
|
|
||||||
if (te != null && (te instanceof BeltTileEntity))
|
|
||||||
affectedBelts.add(Pair.of((BeltTileEntity) te, type));
|
|
||||||
if (direction.getAxis().isVertical())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pos = pos.down();
|
for (int offset : Iterate.zeroAndOne) {
|
||||||
te = world.getTileEntity(pos);
|
BlockPos pos = start.offset(direction, i)
|
||||||
if (te == null || !(te instanceof BeltTileEntity))
|
.down(offset);
|
||||||
continue;
|
TransportedItemStackHandlerBehaviour behaviour =
|
||||||
affectedBelts.add(Pair.of((BeltTileEntity) te, type));
|
TileEntityBehaviour.get(world, pos, TransportedItemStackHandlerBehaviour.TYPE);
|
||||||
|
if (behaviour != null)
|
||||||
|
affectedItemHandlers.add(Pair.of(behaviour, type));
|
||||||
|
if (direction.getAxis()
|
||||||
|
.isVertical())
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tickBelts() {
|
public void tickAffectedHandlers() {
|
||||||
for (Pair<BeltTileEntity, Type> pair : affectedBelts) {
|
for (Pair<TransportedItemStackHandlerBehaviour, Type> pair : affectedItemHandlers) {
|
||||||
BeltTileEntity belt = pair.getKey();
|
TransportedItemStackHandlerBehaviour handler = pair.getKey();
|
||||||
World world = belt.getWorld();
|
World world = handler.getWorld();
|
||||||
InWorldProcessing.Type processingType = pair.getRight();
|
InWorldProcessing.Type processingType = pair.getRight();
|
||||||
|
|
||||||
BeltTileEntity controller = belt.getControllerTE();
|
handler.handleProcessingOnAllItems((transported) -> {
|
||||||
if (controller == null)
|
InWorldProcessing.spawnParticlesForProcessing(world, handler.getWorldPositionOf(transported),
|
||||||
continue;
|
processingType);
|
||||||
|
|
||||||
controller.getInventory().forEachWithin(belt.index + .5f, .51f, (transported) -> {
|
|
||||||
InWorldProcessing.spawnParticlesForProcessing(world,
|
|
||||||
BeltHelper.getVectorForOffset(controller, transported.beltPosition), processingType);
|
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return null;
|
return null;
|
||||||
return InWorldProcessing.applyProcessing(transported, belt, processingType);
|
return InWorldProcessing.applyProcessing(transported, world, processingType);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeToNBT(CompoundNBT nbt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readFromNBT(CompoundNBT nbt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean shouldAlwaysPass(BlockState state) {
|
private static boolean shouldAlwaysPass(BlockState state) {
|
||||||
if (state.isIn(Tags.Blocks.FENCES))
|
if (state.isIn(Tags.Blocks.FENCES))
|
||||||
return true;
|
return true;
|
||||||
|
@ -7,17 +7,17 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode;
|
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
|
||||||
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.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
public class BeltPressingCallbacks {
|
public class BeltPressingCallbacks {
|
||||||
|
|
||||||
static ProcessingResult onItemReceived(TransportedItemStack transported, BeltInventory beltInventory,
|
static ProcessingResult onItemReceived(TransportedItemStack transported,
|
||||||
MechanicalPressTileEntity press) {
|
TransportedItemStackHandlerBehaviour handler, MechanicalPressTileEntity press) {
|
||||||
if (press.getSpeed() == 0 || press.running)
|
if (press.getSpeed() == 0 || press.running)
|
||||||
return PASS;
|
return PASS;
|
||||||
if (!press.getRecipe(transported.stack)
|
if (!press.getRecipe(transported.stack)
|
||||||
@ -28,7 +28,7 @@ public class BeltPressingCallbacks {
|
|||||||
return HOLD;
|
return HOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ProcessingResult whenItemHeld(TransportedItemStack transportedStack, BeltInventory beltInventory,
|
static ProcessingResult whenItemHeld(TransportedItemStack transported, TransportedItemStackHandlerBehaviour handler,
|
||||||
MechanicalPressTileEntity pressTe) {
|
MechanicalPressTileEntity pressTe) {
|
||||||
|
|
||||||
if (pressTe.getSpeed() == 0)
|
if (pressTe.getSpeed() == 0)
|
||||||
@ -38,9 +38,9 @@ public class BeltPressingCallbacks {
|
|||||||
if (pressTe.runningTicks != 30)
|
if (pressTe.runningTicks != 30)
|
||||||
return HOLD;
|
return HOLD;
|
||||||
|
|
||||||
Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack);
|
Optional<PressingRecipe> recipe = pressTe.getRecipe(transported.stack);
|
||||||
pressTe.pressedItems.clear();
|
pressTe.pressedItems.clear();
|
||||||
pressTe.pressedItems.add(transportedStack.stack);
|
pressTe.pressedItems.add(transported.stack);
|
||||||
|
|
||||||
if (!recipe.isPresent())
|
if (!recipe.isPresent())
|
||||||
return PASS;
|
return PASS;
|
||||||
@ -48,10 +48,10 @@ public class BeltPressingCallbacks {
|
|||||||
ItemStack out = recipe.get()
|
ItemStack out = recipe.get()
|
||||||
.getRecipeOutput()
|
.getRecipeOutput()
|
||||||
.copy();
|
.copy();
|
||||||
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
|
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transported.stack, out);
|
||||||
if (multipliedOutput.isEmpty())
|
if (multipliedOutput.isEmpty())
|
||||||
transportedStack.stack = ItemStack.EMPTY;
|
transported.stack = ItemStack.EMPTY;
|
||||||
transportedStack.stack = multipliedOutput.get(0);
|
transported.stack = multipliedOutput.get(0);
|
||||||
pressTe.sendData();
|
pressTe.sendData();
|
||||||
return HOLD;
|
return HOLD;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
|||||||
if (worldIn.isRemote)
|
if (worldIn.isRemote)
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
controllerBelt.getInventory()
|
controllerBelt.getInventory()
|
||||||
.forEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
|
.applyToEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
|
||||||
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
});
|
});
|
||||||
|
@ -12,6 +12,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
@ -24,6 +25,7 @@ import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandle
|
|||||||
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.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.belt.TransportedItemStackHandlerBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
@ -39,6 +41,7 @@ import net.minecraft.util.Direction;
|
|||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.util.math.Vec3i;
|
||||||
import net.minecraftforge.common.capabilities.Capability;
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
@ -72,6 +75,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||||||
behaviours.add(new DirectBeltInputBehaviour(this)
|
behaviours.add(new DirectBeltInputBehaviour(this)
|
||||||
.onlyInsertWhen(d -> getSpeed() != 0 && getMovementFacing() != d.getOpposite())
|
.onlyInsertWhen(d -> getSpeed() != 0 && getMovementFacing() != d.getOpposite())
|
||||||
.setInsertionHandler(this::tryInsertingFromSide));
|
.setInsertionHandler(this::tryInsertingFromSide));
|
||||||
|
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||||
|
.withStackPlacement(this::getWorldPositionOf));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -333,6 +338,20 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyToAllItems(Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
|
||||||
|
BeltTileEntity controller = getControllerTE();
|
||||||
|
if (controller != null)
|
||||||
|
controller.getInventory()
|
||||||
|
.applyToEachWithin(index + .5f, .51f, processFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vec3d getWorldPositionOf(TransportedItemStack transported) {
|
||||||
|
BeltTileEntity controllerTE = getControllerTE();
|
||||||
|
if (controllerTE == null)
|
||||||
|
return Vec3d.ZERO;
|
||||||
|
return BeltHelper.getVectorForOffset(controllerTE, transported.beltPosition);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* always target a DirectBeltInsertionBehaviour
|
* always target a DirectBeltInsertionBehaviour
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
|||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
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.belt.TransportedItemStackHandlerBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@ -198,14 +199,18 @@ public class BeltInventory {
|
|||||||
// Continue processing if held
|
// Continue processing if held
|
||||||
if (currentItem.locked) {
|
if (currentItem.locked) {
|
||||||
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(currentSegment);
|
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(currentSegment);
|
||||||
|
TransportedItemStackHandlerBehaviour stackHandlerBehaviour =
|
||||||
|
getTransportedItemStackHandlerAtSegment(currentSegment);
|
||||||
|
|
||||||
|
if (stackHandlerBehaviour == null)
|
||||||
|
return false;
|
||||||
if (processingBehaviour == null) {
|
if (processingBehaviour == null) {
|
||||||
currentItem.locked = false;
|
currentItem.locked = false;
|
||||||
belt.sendData();
|
belt.sendData();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessingResult result = processingBehaviour.handleHeldItem(currentItem, this);
|
ProcessingResult result = processingBehaviour.handleHeldItem(currentItem, stackHandlerBehaviour);
|
||||||
if (result == ProcessingResult.REMOVE)
|
if (result == ProcessingResult.REMOVE)
|
||||||
return true;
|
return true;
|
||||||
if (result == ProcessingResult.HOLD)
|
if (result == ProcessingResult.HOLD)
|
||||||
@ -225,10 +230,17 @@ public class BeltInventory {
|
|||||||
: segment + .5f >= nextOffset; segment += step) {
|
: segment + .5f >= nextOffset; segment += step) {
|
||||||
|
|
||||||
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(segment);
|
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(segment);
|
||||||
|
TransportedItemStackHandlerBehaviour stackHandlerBehaviour =
|
||||||
|
getTransportedItemStackHandlerAtSegment(segment);
|
||||||
|
|
||||||
if (processingBehaviour == null)
|
if (processingBehaviour == null)
|
||||||
continue;
|
continue;
|
||||||
|
if (stackHandlerBehaviour == null)
|
||||||
|
continue;
|
||||||
|
if (BeltProcessingBehaviour.isBlocked(belt.getWorld(), BeltHelper.getPositionForOffset(belt, segment)))
|
||||||
|
continue;
|
||||||
|
|
||||||
ProcessingResult result = processingBehaviour.handleReceivedItem(currentItem, this);
|
ProcessingResult result = processingBehaviour.handleReceivedItem(currentItem, stackHandlerBehaviour);
|
||||||
if (result == ProcessingResult.REMOVE)
|
if (result == ProcessingResult.REMOVE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -249,6 +261,11 @@ public class BeltInventory {
|
|||||||
.up(2), BeltProcessingBehaviour.TYPE);
|
.up(2), BeltProcessingBehaviour.TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected TransportedItemStackHandlerBehaviour getTransportedItemStackHandlerAtSegment(int segment) {
|
||||||
|
return TileEntityBehaviour.get(belt.getWorld(), BeltHelper.getPositionForOffset(belt, segment),
|
||||||
|
TransportedItemStackHandlerBehaviour.TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
private enum Ending {
|
private enum Ending {
|
||||||
UNRESOLVED(0), EJECT(0), INSERT(.25f), FUNNEL(.35f), BLOCKED(.45f);
|
UNRESOLVED(0), EJECT(0), INSERT(.25f), FUNNEL(.35f), BLOCKED(.45f);
|
||||||
|
|
||||||
@ -379,16 +396,19 @@ public class BeltInventory {
|
|||||||
items.clear();
|
items.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachWithin(float position, float distance,
|
public void applyToEachWithin(float position, float maxDistanceToPosition,
|
||||||
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
|
||||||
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
||||||
boolean dirty = false;
|
boolean dirty = false;
|
||||||
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
|
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
|
||||||
TransportedItemStack transportedItemStack = iterator.next();
|
TransportedItemStack transportedItemStack = iterator.next();
|
||||||
if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
|
ItemStack stackBefore = transportedItemStack.stack.copy();
|
||||||
List<TransportedItemStack> apply = callback.apply(transportedItemStack);
|
if (Math.abs(position - transportedItemStack.beltPosition) < maxDistanceToPosition) {
|
||||||
|
List<TransportedItemStack> apply = processFunction.apply(transportedItemStack);
|
||||||
if (apply == null)
|
if (apply == null)
|
||||||
continue;
|
continue;
|
||||||
|
if (apply.size() == 1 && apply.get(0).stack.equals(stackBefore, false))
|
||||||
|
continue;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
toBeAdded.addAll(apply);
|
toBeAdded.addAll(apply);
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
|
@ -54,6 +54,7 @@ public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
|||||||
public TransportedItemStack copy() {
|
public TransportedItemStack copy() {
|
||||||
TransportedItemStack copy = getSimilar();
|
TransportedItemStack copy = getSimilar();
|
||||||
copy.angle = angle;
|
copy.angle = angle;
|
||||||
|
copy.sideOffset = sideOffset;
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import java.util.Optional;
|
|||||||
import com.simibubi.create.AllRecipeTypes;
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe;
|
import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe;
|
||||||
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
|
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
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.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
@ -70,8 +69,10 @@ public class InWorldProcessing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canProcess(ItemEntity entity, Type type) {
|
public static boolean canProcess(ItemEntity entity, Type type) {
|
||||||
if (entity.getPersistentData().contains("CreateData")) {
|
if (entity.getPersistentData()
|
||||||
CompoundNBT compound = entity.getPersistentData().getCompound("CreateData");
|
.contains("CreateData")) {
|
||||||
|
CompoundNBT compound = entity.getPersistentData()
|
||||||
|
.getCompound("CreateData");
|
||||||
if (compound.contains("Processing")) {
|
if (compound.contains("Processing")) {
|
||||||
CompoundNBT processing = compound.getCompound("Processing");
|
CompoundNBT processing = compound.getCompound("Processing");
|
||||||
|
|
||||||
@ -100,7 +101,8 @@ public class InWorldProcessing {
|
|||||||
SmokerTileEntity smoker = new SmokerTileEntity();
|
SmokerTileEntity smoker = new SmokerTileEntity();
|
||||||
smoker.setLocation(world, BlockPos.ZERO);
|
smoker.setLocation(world, BlockPos.ZERO);
|
||||||
smoker.setInventorySlotContents(0, stack);
|
smoker.setInventorySlotContents(0, stack);
|
||||||
Optional<SmokingRecipe> recipe = world.getRecipeManager().getRecipe(IRecipeType.SMOKING, smoker, world);
|
Optional<SmokingRecipe> recipe = world.getRecipeManager()
|
||||||
|
.getRecipe(IRecipeType.SMOKING, smoker, world);
|
||||||
return recipe.isPresent();
|
return recipe.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +114,8 @@ public class InWorldProcessing {
|
|||||||
|
|
||||||
public static boolean isWashable(ItemStack stack, World world) {
|
public static boolean isWashable(ItemStack stack, World world) {
|
||||||
splashingInv.setInventorySlotContents(0, stack);
|
splashingInv.setInventorySlotContents(0, stack);
|
||||||
Optional<SplashingRecipe> recipe =
|
Optional<SplashingRecipe> recipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world);
|
.getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world);
|
||||||
return recipe.isPresent();
|
return recipe.isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,15 +137,15 @@ public class InWorldProcessing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<TransportedItemStack> applyProcessing(TransportedItemStack transported, BeltTileEntity belt,
|
public static List<TransportedItemStack> applyProcessing(TransportedItemStack transported,
|
||||||
Type type) {
|
World world, Type type) {
|
||||||
if (transported.processedBy != type) {
|
if (transported.processedBy != type) {
|
||||||
transported.processedBy = type;
|
transported.processedBy = type;
|
||||||
int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
|
int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
|
||||||
int processingTime =
|
int processingTime =
|
||||||
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
|
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
|
||||||
transported.processingTime = processingTime;
|
transported.processingTime = processingTime;
|
||||||
if (!canProcess(transported.stack, type, belt.getWorld()))
|
if (!canProcess(transported.stack, type, world))
|
||||||
transported.processingTime = -1;
|
transported.processingTime = -1;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -152,15 +154,13 @@ public class InWorldProcessing {
|
|||||||
if (transported.processingTime-- > 0)
|
if (transported.processingTime-- > 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
List<ItemStack> stacks = process(transported.stack, type, belt.getWorld());
|
List<ItemStack> stacks = process(transported.stack, type, world);
|
||||||
if (stacks == null)
|
if (stacks == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
||||||
for (ItemStack additional : stacks) {
|
for (ItemStack additional : stacks) {
|
||||||
TransportedItemStack newTransported = transported.getSimilar();
|
TransportedItemStack newTransported = transported.getSimilar();
|
||||||
newTransported.beltPosition -= Math.signum(belt.getDirectionAwareBeltMovementSpeed()) * 1/32f;
|
|
||||||
newTransported.prevBeltPosition = newTransported.beltPosition;
|
|
||||||
newTransported.stack = additional.copy();
|
newTransported.stack = additional.copy();
|
||||||
transportedStacks.add(newTransported);
|
transportedStacks.add(newTransported);
|
||||||
}
|
}
|
||||||
@ -170,8 +170,8 @@ public class InWorldProcessing {
|
|||||||
private static List<ItemStack> process(ItemStack stack, Type type, World world) {
|
private static List<ItemStack> process(ItemStack stack, Type type, World world) {
|
||||||
if (type == Type.SPLASHING) {
|
if (type == Type.SPLASHING) {
|
||||||
splashingInv.setInventorySlotContents(0, stack);
|
splashingInv.setInventorySlotContents(0, stack);
|
||||||
Optional<SplashingRecipe> recipe =
|
Optional<SplashingRecipe> recipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world);
|
.getRecipe(AllRecipeTypes.SPLASHING.getType(), splashingInv, world);
|
||||||
if (recipe.isPresent())
|
if (recipe.isPresent())
|
||||||
return applyRecipeOn(stack, recipe.get());
|
return applyRecipeOn(stack, recipe.get());
|
||||||
return null;
|
return null;
|
||||||
@ -181,15 +181,16 @@ public class InWorldProcessing {
|
|||||||
SmokerTileEntity smoker = new SmokerTileEntity();
|
SmokerTileEntity smoker = new SmokerTileEntity();
|
||||||
smoker.setLocation(world, BlockPos.ZERO);
|
smoker.setLocation(world, BlockPos.ZERO);
|
||||||
smoker.setInventorySlotContents(0, stack);
|
smoker.setInventorySlotContents(0, stack);
|
||||||
Optional<SmokingRecipe> smokingRecipe = world.getRecipeManager().getRecipe(IRecipeType.SMOKING, smoker, world);
|
Optional<SmokingRecipe> smokingRecipe = world.getRecipeManager()
|
||||||
|
.getRecipe(IRecipeType.SMOKING, smoker, world);
|
||||||
|
|
||||||
if (type == Type.BLASTING) {
|
if (type == Type.BLASTING) {
|
||||||
// FIXME this does not need to be a TE
|
// FIXME this does not need to be a TE
|
||||||
FurnaceTileEntity furnace = new FurnaceTileEntity();
|
FurnaceTileEntity furnace = new FurnaceTileEntity();
|
||||||
furnace.setLocation(world, BlockPos.ZERO);
|
furnace.setLocation(world, BlockPos.ZERO);
|
||||||
furnace.setInventorySlotContents(0, stack);
|
furnace.setInventorySlotContents(0, stack);
|
||||||
Optional<FurnaceRecipe> smeltingRecipe =
|
Optional<FurnaceRecipe> smeltingRecipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(IRecipeType.SMELTING, furnace, world);
|
.getRecipe(IRecipeType.SMELTING, furnace, world);
|
||||||
|
|
||||||
if (!smokingRecipe.isPresent()) {
|
if (!smokingRecipe.isPresent()) {
|
||||||
if (smeltingRecipe.isPresent())
|
if (smeltingRecipe.isPresent())
|
||||||
@ -199,8 +200,8 @@ public class InWorldProcessing {
|
|||||||
BlastFurnaceTileEntity blastFurnace = new BlastFurnaceTileEntity();
|
BlastFurnaceTileEntity blastFurnace = new BlastFurnaceTileEntity();
|
||||||
blastFurnace.setLocation(world, BlockPos.ZERO);
|
blastFurnace.setLocation(world, BlockPos.ZERO);
|
||||||
blastFurnace.setInventorySlotContents(0, stack);
|
blastFurnace.setInventorySlotContents(0, stack);
|
||||||
Optional<BlastingRecipe> blastingRecipe =
|
Optional<BlastingRecipe> blastingRecipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(IRecipeType.BLASTING, blastFurnace, world);
|
.getRecipe(IRecipeType.BLASTING, blastFurnace, world);
|
||||||
|
|
||||||
if (blastingRecipe.isPresent())
|
if (blastingRecipe.isPresent())
|
||||||
return applyRecipeOn(stack, blastingRecipe.get());
|
return applyRecipeOn(stack, blastingRecipe.get());
|
||||||
@ -228,7 +229,8 @@ public class InWorldProcessing {
|
|||||||
|
|
||||||
if (!processing.contains("Type") || Type.valueOf(processing.getString("Type")) != type) {
|
if (!processing.contains("Type") || Type.valueOf(processing.getString("Type")) != type) {
|
||||||
processing.putString("Type", type.name());
|
processing.putString("Type", type.name());
|
||||||
int timeModifierForStackSize = ((entity.getItem().getCount() - 1) / 16) + 1;
|
int timeModifierForStackSize = ((entity.getItem()
|
||||||
|
.getCount() - 1) / 16) + 1;
|
||||||
int processingTime =
|
int processingTime =
|
||||||
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
|
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
|
||||||
processing.putInt("Time", processingTime);
|
processing.putInt("Time", processingTime);
|
||||||
@ -281,7 +283,8 @@ public class InWorldProcessing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ItemStack out = recipe.getRecipeOutput().copy();
|
ItemStack out = recipe.getRecipeOutput()
|
||||||
|
.copy();
|
||||||
stacks = ItemHelper.multipliedOutput(stackIn, out);
|
stacks = ItemHelper.multipliedOutput(stackIn, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,8 +307,8 @@ public class InWorldProcessing {
|
|||||||
case SPLASHING:
|
case SPLASHING:
|
||||||
Vec3d color = ColorHelper.getRGB(0x0055FF);
|
Vec3d color = ColorHelper.getRGB(0x0055FF);
|
||||||
world.addParticle(new RedstoneParticleData((float) color.x, (float) color.y, (float) color.z, 1),
|
world.addParticle(new RedstoneParticleData((float) color.x, (float) color.y, (float) color.z, 1),
|
||||||
vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f,
|
vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f, vec.z + (world.rand.nextFloat() - .5f) * .5f,
|
||||||
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
0, 1 / 8f, 0);
|
||||||
world.addParticle(ParticleTypes.SPIT, vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f,
|
world.addParticle(ParticleTypes.SPIT, vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f,
|
||||||
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -53,7 +53,7 @@ public class BeltObserverTileEntity extends SmartTileEntity {
|
|||||||
if (controllerTE == null)
|
if (controllerTE == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controllerTE.getInventory().forEachWithin(beltTE.index + .5f, .45f, stack -> {
|
controllerTE.getInventory().applyToEachWithin(beltTE.index + .5f, .45f, stack -> {
|
||||||
if (filtering.test(stack.stack) && turnOffTicks != 6) {
|
if (filtering.test(stack.stack) && turnOffTicks != 6) {
|
||||||
world.setBlockState(pos, getBlockState().with(BeltObserverBlock.POWERED, true));
|
world.setBlockState(pos, getBlockState().with(BeltObserverBlock.POWERED, true));
|
||||||
world.notifyNeighborsOfStateChange(pos, getBlockState().getBlock());
|
world.notifyNeighborsOfStateChange(pos, getBlockState().getBlock());
|
||||||
|
@ -1,15 +1,34 @@
|
|||||||
package com.simibubi.create.content.logistics.block.depot;
|
package com.simibubi.create.content.logistics.block.depot;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
|
import com.simibubi.create.AllTileEntities;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
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.belt.DirectBeltInputBehaviour;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.InventoryHelper;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
public class DepotBlock extends Block {
|
public class DepotBlock extends Block implements ITE<DepotTileEntity> {
|
||||||
|
|
||||||
public DepotBlock(Properties p_i48440_1_) {
|
public DepotBlock(Properties p_i48440_1_) {
|
||||||
super(p_i48440_1_);
|
super(p_i48440_1_);
|
||||||
@ -21,4 +40,93 @@ public class DepotBlock extends Block {
|
|||||||
return AllShapes.DEPOT;
|
return AllShapes.DEPOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTileEntity(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||||
|
return AllTileEntities.DEPOT.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<DepotTileEntity> getTileEntityClass() {
|
||||||
|
return DepotTileEntity.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||||
|
BlockRayTraceResult ray) {
|
||||||
|
if (ray.getFace() != Direction.UP)
|
||||||
|
return ActionResultType.PASS;
|
||||||
|
if (world.isRemote)
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
|
||||||
|
withTileEntityDo(world, pos, te -> {
|
||||||
|
boolean wasEmptyHanded = player.getHeldItem(hand)
|
||||||
|
.isEmpty();
|
||||||
|
|
||||||
|
ItemStack mainItemStack = te.getHeldItemStack();
|
||||||
|
if (!mainItemStack.isEmpty()) {
|
||||||
|
player.inventory.placeItemBackInInventory(world, mainItemStack);
|
||||||
|
te.setHeldItem(null);
|
||||||
|
}
|
||||||
|
ItemStackHandler outputs = te.processingOutputBuffer;
|
||||||
|
for (int i = 0; i < outputs.getSlots(); i++)
|
||||||
|
player.inventory.placeItemBackInInventory(world, outputs.extractItem(i, 64, false));
|
||||||
|
|
||||||
|
if (!wasEmptyHanded) {
|
||||||
|
TransportedItemStack heldItem = new TransportedItemStack(player.getHeldItem(hand));
|
||||||
|
heldItem.insertedFrom = player.getHorizontalFacing();
|
||||||
|
heldItem.prevBeltPosition = .25f;
|
||||||
|
heldItem.beltPosition = .25f;
|
||||||
|
te.setHeldItem(heldItem);
|
||||||
|
player.setHeldItem(hand, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
});
|
||||||
|
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
|
if (!state.hasTileEntity() || state.getBlock() == newState.getBlock()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
withTileEntityDo(worldIn, pos, te -> {
|
||||||
|
ItemHelper.dropContents(worldIn, pos, te.processingOutputBuffer);
|
||||||
|
if (!te.getHeldItemStack()
|
||||||
|
.isEmpty())
|
||||||
|
InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), te.getHeldItemStack());
|
||||||
|
});
|
||||||
|
worldIn.removeTileEntity(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLanded(IBlockReader worldIn, Entity entityIn) {
|
||||||
|
super.onLanded(worldIn, entityIn);
|
||||||
|
if (!AllBlocks.DEPOT.has(worldIn.getBlockState(entityIn.getPosition())))
|
||||||
|
return;
|
||||||
|
if (!(entityIn instanceof ItemEntity))
|
||||||
|
return;
|
||||||
|
if (!entityIn.isAlive())
|
||||||
|
return;
|
||||||
|
if (entityIn.world.isRemote)
|
||||||
|
return;
|
||||||
|
ItemEntity itemEntity = (ItemEntity) entityIn;
|
||||||
|
DirectBeltInputBehaviour inputBehaviour =
|
||||||
|
TileEntityBehaviour.get(worldIn, entityIn.getPosition(), DirectBeltInputBehaviour.TYPE);
|
||||||
|
if (inputBehaviour == null)
|
||||||
|
return;
|
||||||
|
ItemStack remainder = inputBehaviour.handleInsertion(itemEntity.getItem(), Direction.DOWN, false);
|
||||||
|
itemEntity.setItem(remainder);
|
||||||
|
if (remainder.isEmpty())
|
||||||
|
itemEntity.remove();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,74 @@
|
|||||||
|
package com.simibubi.create.content.logistics.block.depot;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
public class DepotItemHandler implements IItemHandler {
|
||||||
|
|
||||||
|
private static final int MAIN_SLOT = 0;
|
||||||
|
private DepotTileEntity te;
|
||||||
|
|
||||||
|
public DepotItemHandler(DepotTileEntity te) {
|
||||||
|
this.te = te;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlots() {
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlot(int slot) {
|
||||||
|
return slot == MAIN_SLOT ? te.getHeldItemStack() : te.processingOutputBuffer.getStackInSlot(slot - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||||
|
if (slot != MAIN_SLOT)
|
||||||
|
return stack;
|
||||||
|
if (!te.getHeldItemStack()
|
||||||
|
.isEmpty())
|
||||||
|
return stack;
|
||||||
|
if (!te.isOutputEmpty())
|
||||||
|
return stack;
|
||||||
|
if (!simulate) {
|
||||||
|
te.setHeldItem(new TransportedItemStack(stack));
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
}
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
|
if (slot != MAIN_SLOT)
|
||||||
|
return te.processingOutputBuffer.extractItem(slot - 1, amount, simulate);
|
||||||
|
|
||||||
|
TransportedItemStack held = te.heldItem;
|
||||||
|
if (held == null)
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
ItemStack stack = held.stack.copy();
|
||||||
|
ItemStack extracted = stack.split(amount);
|
||||||
|
if (!simulate) {
|
||||||
|
te.heldItem.stack = stack;
|
||||||
|
if (stack.isEmpty())
|
||||||
|
te.heldItem = null;
|
||||||
|
te.markDirty();
|
||||||
|
te.sendData();
|
||||||
|
}
|
||||||
|
return extracted;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotLimit(int slot) {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValid(int slot, ItemStack stack) {
|
||||||
|
return slot == MAIN_SLOT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
package com.simibubi.create.content.logistics.block.depot;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||||
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.client.renderer.ItemRenderer;
|
||||||
|
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||||
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
|
||||||
|
|
||||||
|
public DepotRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||||
|
super(dispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderSafe(DepotTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||||
|
int light, int overlay) {
|
||||||
|
|
||||||
|
TransportedItemStack transported = te.heldItem;
|
||||||
|
MatrixStacker msr = MatrixStacker.of(ms);
|
||||||
|
|
||||||
|
ms.push();
|
||||||
|
ms.translate(.5f, 15 / 16f, .5f);
|
||||||
|
|
||||||
|
// Render main item
|
||||||
|
if (transported != null) {
|
||||||
|
ms.push();
|
||||||
|
msr.nudge(0);
|
||||||
|
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
|
||||||
|
float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset);
|
||||||
|
Vec3d offsetVec = new Vec3d(transported.insertedFrom.getOpposite()
|
||||||
|
.getDirectionVec()).scale(.5f - offset);
|
||||||
|
ms.translate(offsetVec.x, offsetVec.y, offsetVec.z);
|
||||||
|
|
||||||
|
if (transported.insertedFrom.getAxis()
|
||||||
|
.isHorizontal()) {
|
||||||
|
boolean alongX = transported.insertedFrom.rotateY()
|
||||||
|
.getAxis() == Axis.X;
|
||||||
|
if (!alongX)
|
||||||
|
sideOffset *= -1;
|
||||||
|
ms.translate(alongX ? sideOffset : 0, 0, alongX ? 0 : sideOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemStack = transported.stack;
|
||||||
|
int angle = transported.angle;
|
||||||
|
Random r = new Random(0);
|
||||||
|
renderItem(ms, buffer, light, overlay, itemStack, angle, r);
|
||||||
|
ms.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render output items
|
||||||
|
for (int i = 0; i < te.processingOutputBuffer.getSlots(); i++) {
|
||||||
|
ItemStack stack = te.processingOutputBuffer.getStackInSlot(i);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
continue;
|
||||||
|
ms.push();
|
||||||
|
msr.nudge(i);
|
||||||
|
msr.rotateY(360 / 8f * i);
|
||||||
|
ms.translate(.35f, 0, 0);
|
||||||
|
Random r = new Random(i + 1);
|
||||||
|
int angle = (int) (360 * r.nextFloat());
|
||||||
|
renderItem(ms, buffer, light, overlay, stack, angle, r);
|
||||||
|
ms.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
ms.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void renderItem(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay, ItemStack itemStack,
|
||||||
|
int angle, Random r) {
|
||||||
|
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||||
|
.getItemRenderer();
|
||||||
|
MatrixStacker msr = MatrixStacker.of(ms);
|
||||||
|
int count = (int) (MathHelper.log2((int) (itemStack.getCount()))) / 2;
|
||||||
|
boolean blockItem = itemRenderer.getItemModelWithOverrides(itemStack, null, null)
|
||||||
|
.isGui3d();
|
||||||
|
for (int i = 0; i <= count; i++) {
|
||||||
|
ms.push();
|
||||||
|
msr.rotateY(angle);
|
||||||
|
if (!blockItem) {
|
||||||
|
ms.translate(0, -.09375, 0);
|
||||||
|
msr.rotateX(90);
|
||||||
|
}
|
||||||
|
if (blockItem)
|
||||||
|
ms.translate(r.nextFloat() * .0625f * i, 0, r.nextFloat() * .0625f * i);
|
||||||
|
ms.scale(.5f, .5f, .5f);
|
||||||
|
itemRenderer.renderItem(itemStack, TransformType.FIXED, light, overlay, ms, buffer);
|
||||||
|
ms.pop();
|
||||||
|
|
||||||
|
if (!blockItem)
|
||||||
|
msr.rotateY(10);
|
||||||
|
ms.translate(0, blockItem ? 1 / 64d : 1 / 16d, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,203 @@
|
|||||||
|
package com.simibubi.create.content.logistics.block.depot;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.common.capabilities.Capability;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
|
||||||
|
public class DepotTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
|
TransportedItemStack heldItem;
|
||||||
|
ItemStackHandler processingOutputBuffer;
|
||||||
|
|
||||||
|
DepotItemHandler itemHandler;
|
||||||
|
LazyOptional<DepotItemHandler> lazyItemHandler;
|
||||||
|
|
||||||
|
public DepotTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||||
|
super(tileEntityTypeIn);
|
||||||
|
itemHandler = new DepotItemHandler(this);
|
||||||
|
lazyItemHandler = LazyOptional.of(() -> itemHandler);
|
||||||
|
processingOutputBuffer = new ItemStackHandler(8) {
|
||||||
|
protected void onContentsChanged(int slot) {
|
||||||
|
markDirty();
|
||||||
|
sendData();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
|
if (heldItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
heldItem.prevBeltPosition = heldItem.beltPosition;
|
||||||
|
heldItem.prevSideOffset = heldItem.sideOffset;
|
||||||
|
float diff = .5f - heldItem.beltPosition;
|
||||||
|
if (diff > 1 / 512f) {
|
||||||
|
if (diff > 1 / 32f)
|
||||||
|
heldItem.angle += 1;
|
||||||
|
heldItem.beltPosition += diff / 4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diff > 1 / 16f)
|
||||||
|
return;
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BeltProcessingBehaviour processingBehaviour =
|
||||||
|
TileEntityBehaviour.get(world, pos.up(2), BeltProcessingBehaviour.TYPE);
|
||||||
|
if (processingBehaviour == null)
|
||||||
|
return;
|
||||||
|
if (!heldItem.locked && BeltProcessingBehaviour.isBlocked(world, pos))
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean wasLocked = heldItem.locked;
|
||||||
|
ItemStack previousItem = heldItem.stack;
|
||||||
|
TransportedItemStackHandlerBehaviour handler = getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
||||||
|
ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, handler)
|
||||||
|
: processingBehaviour.handleReceivedItem(heldItem, handler);
|
||||||
|
if (result == ProcessingResult.REMOVE) {
|
||||||
|
heldItem = null;
|
||||||
|
sendData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
heldItem.locked = result == ProcessingResult.HOLD;
|
||||||
|
if (heldItem.locked != wasLocked || !previousItem.equals(heldItem.stack, false))
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
|
if (heldItem != null)
|
||||||
|
compound.put("HeldItem", heldItem.serializeNBT());
|
||||||
|
compound.put("OutputBuffer", processingOutputBuffer.serializeNBT());
|
||||||
|
return super.write(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(CompoundNBT compound) {
|
||||||
|
heldItem = null;
|
||||||
|
if (compound.contains("HeldItem"))
|
||||||
|
heldItem = TransportedItemStack.read(compound.getCompound("HeldItem"));
|
||||||
|
processingOutputBuffer.deserializeNBT(compound.getCompound("OutputBuffer"));
|
||||||
|
super.read(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
behaviours.add(new DirectBeltInputBehaviour(this).setInsertionHandler(this::tryInsertingFromSide));
|
||||||
|
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||||
|
.withStackPlacement(this::getWorldPositionOf));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getHeldItemStack() {
|
||||||
|
return heldItem == null ? ItemStack.EMPTY : heldItem.stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeldItem(TransportedItemStack heldItem) {
|
||||||
|
this.heldItem = heldItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||||
|
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||||
|
return lazyItemHandler.cast();
|
||||||
|
return super.getCapability(cap, side);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||||
|
ItemStack inserted = transportedStack.stack;
|
||||||
|
ItemStack empty = ItemStack.EMPTY;
|
||||||
|
|
||||||
|
if (!getHeldItemStack().isEmpty())
|
||||||
|
return inserted;
|
||||||
|
if (!isOutputEmpty())
|
||||||
|
return inserted;
|
||||||
|
if (simulate)
|
||||||
|
return empty;
|
||||||
|
|
||||||
|
transportedStack = transportedStack.copy();
|
||||||
|
transportedStack.beltPosition = side.getAxis()
|
||||||
|
.isVertical() ? .5f : 0;
|
||||||
|
transportedStack.insertedFrom = side;
|
||||||
|
transportedStack.prevSideOffset = transportedStack.sideOffset;
|
||||||
|
transportedStack.prevBeltPosition = transportedStack.beltPosition;
|
||||||
|
setHeldItem(transportedStack);
|
||||||
|
markDirty();
|
||||||
|
sendData();
|
||||||
|
|
||||||
|
return empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyToAllItems(Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
|
||||||
|
if (heldItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean dirty = false;
|
||||||
|
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
||||||
|
TransportedItemStack transportedItemStack = heldItem;
|
||||||
|
ItemStack stackBefore = transportedItemStack.stack.copy();
|
||||||
|
List<TransportedItemStack> apply = processFunction.apply(transportedItemStack);
|
||||||
|
|
||||||
|
if (apply == null)
|
||||||
|
return;
|
||||||
|
if (apply.size() == 1 && apply.get(0).stack.equals(stackBefore, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
dirty = true;
|
||||||
|
heldItem = null;
|
||||||
|
toBeAdded.addAll(apply);
|
||||||
|
for (TransportedItemStack added : toBeAdded) {
|
||||||
|
if (heldItem == null) {
|
||||||
|
heldItem = added;
|
||||||
|
heldItem.beltPosition = 0.5f;
|
||||||
|
heldItem.prevBeltPosition = 0.5f;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < processingOutputBuffer.getSlots(); i++) {
|
||||||
|
ItemStack stackInSlot = processingOutputBuffer.getStackInSlot(i);
|
||||||
|
if (!stackInSlot.isEmpty())
|
||||||
|
continue;
|
||||||
|
processingOutputBuffer.setStackInSlot(i, added.stack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty) {
|
||||||
|
markDirty();
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOutputEmpty() {
|
||||||
|
for (int i = 0; i < processingOutputBuffer.getSlots(); i++)
|
||||||
|
if (!processingOutputBuffer.getStackInSlot(i).isEmpty())
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vec3d getWorldPositionOf(TransportedItemStack transported) {
|
||||||
|
Vec3d offsetVec = new Vec3d(.5f, 14 / 16f, .5f);
|
||||||
|
return offsetVec.add(new Vec3d(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -138,7 +138,7 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
|||||||
if (controllerBelt == null)
|
if (controllerBelt == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controllerBelt.getInventory().forEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
|
controllerBelt.getInventory().applyToEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> {
|
||||||
controllerBelt.getInventory().eject(transportedItemStack);
|
controllerBelt.getInventory().eject(transportedItemStack);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
});
|
});
|
||||||
|
@ -7,7 +7,7 @@ import net.minecraft.nbt.CompoundNBT;
|
|||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.ILightReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public abstract class TileEntityBehaviour {
|
public abstract class TileEntityBehaviour {
|
||||||
@ -90,12 +90,12 @@ public abstract class TileEntityBehaviour {
|
|||||||
return tileEntity.getWorld();
|
return tileEntity.getWorld();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends TileEntityBehaviour> T get(ILightReader reader, BlockPos pos,
|
public static <T extends TileEntityBehaviour> T get(IBlockReader reader, BlockPos pos,
|
||||||
BehaviourType<T> type) {
|
BehaviourType<T> type) {
|
||||||
return get(reader.getTileEntity(pos), type);
|
return get(reader.getTileEntity(pos), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends TileEntityBehaviour> void destroy(ILightReader reader, BlockPos pos,
|
public static <T extends TileEntityBehaviour> void destroy(IBlockReader reader, BlockPos pos,
|
||||||
BehaviourType<T> type) {
|
BehaviourType<T> type) {
|
||||||
T behaviour = get(reader.getTileEntity(pos), type);
|
T behaviour = get(reader.getTileEntity(pos), type);
|
||||||
if (behaviour != null)
|
if (behaviour != null)
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
|
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
|
||||||
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.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Behaviour for TileEntities which can process items on belts or depots beneath them.
|
* Behaviour for TileEntities which can process items on belts or depots beneath
|
||||||
* Currently only supports placement location 2 spaces above the belt block.
|
* them. Currently only supports placement location 2 spaces above the belt
|
||||||
* Example use: Mechanical Press
|
* block. Example use: Mechanical Press
|
||||||
*/
|
*/
|
||||||
public class BeltProcessingBehaviour extends TileEntityBehaviour {
|
public class BeltProcessingBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
@ -38,22 +40,29 @@ public class BeltProcessingBehaviour extends TileEntityBehaviour {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBlocked(IBlockReader world, BlockPos processingSpace) {
|
||||||
|
return !world.getBlockState(processingSpace.up())
|
||||||
|
.getCollisionShape(world, processingSpace.up())
|
||||||
|
.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProcessingResult handleReceivedItem(TransportedItemStack stack, BeltInventory inventory) {
|
public ProcessingResult handleReceivedItem(TransportedItemStack stack,
|
||||||
|
TransportedItemStackHandlerBehaviour inventory) {
|
||||||
return onItemEnter.apply(stack, inventory);
|
return onItemEnter.apply(stack, inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProcessingResult handleHeldItem(TransportedItemStack stack, BeltInventory inventory) {
|
public ProcessingResult handleHeldItem(TransportedItemStack stack, TransportedItemStackHandlerBehaviour inventory) {
|
||||||
return continueProcessing.apply(stack, inventory);
|
return continueProcessing.apply(stack, inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface ProcessingCallback {
|
public interface ProcessingCallback {
|
||||||
public ProcessingResult apply(TransportedItemStack stack, BeltInventory inventory);
|
public ProcessingResult apply(TransportedItemStack stack, TransportedItemStackHandlerBehaviour inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
public class TransportedItemStackHandlerBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
|
public static BehaviourType<TransportedItemStackHandlerBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
private ProcessingCallback processingCallback;
|
||||||
|
private PositionGetter positionGetter;
|
||||||
|
|
||||||
|
public TransportedItemStackHandlerBehaviour(SmartTileEntity te, ProcessingCallback processingCallback) {
|
||||||
|
super(te);
|
||||||
|
this.processingCallback = processingCallback;
|
||||||
|
positionGetter = t -> VecHelper.getCenterOf(te.getPos());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransportedItemStackHandlerBehaviour withStackPlacement(PositionGetter function) {
|
||||||
|
this.positionGetter = function;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleProcessingOnAllItems(Function<TransportedItemStack, List<TransportedItemStack>> processFunction) {
|
||||||
|
this.processingCallback.applyToAllItems(processFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vec3d getWorldPositionOf(TransportedItemStack transported) {
|
||||||
|
return positionGetter.getWorldPositionVector(transported);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BehaviourType<?> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ProcessingCallback {
|
||||||
|
public void applyToAllItems(Function<TransportedItemStack, List<TransportedItemStack>> processFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface PositionGetter {
|
||||||
|
public Vec3d getWorldPositionVector(TransportedItemStack transported);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,7 +10,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
public class Iterate {
|
public class Iterate {
|
||||||
|
|
||||||
public static final boolean[] trueAndFalse = { true, false };
|
public static final boolean[] trueAndFalse = { true, false };
|
||||||
public static final int[] zeroAndOne = { 1, -1 };
|
public static final int[] zeroAndOne = { 0, 1 };
|
||||||
public static final int[] positiveAndNegative = { 1, -1 };
|
public static final int[] positiveAndNegative = { 1, -1 };
|
||||||
public static final Direction[] directions = Direction.values();
|
public static final Direction[] directions = Direction.values();
|
||||||
public static final Direction[] horizontalDirections = getHorizontals();
|
public static final Direction[] horizontalDirections = getHorizontals();
|
||||||
|
Loading…
Reference in New Issue
Block a user