aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt83
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java42
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java63
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/BazaarTweaks.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Enchanting.java9
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java3
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/events/IsSlotBeingHoveredEvent.kt46
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/BazaarPriceWarning.kt91
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/HexPriceWarning.kt93
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WarningPopUp.kt163
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/ScreenReplacer.kt40
14 files changed, 595 insertions, 70 deletions
diff --git a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
index 2fae6ceb..d2a25380 100644
--- a/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
+++ b/annotations/src/main/kotlin/io/github/moulberry/notenoughupdates/autosubscribe/NEUAutoSymbolProcessor.kt
@@ -29,11 +29,8 @@ import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.validate
-import com.squareup.kotlinpoet.FileSpec
-import com.squareup.kotlinpoet.FunSpec
+import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
-import com.squareup.kotlinpoet.TypeSpec
-import com.squareup.kotlinpoet.asTypeName
import com.squareup.kotlinpoet.ksp.toClassName
import com.squareup.kotlinpoet.ksp.writeTo
import java.util.function.Consumer
@@ -65,7 +62,9 @@ internal class NEUAutoSymbolProcessor(val codeGenerator: CodeGenerator, val logg
}
if (instanceGetter != null) {
val returnType = instanceGetter.returnType
- if (returnType == null || !element.asStarProjectedType().isAssignableFrom(returnType.resolve())) {
+ if (returnType == null || !element.asStarProjectedType()
+ .isAssignableFrom(returnType.resolve())
+ ) {
logger.error(
"getInstance() does not have the expected return type ${element.asStarProjectedType()}",
instanceGetter
@@ -118,45 +117,59 @@ internal class NEUAutoSymbolProcessor(val codeGenerator: CodeGenerator, val logg
if (subscribers.isEmpty()) return
val deps = subscribers.mapNotNull { it.declaration.containingFile }
logger.info("Dependencies: $deps")
+ val objectBuilder = TypeSpec.objectBuilder("AutoLoad")
FileSpec.builder("io.github.moulberry.notenoughupdates.autosubscribe", "AutoLoad")
.addFileComment("@generated by ${NEUAutoSymbolProcessor::class.simpleName}")
.addType(
- TypeSpec.objectBuilder("AutoLoad")
- .addFunction(
- FunSpec.builder("provide")
- .addParameter(
- "consumer",
- Consumer::class.asTypeName()
- .parameterizedBy(Supplier::class.parameterizedBy(Any::class))
- )
- .apply {
- subscribers.sortedBy { it.declaration.simpleName.asString() }.forEach { (invocationKind, declaration) ->
+ objectBuilder.addFunction(
+ FunSpec.builder("provide")
+ .addParameter(
+ "consumer",
+ Consumer::class.asTypeName()
+ .parameterizedBy(Supplier::class.parameterizedBy(Any::class))
+ )
+ .apply {
+ var instanceCounter = 0
+ subscribers.sortedBy { it.declaration.simpleName.asString() }
+ .forEach { (invocationKind, declaration) ->
when (invocationKind) {
- InvocationKind.GET_INSTANCE -> addStatement(
- "consumer.accept { %T.getInstance() }",
- declaration.toClassName()
- )
+ InvocationKind.GET_INSTANCE -> {
+ addStatement(
+ "consumer.accept { %T.getInstance() }",
+ declaration.toClassName()
+ )
+ }
- InvocationKind.OBJECT_INSTANCE -> addStatement(
- "consumer.accept { %T }",
- declaration.toClassName()
- )
+ InvocationKind.OBJECT_INSTANCE -> {
+ addStatement(
+ "consumer.accept { %T }",
+ declaration.toClassName()
+ )
+ }
- InvocationKind.DEFAULT_CONSTRUCTOR -> addStatement(
- "consumer.accept { %T() }",
- declaration.toClassName()
- )
+ InvocationKind.DEFAULT_CONSTRUCTOR -> {
+ val name = "instance_${instanceCounter++}"
+ objectBuilder.addProperty(
+ PropertySpec.builder(name, declaration.toClassName())
+ .delegate("lazy { %T() }", declaration.toClassName())
+ .build()
+ )
+ addStatement(
+ "consumer.accept { $name }",
+ )
+ }
- InvocationKind.ACCESS_INSTANCE -> addStatement(
- "consumer.accept { %T.INSTANCE }",
- declaration.toClassName()
- )
+ InvocationKind.ACCESS_INSTANCE -> {
+ addStatement(
+ "consumer.accept { %T.INSTANCE }",
+ declaration.toClassName()
+ )
+ }
}
}
- }
- .build()
- )
- .build()
+ }
+ .build()
+ ).build()
)
.build()
.writeTo(codeGenerator, aggregating = true, originatingKSFiles = deps)
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java b/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java
index 13c31b54..d8d3615d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/events/SlotClickEvent.java
@@ -22,11 +22,12 @@ package io.github.moulberry.notenoughupdates.events;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
+import org.jetbrains.annotations.NotNull;
@Cancelable
public class SlotClickEvent extends NEUEvent {
- public final GuiContainer guiContainer;
- public final Slot slot;
+ public final @NotNull GuiContainer guiContainer;
+ public final @NotNull Slot slot;
public final int slotId;
public int clickedButton;
public int clickType;
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
index 82c9b3b6..bd923157 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/RenderListener.java
@@ -31,6 +31,7 @@ import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers;
import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver;
import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers;
+import io.github.moulberry.notenoughupdates.miscfeatures.HexPriceWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.PresetWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager;
import io.github.moulberry.notenoughupdates.miscfeatures.dev.RepoExporters;
@@ -54,6 +55,7 @@ import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.NotificationHandler;
import io.github.moulberry.notenoughupdates.util.Rectangle;
import io.github.moulberry.notenoughupdates.util.SBInfo;
+import io.github.moulberry.notenoughupdates.util.ScreenReplacer;
import io.github.moulberry.notenoughupdates.util.Utils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
@@ -402,6 +404,8 @@ public class RenderListener {
if (GuiCustomHex.getInstance().shouldOverride(containerName)) {
GuiCustomHex.getInstance().render(event.renderPartialTicks, containerName);
+ if (HexPriceWarning.INSTANCE.shouldShow())
+ HexPriceWarning.INSTANCE.render();
event.setCanceled(true);
return;
}
@@ -594,6 +598,12 @@ public class RenderListener {
}
if (!hoveringButton[0]) buttonHovered = null;
+ for (ScreenReplacer allScreenReplacer : ScreenReplacer.Companion.getAllScreenReplacers()) {
+ if (allScreenReplacer.shouldShow()) {
+ allScreenReplacer.render();
+ }
+ }
+
if (AuctionBINWarning.getInstance().shouldShow()) {
AuctionBINWarning.getInstance().render();
}
@@ -768,7 +778,8 @@ public class RenderListener {
}
}
JsonObject kismetBazaar = neu.manager.auctionManager.getBazaarInfo("KISMET_FEATHER");
- double kismetPrice = (kismetBazaar != null && kismetBazaar.has("curr_buy")) ? kismetBazaar.get("curr_buy").getAsFloat() : 0;
+ double kismetPrice =
+ (kismetBazaar != null && kismetBazaar.has("curr_buy")) ? kismetBazaar.get("curr_buy").getAsFloat() : 0;
String kismetStr = EnumChatFormatting.RED + formatCoins(kismetPrice) + " coins";
if (neu.config.dungeons.useKismetOnDungeonProfit)
profitLossBIN = kismetUsed ? profitLossBIN - kismetPrice : profitLossBIN;
@@ -872,6 +883,14 @@ public class RenderListener {
int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth;
int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1;
+ for (ScreenReplacer allScreenReplacer : ScreenReplacer.Companion.getAllScreenReplacers()) {
+ if (allScreenReplacer.shouldShow()) {
+ allScreenReplacer.mouseInput(mouseX, mouseY);
+ event.setCanceled(true);
+ return;
+ }
+ }
+
if (AuctionBINWarning.getInstance().shouldShow()) {
AuctionBINWarning.getInstance().mouseInput(mouseX, mouseY);
event.setCanceled(true);
@@ -1038,6 +1057,14 @@ public class RenderListener {
return;
}
+ for (ScreenReplacer allScreenReplacer : ScreenReplacer.Companion.getAllScreenReplacers()) {
+ if (allScreenReplacer.shouldShow()) {
+ allScreenReplacer.keyboardInput();
+ event.setCanceled(true);
+ return;
+ }
+ }
+
if (AuctionBINWarning.getInstance().shouldShow()) {
AuctionBINWarning.getInstance().keyboardInput();
event.setCanceled(true);
@@ -1093,12 +1120,12 @@ public class RenderListener {
}
if (tradeWindowActive) {
- TradeWindow.keyboardInput();
- if (Keyboard.getEventKey() != Keyboard.KEY_ESCAPE) {
- event.setCanceled(true);
- Minecraft.getMinecraft().dispatchKeypresses();
- neu.overlay.keyboardInput(focusInv);
- }
+ TradeWindow.keyboardInput();
+ if (Keyboard.getEventKey() != Keyboard.KEY_ESCAPE) {
+ event.setCanceled(true);
+ Minecraft.getMinecraft().dispatchKeypresses();
+ neu.overlay.keyboardInput(focusInv);
+ }
return;
}
@@ -1220,6 +1247,7 @@ public class RenderListener {
/**
* Support for switching between different pages in the RecipeView gui via right and left arrow key
+ *
* @param event
*/
//Because GuiScreen.keyTyped does not fire the KEY_LEFT and KEY_RIGHT keys. Maybe some event cancelled it?
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java
index a3af232f..1da81605 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/hex/GuiCustomHex.java
@@ -28,6 +28,8 @@ import io.github.moulberry.notenoughupdates.core.GuiElementTextField;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingFloat;
import io.github.moulberry.notenoughupdates.core.util.lerp.LerpingInteger;
+import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
+import io.github.moulberry.notenoughupdates.miscfeatures.HexPriceWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay;
import io.github.moulberry.notenoughupdates.miscgui.util.OrbDisplay;
@@ -36,6 +38,7 @@ import io.github.moulberry.notenoughupdates.options.NEUConfig;
import io.github.moulberry.notenoughupdates.util.Constants;
import io.github.moulberry.notenoughupdates.util.ItemUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
+import lombok.var;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.FontRenderer;
@@ -3377,7 +3380,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -3389,7 +3392,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(click);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, click, 0, 0, stack, transactionID));
}
return true;
@@ -3414,7 +3417,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
if (isInGemstones()) {
currentState = EnchantState.HAS_ITEM_IN_GEMSTONE;
@@ -3457,7 +3460,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -3473,7 +3476,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(
enchanterCurrentEnch.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
enchanterCurrentEnch.slotIndex, 0, 0, stack, transactionID
));
@@ -3556,7 +3559,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));*/
cancelButtonAnimTime = System.currentTimeMillis();
@@ -3574,7 +3577,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(
enchanterCurrentItem.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID
));
@@ -3656,7 +3659,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -3674,7 +3677,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(
enchanterCurrentItem.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID
));
@@ -3757,7 +3760,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -3779,7 +3782,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(
enchanterCurrentItem.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
enchanterCurrentItem.slotIndex, 0, 0, stack, transactionID
));
@@ -3993,7 +3996,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
ench.slotIndex, 0, 0, stack, transactionID
));
@@ -4001,7 +4004,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -4032,7 +4035,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4064,7 +4067,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4096,7 +4099,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4129,7 +4132,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4166,7 +4169,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(ench.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
ench.slotIndex, 0, 0, stack, transactionID
));
@@ -4174,7 +4177,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -4205,7 +4208,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4242,7 +4245,7 @@ public class GuiCustomHex extends Gui {
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack =
((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(item.slotIndex);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId,
item.slotIndex, 0, 0, stack, transactionID
));
@@ -4299,7 +4302,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -4320,7 +4323,7 @@ public class GuiCustomHex extends Gui {
EntityPlayerSP playerIn = Minecraft.getMinecraft().thePlayer;
short transactionID = playerIn.openContainer.getNextTransactionID(playerIn.inventory);
ItemStack stack = ((ContainerChest) chest.inventorySlots).getLowerChestInventory().getStackInSlot(45);
- Minecraft.getMinecraft().getNetHandler().addToSendQueue(new C0EPacketClickWindow(
+ onClick(new C0EPacketClickWindow(
chest.inventorySlots.windowId, 45, 0, 0, stack, transactionID));
cancelButtonAnimTime = System.currentTimeMillis();
@@ -4333,6 +4336,20 @@ public class GuiCustomHex extends Gui {
return true;
}
+ public void onClick(C0EPacketClickWindow packet) {
+ var cont = Minecraft.getMinecraft().thePlayer.openContainer;
+ var clickEvent = new SlotClickEvent(
+ (GuiContainer) Minecraft.getMinecraft().currentScreen,
+ cont.getSlot(packet.getSlotId()),
+ packet.getSlotId(),
+ packet.getUsedButton(),
+ packet.getMode()
+ );
+ HexPriceWarning.INSTANCE.onClick(clickEvent);
+ if (!clickEvent.isCanceled())
+ Minecraft.getMinecraft().getNetHandler().addToSendQueue(packet);
+ }
+
public boolean keyboardInput() {
if (currentState == EnchantState.HAS_ITEM && searchField.getFocus()) {
if (Keyboard.getEventKeyState()) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
index 41ae6e66..ebc362ac 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinGuiContainer.java
@@ -23,6 +23,7 @@ import io.github.moulberry.notenoughupdates.NEUOverlay;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.events.DrawSlotReturnEvent;
import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent;
+import io.github.moulberry.notenoughupdates.events.IsSlotBeingHoveredEvent;
import io.github.moulberry.notenoughupdates.events.SlotClickEvent;
import io.github.moulberry.notenoughupdates.listener.RenderListener;
import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneFavourites;
@@ -37,6 +38,7 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant;
import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay;
import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex;
import io.github.moulberry.notenoughupdates.util.Utils;
+import lombok.var;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiScreen;
@@ -53,6 +55,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
+import net.minecraftforge.common.MinecraftForge;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -203,6 +206,18 @@ public abstract class MixinGuiContainer extends GuiScreen {
GuiCustomHex.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir);
AuctionBINWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir);
PresetWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir);
+ var event = new IsSlotBeingHoveredEvent();
+ MinecraftForge.EVENT_BUS.post(event);
+ switch (event.getOverride()) {
+ case DEFER_TO_DEFAULT:
+ break;
+ case IS_HOVERED:
+ cir.setReturnValue(true);
+ break;
+ case IS_NOT_HOVERED:
+ cir.setReturnValue(false);
+ break;
+ }
}
@Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/inventory/GuiContainer;drawGradientRect(IIIIII)V"))
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/BazaarTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/BazaarTweaks.java
index 254d0c2e..f29cc97c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/BazaarTweaks.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/BazaarTweaks.java
@@ -23,6 +23,7 @@ import com.google.gson.annotations.Expose;
import io.github.moulberry.moulconfig.annotations.ConfigAccordionId;
import io.github.moulberry.moulconfig.annotations.ConfigEditorAccordion;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
import io.github.moulberry.moulconfig.annotations.ConfigOption;
public class BazaarTweaks {
@@ -70,4 +71,12 @@ public class BazaarTweaks {
@ConfigEditorBoolean
@ConfigAccordionId(id = 0)
public boolean escFullClose = true;
+
+ @Expose
+ @ConfigOption(
+ name = "Bazaar Overpay Warning",
+ desc = "Warns you before you would pay more than this amount of coins for an item in the /bz"
+ )
+ @ConfigEditorSlider(minValue = 0, maxValue = 500_000_000, minStep = 1)
+ public double bazaarOverpayWarning = 1_000_000;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Enchanting.java b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Enchanting.java
index b7c45c0c..a692586d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Enchanting.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/separatesections/Enchanting.java
@@ -24,6 +24,7 @@ import io.github.moulberry.moulconfig.annotations.ConfigAccordionId;
import io.github.moulberry.moulconfig.annotations.ConfigEditorAccordion;
import io.github.moulberry.moulconfig.annotations.ConfigEditorBoolean;
import io.github.moulberry.moulconfig.annotations.ConfigEditorDropdown;
+import io.github.moulberry.moulconfig.annotations.ConfigEditorSlider;
import io.github.moulberry.moulconfig.annotations.ConfigOption;
public class Enchanting {
@@ -239,4 +240,12 @@ public class Enchanting {
)
@ConfigAccordionId(id = 0)
public int supPower = 11;
+
+ @Expose
+ @ConfigOption(
+ name = "Hex Overpay Warning",
+ desc = "Warns you before you would pay more than this amount of coins for an item in the /hex"
+ )
+ @ConfigEditorSlider(minValue = 0, maxValue = 500_000_000, minStep = 1)
+ public double hexOverpayWarning = 10_000_000;
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
index eb6a5696..cc974841 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -158,8 +158,7 @@ public class ItemUtils {
}
public static @Nullable String getDisplayName(@Nullable ItemStack itemStack) {
- if (itemStack == null)
- return null;
+ if (null == itemStack) return null;
return getDisplayName(itemStack.getTagCompound());
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
index 2878406e..6b597ebe 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -66,6 +66,7 @@ import net.minecraft.util.Matrix4f;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraftforge.fml.common.Loader;
+import org.jetbrains.annotations.NotNull;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
@@ -2316,7 +2317,7 @@ public class Utils {
return new UUID(most.longValue(), least.longValue());
}
- public static String getOpenChestName() {
+ public static @NotNull String getOpenChestName() {
return SBInfo.getInstance().currentlyOpenChestName;
}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/events/IsSlotBeingHoveredEvent.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/events/IsSlotBeingHoveredEvent.kt
new file mode 100644
index 00000000..512752b0
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/events/IsSlotBeingHoveredEvent.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.events
+
+import net.minecraftforge.fml.common.eventhandler.Event
+
+
+class IsSlotBeingHoveredEvent : Event() {
+
+ var override = Override.DEFER_TO_DEFAULT
+
+ fun prevent(override: Override = Override.IS_NOT_HOVERED) {
+ this.override = override.or(this.override)
+ }
+
+ enum class Override {
+ DEFER_TO_DEFAULT,
+ IS_HOVERED,
+ IS_NOT_HOVERED, ;
+
+ fun or(override: Override): Override {
+ if (override == DEFER_TO_DEFAULT)
+ return this
+ return override
+ }
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/BazaarPriceWarning.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/BazaarPriceWarning.kt
new file mode 100644
index 00000000..d198100a
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/BazaarPriceWarning.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.events.SlotClickEvent
+import io.github.moulberry.notenoughupdates.util.ItemUtils
+import io.github.moulberry.notenoughupdates.util.Utils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraft.inventory.Slot
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+@NEUAutoSubscribe
+class BazaarPriceWarning : WarningPopUp() {
+ override fun shouldShow(): Boolean {
+ val openSlots = Minecraft.getMinecraft().thePlayer?.openContainer?.inventorySlots ?: return false
+ return super.shouldShow() && openSlots.contains(clickedSlot ?: return false)
+ }
+
+ var clickedSlot: Slot? = null
+ val priceRegx = "§7Price: §6([0-9.,]+) coins".toPattern()
+ var price = 0.0
+
+ val limit get() = NotEnoughUpdates.INSTANCE.config.bazaarTweaks.bazaarOverpayWarning
+ @SubscribeEvent
+ fun onClick(event: SlotClickEvent) {
+ if (!Utils.getOpenChestName().contains("Instant Buy"))
+ return
+ if (shouldShow()) return
+ val stack = event.slot.stack ?: return
+ val lore = ItemUtils.getLore(stack)
+ if (lore.lastOrNull() != "§7§eClick to buy now!") return
+ val priceMatch = lore.firstNotNullOfOrNull { priceRegx.matcher(it).takeIf { it.matches() } } ?: return
+ val price = priceMatch.group(1).replace(",", "").toDouble()
+
+ if (price <= limit || limit < 1)
+ return
+
+ this.price = price
+ clickedSlot = event.slot
+ show()
+ event.cancel()
+ }
+
+ fun getLore(): List<String> {
+ return clickedSlot?.stack?.let(ItemUtils::getLore) ?: listOf()
+ }
+
+ override fun getItemName(): String {
+ return getLore().firstOrNull() ?: "<unknown>"
+ }
+
+ override fun getWarningLines(): List<String> {
+ return listOf("will cost you §6${price}§r coins")
+ }
+
+ override fun getWarningPopup(): List<String> {
+ val displayName = clickedSlot?.stack?.let(ItemUtils::getDisplayName)
+ val tooltip = getLore().toMutableList()
+ if (displayName != null)
+ tooltip.add(0, displayName)
+ return tooltip
+ }
+
+ override fun confirmClick() {
+ val chest = Minecraft.getMinecraft().currentScreen as GuiChest
+ Minecraft.getMinecraft().playerController.windowClick(
+ chest.inventorySlots.windowId,
+ clickedSlot?.slotNumber ?: return, 0, 0, Minecraft.getMinecraft().thePlayer
+ )
+ }
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/HexPriceWarning.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/HexPriceWarning.kt
new file mode 100644
index 00000000..ff90f1c9
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/HexPriceWarning.kt
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.events.SlotClickEvent
+import io.github.moulberry.notenoughupdates.util.ItemUtils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.inventory.GuiChest
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+
+/*
+ We are gathered here today to mourn the death of 26m coins that Alea spent on a Cleave 6 book, while trying to take
+ off Cleave 5.
+ */
+@NEUAutoSubscribe
+object HexPriceWarning : WarningPopUp() {
+
+ fun shouldCheck(): Boolean {
+ return getLimit() >= 1
+ }
+
+ fun getLimit(): Double {
+ return NotEnoughUpdates.INSTANCE.config.enchantingSolvers.hexOverpayWarning;
+ }
+
+ var lastClickedSlot = 0
+ var cost = ""
+ var upgradeName = ""
+ override fun shouldShow(): Boolean {
+ return shouldCheck() && super.shouldShow()
+ }
+
+ override fun getItemName(): String {
+ return upgradeName
+ }
+
+ override fun getWarningLines(): List<String> {
+ return listOf("will cost you §6$cost§r coins")
+ }
+
+ override fun confirmClick() {
+ val chest = Minecraft.getMinecraft().currentScreen as GuiChest
+ Minecraft.getMinecraft().playerController.windowClick(
+ chest.inventorySlots.windowId,
+ lastClickedSlot, 0, 0, Minecraft.getMinecraft().thePlayer
+ )
+ }
+
+ @SubscribeEvent
+ fun onClick(event: SlotClickEvent) {
+ if (!shouldCheck()) return
+ if (isShowing) return
+ val stack = event.slot.stack ?: return
+ val lore = ItemUtils.getLore(stack)
+ val bazaarPriceLine = lore.indexOf("§7Bazaar Price")
+ if (bazaarPriceLine >= 0 &&
+ (bazaarPriceLine + 1) in lore.indices
+ ) {
+ val priceLine = lore[bazaarPriceLine + 1]
+ val priceMatcher = coins.matcher(priceLine)
+ if (!priceMatcher.matches()) return
+ val price = priceMatcher.group(1).replace(",", "").toDouble()
+ if (price >= getLimit()) {
+ lastClickedSlot = event.slotId
+ cost = priceMatcher.group(1)
+ upgradeName = ItemUtils.getDisplayName(stack.tagCompound) ?: "<unnamed upgrade>"
+ show()
+ event.cancel()
+ }
+ }
+ }
+
+ val coins = "§6([,.0-9]+) Coins".toPattern()
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WarningPopUp.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WarningPopUp.kt
new file mode 100644
index 00000000..73e4c462
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/WarningPopUp.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures
+
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils
+import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils
+import io.github.moulberry.notenoughupdates.events.IsSlotBeingHoveredEvent
+import io.github.moulberry.notenoughupdates.util.ScreenReplacer
+import io.github.moulberry.notenoughupdates.util.Utils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.ScaledResolution
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.util.EnumChatFormatting
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import org.lwjgl.input.Keyboard
+import org.lwjgl.input.Mouse
+
+abstract class WarningPopUp : ScreenReplacer() {
+
+ var isShowing = false
+ private set
+ fun show() {
+ isShowing = true
+ }
+
+ override fun shouldShow(): Boolean {
+ return isShowing
+ }
+
+ open fun getWarningPopup(): List<String>? = null
+
+ abstract fun getItemName(): String
+
+ abstract fun getWarningLines(): List<String>
+
+ override fun render() {
+ val scaledResolution = ScaledResolution(Minecraft.getMinecraft())
+ val width = scaledResolution.scaledWidth
+ val height = scaledResolution.scaledHeight
+
+ GlStateManager.disableLighting()
+
+ GlStateManager.pushMatrix()
+ GlStateManager.translate(0f, 0f, 500f)
+
+ drawRect(0, 0, width, height, -0x80000000)
+
+ RenderUtils.drawFloatingRectDark(width / 2 - 90, height / 2 - 45, 180, 90)
+
+ val neuLength = Minecraft.getMinecraft().fontRendererObj.getStringWidth("\u00a7lNEU")
+ Minecraft.getMinecraft().fontRendererObj.drawString(
+ "\u00a7lNEU",
+ width / 2 + 90 - neuLength - 3,
+ height / 2 - 45 + 4,
+ -0x1000000
+ )
+
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ "Are you SURE?",
+ (width / 2).toFloat(), (height / 2 - 45 + 10).toFloat(), false, 170, -0xbfc0
+ )
+
+
+ val itemNameLine = "\u00a77[ §r${getItemName()}\u00a77 ]"
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ itemNameLine,
+ (width / 2).toFloat(), (height / 2 - 45 + 25).toFloat(), false, 170, -0x1
+ )
+ for ((index, line) in getWarningLines().withIndex()) {
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ line,
+ (width / 2).toFloat(), (height / 2 - 45 + 34 + 10 * index).toFloat(),
+ false, 170, -0x5f5f60
+ )
+ }
+
+
+ RenderUtils.drawFloatingRectDark(width / 2 - 43, height / 2 + 23, 40, 16, false)
+ RenderUtils.drawFloatingRectDark(width / 2 + 3, height / 2 + 23, 40, 16, false)
+
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ EnumChatFormatting.GREEN.toString() + "[Y]es",
+ (width / 2 - 23).toFloat(), (height / 2 + 31).toFloat(), true, 36, -0xff0100
+ )
+ TextRenderUtils.drawStringCenteredScaledMaxWidth(
+ EnumChatFormatting.RED.toString() + "[N]o",
+ (width / 2 + 23).toFloat(), (height / 2 + 31).toFloat(), true, 36, -0x10000
+ )
+
+ getWarningPopup()?.let { tooltip ->
+ val mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth
+ val mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1
+
+ val itemNameLength = Minecraft.getMinecraft().fontRendererObj.getStringWidth(itemNameLine)
+
+ if (mouseX >= width / 2 - itemNameLength / 2 && mouseX <= width / 2 + itemNameLength / 2 && mouseY >= height / 2 - 45 + 20 && mouseY <= height / 2 - 45 + 30) {
+ Utils.drawHoveringText(tooltip, mouseX, mouseY, width, height, -1)
+ }
+ }
+
+ GlStateManager.popMatrix()
+ }
+
+ abstract fun confirmClick()
+
+ override fun mouseInput(mouseX: Int, mouseY: Int): Boolean {
+ val scaledResolution = ScaledResolution(Minecraft.getMinecraft())
+ val width = scaledResolution.scaledWidth
+ val height = scaledResolution.scaledHeight
+
+ if (Mouse.getEventButtonState()) {
+ // Yes and No button
+ if ((mouseX >= width / 2 - 43 && mouseX <= width / 2 - 43 + 40) && (mouseY >= height / 2 + 23 && mouseY <= height / 2 + 23 + 16)) {
+ confirmClick()
+ isShowing = false
+ } else if ((mouseX >= width / 2 + 3 && mouseX <= width / 2 + 3 + 40) && (mouseY >= height / 2 + 23 && mouseY <= height / 2 + 23 + 16)) {
+ isShowing = false
+ }
+
+ // click outside the popup
+ if (mouseX < width / 2 - 90 || mouseX > width / 2 + 90 || mouseY < height / 2 - 45 || mouseY > height / 2 + 45) {
+ isShowing = false
+ }
+ }
+ return false
+ }
+
+ @SubscribeEvent
+ fun onHover(event: IsSlotBeingHoveredEvent) {
+ if (shouldShow()) {
+ event.prevent()
+ }
+ }
+
+ override fun keyboardInput(): Boolean {
+ if (!Keyboard.getEventKeyState()) {
+ if (Keyboard.getEventKey() == Keyboard.KEY_Y || Keyboard.getEventKey() == Keyboard.KEY_RETURN) {
+ confirmClick()
+ }
+ isShowing = false
+ return true
+ }
+
+ return false
+ }
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/ScreenReplacer.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/ScreenReplacer.kt
new file mode 100644
index 00000000..d0d6acb4
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/ScreenReplacer.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util
+
+import io.github.moulberry.notenoughupdates.autosubscribe.AutoLoad
+import io.github.moulberry.notenoughupdates.core.GuiElement
+
+abstract class ScreenReplacer : GuiElement() {
+ abstract fun shouldShow(): Boolean
+
+ companion object {
+ val allScreenReplacers by lazy {
+ buildList {
+ AutoLoad.provide {
+ val replacer = it.get()
+ if (replacer is ScreenReplacer) {
+ add(replacer)
+ }
+ }
+ }
+ }
+ }
+}