aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman / Linnea Gräf <roman.graef@gmail.com>2023-05-27 19:21:04 +0200
committerGitHub <noreply@github.com>2023-05-27 19:21:04 +0200
commit813c8d6b20a9c01de27f5d0b5804c4df5dc4044b (patch)
tree706a67563ed65ecb1f96ffec83bb8727854cba28
parent9cb9f7633dd71515eb972028a580c9e60fe22f89 (diff)
downloadNotEnoughUpdates-813c8d6b20a9c01de27f5d0b5804c4df5dc4044b.tar.gz
NotEnoughUpdates-813c8d6b20a9c01de27f5d0b5804c4df5dc4044b.tar.bz2
NotEnoughUpdates-813c8d6b20a9c01de27f5d0b5804c4df5dc4044b.zip
Add NPC Position only exporter (#686)
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java26
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt8
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt153
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt9
6 files changed, 196 insertions, 8 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java
index 8cdf2ef0..3311f21d 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/entityviewer/GUIClientPlayer.java
@@ -32,9 +32,9 @@ public class GUIClientPlayer extends AbstractClientPlayer {
super(null, new GameProfile(UUID.randomUUID(), "GuiPlayer"));
}
- ResourceLocation overrideSkin = DefaultPlayerSkin.getDefaultSkinLegacy();
- ResourceLocation overrideCape = null;
- boolean overrideIsSlim = false;
+ public ResourceLocation overrideSkin = DefaultPlayerSkin.getDefaultSkinLegacy();
+ public ResourceLocation overrideCape = null;
+ public boolean overrideIsSlim = false;
NetworkPlayerInfo playerInfo = new NetworkPlayerInfo(this.getGameProfile()) {
@Override
public String getSkinType() {
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 f8f42b80..93ea6127 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java
@@ -19,6 +19,7 @@
package io.github.moulberry.notenoughupdates.util;
+import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -36,16 +37,34 @@ import net.minecraft.nbt.NBTTagString;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.MathHelper;
+import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
public class ItemUtils {
+ private static final Gson smallPrintingGson = new Gson();
+
+ public static ItemStack createSkullItemStack(String displayName, String uuid, String skinAbsoluteUrl) {
+ JsonObject object = new JsonObject();
+ JsonObject textures = new JsonObject();
+ JsonObject skin = new JsonObject();
+ skin.addProperty("url", skinAbsoluteUrl);
+ textures.add("SKIN", skin);
+ object.add("textures", textures);
+ String json = smallPrintingGson.toJson(object);
+ return Utils.createSkull(
+ displayName,
+ uuid,
+ Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8))
+ );
+ }
public static ItemStack getCoinItemStack(double coinAmount) {
String uuid = "2070f6cb-f5db-367a-acd0-64d39a7e5d1b";
@@ -187,6 +206,13 @@ public class ItemUtils {
return text;
}
+ public static NBTTagCompound getExtraAttributes(ItemStack itemStack) {
+ NBTTagCompound tag = getOrCreateTag(itemStack);
+ NBTTagCompound extraAttributes = tag.getCompoundTag("ExtraAttributes");
+ tag.setTag("ExtraAttributes", extraAttributes);
+ return extraAttributes;
+ }
+
public static ItemStack createPetItemstackFromPetInfo(PetInfoOverlay.Pet currentPet) {
if (currentPet == null) {
ItemStack stack = ItemUtils.createQuestionMarkSkull(EnumChatFormatting.RED + "Unknown Pet");
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt
index fceacfab..9e29d248 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.kt
@@ -67,7 +67,7 @@ class PackDevCommand {
reply("No $name found within $dist blocks")
return@thenArgumentExecute
}
- MiscUtils.copyToClipboard(StringBuilder().appendEntityData(entity).toString().trim())
+ MiscUtils.copyToClipboard(StringBuilder().also { it.appendEntityData(entity) }.toString().trim())
reply("Copied data to clipboard")
}.withHelp("Find the nearest $name and copy data about them to your clipboard")
}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt
index 1d766646..a38ee8c9 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/commands/misc/FairySoulsCommand.kt
@@ -41,22 +41,22 @@ class FairySoulsCommand {
reply("${DARK_PURPLE}Enabled fairy soul waypoints")
FairySouls.getInstance().setShowFairySouls(true)
}.withHelp("Show fairy soul waypoints")
- thenLiteral("on") { redirect(enable) }
+ thenLiteral("on") { thenRedirect(enable) }
val disable = thenLiteralExecute("disable") {
FairySouls.getInstance().setShowFairySouls(false)
reply("${DARK_PURPLE}Disabled fairy soul waypoints")
}.withHelp("Hide fairy soul waypoints")
- thenLiteral("off") { redirect(disable) }
+ thenLiteral("off") { thenRedirect(disable) }
val clear = thenLiteralExecute("clear") {
FairySouls.getInstance().markAllAsFound()
// Reply handled by mark all as found
}.withHelp("Mark all fairy souls in your current world as found")
- thenLiteral("markfound") { redirect(clear) }
+ thenLiteral("markfound") { thenRedirect(clear) }
val unclear = thenLiteralExecute("unclear") {
FairySouls.getInstance().markAllAsMissing()
// Reply handled by mark all as missing
}.withHelp("Mark all fairy souls in your current world as not found")
- thenLiteral("marknotfound") { redirect(unclear) }
+ thenLiteral("marknotfound") { thenRedirect(unclear) }
}
}
}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt
new file mode 100644
index 00000000..7acd88a9
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt
@@ -0,0 +1,153 @@
+/*
+ * 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.recipes.generators
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.core.util.StringUtils
+import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils
+import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField
+import io.github.moulberry.notenoughupdates.util.ItemUtils
+import io.github.moulberry.notenoughupdates.util.SBInfo
+import io.github.moulberry.notenoughupdates.util.Utils
+import io.github.moulberry.notenoughupdates.util.kotlin.set
+import net.minecraft.client.Minecraft
+import net.minecraft.client.entity.AbstractClientPlayer
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.entity.passive.EntityVillager
+import net.minecraft.util.BlockPos
+import net.minecraftforge.client.event.MouseEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import org.lwjgl.input.Keyboard
+import java.util.*
+
+@NEUAutoSubscribe
+class NPCLocationExporter {
+ class NPCNamePrompt(val uuid: UUID, val position: BlockPos, val island: String, val skinId: String) : GuiScreen() {
+ val nameField = GuiElementTextField("§9Unknown (NPC)", GuiElementTextField.COLOUR).also {
+ it.setSize(100, 20)
+ }
+ var name
+ get() = nameField.text
+ set(value) {
+ nameField.text = value
+ }
+ val id
+ get() = StringUtils.cleanColour(name.replace(" ", "_"))
+ .uppercase()
+ .replace("[^A-Z_0-9]".toRegex(), "")
+ val itemStack
+ get() = ItemUtils.createSkullItemStack(
+ name,
+ uuid.toString(),
+ "https://textures.minecraft.net/texture/$skinId"
+ )
+ val top get() = height / 2 - 50
+ val left get() = width / 2 - 100
+
+ override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) {
+ super.drawScreen(mouseX, mouseY, partialTicks)
+ drawDefaultBackground()
+ RenderUtils.drawFloatingRect(left, top, 200, 100)
+ nameField.render(left + 48 + 20, top + 20)
+ GlStateManager.pushMatrix()
+ GlStateManager.translate((left + 5).toDouble(), (top + 5).toDouble(), 0.0)
+ GlStateManager.scale(3.0, 3.0, 1.0)
+ GlStateManager.translate(8F, 8F, 0F)
+
+ GlStateManager.rotate(((System.currentTimeMillis() / 5000.0) % 1 * 360).toFloat(), 0F, 0F, 1F)
+ Utils.drawItemStack(itemStack, -8, -8, false)
+ GlStateManager.popMatrix()
+ }
+
+ fun save() {
+ val itemStack = this.itemStack
+ ItemUtils.getExtraAttributes(itemStack).setString("id", id)
+ val json = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(itemStack)
+ json["internalname"] = id
+ json["clickcommand"] = ""
+ json["modver"] = NotEnoughUpdates.VERSION
+ json["x"] = position.x
+ json["y"] = position.y + 1
+ json["z"] = position.z
+ json["island"] = island
+ NotEnoughUpdates.INSTANCE.manager.writeJsonDefaultDir(json, "$id.json")
+ Utils.addChatMessage("Saved to file")
+ Minecraft.getMinecraft().displayGuiScreen(null)
+ }
+
+ override fun keyTyped(typedChar: Char, keyCode: Int) {
+ super.keyTyped(typedChar, keyCode)
+ if (keyCode == Keyboard.KEY_RETURN) {
+ save()
+ }
+ nameField.keyTyped(typedChar, keyCode)
+ }
+
+ override fun mouseClicked(mouseX: Int, mouseY: Int, mouseButton: Int) {
+ super.mouseClicked(mouseX, mouseY, mouseButton)
+ val mouseX = Utils.getMouseX()
+ val mouseY = Utils.getMouseY()
+ if (mouseX - left - 48 - 20 in 0..nameField.width &&
+ mouseY - top - 20 in 0..nameField.height
+ ) {
+ nameField.mouseClicked(mouseX, mouseY, mouseButton)
+ } else {
+ nameField.otherComponentClick()
+ }
+ }
+ }
+
+ @SubscribeEvent
+ fun onMouseClick(event: MouseEvent) {
+ if (event.buttonstate || event.button != 2 || !NotEnoughUpdates.INSTANCE.config.apiData.repositoryEditing) return
+ val pointedEntity = Minecraft.getMinecraft().pointedEntity
+ if (pointedEntity == null) {
+ Utils.addChatMessage("Could not find entity under cursor")
+ return
+ }
+ if (pointedEntity is EntityVillager) {
+ Minecraft.getMinecraft().displayGuiScreen(
+ NPCNamePrompt(
+ // Just use jerry pet skin, idk, this will probably cause texture packs to overwrite us, but uhhhhh uhhhhhhh
+ UUID.fromString("c9540683-51e4-3942-ad17-4f2c3f3ae4b7"),
+ pointedEntity.position,
+ SBInfo.getInstance().getLocation(),
+ "822d8e751c8f2fd4c8942c44bdb2f5ca4d8ae8e575ed3eb34c18a86e93b"
+ )
+ )
+ return
+ }
+ if (pointedEntity !is AbstractClientPlayer) {
+ Utils.addChatMessage("Entity under cursor is not a player")
+ return
+ }
+ val uuid = pointedEntity.uniqueID
+ val position = pointedEntity.position
+ val island = SBInfo.getInstance().getLocation()
+ val skin = pointedEntity.locationSkin.resourcePath?.replace("skins/", "")
+ if (skin == null) {
+ Utils.addChatMessage("Could not load skin")
+ return
+ }
+ Minecraft.getMinecraft().displayGuiScreen(NPCNamePrompt(uuid, position, island, skin))
+ }
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt
index 17203a4b..1ce00d99 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/brigadier/dsl.kt
@@ -136,6 +136,15 @@ fun <T : ArgumentBuilder<DefaultSource, T>> T.thenLiteralExecute(
thenExecute(block)
}
+fun <T : ArgumentBuilder<DefaultSource, T>> T.thenRedirect(node: CommandNode<DefaultSource>): T {
+ node.children.forEach {
+ this.then(it)
+ }
+ forward(node.redirect, node.redirectModifier, node.isFork)
+ executes(node.command)
+ return this
+}
+
fun <T : ArgumentBuilder<DefaultSource, T>, U : ArgumentBuilder<DefaultSource, U>> T.then(
node: U,
block: U.() -> Unit