/*
* Copyright (C) 2022 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
* NotEnoughUpdates is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* NotEnoughUpdates is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with NotEnoughUpdates. If not, see .
*/
package io.github.moulberry.notenoughupdates.miscgui;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.ButtonExclusionZoneEvent;
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent;
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.Rectangle;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@NEUAutoSubscribe
public class TrophyRewardOverlay {
private static TrophyRewardOverlay instance = null;
private final Map data = new HashMap<>();
private boolean reloadNeeded = true;
public static final ResourceLocation trophyProfitImage =
new ResourceLocation("notenoughupdates:trophy_profit.png");
public static TrophyRewardOverlay getInstance() {
if (instance == null) {
instance = new TrophyRewardOverlay();
}
return instance;
}
/**
* This adds support for the /neureloadrepo command
*/
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onRepoReload(RepositoryReloadEvent event) {
reloadNeeded = true;
}
@SubscribeEvent(priority = EventPriority.LOW)
public void onItemTooltipLow(ItemTooltipEvent event) {
if (!inTrophyFishingInventory()) return;
if (!NotEnoughUpdates.INSTANCE.config.fishing.trophyRewardTooltips) return;
ItemStack itemStack = event.itemStack;
if (itemStack == null) return;
if (!"§aFillet Trophy Fish".equals(itemStack.getDisplayName())) return;
if (ItemUtils.getLore(itemStack).contains("§8Sacks")) return;
event.toolTip.add(2, getToolTip());
event.toolTip.add(2, "");
}
private String getToolTip() {
List line = createText();
if (line.size() == 1) {
return line.get(0);
}
return line.get(1);
}
@SubscribeEvent
public void onButtonExclusionZones(ButtonExclusionZoneEvent event) {
if (inTrophyFishingInventory() && NotEnoughUpdates.INSTANCE.config.fishing.trophyRewardOverlay) {
event.blockArea(
new Rectangle(
event.getGuiBaseRect().getRight(),
event.getGuiBaseRect().getTop(),
158 /*width*/ + 7 /*space*/,
128
),
ButtonExclusionZoneEvent.PushDirection.TOWARDS_RIGHT
);
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onDrawBackground(GuiScreenEvent.BackgroundDrawnEvent event) {
if (!inTrophyFishingInventory()) return;
if (!NotEnoughUpdates.INSTANCE.config.fishing.trophyRewardOverlay) return;
GuiScreen screen = Minecraft.getMinecraft().currentScreen;
if (!(screen instanceof GuiChest)) return;
Gui gui = event.gui;
int xSize = ((AccessorGuiContainer) gui).getXSize();
int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
List list = createText();
int removed = 0;
if (list.size() > 11) {
while (list.size() > 10) {
removed++;
list.remove(9);
}
list.add("§8And " + removed + " more..");
}
renderBasicOverlay(event, guiLeft + xSize + 3, guiTop, list);
}
private void load() {
data.clear();
JsonObject jsonObject = Constants.TROPHYFISH;
if (jsonObject == null) {
return;
}
String[] tiers = new String[]{"_BRONZE", "_SILVER", "_GOLD", "_DIAMOND"};
for (Map.Entry entry : jsonObject.entrySet()) {
String name = entry.getKey();
int i = 0;
for (JsonElement element : entry.getValue().getAsJsonArray()) {
int price = element.getAsInt();
data.put(name + tiers[i], price);
i++;
}
}
}
private List createText() {
if (reloadNeeded) {
load();
reloadNeeded = false;
}
List texts = new ArrayList<>();
if (data.isEmpty()) {
texts.add("§cNo data in Repo found!");
return texts;
}
Map totalAmount = new HashMap<>();
Map totalExchange = new HashMap<>();
readInventory(totalAmount, totalExchange);
int total = totalExchange.values().stream().mapToInt(value -> value).sum();
texts.add("Trophy Fish Exchange");
texts.add("Magma Fish: §e" + total);
for (Map.Entry entry : sortByValueReverse(totalExchange).entrySet()) {
String name = entry.getKey();
int amount = totalAmount.get(name);
String[] split = name.split(" ");
String rarity = split[split.length - 1];
name = name.substring(0, name.length() - rarity.length() - 1);
if (name.length() > 20) {
name = name.substring(0, 18) + "..";
}
String rarityColor = rarity.replace("§l", "").substring(0, 2);
texts.add(String.format("%s%dx §r%s§f: §e%d", rarityColor, amount, name, entry.getValue()));
}
return texts;
}
private void readInventory(Map totalAmount, Map totalExchange) {
if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) {
for (Slot slot : Minecraft.getMinecraft().thePlayer.openContainer.inventorySlots) {
if (!slot.getHasStack()) continue;
ItemStack stack = slot.getStack();
if (stack != null) {
String internalId = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack);
if (data.containsKey(internalId)) {
String displayName = stack.getDisplayName();
int stackSize = stack.stackSize;
int amount = totalAmount.getOrDefault(displayName, 0) + stackSize;
totalAmount.put(displayName, amount);
int exchangeRate = data.get(internalId);
int exchangeValue = totalExchange.getOrDefault(displayName, 0) + exchangeRate * stackSize;
totalExchange.put(displayName, exchangeValue);
}
}
}
}
}
//TODO move into utils class maybe?
public static > Map sortByValue(Map map) {
List> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());
Map result = new LinkedHashMap<>();
for (Map.Entry entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
//TODO move into utils class maybe?
public static > Map sortByValueReverse(Map map) {
List> list = new ArrayList<>(map.entrySet());
list.sort(Map.Entry.comparingByValue());
Collections.reverse(list);
Map result = new LinkedHashMap<>();
for (Map.Entry entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
private void renderBasicOverlay(
GuiScreenEvent.BackgroundDrawnEvent event,
int x,
int y,
List texts
) {
Gui gui = event.gui;
int xSize = ((AccessorGuiContainer) gui).getXSize();
int guiLeft = ((AccessorGuiContainer) gui).getGuiLeft();
int guiTop = ((AccessorGuiContainer) gui).getGuiTop();
Minecraft minecraft = Minecraft.getMinecraft();
minecraft.getTextureManager().bindTexture(trophyProfitImage);
GL11.glColor4f(1, 1, 1, 1);
GlStateManager.disableLighting();
Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 158, 128, 0, 1, 0, 1, GL11.GL_NEAREST);
int a = guiLeft + xSize + 4;
FontRenderer fontRendererObj = minecraft.fontRendererObj;
//Render first two header lines
int i = 0;
for (String text : texts) {
fontRendererObj.drawString("§8" + text, a + 10, guiTop + 6 + i, -1, false);
i += 10;
if (i == 20) break;
}
//Render all other lines
i = 25;
int index = 0;
for (String text : texts) {
if (index > 1) {
fontRendererObj.drawString(text, a + 10, guiTop + 6 + i, -1, false);
i += 10;
} else {
index++;
}
}
}
public static boolean inTrophyFishingInventory() {
if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return false;
Minecraft minecraft = Minecraft.getMinecraft();
if (minecraft == null || minecraft.thePlayer == null) return false;
Container inventoryContainer = minecraft.thePlayer.openContainer;
if (!(inventoryContainer instanceof ContainerChest)) return false;
ContainerChest containerChest = (ContainerChest) inventoryContainer;
return containerChest.getLowerChestInventory().getDisplayName()
.getUnformattedText().equalsIgnoreCase("Trophy Fishing");
}
}