mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-24 14:06:42 +01:00
The Transposer
- Added behaviours to the Transposer tileentity - Created new Inserting Behaviour for item management - Fixed extractors syncing with extractors attached to other inventories
This commit is contained in:
parent
c682247894
commit
7059cf2737
6 changed files with 53 additions and 243 deletions
|
@ -8,8 +8,11 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.simibubi.create.foundation.behaviour.base.IBehaviourType;
|
import com.simibubi.create.foundation.behaviour.base.IBehaviourType;
|
||||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class InsertingBehaviour extends InventoryManagementBehaviour {
|
public class InsertingBehaviour extends InventoryManagementBehaviour {
|
||||||
|
|
||||||
|
@ -20,6 +23,15 @@ public class InsertingBehaviour extends InventoryManagementBehaviour {
|
||||||
super(te, attachments);
|
super(te, attachments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ItemStack insert(ItemStack stack, boolean simulate) {
|
||||||
|
for (IItemHandler inv : getInventories()) {
|
||||||
|
stack = ItemHandlerHelper.insertItemStacked(inv, stack, simulate);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public IBehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
|
|
|
@ -103,7 +103,8 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static class Attachments {
|
public static class Attachments {
|
||||||
public static final Supplier<List<Pair<BlockPos, Direction>>> toward(Supplier<Direction> facing) {
|
public static final Supplier<List<Pair<BlockPos, Direction>>> toward(Supplier<Direction> facing) {
|
||||||
return () -> ImmutableList.of(Pair.of(new BlockPos(facing.get().getDirectionVec()), facing.get()));
|
return () -> ImmutableList
|
||||||
|
.of(Pair.of(new BlockPos(facing.get().getDirectionVec()), facing.get().getOpposite()));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,9 @@ public class SynchronizedExtraction {
|
||||||
continue;
|
continue;
|
||||||
if (!behaviour.shouldExtract.get())
|
if (!behaviour.shouldExtract.get())
|
||||||
continue;
|
continue;
|
||||||
|
if (!behaviour.inventories.keySet().stream()
|
||||||
|
.anyMatch(p -> p.getKey().add(behaviour.getPos()).equals(pos)))
|
||||||
|
continue;
|
||||||
|
|
||||||
list.add(behaviour);
|
list.add(behaviour);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,224 +0,0 @@
|
||||||
package com.simibubi.create.modules.logistics.block;
|
|
||||||
|
|
||||||
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.CreateConfig;
|
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
|
|
||||||
import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity;
|
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.SoundCategory;
|
|
||||||
import net.minecraft.util.SoundEvents;
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
|
|
||||||
// Its like delegation but worse!
|
|
||||||
public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
|
|
||||||
|
|
||||||
public enum State {
|
|
||||||
WAITING_FOR_INVENTORY, WAITING_FOR_ENTITY, RUNNING, ON_COOLDOWN, LOCKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public State getState();
|
|
||||||
|
|
||||||
public void setState(State state);
|
|
||||||
|
|
||||||
public int tickCooldown();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default void tick() {
|
|
||||||
if (isFrozen())
|
|
||||||
return;
|
|
||||||
|
|
||||||
State state = getState();
|
|
||||||
|
|
||||||
if (state == State.LOCKED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (state == State.ON_COOLDOWN || state == State.WAITING_FOR_INVENTORY) {
|
|
||||||
int cooldown = tickCooldown();
|
|
||||||
if (cooldown <= 0) {
|
|
||||||
setState(State.RUNNING);
|
|
||||||
if (!getInventory().isPresent())
|
|
||||||
findNewInventory();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasSpace = hasSpaceForExtracting();
|
|
||||||
boolean hasInventory = getInventory().isPresent();
|
|
||||||
ItemStack toExtract = ItemStack.EMPTY;
|
|
||||||
|
|
||||||
if (hasSpace && hasInventory) {
|
|
||||||
toExtract = extract(true);
|
|
||||||
|
|
||||||
if (!matchesFilter(toExtract))
|
|
||||||
toExtract = ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == State.WAITING_FOR_ENTITY) {
|
|
||||||
if (hasSpace)
|
|
||||||
setState(State.RUNNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == State.RUNNING) {
|
|
||||||
if (!hasSpace) {
|
|
||||||
setState(State.WAITING_FOR_ENTITY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!hasInventory || toExtract.isEmpty()) {
|
|
||||||
setState(State.WAITING_FOR_INVENTORY);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
extract(false);
|
|
||||||
setState(State.ON_COOLDOWN);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean matchesFilter(ItemStack stack) {
|
|
||||||
FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get((TileEntity) this, FilteringBehaviour.TYPE);
|
|
||||||
return filteringBehaviour == null || filteringBehaviour.test(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public default void setLocked(boolean locked) {
|
|
||||||
setState(locked ? State.LOCKED : State.ON_COOLDOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public default void neighborChanged() {
|
|
||||||
if (isFrozen())
|
|
||||||
return;
|
|
||||||
|
|
||||||
boolean hasSpace = hasSpaceForExtracting();
|
|
||||||
boolean hasInventory = getInventory().isPresent();
|
|
||||||
ItemStack toExtract = ItemStack.EMPTY;
|
|
||||||
|
|
||||||
if (hasSpace && hasInventory) {
|
|
||||||
toExtract = extract(true);
|
|
||||||
if (!matchesFilter(toExtract))
|
|
||||||
toExtract = ItemStack.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getState() == State.WAITING_FOR_INVENTORY) {
|
|
||||||
if (!hasInventory) {
|
|
||||||
if (findNewInventory()) {
|
|
||||||
setState(State.RUNNING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!toExtract.isEmpty())
|
|
||||||
setState(State.RUNNING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean hasSpaceForExtracting() {
|
|
||||||
BlockPos pos = getPos();
|
|
||||||
World world = getWorld();
|
|
||||||
|
|
||||||
if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) {
|
|
||||||
TileEntity te = world.getTileEntity(pos.down());
|
|
||||||
if (te != null && te instanceof BeltTileEntity) {
|
|
||||||
BeltTileEntity belt = (BeltTileEntity) te;
|
|
||||||
BeltTileEntity controller = belt.getControllerTE();
|
|
||||||
if (controller != null) {
|
|
||||||
if (!controller.getInventory().canInsertFrom(belt.index, Direction.UP))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return world.getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
default ItemStack extract(boolean simulate) {
|
|
||||||
IItemHandler inv = getInventory().orElse(null);
|
|
||||||
ItemStack extracting = ItemStack.EMPTY;
|
|
||||||
FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get((TileEntity) this, FilteringBehaviour.TYPE);
|
|
||||||
ItemStack filterItem = filteringBehaviour == null ? ItemStack.EMPTY : filteringBehaviour.getFilter();
|
|
||||||
World world = getWorld();
|
|
||||||
int extractionCount = filterItem.isEmpty() ? CreateConfig.parameters.extractorAmount.get()
|
|
||||||
: filterItem.getCount();
|
|
||||||
boolean checkHasEnoughItems = !filterItem.isEmpty();
|
|
||||||
boolean hasEnoughItems = !checkHasEnoughItems;
|
|
||||||
|
|
||||||
Extraction: do {
|
|
||||||
extracting = ItemStack.EMPTY;
|
|
||||||
|
|
||||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
|
||||||
ItemStack stack = inv.extractItem(slot, extractionCount - extracting.getCount(), true);
|
|
||||||
ItemStack compare = stack.copy();
|
|
||||||
|
|
||||||
compare.setCount(filterItem.getCount());
|
|
||||||
if (!filterItem.isEmpty() && !filterItem.equals(compare, false))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
compare.setCount(extracting.getCount());
|
|
||||||
if (!extracting.isEmpty() && !extracting.equals(compare, false))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (extracting.isEmpty())
|
|
||||||
extracting = stack.copy();
|
|
||||||
else
|
|
||||||
extracting.grow(stack.getCount());
|
|
||||||
|
|
||||||
if (!simulate && hasEnoughItems)
|
|
||||||
inv.extractItem(slot, stack.getCount(), false);
|
|
||||||
|
|
||||||
if (extracting.getCount() >= extractionCount) {
|
|
||||||
if (checkHasEnoughItems) {
|
|
||||||
hasEnoughItems = true;
|
|
||||||
checkHasEnoughItems = false;
|
|
||||||
continue Extraction;
|
|
||||||
} else {
|
|
||||||
break Extraction;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkHasEnoughItems)
|
|
||||||
checkHasEnoughItems = false;
|
|
||||||
else
|
|
||||||
break Extraction;
|
|
||||||
} while (true);
|
|
||||||
|
|
||||||
if (!simulate && hasEnoughItems) {
|
|
||||||
Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
|
||||||
Entity entityIn = null;
|
|
||||||
|
|
||||||
if (extracting.getItem() instanceof CardboardBoxItem) {
|
|
||||||
Direction face = getWorld().getBlockState(getPos()).get(HORIZONTAL_FACING).getOpposite();
|
|
||||||
entityIn = new CardboardBoxEntity(world, entityPos, extracting, face);
|
|
||||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .25f, .05f);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
entityIn = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, extracting);
|
|
||||||
entityIn.setMotion(Vec3d.ZERO);
|
|
||||||
world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
world.addEntity(entityIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
return extracting;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFrozen() {
|
|
||||||
return CreateConfig.parameters.freezeExtractors.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -30,10 +30,10 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class ExtractorTileEntity extends SmartTileEntity {
|
public class ExtractorTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
private static FilteringBehaviour.SlotPositioning slots;
|
protected static FilteringBehaviour.SlotPositioning slots;
|
||||||
|
|
||||||
private ExtractingBehaviour extracting;
|
protected ExtractingBehaviour extracting;
|
||||||
private FilteringBehaviour filtering;
|
protected FilteringBehaviour filtering;
|
||||||
|
|
||||||
public ExtractorTileEntity() {
|
public ExtractorTileEntity() {
|
||||||
this(AllTileEntities.EXTRACTOR.type);
|
this(AllTileEntities.EXTRACTOR.type);
|
||||||
|
@ -59,7 +59,7 @@ public class ExtractorTileEntity extends SmartTileEntity {
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onExtract(ItemStack stack) {
|
protected void onExtract(ItemStack stack) {
|
||||||
Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0);
|
||||||
Entity entityIn = null;
|
Entity entityIn = null;
|
||||||
Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState());
|
Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState());
|
||||||
|
@ -88,7 +88,7 @@ public class ExtractorTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canExtract() {
|
protected boolean canExtract() {
|
||||||
if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) {
|
if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) {
|
||||||
TileEntity te = world.getTileEntity(pos.down());
|
TileEntity te = world.getTileEntity(pos.down());
|
||||||
if (te != null && te instanceof BeltTileEntity) {
|
if (te != null && te instanceof BeltTileEntity) {
|
||||||
|
|
|
@ -3,19 +3,19 @@ package com.simibubi.create.modules.logistics.block.transposer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
|
|
||||||
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour;
|
||||||
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning;
|
import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments;
|
||||||
import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
|
import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock;
|
||||||
|
import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class TransposerTileEntity extends SmartTileEntity {
|
public class TransposerTileEntity extends ExtractorTileEntity {
|
||||||
|
|
||||||
private static FilteringBehaviour.SlotPositioning slots;
|
private InsertingBehaviour inserting;
|
||||||
private FilteringBehaviour filtering;
|
|
||||||
|
|
||||||
public TransposerTileEntity() {
|
public TransposerTileEntity() {
|
||||||
this(AllTileEntities.TRANSPOSER.type);
|
this(AllTileEntities.TRANSPOSER.type);
|
||||||
|
@ -27,15 +27,33 @@ public class TransposerTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
if (slots == null)
|
super.addBehaviours(behaviours);
|
||||||
slots = new SlotPositioning(ExtractorBlock::getFilterSlotPosition, ExtractorBlock::getFilterSlotOrientation)
|
inserting = new InsertingBehaviour(this,
|
||||||
.scale(.4f);
|
Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite()));
|
||||||
filtering = new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots)
|
behaviours.add(inserting);
|
||||||
.showCount();
|
extracting.withSpecialFilter(this::shouldExtract);
|
||||||
behaviours.add(filtering);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void filterChanged(ItemStack stack) {
|
public void filterChanged(ItemStack stack) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean shouldExtract(ItemStack stack) {
|
||||||
|
if (filtering.getFilter().isEmpty())
|
||||||
|
return true;
|
||||||
|
return inserting.insert(stack, true).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canExtract() {
|
||||||
|
return inserting.getInventory() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onExtract(ItemStack stack) {
|
||||||
|
ItemStack remainder = inserting.insert(stack, false);
|
||||||
|
remainder = ItemHandlerHelper.insertItemStacked(extracting.getInventory(), remainder, false);
|
||||||
|
if (!remainder.isEmpty())
|
||||||
|
super.onExtract(remainder);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue