Begin the ContainerBuilder system

Right now it doesn't do much and the internal code is quite ugly.
This commit is contained in:
Ourten 2017-01-06 00:43:21 +01:00
parent 56b8b346f0
commit b70d9b41c6
11 changed files with 428 additions and 93 deletions

View file

@ -1,12 +1,14 @@
package techreborn.client;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import reborncore.api.tile.IContainerLayout;
import reborncore.common.container.RebornContainer;
import techreborn.client.container.*;
import techreborn.client.container.builder.ContainerBuilder;
import techreborn.client.gui.*;
import techreborn.manual.GuiManual;
import techreborn.tiles.*;
@ -75,11 +77,11 @@ public class GuiHandler implements IGuiHandler {
return new ContainerGasTurbine((TileGasTurbine) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == quantumTankID) {
return new ContainerQuantumTank((TileQuantumTank) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == digitalChestID) {
return new ContainerDigitalChest((TileDigitalChest) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == quantumChestID) {
return new ContainerQuantumChest((TileQuantumChest) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == centrifugeID) {
} else if (ID == GuiHandler.digitalChestID || ID == GuiHandler.quantumChestID) {
return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory()
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).slot(0, 80, 17).output(1, 80, 53)
.fake(2, 59, 42).addInventory().create();
} else if (ID == GuiHandler.centrifugeID) {
container = new ContainerCentrifuge(player, (TileCentrifuge) world.getTileEntity(new BlockPos(x, y, z)));
} else if (ID == rollingMachineID) {
return new ContainerRollingMachine((TileRollingMachine) world.getTileEntity(new BlockPos(x, y, z)), player);

View file

@ -1,41 +0,0 @@
package techreborn.client.container;
import net.minecraft.entity.player.EntityPlayer;
import reborncore.client.gui.slots.BaseSlot;
import reborncore.client.gui.slots.SlotFake;
import reborncore.client.gui.slots.SlotOutput;
import reborncore.common.container.RebornContainer;
import techreborn.tiles.TileDigitalChest;
public class ContainerDigitalChest extends RebornContainer {
public TileDigitalChest tileDigitalChest;
public EntityPlayer player;
public ContainerDigitalChest(TileDigitalChest tileDigitalChest, EntityPlayer player) {
super();
this.tileDigitalChest = tileDigitalChest;
this.player = player;
this.addSlotToContainer(new BaseSlot(tileDigitalChest.inventory, 0, 80, 17));
this.addSlotToContainer(new SlotOutput(tileDigitalChest.inventory, 1, 80, 53));
this.addSlotToContainer(new SlotFake(tileDigitalChest.inventory, 2, 59, 42, false, false, Integer.MAX_VALUE));
int i;
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.addSlotToContainer(new BaseSlot(player.inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.addSlotToContainer(new BaseSlot(player.inventory, i, 8 + i * 18, 142));
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return true;
}
}

View file

@ -1,41 +0,0 @@
package techreborn.client.container;
import net.minecraft.entity.player.EntityPlayer;
import reborncore.client.gui.slots.BaseSlot;
import reborncore.client.gui.slots.SlotFake;
import reborncore.client.gui.slots.SlotOutput;
import reborncore.common.container.RebornContainer;
import techreborn.tiles.TileQuantumChest;
public class ContainerQuantumChest extends RebornContainer {
public TileQuantumChest tileQuantumChest;
public EntityPlayer player;
public ContainerQuantumChest(TileQuantumChest tileQuantumChest, EntityPlayer player) {
super();
this.tileQuantumChest = tileQuantumChest;
this.player = player;
this.addSlotToContainer(new BaseSlot(tileQuantumChest.inventory, 0, 80, 17));
this.addSlotToContainer(new SlotOutput(tileQuantumChest.inventory, 1, 80, 53));
this.addSlotToContainer(new SlotFake(tileQuantumChest.inventory, 2, 59, 42, false, false, Integer.MAX_VALUE));
int i;
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
this.addSlotToContainer(new BaseSlot(player.inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
for (i = 0; i < 9; ++i) {
this.addSlotToContainer(new BaseSlot(player.inventory, i, 8 + i * 18, 142));
}
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return true;
}
}

View file

@ -0,0 +1,26 @@
package techreborn.client.container.builder;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.util.ResourceLocation;
import techreborn.lib.ModInfo;
public class ArmorSlot extends FilteredSlot {
public ArmorSlot(final EntityEquipmentSlot armorType, final InventoryPlayer inventory, final int index,
final int xPosition, final int yPosition) {
super(inventory, index, xPosition, yPosition);
this.setFilter(stack -> stack != null && stack.getItem().isValidArmor(stack, armorType, inventory.player));
this.setBackgroundLocation(
new ResourceLocation(ModInfo.MOD_ID, "textures/gui/armor_" + armorType.getName() + ".png"));
}
@Override
public int getSlotStackLimit() {
return 1;
}
}

View file

@ -0,0 +1,134 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import reborncore.common.util.ItemUtils;
import java.util.List;
import java.util.function.Predicate;
final class BuiltContainer extends Container {
private final Predicate<EntityPlayer> canInteract;
private final List<Range<Integer>> playerSlotRanges;
private final List<Range<Integer>> tileSlotRanges;
public BuiltContainer(final Predicate<EntityPlayer> canInteract, final List<Range<Integer>> playerSlotRange,
final List<Range<Integer>> tileSlotRange) {
this.canInteract = canInteract;
this.playerSlotRanges = playerSlotRange;
this.tileSlotRanges = tileSlotRange;
}
public void addSlot(final Slot slot) {
this.addSlotToContainer(slot);
}
@Override
public boolean canInteractWith(final EntityPlayer playerIn) {
return this.canInteract.test(playerIn);
}
@Override
public ItemStack transferStackInSlot(final EntityPlayer player, final int index) {
ItemStack originalStack = ItemStack.EMPTY;
final Slot slot = this.inventorySlots.get(index);
if (slot != null && slot.getHasStack()) {
final ItemStack stackInSlot = slot.getStack();
originalStack = stackInSlot.copy();
boolean shifted = false;
for (final Range<Integer> range : this.playerSlotRanges)
if (range.contains(index)) {
this.shiftToTile(stackInSlot);
shifted = true;
break;
}
if (!shifted)
for (final Range<Integer> range : this.tileSlotRanges)
if (range.contains(index)) {
this.shiftToPlayer(stackInSlot);
shifted = true;
break;
}
slot.onSlotChange(stackInSlot, originalStack);
if (stackInSlot.getCount() <= 0)
slot.putStack(ItemStack.EMPTY);
else
slot.onSlotChanged();
if (stackInSlot.getCount() == originalStack.getCount())
return ItemStack.EMPTY;
slot.onTake(player, stackInSlot);
}
return originalStack;
}
protected boolean shiftItemStack(final ItemStack stackToShift, final int start, final int end) {
boolean changed = false;
if (stackToShift.isStackable()) {
for (int slotIndex = start; stackToShift.getCount() > 0 && slotIndex < end; slotIndex++) {
final Slot slot = this.inventorySlots.get(slotIndex);
final ItemStack stackInSlot = slot.getStack();
if (stackInSlot != ItemStack.EMPTY && ItemUtils.isItemEqual(stackInSlot, stackToShift, true, true)) {
final int resultingStackSize = stackInSlot.getCount() + stackToShift.getCount();
final int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit());
if (resultingStackSize <= max) {
stackToShift.setCount(0);
stackInSlot.setCount(resultingStackSize);
slot.onSlotChanged();
changed = true;
} else if (stackInSlot.getCount() < max) {
stackToShift.setCount(-(max - stackInSlot.getCount()));
stackInSlot.setCount(max);
slot.onSlotChanged();
changed = true;
}
}
}
}
if (stackToShift.getCount() > 0) {
for (int slotIndex = start; stackToShift.getCount() > 0 && slotIndex < end; slotIndex++) {
final Slot slot = this.inventorySlots.get(slotIndex);
ItemStack stackInSlot = slot.getStack();
if (stackInSlot == ItemStack.EMPTY) {
final int max = Math.min(stackToShift.getMaxStackSize(), slot.getSlotStackLimit());
stackInSlot = stackToShift.copy();
stackInSlot.setCount(Math.min(stackToShift.getCount(), max));
stackToShift.setCount(-stackInSlot.getCount());
slot.putStack(stackInSlot);
slot.onSlotChanged();
changed = true;
}
}
}
return changed;
}
private boolean shiftToTile(final ItemStack stackToShift) {
for (final Range<Integer> range : this.tileSlotRanges)
if (this.shiftItemStack(stackToShift, range.getMinimum(), range.getMaximum()))
return true;
return false;
}
private boolean shiftToPlayer(final ItemStack stackToShift) {
for (final Range<Integer> range : this.playerSlotRanges)
if (this.shiftItemStack(stackToShift, range.getMinimum(), range.getMaximum()))
return true;
return false;
}
}

View file

@ -0,0 +1,56 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class ContainerBuilder {
private Predicate<EntityPlayer> canInteract = player -> true;
final List<Slot> slots;
final List<Range<Integer>> playerInventoryRanges, tileInventoryRanges;
public ContainerBuilder() {
this.slots = new ArrayList<>();
this.playerInventoryRanges = new ArrayList<>();
this.tileInventoryRanges = new ArrayList<>();
}
public ContainerBuilder interact(final Predicate<EntityPlayer> canInteract) {
this.canInteract = canInteract;
return this;
}
public ContainerPlayerInventoryBuilder player(final InventoryPlayer player) {
return new ContainerPlayerInventoryBuilder(this, player);
}
public ContainerTileInventoryBuilder tile(final IInventory tile) {
return new ContainerTileInventoryBuilder(this, tile);
}
void addPlayerInventoryRange(final Range<Integer> range) {
this.playerInventoryRanges.add(range);
}
void addTileInventoryRange(final Range<Integer> range) {
this.tileInventoryRanges.add(range);
}
public BuiltContainer create() {
final BuiltContainer built = new BuiltContainer(this.canInteract, this.playerInventoryRanges,
this.tileInventoryRanges);
this.slots.forEach(built::addSlot);
this.slots.clear();
return built;
}
}

View file

@ -0,0 +1,127 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.EntityEquipmentSlot;
import reborncore.client.gui.slots.BaseSlot;
public final class ContainerPlayerInventoryBuilder {
private final InventoryPlayer player;
private final ContainerBuilder parent;
private Range<Integer> main;
private Range<Integer> hotbar;
private Range<Integer> armor;
ContainerPlayerInventoryBuilder(final ContainerBuilder parent, final InventoryPlayer player) {
this.player = player;
this.parent = parent;
}
public ContainerPlayerInventoryBuilder inventory(final int xStart, final int yStart) {
final int startIndex = this.parent.slots.size();
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 9; ++j)
this.parent.slots.add(new BaseSlot(this.player, j + i * 9 + 9, xStart + j * 18, yStart + i * 18));
this.main = Range.between(startIndex, this.parent.slots.size() - 1);
return this;
}
public ContainerPlayerInventoryBuilder hotbar(final int xStart, final int yStart) {
final int startIndex = this.parent.slots.size();
for (int i = 0; i < 9; ++i)
this.parent.slots.add(new BaseSlot(this.player, i, xStart + i * 18, yStart));
this.hotbar = Range.between(startIndex, this.parent.slots.size() - 1);
return this;
}
public ContainerPlayerInventoryBuilder inventory() {
return this.inventory(8, 84);
}
public ContainerPlayerInventoryBuilder hotbar() {
return this.hotbar(8, 142);
}
private ContainerPlayerInventoryBuilder armor(final int index, final int xStart, final int yStart,
final EntityEquipmentSlot slotType) {
this.parent.slots.add(new ArmorSlot(slotType, this.player, index, xStart, yStart));
return this;
}
public ContainerPlayerInventoryBuilder helmet(final int xStart, final int yStart) {
return this.armor(this.player.getSizeInventory() - 2, xStart, yStart, EntityEquipmentSlot.HEAD);
}
public ContainerPlayerInventoryBuilder chestplate(final int xStart, final int yStart) {
return this.armor(this.player.getSizeInventory() - 3, xStart, yStart, EntityEquipmentSlot.CHEST);
}
public ContainerPlayerInventoryBuilder leggings(final int xStart, final int yStart) {
return this.armor(this.player.getSizeInventory() - 4, xStart, yStart, EntityEquipmentSlot.LEGS);
}
public ContainerPlayerInventoryBuilder boots(final int xStart, final int yStart) {
return this.armor(this.player.getSizeInventory() - 5, xStart, yStart, EntityEquipmentSlot.FEET);
}
public ContainerPlayerInventoryBuilder armor(final int xStart, final int yStart) {
return this.helmet(xStart, yStart).chestplate(xStart, yStart + 19).leggings(xStart, yStart + 38).boots(xStart,
yStart + 57);
}
public ContainerBuilder addInventory() {
if (this.hotbar != null)
this.parent.addPlayerInventoryRange(this.hotbar);
if (this.main != null)
this.parent.addPlayerInventoryRange(this.main);
if (this.armor != null)
this.parent.addTileInventoryRange(this.armor);
return this.parent;
}
public static final class ContainerPlayerArmorInventoryBuilder {
private final ContainerPlayerInventoryBuilder parent;
private final int startIndex;
public ContainerPlayerArmorInventoryBuilder(final ContainerPlayerInventoryBuilder parent) {
this.parent = parent;
this.startIndex = parent.parent.slots.size();
}
private ContainerPlayerArmorInventoryBuilder armor(final int index, final int xStart, final int yStart,
final EntityEquipmentSlot slotType) {
this.parent.parent.slots.add(new ArmorSlot(slotType, this.parent.player, index, xStart, yStart));
return this;
}
public ContainerPlayerArmorInventoryBuilder helmet(final int xStart, final int yStart) {
return this.armor(this.parent.player.getSizeInventory() - 2, xStart, yStart, EntityEquipmentSlot.HEAD);
}
public ContainerPlayerArmorInventoryBuilder chestplate(final int xStart, final int yStart) {
return this.armor(this.parent.player.getSizeInventory() - 3, xStart, yStart, EntityEquipmentSlot.CHEST);
}
public ContainerPlayerArmorInventoryBuilder leggings(final int xStart, final int yStart) {
return this.armor(this.parent.player.getSizeInventory() - 4, xStart, yStart, EntityEquipmentSlot.LEGS);
}
public ContainerPlayerArmorInventoryBuilder boots(final int xStart, final int yStart) {
return this.armor(this.parent.player.getSizeInventory() - 5, xStart, yStart, EntityEquipmentSlot.FEET);
}
public ContainerPlayerArmorInventoryBuilder complete(final int xStart, final int yStart) {
return this.helmet(xStart, yStart).chestplate(xStart, yStart + 19).leggings(xStart, yStart + 38)
.boots(xStart, yStart + 57);
}
public ContainerPlayerInventoryBuilder addArmor() {
this.parent.armor = Range.between(this.startIndex, this.parent.parent.slots.size() - 1);
return this.parent;
}
}
}

View file

@ -0,0 +1,42 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import net.minecraft.inventory.IInventory;
import reborncore.client.gui.slots.BaseSlot;
import reborncore.client.gui.slots.SlotFake;
import reborncore.client.gui.slots.SlotOutput;
public class ContainerTileInventoryBuilder {
private final IInventory tile;
private final ContainerBuilder parent;
private final int rangeStart;
ContainerTileInventoryBuilder(final ContainerBuilder parent, final IInventory tile) {
this.tile = tile;
this.parent = parent;
this.rangeStart = parent.slots.size();
}
public ContainerTileInventoryBuilder slot(final int index, final int x, final int y) {
this.parent.slots.add(new BaseSlot(this.tile, index, x, y));
return this;
}
public ContainerTileInventoryBuilder output(final int index, final int x, final int y) {
this.parent.slots.add(new SlotOutput(this.tile, index, x, y));
return this;
}
public ContainerTileInventoryBuilder fake(final int index, final int x, final int y) {
this.parent.slots.add(new SlotFake(this.tile, index, x, y, false, false, Integer.MAX_VALUE));
return this;
}
public ContainerBuilder addInventory() {
this.parent.tileInventoryRanges.add(Range.between(this.rangeStart, this.parent.slots.size() - 1));
return this.parent;
}
}

View file

@ -0,0 +1,26 @@
package techreborn.client.container.builder;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.util.function.Predicate;
public class FilteredSlot extends Slot {
private Predicate<ItemStack> filter;
public FilteredSlot(final IInventory inventory, final int index, final int xPosition, final int yPosition) {
super(inventory, index, xPosition, yPosition);
}
public FilteredSlot setFilter(final Predicate<ItemStack> filter) {
this.filter = filter;
return this;
}
@Override
public boolean isItemValid(final ItemStack stack) {
return this.filter.test(stack);
}
}

View file

@ -6,7 +6,8 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n;
import techreborn.client.container.ContainerDigitalChest;
import techreborn.client.container.builder.ContainerBuilder;
import techreborn.tiles.TileDigitalChest;
public class GuiDigitalChest extends GuiContainer {
@ -16,8 +17,9 @@ public class GuiDigitalChest extends GuiContainer {
TileDigitalChest tile;
public GuiDigitalChest(EntityPlayer player, TileDigitalChest tile) {
super(new ContainerDigitalChest(tile, player));
public GuiDigitalChest(final EntityPlayer player, final TileDigitalChest tile) {
super(new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile).slot(0, 80, 17)
.output(1, 80, 53).fake(2, 59, 42).addInventory().create());
this.xSize = 176;
this.ySize = 167;
this.tile = tile;

View file

@ -7,7 +7,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n;
import reborncore.common.util.ItemUtils;
import techreborn.client.container.ContainerQuantumChest;
import techreborn.client.container.builder.ContainerBuilder;
import techreborn.tiles.TileQuantumChest;
public class GuiQuantumChest extends GuiContainer {
@ -17,8 +18,9 @@ public class GuiQuantumChest extends GuiContainer {
TileQuantumChest tile;
public GuiQuantumChest(EntityPlayer player, TileQuantumChest tile) {
super(new ContainerQuantumChest(tile, player));
public GuiQuantumChest(final EntityPlayer player, final TileQuantumChest tile) {
super(new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile)
.slot(0, 80, 17).output(1, 80, 53).fake(2, 59, 42).addInventory().create());
this.xSize = 176;
this.ySize = 167;
this.tile = tile;