aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorJakub <53441451+kuba6000@users.noreply.github.com>2023-09-05 08:27:22 +0200
committerGitHub <noreply@github.com>2023-09-05 08:27:22 +0200
commit74e1d0964ec002482253384c97fe76de54dc7de1 (patch)
tree281d159099ec7d2c315a54f89bae6eeb3d5b1873 /src/main
parentd1f7d54620be77d4e9c413978a6c9497401fc9c2 (diff)
downloadGT5-Unofficial-74e1d0964ec002482253384c97fe76de54dc7de1.tar.gz
GT5-Unofficial-74e1d0964ec002482253384c97fe76de54dc7de1.tar.bz2
GT5-Unofficial-74e1d0964ec002482253384c97fe76de54dc7de1.zip
Merge identical slots in EIG + MApiary GUI (#93)
* Merge identical slots in EIG GUI * Mega Apiary * Update MobHandlerLoader.java * Update GTHelper.java * Update GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java * Update GT_MetaTileEntity_MegaIndustrialApiary.java * Update build.gradle * crop * 99+
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/kubatech/api/helpers/GTHelper.java45
-rw-r--r--src/main/java/kubatech/loaders/MobHandlerLoader.java8
-rw-r--r--src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java301
-rw-r--r--src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java310
4 files changed, 448 insertions, 216 deletions
diff --git a/src/main/java/kubatech/api/helpers/GTHelper.java b/src/main/java/kubatech/api/helpers/GTHelper.java
index 201f8b45b7..e368c7b778 100644
--- a/src/main/java/kubatech/api/helpers/GTHelper.java
+++ b/src/main/java/kubatech/api/helpers/GTHelper.java
@@ -23,6 +23,14 @@ package kubatech.api.helpers;
import static gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase.isValidMetaTileEntity;
import static kubatech.api.Variables.ln4;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.PacketBuffer;
+
+import com.kuba6000.mobsinfo.api.utils.ItemID;
+
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy;
import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_MultiBlockBase;
import kubatech.api.implementations.KubaTechGTMultiBlockBase;
@@ -52,4 +60,41 @@ public class GTHelper {
public static int getVoltageTier(GT_MetaTileEntity_MultiBlockBase mte) {
return (int) getVoltageTierD(mte);
}
+
+ public static class StackableItemSlot {
+
+ public StackableItemSlot(int count, ItemStack stack, ArrayList<Integer> realSlots) {
+ this.count = count;
+ this.stack = stack;
+ this.realSlots = realSlots;
+ }
+
+ public final int count;
+ public final ItemStack stack;
+ public final ArrayList<Integer> realSlots;
+
+ public void write(PacketBuffer buffer) throws IOException {
+ buffer.writeVarIntToBuffer(count);
+ buffer.writeItemStackToBuffer(stack);
+ }
+
+ public static StackableItemSlot read(PacketBuffer buffer) throws IOException {
+ return new StackableItemSlot(
+ buffer.readVarIntFromBuffer(),
+ buffer.readItemStackFromBuffer(),
+ new ArrayList<>());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!(obj instanceof StackableItemSlot)) return false;
+ StackableItemSlot other = (StackableItemSlot) obj;
+ return count == other.count && ItemID.createNoCopy(stack, false)
+ .hashCode()
+ == ItemID.createNoCopy(other.stack, false)
+ .hashCode()
+ && realSlots.equals(other.realSlots);
+ }
+ }
}
diff --git a/src/main/java/kubatech/loaders/MobHandlerLoader.java b/src/main/java/kubatech/loaders/MobHandlerLoader.java
index 7089aa6f6e..35d92de13d 100644
--- a/src/main/java/kubatech/loaders/MobHandlerLoader.java
+++ b/src/main/java/kubatech/loaders/MobHandlerLoader.java
@@ -221,16 +221,10 @@ public class MobHandlerLoader {
@SubscribeEvent
public void onPostMobRegistration(PostMobRegistrationEvent event) {
if (!event.drops.isEmpty() && event.recipe.isUsableInVial) {
+ @SuppressWarnings("unchecked")
ArrayList<MobDrop> drops = (ArrayList<MobDrop>) event.drops.clone();
- // drops.removeIf(d -> d.chance == 0);
if (!drops.isEmpty()) {
recipeMap.put(event.currentMob, new MobEECRecipe(drops, event.recipe));
- /*
- * event.drops.stream()
- * .filter(d -> d.chance == 0)
- * .forEach(
- * d -> d.additionalInfo.add(StatCollector.translateToLocal("kubatech.mobhandler.eec_disabled")));
- */
}
}
}
diff --git a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java
index 71ed169c1c..2e916e29e0 100644
--- a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java
+++ b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeIndustrialGreenhouse.java
@@ -46,7 +46,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFlower;
@@ -91,7 +90,6 @@ import com.gtnewhorizons.modularui.api.math.Pos2d;
import com.gtnewhorizons.modularui.api.screen.ModularUIContext;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
-import com.gtnewhorizons.modularui.api.widget.IWidgetParent;
import com.gtnewhorizons.modularui.api.widget.Widget;
import com.gtnewhorizons.modularui.common.builder.UIInfo;
import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer;
@@ -107,6 +105,7 @@ import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
import com.gtnewhorizons.modularui.common.widget.Scrollable;
import com.gtnewhorizons.modularui.common.widget.SlotWidget;
import com.gtnewhorizons.modularui.common.widget.TextWidget;
+import com.kuba6000.mobsinfo.api.utils.ItemID;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
@@ -138,7 +137,9 @@ import ic2.core.Ic2Items;
import ic2.core.crop.TileEntityCrop;
import kubatech.Tags;
import kubatech.api.LoaderReference;
+import kubatech.api.helpers.GTHelper;
import kubatech.api.implementations.KubaTechGTMultiBlockBase;
+import kubatech.api.utils.ModUtils;
import kubatech.client.effect.CropRenderer;
@SuppressWarnings("unused")
@@ -625,7 +626,8 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse
return super.transferStackInSlot(aPlayer, aSlotIndex);
}
if (mte.addCrop(aStack)) {
- s.putStack(null);
+ if (aStack.stackSize == 0) s.putStack(null);
+ else s.putStack(aStack);
detectAndSendChanges();
return null;
}
@@ -633,7 +635,8 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse
}
}
- final List<ItemStack> drawables = new ArrayList<>(mMaxSlots);
+ List<GTHelper.StackableItemSlot> drawables = new ArrayList<>();
+ private int usedSlots = 0; // mStorage.size()
@SuppressWarnings("UnstableApiUsage")
@Override
@@ -681,6 +684,7 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse
ChangeableWidget cropsContainer = new ChangeableWidget(() -> createCropsContainerWidget(player));
AtomicInteger lastMaxSlots = new AtomicInteger();
+ AtomicInteger lastUsedSlots = new AtomicInteger();
builder.widget(cropsContainer.attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> {
if (lastMaxSlots.get() != mMaxSlots) {
lastMaxSlots.set(mMaxSlots);
@@ -693,36 +697,60 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse
cropsContainer.notifyChangeNoSync();
}
}), builder)
- .attachSyncer(
- new FakeSyncWidget.ListSyncer<>(
- () -> mStorage.stream()
- .map(s -> s.input)
- .collect(Collectors.toList()),
- l -> {
- drawables.clear();
- drawables.addAll(l);
- if (cropsContainer.getChildren()
- .size() > 0)
- IWidgetParent.forEachByLayer(
- (IWidgetParent) cropsContainer.getChildren()
- .get(0),
- Widget::notifyTooltipChange);
- },
- (buffer, i) -> {
- try {
- buffer.writeItemStackToBuffer(i);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- },
- buffer -> {
- try {
- return buffer.readItemStackFromBuffer();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }),
- builder));
+ .attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> {
+ if (lastUsedSlots.get() != mStorage.size()) {
+ lastUsedSlots.set(mStorage.size());
+ cropsContainer.notifyChangeNoSync();
+ }
+ return mStorage.size();
+ }, i -> {
+ if (usedSlots != i) {
+ usedSlots = i;
+ cropsContainer.notifyChangeNoSync();
+ }
+ }), builder)
+ .attachSyncer(new FakeSyncWidget.ListSyncer<>(() -> {
+ HashMap<ItemID, Integer> itemMap = new HashMap<>();
+ HashMap<ItemID, ItemStack> stackMap = new HashMap<>();
+ HashMap<ItemID, ArrayList<Integer>> realSlotMap = new HashMap<>();
+ for (int i = 0, mStorageSize = mStorage.size(); i < mStorageSize; i++) {
+ GreenHouseSlot slot = mStorage.get(i);
+ ItemID id = ItemID.createNoCopy(slot.input, false);
+ itemMap.merge(id, 1, Integer::sum);
+ stackMap.putIfAbsent(id, slot.input);
+ realSlotMap.computeIfAbsent(id, unused -> new ArrayList<>())
+ .add(i);
+ }
+ List<GTHelper.StackableItemSlot> newDrawables = new ArrayList<>();
+ for (Map.Entry<ItemID, Integer> entry : itemMap.entrySet()) {
+ newDrawables.add(
+ new GTHelper.StackableItemSlot(
+ entry.getValue(),
+ stackMap.get(entry.getKey()),
+ realSlotMap.get(entry.getKey())));
+ }
+ if (!Objects.equals(newDrawables, drawables)) {
+ drawables = newDrawables;
+ cropsContainer.notifyChangeNoSync();
+ }
+ return drawables;
+ }, l -> {
+ drawables.clear();
+ drawables.addAll(l);
+ cropsContainer.notifyChangeNoSync();
+ }, (buffer, i) -> {
+ try {
+ i.write(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }, buffer -> {
+ try {
+ return GTHelper.StackableItemSlot.read(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }), builder));
final DynamicPositionedColumn screenElements = new DynamicPositionedColumn();
drawTexts(screenElements, null);
@@ -731,85 +759,152 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse
protected Widget createCropsContainerWidget(EntityPlayer player) {
Scrollable cropsContainer = new Scrollable().setVerticalScroll();
- final int perRow = 7;
- if (mMaxSlots > 0) for (int i = 0, imax = ((mMaxSlots - 1) / perRow); i <= imax; i++) {
- DynamicPositionedRow row = new DynamicPositionedRow().setSynced(false);
- for (int j = 0, jmax = (i == imax ? (mMaxSlots - 1) % perRow : (perRow - 1)); j <= jmax; j++) {
- final int finalI = i * perRow;
- final int finalJ = j;
- final int ID = finalI + finalJ;
- row.widget(new ButtonWidget().setOnClick((clickData, widget) -> {
- if (!(player instanceof EntityPlayerMP)) return;
- if (!clickData.shift) {
- ItemStack input = player.inventory.getItemStack();
- if (input != null) {
- if (this.mMaxProgresstime > 0) {
- GT_Utility.sendChatToPlayer(
- player,
- EnumChatFormatting.RED + "Can't replace/insert while running !");
- return;
- }
- if (addCrop(input, -1, true)) {
- if (mStorage.size() > ID) {
- GreenHouseSlot removed = mStorage.remove(ID);
- addCrop(input, ID, false);
- player.inventory.setItemStack(removed.input);
-
- } else {
- addCrop(input);
- player.inventory.setItemStack(null);
- }
- ((EntityPlayerMP) player).isChangingQuantityOnly = false;
- ((EntityPlayerMP) player).updateHeldItem();
- }
- return;
- }
- }
- if (mStorage.size() <= ID) return;
- if (this.mMaxProgresstime > 0) {
- GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't eject while running !");
- return;
- }
- GreenHouseSlot removed = mStorage.remove(ID);
- if (clickData.shift) {
- if (player.inventory.addItemStackToInventory(removed.input)) {
- player.inventoryContainer.detectAndSendChanges();
+ ArrayList<Widget> buttons = new ArrayList<>();
+
+ if (!ModUtils.isClientThreaded()) {
+ HashMap<ItemID, Integer> itemMap = new HashMap<>();
+ HashMap<ItemID, ItemStack> stackMap = new HashMap<>();
+ HashMap<ItemID, ArrayList<Integer>> realSlotMap = new HashMap<>();
+ for (int i = 0, mStorageSize = mStorage.size(); i < mStorageSize; i++) {
+ GreenHouseSlot slot = mStorage.get(i);
+ ItemID id = ItemID.createNoCopy(slot.input, false);
+ itemMap.merge(id, 1, Integer::sum);
+ stackMap.putIfAbsent(id, slot.input);
+ realSlotMap.computeIfAbsent(id, unused -> new ArrayList<>())
+ .add(i);
+ }
+ drawables = new ArrayList<>();
+ for (Map.Entry<ItemID, Integer> entry : itemMap.entrySet()) {
+ drawables.add(
+ new GTHelper.StackableItemSlot(
+ entry.getValue(),
+ stackMap.get(entry.getKey()),
+ realSlotMap.get(entry.getKey())));
+ }
+ }
+
+ for (int ID = 0; ID < drawables.size(); ID++) {
+ final int finalID = ID;
+ buttons.add(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!(player instanceof EntityPlayerMP)) return;
+ if (!clickData.shift) {
+ ItemStack input = player.inventory.getItemStack();
+ if (input != null) {
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility
+ .sendChatToPlayer(player, EnumChatFormatting.RED + "Can't replace while running !");
return;
}
- }
- if (clickData.mouseButton == 1) {
- if (player.inventory.getItemStack() == null) {
- player.inventory.setItemStack(removed.input);
+ if (addCrop(input, -1, true)) {
+ if (drawables.size() > finalID) {
+ int realID = drawables.get(finalID).realSlots.get(0);
+ GreenHouseSlot removed = mStorage.remove(realID);
+ addCrop(input, realID, false);
+ player.inventory.setItemStack(removed.input);
+ // force widget update??
+ } else {
+ if (input.stackSize == 0) addCrop(input);
+ player.inventory.setItemStack(null);
+ }
((EntityPlayerMP) player).isChangingQuantityOnly = false;
((EntityPlayerMP) player).updateHeldItem();
- return;
}
+ return;
}
-
- addOutput(removed.input);
- GT_Utility.sendChatToPlayer(player, "Crop ejected !");
- })
- .setBackground(
- () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
- .getItemSlot(),
- new ItemDrawable(drawables.size() > ID ? drawables.get(ID) : null)
- .withFixedSize(16, 16, 1, 1),
- new Text(drawables.size() > ID ? String.valueOf(drawables.get(ID).stackSize) : "")
+ }
+ if (drawables.size() <= finalID) return;
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't eject while running !");
+ return;
+ }
+ int realID = drawables.get(finalID).realSlots.get(0);
+ GreenHouseSlot removed = mStorage.remove(realID);
+ if (clickData.shift) {
+ if (player.inventory.addItemStackToInventory(removed.input)) {
+ player.inventoryContainer.detectAndSendChanges();
+ return;
+ }
+ }
+ if (clickData.mouseButton == 1) {
+ if (player.inventory.getItemStack() == null) {
+ player.inventory.setItemStack(removed.input);
+ ((EntityPlayerMP) player).isChangingQuantityOnly = false;
+ ((EntityPlayerMP) player).updateHeldItem();
+ return;
+ }
+ }
+ addOutput(removed.input);
+ GT_Utility.sendChatToPlayer(player, "Crop ejected !");
+ })
+ .setBackground(
+ () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
+ .getItemSlot(),
+ new ItemDrawable(drawables.size() > finalID ? drawables.get(finalID).stack : null)
+ .withFixedSize(16, 16, 1, 1),
+ new Text(
+ drawables.size() > finalID ? (drawables.get(finalID).count > 99 ? "+99"
+ : String.valueOf(drawables.get(finalID).count)) : "").color(Color.PURPLE.normal)
+ .alignment(Alignment.TopRight),
+ new Text(
+ drawables.size() > finalID ? String.valueOf(drawables.get(finalID).stack.stackSize) : "")
.color(Color.WHITE.normal)
.shadow()
.alignment(Alignment.BottomRight) })
- .dynamicTooltip(() -> {
- if (drawables.size() > ID) return Arrays.asList(
- drawables.get(ID)
- .getDisplayName(),
- EnumChatFormatting.GRAY + "Left click to eject into input bus",
- EnumChatFormatting.GRAY + "Right click to get into mouse",
- EnumChatFormatting.GRAY + "Shift click to get into inventory",
- EnumChatFormatting.GRAY + "Click with other crop in mouse to replace");
- return Collections.emptyList();
- })
- .setSize(18, 18));
+ .dynamicTooltip(() -> {
+ if (drawables.size() > finalID) return Arrays.asList(
+ "x" + drawables.get(finalID).stack.stackSize
+ + " "
+ + drawables.get(finalID).stack.getDisplayName(),
+ EnumChatFormatting.DARK_PURPLE + "There are "
+ + drawables.get(finalID).count
+ + " identical slots",
+ EnumChatFormatting.GRAY + "Left click to eject into input bus",
+ EnumChatFormatting.GRAY + "Right click to get into mouse",
+ EnumChatFormatting.GRAY + "Shift click to get into inventory",
+ EnumChatFormatting.GRAY + "Click with other crop in mouse to replace");
+ return Collections.emptyList();
+ })
+ .setSize(18, 18));
+ }
+
+ buttons.add(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!(player instanceof EntityPlayerMP)) return;
+ ItemStack input = player.inventory.getItemStack();
+ if (input != null) {
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't insert while running !");
+ return;
+ }
+ if (addCrop(input)) {
+ if (input.stackSize == 0) player.inventory.setItemStack(null);
+ ((EntityPlayerMP) player).isChangingQuantityOnly = false;
+ ((EntityPlayerMP) player).updateHeldItem();
+ }
+ }
+ })
+ .setBackground(
+ () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
+ .getItemSlot(),
+ new Text(String.valueOf((mMaxSlots - usedSlots) > 99 ? "+99" : (mMaxSlots - usedSlots)))
+ .color(Color.PURPLE.normal)
+ .alignment(Alignment.TopRight) })
+ .dynamicTooltip(
+ () -> Arrays.asList(
+ EnumChatFormatting.GRAY + "Empty slot",
+ EnumChatFormatting.DARK_PURPLE + "There are " + (mMaxSlots - usedSlots) + " identical slots",
+ EnumChatFormatting.GRAY + "Click with crop in mouse to insert",
+ EnumChatFormatting.GRAY + "Shift click a crop in your inventory to insert"))
+ .setSize(18, 18));
+
+ final int perRow = 7;
+ for (int i = 0, imax = ((buttons.size() - 1) / perRow); i <= imax; i++) {
+ DynamicPositionedRow row = new DynamicPositionedRow().setSynced(false);
+ for (int j = 0, jmax = (i == imax ? (buttons.size() - 1) % perRow : (perRow - 1)); j <= jmax; j++) {
+ final int finalI = i * perRow;
+ final int finalJ = j;
+ final int ID = finalI + finalJ;
+ row.widget(buttons.get(ID));
}
cropsContainer.widget(row.setPos(0, i * 18));
}
diff --git a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java
index 9d5dc463e7..df12c901b8 100644
--- a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java
+++ b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_MegaIndustrialApiary.java
@@ -49,6 +49,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@@ -79,12 +80,12 @@ import com.gtnewhorizons.modularui.api.ModularUITextures;
import com.gtnewhorizons.modularui.api.drawable.IDrawable;
import com.gtnewhorizons.modularui.api.drawable.ItemDrawable;
import com.gtnewhorizons.modularui.api.drawable.Text;
+import com.gtnewhorizons.modularui.api.math.Alignment;
import com.gtnewhorizons.modularui.api.math.Color;
import com.gtnewhorizons.modularui.api.math.Pos2d;
import com.gtnewhorizons.modularui.api.screen.ModularUIContext;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
-import com.gtnewhorizons.modularui.api.widget.IWidgetParent;
import com.gtnewhorizons.modularui.api.widget.Widget;
import com.gtnewhorizons.modularui.common.builder.UIInfo;
import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer;
@@ -100,6 +101,7 @@ import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget;
import com.gtnewhorizons.modularui.common.widget.Scrollable;
import com.gtnewhorizons.modularui.common.widget.SlotWidget;
import com.gtnewhorizons.modularui.common.widget.TextWidget;
+import com.kuba6000.mobsinfo.api.utils.ItemID;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -129,7 +131,9 @@ import gregtech.api.util.GT_Multiblock_Tooltip_Builder;
import gregtech.api.util.GT_Utility;
import kubatech.Tags;
import kubatech.api.LoaderReference;
+import kubatech.api.helpers.GTHelper;
import kubatech.api.implementations.KubaTechGTMultiBlockBase;
+import kubatech.api.utils.ModUtils;
import kubatech.client.effect.MegaApiaryBeesRenderer;
public class GT_MetaTileEntity_MegaIndustrialApiary
@@ -717,7 +721,8 @@ public class GT_MetaTileEntity_MegaIndustrialApiary
}
}
- private final List<ItemStack> drawables = new ArrayList<>(mMaxSlots);
+ private List<GTHelper.StackableItemSlot> drawables = new ArrayList<>();
+ private int usedSlots = 0; // mStorage.size()
@SuppressWarnings("UnstableApiUsage")
@Override
@@ -765,6 +770,7 @@ public class GT_MetaTileEntity_MegaIndustrialApiary
ChangeableWidget beesContainer = new ChangeableWidget(() -> createBeesContainerWidget(player));
AtomicInteger lastMaxSlots = new AtomicInteger();
+ AtomicInteger lastUsedSlots = new AtomicInteger();
builder.widget(beesContainer.attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> {
if (lastMaxSlots.get() != mMaxSlots) {
lastMaxSlots.set(mMaxSlots);
@@ -777,36 +783,60 @@ public class GT_MetaTileEntity_MegaIndustrialApiary
beesContainer.notifyChangeNoSync();
}
}), builder)
- .attachSyncer(
- new FakeSyncWidget.ListSyncer<>(
- () -> mStorage.stream()
- .map(s -> s.queenStack)
- .collect(Collectors.toList()),
- l -> {
- drawables.clear();
- drawables.addAll(l);
- if (beesContainer.getChildren()
- .size() > 0)
- IWidgetParent.forEachByLayer(
- (IWidgetParent) beesContainer.getChildren()
- .get(0),
- Widget::notifyTooltipChange);
- },
- (buffer, i) -> {
- try {
- buffer.writeItemStackToBuffer(i);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- },
- buffer -> {
- try {
- return buffer.readItemStackFromBuffer();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }),
- builder)
+ .attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> {
+ if (lastUsedSlots.get() != mStorage.size()) {
+ lastUsedSlots.set(mStorage.size());
+ beesContainer.notifyChangeNoSync();
+ }
+ return mStorage.size();
+ }, i -> {
+ if (usedSlots != i) {
+ usedSlots = i;
+ beesContainer.notifyChangeNoSync();
+ }
+ }), builder)
+ .attachSyncer(new FakeSyncWidget.ListSyncer<>(() -> {
+ HashMap<ItemID, Integer> itemMap = new HashMap<>();
+ HashMap<ItemID, ItemStack> stackMap = new HashMap<>();
+ HashMap<ItemID, ArrayList<Integer>> realSlotMap = new HashMap<>();
+ for (int i = 0, mStorageSize = mStorage.size(); i < mStorageSize; i++) {
+ BeeSimulator slot = mStorage.get(i);
+ ItemID id = ItemID.createNoCopy(slot.queenStack, false);
+ itemMap.merge(id, 1, Integer::sum);
+ stackMap.putIfAbsent(id, slot.queenStack);
+ realSlotMap.computeIfAbsent(id, unused -> new ArrayList<>())
+ .add(i);
+ }
+ List<GTHelper.StackableItemSlot> newDrawables = new ArrayList<>();
+ for (Map.Entry<ItemID, Integer> entry : itemMap.entrySet()) {
+ newDrawables.add(
+ new GTHelper.StackableItemSlot(
+ entry.getValue(),
+ stackMap.get(entry.getKey()),
+ realSlotMap.get(entry.getKey())));
+ }
+ if (!Objects.equals(newDrawables, drawables)) {
+ drawables = newDrawables;
+ beesContainer.notifyChangeNoSync();
+ }
+ return drawables;
+ }, l -> {
+ drawables.clear();
+ drawables.addAll(l);
+ beesContainer.notifyChangeNoSync();
+ }, (buffer, i) -> {
+ try {
+ i.write(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }, buffer -> {
+ try {
+ return GTHelper.StackableItemSlot.read(buffer);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }), builder)
.attachSyncer(new FakeSyncWidget.ListSyncer<>(() -> {
if (flowersError) {
List<String> s = flowersCheck.stream()
@@ -838,90 +868,158 @@ public class GT_MetaTileEntity_MegaIndustrialApiary
private Widget createBeesContainerWidget(EntityPlayer player) {
Scrollable beesContainer = new Scrollable().setVerticalScroll();
- final int perRow = 7;
- if (mMaxSlots > 0) for (int i = 0, imax = ((mMaxSlots - 1) / perRow); i <= imax; i++) {
- DynamicPositionedRow row = new DynamicPositionedRow().setSynced(false);
- for (int j = 0, jmax = (i == imax ? (mMaxSlots - 1) % perRow : (perRow - 1)); j <= jmax; j++) {
- final int finalI = i * perRow;
- final int finalJ = j;
- final int ID = finalI + finalJ;
- row.widget(new ButtonWidget().setOnClick((clickData, widget) -> {
- if (!(player instanceof EntityPlayerMP)) return;
- if (!clickData.shift) {
- ItemStack input = player.inventory.getItemStack();
- if (input != null) {
- if (this.mMaxProgresstime > 0) {
- GT_Utility.sendChatToPlayer(
- player,
- EnumChatFormatting.RED + "Can't replace/insert while running !");
- return;
- }
- if (beeRoot.getType(input) == EnumBeeType.QUEEN) {
- World w = getBaseMetaTileEntity().getWorld();
- float t = (float) getVoltageTierExact();
- BeeSimulator bs = new BeeSimulator(input, w, t);
- if (bs.isValid) {
- if (mStorage.size() > ID) {
- BeeSimulator removed = mStorage.remove(ID);
- mStorage.add(ID, bs);
- player.inventory.setItemStack(removed.queenStack);
-
- } else {
- mStorage.add(bs);
- player.inventory.setItemStack(null);
- }
- ((EntityPlayerMP) player).isChangingQuantityOnly = false;
- ((EntityPlayerMP) player).updateHeldItem();
-
- isCacheDirty = true;
+
+ ArrayList<Widget> buttons = new ArrayList<>();
+
+ if (!ModUtils.isClientThreaded()) {
+ HashMap<ItemID, Integer> itemMap = new HashMap<>();
+ HashMap<ItemID, ItemStack> stackMap = new HashMap<>();
+ HashMap<ItemID, ArrayList<Integer>> realSlotMap = new HashMap<>();
+ for (int i = 0, mStorageSize = mStorage.size(); i < mStorageSize; i++) {
+ BeeSimulator slot = mStorage.get(i);
+ ItemID id = ItemID.createNoCopy(slot.queenStack, false);
+ itemMap.merge(id, 1, Integer::sum);
+ stackMap.putIfAbsent(id, slot.queenStack);
+ realSlotMap.computeIfAbsent(id, unused -> new ArrayList<>())
+ .add(i);
+ }
+ drawables = new ArrayList<>();
+ for (Map.Entry<ItemID, Integer> entry : itemMap.entrySet()) {
+ drawables.add(
+ new GTHelper.StackableItemSlot(
+ entry.getValue(),
+ stackMap.get(entry.getKey()),
+ realSlotMap.get(entry.getKey())));
+ }
+ }
+
+ for (int ID = 0; ID < drawables.size(); ID++) {
+ final int finalID = ID;
+ buttons.add(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!(player instanceof EntityPlayerMP)) return;
+ if (!clickData.shift) {
+ ItemStack input = player.inventory.getItemStack();
+ if (input != null) {
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility
+ .sendChatToPlayer(player, EnumChatFormatting.RED + "Can't replace while running !");
+ return;
+ }
+ if (beeRoot.getType(input) == EnumBeeType.QUEEN) {
+ World w = getBaseMetaTileEntity().getWorld();
+ float t = (float) getVoltageTierExact();
+ BeeSimulator bs = new BeeSimulator(input, w, t);
+ if (bs.isValid) {
+ if (mStorage.size() > finalID) {
+ int realID = drawables.get(finalID).realSlots.get(0);
+ BeeSimulator removed = mStorage.remove(realID);
+ mStorage.add(realID, bs);
+ player.inventory.setItemStack(removed.queenStack);
+ } else {
+ mStorage.add(bs);
+ player.inventory.setItemStack(null);
}
+ ((EntityPlayerMP) player).isChangingQuantityOnly = false;
+ ((EntityPlayerMP) player).updateHeldItem();
+
+ isCacheDirty = true;
}
- return;
}
+ return;
}
+ }
- if (mStorage.size() <= ID) return;
- if (this.mMaxProgresstime > 0) {
- GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't eject while running !");
+ if (mStorage.size() <= finalID) return;
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't eject while running !");
+ return;
+ }
+ int realID = drawables.get(finalID).realSlots.get(0);
+ BeeSimulator removed = mStorage.remove(realID);
+ isCacheDirty = true;
+ if (clickData.shift) {
+ if (player.inventory.addItemStackToInventory(removed.queenStack)) {
+ player.inventoryContainer.detectAndSendChanges();
return;
}
- BeeSimulator removed = mStorage.remove(ID);
- isCacheDirty = true;
- if (clickData.shift) {
- if (player.inventory.addItemStackToInventory(removed.queenStack)) {
- player.inventoryContainer.detectAndSendChanges();
- return;
- }
- }
- if (clickData.mouseButton == 1) {
- if (player.inventory.getItemStack() == null) {
- player.inventory.setItemStack(removed.queenStack);
- ((EntityPlayerMP) player).isChangingQuantityOnly = false;
- ((EntityPlayerMP) player).updateHeldItem();
- return;
- }
+ }
+ if (clickData.mouseButton == 1) {
+ if (player.inventory.getItemStack() == null) {
+ player.inventory.setItemStack(removed.queenStack);
+ ((EntityPlayerMP) player).isChangingQuantityOnly = false;
+ ((EntityPlayerMP) player).updateHeldItem();
+ return;
}
+ }
- addOutput(removed.queenStack);
- GT_Utility.sendChatToPlayer(player, "Queen ejected !");
+ addOutput(removed.queenStack);
+ GT_Utility.sendChatToPlayer(player, "Queen ejected !");
+ })
+ .setBackground(
+ () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
+ .getItemSlot(),
+ new ItemDrawable(drawables.size() > finalID ? drawables.get(finalID).stack : null)
+ .withFixedSize(16, 16, 1, 1),
+ new Text(
+ drawables.size() > finalID ? (drawables.get(finalID).count > 99 ? "+99"
+ : String.valueOf(drawables.get(finalID).count)) : "").color(Color.PURPLE.normal)
+ .alignment(Alignment.TopRight) })
+ .dynamicTooltip(() -> {
+ if (drawables.size() > finalID) return Arrays.asList(
+ drawables.get(finalID).stack.getDisplayName(),
+ EnumChatFormatting.DARK_PURPLE + "There are "
+ + drawables.get(finalID).count
+ + " identical slots",
+ EnumChatFormatting.GRAY + "Left click to eject into input bus",
+ EnumChatFormatting.GRAY + "Right click to get into mouse",
+ EnumChatFormatting.GRAY + "Shift click to get into inventory",
+ EnumChatFormatting.GRAY + "Click with other queen in mouse to replace");
+ return Collections.emptyList();
})
- .setBackground(
- () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
- .getItemSlot(), GT_UITextures.OVERLAY_SLOT_BEE_QUEEN,
- new ItemDrawable(drawables.size() > ID ? drawables.get(ID) : null)
- .withFixedSize(16, 16, 1, 1) })
- .dynamicTooltip(() -> {
- if (drawables.size() > ID) return Arrays.asList(
- drawables.get(ID)
- .getDisplayName(),
- EnumChatFormatting.GRAY + "Left click to eject into input bus",
- EnumChatFormatting.GRAY + "Right click to get into mouse",
- EnumChatFormatting.GRAY + "Shift click to get into inventory",
- EnumChatFormatting.GRAY + "Click with other queen in mouse to replace");
- return Collections
- .singletonList(EnumChatFormatting.GRAY + "Click with queen in mouse to insert");
- })
- .setSize(18, 18));
+ .setSize(18, 18));
+ }
+
+ buttons.add(new ButtonWidget().setOnClick((clickData, widget) -> {
+ if (!(player instanceof EntityPlayerMP)) return;
+ ItemStack input = player.inventory.getItemStack();
+ if (input != null) {
+ if (this.mMaxProgresstime > 0) {
+ GT_Utility.sendChatToPlayer(player, EnumChatFormatting.RED + "Can't insert while running !");
+ return;
+ }
+ World w = getBaseMetaTileEntity().getWorld();
+ float t = (float) getVoltageTierExact();
+ BeeSimulator bs = new BeeSimulator(input, w, t);
+ if (bs.isValid) {
+ mStorage.add(bs);
+ player.inventory.setItemStack(null);
+ ((EntityPlayerMP) player).isChangingQuantityOnly = false;
+ ((EntityPlayerMP) player).updateHeldItem();
+ }
+ }
+ })
+ .setBackground(
+ () -> new IDrawable[] { getBaseMetaTileEntity().getGUITextureSet()
+ .getItemSlot(), GT_UITextures.OVERLAY_SLOT_BEE_QUEEN,
+ new Text(String.valueOf((mMaxSlots - usedSlots) > 99 ? "+99" : (mMaxSlots - usedSlots)))
+ .color(Color.PURPLE.normal)
+ .alignment(Alignment.TopRight) })
+ .dynamicTooltip(
+ () -> Arrays.asList(
+ EnumChatFormatting.GRAY + "Empty slot",
+ EnumChatFormatting.DARK_PURPLE + "There are " + (mMaxSlots - usedSlots) + " identical slots",
+ EnumChatFormatting.GRAY + "Click with queen in mouse to insert",
+ EnumChatFormatting.GRAY + "Shift click a queen in your inventory to insert"))
+ .setSize(18, 18));
+
+ final int perRow = 7;
+ for (int i = 0, imax = ((buttons.size() - 1) / perRow); i <= imax; i++) {
+ DynamicPositionedRow row = new DynamicPositionedRow().setSynced(false);
+ for (int j = 0, jmax = (i == imax ? (buttons.size() - 1) % perRow : (perRow - 1)); j <= jmax; j++) {
+ final int finalI = i * perRow;
+ final int finalJ = j;
+ final int ID = finalI + finalJ;
+ row.widget(buttons.get(ID));
}
beesContainer.widget(row.setPos(0, i * 18));
}