Add container syncing helper + Rename slot builder methods

An example of the new syncing system can be found in the ChargeBench
This commit is contained in:
Ourten 2017-01-07 02:46:46 +01:00
parent b688fe72e4
commit 9f74feabff
7 changed files with 170 additions and 12 deletions

View file

@ -79,8 +79,8 @@ public class GuiHandler implements IGuiHandler {
return new ContainerQuantumTank((TileQuantumTank) world.getTileEntity(new BlockPos(x, y, z)), player);
} 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();
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).slot(0, 80, 17).outputSlot(1, 80, 53)
.fakeSlot(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) {
@ -132,9 +132,13 @@ public class GuiHandler implements IGuiHandler {
player);
} else if (ID == GuiHandler.chargeBench) {
return new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory()
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z)))
.energy(0, 62, 21).energy(1, 80, 21).energy(2, 98, 21).energy(3, 62, 39).energy(4, 80, 39)
.energy(5, 98, 39).addInventory().create();
.tile((IInventory) world.getTileEntity(new BlockPos(x, y, z))).energySlot(0, 62, 21)
.energySlot(1, 80, 21).energySlot(2, 98, 21).energySlot(3, 62, 39).energySlot(4, 80, 39)
.energySlot(5, 98, 39)
.syncIntegerValue(
() -> (int) ((TileChargeBench) world.getTileEntity(new BlockPos(x, y, z))).getEnergy(),
((TileChargeBench) world.getTileEntity(new BlockPos(x, y, z)))::setEnergy)
.addInventory().create();
} else if (ID == vacuumFreezerID) {
return new ContainerVacuumFreezer((TileVacuumFreezer) world.getTileEntity(new BlockPos(x, y, z)), player);
} else if (ID == grinderID) {

View file

@ -1,15 +1,23 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.MutableTriple;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import reborncore.common.util.ItemUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
final class BuiltContainer extends Container {
@ -18,12 +26,34 @@ final class BuiltContainer extends Container {
private final List<Range<Integer>> playerSlotRanges;
private final List<Range<Integer>> tileSlotRanges;
private final ArrayList<MutableTriple<IntSupplier, IntConsumer, Short>> shortValues;
private final ArrayList<MutableTriple<IntSupplier, IntConsumer, Integer>> integerValues;
private Integer[] integerParts;
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;
this.shortValues = new ArrayList<>();
this.integerValues = new ArrayList<>();
}
public void addShortSync(final List<Pair<IntSupplier, IntConsumer>> syncables) {
for (final Pair<IntSupplier, IntConsumer> syncable : syncables)
this.shortValues.add(MutableTriple.of(syncable.getLeft(), syncable.getRight(), (short) 0));
this.shortValues.trimToSize();
}
public void addIntegerSync(final List<Pair<IntSupplier, IntConsumer>> syncables) {
for (final Pair<IntSupplier, IntConsumer> syncable : syncables)
this.integerValues.add(MutableTriple.of(syncable.getLeft(), syncable.getRight(), 0));
this.integerValues.trimToSize();
this.integerParts = new Integer[this.integerValues.size()];
}
public void addSlot(final Slot slot) {
@ -35,6 +65,86 @@ final class BuiltContainer extends Container {
return this.canInteract.test(playerIn);
}
@Override
public void detectAndSendChanges() {
super.detectAndSendChanges();
for (final IContainerListener listener : this.listeners) {
int i = 0;
if (!this.shortValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Short> value : this.shortValues) {
final short supplied = (short) value.getLeft().getAsInt();
if (supplied != value.getRight()) {
listener.sendProgressBarUpdate(this, i, supplied);
value.setRight(supplied);
}
i++;
}
if (!this.integerValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Integer> value : this.integerValues) {
final int supplied = value.getLeft().getAsInt();
if (supplied != value.getRight()) {
listener.sendProgressBarUpdate(this, i, supplied >> 16);
listener.sendProgressBarUpdate(this, i + 1, (short) (supplied & 0xFFFF));
value.setRight(supplied);
}
i += 2;
}
}
}
@Override
public void addListener(final IContainerListener listener) {
super.addListener(listener);
int i = 0;
if (!this.shortValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Short> value : this.shortValues) {
final short supplied = (short) value.getLeft().getAsInt();
listener.sendProgressBarUpdate(this, i, supplied);
value.setRight(supplied);
i++;
}
if (!this.integerValues.isEmpty())
for (final MutableTriple<IntSupplier, IntConsumer, Integer> value : this.integerValues) {
final int supplied = value.getLeft().getAsInt();
listener.sendProgressBarUpdate(this, i, supplied >> 16);
listener.sendProgressBarUpdate(this, i + 1, (short) (supplied & 0xFFFF));
value.setRight(supplied);
i += 2;
}
}
@SideOnly(Side.CLIENT)
@Override
public void updateProgressBar(final int id, final int value) {
if(id < this.shortValues.size())
{
this.shortValues.get(id).getMiddle().accept((short) value);
this.shortValues.get(id).setRight((short) value);
}
else if (id - this.shortValues.size() < this.integerValues.size() * 2)
{
if ((id - this.shortValues.size()) % 2 == 0)
this.integerParts[(id - this.shortValues.size()) / 2] = value;
else
{
this.integerValues.get((id - this.shortValues.size()) / 2).getMiddle().accept(
(this.integerParts[(id - this.shortValues.size()) / 2] & 0xFFFF) << 16 | value & 0xFFFF);
}
}
}
@Override
public ItemStack transferStackInSlot(final EntityPlayer player, final int index) {

View file

@ -1,6 +1,7 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
@ -9,6 +10,8 @@ import net.minecraft.inventory.Slot;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Predicate;
public class ContainerBuilder {
@ -17,10 +20,16 @@ public class ContainerBuilder {
final List<Slot> slots;
final List<Range<Integer>> playerInventoryRanges, tileInventoryRanges;
final List<Pair<IntSupplier, IntConsumer>> shortValues;
final List<Pair<IntSupplier, IntConsumer>> integerValues;
public ContainerBuilder() {
this.slots = new ArrayList<>();
this.playerInventoryRanges = new ArrayList<>();
this.tileInventoryRanges = new ArrayList<>();
this.shortValues = new ArrayList<>();
this.integerValues = new ArrayList<>();
}
public ContainerBuilder interact(final Predicate<EntityPlayer> canInteract) {
@ -47,6 +56,10 @@ public class ContainerBuilder {
public BuiltContainer create() {
final BuiltContainer built = new BuiltContainer(this.canInteract, this.playerInventoryRanges,
this.tileInventoryRanges);
if (!this.shortValues.isEmpty())
built.addShortSync(this.shortValues);
if (!this.integerValues.isEmpty())
built.addIntegerSync(this.integerValues);
this.slots.forEach(built::addSlot);

View file

@ -1,6 +1,7 @@
package techreborn.client.container.builder;
import org.apache.commons.lang3.Range;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.inventory.IInventory;
@ -10,6 +11,9 @@ import reborncore.client.gui.slots.SlotOutput;
import techreborn.client.container.builder.slot.EnergyChargeSlot;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
public class ContainerTileInventoryBuilder {
private final IInventory tile;
@ -27,21 +31,47 @@ public class ContainerTileInventoryBuilder {
return this;
}
public ContainerTileInventoryBuilder output(final int index, final int x, final int y) {
public ContainerTileInventoryBuilder outputSlot(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) {
public ContainerTileInventoryBuilder fakeSlot(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 ContainerTileInventoryBuilder energy(final int index, final int x, final int y) {
public ContainerTileInventoryBuilder energySlot(final int index, final int x, final int y) {
this.parent.slots.add(new EnergyChargeSlot(this.tile, index, x, y));
return this;
}
/**
*
* @param supplier
* The supplier must supply a variable holding inside a Short, it
* will be truncated by force.
* @param setter
* The setter to call when the variable has been updated.
*/
public ContainerTileInventoryBuilder syncShortValue(final IntSupplier supplier, final IntConsumer setter) {
this.parent.shortValues.add(Pair.of(supplier, setter));
return this;
}
/**
*
* @param supplier
* The supplier it can supply a variable holding in an Integer it
* will be split inside multiples shorts.
* @param setter
* The setter to call when the variable has been updated.
*/
public ContainerTileInventoryBuilder syncIntegerValue(final IntSupplier supplier, final IntConsumer setter) {
this.parent.integerValues.add(Pair.of(supplier, setter));
return this;
}
public ContainerBuilder addInventory() {
this.parent.tileInventoryRanges.add(Range.between(this.rangeStart, this.parent.slots.size() - 1));
return this.parent;

View file

@ -16,8 +16,9 @@ public class GuiChargeBench extends GuiContainer {
public GuiChargeBench(final EntityPlayer player, final TileChargeBench tile) {
super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile)
.energy(0, 62, 21).energy(1, 80, 21).energy(2, 98, 21).energy(3, 62, 39).energy(4, 80, 39)
.energy(5, 98, 39).addInventory().create());
.energySlot(0, 62, 21).energySlot(1, 80, 21).energySlot(2, 98, 21).energySlot(3, 62, 39).energySlot(4, 80, 39)
.energySlot(5, 98, 39).syncIntegerValue(() -> (int) tile.getEnergy(), tile::setEnergy).addInventory()
.create());
this.xSize = 176;
this.ySize = 167;
chargebench = tile;

View file

@ -10,7 +10,7 @@ public class GuiDigitalChest extends GuiBase {
TileDigitalChest tile;
public GuiDigitalChest(final EntityPlayer player, final TileDigitalChest tile) {
super(player, tile, new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile).slot(0, 80, 20).output(1, 80, 70).fake(2, 80, 45).addInventory().create());
super(player, tile, new ContainerBuilder().player(player.inventory).inventory().hotbar().addInventory().tile(tile).slot(0, 80, 20).outputSlot(1, 80, 70).fakeSlot(2, 80, 45).addInventory().create());
this.tile = tile;
}

View file

@ -20,7 +20,7 @@ public class GuiQuantumChest extends GuiContainer {
public GuiQuantumChest(final EntityPlayer player, final TileQuantumChest tile) {
super(new ContainerBuilder().player(player.inventory).inventory(true).hotbar(true).addInventory().tile(tile)
.slot(0, 80, 17).output(1, 80, 53).fake(2, 59, 42).addInventory().create());
.slot(0, 80, 17).outputSlot(1, 80, 53).fakeSlot(2, 59, 42).addInventory().create());
this.xSize = 176;
this.ySize = 167;
this.tile = tile;