From 893e7262ed05d9266548d899c98dad2e1cb285f1 Mon Sep 17 00:00:00 2001 From: nea Date: Fri, 14 Apr 2023 03:46:12 +0200 Subject: Add NPC Position only exporter --- .../miscfeatures/entityviewer/GUIClientPlayer.java | 6 +- .../moulberry/notenoughupdates/util/ItemUtils.java | 26 ++++ .../recipes/generators/NPCLocationExporter.kt | 140 +++++++++++++++++++++ 3 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt 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/recipes/generators/NPCLocationExporter.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt new file mode 100644 index 00000000..7c352dae --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/generators/NPCLocationExporter.kt @@ -0,0 +1,140 @@ +/* + * 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 . + */ + +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.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 + 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 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)) + } +} -- cgit