diff options
Diffstat (limited to 'src')
12 files changed, 1005 insertions, 975 deletions
diff --git a/src/main/java/kubatech/Tags.java b/src/main/java/kubatech/Tags.java index a49dc60207..cd596921a9 100644 --- a/src/main/java/kubatech/Tags.java +++ b/src/main/java/kubatech/Tags.java @@ -25,7 +25,7 @@ package kubatech; public class Tags { // GRADLETOKEN_* will be replaced by your configuration values at build time - public static final String MODID = "GRADLETOKEN_MODID"; - public static final String MODNAME = "GRADLETOKEN_MODNAME"; + public static final String MODID = "kubatech"; + public static final String MODNAME = "KubaTech"; public static final String VERSION = "GRADLETOKEN_VERSION"; } diff --git a/src/main/java/kubatech/api/DynamicInventory.java b/src/main/java/kubatech/api/DynamicInventory.java new file mode 100644 index 0000000000..ef89c3a341 --- /dev/null +++ b/src/main/java/kubatech/api/DynamicInventory.java @@ -0,0 +1,469 @@ +package kubatech.api; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Supplier; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; + +import org.lwjgl.opengl.GL11; + +import com.gtnewhorizons.modularui.api.GlStateManager; +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.drawable.UITexture; +import com.gtnewhorizons.modularui.api.math.Alignment; +import com.gtnewhorizons.modularui.api.math.Color; +import com.gtnewhorizons.modularui.api.screen.ModularWindow; +import com.gtnewhorizons.modularui.api.screen.UIBuildContext; +import com.gtnewhorizons.modularui.api.widget.Widget; +import com.gtnewhorizons.modularui.common.internal.Theme; +import com.gtnewhorizons.modularui.common.internal.wrapper.ModularGui; +import com.gtnewhorizons.modularui.common.widget.ButtonWidget; +import com.gtnewhorizons.modularui.common.widget.ChangeableWidget; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedRow; +import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; +import com.gtnewhorizons.modularui.common.widget.Scrollable; +import com.kuba6000.mobsinfo.api.utils.ItemID; + +import kubatech.api.helpers.GTHelper; +import kubatech.api.utils.ModUtils; + +public class DynamicInventory<T> { + + int width, height; + Supplier<Integer> slotsGetter; + private int slots = 0; + private int usedSlots = 0; + List<T> inventory; + TInventoryGetter<T> inventoryGetter; + TInventoryInjector inventoryInjector = null; + TInventoryExtractor<T> inventoryExtractor = null; + TInventoryReplacerOrMerger inventoryReplacer = null; + Supplier<Boolean> isEnabledGetter = null; + boolean isEnabled = true; + + public DynamicInventory(int width, int height, Supplier<Integer> slotsGetter, List<T> inventory, + TInventoryGetter<T> inventoryGetter) { + this.width = width; + this.height = height; + this.slotsGetter = slotsGetter; + this.inventory = inventory; + this.inventoryGetter = inventoryGetter; + } + + public DynamicInventory<T> allowInventoryInjection(TInventoryInjector inventoryInjector) { + this.inventoryInjector = inventoryInjector; + return this; + } + + public DynamicInventory<T> allowInventoryExtraction(TInventoryExtractor<T> inventoryExtractor) { + this.inventoryExtractor = inventoryExtractor; + return this; + } + + public DynamicInventory<T> allowInventoryReplace(TInventoryReplacerOrMerger inventoryReplacer) { + this.inventoryReplacer = inventoryReplacer; + return this; + } + + public DynamicInventory<T> setEnabled(Supplier<Boolean> isEnabled) { + this.isEnabledGetter = isEnabled; + return this; + } + + public UITexture getItemSlot() { + return ModularUITextures.ITEM_SLOT; + } + + @SuppressWarnings("UnstableApiUsage") + public Widget asWidget(ModularWindow.Builder builder, UIBuildContext buildContext) { + ChangeableWidget container = new ChangeableWidget(() -> createWidget(buildContext.getPlayer())); + + // TODO: Only reset the widget when there are more slot stacks, otherwise just refresh them somehow + + container.attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> { + if (slots != slotsGetter.get()) { + slots = slotsGetter.get(); + container.notifyChangeNoSync(); + } + return slots; + }, i -> { + if (slots != i) { + slots = i; + container.notifyChangeNoSync(); + } + }), builder) + .attachSyncer(new FakeSyncWidget.IntegerSyncer(() -> { + if (usedSlots != inventory.size()) { + usedSlots = inventory.size(); + container.notifyChangeNoSync(); + } + return usedSlots; + }, i -> { + if (usedSlots != i) { + usedSlots = i; + container.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 = inventory.size(); i < mStorageSize; i++) { + ItemStack stack = inventoryGetter.get(inventory.get(i)); + ItemID id = ItemID.createNoCopy(stack, false); + itemMap.merge(id, 1, Integer::sum); + stackMap.putIfAbsent(id, stack); + 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; + container.notifyChangeNoSync(); + } + return drawables; + }, l -> { + drawables.clear(); + drawables.addAll(l); + container.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); + if (isEnabledGetter != null) { + container.attachSyncer(new FakeSyncWidget.BooleanSyncer(isEnabledGetter, i -> isEnabled = i), builder); + } + return container; + } + + List<GTHelper.StackableItemSlot> drawables = new ArrayList<>(); + + private Widget createWidget(EntityPlayer player) { + Scrollable dynamicInventoryWidget = new Scrollable().setVerticalScroll(); + + 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, inventorySize = inventory.size(); i < inventorySize; i++) { + ItemStack stack = inventoryGetter.get(inventory.get(i)); + ItemID id = ItemID.createNoCopy(stack, false); + itemMap.merge(id, 1, Integer::sum); + stackMap.putIfAbsent(id, stack); + 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() { + + @Override + public void drawBackground(float partialTicks) { + super.drawBackground(partialTicks); + if (!isEnabled) { + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GlStateManager.colorMask(true, true, true, false); + ModularGui.drawSolidRect(1, 1, 16, 16, Color.withAlpha(Color.BLACK.normal, 0x80)); + GlStateManager.colorMask(true, true, true, true); + GL11.glDisable(GL11.GL_BLEND); + } + // Copied from SlotWidget#draw + else if (isHovering() && !getContext().getCursor() + .hasDraggable()) { + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GlStateManager.colorMask(true, true, true, false); + ModularGui.drawSolidRect(1, 1, 16, 16, Theme.INSTANCE.getSlotHighlight()); + GlStateManager.colorMask(true, true, true, true); + GL11.glDisable(GL11.GL_BLEND); + } + } + }.setPlayClickSound(false) + .setOnClick((clickData, widget) -> { + if (!(player instanceof EntityPlayerMP)) return; + if (!isEnabledGetter.get()) return; + + if (clickData.mouseButton == 2) { + // special button handler goes here + if (drawables.size() <= finalID) return; + if (player.capabilities.isCreativeMode && player.inventory.getItemStack() == null) { + int realID = drawables.get(finalID).realSlots.get(0); + ItemStack stack = inventoryGetter.get(inventory.get(realID)) + .copy(); + stack.stackSize = stack.getMaxStackSize(); + player.inventory.setItemStack(stack); + ((EntityPlayerMP) player).isChangingQuantityOnly = false; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } + } else if (clickData.shift) { + if (inventoryExtractor == null) return; + if (drawables.size() <= finalID) return; + int realID = drawables.get(finalID).realSlots.get(0); + T removed = inventoryExtractor.extract(realID); + if (removed != null) { + ItemStack stack = inventoryGetter.get(removed); + if (player.inventory.addItemStackToInventory(stack)) + player.inventoryContainer.detectAndSendChanges(); + else player.entityDropItem(stack, 0.f); + return; + } + } else { + ItemStack input = player.inventory.getItemStack(); + if (input != null) { + if (drawables.size() > finalID) { + if (inventoryReplacer == null) return; + int realID = drawables.get(finalID).realSlots.get(0); + ItemStack removed = inventoryReplacer.replaceOrMerge(realID, input); + if (removed == null) return; + player.inventory.setItemStack(removed.stackSize == 0 ? null : removed); + } else { + if (inventoryInjector == null) return; + if (clickData.mouseButton == 1) { + ItemStack copy = input.copy(); + copy.stackSize = 1; + ItemStack leftover = inventoryInjector.inject(copy); + if (leftover == null) return; + input.stackSize--; + if (input.stackSize > 0) { + ((EntityPlayerMP) player).isChangingQuantityOnly = true; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } else player.inventory.setItemStack(null); + } else { + ItemStack leftover = inventoryInjector.inject(input); + if (leftover == null) return; + if (input.stackSize > 0) { + ((EntityPlayerMP) player).isChangingQuantityOnly = true; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } else player.inventory.setItemStack(null); + } + } + ((EntityPlayerMP) player).isChangingQuantityOnly = false; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } + if (drawables.size() > finalID) { + if (inventoryExtractor == null) return; + int realID = drawables.get(finalID).realSlots.get(0); + T removed = inventoryExtractor.extract(realID); + if (removed != null) { + ItemStack stack = inventoryGetter.get(removed); + player.inventory.setItemStack(stack); + ((EntityPlayerMP) player).isChangingQuantityOnly = false; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } + } + } + }) + .setBackground( + () -> new IDrawable[] { 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 > 1) + ? (drawables.get(finalID).count > 99 ? "+99" + : String.valueOf(drawables.get(finalID).count)) + : "").color(Color.WHITE.normal) + .alignment(Alignment.TopLeft) + .withOffset(1, 1), + new Text( + (drawables.size() > finalID && drawables.get(finalID).stack.stackSize > 1) + ? String.valueOf(drawables.get(finalID).stack.stackSize) + : "").color(Color.WHITE.normal) + .shadow() + .alignment(Alignment.BottomRight) }) + .dynamicTooltip(() -> { + if (drawables.size() > finalID) { + List<String> tip = new ArrayList<>( + Collections.singletonList(drawables.get(finalID).stack.getDisplayName())); + if (drawables.get(finalID).count > 1) tip.add( + EnumChatFormatting.DARK_PURPLE + "There are " + + drawables.get(finalID).count + + " identical slots"); + return tip; + } + return Collections.emptyList(); + }) + .setSize(18, 18)); + } + + buttons.add(new ButtonWidget() { + + @Override + public void drawBackground(float partialTicks) { + super.drawBackground(partialTicks); + if (!isEnabled) { + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GlStateManager.colorMask(true, true, true, false); + ModularGui.drawSolidRect(1, 1, 16, 16, Color.withAlpha(Color.BLACK.normal, 0x80)); + GlStateManager.colorMask(true, true, true, true); + GL11.glDisable(GL11.GL_BLEND); + } + // Copied from SlotWidget#draw + else if (isHovering() && !getContext().getCursor() + .hasDraggable()) { + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GlStateManager.colorMask(true, true, true, false); + ModularGui.drawSolidRect(1, 1, 16, 16, Theme.INSTANCE.getSlotHighlight()); + GlStateManager.colorMask(true, true, true, true); + GL11.glDisable(GL11.GL_BLEND); + } + } + }.setPlayClickSound(false) + .setOnClick((clickData, widget) -> { + if (!(player instanceof EntityPlayerMP)) return; + if (!isEnabledGetter.get()) return; + ItemStack input = player.inventory.getItemStack(); + if (input != null) { + if (clickData.mouseButton == 1) { + ItemStack copy = input.copy(); + copy.stackSize = 1; + ItemStack leftover = inventoryInjector.inject(copy); + if (leftover == null) return; + input.stackSize--; + if (input.stackSize > 0) { + ((EntityPlayerMP) player).isChangingQuantityOnly = true; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } else player.inventory.setItemStack(null); + } else { + ItemStack leftover = inventoryInjector.inject(input); + if (leftover == null) return; + if (input.stackSize > 0) { + ((EntityPlayerMP) player).isChangingQuantityOnly = true; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } else player.inventory.setItemStack(null); + } + ((EntityPlayerMP) player).isChangingQuantityOnly = false; + ((EntityPlayerMP) player).updateHeldItem(); + return; + } + }) + .setBackground( + () -> new IDrawable[] { getItemSlot(), + new Text( + (slots - usedSlots) <= 1 ? "" + : ((slots - usedSlots) > 99 ? "+99" : String.valueOf((slots - usedSlots)))) + .color(Color.WHITE.normal) + .alignment(Alignment.TopLeft) + .withOffset(1, 1) }) + .dynamicTooltip(() -> { + List<String> tip = new ArrayList<>(Collections.singleton(EnumChatFormatting.GRAY + "Empty slot")); + if (slots - usedSlots > 1) + tip.add(EnumChatFormatting.DARK_PURPLE + "There are " + (slots - usedSlots) + " identical slots"); + return tip; + }) + .setSize(18, 18)); + + final int perRow = width / 18; + 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)); + } + dynamicInventoryWidget.widget(row.setPos(0, i * 18)); + } + + return dynamicInventoryWidget.setSize(width, height); + } + + @FunctionalInterface + public interface TInventoryGetter<T> { + + /** + * Allows to get an ItemStack from the dynamic inventory + * + * @param from Dynamic inventory item from which we want to take an item out + * @return ItemStack or null if inaccessible + */ + ItemStack get(T from); + } + + @FunctionalInterface + public interface TInventoryInjector { + + /** + * Allows to insert an item to the dynamic inventory + * + * @param what ItemStack which we are trying to insert + * @return Leftover ItemStack (stackSize == 0 if everything has been inserted) or null + */ + ItemStack inject(ItemStack what); + } + + @FunctionalInterface + public interface TInventoryExtractor<T> { + + /** + * Allows to extract an item from the dynamic inventory + * + * @param where Index from where we want to take an item out + * @return Item that we took out or null + */ + T extract(int where); + } + + @FunctionalInterface + public interface TInventoryReplacerOrMerger { + + /** + * Allows to replace an item in Dynamic Inventory + * + * @param where which index we want to replace + * @param stack what stack we want to replace it with + * @return Stack that we are left with or null + */ + ItemStack replaceOrMerge(int where, ItemStack stack); + } + +} diff --git a/src/main/java/kubatech/api/implementations/KubaTechGTMultiBlockBase.java b/src/main/java/kubatech/api/implementations/KubaTechGTMultiBlockBase.java index e561e712fe..119ce94019 100644 --- a/src/main/java/kubatech/api/implementations/KubaTechGTMultiBlockBase.java +++ b/src/main/java/kubatech/api/implementations/KubaTechGTMultiBlockBase.java @@ -20,9 +20,11 @@ package kubatech.api.implementations; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; import static kubatech.api.Variables.ln2; import static kubatech.api.Variables.ln4; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.function.Function; @@ -33,6 +35,11 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.fluids.FluidStack; import com.gtnewhorizons.modularui.api.drawable.IDrawable; +import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.math.Color; +import com.gtnewhorizons.modularui.api.math.MainAxisAlignment; +import com.gtnewhorizons.modularui.api.math.Pos2d; import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI; import com.gtnewhorizons.modularui.api.screen.ModularUIContext; import com.gtnewhorizons.modularui.api.screen.ModularWindow; @@ -42,6 +49,10 @@ import com.gtnewhorizons.modularui.common.builder.UIBuilder; import com.gtnewhorizons.modularui.common.builder.UIInfo; import com.gtnewhorizons.modularui.common.internal.wrapper.ModularGui; import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; +import com.gtnewhorizons.modularui.common.widget.Column; +import com.gtnewhorizons.modularui.common.widget.DrawableWidget; +import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; +import com.gtnewhorizons.modularui.common.widget.SlotWidget; import gregtech.api.enums.GT_Values; import gregtech.api.gui.modularui.GT_UITextures; @@ -50,6 +61,7 @@ import gregtech.api.metatileentity.BaseMetaTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_ExtendedPowerMultiBlockBase; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_OutputBus; import gregtech.common.tileentities.machines.GT_MetaTileEntity_Hatch_OutputBus_ME; +import kubatech.Tags; public abstract class KubaTechGTMultiBlockBase<T extends GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T>> extends GT_MetaTileEntity_ExtendedPowerMultiBlockBase<T> { @@ -244,6 +256,76 @@ public abstract class KubaTechGTMultiBlockBase<T extends GT_MetaTileEntity_Exten // UI stuff + public static final UITexture PICTURE_KUBATECH_LOGO = UITexture.fullImage(Tags.MODID, "gui/logo_13x15_dark"); + + @Override + public boolean useModularUI() { + return true; + } + + @Override + public void addGregTechLogo(ModularWindow.Builder builder) { + builder.widget( + new DrawableWidget().setDrawable(PICTURE_KUBATECH_LOGO) + .setSize(13, 15) + .setPos(191 - 13, 86 - 15) + .addTooltip(new Text(Tags.MODNAME).color(Color.GRAY.normal)) + .setTooltipShowUpDelay(TOOLTIP_DELAY)); + } + + protected List<SlotWidget> slotWidgets = new ArrayList<>(1); + + public void createInventorySlots() { + final SlotWidget inventorySlot = new SlotWidget(inventoryHandler, 1); + inventorySlot.setBackground(GT_UITextures.SLOT_DARK_GRAY); + slotWidgets.add(inventorySlot); + } + + @Override + public Pos2d getPowerSwitchButtonPos() { + return new Pos2d(174, 166 - (slotWidgets.size() * 18)); + } + + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + builder.widget( + new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) + .setPos(4, 4) + .setSize(190, 85)); + + slotWidgets.clear(); + createInventorySlots(); + + Column slotsColumn = new Column(); + for (int i = slotWidgets.size() - 1; i >= 0; i--) { + slotsColumn.widget(slotWidgets.get(i)); + } + builder.widget( + slotsColumn.setAlignment(MainAxisAlignment.END) + .setPos(173, 167 - 1)); + + final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); + drawTexts(screenElements, slotWidgets.size() > 0 ? slotWidgets.get(0) : null); + builder.widget(screenElements); + + builder.widget(createPowerSwitchButton(builder)) + .widget(createVoidExcessButton(builder)) + .widget(createInputSeparationButton(builder)) + .widget(createBatchModeButton(builder)) + .widget(createLockToSingleRecipeButton(builder)); + + DynamicPositionedColumn configurationElements = new DynamicPositionedColumn(); + addConfigurationWidgets(configurationElements, buildContext); + + builder.widget( + configurationElements.setAlignment(MainAxisAlignment.END) + .setPos(getPowerSwitchButtonPos().subtract(0, 18))); + } + + protected void addConfigurationWidgets(DynamicPositionedColumn configurationElements, UIBuildContext buildContext) { + + } + protected static String voltageTooltipFormatted(int tier) { return GT_Values.TIER_COLORS[tier] + GT_Values.VN[tier] + EnumChatFormatting.GRAY; } @@ -252,4 +334,6 @@ public abstract class KubaTechGTMultiBlockBase<T extends GT_MetaTileEntity_Exten protected static final Function<Integer, IDrawable> toggleButtonTextureGetter = val -> val == 0 ? GT_UITextures.OVERLAY_BUTTON_CROSS : GT_UITextures.OVERLAY_BUTTON_CHECKMARK; + protected static final Function<Integer, IDrawable[]> toggleButtonBackgroundGetter = val -> new IDrawable[] { + val == 0 ? GT_UITextures.BUTTON_STANDARD : GT_UITextures.BUTTON_STANDARD_PRESSED }; } diff --git a/src/main/java/kubatech/loaders/RecipeLoader.java b/src/main/java/kubatech/loaders/RecipeLoader.java index b8e8abfc8f..a9492a6535 100644 --- a/src/main/java/kubatech/loaders/RecipeLoader.java +++ b/src/main/java/kubatech/loaders/RecipeLoader.java @@ -165,15 +165,22 @@ public class RecipeLoader { } private static boolean registerMTE(ItemList item, Class<? extends MetaTileEntity> mte, String aName, - String aNameRegional, boolean dep) { + String aNameRegional, boolean... deps) { if (MTEID > MTEIDMax) throw new RuntimeException("MTE ID's"); - registerMTEUsingID(MTEID, item, mte, aName, aNameRegional, dep); + boolean dep = registerMTEUsingID(MTEID, item, mte, aName, aNameRegional, deps); MTEID++; return dep; } private static boolean registerMTEUsingID(int ID, ItemList item, Class<? extends MetaTileEntity> mte, String aName, - String aNameRegional, boolean dep) { + String aNameRegional, boolean... deps) { + boolean dep = true; + for (boolean b : deps) { + if (!b) { + dep = false; + break; + } + } if (dep) { try { item.set( diff --git a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeEntityCrusher.java b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeEntityCrusher.java index b7fec167cb..25b5a43d8f 100644 --- a/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeEntityCrusher.java +++ b/src/main/java/kubatech/tileentity/gregtech/multiblock/GT_MetaTileEntity_ExtremeEntityCrusher.java @@ -24,7 +24,6 @@ import static com.gtnewhorizon.structurelib.structure.StructureUtility.isAir; import static com.gtnewhorizon.structurelib.structure.StructureUtility.ofBlock; import static com.gtnewhorizon.structurelib.structure.StructureUtility.onElementPass; import static com.gtnewhorizon.structurelib.structure.StructureUtility.transpose; -import static com.kuba6000.mobsinfo.api.MobRecipe.MobNameToRecipeMap; import static gregtech.api.enums.GT_HatchElement.Energy; import static gregtech.api.enums.GT_HatchElement.InputBus; import static gregtech.api.enums.GT_HatchElement.Maintenance; @@ -34,6 +33,7 @@ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_ import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE; import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_ACTIVE_GLOW; import static gregtech.api.enums.Textures.BlockIcons.OVERLAY_FRONT_DISTILLATION_TOWER_GLOW; +import static gregtech.api.metatileentity.BaseTileEntity.TOOLTIP_DELAY; import static gregtech.api.util.GT_StructureUtility.buildHatchAdder; import static gregtech.api.util.GT_StructureUtility.ofFrame; import static kubatech.api.Variables.Author; @@ -61,7 +61,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.StatCollector; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.World; import net.minecraft.world.WorldProviderHell; @@ -82,20 +81,14 @@ import com.gtnewhorizon.structurelib.structure.IStructureDefinition; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import com.gtnewhorizon.structurelib.structure.StructureDefinition; import com.gtnewhorizons.modularui.api.drawable.Text; +import com.gtnewhorizons.modularui.api.drawable.UITexture; +import com.gtnewhorizons.modularui.api.forge.ItemStackHandler; import com.gtnewhorizons.modularui.api.math.Color; -import com.gtnewhorizons.modularui.api.math.Pos2d; -import com.gtnewhorizons.modularui.api.screen.ModularWindow; import com.gtnewhorizons.modularui.api.screen.UIBuildContext; import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; -import com.gtnewhorizons.modularui.common.widget.DrawableWidget; import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; -import com.gtnewhorizons.modularui.common.widget.DynamicPositionedRow; -import com.gtnewhorizons.modularui.common.widget.DynamicTextWidget; -import com.gtnewhorizons.modularui.common.widget.FakeSyncWidget; import com.gtnewhorizons.modularui.common.widget.SlotWidget; -import com.gtnewhorizons.modularui.common.widget.TextWidget; import com.kuba6000.mobsinfo.api.utils.FastRandom; -import com.kuba6000.mobsinfo.api.utils.ItemID; import com.mojang.authlib.GameProfile; import WayofTime.alchemicalWizardry.api.alchemy.energy.ReagentRegistry; @@ -121,6 +114,7 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_InputBus; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SimpleCheckRecipeResult; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; @@ -129,6 +123,7 @@ import kubatech.api.LoaderReference; import kubatech.api.helpers.ReflectionHelper; import kubatech.api.implementations.KubaTechGTMultiBlockBase; import kubatech.api.tileentity.CustomTileEntityPacketHandler; +import kubatech.api.utils.ModUtils; import kubatech.client.effect.EntityRenderer; import kubatech.loaders.MobHandlerLoader; import kubatech.network.CustomTileEntityPacket; @@ -223,6 +218,10 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher aNBT.setBoolean("mAnimationEnabled", mAnimationEnabled); aNBT.setByte("mGlassTier", mGlassTier); aNBT.setBoolean("mIsProducingInfernalDrops", mIsProducingInfernalDrops); + if (weaponCache.getStackInSlot(0) != null) aNBT.setTag( + "weaponCache", + weaponCache.getStackInSlot(0) + .writeToNBT(new NBTTagCompound())); } @Override @@ -233,6 +232,8 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher mGlassTier = aNBT.getByte("mGlassTier"); mIsProducingInfernalDrops = !aNBT.hasKey("mIsProducingInfernalDrops") || aNBT.getBoolean("mIsProducingInfernalDrops"); + if (aNBT.hasKey("weaponCache")) + weaponCache.setStackInSlot(0, ItemStack.loadItemStackFromNBT(aNBT.getCompoundTag("weaponCache"))); } @Override @@ -266,7 +267,7 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher .addInfo("Base energy usage: 2,000 EU/t") .addInfo("Supports perfect OC, minimum time: 20 ticks, after that multiplies the outputs.") .addInfo("Recipe time is based on mob health.") - .addInfo("You can additionally put a weapon in the ULV input bus.") + .addInfo("You can additionally put a weapon inside the GUI.") .addInfo("It will speed up the process and apply the looting level from the weapon (maximum 4 levels).") .addInfo(EnumChatFormatting.RED + "Enchanting the spikes inside does nothing!") .addInfo("Also produces 120 Liquid XP per operation.") @@ -287,10 +288,6 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher .addOtherStructurePart("Steel Frame Box", "All vertical edges without corners") .addOtherStructurePart("Diamond spikes", "Inside second layer") .addOutputBus("Any bottom casing", 1) - .addOtherStructurePart( - "1x ULV " + StatCollector.translateToLocal("GT5U.MBTT.InputBus"), - "Any bottom casing", - 1) .addOutputHatch("Any bottom casing", 1) .addEnergyHatch("Any bottom casing", 1) .addMaintenanceHatch("Any bottom casing", 1) @@ -478,12 +475,41 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher private CustomTileEntityPacket mobPacket = null; - private static class WeaponCache { + private static class WeaponCache extends ItemStackHandler { boolean isValid = false; - ItemID id = null; int looting = 0; double attackDamage = 0; + + public WeaponCache() { + super(1); + } + + @Override + protected void onContentsChanged(int slot) { + if (slot != 0) return; + if (ModUtils.isClientThreaded()) return; + ItemStack stack = getStackInSlot(0); + if (stack == null) { + isValid = false; + return; + } + // noinspection unchecked + attackDamage = ((Multimap<String, AttributeModifier>) stack.getAttributeModifiers()) + .get(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()) + .stream() + .mapToDouble( + attr -> attr.getAmount() + + (double) EnchantmentHelper.func_152377_a(stack, EnumCreatureAttribute.UNDEFINED)) + .sum(); + looting = Math.min(4, EnchantmentHelper.getEnchantmentLevel(Enchantment.looting.effectId, stack)); + isValid = true; + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return Enchantment.looting.canApply(stack); + } } private final WeaponCache weaponCache = new WeaponCache(); @@ -494,14 +520,14 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher public CheckRecipeResult checkProcessing() { if (getBaseMetaTileEntity().isClientSide()) return CheckRecipeResultRegistry.NO_RECIPE; ItemStack aStack = mInventory[1]; - if (aStack == null) return CheckRecipeResultRegistry.NO_RECIPE; + if (aStack == null) return SimpleCheckRecipeResult.ofFailure("EEC_nospawner"); - if (aStack.getItem() != poweredSpawnerItem) return CheckRecipeResultRegistry.NO_RECIPE; + if (aStack.getItem() != poweredSpawnerItem) return SimpleCheckRecipeResult.ofFailure("EEC_nospawner"); - if (aStack.getTagCompound() == null) return CheckRecipeResultRegistry.NO_RECIPE; + if (aStack.getTagCompound() == null) return SimpleCheckRecipeResult.ofFailure("EEC_invalidspawner"); String mobType = aStack.getTagCompound() .getString("mobType"); - if (mobType.isEmpty()) return CheckRecipeResultRegistry.NO_RECIPE; + if (mobType.isEmpty()) return SimpleCheckRecipeResult.ofFailure("EEC_invalidspawner"); if (mobType.equals("Skeleton") && getBaseMetaTileEntity().getWorld().provider instanceof WorldProviderHell && rand.nextInt(5) > 0) mobType = "witherSkeleton"; @@ -510,7 +536,8 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher if (recipe == null) return CheckRecipeResultRegistry.NO_RECIPE; if (!recipe.recipe.isPeacefulAllowed && this.getBaseMetaTileEntity() - .getWorld().difficultySetting == EnumDifficulty.PEACEFUL) return CheckRecipeResultRegistry.NO_RECIPE; + .getWorld().difficultySetting == EnumDifficulty.PEACEFUL) + return SimpleCheckRecipeResult.ofFailure("EEC_peaceful"); if (isInRitualMode && isRitualValid()) { if (getMaxInputEu() < recipe.mEUt / 4) return CheckRecipeResultRegistry.insufficientPower(recipe.mEUt / 4); @@ -524,38 +551,23 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher return CheckRecipeResultRegistry.insufficientPower(recipe.mEUt * 8); double attackDamage = DIAMOND_SPIKES_DAMAGE; // damage from spikes - GT_MetaTileEntity_Hatch_InputBus inputbus = this.mInputBusses.size() == 0 ? null : this.mInputBusses.get(0); - if (inputbus != null && !inputbus.isValid()) inputbus = null; - ItemStack lootingHolder = inputbus == null ? null : inputbus.getStackInSlot(0); weaponCheck: { - // noinspection EqualsBetweenInconvertibleTypes - if (weaponCache.isValid && weaponCache.id.equals(lootingHolder)) break weaponCheck; - if (lootingHolder == null || !Enchantment.looting.canApply(lootingHolder)) { - weaponCache.isValid = false; - break weaponCheck; - } - try { - // noinspection unchecked - weaponCache.attackDamage = ((Multimap<String, AttributeModifier>) lootingHolder - .getAttributeModifiers()) - .get(SharedMonsterAttributes.attackDamage.getAttributeUnlocalizedName()) - .stream() - .mapToDouble( - attr -> attr.getAmount() + (double) EnchantmentHelper - .func_152377_a(lootingHolder, EnumCreatureAttribute.UNDEFINED)) - .sum(); - } catch (Exception ex) { - ex.printStackTrace(); + GT_MetaTileEntity_Hatch_InputBus inputbus = this.mInputBusses.size() == 0 ? null + : this.mInputBusses.get(0); + if (inputbus != null && !inputbus.isValid()) inputbus = null; + ItemStack lootingHolder = inputbus == null ? null : inputbus.getStackInSlot(0); + if (lootingHolder == null) break weaponCheck; + if (weaponCache.getStackInSlot(0) != null) break weaponCheck; + if (weaponCache.isItemValid(0, lootingHolder)) { + weaponCache.setStackInSlot(0, lootingHolder); + inputbus.setInventorySlotContents(0, null); + updateSlots(); } - weaponCache.isValid = true; - weaponCache.looting = Math - .min(4, EnchantmentHelper.getEnchantmentLevel(Enchantment.looting.effectId, lootingHolder)); - weaponCache.id = ItemID.createNoCopy(lootingHolder, true, true); } if (weaponCache.isValid) attackDamage += weaponCache.attackDamage; if (EECPlayer == null) EECPlayer = new EECFakePlayer(this); - EECPlayer.currentWeapon = lootingHolder; + EECPlayer.currentWeapon = weaponCache.getStackInSlot(0); this.mOutputItems = recipe.generateOutputs( rand, @@ -567,15 +579,16 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher EECPlayer.currentWeapon = null; this.mOutputFluids = new FluidStack[] { FluidRegistry.getFluidStack("xpjuice", 120) }; + ItemStack weapon = weaponCache.getStackInSlot(0); int times = this.calculatePerfectOverclock(this.lEUt, this.mMaxProgresstime); - if (weaponCache.isValid && lootingHolder.isItemStackDamageable()) { - EECPlayer.currentWeapon = lootingHolder; - Item lootingHolderItem = lootingHolder.getItem(); + if (weaponCache.isValid && weapon.isItemStackDamageable()) { + EECPlayer.currentWeapon = weapon; + Item lootingHolderItem = weapon.getItem(); for (int i = 0; i < times + 1; i++) { // noinspection ConstantConditions - if (!lootingHolderItem.hitEntity(lootingHolder, recipe.recipe.entity, EECPlayer)) break; - if (lootingHolder.stackSize == 0) { - inputbus.setInventorySlotContents(0, null); + if (!lootingHolderItem.hitEntity(weapon, recipe.recipe.entity, EECPlayer)) break; + if (weapon.stackSize == 0) { + weaponCache.setStackInSlot(0, null); break; } } @@ -670,77 +683,8 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher } @Override - public boolean useModularUI() { - return true; - } - - @Override - public int getGUIHeight() { - return 166; - } - - @Override - public int getGUIWidth() { - return 176; - } - - @Override - public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.bindPlayerInventory( - buildContext.getPlayer(), - new Pos2d(7, 83), - this.getGUITextureSet() - .getItemSlot()); - } - - @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(7, 4) - .setSize(143, 75) - .setEnabled(widget -> !isFixed.apply(widget))); - final SlotWidget inventorySlot = new SlotWidget(inventoryHandler, 1) - .setFilter(stack -> stack.getItem() == poweredSpawnerItem); - - DynamicPositionedColumn configurationElements = new DynamicPositionedColumn(); - addConfigurationWidgets(configurationElements, buildContext, inventorySlot); - - builder.widget( - new DynamicPositionedColumn().setSynced(false) - .widget(inventorySlot) - .widget(new CycleButtonWidget().setToggle(() -> getBaseMetaTileEntity().isAllowedToWork(), works -> { - if (works) getBaseMetaTileEntity().enableWorking(); - else getBaseMetaTileEntity().disableWorking(); - - if (!(buildContext.getPlayer() instanceof EntityPlayerMP)) return; - String tChat = GT_Utility.trans("090", "Machine Processing: ") - + (works ? GT_Utility.trans("088", "Enabled") : GT_Utility.trans("087", "Disabled")); - if (hasAlternativeModeText()) tChat = getAlternativeModeText(); - GT_Utility.sendChatToPlayer(buildContext.getPlayer(), tChat); - }) - .addTooltip(0, new Text("Disabled").color(Color.RED.dark(3))) - .addTooltip(1, new Text("Enabled").color(Color.GREEN.dark(3))) - .setTextureGetter(toggleButtonTextureGetter) - .setBackground(GT_UITextures.BUTTON_STANDARD) - .setSize(18, 18) - .addTooltip("Working status")) - .widget(configurationElements.setEnabled(widget -> !getBaseMetaTileEntity().isActive())) - .widget( - new DrawableWidget().setDrawable(GT_UITextures.OVERLAY_BUTTON_CROSS) - .setSize(18, 18) - .addTooltip(new Text("Please stop the machine to configure it").color(Color.RED.dark(3))) - .setEnabled(widget -> getBaseMetaTileEntity().isActive())) - .setPos(151, 4)); - - final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); - drawTexts(screenElements, inventorySlot); - builder.widget(screenElements); - } - - private void addConfigurationWidgets(DynamicPositionedColumn configurationElements, UIBuildContext buildContext, - SlotWidget inventorySlot) { - configurationElements.setSynced(false); + protected void addConfigurationWidgets(DynamicPositionedColumn configurationElements, UIBuildContext buildContext) { + configurationElements.setSynced(true); configurationElements.widget(new CycleButtonWidget().setToggle(() -> isInRitualMode, v -> { if (this.mMaxProgresstime > 0) { GT_Utility.sendChatToPlayer(buildContext.getPlayer(), "Can't change mode when running !"); @@ -760,9 +704,10 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher } }) .setTextureGetter(toggleButtonTextureGetter) - .setBackground(GT_UITextures.BUTTON_STANDARD) - .setSize(18, 18) - .addTooltip("Ritual mode")); + .setVariableBackgroundGetter(toggleButtonBackgroundGetter) + .setSize(16, 16) + .addTooltip("Ritual mode") + .setTooltipShowUpDelay(TOOLTIP_DELAY)); configurationElements.widget(new CycleButtonWidget().setToggle(() -> mIsProducingInfernalDrops, v -> { if (this.mMaxProgresstime > 0) { GT_Utility.sendChatToPlayer(buildContext.getPlayer(), "Can't change mode when running !"); @@ -777,85 +722,30 @@ public class GT_MetaTileEntity_ExtremeEntityCrusher else GT_Utility.sendChatToPlayer(buildContext.getPlayer(), "Mobs can spawn infernal now"); }) .setTextureGetter(toggleButtonTextureGetter) - .setBackground(GT_UITextures.BUTTON_STANDARD) - .setSize(18, 18) + .setVariableBackgroundGetter(toggleButtonBackgroundGetter) + .setSize(16, 16) .addTooltip("Is allowed to spawn infernal mobs") - .addTooltip(new Text("Does not affect mobs that are always infernal !").color(Color.GRAY.normal))); + .addTooltip(new Text("Does not affect mobs that are always infernal !").color(Color.GRAY.normal)) + .setTooltipShowUpDelay(TOOLTIP_DELAY)); } @Override - protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { - screenElements.setSynced(false) - .setSpace(0) - .setPos(10, 7); - - screenElements.widget( - new DynamicPositionedRow().setSynced(false) - .widget(new TextWidget("Status: ").setDefaultColor(COLOR_TEXT_GRAY.get())) - .widget(new DynamicTextWidget(() -> { - if (getBaseMetaTileEntity().isActive()) return new Text("Working !").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().isAllowedToWork()) - return new Text("Enabled").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().wasShutdown()) - return new Text("Shutdown (CRITICAL)").color(Color.RED.dark(3)); - else return new Text("Disabled").color(Color.RED.dark(3)); - })) - .setEnabled(isFixed)); - screenElements.widget(new DynamicTextWidget(() -> { - ItemStack aStack = mInventory[1]; - if (aStack == null) return new Text("Insert Powered Spawner").color(Color.RED.dark(3)); - else { - Text invalid = new Text("Invalid Spawner").color(Color.RED.dark(3)); - if (aStack.getItem() != poweredSpawnerItem) return invalid; - - if (aStack.getTagCompound() == null) return invalid; - String mobType = aStack.getTagCompound() - .getString("mobType"); - if (mobType.isEmpty()) return invalid; - - if (!MobNameToRecipeMap.containsKey(mobType)) return invalid; - - return new Text(StatCollector.translateToLocal("entity." + mobType + ".name")) - .color(Color.GREEN.dark(3)); - } - }).setEnabled(isFixed)); - - screenElements - .widget( - new TextWidget(GT_Utility.trans("132", "Pipe is loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mWrench)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mWrench, val -> mWrench = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("133", "Screws are loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mScrewdriver)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mScrewdriver, val -> mScrewdriver = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("134", "Something is stuck.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSoftHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSoftHammer, val -> mSoftHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("135", "Platings are dented.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mHardHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mHardHammer, val -> mHardHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("136", "Circuitry burned out.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSolderingTool)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSolderingTool, val -> mSolderingTool = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("137", "That doesn't belong there.")) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mCrowbar)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mCrowbar, val -> mCrowbar = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("138", "Incomplete Structure.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mMachine)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mMachine, val -> mMachine = val)); + public void createInventorySlots() { + final SlotWidget spawnerSlot = new SlotWidget(inventoryHandler, 1); + spawnerSlot.setBackground( + GT_UITextures.SLOT_DARK_GRAY, + UITexture.fullImage(Tags.MODID, "gui/slot/gray_spawner") + .withFixedSize(16, 16) + .withOffset(1, 1)); + spawnerSlot.setFilter(stack -> stack.getItem() == poweredSpawnerItem); + slotWidgets.add(spawnerSlot); + final SlotWidget weaponSlot = new SlotWidget(weaponCache, 0); + weaponSlot.setBackground( + GT_UITextures.SLOT_DARK_GRAY, + UITexture.fullImage(Tags.MODID, "gui/slot/gray_sword") + .withFixedSize(16, 16) + .withOffset(1, 1)); + slotWidgets.add(weaponSlot); } private static class EECFakePlayer extends FakePlayer { 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 164ba7e7ba..0ab7995f7a 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 @@ -45,7 +45,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; import net.minecraft.block.Block; import net.minecraft.block.BlockFlower; @@ -81,31 +80,23 @@ import com.gtnewhorizon.structurelib.alignment.IAlignmentLimits; import com.gtnewhorizon.structurelib.structure.IStructureDefinition; import com.gtnewhorizon.structurelib.structure.StructureDefinition; 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.drawable.shapes.Rectangle; import com.gtnewhorizons.modularui.api.math.Color; -import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.math.MainAxisAlignment; 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.Widget; import com.gtnewhorizons.modularui.common.builder.UIInfo; import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.ChangeableWidget; import com.gtnewhorizons.modularui.common.widget.Column; import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; import com.gtnewhorizons.modularui.common.widget.DrawableWidget; import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; -import com.gtnewhorizons.modularui.common.widget.DynamicPositionedRow; -import com.gtnewhorizons.modularui.common.widget.DynamicTextWidget; 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; @@ -124,6 +115,7 @@ import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Input import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_MultiInput; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SimpleCheckRecipeResult; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; @@ -136,10 +128,9 @@ import ic2.api.crops.Crops; import ic2.core.Ic2Items; import ic2.core.crop.TileEntityCrop; import kubatech.Tags; +import kubatech.api.DynamicInventory; 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") @@ -150,6 +141,7 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse private static final int EIG_MATH_VERSION = 0; private static final int CONFIGURATION_WINDOW_ID = 999; + public final List<GreenHouseSlot> mStorage = new ArrayList<>(); private int oldVersion = 0; private int mCasing = 0; public int mMaxSlots = 0; @@ -445,7 +437,7 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse this.mEfficiencyIncrease = 10000; return CheckRecipeResultRegistry.SUCCESSFUL; } - if (mStorage.size() > mMaxSlots) return CheckRecipeResultRegistry.NO_RECIPE; + if (mStorage.size() > mMaxSlots) return SimpleCheckRecipeResult.ofFailure("EIG_slotoverflow"); if (mStorage.isEmpty()) return CheckRecipeResultRegistry.NO_RECIPE; waterusage = 0; @@ -474,7 +466,7 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse fluidsToUse.add(i); if (watercheck <= 0) break; } - if (watercheck > 0 && !debug) return CheckRecipeResultRegistry.NO_RECIPE; + if (watercheck > 0 && !debug) return SimpleCheckRecipeResult.ofFailure("EIG_missingwater"); watercheck = waterusage; for (GT_MetaTileEntity_Hatch_Input i : fluidsToUse) { int used = i.drain(watercheck, true).amount; @@ -515,12 +507,12 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse double multiplier = 1.d + (((double) boost / (double) maxboost) * 4d); if (isIC2Mode) { - if (glasTier < 6) return CheckRecipeResultRegistry.NO_RECIPE; + if (glasTier < 6) return SimpleCheckRecipeResult.ofFailure("EIG_ic2glass"); this.mMaxProgresstime = 100; List<ItemStack> outputs = new ArrayList<>(); for (int i = 0; i < Math.min(mMaxSlots, mStorage.size()); i++) outputs.addAll( mStorage.get(i) - .getIC2Drops(((double) this.mMaxProgresstime * 32d) * multiplier)); + .getIC2Drops(this, ((double) this.mMaxProgresstime * 32d) * multiplier)); this.mOutputItems = outputs.toArray(new ItemStack[0]); } else { this.mMaxProgresstime = Math.max(20, 100 / (tier - 3)); // Min 1 s @@ -561,30 +553,6 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse return valid; } - @Override - public boolean useModularUI() { - return true; - } - - @Override - public int getGUIHeight() { - return 166; - } - - @Override - public int getGUIWidth() { - return 176; - } - - @Override - public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.bindPlayerInventory( - buildContext.getPlayer(), - new Pos2d(7, 83), - this.getGUITextureSet() - .getItemSlot()); - } - private static final UIInfo<?, ?> GreenhouseUI = createKTMetaTileEntityUI( KT_ModulaUIContainer_ExtremeIndustrialGreenhouse::new); @@ -625,7 +593,7 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse GT_Utility.sendChatToPlayer(aPlayer, EnumChatFormatting.RED + "Can't insert while running !"); return super.transferStackInSlot(aPlayer, aSlotIndex); } - if (mte.addCrop(aStack)) { + if (mte.addCrop(aStack) != null) { if (aStack.stackSize == 0) s.putStack(null); else s.putStack(aStack); detectAndSendChanges(); @@ -635,281 +603,98 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse } } - List<GTHelper.StackableItemSlot> drawables = new ArrayList<>(); - private int usedSlots = 0; // mStorage.size() + @Override + protected void addConfigurationWidgets(DynamicPositionedColumn configurationElements, UIBuildContext buildContext) { + buildContext.addSyncedWindow(CONFIGURATION_WINDOW_ID, this::createConfigurationWindow); + configurationElements.setSynced(false); + configurationElements.widget( + new ButtonWidget().setOnClick( + (clickData, widget) -> { + if (!widget.isClient()) widget.getContext() + .openSyncedWindow(CONFIGURATION_WINDOW_ID); + }) + .setBackground(GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_BUTTON_CYCLIC) + .addTooltip("Configuration") + .setSize(16, 16)); + } + + DynamicInventory<GreenHouseSlot> dynamicInventory = new DynamicInventory<>( + 128, + 60, + () -> mMaxSlots, + mStorage, + s -> s.input).allowInventoryInjection(this::addCrop) + .allowInventoryExtraction(mStorage::remove) + .allowInventoryReplace((i, stack) -> { + if (!isIC2Mode) { + GreenHouseSlot slot = mStorage.get(i); + if (GT_Utility.areStacksEqual(stack, slot.input)) { + if (slot.input.stackSize < 64) { + slot.addAll( + this.getBaseMetaTileEntity() + .getWorld(), + stack); + return stack; + } + return null; + } + if (!addCrop(stack, i, true)) return null; + slot = mStorage.remove(i); + addCrop(stack, i, false); + return slot.input; + } else { + if (stack.stackSize != 1) return null; + if (!addCrop(stack, i, true)) return null; + GreenHouseSlot slot = mStorage.remove(i); + addCrop(stack, i, false); + return slot.input; + } + }) + .setEnabled(() -> this.mMaxProgresstime == 0); - @SuppressWarnings("UnstableApiUsage") @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(7, 4) - .setSize(143, 75) - .setEnabled(widget -> !isFixed.apply(widget))); + public void createInventorySlots() { - buildContext.addSyncedWindow(CONFIGURATION_WINDOW_ID, this::createConfigurationWindow); - EntityPlayer player = buildContext.getPlayer(); + } - // Slot is not needed + private boolean isInInventory = true; + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + isInInventory = !getBaseMetaTileEntity().isActive(); builder.widget( - new DynamicPositionedColumn().setSynced(false) - .widget(new CycleButtonWidget().setToggle(() -> getBaseMetaTileEntity().isAllowedToWork(), works -> { - if (works) getBaseMetaTileEntity().enableWorking(); - else getBaseMetaTileEntity().disableWorking(); - - if (!(player instanceof EntityPlayerMP)) return; - String tChat = GT_Utility.trans("090", "Machine Processing: ") - + (works ? GT_Utility.trans("088", "Enabled") : GT_Utility.trans("087", "Disabled")); - if (hasAlternativeModeText()) tChat = getAlternativeModeText(); - GT_Utility.sendChatToPlayer(player, tChat); - }) - .addTooltip(0, new Text("Disabled").color(Color.RED.dark(3))) - .addTooltip(1, new Text("Enabled").color(Color.GREEN.dark(3))) - .setTextureGetter(toggleButtonTextureGetter) - .setBackground(GT_UITextures.BUTTON_STANDARD) - .setSize(18, 18) - .addTooltip("Working status")) - .widget( - new ButtonWidget().setOnClick( - (clickData, widget) -> { - if (!widget.isClient()) widget.getContext() - .openSyncedWindow(CONFIGURATION_WINDOW_ID); - }) - .setBackground(GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_BUTTON_CYCLIC) - .addTooltip("Configuration") - .setSize(18, 18)) - .setPos(151, 4)); - - 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); - cropsContainer.notifyChangeNoSync(); - } - return mMaxSlots; - }, i -> { - if (mMaxSlots != i) { - mMaxSlots = i; - cropsContainer.notifyChangeNoSync(); - } - }), 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)); + new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) + .setPos(4, 4) + .setSize(190, 85) + .setEnabled(w -> !isInInventory)); + builder.widget( + dynamicInventory.asWidget(builder, buildContext) + .setPos(10, 16) + .setBackground(new Rectangle().setColor(Color.rgb(163, 163, 198))) + .setEnabled(w -> isInInventory)); + builder.widget( + new CycleButtonWidget().setToggle(() -> isInInventory, i -> isInInventory = i) + .setTextureGetter(i -> i == 0 ? new Text("Inventory") : new Text("Status")) + .setBackground(GT_UITextures.BUTTON_STANDARD) + .setPos(140, 4) + .setSize(55, 16)); final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); drawTexts(screenElements, null); - builder.widget(screenElements); - } + builder.widget(screenElements.setEnabled(w -> !isInInventory)); - protected Widget createCropsContainerWidget(EntityPlayer player) { - Scrollable cropsContainer = new Scrollable().setVerticalScroll(); - - 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()))); - } - } + builder.widget(createPowerSwitchButton(builder)) + .widget(createVoidExcessButton(builder)) + .widget(createInputSeparationButton(builder)) + .widget(createBatchModeButton(builder)) + .widget(createLockToSingleRecipeButton(builder)); - 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 (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; - } - } - 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() > 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)); - } + DynamicPositionedColumn configurationElements = new DynamicPositionedColumn(); + addConfigurationWidgets(configurationElements, buildContext); - 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)); - } - return cropsContainer.setPos(10, 16) - .setSize(128, 60); + builder.widget( + configurationElements.setAlignment(MainAxisAlignment.END) + .setPos(getPowerSwitchButtonPos().subtract(0, 18))); } protected ModularWindow createConfigurationWindow(final EntityPlayer player) { @@ -1027,61 +812,75 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse return builder.build(); } + private HashMap<ItemStack, Double> GUIDropProgress = new HashMap<>(); + + @Override + protected String generateCurrentRecipeInfoString() { + if (!isIC2Mode) return super.generateCurrentRecipeInfoString(); + StringBuilder ret = new StringBuilder(EnumChatFormatting.WHITE + "Progress: ") + .append(String.format("%,.2f", (double) mProgresstime / 20)) + .append("s / ") + .append(String.format("%,.2f", (double) mMaxProgresstime / 20)) + .append("s (") + .append(String.format("%,.1f", (double) mProgresstime / mMaxProgresstime * 100)) + .append("%)\n"); + + for (Map.Entry<ItemStack, Double> drop : GUIDropProgress.entrySet()) { + ret.append( + drop.getKey() + .getDisplayName()) + .append(": ") + .append( + String.format( + "%.2f (+%d)\n", + drop.getValue(), + Arrays.stream(mOutputItems) + .filter(s -> s.isItemEqual(drop.getKey())) + .mapToInt(i -> i.stackSize) + .sum())); + } + + return ret.toString(); + } + @Override protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { - screenElements.setSynced(false) - .setSpace(0) - .setPos(10, 7); - - screenElements.widget( - new DynamicPositionedRow().setSynced(false) - .widget(new TextWidget("Status: ").setDefaultColor(COLOR_TEXT_GRAY.get())) - .widget(new DynamicTextWidget(() -> { - if (getBaseMetaTileEntity().isActive()) return new Text("Working !").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().isAllowedToWork()) - return new Text("Enabled").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().wasShutdown()) - return new Text("Shutdown (CRITICAL)").color(Color.RED.dark(3)); - else return new Text("Disabled").color(Color.RED.dark(3)); - })) - .setEnabled(isFixed)); - - screenElements - .widget( - new TextWidget(GT_Utility.trans("132", "Pipe is loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mWrench)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mWrench, val -> mWrench = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("133", "Screws are loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mScrewdriver)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mScrewdriver, val -> mScrewdriver = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("134", "Something is stuck.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSoftHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSoftHammer, val -> mSoftHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("135", "Platings are dented.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mHardHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mHardHammer, val -> mHardHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("136", "Circuitry burned out.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSolderingTool)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSolderingTool, val -> mSolderingTool = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("137", "That doesn't belong there.")) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mCrowbar)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mCrowbar, val -> mCrowbar = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("138", "Incomplete Structure.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mMachine)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mMachine, val -> mMachine = val)); + screenElements.widget(new FakeSyncWidget.BooleanSyncer(() -> isIC2Mode, b -> isIC2Mode = b)); + screenElements.widget(new FakeSyncWidget<>(() -> { + HashMap<ItemStack, Double> ret = new HashMap<>(); + HashMap<String, Double> dropProgress = new HashMap<>(); + + for (Map.Entry<String, Double> drop : dropprogress.entrySet()) { + dropProgress.merge(drop.getKey(), drop.getValue(), Double::sum); + } + + for (Map.Entry<String, Double> drop : dropProgress.entrySet()) { + ret.put(GreenHouseSlot.dropstacks.get(drop.getKey()), drop.getValue()); + } + return ret; + }, h -> GUIDropProgress = h, (buffer, h) -> { + buffer.writeVarIntToBuffer(h.size()); + for (Map.Entry<ItemStack, Double> itemStackDoubleEntry : h.entrySet()) { + try { + buffer.writeItemStackToBuffer(itemStackDoubleEntry.getKey()); + buffer.writeDouble(itemStackDoubleEntry.getValue()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }, buffer -> { + int len = buffer.readVarIntFromBuffer(); + HashMap<ItemStack, Double> ret = new HashMap<>(len); + for (int i = 0; i < len; i++) { + try { + ret.put(buffer.readItemStackFromBuffer(), buffer.readDouble()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return ret; + })); + super.drawTexts(screenElements, inventorySlot); } @Override @@ -1147,8 +946,6 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; } - public final List<GreenHouseSlot> mStorage = new ArrayList<>(); - private boolean addCrop(ItemStack input, int slot, boolean simulate) { if (!isIC2Mode && !simulate) for (GreenHouseSlot g : mStorage) if (g.input.stackSize < 64 && GT_Utility.areStacksEqual(g.input, input)) { @@ -1169,10 +966,13 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse return false; } - private boolean addCrop(ItemStack input) { - return addCrop(input, -1, false); + private ItemStack addCrop(ItemStack input) { + if (addCrop(input, -1, false)) return input; + return null; } + final Map<String, Double> dropprogress = new HashMap<>(); + private static class GreenHouseSlot extends InventoryCrafting { final ItemStack input; @@ -1526,10 +1326,10 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse return drops; } - final Map<String, Double> dropprogress = new HashMap<>(); static final Map<String, ItemStack> dropstacks = new HashMap<>(); - public List<ItemStack> getIC2Drops(double timeelapsed) { + public List<ItemStack> getIC2Drops(GT_MetaTileEntity_ExtremeIndustrialGreenhouse tileEntity, + double timeelapsed) { int r = rn.nextInt(10); if (generations.size() <= r) return new ArrayList<>(); double growthPercent = (timeelapsed / (double) growthticks); @@ -1539,13 +1339,11 @@ public class GT_MetaTileEntity_ExtremeIndustrialGreenhouse for (ItemStack s : copied) { double pro = ((double) s.stackSize * growthPercent); s.stackSize = 1; - if (dropprogress.containsKey(s.toString())) - dropprogress.put(s.toString(), dropprogress.get(s.toString()) + pro); - else dropprogress.put(s.toString(), pro); + tileEntity.dropprogress.merge(s.toString(), pro, Double::sum); if (!dropstacks.containsKey(s.toString())) dropstacks.put(s.toString(), s.copy()); } copied.clear(); - for (Map.Entry<String, Double> entry : dropprogress.entrySet()) if (entry.getValue() >= 1d) { + for (Map.Entry<String, Double> entry : tileEntity.dropprogress.entrySet()) if (entry.getValue() >= 1d) { copied.add( dropstacks.get(entry.getKey()) .copy()); 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 360ea1ee65..1b519179d7 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 @@ -50,8 +50,6 @@ 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; import java.util.stream.IntStream; @@ -77,28 +75,21 @@ import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; import com.gtnewhorizon.structurelib.structure.StructureDefinition; 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.drawable.shapes.Rectangle; import com.gtnewhorizons.modularui.api.math.Color; -import com.gtnewhorizons.modularui.api.math.Pos2d; +import com.gtnewhorizons.modularui.api.math.MainAxisAlignment; 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.Widget; import com.gtnewhorizons.modularui.common.builder.UIInfo; import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer; import com.gtnewhorizons.modularui.common.widget.ButtonWidget; -import com.gtnewhorizons.modularui.common.widget.ChangeableWidget; import com.gtnewhorizons.modularui.common.widget.Column; import com.gtnewhorizons.modularui.common.widget.CycleButtonWidget; import com.gtnewhorizons.modularui.common.widget.DrawableWidget; import com.gtnewhorizons.modularui.common.widget.DynamicPositionedColumn; -import com.gtnewhorizons.modularui.common.widget.DynamicPositionedRow; -import com.gtnewhorizons.modularui.common.widget.DynamicTextWidget; 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; @@ -126,14 +117,14 @@ import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_Hatch_Energy; import gregtech.api.recipe.check.CheckRecipeResult; import gregtech.api.recipe.check.CheckRecipeResultRegistry; +import gregtech.api.recipe.check.SimpleCheckRecipeResult; import gregtech.api.render.TextureFactory; import gregtech.api.util.GT_Multiblock_Tooltip_Builder; import gregtech.api.util.GT_Utility; import kubatech.Tags; +import kubatech.api.DynamicInventory; 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 @@ -494,9 +485,10 @@ public class GT_MetaTileEntity_MegaIndustrialApiary mStorage.forEach(s -> s.generate(w, t)); } - if (mStorage.size() > mMaxSlots) return CheckRecipeResultRegistry.NO_RECIPE; + if (mStorage.size() > mMaxSlots) + return SimpleCheckRecipeResult.ofFailure("MegaApiary_slotoverflow"); - if (flowersError) return CheckRecipeResultRegistry.NO_RECIPE; + if (flowersError) return SimpleCheckRecipeResult.ofFailure("MegaApiary_noflowers"); if (needsTVarUpdate) { float t = (float) getVoltageTierExact(); @@ -525,7 +517,7 @@ public class GT_MetaTileEntity_MegaIndustrialApiary List<ItemStack> stacks = new ArrayList<>(); for (int i = 0, mStorageSize = Math.min(mStorage.size(), mMaxSlots); i < mStorageSize; i++) { BeeSimulator beeSimulator = mStorage.get(i); - stacks.addAll(beeSimulator.getDrops(64_00d * boosted)); + stacks.addAll(beeSimulator.getDrops(this, 64_00d * boosted)); } this.lEUt = -(int) ((double) GT_Values.V[6] * (double) mMaxSlots * 0.99d); @@ -639,30 +631,6 @@ public class GT_MetaTileEntity_MegaIndustrialApiary return new ITexture[] { Textures.BlockIcons.getCasingTextureForId(CASING_INDEX) }; } - @Override - public boolean useModularUI() { - return true; - } - - @Override - public int getGUIHeight() { - return 166; - } - - @Override - public int getGUIWidth() { - return 176; - } - - @Override - public void bindPlayerInventoryUI(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.bindPlayerInventory( - buildContext.getPlayer(), - new Pos2d(7, 83), - this.getGUITextureSet() - .getItemSlot()); - } - private static final UIInfo<?, ?> MegaApiaryUI = createKTMetaTileEntityUI( KT_ModulaUIContainer_MegaIndustrialApiary::new); @@ -720,311 +688,94 @@ public class GT_MetaTileEntity_MegaIndustrialApiary } } - private List<GTHelper.StackableItemSlot> drawables = new ArrayList<>(); - private int usedSlots = 0; // mStorage.size() + DynamicInventory<BeeSimulator> dynamicInventory = new DynamicInventory<>( + 128, + 60, + () -> mMaxSlots, + mStorage, + s -> s.queenStack).allowInventoryInjection(input -> { + World w = getBaseMetaTileEntity().getWorld(); + float t = (float) getVoltageTierExact(); + BeeSimulator bs = new BeeSimulator(input, w, t); + if (bs.isValid) { + mStorage.add(bs); + return input; + } + return null; + }) + .allowInventoryExtraction(mStorage::remove) + .allowInventoryReplace((i, stack) -> { + if (stack.stackSize != 1) return null; + World w = getBaseMetaTileEntity().getWorld(); + float t = (float) getVoltageTierExact(); + BeeSimulator bs = new BeeSimulator(stack, w, t); + if (bs.isValid) { + BeeSimulator removed = mStorage.remove(i); + mStorage.add(i, bs); + return removed.queenStack; + } + return null; + }) + .setEnabled(() -> this.mMaxProgresstime == 0); - @SuppressWarnings("UnstableApiUsage") @Override - public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { - builder.widget( - new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) - .setPos(7, 4) - .setSize(143, 75) - .setEnabled(widget -> !isFixed.apply(widget))); + public void createInventorySlots() { - buildContext.addSyncedWindow(CONFIGURATION_WINDOW_ID, this::createConfigurationWindow); - EntityPlayer player = buildContext.getPlayer(); + } - // Slot is not needed + private boolean isInInventory = true; + @Override + public void addUIWidgets(ModularWindow.Builder builder, UIBuildContext buildContext) { + isInInventory = !getBaseMetaTileEntity().isActive(); builder.widget( - new DynamicPositionedColumn().setSynced(false) - .widget(new CycleButtonWidget().setToggle(() -> getBaseMetaTileEntity().isAllowedToWork(), works -> { - if (works) getBaseMetaTileEntity().enableWorking(); - else getBaseMetaTileEntity().disableWorking(); - - if (!(player instanceof EntityPlayerMP)) return; - String tChat = GT_Utility.trans("090", "Machine Processing: ") - + (works ? GT_Utility.trans("088", "Enabled") : GT_Utility.trans("087", "Disabled")); - if (hasAlternativeModeText()) tChat = getAlternativeModeText(); - GT_Utility.sendChatToPlayer(player, tChat); - }) - .addTooltip(0, new Text("Disabled").color(Color.RED.dark(3))) - .addTooltip(1, new Text("Enabled").color(Color.GREEN.dark(3))) - .setTextureGetter(toggleButtonTextureGetter) - .setBackground(GT_UITextures.BUTTON_STANDARD) - .setSize(18, 18) - .addTooltip("Working status")) - .widget( - new ButtonWidget().setOnClick( - (clickData, widget) -> { - if (!widget.isClient()) widget.getContext() - .openSyncedWindow(CONFIGURATION_WINDOW_ID); - }) - .setBackground(GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_BUTTON_CYCLIC) - .addTooltip("Configuration") - .setSize(18, 18)) - .setPos(151, 4)); - - 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); - beesContainer.notifyChangeNoSync(); - } - return mMaxSlots; - }, i -> { - if (mMaxSlots != i) { - mMaxSlots = i; - beesContainer.notifyChangeNoSync(); - } - }), 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() - .map(flowersCache::get) - .filter(Objects::nonNull) - .sorted() - .collect(Collectors.toList()); - s.add(0, "Missing flower types:"); - return s; - } else return Collections.emptyList(); - }, f -> flowersGUI = f, (b, e) -> { - try { - b.writeStringToBuffer(e); - } catch (IOException ex) { - throw new RuntimeException(ex); - } - }, b -> { - try { - return b.readStringFromBuffer(999); - } catch (IOException e) { - throw new RuntimeException(e); - } - }), builder)); + new DrawableWidget().setDrawable(GT_UITextures.PICTURE_SCREEN_BLACK) + .setPos(4, 4) + .setSize(190, 85) + .setEnabled(w -> !isInInventory)); + builder.widget( + dynamicInventory.asWidget(builder, buildContext) + .setPos(10, 16) + .setBackground(new Rectangle().setColor(Color.rgb(163, 163, 198))) + .setEnabled(w -> isInInventory)); + builder.widget( + new CycleButtonWidget().setToggle(() -> isInInventory, i -> isInInventory = i) + .setTextureGetter(i -> i == 0 ? new Text("Inventory") : new Text("Status")) + .setBackground(GT_UITextures.BUTTON_STANDARD) + .setPos(140, 4) + .setSize(55, 16)); final DynamicPositionedColumn screenElements = new DynamicPositionedColumn(); drawTexts(screenElements, null); - builder.widget(screenElements); - } - - private Widget createBeesContainerWidget(EntityPlayer player) { - Scrollable beesContainer = new Scrollable().setVerticalScroll(); - - 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()))); - } - } + builder.widget(screenElements.setEnabled(w -> !isInInventory)); - 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(); + builder.widget(createPowerSwitchButton(builder)) + .widget(createVoidExcessButton(builder)) + .widget(createInputSeparationButton(builder)) + .widget(createBatchModeButton(builder)) + .widget(createLockToSingleRecipeButton(builder)); - isCacheDirty = true; - } - } - return; - } - } + DynamicPositionedColumn configurationElements = new DynamicPositionedColumn(); + addConfigurationWidgets(configurationElements, buildContext); - 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; - } - } - if (clickData.mouseButton == 1) { - if (player.inventory.getItemStack() == null) { - player.inventory.setItemStack(removed.queenStack); - ((EntityPlayerMP) player).isChangingQuantityOnly = false; - ((EntityPlayerMP) player).updateHeldItem(); - return; - } - } + builder.widget( + configurationElements.setAlignment(MainAxisAlignment.END) + .setPos(getPowerSwitchButtonPos().subtract(0, 18))); + } - 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(); + @Override + protected void addConfigurationWidgets(DynamicPositionedColumn configurationElements, UIBuildContext buildContext) { + buildContext.addSyncedWindow(CONFIGURATION_WINDOW_ID, this::createConfigurationWindow); + configurationElements.setSynced(false); + configurationElements.widget( + new ButtonWidget().setOnClick( + (clickData, widget) -> { + if (!widget.isClient()) widget.getContext() + .openSyncedWindow(CONFIGURATION_WINDOW_ID); }) - .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)); - } - beesContainer.setPos(10, 16) - .setSize(128, 60); - return beesContainer; + .setBackground(GT_UITextures.BUTTON_STANDARD, GT_UITextures.OVERLAY_BUTTON_CYCLIC) + .addTooltip("Configuration") + .setSize(16, 16)); } protected ModularWindow createConfigurationWindow(final EntityPlayer player) { @@ -1126,67 +877,82 @@ public class GT_MetaTileEntity_MegaIndustrialApiary return builder.build(); } - private List<String> flowersGUI = Collections.emptyList(); + // private List<String> flowersGUI = Collections.emptyList(); + + private HashMap<ItemStack, Double> GUIDropProgress = new HashMap<>(); + + @Override + protected String generateCurrentRecipeInfoString() { + if (mSecondaryMode == 1) return super.generateCurrentRecipeInfoString(); + StringBuilder ret = new StringBuilder(EnumChatFormatting.WHITE + "Progress: ") + .append(String.format("%,.2f", (double) mProgresstime / 20)) + .append("s / ") + .append(String.format("%,.2f", (double) mMaxProgresstime / 20)) + .append("s (") + .append(String.format("%,.1f", (double) mProgresstime / mMaxProgresstime * 100)) + .append("%)\n"); + + for (Map.Entry<ItemStack, Double> drop : GUIDropProgress.entrySet()) { + ret.append( + drop.getKey() + .getDisplayName()) + .append(": ") + .append( + String.format( + "%.2f (+%d)\n", + drop.getValue(), + Arrays.stream(mOutputItems) + .filter(s -> s.isItemEqual(drop.getKey())) + .mapToInt(i -> i.stackSize) + .sum())); + } + + return ret.toString(); + } @Override protected void drawTexts(DynamicPositionedColumn screenElements, SlotWidget inventorySlot) { - screenElements.setSynced(false) - .setSpace(0) - .setPos(10, 7); - - screenElements.widget( - new DynamicPositionedRow().setSynced(false) - .widget(new TextWidget("Status: ").setDefaultColor(COLOR_TEXT_GRAY.get())) - .widget(new DynamicTextWidget(() -> { - if (flowersError) return new Text("Missing flowers!").color(Color.RED.dark(3)); - if (getBaseMetaTileEntity().isActive()) return new Text("Working !").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().isAllowedToWork()) - return new Text("Enabled").color(Color.GREEN.dark(3)); - else if (getBaseMetaTileEntity().wasShutdown()) - return new Text("Shutdown (CRITICAL)").color(Color.RED.dark(3)); - else return new Text("Disabled").color(Color.RED.dark(3)); - }).dynamicTooltip(() -> flowersGUI) - .setUpdateTooltipEveryTick(true)) - .setEnabled(isFixed)); - - screenElements - .widget( - new TextWidget(GT_Utility.trans("132", "Pipe is loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mWrench)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mWrench, val -> mWrench = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("133", "Screws are loose.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mScrewdriver)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mScrewdriver, val -> mScrewdriver = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("134", "Something is stuck.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSoftHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSoftHammer, val -> mSoftHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("135", "Platings are dented.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mHardHammer)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mHardHammer, val -> mHardHammer = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("136", "Circuitry burned out.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mSolderingTool)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mSolderingTool, val -> mSolderingTool = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("137", "That doesn't belong there.")) - .setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mCrowbar)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mCrowbar, val -> mCrowbar = val)); - screenElements - .widget( - new TextWidget(GT_Utility.trans("138", "Incomplete Structure.")).setDefaultColor(COLOR_TEXT_WHITE.get()) - .setEnabled(widget -> !mMachine)) - .widget(new FakeSyncWidget.BooleanSyncer(() -> mMachine, val -> mMachine = val)); + + screenElements.widget(new FakeSyncWidget.IntegerSyncer(() -> mSecondaryMode, b -> mSecondaryMode = b)); + screenElements.widget(new FakeSyncWidget<>(() -> { + HashMap<ItemStack, Double> ret = new HashMap<>(); + HashMap<ItemID, Double> dropProgress = new HashMap<>(); + + for (Map.Entry<ItemID, Double> drop : this.dropProgress.entrySet()) { + dropProgress.merge(drop.getKey(), drop.getValue(), Double::sum); + } + + for (Map.Entry<ItemID, Double> drop : dropProgress.entrySet()) { + ret.put(BeeSimulator.dropstacks.get(drop.getKey()), drop.getValue()); + } + return ret; + }, h -> GUIDropProgress = h, (buffer, h) -> { + buffer.writeVarIntToBuffer(h.size()); + for (Map.Entry<ItemStack, Double> itemStackDoubleEntry : h.entrySet()) { + try { + buffer.writeItemStackToBuffer(itemStackDoubleEntry.getKey()); + buffer.writeDouble(itemStackDoubleEntry.getValue()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + }, buffer -> { + int len = buffer.readVarIntFromBuffer(); + HashMap<ItemStack, Double> ret = new HashMap<>(len); + for (int i = 0; i < len; i++) { + try { + ret.put(buffer.readItemStackFromBuffer(), buffer.readDouble()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return ret; + })); + super.drawTexts(screenElements, inventorySlot); } + final HashMap<ItemID, Double> dropProgress = new HashMap<>(); + private static class BeeSimulator { final ItemStack queenStack; @@ -1280,20 +1046,27 @@ public class GT_MetaTileEntity_MegaIndustrialApiary return tag; } - final HashMap<BeeDrop, Double> dropProgress = new HashMap<>(); - - public List<ItemStack> getDrops(final double timePassed) { - drops.forEach(d -> dropProgress.merge(d, d.getAmount(timePassed / 550d), Double::sum)); - specialDrops.forEach(d -> dropProgress.merge(d, d.getAmount(timePassed / 550d), Double::sum)); + static final Map<ItemID, ItemStack> dropstacks = new HashMap<>(); + + public List<ItemStack> getDrops(final GT_MetaTileEntity_MegaIndustrialApiary MTE, final double timePassed) { + drops.forEach(d -> { + MTE.dropProgress.merge(d.id, d.getAmount(timePassed / 550d), Double::sum); + if (!dropstacks.containsKey(d.id)) dropstacks.put(d.id, d.stack); + }); + specialDrops.forEach(d -> { + MTE.dropProgress.merge(d.id, d.getAmount(timePassed / 550d), Double::sum); + if (!dropstacks.containsKey(d.id)) dropstacks.put(d.id, d.stack); + }); List<ItemStack> currentDrops = new ArrayList<>(); - dropProgress.entrySet() + MTE.dropProgress.entrySet() .forEach(e -> { double v = e.getValue(); while (v > 1.f) { int size = Math.min((int) v, 64); - currentDrops.add( - e.getKey() - .get(size)); + ItemStack stack = dropstacks.get(e.getKey()) + .copy(); + stack.stackSize = size; + currentDrops.add(stack); v -= size; e.setValue(v); } @@ -1318,7 +1091,7 @@ public class GT_MetaTileEntity_MegaIndustrialApiary private static final float MAX_PRODUCTION_MODIFIER_FROM_UPGRADES = 17.19926784f; // 4*1.2^8 final ItemStack stack; double amount; - final GT_Utility.ItemId id; + final ItemID id; final float chance; final float beeSpeed; @@ -1329,7 +1102,7 @@ public class GT_MetaTileEntity_MegaIndustrialApiary this.chance = chance; this.beeSpeed = beeSpeed; this.t = t; - id = GT_Utility.ItemId.createNoCopy(stack); + id = ItemID.createNoCopy(this.stack); evaluate(); } @@ -1365,7 +1138,7 @@ public class GT_MetaTileEntity_MegaIndustrialApiary beeSpeed = tag.getFloat("beeSpeed"); t = tag.getFloat("t"); amount = tag.getDouble("amount"); - id = GT_Utility.ItemId.createNoCopy(stack); + id = ItemID.createNoCopy(stack); } public NBTTagCompound toNBTTagCompound() { diff --git a/src/main/resources/assets/kubatech/lang/en_US.lang b/src/main/resources/assets/kubatech/lang/en_US.lang index 774ab754b4..217d438ce0 100644 --- a/src/main/resources/assets/kubatech/lang/en_US.lang +++ b/src/main/resources/assets/kubatech/lang/en_US.lang @@ -26,6 +26,15 @@ kubatech.command.tea.success_set=Player %s now has %d Tea kubatech.command.tea.success_add=Player %s now has %d Tea kubatech.command.tea.usage=<username> get/set/add (<amount>) +#GUI +GT5U.gui.text.EEC_nospawner=No powered spawner! +GT5U.gui.text.EEC_invalidspawner=Invalid spawner! +GT5U.gui.text.EEC_peaceful=Inserted mob cannot spawn on peaceful mode! +GT5U.gui.text.MegaApiary_slotoverflow=Too much bees inside! +GT5U.gui.text.MegaApiary_noflowers=Missing flowers! +GT5U.gui.text.EIG_slotoverflow=Too much crops inside! +GT5U.gui.text.EIG_missingwater=No water! +GT5U.gui.text.EIG_ic2glass=Insufficient glass tier! #Blocks kubablock.tea_acceptor.name=§4§lTea Acceptor diff --git a/src/main/resources/assets/kubatech/textures/gui/MobHandler.png b/src/main/resources/assets/kubatech/textures/gui/MobHandler.png Binary files differdeleted file mode 100644 index 1cb2a616b3..0000000000 --- a/src/main/resources/assets/kubatech/textures/gui/MobHandler.png +++ /dev/null diff --git a/src/main/resources/assets/kubatech/textures/gui/logo_13x15_dark.png b/src/main/resources/assets/kubatech/textures/gui/logo_13x15_dark.png Binary files differnew file mode 100644 index 0000000000..53f69a0783 --- /dev/null +++ b/src/main/resources/assets/kubatech/textures/gui/logo_13x15_dark.png diff --git a/src/main/resources/assets/kubatech/textures/gui/slot/gray_spawner.png b/src/main/resources/assets/kubatech/textures/gui/slot/gray_spawner.png Binary files differnew file mode 100644 index 0000000000..dc7d3ab49d --- /dev/null +++ b/src/main/resources/assets/kubatech/textures/gui/slot/gray_spawner.png diff --git a/src/main/resources/assets/kubatech/textures/gui/slot/gray_sword.png b/src/main/resources/assets/kubatech/textures/gui/slot/gray_sword.png Binary files differnew file mode 100644 index 0000000000..3e3065c86c --- /dev/null +++ b/src/main/resources/assets/kubatech/textures/gui/slot/gray_sword.png |