aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVixid <52578495+VixidDev@users.noreply.github.com>2023-03-11 23:51:41 +0000
committerGitHub <noreply@github.com>2023-03-12 10:51:41 +1100
commit5f147d6adbe9898239a0cb86e4daaa74c9e4c08a (patch)
treedb16c1b2499e8268ebad7015436ae582c0f130d9
parenta5433dc40dee8517fc0bd8105ae10e0f29778c40 (diff)
downloadNotEnoughUpdates-5f147d6adbe9898239a0cb86e4daaa74c9e4c08a.tar.gz
NotEnoughUpdates-5f147d6adbe9898239a0cb86e4daaa74c9e4c08a.tar.bz2
NotEnoughUpdates-5f147d6adbe9898239a0cb86e4daaa74c9e4c08a.zip
Dynamic Light Items (#646)
Co-authored-by: Vixid <52578495+Vixid1@users.noreply.github.com>
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/envcheck/NEUMixinConfigPlugin.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinOFDynamicLights.java40
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java4
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/MiscCommands.kt6
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscgui/DynamicLightItemsEditor.kt255
-rw-r--r--src/main/resources/assets/notenoughupdates/disabled_button.pngbin0 -> 161 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/dynamic_light_items_editor.pngbin0 -> 439 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/enabled_button.pngbin0 -> 158 bytes
-rw-r--r--src/main/resources/mixins.notenoughupdates.json1
9 files changed, 310 insertions, 0 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/envcheck/NEUMixinConfigPlugin.java b/src/main/java/io/github/moulberry/notenoughupdates/envcheck/NEUMixinConfigPlugin.java
index 44e24ff4..1d12813c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/envcheck/NEUMixinConfigPlugin.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/envcheck/NEUMixinConfigPlugin.java
@@ -1,5 +1,6 @@
package io.github.moulberry.notenoughupdates.envcheck;
+import io.github.moulberry.notenoughupdates.miscgui.DynamicLightItemsEditor;
import org.spongepowered.asm.lib.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@@ -42,5 +43,8 @@ public class NEUMixinConfigPlugin implements IMixinConfigPlugin {
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
+ if ("io.github.moulberry.notenoughupdates.mixins.MixinOFDynamicLights".equals(mixinClassName)) {
+ DynamicLightItemsEditor.setDidApplyMixin(true);
+ }
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinOFDynamicLights.java b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinOFDynamicLights.java
new file mode 100644
index 00000000..68f75d49
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/mixins/MixinOFDynamicLights.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.mixins;
+
+import io.github.moulberry.notenoughupdates.miscgui.DynamicLightItemsEditor;
+import net.minecraft.item.ItemStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Pseudo;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Pseudo
+@Mixin(targets = "net.optifine.DynamicLights", remap = false)
+public class MixinOFDynamicLights {
+
+ @Inject(method = "getLightLevel(Lnet/minecraft/item/ItemStack;)I", at = @At("TAIL"), cancellable = true)
+ private static void getLightLevel(ItemStack itemStack, CallbackInfoReturnable<Integer> cir) {
+ int lightLevel = DynamicLightItemsEditor.findDynamicLightItems(itemStack);
+ if (lightLevel != 0) cir.setReturnValue(lightLevel);
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
index e2a483f7..498b3b0d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java
@@ -82,9 +82,11 @@ import net.minecraftforge.client.ClientCommandHandler;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
public class NEUConfig extends Config {
public void editOverlay() {
@@ -471,6 +473,8 @@ public class NEUConfig extends Config {
public ArrayList<String> quickCommands = createDefaultQuickCommands();
@Expose
public ArrayList<String> enchantColours = createDefaultEnchantColours();
+ @Expose
+ public Set<String> dynamicLightItems = new HashSet<>();
@Expose
public boolean firstTimeSearchFocus = true;
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/MiscCommands.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/MiscCommands.kt
index c86eb4fe..caa57909 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/MiscCommands.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/MiscCommands.kt
@@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.cosmetics.GuiCosmetics
import io.github.moulberry.notenoughupdates.events.RegisterBrigadierCommandEvent
import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay
+import io.github.moulberry.notenoughupdates.miscgui.DynamicLightItemsEditor
import io.github.moulberry.notenoughupdates.miscgui.GuiItemCustomize
import io.github.moulberry.notenoughupdates.util.Calculator
import io.github.moulberry.notenoughupdates.util.Calculator.CalculatorException
@@ -127,6 +128,11 @@ class MiscCommands {
reply("§bTo ensure we do not accidentally corrupt your mod folder, we can only offer support for auto-updates on system with certain capabilities for file deletions (specifically unix systems). You can still manually update your files")
}.withHelp("Display an explanation why you cannot auto update")
}
+ event.command("neudynamiclights", "neudli", "neudynlights", "neudynamicitems") {
+ thenExecute {
+ NotEnoughUpdates.INSTANCE.openGui = DynamicLightItemsEditor()
+ }
+ }.withHelp("Add items to dynamically emit light")
}
fun fetchPronouns(platform: String, user: String) {
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscgui/DynamicLightItemsEditor.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscgui/DynamicLightItemsEditor.kt
new file mode 100644
index 00000000..7cebadcb
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscgui/DynamicLightItemsEditor.kt
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2023 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.miscgui
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.util.Utils
+import net.minecraft.client.Minecraft
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.item.ItemStack
+import net.minecraft.util.ResourceLocation
+import net.minecraftforge.fml.common.registry.GameRegistry
+import org.lwjgl.opengl.GL11
+import java.awt.Color
+import kotlin.math.ceil
+
+class DynamicLightItemsEditor() : GuiScreen() {
+
+ val background = ResourceLocation("notenoughupdates:dynamic_light_items_editor.png")
+ val enabledButton = ResourceLocation("notenoughupdates:enabled_button.png")
+ val disabledButton = ResourceLocation("notenoughupdates:disabled_button.png")
+ val chestGui = ResourceLocation("textures/gui/container/generic_54.png")
+ val widgets = ResourceLocation("textures/gui/widgets.png")
+ val help = ResourceLocation("notenoughupdates:help.png")
+
+ var xSize = 217
+ var ySize = 88
+ var guiLeft = 0
+ var guiTop = 0
+
+ var stackToRender: String? = null
+ var itemSelected: String? = null
+
+ override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) {
+ drawDefaultBackground()
+
+ val numOfItems = NotEnoughUpdates.INSTANCE.config.hidden.dynamicLightItems.size
+ val numOfRows = if (didApplyMixin) ceil(numOfItems / 9f).toInt() else 0
+ ySize = 70 + 18 * numOfRows
+ guiLeft = (width - xSize) / 2
+ guiTop = (height - ySize) / 2
+
+ // Top and bottom half of gui
+ Minecraft.getMinecraft().textureManager.bindTexture(background)
+ Utils.drawTexturedRect(guiLeft.toFloat(), guiTop.toFloat(), xSize.toFloat(), 24F,
+ 0F, 1F, 0F, 24 / 88f, GL11.GL_NEAREST)
+ Utils.drawTexturedRect(guiLeft.toFloat(), (guiTop + ySize - 46).toFloat(), xSize.toFloat(), 46F,
+ 0F, 1F, 42 / 88f, 1F, GL11.GL_NEAREST)
+
+ fontRendererObj.drawString("Dynamic Light Items Editor", guiLeft + 10, guiTop + 7, 4210752)
+
+ GlStateManager.color(1f, 1f, 1f, 1f)
+ Minecraft.getMinecraft().textureManager.bindTexture(help)
+ Utils.drawTexturedRect((guiLeft + xSize + 3).toFloat(), guiTop.toFloat(), 16F, 16F, GL11.GL_NEAREST)
+ if (mouseX >= guiLeft + xSize + 3 &&
+ mouseX <= guiLeft + xSize + 19 &&
+ mouseY >= guiTop &&
+ mouseY <= guiTop + 16) {
+ val tooltip = listOf(
+ "§bDynamic Light Item Editor",
+ "§eWhat is this?",
+ "§eNEU makes use of OptiFine's feature of certain items",
+ "§eemitting dynamic light. By default OptiFine only implements",
+ "§ethis feature for a select few minecraft items.",
+ "",
+ "§eThis editor however, allows you to add specific skyblock",
+ "§eitems that will emit dynamic light when held. Simply hold the",
+ "§eitem you wish to add, then open this menu again and click",
+ "§e'Add Held Item', now if you have OptiFine installed and the",
+ "§edynamic lights option enabled, the added items will emit light!",
+ "",
+ "§eTo remove an item, click the item in this menu and click",
+ "§ethe 'Remove Item' button in the bottom right.",
+ )
+ Utils.drawHoveringText(tooltip, mouseX, mouseY, width, height, -1)
+ }
+
+ if (!didApplyMixin) {
+ fontRendererObj.drawString("Could not find OptiFine!", guiLeft + 50, guiTop + 22, Color.RED.rgb)
+ fontRendererObj.drawString("Go to #neu-support in", guiLeft + 50, guiTop + 32, Color.RED.rgb)
+ fontRendererObj.drawString("the discord for help", guiLeft + 52, guiTop + 42, Color.RED.rgb)
+ return
+ }
+
+ // Buttons
+ GlStateManager.color(1f, 1f, 1f, 1f)
+ Minecraft.getMinecraft().textureManager.bindTexture(enabledButton)
+ Utils.drawTexturedRect(guiLeft.toFloat() + 15, (guiTop + ySize - 32).toFloat(), 88F, 20F,
+ 0F, 1F, 0F, 1F, GL11.GL_NEAREST)
+
+ if (itemSelected != null) {
+ Minecraft.getMinecraft().textureManager.bindTexture(enabledButton)
+ } else {
+ Minecraft.getMinecraft().textureManager.bindTexture(disabledButton)
+ }
+ Utils.drawTexturedRect(guiLeft.toFloat() + 114, (guiTop + ySize - 32).toFloat(), 88F, 20F,
+ 0F, 1F, 0F, 1F, GL11.GL_NEAREST)
+
+ fontRendererObj.drawString("Add Held Item", guiLeft + 27, guiTop + ySize - 26, 4210752)
+ fontRendererObj.drawString("Remove Item", guiLeft + 130, guiTop + ySize - 26, 4210752)
+
+ GlStateManager.color(1f, 1f, 1f, 1f)
+
+ // Add in some part of the gui for every row
+ Minecraft.getMinecraft().textureManager.bindTexture(background)
+ for (i in 0 until numOfRows) {
+ Utils.drawTexturedRect(guiLeft.toFloat(), ((guiTop + 24) + (i * 18)).toFloat(), xSize.toFloat(), 18f,
+ 0f, 1f, 24 / 88f, 42 / 88f, GL11.GL_NEAREST)
+ }
+
+ var hoveredItem: String? = null
+ var selectedPosition: Pair<Int, Int> = Pair(-999, -999)
+
+ // Draw a slot for each item and the ItemStack
+ for ((index, item) in NotEnoughUpdates.INSTANCE.config.hidden.dynamicLightItems.withIndex()) {
+ val i = index % 9
+ val j = index / 9
+ GlStateManager.color(1f, 1f, 1f, 1f)
+
+ Minecraft.getMinecraft().textureManager.bindTexture(chestGui)
+ drawTexturedModalRect(guiLeft + 27 + i % 9 * 18, guiTop + 24 + j * 18, 7, 17, 18, 18)
+
+ val itemStack = resolveItemStack(item) ?: return
+ Utils.drawItemStack(itemStack, guiLeft + 28 + i % 9 * 18, guiTop + 25 + j * 18)
+
+ if (mouseX >= guiLeft + 27 + i % 9 * 18 && mouseX <= guiLeft + 45 + i % 9 * 18) {
+ if (mouseY >= guiTop + 24 + j * 18 && mouseY <= guiTop + 42 + j * 18) {
+ hoveredItem = item
+ val tooltip = itemStack.getTooltip(Minecraft.getMinecraft().thePlayer, false)
+ Utils.drawHoveringText(tooltip, mouseX, mouseY, width, height, -1)
+ }
+ }
+
+ if (itemSelected != null && itemSelected.equals(item)) {
+ // Save the position, so when we render the selected box its renders on top of everything
+ selectedPosition = Pair(guiLeft + 24 + i % 9 * 18, guiTop + 21 + j * 18)
+ }
+ }
+
+ stackToRender = hoveredItem
+
+ GlStateManager.color(1f, 1f, 1f, 1f)
+ Minecraft.getMinecraft().textureManager.bindTexture(widgets)
+ drawTexturedModalRect(selectedPosition.first, selectedPosition.second, 0, 22, 24, 24)
+
+ super.drawScreen(mouseX, mouseY, partialTicks)
+ }
+
+ override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) {
+ if (didApplyMixin) {
+ // Add Held Item button
+ if (mouseX >= guiLeft + 15 &&
+ mouseX <= guiLeft + 103 &&
+ mouseY >= (guiTop + ySize - 32) &&
+ mouseY <= (guiTop + ySize - 12)) {
+
+ val heldItem = Minecraft.getMinecraft().thePlayer.heldItem
+
+ if (heldItem == null) {
+ Utils.addChatMessage("§c[NEU] You can't add your hand to the list of dynamic light items.")
+ return
+ }
+
+ val internalName = resolveInternalName(heldItem)
+ if (internalName == null) {
+ Utils.addChatMessage("§c[NEU] Couldn't resolve an internal name for this item!")
+ return
+ }
+ NotEnoughUpdates.INSTANCE.config.hidden.dynamicLightItems.add(internalName)
+ }
+
+ // Remove Item button
+ if (mouseX >= guiLeft + 114 &&
+ mouseX <= guiLeft + 202 &&
+ mouseY >= guiTop + ySize - 32 &&
+ mouseY <= guiTop + ySize - 12 &&
+ itemSelected != null) {
+ NotEnoughUpdates.INSTANCE.config.hidden.dynamicLightItems.remove(itemSelected)
+ itemSelected = null
+ }
+
+ if (stackToRender != null) {
+ itemSelected = stackToRender
+ }
+ }
+
+ super.mouseClicked(mouseX, mouseY, mouseButton)
+ }
+
+ companion object {
+ @JvmStatic
+ var didApplyMixin = false
+
+ fun resolveItemStack(internalName: String): ItemStack? {
+ var itemStack = NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withKnownInternalName(internalName)
+ .resolveToItemStack()
+ if (itemStack == null) {
+ // Try resolve the item stack through forge
+ itemStack = GameRegistry.makeItemStack(internalName, 0, 1, null)
+ if (itemStack == null) {
+ Utils.addChatMessage("§c[NEU] Couldn't resolve the ItemStack for $internalName")
+ return null
+ }
+ }
+
+ return itemStack
+ }
+
+ @JvmStatic
+ fun resolveInternalName(itemStack: ItemStack): String? {
+ var internalName =
+ NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(itemStack).resolveInternalName()
+ if (internalName == null) {
+ // If resolving internal name failed, the item may be a minecraft item
+ internalName = itemStack.item.registryName
+ if (internalName == null) {
+ // Check if minecraft searching also fails
+ // Leave error handling for caller since this method is also called in MixinOFDynamicLights which
+ // is run every tick, and we don't want to flood the chat
+ return null
+ }
+ }
+
+ return internalName
+ }
+
+ @JvmStatic
+ fun findDynamicLightItems(itemStack: ItemStack): Int {
+ val internalName: String = resolveInternalName(itemStack) ?: return 0
+ if (NotEnoughUpdates.INSTANCE.config.hidden.dynamicLightItems.contains(internalName)) {
+ return 15
+ }
+ return 0
+ }
+ }
+}
diff --git a/src/main/resources/assets/notenoughupdates/disabled_button.png b/src/main/resources/assets/notenoughupdates/disabled_button.png
new file mode 100644
index 00000000..4283fbf3
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/disabled_button.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/dynamic_light_items_editor.png b/src/main/resources/assets/notenoughupdates/dynamic_light_items_editor.png
new file mode 100644
index 00000000..399924c1
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/dynamic_light_items_editor.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/enabled_button.png b/src/main/resources/assets/notenoughupdates/enabled_button.png
new file mode 100644
index 00000000..a0f8d7fc
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/enabled_button.png
Binary files differ
diff --git a/src/main/resources/mixins.notenoughupdates.json b/src/main/resources/mixins.notenoughupdates.json
index eb04957b..279d5cef 100644
--- a/src/main/resources/mixins.notenoughupdates.json
+++ b/src/main/resources/mixins.notenoughupdates.json
@@ -37,6 +37,7 @@
"MixinMinecraft",
"MixinMouseHelper",
"MixinNetHandlerPlayClient",
+ "MixinOFDynamicLights",
"MixinPlayerControllerMP",
"MixinRender",
"MixinRendererLivingEntity",