From 82d9f737460481a4b9933faa04a18cd59c02fd5d Mon Sep 17 00:00:00 2001 From: nea Date: Sun, 1 May 2022 18:01:28 +0200 Subject: Warping... (to deez nuts) --- .../notenoughupdates/miscfeatures/Navigation.java | 139 ++++++++++++++++++++- .../notenoughupdates/options/NEUConfig.java | 3 + .../options/seperateSections/Misc.java | 9 ++ .../notenoughupdates/recipes/ItemShopRecipe.java | 7 +- .../moulberry/notenoughupdates/util/ItemUtils.java | 15 +++ 5 files changed, 166 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java index 651270cb..3419b8c4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/Navigation.java @@ -5,23 +5,31 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; +import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscgui.GuiNavigation; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.JsonUtils; import io.github.moulberry.notenoughupdates.util.NotificationHandler; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.item.ItemStack; import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.Vec3i; import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import org.lwjgl.input.Keyboard; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -35,12 +43,24 @@ public class Navigation { private List teleporters = new ArrayList<>(); private Map areaNames = new HashMap<>(); + private Map warps = new HashMap<>(); private Map waypoints = new HashMap<>(); public Map getWaypoints() { return waypoints; } + public static class WarpPoint { + public final BlockPos blockPos; + public final String warpName, modeName; + + public WarpPoint(double x, double y, double z, String warpName, String modeName) { + this.blockPos = new BlockPos(x, y, z); + this.warpName = warpName; + this.modeName = modeName; + } + } + public static class Teleporter { public final double x, y, z; public final String from, to; @@ -66,6 +86,9 @@ public class Navigation { private String island = null; private String displayName = null; private String internalname = null; + private String warpAgainTo = null; + private int lastInvHashcode = 0; + private Instant warpAgainTiming = null; private Teleporter nextTeleporter = null; @@ -84,7 +107,10 @@ public class Navigation { } else { JsonObject jsonObject = waypoints.get(trackNow); if (jsonObject == null) { - showError("Could not track waypoint " + trackNow + ". This is likely due to an outdated or broken repository."); + showError( + "Could not track waypoint " + trackNow + ". This is likely due to an outdated or broken repository.", + true + ); return; } trackWaypoint(jsonObject); @@ -93,7 +119,7 @@ public class Navigation { public void trackWaypoint(JsonObject trackNow) { if (trackNow != null && !isValidWaypoint(trackNow)) { - showError("Could not track waypoint. This is likely due to an outdated or broken repository."); + showError("Could not track waypoint. This is likely due to an outdated or broken repository.", true); return; } if (!neu.config.hidden.hasOpenedWaypointMenu) @@ -122,7 +148,7 @@ public class Navigation { }); for (Teleporter teleporter : teleporters) { if (teleporter.from.equals(teleporter.to)) { - showError("Found self referencing teleporter: " + teleporter.from); + showError("Found self referencing teleporter: " + teleporter.from, true); } } this.teleporters = teleporters; @@ -131,13 +157,113 @@ public class Navigation { .filter(this::isValidWaypoint) .collect(Collectors.toMap(it -> it.get("internalname").getAsString(), it -> it)); this.areaNames = JsonUtils.transformJsonObjectToMap(obj.getAsJsonObject("area_names"), JsonElement::getAsString); + this.warps = JsonUtils.getJsonArrayOrEmpty(obj, "island_warps", jsonElement -> { + JsonObject warpObject = jsonElement.getAsJsonObject(); + return new WarpPoint( + warpObject.get("x").getAsDouble(), + warpObject.get("y").getAsDouble(), + warpObject.get("z").getAsDouble(), + warpObject.get("warp").getAsString(), + warpObject.get("mode").getAsString() + ); + }).stream().collect(Collectors.toMap(it -> it.warpName, it -> it)); } @SubscribeEvent public void onKeybindPressed(InputEvent.KeyInputEvent event) { + if (!Keyboard.getEventKeyState()) return; int key = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); if (neu.config.misc.keybindWaypoint == key) { - Minecraft.getMinecraft().displayGuiScreen(new GuiNavigation()); + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { + if (currentlyTrackedWaypoint != null) { + useWarpCommand(); + } + } else { + Minecraft.getMinecraft().displayGuiScreen(new GuiNavigation()); + } + } + } + + @SubscribeEvent + public void onGuiTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.START) return; + if (Minecraft.getMinecraft().theWorld == null) return; + if (Minecraft.getMinecraft().thePlayer == null) return; + + if (Minecraft.getMinecraft().currentScreen instanceof GuiChest && RenderListener.inventoryLoaded) { + GuiChest currentScreen = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) currentScreen.inventorySlots; + if (container.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Fast Travel")) { + int hashCode = container.getInventory().hashCode(); + if (hashCode == lastInvHashcode) return; + lastInvHashcode = hashCode; + for (ItemStack stackInSlot : container.getInventory()) { + if (stackInSlot == null) continue; + List lore = ItemUtils.getLore(stackInSlot); + if (lore.isEmpty()) + continue; + String warpLine = Utils.cleanColour(lore.get(0)); + if (!warpLine.startsWith("/warp ")) continue; + String warpName = warpLine.substring(6); + boolean isUnlocked = !lore.contains("§cWarp not unlocked!"); + neu.config.getProfileSpecific().unlockedWarpScrolls.put(warpName, isUnlocked); + } + } + } + } + + public Map getWarps() { + return warps; + } + + public WarpPoint getClosestWarp(String mode, Vec3i position, boolean checkAvailable) { + double minDistance = -1; + HashMap unlockedWarpScrolls = neu.config.getProfileSpecific().unlockedWarpScrolls; + WarpPoint minWarp = null; + for (WarpPoint value : warps.values()) { + if (value.modeName.equals(mode)) { + if (checkAvailable && !unlockedWarpScrolls.getOrDefault(value.warpName, false)) + continue; + double distance = value.blockPos.distanceSq(position); + if (distance < minDistance || minWarp == null) { + minDistance = distance; + minWarp = value; + } + } + } + return minWarp; + } + + public void useWarpCommand() { + EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; + if (currentlyTrackedWaypoint == null || thePlayer == null) return; + WarpPoint closestWarp = getClosestWarp(island, position, true); + if (closestWarp == null) { + showError("Could not find an unlocked warp that could be used.", false); + return; + } + + if (!island.equals(SBInfo.getInstance().mode)) { + warpAgainTiming = Instant.now(); + warpAgainTo = closestWarp.warpName; + } else if (thePlayer.getDistanceSq(position) < closestWarp.blockPos.distanceSq(position)) { + showError("You are already on the same island and nearer than the closest unlocked warp scroll.", false); + return; + } + thePlayer.sendChatMessage("/warp " + closestWarp.warpName); + } + + @SubscribeEvent + public void onTeleportDone(EntityJoinWorldEvent event) { + if (neu.config.misc.warpTwice + && event.entity == Minecraft.getMinecraft().thePlayer + && warpAgainTo != null + && warpAgainTiming != null + && warpAgainTiming.plusSeconds(1).isAfter(Instant.now())) { + warpAgainTiming = null; + String savedWarpAgain = warpAgainTo; + warpAgainTo = null; + Minecraft.getMinecraft().thePlayer.sendChatMessage("/warp " + savedWarpAgain); } } @@ -230,12 +356,13 @@ public class Navigation { return minPath; } - private void showError(String message) { + private void showError(String message, boolean log) { EntityPlayerSP player = Minecraft.getMinecraft().thePlayer; if (player != null) player.addChatMessage(new ChatComponentText(EnumChatFormatting.DARK_RED + "[NEU-Waypoint] " + message)); - new RuntimeException("[NEU-Waypoint] " + message).printStackTrace(); + if (log) + new RuntimeException("[NEU-Waypoint] " + message).printStackTrace(); } @SubscribeEvent 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 e0d46a1e..71f7b0ab 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -513,6 +513,9 @@ public class NEUConfig extends Config { public long dailyGemstonePowderCompleted = 0L; @Expose public long dailyMithrilPowerCompleted = 0L; + + @Expose + public HashMap unlockedWarpScrolls = new HashMap<>(); } public HiddenLocationSpecific getLocationSpecific() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java index 4c521023..a04a51f9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java @@ -187,4 +187,13 @@ public class Misc { ) @ConfigEditorBoolean public boolean untrackCloseWaypoints = true; + + @Expose + @ConfigOption( + name = "Warp twice", + desc = "Warp twice when using SHIFT+N to /warp to a waypoint." + ) + @ConfigEditorBoolean + public boolean warpTwice = true; + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ItemShopRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ItemShopRecipe.java index 1b9bb248..54253607 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/ItemShopRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/ItemShopRecipe.java @@ -11,6 +11,7 @@ import io.github.moulberry.notenoughupdates.util.JsonUtils; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.util.ResourceLocation; +import org.lwjgl.input.Keyboard; import java.util.ArrayList; import java.util.HashSet; @@ -119,10 +120,14 @@ public class ItemShopRecipe implements NeuRecipe { GuiNavigation.ICON_SIZE, GuiNavigation.ICON_SIZE )) { - if (selected) { + boolean shiftPressed = Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); + if (selected && !shiftPressed) { NotEnoughUpdates.INSTANCE.navigation.untrackWaypoint(); } else { NotEnoughUpdates.INSTANCE.navigation.trackWaypoint(npcIngredient.getInternalItemId()); + if (shiftPressed) { + NotEnoughUpdates.INSTANCE.navigation.useWarpCommand(); + } } Utils.playPressSound(); selected = !selected; 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 f5e552a2..729e68bd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java @@ -5,6 +5,8 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; +import java.util.ArrayList; +import java.util.Collections; import java.util.List; public class ItemUtils { @@ -48,4 +50,17 @@ public class ItemUtils { tagCompound.setTag("display", display); is.setTagCompound(tagCompound); } + + public static List getLore(ItemStack is) { + NBTTagCompound tagCompound = is.getTagCompound(); + if (tagCompound == null) { + return Collections.emptyList(); + } + NBTTagList tagList = tagCompound.getCompoundTag("display").getTagList("Lore", 8); + List list = new ArrayList<>(); + for (int i = 0; i < tagList.tagCount(); i++) { + list.add(tagList.getStringTagAt(i)); + } + return list; + } } -- cgit