aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java15
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java1717
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java1545
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/SpiritLeap.java40
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMap.java161
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapDebugOverlay.java117
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapPlayers.java267
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapRenderer.java526
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapStaticParser.java228
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonResources.java86
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/Room.java122
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnection.java28
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnectionType.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomOffset.java46
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java51
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/RecencyList.java130
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java16
-rw-r--r--src/main/resources/assets/notenoughupdates/dungeon_map/corridors_default/black_corridor.pngbin0 -> 4829 bytes
20 files changed, 2567 insertions, 2539 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
index 8c23aa60..9701005f 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java
@@ -27,7 +27,6 @@ import io.github.moulberry.notenoughupdates.commands.Commands;
import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
import io.github.moulberry.notenoughupdates.cosmetics.CapeManager;
import io.github.moulberry.notenoughupdates.cosmetics.ShaderManager;
-import io.github.moulberry.notenoughupdates.dungeons.DungeonMap;
import io.github.moulberry.notenoughupdates.listener.ChatListener;
import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener;
import io.github.moulberry.notenoughupdates.listener.NEUEventListener;
@@ -262,7 +261,6 @@ public class NotEnoughUpdates {
MinecraftForge.EVENT_BUS.register(SBInfo.getInstance());
MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE);
MinecraftForge.EVENT_BUS.register(new Constants());
- MinecraftForge.EVENT_BUS.register(new DungeonMap());
MinecraftForge.EVENT_BUS.register(new SunTzu());
MinecraftForge.EVENT_BUS.register(new MiningStuff());
MinecraftForge.EVENT_BUS.register(FairySouls.getInstance());
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
index 326c00b4..fb546efb 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java
@@ -41,7 +41,8 @@ public class DiagCommand extends ClientCommandBase {
" center=<off | on> Disable / enable using center\n" +
"/neudiag wishing Wishing Compass Solver diagnostics\n" +
"/neudiag debug\n" +
- " <no sub-command> Show current flags\n" +
+ " <no sub-command> Show all enabled flags\n" +
+ " <list> Show all flags\n"+
" <enable | disable> <flag> Enable/disable flag\n";
private void showUsage(ICommandSender sender) {
@@ -86,6 +87,10 @@ public class DiagCommand extends ClientCommandBase {
boolean enablingFlag = true;
String action = args[1];
switch (action) {
+ case "list":
+ sender.addChatMessage(new ChatComponentText(
+ EnumChatFormatting.YELLOW + "Here are all flags:\n" + NEUDebugFlag.getFlagList()));
+ return;
case "disable":
enablingFlag = false;
// falls through
@@ -93,7 +98,7 @@ public class DiagCommand extends ClientCommandBase {
if (args.length != 3) {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
"You must specify a flag:\n" +
- NEUDebugFlag.FLAG_LIST));
+ NEUDebugFlag.getFlagList()));
return;
}
@@ -108,7 +113,7 @@ public class DiagCommand extends ClientCommandBase {
} catch (IllegalArgumentException e) {
sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED +
flagName + " is invalid. Valid flags are:\n" +
- NEUDebugFlag.FLAG_LIST));
+ NEUDebugFlag.getFlagList()));
return;
}
break;
@@ -118,8 +123,8 @@ public class DiagCommand extends ClientCommandBase {
}
}
- sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: " +
- NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.toString()));
+ sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: \n" +
+ NEUDebugFlag.getEnabledFlags()));
break;
default:
showUsage(sender);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
deleted file mode 100644
index 2693341a..00000000
--- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java
+++ /dev/null
@@ -1,1717 +0,0 @@
-/*
- * Copyright (C) 2022 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.dungeons;
-
-import com.google.common.collect.Iterables;
-import com.google.gson.JsonObject;
-import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
-import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
-import io.github.moulberry.notenoughupdates.core.config.Position;
-import io.github.moulberry.notenoughupdates.util.NEUResourceManager;
-import io.github.moulberry.notenoughupdates.util.SpecialColour;
-import io.github.moulberry.notenoughupdates.util.Utils;
-import net.minecraft.block.material.MapColor;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.entity.AbstractClientPlayer;
-import net.minecraft.client.gui.Gui;
-import net.minecraft.client.gui.ScaledResolution;
-import net.minecraft.client.renderer.GlStateManager;
-import net.minecraft.client.renderer.OpenGlHelper;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.WorldRenderer;
-import net.minecraft.client.renderer.texture.TextureUtil;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.client.resources.DefaultPlayerSkin;
-import net.minecraft.client.shader.Framebuffer;
-import net.minecraft.client.shader.Shader;
-import net.minecraft.entity.Entity;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.init.Items;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemMap;
-import net.minecraft.item.ItemStack;
-import net.minecraft.scoreboard.Score;
-import net.minecraft.scoreboard.ScoreObjective;
-import net.minecraft.scoreboard.ScorePlayerTeam;
-import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.util.Matrix4f;
-import net.minecraft.util.ResourceLocation;
-import net.minecraft.util.Vec4b;
-import net.minecraft.world.storage.MapData;
-import net.minecraftforge.client.event.RenderGameOverlayEvent;
-import net.minecraftforge.event.world.WorldEvent;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL14;
-
-import java.awt.*;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-public class DungeonMap {
- private static final ResourceLocation GREEN_CHECK = new ResourceLocation(
- "notenoughupdates:dungeon_map/green_check.png");
- private static final ResourceLocation WHITE_CHECK = new ResourceLocation(
- "notenoughupdates:dungeon_map/white_check.png");
- private static final ResourceLocation QUESTION = new ResourceLocation("notenoughupdates:dungeon_map/question.png");
- private static final ResourceLocation CROSS = new ResourceLocation("notenoughupdates:dungeon_map/cross.png");
-
- private static final ResourceLocation ROOM_RED = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/red_room.png");
- private static final ResourceLocation ROOM_BROWN = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/brown_room.png");
- private static final ResourceLocation ROOM_GRAY = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/gray_room.png");
- private static final ResourceLocation ROOM_GREEN = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/green_room.png");
- private static final ResourceLocation ROOM_PINK = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/pink_room.png");
- private static final ResourceLocation ROOM_PURPLE = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/purple_room.png");
- private static final ResourceLocation ROOM_YELLOW = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/yellow_room.png");
- private static final ResourceLocation ROOM_ORANGE = new ResourceLocation(
- "notenoughupdates:dungeon_map/rooms_default/orange_room.png");
-
- private static final ResourceLocation CORRIDOR_RED = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/red_corridor.png");
- private static final ResourceLocation CORRIDOR_BROWN = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/brown_corridor.png");
- private static final ResourceLocation CORRIDOR_GRAY = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/gray_corridor.png");
- private static final ResourceLocation CORRIDOR_GREEN = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/green_corridor.png");
- private static final ResourceLocation CORRIDOR_PINK = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/pink_corridor.png");
- private static final ResourceLocation CORRIDOR_PURPLE = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/purple_corridor.png");
- private static final ResourceLocation CORRIDOR_YELLOW = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/yellow_corridor.png");
- private static final ResourceLocation CORRIDOR_ORANGE = new ResourceLocation(
- "notenoughupdates:dungeon_map/corridors_default/orange_corridor.png");
-
- private static final ResourceLocation DIVIDER_BROWN = new ResourceLocation(
- "notenoughupdates:dungeon_map/dividers_default/brown_divider.png");
-
- private static final ResourceLocation CORNER_BROWN = new ResourceLocation(
- "notenoughupdates:dungeon_map/corners_default/brown_corner.png");
-
- private final HashMap<RoomOffset, Room> roomMap = new HashMap<>();
- private Color[][] colourMap = new Color[128][128];
- private int startRoomX = -1;
- private int startRoomY = -1;
- private int connectorSize = 5;
- private int roomSize = 0;
-
- //private final List<MapDecoration> decorations = new ArrayList<>();
- //private final List<MapDecoration> lastDecorations = new ArrayList<>();
- private long lastDecorationsMillis = -1;
- private long lastLastDecorationsMillis = -1;
-
- private final Map<String, MapPosition> playerEntityMapPositions = new HashMap<>();
- private final Map<String, MapPosition> playerMarkerMapPositions = new HashMap<>();
- private final Set<MapPosition> rawPlayerMarkerMapPositions = new HashSet<>();
- private final Map<String, MapPosition> playerMarkerMapPositionsLast = new HashMap<>();
- private final HashMap<String, Integer> playerIdMap = new HashMap<>();
-
- private final Map<String, ResourceLocation> playerSkinMap = new HashMap<>();
-
- private static class RoomOffset {
- int x;
- int y;
-
- public RoomOffset(int x, int y) {
- this.x = x;
- this.y = y;
- }
-
- public RoomOffset left() {
- return new RoomOffset(x - 1, y);
- }
-
- public RoomOffset right() {
- return new RoomOffset(x + 1, y);
- }
-
- public RoomOffset up() {
- return new RoomOffset(x, y - 1);
- }
-
- public RoomOffset down() {
- return new RoomOffset(x, y + 1);
- }
-
- public RoomOffset[] getNeighbors() {
- return new RoomOffset[]{left(), right(), up(), down()};
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- RoomOffset that = (RoomOffset) o;
- return x == that.x && y == that.y;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(x, y);
- }
- }
-
- private enum RoomConnectionType {
- NONE, WALL, CORRIDOR, ROOM_DIVIDER
- }
-
- private static class RoomConnection {
- RoomConnectionType type;
- Color colour;
-
- public RoomConnection(RoomConnectionType type, Color colour) {
- this.type = type;
- this.colour = colour;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- RoomConnection that = (RoomConnection) o;
- return type == that.type &&
- Objects.equals(colour, that.colour);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(type, colour);
- }
- }
-
- private class Room {
- Color colour = new Color(0, 0, 0, 0);
- int tickColour = 0;
- boolean fillCorner = false;
-
- RoomConnection left = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
- RoomConnection up = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
- RoomConnection right = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
- RoomConnection down = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
-
- public void renderNoRotate(int roomSize, int connectorSize, int rotation) {
- if (tickColour != 0) {
- Color tick = new Color(tickColour, true);
- ResourceLocation indicatorTex = null;
- if (tick.getRed() == 255 && tick.getGreen() == 255 && tick.getBlue() == 255) {
- indicatorTex = WHITE_CHECK;
- } else if (tick.getRed() == 0 && tick.getGreen() == 124 && tick.getBlue() == 0) {
- indicatorTex = GREEN_CHECK;
- } else if (tick.getRed() == 13 && tick.getGreen() == 13 && tick.getBlue() == 13) {
- indicatorTex = QUESTION;
- } else if (tick.getRed() == 255 && tick.getGreen() == 0 && tick.getBlue() == 0) {
- indicatorTex = CROSS;
- }
- if (indicatorTex != null) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(indicatorTex);
- float x = 0;
- float y = 0;
-
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterCheck) {
- if (fillCorner) {
- x += -(roomSize + connectorSize) / 2f * Math.cos(Math.toRadians(rotation - 45)) * 1.414f;
- y += (roomSize + connectorSize) / 2f * Math.sin(Math.toRadians(rotation - 45)) * 1.414;
- }
- if (down.type == RoomConnectionType.ROOM_DIVIDER && right.type != RoomConnectionType.ROOM_DIVIDER) {
- x += -(roomSize + connectorSize) / 2f * Math.sin(Math.toRadians(rotation));
- y += -(roomSize + connectorSize) / 2f * Math.cos(Math.toRadians(rotation));
- } else if (down.type != RoomConnectionType.ROOM_DIVIDER && right.type == RoomConnectionType.ROOM_DIVIDER) {
- x += -(roomSize + connectorSize) / 2f * Math.cos(Math.toRadians(rotation));
- y += (roomSize + connectorSize) / 2f * Math.sin(Math.toRadians(rotation));
- }
- }
- GlStateManager.translate(x, y, 0);
- if (!NotEnoughUpdates.INSTANCE.config.dungeonMap.dmOrientCheck) {
- GlStateManager.rotate(-rotation + 180, 0, 0, 1);
- }
-
- GlStateManager.pushMatrix();
- GlStateManager.scale(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale,
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale, 1
- );
- Utils.drawTexturedRect(-5, -5, 10, 10, GL11.GL_NEAREST);
- GlStateManager.popMatrix();
-
- if (!NotEnoughUpdates.INSTANCE.config.dungeonMap.dmOrientCheck) {
- GlStateManager.rotate(rotation - 180, 0, 0, 1);
- }
- GlStateManager.translate(-x, -y, 0);
- }
- }
- }
-
- public void render(int roomSize, int connectorSize) {
- ResourceLocation roomTex = null;
- if (colour.getRed() == 114 && colour.getGreen() == 67 && colour.getBlue() == 27) {
- roomTex = ROOM_BROWN;
- } else if (colour.getRed() == 65 && colour.getGreen() == 65 && colour.getBlue() == 65) {
- roomTex = ROOM_GRAY;
- } else if (colour.getRed() == 0 && colour.getGreen() == 124 && colour.getBlue() == 0) {
- roomTex = ROOM_GREEN;
- } else if (colour.getRed() == 242 && colour.getGreen() == 127 && colour.getBlue() == 165) {
- roomTex = ROOM_PINK;
- } else if (colour.getRed() == 178 && colour.getGreen() == 76 && colour.getBlue() == 216) {
- roomTex = ROOM_PURPLE;
- } else if (colour.getRed() == 255 && colour.getGreen() == 0 && colour.getBlue() == 0) {
- roomTex = ROOM_RED;
- } else if (colour.getRed() == 229 && colour.getGreen() == 229 && colour.getBlue() == 51) {
- roomTex = ROOM_YELLOW;
- } else if (colour.getRed() == 216 && colour.getGreen() == 127 && colour.getBlue() == 51) {
- roomTex = ROOM_ORANGE;
- }
-
- if (roomTex != null) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(roomTex);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(0, 0, roomSize, roomSize, GL11.GL_LINEAR);
- } else {
- Gui.drawRect(0, 0, roomSize, roomSize, colour.getRGB());
- }
-
- if (fillCorner) {
- GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(CORNER_BROWN);
- Utils.drawTexturedRect(roomSize, roomSize, connectorSize, connectorSize, GL11.GL_NEAREST);
- }
-
- for (int k = 0; k < 2; k++) {
- RoomConnection connection = down;
- if (k == 1) connection = right;
-
- if (connection.type == RoomConnectionType.NONE || connection.type == RoomConnectionType.WALL) continue;
-
- ResourceLocation corridorTex = null;
- if (connection.colour.getRed() == 114 && connection.colour.getGreen() == 67 &&
- connection.colour.getBlue() == 27) {
- corridorTex = connection.type == RoomConnectionType.CORRIDOR ? CORRIDOR_BROWN : DIVIDER_BROWN;
- } else if (connection.colour.getRed() == 65 && connection.colour.getGreen() == 65 &&
- connection.colour.getBlue() == 65) {
- corridorTex = CORRIDOR_GRAY;
- } else if (connection.colour.getRed() == 0 && connection.colour.getGreen() == 124 &&
- connection.colour.getBlue() == 0) {
- corridorTex = CORRIDOR_GREEN;
- } else if (connection.colour.getRed() == 242 && connection.colour.getGreen() == 127 &&
- connection.colour.getBlue() == 165) {
- corridorTex = CORRIDOR_PINK;
- } else if (connection.colour.getRed() == 178 && connection.colour.getGreen() == 76 &&
- connection.colour.getBlue() == 216) {
- corridorTex = CORRIDOR_PURPLE;
- } else if (connection.colour.getRed() == 255 && connection.colour.getGreen() == 0 &&
- connection.colour.getBlue() == 0) {
- corridorTex = CORRIDOR_RED;
- } else if (connection.colour.getRed() == 229 && connection.colour.getGreen() == 229 &&
- connection.colour.getBlue() == 51) {
- corridorTex = CORRIDOR_YELLOW;
- } else if (connection.colour.getRed() == 216 && connection.colour.getGreen() == 127 &&
- connection.colour.getBlue() == 51) {
- corridorTex = CORRIDOR_ORANGE;
- }
-
- if (corridorTex == null) {
- int xOffset = 0;
- int yOffset = 0;
- int width = 0;
- int height = 0;
-
- if (connection == right) {
- xOffset = roomSize;
- width = connectorSize;
- height = roomSize;
-
- if (connection.type == RoomConnectionType.CORRIDOR) {
- height = 8;
- yOffset += 4;
- }
- } else if (connection == down) {
- yOffset = roomSize;
- width = roomSize;
- height = connectorSize;
-
- if (connection.type == RoomConnectionType.CORRIDOR) {
- width = 8;
- xOffset += 4;
- }
- }
-
- Gui.drawRect(xOffset, yOffset, xOffset + width, yOffset + height, connection.colour.getRGB());
- } else {
- GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(corridorTex);
- GlStateManager.pushMatrix();
- if (connection == right) {
- GlStateManager.translate(roomSize / 2f, roomSize / 2f, 0);
- GlStateManager.rotate(-90, 0, 0, 1);
- GlStateManager.translate(-roomSize / 2f, -roomSize / 2f, 0);
- }
- Utils.drawTexturedRect(0, roomSize, roomSize, connectorSize, GL11.GL_NEAREST);
- GlStateManager.popMatrix();
- }
- }
- }
- }
-
- private static final ResourceLocation mapIcons = new ResourceLocation("textures/map/map_icons.png");
-
- public static Framebuffer mapFramebuffer1 = null;
- public static Framebuffer mapFramebuffer2 = null;
- public static Matrix4f projectionMatrix = null;
- public static Shader mapShader = null;
-
- private static Framebuffer checkFramebufferSizes(Framebuffer framebuffer, int width, int height) {
- if (framebuffer == null || framebuffer.framebufferWidth != width || framebuffer.framebufferHeight != height) {
- if (framebuffer == null) {
- framebuffer = new Framebuffer(width, height, true);
- } else {
- framebuffer.createBindFramebuffer(width, height);
- }
- framebuffer.setFramebufferFilter(GL11.GL_NEAREST);
- }
- return framebuffer;
- }
-
- private static void upload(Shader shader, int width, int height, int scale, float radiusSq) {
- if (shader == null) return;
- shader.getShaderManager().getShaderUniformOrDefault("ProjMat").set(projectionMatrix);
- shader.getShaderManager().getShaderUniformOrDefault("InSize").set(width * scale, height * scale);
- shader.getShaderManager().getShaderUniformOrDefault("OutSize").set(width, height);
- shader.getShaderManager().getShaderUniformOrDefault("ScreenSize").set((float) width, (float) height);
- shader.getShaderManager().getShaderUniformOrDefault("radiusSq").set(radiusSq);
- }
-
- public int getRenderRoomSize() {
- double roomSizeOption = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmRoomSize;
- if (roomSizeOption <= 0) return 12;
- return 12 + (int) Math.round(roomSizeOption * 4);
- }
-
- public int getRenderConnSize() {
- int roomSizeOption = Math.round(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmRoomSize);
- if (roomSizeOption <= 0) return 3;
- return 3 + roomSizeOption;
- }
-
- private final HashMap<Integer, Float> borderRadiusCache = new HashMap<>();
-
- public float getBorderRadius() {
- int borderSizeOption = Math.round(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
- String sizeId = borderSizeOption == 0 ? "small" : borderSizeOption == 2 ? "large" : "medium";
-
- int style = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderStyle;
- if (borderRadiusCache.containsKey(style)) {
- return borderRadiusCache.get(style);
- }
-
- try (
- BufferedReader reader = new BufferedReader(new InputStreamReader(Minecraft
- .getMinecraft()
- .getResourceManager()
- .getResource(
- new ResourceLocation("notenoughupdates:dungeon_map/borders/" + sizeId + "/" + style + ".json"))
- .getInputStream(), StandardCharsets.UTF_8))
- ) {
- JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class);
- float radiusSq = json.get("radiusSq").getAsFloat();
-
- borderRadiusCache.put(style, radiusSq);
- return radiusSq;
- } catch (Exception ignored) {
- }
-
- borderRadiusCache.put(style, 1f);
- return 1f;
- }
-
- public void render(int centerX, int centerY) {
- boolean useFb = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCompat <= 1 && OpenGlHelper.isFramebufferEnabled();
- boolean useShd = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCompat <= 0 && OpenGlHelper.areShadersSupported();
-
- /*if((useFb && !OpenGlHelper.isFramebufferEnabled()) || (useShd && !OpenGlHelper.areShadersSupported())) {
- Utils.drawStringCentered(EnumChatFormatting.RED+"NEU Dungeon Map requires framebuffers & shaders",
- Minecraft.getMinecraft().fontRendererObj, centerX, centerY-10, true, 0);
- Utils.drawStringCentered(EnumChatFormatting.RED+"Turn off Optifine Fast Render",
- Minecraft.getMinecraft().fontRendererObj, centerX, centerY, true, 0);
- Utils.drawStringCentered(EnumChatFormatting.RED+"If that doesn't work, join NEU discord for support",
- Minecraft.getMinecraft().fontRendererObj, centerX, centerY+10, true, 0);
- return;
- }*/
-
- ScaledResolution scaledResolution = Utils.pushGuiScale(2);
-
- int minRoomX = 999;
- int minRoomY = 999;
- int maxRoomX = -999;
- int maxRoomY = -999;
- for (RoomOffset offset : roomMap.keySet()) {
- minRoomX = Math.min(offset.x, minRoomX);
- minRoomY = Math.min(offset.y, minRoomY);
- maxRoomX = Math.max(offset.x, maxRoomX);
- maxRoomY = Math.max(offset.y, maxRoomY);
- }
-
- int borderSizeOption = Math.round(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
-
- int renderRoomSize = getRenderRoomSize();
- int renderConnSize = getRenderConnSize();
-
- MapPosition playerPos = null;
- if (playerEntityMapPositions.containsKey(Minecraft.getMinecraft().thePlayer.getName())) {
- playerPos = playerEntityMapPositions.get(Minecraft.getMinecraft().thePlayer.getName());
- } else if (playerMarkerMapPositions.containsKey(Minecraft.getMinecraft().thePlayer.getName())) {
- playerPos = playerMarkerMapPositions.get(Minecraft.getMinecraft().thePlayer.getName());
- }
-
- int rotation = 180;
- if (playerPos != null && NotEnoughUpdates.INSTANCE.config.dungeonMap.dmRotatePlayer) {
- rotation = (int) playerPos.rotation;
- }
-
- int mapSizeX;
- int mapSizeY;
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderStyle <= 1) {
- mapSizeX = 80 + Math.round(40 * NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
- } else {
- mapSizeX = borderSizeOption == 0 ? 90 : borderSizeOption == 1 ? 120 : borderSizeOption == 2 ? 160 : 240;
- }
- mapSizeY = mapSizeX;
- int roomsSizeX = (maxRoomX - minRoomX) * (renderRoomSize + renderConnSize) + renderRoomSize;
- int roomsSizeY = (maxRoomY - minRoomY) * (renderRoomSize + renderConnSize) + renderRoomSize;
- int mapCenterX = mapSizeX / 2;
- int mapCenterY = mapSizeY / 2;
- int scaleFactor = 8;
-
- projectionMatrix = Utils.createProjectionMatrix(mapSizeX * scaleFactor, mapSizeY * scaleFactor);
- mapFramebuffer1 = checkFramebufferSizes(mapFramebuffer1, mapSizeX * scaleFactor, mapSizeY * scaleFactor);
- mapFramebuffer2 = checkFramebufferSizes(mapFramebuffer2, mapSizeX * scaleFactor, mapSizeY * scaleFactor);
- mapFramebuffer1.framebufferColor[1] = 0;
- mapFramebuffer1.framebufferColor[2] = 0;
-
- try {
- if (mapShader == null) {
- mapShader = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()),
- "dungeonmap", mapFramebuffer1, mapFramebuffer2
- );
- }
- } catch (Exception e) {
- e.printStackTrace();
- Utils.pushGuiScale(-1);
- return;
- }
-
- int backgroundColour =
- SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundColour);
-
- mapFramebuffer1.framebufferColor[0] = ((backgroundColour >> 16) & 0xFF) / 255f;
- mapFramebuffer1.framebufferColor[1] = ((backgroundColour >> 8) & 0xFF) / 255f;
- mapFramebuffer1.framebufferColor[2] = (backgroundColour & 0xFF) / 255f;
- mapFramebuffer2.framebufferColor[0] = ((backgroundColour >> 16) & 0xFF) / 255f;
- mapFramebuffer2.framebufferColor[1] = ((backgroundColour >> 8) & 0xFF) / 255f;
- mapFramebuffer2.framebufferColor[2] = (backgroundColour & 0xFF) / 255f;
-
- try {
- if (useFb) {
- mapFramebuffer1.framebufferClear();
- mapFramebuffer2.framebufferClear();
- }
-
- GlStateManager.pushMatrix();
- {
- if (useFb) {
- GlStateManager.matrixMode(5889);
- GlStateManager.loadIdentity();
- GlStateManager.ortho(0.0D, mapSizeX * scaleFactor, mapSizeY * scaleFactor, 0.0D, 1000.0D, 3000.0D);
- GlStateManager.matrixMode(5888);
- GlStateManager.loadIdentity();
- GlStateManager.translate(0.0F, 0.0F, -2000.0F);
-
- GlStateManager.scale(scaleFactor, scaleFactor, 1);
- mapFramebuffer1.bindFramebuffer(true);
-
- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
- GlStateManager.disableBlend();
- } else {
- GL11.glEnable(GL11.GL_SCISSOR_TEST);
- GL11.glScissor(
- (centerX - mapSizeX / 2) * 2,
- Minecraft.getMinecraft().displayHeight - (centerY + mapSizeY / 2) * 2,
- mapSizeX * 2,
- mapSizeY * 2
- );
-
- GlStateManager.translate(centerX - mapSizeX / 2, centerY - mapSizeY / 2, 100);
- }
-
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur > 0.1 &&
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur < 100 &&
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmEnable) {
- GlStateManager.translate(-centerX + mapSizeX / 2, -centerY + mapSizeY / 2, 0);
- BackgroundBlur.renderBlurredBackground(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur,
- scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(),
- centerX - mapSizeX / 2, centerY - mapSizeY / 2, mapSizeX, mapSizeY
- );
- BackgroundBlur.markDirty();
- GlStateManager.translate(centerX - mapSizeX / 2, centerY - mapSizeY / 2, 0);
- }
-
- GlStateManager.translate(mapCenterX, mapCenterY, 10);
-
- if (!useFb || NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur > 0.1 &&
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur < 100) {
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(
- GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA,
- GL11.GL_ONE,
- GL11.GL_ONE_MINUS_SRC_ALPHA
- );
- }
- Utils.drawRectNoBlend(-mapCenterX, -mapCenterY, mapCenterX, mapCenterY, backgroundColour);
-
- GlStateManager.rotate(-rotation + 180, 0, 0, 1);
-
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterPlayer && playerPos != null) {
- float x = playerPos.getRenderX(0);
- float y = playerPos.getRenderY(0);
- x -= minRoomX * (renderRoomSize + renderConnSize);
- y -= minRoomY * (renderRoomSize + renderConnSize);
-
- GlStateManager.translate(-x, -y, 0);
- } else {
- GlStateManager.translate(-roomsSizeX / 2, -roomsSizeY / 2, 0);
- }
-
- for (Map.Entry<RoomOffset, Room> entry : roomMap.entrySet()) {
- RoomOffset roomOffset = entry.getKey();
- Room room = entry.getValue();
-
- int x = (roomOffset.x - minRoomX) * (renderRoomSize + renderConnSize);
- int y = (roomOffset.y - minRoomY) * (renderRoomSize + renderConnSize);
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(x, y, 0);
-
- room.render(renderRoomSize, renderConnSize);
-
- GlStateManager.translate(-x, -y, 0);
- GlStateManager.popMatrix();
- }
-
- GlStateManager.translate(-mapCenterX + roomsSizeX / 2f, -mapCenterY + roomsSizeY / 2f, 0);
-
- GlStateManager.translate(mapCenterX, mapCenterY, 0);
- GlStateManager.rotate(rotation - 180, 0, 0, 1);
- GlStateManager.translate(-mapCenterX, -mapCenterY, 0);
-
- GlStateManager.translate(mapCenterX, mapCenterY, 0);
-
- for (Map.Entry<RoomOffset, Room> entry : roomMap.entrySet()) {
- RoomOffset roomOffset = entry.getKey();
- Room room = entry.getValue();
-
- float x =
- (roomOffset.x - minRoomX) * (renderRoomSize + renderConnSize) - roomsSizeX / 2f + renderRoomSize / 2f;
- float y =
- (roomOffset.y - minRoomY) * (renderRoomSize + renderConnSize) - roomsSizeY / 2f + renderRoomSize / 2f;
- float x2 = (float) (-x * Math.cos(Math.toRadians(-rotation)) + y * Math.sin(Math.toRadians(-rotation)));
- float y2 = (float) (-x * Math.sin(Math.toRadians(-rotation)) - y * Math.cos(Math.toRadians(-rotation)));
-
- GlStateManager.pushMatrix();
- GlStateManager.translate(x2, y2, 0);
-
- GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
- room.renderNoRotate(renderRoomSize, renderConnSize, rotation);
-
- GlStateManager.translate(-x2, -y2, 0);
- GlStateManager.popMatrix();
- }
-
- GlStateManager.translate(-mapCenterX, -mapCenterY, 0);
-
- GlStateManager.translate(mapCenterX, mapCenterY, 0);
- GlStateManager.rotate(-rotation + 180, 0, 0, 1);
- GlStateManager.translate(-mapCenterX, -mapCenterY, 0);
-
- GlStateManager.translate(mapCenterX - roomsSizeX / 2f, mapCenterY - roomsSizeY / 2f, 0);
-
- Tessellator tessellator = Tessellator.getInstance();
- WorldRenderer worldrenderer = tessellator.getWorldRenderer();
- int k = 0;
-
- for (Map.Entry<String, MapPosition> entry : playerMarkerMapPositions.entrySet()) {
- String name = entry.getKey();
- MapPosition pos = entry.getValue();
- float x = pos.getRenderX(0);
- float y = pos.getRenderY(0);
- float angle = pos.rotation;
-
- boolean doInterp = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerInterp;
- if (!isFloorOne && playerEntityMapPositions.containsKey(name)) {
- MapPosition entityPos = playerEntityMapPositions.get(name);
- angle = entityPos.rotation;
-
- float deltaX = entityPos.getRenderX(9) - pos.getRenderX(0);
- float deltaY = entityPos.getRenderY(9) - pos.getRenderY(0);
-
- x += deltaX;
- y += deltaY;
-
- doInterp = false;
- }
-
- float minU = 3 / 4f;
- float minV = 0;
-
- if (name.equals(Minecraft.getMinecraft().thePlayer.getName())) {
- minU = 1 / 4f;
- }
-
- float maxU = minU + 1 / 4f;
- float maxV = minV + 1 / 4f;
-
- if (doInterp && playerMarkerMapPositionsLast.containsKey(name)) {
- MapPosition last = playerMarkerMapPositionsLast.get(name);
- float xLast = last.getRenderX(0);
- float yLast = last.getRenderY(0);
-
- float distSq = (x - xLast) * (x - xLast) + (y - yLast) * (y - yLast);
- if (distSq < renderRoomSize * renderRoomSize / 4f) {
- float angleLast = last.rotation;
- if (angle > 180 && angleLast < 180) angleLast += 360;
- if (angleLast > 180 && angle < 180) angle += 360;
-
- float interpFactor = Math.round((System.currentTimeMillis() - lastDecorationsMillis) * 100f) / 100f /
- (lastDecorationsMillis - lastLastDecorationsMillis);
- interpFactor = Math.max(0, Math.min(1, interpFactor));
-
- x = xLast + (x - xLast) * interpFactor;
- y = yLast + (y - yLast) * interpFactor;
- angle = angleLast + (angle - angleLast) * interpFactor;
- angle %= 360;
- }
- }
-
- boolean blackBorder = false;
- boolean headLayer = false;
- int pixelWidth = 8;
- int pixelHeight = 8;
- if (renderRoomSize >= 24) {
- pixelWidth = pixelHeight = 12;
- }
- GlStateManager.color(1, 1, 1, 1);
- if ((!NotEnoughUpdates.INSTANCE.config.dungeons.showOwnHeadAsMarker ||
- playerMarkerMapPositions.size() <= 1 || minU != 1 / 4f) &&
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerHeads >= 1 &&
- playerSkinMap.containsKey(entry.getKey())) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(playerSkinMap.get(entry.getKey()));
-
- minU = 8 / 64f;
- minV = 8 / 64f;
- maxU = 16 / 64f;
- maxV = 16 / 64f;
-
- headLayer = true;
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerHeads >= 2) {
- blackBorder = true;
- }
- } else {
- Minecraft.getMinecraft().getTextureManager().bindTexture(mapIcons);
- }
-
- x -= minRoomX * (renderRoomSize + renderConnSize);
- y -= minRoomY * (renderRoomSize + renderConnSize);
-
- GlStateManager.pushMatrix();
-
- GlStateManager.disableDepth();
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(
- GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA,
- GL11.GL_ONE,
- GL11.GL_ONE_MINUS_SRC_ALPHA
- );
-
- GlStateManager.translate(x, y, -0.02F);
- GlStateManager.scale(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale,
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale, 1
- );
- GlStateManager.rotate(angle, 0.0F, 0.0F, 1.0F);
- GlStateManager.translate(-0.5F, 0.5F, 0.0F);
-
- if (blackBorder) {
- Gui.drawRect(
- -pixelWidth / 2 - 1,
- -pixelHeight / 2 - 1,
- pixelWidth / 2 + 1,
- pixelHeight / 2 + 1,
- 0xff111111
- );
- GlStateManager.color(1, 1, 1, 1);
- }
-
- worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
- worldrenderer.pos(-pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(minU, minV).endVertex();
- worldrenderer.pos(pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(maxU, minV).endVertex();
- worldrenderer.pos(pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(maxU, maxV).endVertex();
- worldrenderer
- .pos(-pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F))
- .tex(minU, maxV)
- .endVertex();
- tessellator.draw();
-
- if (headLayer) {
- worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
- worldrenderer.pos(-pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f).tex(
- minU + 0.5f,
- minV
- ).endVertex();
- worldrenderer.pos(pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f).tex(
- maxU + 0.5f,
- minV
- ).endVertex();
- worldrenderer.pos(pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f).tex(
- maxU + 0.5f,
- maxV
- ).endVertex();
- worldrenderer.pos(-pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f).tex(
- minU + 0.5f,
- maxV
- ).endVertex();
- tessellator.draw();
- }
- GlStateManager.popMatrix();
- k--;
- }
-
- if (useFb) {
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(
- GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA,
- GL11.GL_ONE,
- GL11.GL_ONE_MINUS_SRC_ALPHA
- );
- } else {
- GL11.glDisable(GL11.GL_SCISSOR_TEST);
- }
- }
- GlStateManager.popMatrix();
-
- if (useFb) {
- Framebuffer renderFromBuffer = mapFramebuffer1;
- if (useShd) {
- GlStateManager.pushMatrix();
- {
- try {
- upload(mapShader, mapSizeX, mapSizeY, scaleFactor, getBorderRadius());
- mapShader.setProjectionMatrix(projectionMatrix);
- mapShader.loadShader(0);
- renderFromBuffer = mapFramebuffer2;
- } catch (Exception ignored) {
- }
- }
- GlStateManager.popMatrix();
- }
-
- Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
-
- Utils.pushGuiScale(2);
-
- GlStateManager.translate(centerX, centerY, 100);
-
- renderFromBuffer.bindFramebufferTexture();
- Utils.drawTexturedRect(-mapSizeX / 2, -mapSizeY / 2, mapSizeX, mapSizeY,
- 0, 1, 1, 0, GL11.GL_NEAREST
- );
- GlStateManager.bindTexture(0);
-
- GlStateManager.translate(-centerX, -centerY, -100);
-
- Utils.pushGuiScale(-1);
- }
-
- GlStateManager.translate(centerX, centerY, 100);
-
- if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmChromaBorder) {
- int colour = SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderColour);
-
- Gui.drawRect(-mapCenterX - 2, -mapCenterY - 2, -mapCenterX, -mapCenterY,
- colour
- ); //topleft
- Gui.drawRect(-mapCenterX - 2, mapCenterY + 2, -mapCenterX, mapCenterY,
- SpecialColour.rotateHue(colour, -180)
- ); //bottomleft
- Gui.drawRect(mapCenterX, -mapCenterY - 2, mapCenterX + 2, mapCenterY,
- SpecialColour.rotateHue(colour, -180)
- ); //topright
- Gui.drawRect(mapCenterX, mapCenterY, mapCenterX + 2, mapCenterY + 2,
- colour
- ); //bottomright
-
- for (int i = 0; i < 20; i++) {
- int start1 = SpecialColour.rotateHue(colour, -9 * i);
- int start2 = SpecialColour.rotateHue(colour, -9 * i - 9);
- int end1 = SpecialColour.rotateHue(colour, -180 - 9 * i);
- int end2 = SpecialColour.rotateHue(colour, -180 - 9 * i - 9);
-
- Utils.drawGradientRect(-mapCenterX - 2, -mapCenterY + (int) (mapSizeY * (i / 20f)), -mapCenterX,
- -mapCenterY + (int) (mapSizeY * ((i + 1) / 20f)), start1, start2
- ); //left
- Utils.drawGradientRect(mapCenterX, -mapCenterY + (int) (mapSizeX * (i / 20f)), mapCenterX + 2,
- -mapCenterY + (int) (mapSizeX * ((i + 1) / 20f)),
- end1, end2
- ); //right
- Utils.drawGradientRectHorz(-mapCenterX + (int) (mapSizeX * (i / 20f)), -mapCenterY - 2,
- -mapCenterX + (int) (mapSizeX * ((i + 1) / 20f)), -mapCenterY, start1, start2
- ); //top
- Utils.drawGradientRectHorz(-mapCenterX + (int) (mapSizeX * (i / 20f)),
- mapCenterY, -mapCenterX + (int) (mapSizeX * ((i + 1) / 20f)), mapCenterY + 2,
- end1, end2
- ); //bottom
- }
-
- } else {
- Gui.drawRect(-mapCenterX - 2, -mapCenterY, -mapCenterX, mapCenterY,
- SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderColour)
- ); //left
- Gui.drawRect(mapCenterX, -mapCenterY, mapCenterX + 2, mapCenterY,
- SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderColour)
- ); //right
- Gui.drawRect(-mapCenterX - 2, -mapCenterY - 2, mapCenterX + 2, -mapCenterY,
- SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderColour)
- ); //top
- Gui.drawRect(-mapCenterX - 2, mapCenterY, mapCenterX + 2, mapCenterY + 2,
- SpecialColour.specialToChromaRGB(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderColour)
- ); //bottom
- }
-
- String sizeId = borderSizeOption == 0 ? "small" : borderSizeOption == 2 ? "large" : "medium";
-
- ResourceLocation rl = new ResourceLocation("notenoughupdates:dungeon_map/borders/" + sizeId + "/" +
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderStyle + ".png");
- if (Minecraft.getMinecraft().getTextureManager().getTexture(rl) != TextureUtil.missingTexture) {
- Minecraft.getMinecraft().getTextureManager().bindTexture(rl);
- GlStateManager.color(1, 1, 1, 1);
-
- int size = borderSizeOption == 0 ? 165 : borderSizeOption == 1 ? 220 : borderSizeOption == 2 ? 300 : 440;
- Utils.drawTexturedRect(-size / 2, -size / 2, size, size, GL11.GL_NEAREST);
- }
-
- GlStateManager.translate(-centerX, -centerY, -100);
- } catch (Exception e) {
- e.printStackTrace();
- Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
- Minecraft.getMinecraft().entityRenderer.setupOverlayRendering();
- }
-
- Utils.pushGuiScale(-1);
-
- GlStateManager.enableBlend();
- GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
- GlStateManager.enableDepth();
- GlStateManager.disableLighting();
- }
-
- public void updateRoomConnections(RoomOffset roomOffset) {
- if (roomMap.containsKey(roomOffset)) {
- Room room = roomMap.get(roomOffset);
-
- int otherPixelFilled = 0;
- int otherPixelColour = 0;
- for (int xOff = 0; xOff < roomSize; xOff++) {
- for (int yOff = 0; yOff < roomSize; yOff++) {
- int x = startRoomX + roomOffset.x * (roomSize + connectorSize) + xOff;
- int y = startRoomY + roomOffset.y * (roomSize + connectorSize) + yOff;
-
- if (x > 0 && y > 0 && x < colourMap.length && y < colourMap[x].length) {
- Color c = colourMap[x][y];
- if (!c.equals(room.colour)) {
- if (otherPixelColour == c.getRGB()) {
- otherPixelFilled++;
- } else {
- otherPixelFilled--;
- if (otherPixelFilled <= 0) {
- otherPixelFilled = 1;
- otherPixelColour = c.getRGB();
- }
- }
- }
- }
- }
- }
-
- room.tickColour = 0;
- if ((float) otherPixelFilled / roomSize / connectorSize > 0.05) {
- room.tickColour = otherPixelColour;
- }
-
- for (int k = 0; k < 4; k++) {
- Color colour = null;
- int totalFilled = 0;
-
- for (int i = 0; i < roomSize; i++) {
- for (int j = 1; j <= connectorSize; j++) {
- int x = startRoomX + roomOffset.x * (roomSize + connectorSize);
- int y = startRoomY + roomOffset.y * (roomSize + connectorSize);
-
- if (k == 0) {
- x += i;
- y -= j;
- } else if (k == 1) {
- x += roomSize + j - 1;
- y += i;
- } else if (k == 2) {
- x += i;
- y += roomSize + j - 1;
- } else {
- x -= j;
- y += i;
- }
-
- if (x > 0 && y > 0 && x < colourMap.length && y < colourMap[x].length) {
- Color pixel = colourMap[x][y];
- if (pixel.getAlpha() > 40) {
- if (colour == null) {
- colour = pixel;
- totalFilled = 1;
- } else {
- if (colour.equals(pixel)) {
- totalFilled++;
- } else {
- totalFilled--;
- if (totalFilled <= 0) {
- colour = pixel;
- totalFilled = 1;
- }
- }
- }
- }
- }
- }
- }
- float proportionFilled = (float) totalFilled / roomSize / connectorSize;
-
- RoomConnectionType type = RoomConnectionType.WALL;
- if (proportionFilled > 0.8) {
- type = RoomConnectionType.ROOM_DIVIDER;
- } else if (proportionFilled > 0.1) {
- type = RoomConnectionType.CORRIDOR;
- }
- if (k == 0) {
- room.up = new RoomConnection(type, colour);
- } else if (k == 1) {
- room.right = new RoomConnection(type, colour);
- } else if (k == 2) {
- room.down = new RoomConnection(type, colour);
- } else {
- room.left = new RoomConnection(type, colour);
- }
- }
-
- int x = startRoomX + roomOffset.x * (roomSize + connectorSize) + roomSize + connectorSize / 2;
- int y = startRoomY + roomOffset.y * (roomSize + connectorSize) + roomSize + connectorSize / 2;
-
- room.fillCorner = false;
- if (x > 0 && y > 0 && x < colourMap.length && y < colourMap[x].length) {
- Color pixel = colourMap[x][y];
- if (pixel.equals(room.colour)) {
- room.fillCorner = true;
- }
- }
- }
- }
-
- public void loadNeighbors(RoomOffset room) {
- if (!roomMap.containsKey(room)) {
- roomMap.put(room, new Room());
- }
- for (RoomOffset neighbor : room.getNeighbors()) {
- if (!roomMap.containsKey(neighbor)) {
- int x = startRoomX + neighbor.x * (roomSize + connectorSize);
- int y = startRoomY + neighbor.y * (roomSize + connectorSize);
-
- if (x >= 0 && y >= 0 && x + roomSize < colourMap.length && y + roomSize < colourMap[x].length) {
- if (colourMap[x][y].getAlpha() > 100) {
- roomMap.put(neighbor, new Room());
- loadNeighbors(neighbor);
- }
- }
- }
- }
- }
-
- public void updateRoomColours() {
- for (Map.Entry<RoomOffset, Room> entry : roomMap.entrySet()) {
- int x = startRoomX + entry.getKey().x * (roomSize + connectorSize);
- int y = startRoomY + entry.getKey().y * (roomSize + connectorSize);
-
- try {
- entry.getValue().colour = colourMap[x][y];
- } catch (Exception ignored) {
- }
- }
- }
-
- private class MapPosition {
- public float roomOffsetX;
- public float connOffsetX;
-
- public float roomOffsetY;
- public float connOffsetY;
-
- public float rotation;
-
- public MapPosition(float roomOffsetX, float connOffsetX, float roomOffsetY, float connOffsetY) {
- this.roomOffsetX = roomOffsetX;
- this.connOffsetX = connOffsetX;
- this.roomOffsetY = roomOffsetY;
- this.connOffsetY = connOffsetY;
- }
-
- public float getRenderX(int blockOffset) {
- return (roomOffsetX + blockOffset) * getRenderRoomSize() + connOffsetX * getRenderConnSize();
- }
-
- public float getRenderY(int blockOffset) {
- return (roomOffsetY + blockOffset) * getRenderRoomSize() + connOffsetY * getRenderConnSize();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- MapPosition that = (MapPosition) o;
- return Float.compare(that.roomOffsetX, roomOffsetX) == 0 &&
- Float.compare(that.connOffsetX, connOffsetX) == 0 &&
- Float.compare(that.roomOffsetY, roomOffsetY) == 0 &&
- Float.compare(that.connOffsetY, connOffsetY) == 0 &&
- Float.compare(that.rotation, rotation) == 0;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(roomOffsetX, connOffsetX, roomOffsetY, connOffsetY, rotation);
- }
- }
-
- private boolean isFloorOne = false;
- private boolean failMap = false;
- private long lastClearCache = 0;
-
- public void renderMap(
- int centerX, int centerY, Color[][] colourMap, Map<String, Vec4b> mapDecorations,
- int roomSizeBlocks, Set<String> actualPlayers, boolean usePlayerPositions, float partialTicks
- ) {
- if (!NotEnoughUpdates.INSTANCE.config.dungeonMap.dmEnable) return;
- if (colourMap == null) return;
- if (colourMap.length != 128) return;
- if (colourMap[0].length != 128) return;
- this.colourMap = colourMap;
-
- boolean searchForPlayers = false;
- if (System.currentTimeMillis() - lastClearCache > 1000) {
- roomMap.clear();
- searchForPlayers = true;
- startRoomX = -1;
- startRoomY = -1;
- connectorSize = -1;
- roomSize = -1;
- borderRadiusCache.clear();
- failMap = false;
-
- lastClearCache = System.currentTimeMillis();
-
- isFloorOne = false;
- Scoreboard scoreboard = Minecraft.getMinecraft().thePlayer.getWorldScoreboard();
-
- ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1);
-
- List<Score> scores = new ArrayList<>(scoreboard.getSortedScores(sidebarObjective));
-
- for (int i = scores.size() - 1; i >= 0; i--) {
- Score score = scores.get(i);
- ScorePlayerTeam scoreplayerteam1 = scoreboard.getPlayersTeam(score.getPlayerName());
- String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName());
- line = Utils.cleanColour(line);
-
- if (line.contains("(F1)") || line.contains("(E)") || line.contains("(M1)")) {
- isFloorOne = true;
- break;
- }
- }
- }
-
- if (failMap) {
- return;
- }
-
- int alphaPixels = 0;
- for (int x = 0; x < 128; x++) {
- for (int y = 0; y < 128; y++) {
- Color c = colourMap[x][y];
- if (c == null) {
- return;
- } else if (c.getAlpha() < 50) {
- alphaPixels++;
- }
- }
- }
- if (alphaPixels < 128 * 128 / 10) {
- failMap = true;
- return;
- }
-
- if (startRoomX < 0 || startRoomY < 0 || roomSize <= 0) {
- for (int x = 0; x < colourMap.length; x++) {
- for (int y = 0; y < colourMap[x].length; y++) {
- Color c = colourMap[x][y];
- if (c.getAlpha() > 80) {
- if (startRoomX < 0 && startRoomY < 0 && c.getRed() == 0 && c.getGreen() == 124 && c.getBlue() == 0) {
- roomSize = 0;
- out:
- for (int xd = 0; xd <= 20; xd++) {
- for (int yd = 0; yd <= 20; yd++) {
- if (x + xd >= colourMap.length || y + yd >= colourMap[x + xd].length) continue;
- Color c2 = colourMap[x + xd][y + yd];
-
- if (c2.getGreen() != 124 || c2.getAlpha() <= 80) {
- if (xd < 10 && yd < 10) {
- break out;
- }
- } else {
- roomSize = Math.max(roomSize, Math.min(xd + 1, yd + 1));
- }
- if (xd == 20 && yd == 20) {
- if (roomSize == 0) roomSize = 20;
- startRoomX = x;
- startRoomY = y;
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (startRoomX < 0 || startRoomY < 0) {
- failMap = true;
- return;
- }
-
- if (connectorSize <= 0) {
- for (int i = 0; i < roomSize; i++) {
- for (int k = 0; k < 4; k++) {
- for (int j = 1; j < 8; j++) {
- int x;
- int y;
-
- if (k == 0) {
- x = startRoomX + i;
- y = startRoomY - j;
- } else if (k == 1) {
- x = startRoomX + roomSize + j - 1;
- y = startRoomY + i;
- } else if (k == 2) {
- x = startRoomX + i;
- y = startRoomY + roomSize + j - 1;
- } else {
- x = startRoomX - j;
- y = startRoomY + i;
- }
-
- if (x > 0 && y > 0 && x < colourMap.length && y < colourMap[x].length) {
- if (colourMap[x][y].getAlpha() > 80) {
- if (j == 1) {
- break;
- }
- connectorSize = Math.min(connectorSize, j - 1);
- }
- }
- }
- }
- }
-
- if (connectorSize <= 0) {
- connectorSize = 4;
- }
- }
-
- actualPlayers.add(Minecraft.getMinecraft().thePlayer.getName());
- if (searchForPlayers) {
- for (EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) {
- if (player instanceof AbstractClientPlayer && actualPlayers.contains(player.getName())) {
- AbstractClientPlayer aplayer = (AbstractClientPlayer) player;
- ResourceLocation skin = aplayer.getLocationSkin();
- if (skin != DefaultPlayerSkin.getDefaultSkin(aplayer.getUniqueID())) {
- playerSkinMap.put(player.getName(), skin);
- playerIdMap.put(player.getName(), player.getEntityId());
- }
- }
- }
- }
-
- playerEntityMapPositions.clear();
- if (usePlayerPositions) {
- for (String playerName : actualPlayers) {
- if (playerIdMap.containsKey(playerName)) {
- Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(playerIdMap.get(playerName));
- if (entity instanceof EntityPlayer) {
- EntityPlayer player = (EntityPlayer) entity;
-
- float roomX = (float) player.posX / (roomSizeBlocks + 1);
- float roomY = (float) player.posZ / (roomSizeBlocks + 1);
-
- float playerRoomOffsetX = (float) Math.floor(roomX);
- float playerConnOffsetX = (float) Math.floor(roomX);
- float playerRoomOffsetY = (float) Math.floor(roomY);
- float playerConnOffsetY = (float) Math.floor(roomY);
-
- float roomXInBlocks = (float) player.posX % (roomSizeBlocks + 1);
- if (roomXInBlocks < 2) { //0,1
- playerConnOffsetX -= 2 / 5f - roomXInBlocks / 5f;
- } else if (roomXInBlocks > roomSizeBlocks - 2) { //31,30,29
- playerRoomOffsetX++;
- playerConnOffsetX += (roomXInBlocks - (roomSizeBlocks - 2)) / 5f;
- } else {
- playerRoomOffsetX += (roomXInBlocks - 2) / (roomSizeBlocks - 4);
- }
-
- float roomYInBlocks = (float) player.posZ % (roomSizeBlocks + 1);
- if (roomYInBlocks < 2) { //0,1
- playerConnOffsetY -= 2 / 5f - roomYInBlocks / 5f;
- } else if (roomYInBlocks > roomSizeBlocks - 2) { //31,30,29
- playerRoomOffsetY++;
- playerConnOffsetY += (roomYInBlocks - (roomSizeBlocks - 2)) / 5f;
- } else {
- playerRoomOffsetY += (roomYInBlocks - 2) / (roomSizeBlocks - 4);
- }
-
- playerRoomOffsetX -= startRoomX / (roomSize + connectorSize);
- playerRoomOffsetY -= startRoomY / (roomSize + connectorSize);
- playerConnOffsetX -= startRoomX / (roomSize + connectorSize);
- playerConnOffsetY -= startRoomY / (roomSize + connectorSize);
-
- MapPosition pos = new MapPosition(
- playerRoomOffsetX,
- playerConnOffsetX,
- playerRoomOffsetY,
- playerConnOffsetY
- );
- pos.rotation =
- (player.prevRotationYawHead + (player.rotationYawHead - player.prevRotationYawHead) * partialTicks) % 360;
- if (pos.rotation < 0) pos.rotation += 360;
- playerEntityMapPositions.put(player.getName(), pos);
- }
- }
- }
- }
-
- loadNeighbors(new RoomOffset(0, 0));
- updateRoomColours();
- for (RoomOffset offset : roomMap.keySet()) {
- updateRoomConnections(offset);
- }
-
- if (roomMap.isEmpty()) {
- failMap = true;
- return;
- }
-
- if (mapDecorations != null && mapDecorations.size() > 0) {
- List<MapPosition> positions = new ArrayList<>();
- int decorations = 0;
- for (Vec4b vec4b : mapDecorations.values()) {
- byte id = vec4b.func_176110_a();
- if (id != 1 && id != 3) continue;
-
- float x = (float) vec4b.func_176112_b() / 2.0F + 64.0F;
- float y = (float) vec4b.func_176113_c() / 2.0F + 64.0F;
-
- if (x < 0 || y < 0 || x > 128 || y > 128) {
- continue;
- }
-
- float deltaX = x - startRoomX;
- float deltaY = y - startRoomY;
-
- float roomsOffsetX = (int) Math.floor(deltaX / (roomSize + connectorSize));
- float connOffsetX = (int) Math.floor(deltaX / (roomSize + connectorSize));
- float xRemainder = deltaX % (roomSize + connectorSize);
- if (Math.abs(xRemainder) > roomSize) {
- roomsOffsetX += Math.copySign(1, xRemainder);
- connOffsetX += Math.copySign(1, xRemainder) * (Math.abs(xRemainder) - roomSize) / connectorSize;
- } else {
- roomsOffsetX += xRemainder / roomSize;
- }
- if (deltaX < 0 && xRemainder != 0) {
- roomsOffsetX++;
- connOffsetX++;
- }
- float roomsOffsetY = (int) Math.floor(deltaY / (roomSize + connectorSize));
- float connOffsetY = (int) Math.floor(deltaY / (roomSize + connectorSize));
- float yRemainder = deltaY % (roomSize + connectorSize);
- if (Math.abs(yRemainder) > roomSize) {
- roomsOffsetY += Math.copySign(1, yRemainder);
- connOffsetY += Math.copySign(1, yRemainder) * (Math.abs(yRemainder) - roomSize) / connectorSize;
- } else {
- roomsOffsetY += yRemainder / roomSize;
- }
- if (deltaY < 0 && yRemainder != 0) {
- roomsOffsetY++;
- connOffsetY++;
- }
-
- float angle = (float) (vec4b.func_176111_d() * 360) / 16.0F;
-
- MapPosition pos = new MapPosition(roomsOffsetX, connOffsetX, roomsOffsetY, connOffsetY);
- pos.rotation = angle % 360;
- if (pos.rotation < 0) pos.rotation += 360;
-
- if (decorations++ <= 6) {
- positions.add(pos);
- }
- rawPlayerMarkerMapPositions.add(pos);
- }
-
- boolean different = playerMarkerMapPositions.size() != positions.size();
-
- if (!different) {
- for (MapPosition pos : playerMarkerMapPositions.values()) {
- if (!positions.contains(pos)) {
- different = true;
- break;
- }
- }
- }
-
- if (different && positions.size() > 0) {
- lastLastDecorationsMillis = lastDecorationsMillis;
- lastDecorationsMillis = System.currentTimeMillis();
-
- playerMarkerMapPositionsLast.clear();
- for (Map.Entry<String, MapPosition> entry : playerMarkerMapPositions.entrySet()) {
- playerMarkerMapPositionsLast.put(entry.getKey(), entry.getValue());
- }
- playerMarkerMapPositions.clear();
-
- Set<String> foundPlayers = new HashSet<>();
- for (Map.Entry<String, MapPosition> entry : playerEntityMapPositions.entrySet()) {
- playerMarkerMapPositions.put(entry.getKey(), entry.getValue());
- playerMarkerMapPositionsLast.put(entry.getKey(), entry.getValue());
- foundPlayers.add(entry.getKey());
- }
-
- HashMap<String, HashMap<Integer, Float>> distanceMap = new HashMap<>();
- for (Map.Entry<String, MapPosition> entry : playerMarkerMapPositionsLast.entrySet()) {
- HashMap<Integer, Float> deltaDists = new HashMap<>();
- for (int i = 0; i < positions.size(); i++) {
- float dx = entry.getValue().getRenderX(0) - positions.get(i).getRenderX(0);
- float dy = entry.getValue().getRenderY(0) - positions.get(i).getRenderY(0);
- deltaDists.put(i, dx * dx + dy * dy);
- }
- distanceMap.put(entry.getKey(), deltaDists);
- }
-
- List<String> playerList = new ArrayList<>(playerMarkerMapPositionsLast.keySet());
- List<List<String>> playerPermutations = permutations(playerList);
-
- List<Integer> finalUsedIndexes = new ArrayList<>();
- if (playerPermutations.size() > 0) {
- HashMap<String, Integer> smallestPermutation = null;
- float smallestTotalDistance = 0;
-
- for (List<String> permutation : playerPermutations) {
- HashMap<String, Integer> usedIndexes = new HashMap<>();
-
- float totalDistance = 0;
- for (String player : permutation) {
- int smallestIndex = -1;
- float smallestDist = 0;
- for (Map.Entry<Integer, Float> entry : distanceMap.get(player).entrySet()) {
- if (!usedIndexes.containsValue(entry.getKey())) {
- if (smallestIndex == -1 || entry.getValue() < smallestDist) {
- smallestIndex = entry.getKey();
- smallestDist = entry.getValue();
- }
- }
- }
- if (smallestIndex != -1) {
- usedIndexes.put(player, smallestIndex);
- totalDistance += smallestDist;
- }
- }
-
- if (smallestPermutation == null || totalDistance < smallestTotalDistance) {
- smallestPermutation = usedIndexes;
- smallestTotalDistance = totalDistance;
- }
- }
-
- //System.out.println("--- PERM START ---");
- for (Map.Entry<String, Integer> entry : smallestPermutation.entrySet()) {
- //System.out.println(entry.getKey() + ":" + entry.getValue() + " : Total dist: " + smallestTotalDistance);
- finalUsedIndexes.add(entry.getValue());
- playerMarkerMapPositions.put(entry.getKey(), positions.get(entry.getValue()));
- }
- }
-
- List<Integer> nonUsedIndexes = new ArrayList<>();
- for (int i = 0; i < positions.size(); i++) {
- if (!finalUsedIndexes.contains(i)) {
- nonUsedIndexes.add(i);
- }
- }
-
- for (String missingPlayer : actualPlayers) {
- if (!playerList.contains(missingPlayer)) {
- if (nonUsedIndexes.isEmpty()) break;
- playerMarkerMapPositions.put(missingPlayer, positions.get(nonUsedIndexes.get(0)));
- nonUsedIndexes.remove(0);
- }
- }
- }
- } else if (mapDecorations == null) {
- playerMarkerMapPositions.clear();
- playerMarkerMapPositionsLast.clear();
-
- for (Map.Entry<String, MapPosition> entry : playerEntityMapPositions.entrySet()) {
- playerMarkerMapPositions.put(entry.getKey(), entry.getValue());
- }
- }
-
- if (!roomMap.isEmpty() && startRoomX >= 0 && startRoomY >= 0) {
- render(centerX, centerY);
- }
-
- this.colourMap = colourMap;
- }
-
- @SubscribeEvent
- public void onWorldChange(WorldEvent.Load event) {
- colourMap = null;
- }
-
- @SubscribeEvent
- public void onRenderOverlay(RenderGameOverlayEvent.Post event) {
- if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
- if (event.type == RenderGameOverlayEvent.ElementType.ALL) {
- if (!NotEnoughUpdates.INSTANCE.config.dungeonMap.dmEnable) return;
-
- if (Minecraft.getMinecraft().gameSettings.showDebugInfo ||
- (Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isKeyDown() &&
- (!Minecraft.getMinecraft().isIntegratedServerRunning() ||
- Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap().size() > 1))) {
- return;
- }
-
- ItemStack stack = Minecraft.getMinecraft().thePlayer.inventory.mainInventory[8];
- boolean holdingBow = stack != null && stack.getItem() == Items.arrow && colourMap != null;
- if (holdingBow || (stack != null && stack.getItem() instanceof ItemMap)) {
- Map<String, Vec4b> decorations = null;
-
- Color[][] colourMap = new Color[128][128];
- if (holdingBow) {
- for (int x = 0; x < 128; x++) {
- for (int y = 0; y < 128; y++) {
- if (this.colourMap[x][y] != null) {
- colourMap[x][y] = this.colourMap[x][y];
- } else {
- colourMap[x][y] = new Color(0, true);
- }
- }
- }
- } else {
- ItemMap map = (ItemMap) stack.getItem();
- MapData mapData = map.getMapData(stack, Minecraft.getMinecraft().theWorld);
-
- if (mapData == null) return;
-
- decorations = mapData.mapDecorations;
-
- for (int i = 0; i < 16384; ++i) {
- int x = i % 128;
- int y = i / 128;
-
- int j = mapData.colors[i] & 255;
-
- Color c;
- if (j / 4 == 0) {
- c = new Color((i + i / 128 & 1) * 8 + 16 << 24, true);
- } else {
- c = new Color(MapColor.mapColorArray[j / 4].getMapColor(j & 3), true);
- }
-
- colourMap[x][y] = c;
- }
- }
-
- int roomSizeBlocks = 31;
- /*List<Integer> dists = new ArrayList<>();
- int currentBlockCount = 0;
- for(int i=0; i<300; i++) {
- IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(new BlockPos(0, 99, i));
- if(state == null || state.getBlock() == Blocks.air) {
- if(currentBlockCount > 0) dists.add(currentBlockCount);
- currentBlockCount = 0;
- } else {
- currentBlockCount++;
- }
- }
- currentBlockCount = 0;
- for(int i=0; i<300; i++) {
- IBlockState state = Minecraft.getMinecraft().theWorld.getBlockState(new BlockPos(i, 99, 0));
- if(state == null || state.getBlock() == Blocks.air) {
- if(currentBlockCount > 0) dists.add(currentBlockCount);
- currentBlockCount = 0;
- } else {
- currentBlockCount++;
- }
- }
- int count = 0;
- int mostCommonDist = -1;
- for(int dist : dists) {
- if(dist == mostCommonDist) {
- count++;
- } else {
- if(--count < 0) {
- count = 1;
- mostCommonDist = dist;
- }
- }
- }
- if(mostCommonDist > 31) roomSizeBlocks = mostCommonDist;*/
-
- Set<String> actualPlayers = new HashSet<>();
- /*for(EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) {
- if(player.getUniqueID().toString().charAt(14) == '4') {
- actualPlayers.add(player.getName());
- System.out.println(player.getName());
-
- }
- }*/
- int players = 0;
- for (ScorePlayerTeam team : Minecraft.getMinecraft().thePlayer.getWorldScoreboard().getTeams()) {
- if (team.getTeamName().startsWith("a") && team.getMembershipCollection().size() == 1) {
- String playerName = Iterables.get(team.getMembershipCollection(), 0);
- boolean foundPlayer = false;
- for (EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) {
- if (player.getName().equals(playerName) &&
- (player == Minecraft.getMinecraft().thePlayer || !player.isPlayerSleeping())) {
- actualPlayers.add(playerName);
- foundPlayer = true;
- break;
- }
- }
- if (!foundPlayer) actualPlayers.add(playerName);
- if (++players >= 6) break;
- }
- }
-
- Position pos = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition;
-
- int size = 80 + Math.round(40 * NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
- ScaledResolution scaledResolution = Utils.pushGuiScale(2);
- renderMap(
- pos.getAbsX(scaledResolution, size / 2) + size / 2,
- pos.getAbsY(scaledResolution, size / 2) + size / 2,
- colourMap,
- decorations,
- roomSizeBlocks,
- actualPlayers,
- true,
- event.partialTicks
- );
- Utils.pushGuiScale(-1);
- } else if (stack != null && Item.getIdFromItem(stack.getItem()) == 399) {
- //This should clear the map if you're in the dungeon boss room
- //so when you're holding a bow it doesnt show the map anymore
- this.colourMap = null;
- }
- }
- }
-
- public List<List<String>> permutations(List<String> values) {
- List<List<String>> permutations = new ArrayList<>();
-
- if (values.size() == 1) {
- permutations.add(values);
- return permutations;
- }
-
- for (String first : values) {
- List<String> newList = new ArrayList<>();
- for (String val : values) {
- if (!val.equals(first)) {
- newList.add(val);
- }
- }
-
- for (List<String> list2 : permutations(newList)) {
- List<String> perm = new ArrayList<>();
- perm.add(first);
- perm.addAll(list2);
- permutations.add(perm);
- }
- }
-
- return permutations;
- }
-
- Shader blurShaderHorz = null;
- Framebuffer blurOutputHorz = null;
- Shader blurShaderVert = null;
- Framebuffer blurOutputVert = null;
-
- /**
- * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate
- * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis).
- * <p>
- * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to
- * apply scales and translations manually.
- */
- private Matrix4f createProjectionMatrix(int width, int height) {
- Matrix4f projMatrix = new Matrix4f();
- projMatrix.setIdentity();
- projMatrix.m00 = 2.0F / (float) width;
- projMatrix.m11 = 2.0F / (float) (-height);
- projMatrix.m22 = -0.0020001999F;
- projMatrix.m33 = 1.0F;
- projMatrix.m03 = -1.0F;
- projMatrix.m13 = 1.0F;
- projMatrix.m23 = -1.0001999F;
- return projMatrix;
- }
-}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
index 47e85023..98a31545 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java
@@ -26,6 +26,9 @@ import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption
import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor;
import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils;
import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils;
+import io.github.moulberry.notenoughupdates.dungeons.map.DungeonMap;
+import io.github.moulberry.notenoughupdates.dungeons.map.DungeonMapPlayers;
+import io.github.moulberry.notenoughupdates.dungeons.map.DungeonMapStaticParser;
import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField;
import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig;
import io.github.moulberry.notenoughupdates.util.SpecialColour;
@@ -60,813 +63,739 @@ import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_off_l
import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_on_large;
public class GuiDungeonMapEditor extends GuiScreen {
- public static final ResourceLocation BACKGROUND = new ResourceLocation(
- "notenoughupdates:dungeon_map/editor/background.png");
- public static final ResourceLocation BUTTON = new ResourceLocation("notenoughupdates:dungeon_map/editor/button.png");
- private static final DungeonMap demoMap = new DungeonMap();
-
- private int sizeX;
- private int sizeY;
- private int guiLeft;
- private int guiTop;
-
- private final List<Button> buttons = new ArrayList<>();
-
- private final GuiElementTextField blurField = new GuiElementTextField(
- "",
- GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE
- );
- private GuiElementColour activeColourEditor = null;
-
- private Field clickedSlider;
-
- class Button {
- private final int id;
- private final int x;
- private final int y;
- private String text;
- private Color colour = new Color(-1, true);
- private final Field option;
- private String displayName;
- private String desc;
-
- public Button(int id, int x, int y, String text) {
- this(id, x, y, text, null);
- }
-
- public Button(int id, int x, int y, String text, Field option) {
- this.id = id;
- this.x = x;
- this.y = y;
- this.text = text;
- this.option = option;
-
- if (option != null) {
- ConfigOption optionAnnotation = option.getAnnotation(ConfigOption.class);
- displayName = optionAnnotation.name();
- desc = optionAnnotation.desc();
- }
- }
-
- public List<String> getTooltip() {
- if (option == null) {
- return null;
- }
-
- List<String> tooltip = new ArrayList<>();
- tooltip.add(EnumChatFormatting.YELLOW + displayName);
- for (String line : desc.split("\n")) {
- tooltip.add(EnumChatFormatting.AQUA + line);
- }
- return tooltip;
- }
-
- public void render() {
- if (text == null) return;
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(BUTTON);
- if (isButtonPressed(id)) {
- GlStateManager.color(colour.getRed() * 0.85f / 255f, colour.getGreen() * 0.85f / 255f,
- colour.getBlue() * 0.85f / 255f, 1
- );
- Utils.drawTexturedRect(guiLeft + x, guiTop + y, 48, 16, 1, 0, 1, 0, GL11.GL_NEAREST);
- } else {
- GlStateManager.color(colour.getRed() / 255f, colour.getGreen() / 255f, colour.getBlue() / 255f, 1);
- Utils.drawTexturedRect(guiLeft + x, guiTop + y, 48, 16, GL11.GL_NEAREST);
- }
-
- if (text.length() > 0) {
- Utils.drawStringCenteredScaledMaxWidth(
- text,
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + x + 24,
- guiTop + y + 8,
- false,
- 39,
- 0xFF000000
- );
- }
- }
-
- }
-
- public GuiDungeonMapEditor() {
- DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
- //Map Border Size
- //buttons.add(new Button(0, 6, 37, "Small", options.dmBorderSize));
- //buttons.add(new Button(1, 52, 37, "Medium", options.dmBorderSize));
- //buttons.add(new Button(2, 98, 37, "Large", options.dmBorderSize));
-
- //Map Rooms Size
- //buttons.add(new Button(3, 6, 67+19, "Small", options.dmRoomSize));
- //buttons.add(new Button(4, 52, 67+19, "Medium", options.dmRoomSize));
- //buttons.add(new Button(5, 98, 67+19, "Large", options.dmRoomSize));
-
- //Map Border Styles
- buttons.add(new Button(6, 6, 97 + 30, "None"));
- buttons.add(new Button(7, 52, 97 + 30, "Custom"));
- buttons.add(new Button(8, 98, 97 + 30, "Stone"));
- buttons.add(new Button(9, 6, 116 + 30, "Wood"));
- buttons.add(new Button(10, 52, 116 + 30, "Rustic(S)"));
- buttons.add(new Button(11, 98, 116 + 30, "Rustic(C)"));
- buttons.add(new Button(12, 6, 135 + 30, "Fade"));
- buttons.add(new Button(13, 52, 135 + 30, "Ribbons"));
- buttons.add(new Button(14, 98, 135 + 30, "Paper"));
- buttons.add(new Button(15, 6, 154 + 30, "Crimson"));
- buttons.add(new Button(16, 52, 154 + 30, "Ornate"));
- buttons.add(new Button(17, 98, 154 + 30, "Dragon"));
-
- try {
- //Dungeon Map
- buttons.add(new Button(18, 20 + 139, 36, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmEnable")));
- //Center
- buttons.add(new Button(
- 19,
- 84 + 139,
- 36,
- "Player/Map",
- DungeonMapConfig.class.getDeclaredField("dmCenterPlayer")
- ));
- //Rotate
- buttons.add(new Button(
- 20,
- 20 + 139,
- 65,
- "Player/No Rotate",
- DungeonMapConfig.class.getDeclaredField("dmRotatePlayer")
- ));
- //Icon Style
- buttons.add(new Button(
- 21,
- 84 + 139,
- 65,
- "Default/Heads",
- DungeonMapConfig.class.getDeclaredField("dmPlayerHeads")
- ));
- //Check Orient
- buttons.add(new Button(
- 22,
- 20 + 139,
- 94,
- "Normal/Reorient",
- DungeonMapConfig.class.getDeclaredField("dmOrientCheck")
- ));
- //Check Center
- buttons.add(new Button(23, 84 + 139, 94, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmCenterCheck")));
- //Interpolation
- buttons.add(new Button(24, 20 + 139, 123, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmPlayerInterp")));
- //Compatibility
- buttons.add(new Button(
- 25,
- 84 + 139,
- 123,
- "Normal/No SHD/No FB/SHD",
- DungeonMapConfig.class.getDeclaredField("dmCompat")
- ));
-
- //Background
- buttons.add(new Button(26, 20 + 139, 152, "", DungeonMapConfig.class.getDeclaredField("dmBackgroundColour")));
- //Border
- buttons.add(new Button(27, 84 + 139, 152, "", DungeonMapConfig.class.getDeclaredField("dmBorderColour")));
-
- //Chroma Mode
- buttons.add(new Button(
- 28,
- 84 + 139,
- 181,
- "Normal/Scroll",
- DungeonMapConfig.class.getDeclaredField("dmChromaBorder")
- ));
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- //buttons.add(new Button(29, 52, 86+19, "XLarge", options.dmRoomSize));
- //buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize));
-
- {
- double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur;
- String strVal;
- if (val % 1 == 0) {
- strVal = Integer.toString((int) val);
- } else {
- strVal = Double.toString(val);
- strVal = strVal.replaceAll("(\\.\\d\\d\\d)(?:\\d)+", "$1");
- strVal = strVal.replaceAll("0+$", "");
- }
- blurField.setText(strVal);
- }
- }
-
- @Override
- public void drawScreen(int mouseX, int mouseY, float partialTicks) {
- ScaledResolution scaledResolution = Utils.pushGuiScale(2);
- this.width = scaledResolution.getScaledWidth();
- this.height = scaledResolution.getScaledHeight();
-
- mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth;
- mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
-
- List<String> tooltipToDisplay = null;
- for (Button button : buttons) {
- if (mouseX >= guiLeft + button.x && mouseX <= guiLeft + button.x + 48 &&
- mouseY >= guiTop + button.y - 13 && mouseY <= guiTop + button.y + 16) {
- if (button.id >= 6 && button.id <= 17) {
- String mapDesc = null;
- String mapCredit = null;
- int id = button.id;
- switch (id) {
- case 6:
- mapDesc = "No Border";
- break;
- case 7:
- mapDesc = "Used by custom Resource Packs";
- break;
- case 8:
- mapDesc = "Simple gray border";
- mapCredit = "TomEngMaster";
- break;
- case 9:
- mapDesc = "Viney wood border";
- mapCredit = "iDevil4Hell";
- break;
- case 10:
- mapDesc = "Steampunk-inspired square border";
- mapCredit = "ThatGravyBoat";
- break;
- case 11:
- mapDesc = "Steampunk-inspired circular border";
- mapCredit = "ThatGravyBoat";
- break;
- case 12:
- mapDesc = "Light fade border";
- mapCredit = "Qwiken";
- break;
- case 13:
- mapDesc = "Simple gray border with red ribbons";
- mapCredit = "Sai";
- break;
- case 14:
- mapDesc = "Paper border";
- mapCredit = "KingJames02st";
- break;
- case 15:
- mapDesc = "Nether-inspired border";
- mapCredit = "DTRW191";
- break;
- case 16:
- mapDesc = "Golden ornate border";
- mapCredit = "iDevil4Hell";
- break;
- case 17:
- mapDesc = "Stone dragon border";
- mapCredit = "ImperiaL";
- break;
- }
-
- ArrayList<String> tooltip = new ArrayList<>();
- tooltip.add(EnumChatFormatting.YELLOW + "Border Style");
- tooltip.add(EnumChatFormatting.AQUA + "Customize the look of the dungeon border");
- tooltip.add("");
- if (mapDesc != null)
- tooltip.add(EnumChatFormatting.YELLOW + "Set to: " + EnumChatFormatting.AQUA + mapDesc);
- if (mapCredit != null)
- tooltip.add(EnumChatFormatting.YELLOW + "Artist: " + EnumChatFormatting.GOLD + mapCredit);
- tooltipToDisplay = tooltip;
- } else {
- tooltipToDisplay = button.getTooltip();
- }
- break;
- }
- }
-
- this.sizeX = 431;
- this.sizeY = 237;
- this.guiLeft = (this.width - this.sizeX) / 2;
- this.guiTop = (this.height - this.sizeY) / 2;
-
- super.drawScreen(mouseX, mouseY, partialTicks);
- drawDefaultBackground();
-
- blurBackground();
- renderBlurredBackground(width, height, guiLeft + 2, guiTop + 2, sizeX - 4, sizeY - 4);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
- GlStateManager.color(1, 1, 1, 1);
- Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST);
-
- Minecraft.getMinecraft().fontRendererObj.drawString("NEU Dungeon Map Editor", guiLeft + 8, guiTop + 6, 0xFFB4B4B4);
-
- Utils.drawStringCenteredScaledMaxWidth("Border Size", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 76, guiTop + 30, false, 137, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Rooms Size", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 76, guiTop + 60, false, 137, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Icon Scale", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 76, guiTop + 90, false, 137, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Border Style", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 76, guiTop + 120, false, 137, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Dungeon Map", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 30, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Center", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 30, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Rotate", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 59, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Icon Style", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 59, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Check Orient", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 88, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Check Center", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 88, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Interpolation", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 117, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Compatibility", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 117, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Background", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 146, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Border", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 146, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("BG Blur", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 44 + 139, guiTop + 175, false, 60, 0xFFB4B4B4
- );
- Utils.drawStringCenteredScaledMaxWidth("Chroma Type", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 108 + 139, guiTop + 175, false, 60, 0xFFB4B4B4
- );
-
- Utils.drawStringCenteredScaledMaxWidth("Edit Map Position", Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 76, guiTop + 209, false, 200, 0xFFB4B4B4
- );
-
- try {
- drawSlider(DungeonMapConfig.class.getDeclaredField("dmBorderSize"), guiLeft + 76, guiTop + 45);
- drawSlider(DungeonMapConfig.class.getDeclaredField("dmRoomSize"), guiLeft + 76, guiTop + 75);
- drawSlider(DungeonMapConfig.class.getDeclaredField("dmIconScale"), guiLeft + 76, guiTop + 105);
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
- buttons.get(18 - 6).text = options.dmEnable ? "Enabled" : "Disabled";
- buttons.get(19 - 6).text = options.dmCenterPlayer ? "Player" : "Map";
- buttons.get(20 - 6).text = options.dmRotatePlayer ? "Player" : "Vertical";
- buttons.get(21 - 6).text =
- options.dmPlayerHeads <= 0 ? "Default" : options.dmPlayerHeads == 1 ? "Heads" : "Heads w/ Border";
- buttons.get(22 - 6).text = options.dmOrientCheck ? "Orient" : "Off";
- buttons.get(23 - 6).text = options.dmCenterCheck ? "Center" : "Off";
- buttons.get(24 - 6).text = options.dmPlayerInterp ? "Interp" : "No Interp";
- buttons.get(25 - 6).text = options.dmCompat <= 0 ? "Normal" : options.dmCompat >= 2 ? "No FB/SHD" : "No SHD";
-
- buttons.get(26 - 6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBackgroundColour));
- buttons.get(27 - 6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBorderColour));
-
- buttons.get(28 - 6).text = options.dmChromaBorder ? "Scroll" : "Normal";
-
- blurField.setSize(48, 16);
- blurField.render(guiLeft + 20 + 139, guiTop + 181);
-
- GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(button_tex);
- RenderUtils.drawTexturedRect(guiLeft + 52, guiTop + 215, 48, 16);
- TextRenderUtils.drawStringCenteredScaledMaxWidth("Edit", fontRendererObj, guiLeft + 76, guiTop + 223,
- false, 48, 0xFF303030
- );
-
- Map<String, Vec4b> decorations = new HashMap<>();
- Vec4b vec4b = new Vec4b((byte) 3, (byte) (((50) - 64) * 2), (byte) (((40) - 64) * 2), (byte) ((60) * 16 / 360));
- decorations.put(Minecraft.getMinecraft().thePlayer.getName(), vec4b);
-
- HashSet<String> players = new HashSet<>();
- players.add(Minecraft.getMinecraft().thePlayer.getName());
- GlStateManager.color(1, 1, 1, 1);
-
- demoMap.renderMap(guiLeft + 357, guiTop + 125, NotEnoughUpdates.INSTANCE.colourMap, decorations, 0,
- players, false, partialTicks
- );
-
- for (Button button : buttons) {
- button.render();
- }
-
- //List<String> textLines, final int mouseX, final int mouseY, final int screenWidth, final int screenHeight, final int maxTextWidth, FontRenderer font
- if (tooltipToDisplay != null) {
- Utils.drawHoveringText(
- tooltipToDisplay,
- mouseX,
- mouseY,
- width,
- height,
- 200,
- Minecraft.getMinecraft().fontRendererObj
+ public static final ResourceLocation BACKGROUND = new ResourceLocation("notenoughupdates:dungeon_map/editor/background.png");
+ public static final ResourceLocation BUTTON = new ResourceLocation("notenoughupdates:dungeon_map/editor/button.png");
+ private static final DungeonMap demoMap = new DungeonMap();
+
+ private int sizeX;
+ private int sizeY;
+ private int guiLeft;
+ private int guiTop;
+
+ private final List<Button> buttons = new ArrayList<>();
+
+ private final GuiElementTextField blurField = new GuiElementTextField("", GuiElementTextField.NUM_ONLY | GuiElementTextField.NO_SPACE);
+ private GuiElementColour activeColourEditor = null;
+
+ private Field clickedSlider;
+
+ class Button {
+ private final int id;
+ private final int x;
+ private final int y;
+ private String text;
+ private Color colour = new Color(-1, true);
+ private final Field option;
+ private String displayName;
+ private String desc;
+
+ public Button(int id, int x, int y, String text) {
+ this(id, x, y, text, null);
+ }
+
+ public Button(int id, int x, int y, String text, Field option) {
+ this.id = id;
+ this.x = x;
+ this.y = y;
+ this.text = text;
+ this.option = option;
+
+ if (option != null) {
+ ConfigOption optionAnnotation = option.getAnnotation(ConfigOption.class);
+ displayName = optionAnnotation.name();
+ desc = optionAnnotation.desc();
+ }
+ }
+
+ public List<String> getTooltip() {
+ if (option == null) {
+ return null;
+ }
+
+ List<String> tooltip = new ArrayList<>();
+ tooltip.add(EnumChatFormatting.YELLOW + displayName);
+ for (String line : desc.split("\n")) {
+ tooltip.add(EnumChatFormatting.AQUA + line);
+ }
+ return tooltip;
+ }
+
+ public void render() {
+ if (text == null) return;
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(BUTTON);
+ if (isButtonPressed(id)) {
+ GlStateManager.color(colour.getRed() * 0.85f / 255f, colour.getGreen() * 0.85f / 255f,
+ colour.getBlue() * 0.85f / 255f, 1);
+ Utils.drawTexturedRect(guiLeft + x, guiTop + y, 48, 16, 1, 0, 1, 0, GL11.GL_NEAREST);
+ } else {
+ GlStateManager.color(colour.getRed() / 255f, colour.getGreen() / 255f, colour.getBlue() / 255f, 1);
+ Utils.drawTexturedRect(guiLeft + x, guiTop + y, 48, 16, GL11.GL_NEAREST);
+ }
+
+ if (text.length() > 0) {
+ Utils.drawStringCenteredScaledMaxWidth(text, Minecraft.getMinecraft().fontRendererObj, guiLeft + x + 24, guiTop + y + 8, false, 39, 0xFF000000);
+ }
+ }
+
+ }
+
+ public GuiDungeonMapEditor() {
+ DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
+ //Map Border Size
+ //buttons.add(new Button(0, 6, 37, "Small", options.dmBorderSize));
+ //buttons.add(new Button(1, 52, 37, "Medium", options.dmBorderSize));
+ //buttons.add(new Button(2, 98, 37, "Large", options.dmBorderSize));
+
+ //Map Rooms Size
+ //buttons.add(new Button(3, 6, 67+19, "Small", options.dmRoomSize));
+ //buttons.add(new Button(4, 52, 67+19, "Medium", options.dmRoomSize));
+ //buttons.add(new Button(5, 98, 67+19, "Large", options.dmRoomSize));
+
+ //Map Border Styles
+ buttons.add(new Button(6, 6, 97 + 30, "None"));
+ buttons.add(new Button(7, 52, 97 + 30, "Custom"));
+ buttons.add(new Button(8, 98, 97 + 30, "Stone"));
+ buttons.add(new Button(9, 6, 116 + 30, "Wood"));
+ buttons.add(new Button(10, 52, 116 + 30, "Rustic(S)"));
+ buttons.add(new Button(11, 98, 116 + 30, "Rustic(C)"));
+ buttons.add(new Button(12, 6, 135 + 30, "Fade"));
+ buttons.add(new Button(13, 52, 135 + 30, "Ribbons"));
+ buttons.add(new Button(14, 98, 135 + 30, "Paper"));
+ buttons.add(new Button(15, 6, 154 + 30, "Crimson"));
+ buttons.add(new Button(16, 52, 154 + 30, "Ornate"));
+ buttons.add(new Button(17, 98, 154 + 30, "Dragon"));
+
+ try {
+ //Dungeon Map
+ buttons.add(new Button(18, 20 + 139, 36, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmEnable")));
+ //Center
+ buttons.add(new Button(19, 84 + 139, 36, "Player/Map", DungeonMapConfig.class.getDeclaredField("dmCenterPlayer")));
+ //Rotate
+ buttons.add(new Button(20, 20 + 139, 65, "Player/No Rotate", DungeonMapConfig.class.getDeclaredField("dmRotatePlayer")));
+ //Icon Style
+ buttons.add(new Button(21, 84 + 139, 65, "Default/Heads", DungeonMapConfig.class.getDeclaredField("dmPlayerHeads")));
+ //Check Orient
+ buttons.add(new Button(22, 20 + 139, 94, "Normal/Reorient", DungeonMapConfig.class.getDeclaredField("dmOrientCheck")));
+ //Check Center
+ buttons.add(new Button(23, 84 + 139, 94, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmCenterCheck")));
+ //Interpolation
+ buttons.add(new Button(24, 20 + 139, 123, "Yes/No", DungeonMapConfig.class.getDeclaredField("dmPlayerInterp")));
+ //Compatibility
+ buttons.add(new Button(25, 84 + 139, 123, "Normal/No SHD/No FB/SHD", DungeonMapConfig.class.getDeclaredField("dmCompat")));
+
+ //Background
+ buttons.add(new Button(26, 20 + 139, 152, "", DungeonMapConfig.class.getDeclaredField("dmBackgroundColour")));
+ //Border
+ buttons.add(new Button(27, 84 + 139, 152, "", DungeonMapConfig.class.getDeclaredField("dmBorderColour")));
+
+ //Chroma Mode
+ buttons.add(new Button(28, 84 + 139, 181, "Normal/Scroll", DungeonMapConfig.class.getDeclaredField("dmChromaBorder")));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ //buttons.add(new Button(29, 52, 86+19, "XLarge", options.dmRoomSize));
+ //buttons.add(new Button(30, 52, 56, "XLarge", options.dmBorderSize));
+
+ {
+ double val = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur;
+ String strVal;
+ if (val % 1 == 0) {
+ strVal = Integer.toString((int) val);
+ } else {
+ strVal = Double.toString(val);
+ strVal = strVal.replaceAll("(\\.\\d\\d\\d)(?:\\d)+", "$1");
+ strVal = strVal.replaceAll("0+$", "");
+ }
+ blurField.setText(strVal);
+ }
+ }
+
+ @Override
+ public void drawScreen(int mouseX, int mouseY, float partialTicks) {
+ ScaledResolution scaledResolution = Utils.pushGuiScale(2);
+ this.width = scaledResolution.getScaledWidth();
+ this.height = scaledResolution.getScaledHeight();
+
+ mouseX = Mouse.getEventX() * this.width / this.mc.displayWidth;
+ mouseY = this.height - Mouse.getEventY() * this.height / this.mc.displayHeight - 1;
+
+ List<String> tooltipToDisplay = null;
+ for (Button button : buttons) {
+ if (mouseX >= guiLeft + button.x && mouseX <= guiLeft + button.x + 48 &&
+ mouseY >= guiTop + button.y - 13 && mouseY <= guiTop + button.y + 16) {
+ if (button.id >= 6 && button.id <= 17) {
+ String mapDesc = null;
+ String mapCredit = null;
+ int id = button.id;
+ switch (id) {
+ case 6:
+ mapDesc = "No Border";
+ break;
+ case 7:
+ mapDesc = "Used by custom Resource Packs";
+ break;
+ case 8:
+ mapDesc = "Simple gray border";
+ mapCredit = "LucyTightMistress";
+ break;
+ case 9:
+ mapDesc = "Viney wood border";
+ mapCredit = "iDevil4Hell";
+ break;
+ case 10:
+ mapDesc = "Steampunk-inspired square border";
+ mapCredit = "ThatGravyBoat";
+ break;
+ case 11:
+ mapDesc = "Steampunk-inspired circular border";
+ mapCredit = "ThatGravyBoat";
+ break;
+ case 12:
+ mapDesc = "Light fade border";
+ mapCredit = "Qwiken";
+ break;
+ case 13:
+ mapDesc = "Simple gray border with red ribbons";
+ mapCredit = "Sai";
+ break;
+ case 14:
+ mapDesc = "Paper border";
+ mapCredit = "KingJames02st";
+ break;
+ case 15:
+ mapDesc = "Nether-inspired border";
+ mapCredit = "DTRW191";
+ break;
+ case 16:
+ mapDesc = "Golden ornate border";
+ mapCredit = "iDevil4Hell";
+ break;
+ case 17:
+ mapDesc = "Stone dragon border";
+ mapCredit = "ImperiaL";
+ break;
+ }
+
+ ArrayList<String> tooltip = new ArrayList<>();
+ tooltip.add(EnumChatFormatting.YELLOW + "Border Style");
+ tooltip.add(EnumChatFormatting.AQUA + "Customize the look of the dungeon border");
+ tooltip.add("");
+ if (mapDesc != null)
+ tooltip.add(EnumChatFormatting.YELLOW + "Set to: " + EnumChatFormatting.AQUA + mapDesc);
+ if (mapCredit != null)
+ tooltip.add(EnumChatFormatting.YELLOW + "Artist: " + EnumChatFormatting.GOLD + mapCredit);
+ tooltipToDisplay = tooltip;
+ } else {
+ tooltipToDisplay = button.getTooltip();
+ }
+ break;
+ }
+ }
+
+ this.sizeX = 431;
+ this.sizeY = 237;
+ this.guiLeft = (this.width - this.sizeX) / 2;
+ this.guiTop = (this.height - this.sizeY) / 2;
+
+ super.drawScreen(mouseX, mouseY, partialTicks);
+ drawDefaultBackground();
+
+ blurBackground();
+ renderBlurredBackground(width, height, guiLeft + 2, guiTop + 2, sizeX - 4, sizeY - 4);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(BACKGROUND);
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST);
+
+ DungeonMapStaticParser parser = new DungeonMapStaticParser(
+ demoMap,
+ "F1",
+ NotEnoughUpdates.INSTANCE.colourMap,
+ new HashMap<>()
);
- }
-
- Utils.pushGuiScale(-1);
-
- if (activeColourEditor != null) {
- activeColourEditor.render();
- }
- }
-
- public void drawSlider(Field option, int centerX, int centerY) {
- float value;
- float minValue;
- float maxValue;
- try {
- value = ((Number) option.get(NotEnoughUpdates.INSTANCE.config.dungeonMap)).floatValue();
-
- ConfigEditorSlider sliderAnnotation = option.getAnnotation(ConfigEditorSlider.class);
- minValue = sliderAnnotation.minValue();
- maxValue = sliderAnnotation.maxValue();
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
-
- float sliderAmount = Math.max(0, Math.min(1, (value - minValue) / (maxValue - minValue)));
- int sliderAmountI = (int) (96 * sliderAmount);
-
- GlStateManager.color(1f, 1f, 1f, 1f);
- Minecraft.getMinecraft().getTextureManager().bindTexture(slider_on_large);
- Utils.drawTexturedRect(centerX - 48, centerY - 8, sliderAmountI, 16,
- 0, sliderAmount, 0, 1, GL11.GL_NEAREST
- );
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(slider_off_large);
- Utils.drawTexturedRect(centerX - 48 + sliderAmountI, centerY - 8, 96 - sliderAmountI, 16,
- sliderAmount, 1, 0, 1, GL11.GL_NEAREST
- );
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(slider_button);
- Utils.drawTexturedRect(centerX - 48 + sliderAmountI - 4, centerY - 8, 8, 16,
- 0, 1, 0, 1, GL11.GL_NEAREST
- );
- }
-
- @Override
- protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
- super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
-
- if (clickedSlider != null) {
- float minValue;
- float maxValue;
- try {
- ConfigEditorSlider sliderAnnotation = clickedSlider.getAnnotation(ConfigEditorSlider.class);
- minValue = sliderAnnotation.minValue();
- maxValue = sliderAnnotation.maxValue();
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
-
- float sliderAmount = (mouseX - (guiLeft + 76 - 48)) / 96f;
- double val = minValue + (maxValue - minValue) * sliderAmount;
- if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
- val = Math.round(val);
- }
- float value = (float) Math.max(minValue, Math.min(maxValue, val));
- try {
- if (clickedSlider.getType() == int.class) {
- clickedSlider.set(NotEnoughUpdates.INSTANCE.config.dungeonMap, Math.round(value));
- } else {
- clickedSlider.set(NotEnoughUpdates.INSTANCE.config.dungeonMap, value);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- }
-
- @Override
- protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
- for (Button button : buttons) {
- if (mouseX >= guiLeft + button.x && mouseX <= guiLeft + button.x + 48 &&
- mouseY >= guiTop + button.y && mouseY <= guiTop + button.y + 16) {
- buttonClicked(mouseX, mouseY, button.id);
-
- blurField.otherComponentClick();
- return;
- }
- }
-
- clickedSlider = null;
- if (mouseX >= guiLeft + 76 - 48 && mouseX <= guiLeft + 76 + 48) {
- try {
- if (mouseY > guiTop + 45 - 8 && mouseY < guiTop + 45 + 8) {
- clickedSlider = DungeonMapConfig.class.getDeclaredField("dmBorderSize");
- return;
- } else if (mouseY > guiTop + 75 - 8 && mouseY < guiTop + 75 + 8) {
- clickedSlider = DungeonMapConfig.class.getDeclaredField("dmRoomSize");
- return;
- } else if (mouseY > guiTop + 105 - 8 && mouseY < guiTop + 105 + 8) {
- clickedSlider = DungeonMapConfig.class.getDeclaredField("dmIconScale");
- return;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- if (mouseY > guiTop + 181 && mouseY < guiTop + 181 + 16) {
- if (mouseX > guiLeft + 20 + 139 && mouseX < guiLeft + 20 + 139 + 48) {
- blurField.mouseClicked(mouseX, mouseY, mouseButton);
- return;
- }
- } else if (mouseY > guiTop + 215 && mouseY < guiTop + 215 + 16) {
- if (mouseX > guiLeft + 52 && mouseX < guiLeft + 100) {
- int size = 80 + Math.round(40 * NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
-
- Map<String, Vec4b> decorations = new HashMap<>();
- Vec4b vec4b = new Vec4b((byte) 3, (byte) (((50) - 64) * 2), (byte) (((40) - 64) * 2), (byte) ((60) * 16 / 360));
- decorations.put(Minecraft.getMinecraft().thePlayer.getName(), vec4b);
-
- HashSet<String> players = new HashSet<>();
- players.add(Minecraft.getMinecraft().thePlayer.getName());
- GlStateManager.color(1, 1, 1, 1);
-
- Minecraft.getMinecraft().displayGuiScreen(new GuiPositionEditor(
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition,
- size, size, () -> {
- ScaledResolution scaledResolution = Utils.pushGuiScale(2);
- demoMap.renderMap(
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsX(scaledResolution, size) + size / 2,
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsY(scaledResolution, size) + size / 2,
- NotEnoughUpdates.INSTANCE.colourMap,
- decorations,
- 0,
- players,
- false,
- 0
- );
- Utils.pushGuiScale(-1);
- }, () -> {}, () -> NotEnoughUpdates.INSTANCE.openGui = new GuiDungeonMapEditor()
- ).withScale(2));
- return;
- }
- }
-
- blurField.otherComponentClick();
- }
-
- @Override
- public void handleMouseInput() throws IOException {
- super.handleMouseInput();
-
- if (activeColourEditor != null) {
- ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
- int mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
- int mouseY =
- realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
- activeColourEditor.mouseInput(mouseX, mouseY);
- }
- }
-
- @Override
- public void handleKeyboardInput() throws IOException {
- super.handleKeyboardInput();
-
- if (activeColourEditor != null) {
- activeColourEditor.keyboardInput();
- }
- }
-
- @Override
- protected void keyTyped(char typedChar, int keyCode) throws IOException {
- super.keyTyped(typedChar, keyCode);
-
- if (blurField.getFocus()) {
- blurField.keyTyped(typedChar, keyCode);
-
- try {
- blurField.setCustomBorderColour(-1);
- NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur = Float.parseFloat(blurField.getText());
- } catch (Exception e) {
- blurField.setCustomBorderColour(Color.RED.getRGB());
- }
- }
- }
-
- private void buttonClicked(int mouseX, int mouseY, int id) {
- DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
- switch (id) {
- case 0:
- options.dmBorderSize = 0;
- break;
- case 1:
- options.dmBorderSize = 1;
- break;
- case 2:
- options.dmBorderSize = 2;
- break;
- case 30:
- options.dmBorderSize = 3;
- break;
- case 3:
- options.dmRoomSize = 0;
- break;
- case 4:
- options.dmRoomSize = 1;
- break;
- case 5:
- options.dmRoomSize = 2;
- break;
- case 29:
- options.dmRoomSize = 3;
- break;
- case 18:
- options.dmEnable = !options.dmEnable;
- break;
- case 19:
- options.dmCenterPlayer = !options.dmCenterPlayer;
- break;
- case 20:
- options.dmRotatePlayer = !options.dmRotatePlayer;
- break;
- case 21:
- options.dmPlayerHeads++;
- if (options.dmPlayerHeads > 2) options.dmPlayerHeads = 0;
- break;
- case 22:
- options.dmOrientCheck = !options.dmOrientCheck;
- break;
- case 23:
- options.dmCenterCheck = !options.dmCenterCheck;
- break;
- case 24:
- options.dmPlayerInterp = !options.dmPlayerInterp;
- break;
- case 25:
- options.dmCompat++;
- if (options.dmCompat > 2) options.dmCompat = 0;
- break;
- case 26: {
- ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
- mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
- mouseY = realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
- activeColourEditor = new GuiElementColour(mouseX, mouseY, options.dmBackgroundColour,
- (col) -> options.dmBackgroundColour = col, () -> activeColourEditor = null
- );
- }
- break;
- case 27: {
- ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
- mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
- mouseY = realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
- activeColourEditor = new GuiElementColour(mouseX, mouseY, options.dmBorderColour,
- (col) -> options.dmBorderColour = col, () -> activeColourEditor = null
- );
- }
- break;
- case 28:
- options.dmChromaBorder = !options.dmChromaBorder;
- break;
- default:
- if (id >= 6 && id <= 17) {
- options.dmBorderStyle = id - 6;
- break;
- }
- }
- }
-
- private boolean isButtonPressed(int id) {
- DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
-
- if (id >= 0 && id <= 2) {
- return options.dmBorderSize == id;
- } else if (id >= 3 && id <= 5) {
- return options.dmRoomSize == id - 3;
- } else if (id >= 6 && id <= 17) {
- return options.dmBorderStyle == id - 6;
- } else if (id == 29) {
- return options.dmRoomSize == 3;
- } else if (id == 30) {
- return options.dmBorderSize == 3;
- }
- return false;
- }
-
- Shader blurShaderHorz = null;
- Framebuffer blurOutputHorz = null;
- Shader blurShaderVert = null;
- Framebuffer blurOutputVert = null;
-
- /**
- * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate
- * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis).
- * <p>
- * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to
- * apply scales and translations manually.
- */
- private Matrix4f createProjectionMatrix(int width, int height) {
- Matrix4f projMatrix = new Matrix4f();
- projMatrix.setIdentity();
- projMatrix.m00 = 2.0F / (float) width;
- projMatrix.m11 = 2.0F / (float) (-height);
- projMatrix.m22 = -0.0020001999F;
- projMatrix.m33 = 1.0F;
- projMatrix.m03 = -1.0F;
- projMatrix.m13 = 1.0F;
- projMatrix.m23 = -1.0001999F;
- return projMatrix;
- }
-
- private double lastBgBlurFactor = -1;
-
- private void blurBackground() {
- if (!OpenGlHelper.isFramebufferEnabled()) return;
-
- int width = Minecraft.getMinecraft().displayWidth;
- int height = Minecraft.getMinecraft().displayHeight;
-
- if (blurOutputHorz == null) {
- blurOutputHorz = new Framebuffer(width, height, false);
- blurOutputHorz.setFramebufferFilter(GL11.GL_NEAREST);
- }
- if (blurOutputVert == null) {
- blurOutputVert = new Framebuffer(width, height, false);
- blurOutputVert.setFramebufferFilter(GL11.GL_NEAREST);
- }
- if (blurOutputHorz.framebufferWidth != width || blurOutputHorz.framebufferHeight != height) {
- blurOutputHorz.createBindFramebuffer(width, height);
- blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height));
- Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
- }
- if (blurOutputVert.framebufferWidth != width || blurOutputVert.framebufferHeight != height) {
- blurOutputVert.createBindFramebuffer(width, height);
- blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height));
- Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
- }
-
- if (blurShaderHorz == null) {
- try {
- blurShaderHorz = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur",
- Minecraft.getMinecraft().getFramebuffer(), blurOutputHorz
- );
- blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0);
- blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height));
- } catch (Exception ignored) {
- }
- }
- if (blurShaderVert == null) {
- try {
- blurShaderVert = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur",
- blurOutputHorz, blurOutputVert
- );
- blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1);
- blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height));
- } catch (Exception ignored) {
- }
- }
- if (blurShaderHorz != null && blurShaderVert != null) {
- if (15 != lastBgBlurFactor) {
- blurShaderHorz.getShaderManager().getShaderUniform("Radius").set((float) 15);
- blurShaderVert.getShaderManager().getShaderUniform("Radius").set((float) 15);
- lastBgBlurFactor = 15;
- }
- GL11.glPushMatrix();
- blurShaderHorz.loadShader(0);
- blurShaderVert.loadShader(0);
- GlStateManager.enableDepth();
- GL11.glPopMatrix();
-
- Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
- }
- }
-
- /**
- * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen.
- * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight]
- */
- public void renderBlurredBackground(int width, int height, int x, int y, int blurWidth, int blurHeight) {
- if (!OpenGlHelper.isFramebufferEnabled()) return;
-
- float uMin = x / (float) width;
- float uMax = (x + blurWidth) / (float) width;
- float vMin = (height - y) / (float) height;
- float vMax = (height - y - blurHeight) / (float) height;
-
- blurOutputVert.bindFramebufferTexture();
- GlStateManager.color(1f, 1f, 1f, 1f);
- Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax);
- blurOutputVert.unbindFramebufferTexture();
- }
+ parser.parseDungeonMap();
+ DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
+ DungeonMapPlayers renderPlayer = new DungeonMapPlayers();
+ renderPlayer.getRunnerPositions().put(
+ Minecraft.getMinecraft().thePlayer.getName(),
+ new DungeonMapPlayers.PlayerMarker(50, 40, 60F)
+ );
+ renderPlayer.setMainPlayerX(50);
+ renderPlayer.setMainPlayerZ(40);
+ renderPlayer.setMainPlayerRotation(60);
+ float savedSize = options.dmBorderSize;
+ options.dmBorderSize = 1F;
+ demoMap.renderMap(options, parser, renderPlayer, guiLeft + 357, guiTop + 125);
+ options.dmBorderSize = savedSize;
+
+ Minecraft.getMinecraft().fontRendererObj.drawString(
+ "NEU Dungeon Map Editor",
+ guiLeft + 8,
+ guiTop + 6,
+ 0xFFB4B4B4
+ );
+
+ Utils.drawStringCenteredScaledMaxWidth("Border Size", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 76, guiTop + 30, false, 137, 0xFFB4B4B4
+ );
+ Utils.drawStringCenteredScaledMaxWidth("Rooms Size", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 76, guiTop + 60, false, 137, 0xFFB4B4B4
+ );
+ Utils.drawStringCenteredScaledMaxWidth("Icon Scale", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 76, guiTop + 90, false, 137, 0xFFB4B4B4
+ );
+ Utils.drawStringCenteredScaledMaxWidth("Border Style", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 76, guiTop + 120, false, 137, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Dungeon Map", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 30, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Center", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 30, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Rotate", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 59, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Icon Style", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 59, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Check Orient", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 88, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Check Center", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 88, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Interpolation", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 117, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Compatibility", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 117, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Background", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 146, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Border", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 146, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("BG Blur", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 44 + 139, guiTop + 175, false, 60, 0xFFB4B4B4);
+ Utils.drawStringCenteredScaledMaxWidth("Chroma Type", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 108 + 139, guiTop + 175, false, 60, 0xFFB4B4B4);
+
+ Utils.drawStringCenteredScaledMaxWidth("Edit Map Position", Minecraft.getMinecraft().fontRendererObj,
+ guiLeft + 76, guiTop + 209, false, 200, 0xFFB4B4B4);
+
+ try {
+ drawSlider(DungeonMapConfig.class.getDeclaredField("dmBorderSize"), guiLeft + 76, guiTop + 45);
+ drawSlider(DungeonMapConfig.class.getDeclaredField("dmRoomSize"), guiLeft + 76, guiTop + 75);
+ drawSlider(DungeonMapConfig.class.getDeclaredField("dmIconScale"), guiLeft + 76, guiTop + 105);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ buttons.get(18 - 6).text = options.dmEnable ? "Enabled" : "Disabled";
+ buttons.get(19 - 6).text = options.dmCenterPlayer ? "Player" : "Map";
+ buttons.get(20 - 6).text = options.dmRotatePlayer ? "Player" : "Vertical";
+ buttons.get(21 - 6).text = options.dmPlayerHeads <= 0 ? "Default" : options.dmPlayerHeads == 1 ? "Heads" : "Heads w/ Border";
+ buttons.get(22 - 6).text = options.dmOrientCheck ? "Orient" : "Off";
+ buttons.get(23 - 6).text = options.dmCenterCheck ? "Center" : "Off";
+ buttons.get(24 - 6).text = options.dmPlayerInterp ? "Interp" : "No Interp";
+ buttons.get(25 - 6).text = options.dmCompat <= 0 ? "Normal" : options.dmCompat >= 2 ? "No FB/SHD" : "No SHD";
+
+ buttons.get(26 - 6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBackgroundColour));
+ buttons.get(27 - 6).colour = new Color(SpecialColour.specialToChromaRGB(options.dmBorderColour));
+
+ buttons.get(28 - 6).text = options.dmChromaBorder ? "Scroll" : "Normal";
+
+ blurField.setSize(48, 16);
+ blurField.render(guiLeft + 20 + 139, guiTop + 181);
+
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(button_tex);
+ RenderUtils.drawTexturedRect(guiLeft + 52, guiTop + 215, 48, 16);
+ TextRenderUtils.drawStringCenteredScaledMaxWidth("Edit", fontRendererObj, guiLeft + 76, guiTop + 223,
+ false, 48, 0xFF303030);
+
+
+ GlStateManager.color(1, 1, 1, 1);
+ for (Button button : buttons) {
+ button.render();
+ }
+
+ //List<String> textLines, final int mouseX, final int mouseY, final int screenWidth, final int screenHeight, final int maxTextWidth, FontRenderer font
+ if (tooltipToDisplay != null) {
+ Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, 200, Minecraft.getMinecraft().fontRendererObj);
+ }
+
+ Utils.pushGuiScale(-1);
+
+ if (activeColourEditor != null) {
+ activeColourEditor.render();
+ }
+ }
+
+ public void drawSlider(Field option, int centerX, int centerY) {
+ float value;
+ float minValue;
+ float maxValue;
+ try {
+ value = ((Number) option.get(NotEnoughUpdates.INSTANCE.config.dungeonMap)).floatValue();
+
+ ConfigEditorSlider sliderAnnotation = option.getAnnotation(ConfigEditorSlider.class);
+ minValue = sliderAnnotation.minValue();
+ maxValue = sliderAnnotation.maxValue();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ float sliderAmount = Math.max(0, Math.min(1, (value - minValue) / (maxValue - minValue)));
+ int sliderAmountI = (int) (96 * sliderAmount);
+
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(slider_on_large);
+ Utils.drawTexturedRect(centerX - 48, centerY - 8, sliderAmountI, 16,
+ 0, sliderAmount, 0, 1, GL11.GL_NEAREST);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(slider_off_large);
+ Utils.drawTexturedRect(centerX - 48 + sliderAmountI, centerY - 8, 96 - sliderAmountI, 16,
+ sliderAmount, 1, 0, 1, GL11.GL_NEAREST);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(slider_button);
+ Utils.drawTexturedRect(centerX - 48 + sliderAmountI - 4, centerY - 8, 8, 16,
+ 0, 1, 0, 1, GL11.GL_NEAREST);
+ }
+
+ @Override
+ protected void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) {
+ super.mouseClickMove(mouseX, mouseY, clickedMouseButton, timeSinceLastClick);
+
+ if (clickedSlider != null) {
+ float minValue;
+ float maxValue;
+ try {
+ ConfigEditorSlider sliderAnnotation = clickedSlider.getAnnotation(ConfigEditorSlider.class);
+ minValue = sliderAnnotation.minValue();
+ maxValue = sliderAnnotation.maxValue();
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ float sliderAmount = (mouseX - (guiLeft + 76 - 48)) / 96f;
+ double val = minValue + (maxValue - minValue) * sliderAmount;
+ if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
+ val = Math.round(val);
+ }
+ float value = (float) Math.max(minValue, Math.min(maxValue, val));
+ try {
+ if (clickedSlider.getType() == int.class) {
+ clickedSlider.set(NotEnoughUpdates.INSTANCE.config.dungeonMap, Math.round(value));
+ } else {
+ clickedSlider.set(NotEnoughUpdates.INSTANCE.config.dungeonMap, value);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ @Override
+ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) {
+ for (Button button : buttons) {
+ if (mouseX >= guiLeft + button.x && mouseX <= guiLeft + button.x + 48 &&
+ mouseY >= guiTop + button.y && mouseY <= guiTop + button.y + 16) {
+ buttonClicked(mouseX, mouseY, button.id);
+
+ blurField.otherComponentClick();
+ return;
+ }
+ }
+
+ clickedSlider = null;
+ if (mouseX >= guiLeft + 76 - 48 && mouseX <= guiLeft + 76 + 48) {
+ try {
+ if (mouseY > guiTop + 45 - 8 && mouseY < guiTop + 45 + 8) {
+ clickedSlider = DungeonMapConfig.class.getDeclaredField("dmBorderSize");
+ return;
+ } else if (mouseY > guiTop + 75 - 8 && mouseY < guiTop + 75 + 8) {
+ clickedSlider = DungeonMapConfig.class.getDeclaredField("dmRoomSize");
+ return;
+ } else if (mouseY > guiTop + 105 - 8 && mouseY < guiTop + 105 + 8) {
+ clickedSlider = DungeonMapConfig.class.getDeclaredField("dmIconScale");
+ return;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ if (mouseY > guiTop + 181 && mouseY < guiTop + 181 + 16) {
+ if (mouseX > guiLeft + 20 + 139 && mouseX < guiLeft + 20 + 139 + 48) {
+ blurField.mouseClicked(mouseX, mouseY, mouseButton);
+ return;
+ }
+ } else if (mouseY > guiTop + 215 && mouseY < guiTop + 215 + 16) {
+ if (mouseX > guiLeft + 52 && mouseX < guiLeft + 100) {
+ int size = 80 + Math.round(40 * NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
+
+ Map<String, Vec4b> decorations = new HashMap<>();
+ Vec4b vec4b = new Vec4b((byte) 3, (byte) (((50) - 64) * 2), (byte) (((40) - 64) * 2), (byte) ((60) * 16 / 360));
+ decorations.put(Minecraft.getMinecraft().thePlayer.getName(), vec4b);
+
+ HashSet<String> players = new HashSet<>();
+ players.add(Minecraft.getMinecraft().thePlayer.getName());
+ GlStateManager.color(1, 1, 1, 1);
+
+ Minecraft.getMinecraft().displayGuiScreen(new GuiPositionEditor(
+ NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition,
+ size, size, () -> {
+ ScaledResolution scaledResolution = Utils.pushGuiScale(2);
+ /* demoMap.renderMap(NotEnoughUpdates.INSTANCE.config.dungeonMap, NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsX(scaledResolution, size) + size / 2,
+ NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition.getAbsY(scaledResolution, size) + size / 2,
+ NotEnoughUpdates.INSTANCE.colourMap, decorations, 0,
+ players, false, 0);*/
+ Utils.pushGuiScale(-1);
+ }, () -> {}, () -> NotEnoughUpdates.INSTANCE.openGui = new GuiDungeonMapEditor()
+ ).withScale(2));
+ return;
+ }
+ }
+
+ blurField.otherComponentClick();
+ }
+
+ @Override
+ public void handleMouseInput() throws IOException {
+ super.handleMouseInput();
+
+ if (activeColourEditor != null) {
+ ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
+ int mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
+ int mouseY = realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
+ activeColourEditor.mouseInput(mouseX, mouseY);
+ }
+ }
+
+ @Override
+ public void handleKeyboardInput() throws IOException {
+ super.handleKeyboardInput();
+
+ if (activeColourEditor != null) {
+ activeColourEditor.keyboardInput();
+ }
+ }
+
+ @Override
+ protected void keyTyped(char typedChar, int keyCode) throws IOException {
+ super.keyTyped(typedChar, keyCode);
+
+ if (blurField.getFocus()) {
+ blurField.keyTyped(typedChar, keyCode);
+
+ try {
+ blurField.setCustomBorderColour(-1);
+ NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBackgroundBlur = Float.parseFloat(blurField.getText());
+ } catch (Exception e) {
+ blurField.setCustomBorderColour(Color.RED.getRGB());
+ }
+ }
+ }
+
+ private void buttonClicked(int mouseX, int mouseY, int id) {
+ DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
+ switch (id) {
+ case 0:
+ options.dmBorderSize = 0;
+ break;
+ case 1:
+ options.dmBorderSize = 1;
+ break;
+ case 2:
+ options.dmBorderSize = 2;
+ break;
+ case 30:
+ options.dmBorderSize = 3;
+ break;
+ case 3:
+ options.dmRoomSize = 0;
+ break;
+ case 4:
+ options.dmRoomSize = 1;
+ break;
+ case 5:
+ options.dmRoomSize = 2;
+ break;
+ case 29:
+ options.dmRoomSize = 3;
+ break;
+ case 18:
+ options.dmEnable = !options.dmEnable;
+ break;
+ case 19:
+ options.dmCenterPlayer = !options.dmCenterPlayer;
+ break;
+ case 20:
+ options.dmRotatePlayer = !options.dmRotatePlayer;
+ break;
+ case 21:
+ options.dmPlayerHeads++;
+ if (options.dmPlayerHeads > 2) options.dmPlayerHeads = 0;
+ break;
+ case 22:
+ options.dmOrientCheck = !options.dmOrientCheck;
+ break;
+ case 23:
+ options.dmCenterCheck = !options.dmCenterCheck;
+ break;
+ case 24:
+ options.dmPlayerInterp = !options.dmPlayerInterp;
+ break;
+ case 25:
+ options.dmCompat++;
+ if (options.dmCompat > 2) options.dmCompat = 0;
+ break;
+ case 26: {
+ ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
+ mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
+ mouseY = realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
+ activeColourEditor = new GuiElementColour(mouseX, mouseY, options.dmBackgroundColour,
+ (col) -> options.dmBackgroundColour = col, () -> activeColourEditor = null);
+ }
+ break;
+ case 27: {
+ ScaledResolution realRes = new ScaledResolution(Minecraft.getMinecraft());
+ mouseX = Mouse.getEventX() * realRes.getScaledWidth() / this.mc.displayWidth;
+ mouseY = realRes.getScaledHeight() - Mouse.getEventY() * realRes.getScaledHeight() / this.mc.displayHeight - 1;
+ activeColourEditor = new GuiElementColour(mouseX, mouseY, options.dmBorderColour,
+ (col) -> options.dmBorderColour = col, () -> activeColourEditor = null);
+ }
+ break;
+ case 28:
+ options.dmChromaBorder = !options.dmChromaBorder;
+ break;
+ default:
+ if (id >= 6 && id <= 17) {
+ options.dmBorderStyle = id - 6;
+ break;
+ }
+ }
+ }
+
+ private boolean isButtonPressed(int id) {
+ DungeonMapConfig options = NotEnoughUpdates.INSTANCE.config.dungeonMap;
+
+ if (id >= 0 && id <= 2) {
+ return options.dmBorderSize == id;
+ } else if (id >= 3 && id <= 5) {
+ return options.dmRoomSize == id - 3;
+ } else if (id >= 6 && id <= 17) {
+ return options.dmBorderStyle == id - 6;
+ } else if (id == 29) {
+ return options.dmRoomSize == 3;
+ } else if (id == 30) {
+ return options.dmBorderSize == 3;
+ }
+ return false;
+ }
+
+ Shader blurShaderHorz = null;
+ Framebuffer blurOutputHorz = null;
+ Shader blurShaderVert = null;
+ Framebuffer blurOutputVert = null;
+
+ /**
+ * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate
+ * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis).
+ * <p>
+ * This is so that we can render to and from the framebuffer in a way that is familiar to us, instead of needing to
+ * apply scales and translations manually.
+ */
+ private Matrix4f createProjectionMatrix(int width, int height) {
+ Matrix4f projMatrix = new Matrix4f();
+ projMatrix.setIdentity();
+ projMatrix.m00 = 2.0F / (float) width;
+ projMatrix.m11 = 2.0F / (float) (-height);
+ projMatrix.m22 = -0.0020001999F;
+ projMatrix.m33 = 1.0F;
+ projMatrix.m03 = -1.0F;
+ projMatrix.m13 = 1.0F;
+ projMatrix.m23 = -1.0001999F;
+ return projMatrix;
+ }
+
+ private double lastBgBlurFactor = -1;
+
+ private void blurBackground() {
+ if (!OpenGlHelper.isFramebufferEnabled()) return;
+
+ int width = Minecraft.getMinecraft().displayWidth;
+ int height = Minecraft.getMinecraft().displayHeight;
+
+ if (blurOutputHorz == null) {
+ blurOutputHorz = new Framebuffer(width, height, false);
+ blurOutputHorz.setFramebufferFilter(GL11.GL_NEAREST);
+ }
+ if (blurOutputVert == null) {
+ blurOutputVert = new Framebuffer(width, height, false);
+ blurOutputVert.setFramebufferFilter(GL11.GL_NEAREST);
+ }
+ if (blurOutputHorz.framebufferWidth != width || blurOutputHorz.framebufferHeight != height) {
+ blurOutputHorz.createBindFramebuffer(width, height);
+ blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height));
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ }
+ if (blurOutputVert.framebufferWidth != width || blurOutputVert.framebufferHeight != height) {
+ blurOutputVert.createBindFramebuffer(width, height);
+ blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height));
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ }
+
+ if (blurShaderHorz == null) {
+ try {
+ blurShaderHorz = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur",
+ Minecraft.getMinecraft().getFramebuffer(), blurOutputHorz);
+ blurShaderHorz.getShaderManager().getShaderUniform("BlurDir").set(1, 0);
+ blurShaderHorz.setProjectionMatrix(createProjectionMatrix(width, height));
+ } catch (Exception ignored) {}
+ }
+ if (blurShaderVert == null) {
+ try {
+ blurShaderVert = new Shader(Minecraft.getMinecraft().getResourceManager(), "blur",
+ blurOutputHorz, blurOutputVert);
+ blurShaderVert.getShaderManager().getShaderUniform("BlurDir").set(0, 1);
+ blurShaderVert.setProjectionMatrix(createProjectionMatrix(width, height));
+ } catch (Exception ignored) {}
+ }
+ if (blurShaderHorz != null && blurShaderVert != null) {
+ if (15 != lastBgBlurFactor) {
+ blurShaderHorz.getShaderManager().getShaderUniform("Radius").set((float) 15);
+ blurShaderVert.getShaderManager().getShaderUniform("Radius").set((float) 15);
+ lastBgBlurFactor = 15;
+ }
+ GL11.glPushMatrix();
+ blurShaderHorz.loadShader(0);
+ blurShaderVert.loadShader(0);
+ GlStateManager.enableDepth();
+ GL11.glPopMatrix();
+
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ }
+ }
+
+ /**
+ * Renders a subsection of the blurred framebuffer on to the corresponding section of the screen.
+ * Essentially, this method will "blur" the background inside the bounds specified by [x->x+blurWidth, y->y+blurHeight]
+ */
+ public void renderBlurredBackground(int width, int height, int x, int y, int blurWidth, int blurHeight) {
+ if (!OpenGlHelper.isFramebufferEnabled()) return;
+
+ float uMin = x / (float) width;
+ float uMax = (x + blurWidth) / (float) width;
+ float vMin = (height - y) / (float) height;
+ float vMax = (height - y - blurHeight) / (float) height;
+
+ blurOutputVert.bindFramebufferTexture();
+ GlStateManager.color(1f, 1f, 1f, 1f);
+ Utils.drawTexturedRect(x, y, blurWidth, blurHeight, uMin, uMax, vMin, vMax);
+ blurOutputVert.unbindFramebufferTexture();
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/SpiritLeap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/SpiritLeap.java
new file mode 100644
index 00000000..a35ab34e
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/SpiritLeap.java
@@ -0,0 +1,40 @@
+package io.github.moulberry.notenoughupdates.dungeons;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.dungeons.map.DungeonMap;
+import io.github.moulberry.notenoughupdates.dungeons.map.DungeonMapPlayers;
+import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig;
+import io.github.moulberry.notenoughupdates.util.SBInfo;
+import net.minecraft.client.gui.inventory.GuiChest;
+import net.minecraft.inventory.ContainerChest;
+import net.minecraftforge.client.event.GuiScreenEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+
+public class SpiritLeap {
+
+ DungeonMap dungeonMap = new DungeonMap();
+ DungeonMapPlayers savedPlayers = null;
+
+ @SubscribeEvent
+ public void onGuiRender(GuiScreenEvent.DrawScreenEvent.Post event) {
+ if (!(event.gui instanceof GuiChest)) return;
+ if (!SBInfo.getInstance().isInDungeon) return;
+ GuiChest gui = (GuiChest) event.gui;
+ ContainerChest chest = (ContainerChest) gui.inventorySlots;
+ if (!chest.getLowerChestInventory().getDisplayName().getUnformattedText().equals("Spirit Leap")) return;
+ DungeonMapConfig config = NotEnoughUpdates.INSTANCE.config.dungeonMap;
+ this.dungeonMap.renderMap(
+ config,
+ this.dungeonMap.parsedDungeon,
+ savedPlayers != null ? savedPlayers : this.dungeonMap.dungeonMapPlayers,
+ gui.guiLeft - Math.round(20 * config.dmBorderSize),
+ gui.guiTop + gui.height / 2
+ );
+ }
+
+ @SubscribeEvent
+ public void onGuiClick(GuiScreenEvent.MouseInputEvent.Post event) {
+
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMap.java
new file mode 100644
index 00000000..716a3274
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMap.java
@@ -0,0 +1,161 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.config.Position;
+import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.block.material.MapColor;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.EntityPlayerSP;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemMap;
+import net.minecraft.item.ItemStack;
+import net.minecraft.scoreboard.Score;
+import net.minecraft.scoreboard.ScoreObjective;
+import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.scoreboard.Scoreboard;
+import net.minecraft.world.storage.MapData;
+import net.minecraftforge.client.event.RenderGameOverlayEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DungeonMap {
+
+ public DungeonMapRenderer renderer = new DungeonMapRenderer(this, NotEnoughUpdates.INSTANCE.config.dungeonMap);
+
+ public DungeonMapStaticParser parsedDungeon;
+ public DungeonMapPlayers dungeonMapPlayers;
+ public DungeonMapDebugOverlay dungeonMapDebugOverlay = new DungeonMapDebugOverlay(this);
+
+ public void renderMap(
+ DungeonMapConfig config,
+ DungeonMapStaticParser parsedDungeonData,
+ DungeonMapPlayers players,
+ int centerX,
+ int centerY
+ ) {
+ if (!config.dmEnable) return;
+ if (parsedDungeonData == null) return;
+ if (players == null) return;
+ renderer.render(centerX, centerY, parsedDungeonData, players);
+ }
+
+ @SubscribeEvent
+ public void onWorldChange(WorldEvent.Load event) {
+ this.parsedDungeon = null;
+ this.dungeonMapDebugOverlay.logFile = null;
+ this.dungeonMapPlayers = null;
+ }
+
+ // \(([MASC]\d?)\)
+ // nea stop being so genderbrained
+ private static final Pattern FLOOR_REGEX = Pattern.compile("\\(([FEM]\\d?)\\)");
+
+ @SubscribeEvent
+ public void onTickEvent(TickEvent.ClientTickEvent event) {
+ EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer;
+ if (thePlayer == null) return;
+ ItemStack stack = thePlayer.inventory.mainInventory[8];
+
+ Scoreboard scoreboard = Minecraft.getMinecraft().thePlayer.getWorldScoreboard();
+
+ ScoreObjective sidebarObjective = scoreboard.getObjectiveInDisplaySlot(1);
+
+ List<Score> scores = new ArrayList<>(scoreboard.getSortedScores(sidebarObjective));
+
+ String floorName = null;
+ for (int i = scores.size() - 1; i >= 0; i--) {
+ Score score = scores.get(i);
+ ScorePlayerTeam scoreplayerteam1 = scoreboard.getPlayersTeam(score.getPlayerName());
+ String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName());
+ line = Utils.cleanColour(line).replaceAll("[^ -~]+", "");
+
+ if (line.contains("The Catacombs")) {
+ Matcher matcher = FLOOR_REGEX.matcher(line);
+ if (matcher.find()) {
+ floorName = matcher.group(1);
+ break;
+ }
+ }
+
+ }
+ Item item = stack != null ? stack.getItem() : null;
+ if (item instanceof ItemMap) {
+ ItemMap map = (ItemMap) stack.getItem();
+ MapData mapData = map.getMapData(stack, Minecraft.getMinecraft().theWorld);
+
+ if (mapData == null) return;
+
+ Color[][] colors = new Color[128][128];
+ for (int i = 0; i < 128 * 128; ++i) {
+ int x = i % 128;
+ int y = i / 128;
+
+ int j = mapData.colors[i] & 255;
+
+ Color c;
+ if (j / 4 == 0) {
+ c = new Color(((((i + i / 128) & 1) * 8) + 16) << 24, true);
+ } else {
+ c = new Color(MapColor.mapColorArray[j / 4].getMapColor(j & 3), true);
+ }
+
+ colors[x][y] = c;
+ }
+ // TODO: do not parse static again if the colors are the same.
+
+ DungeonMapStaticParser parser = new DungeonMapStaticParser(this, floorName, colors, mapData.mapDecorations);
+ if (parser.parseDungeonMap())
+ parsedDungeon = parser;
+ DungeonMapPlayers players = new DungeonMapPlayers();
+ players.parse(parser, this.dungeonMapPlayers);
+ this.dungeonMapPlayers = players;
+ } else if (item != Items.arrow) {
+ // This should clear the map if you're in the dungeon boss room
+ // The check for arrows is so that holding a bow will not hide the map (but it will stop the map from updating)
+ this.parsedDungeon = null;
+ }
+
+ }
+
+ @SubscribeEvent
+ public void onRenderOverlay(RenderGameOverlayEvent.Post event) {
+ if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
+ if (event.type == RenderGameOverlayEvent.ElementType.ALL) {
+ if (!NotEnoughUpdates.INSTANCE.config.dungeonMap.dmEnable) return;
+
+ if (Minecraft.getMinecraft().gameSettings.showDebugInfo ||
+ (Minecraft.getMinecraft().gameSettings.keyBindPlayerList.isKeyDown() &&
+ (!Minecraft.getMinecraft().isIntegratedServerRunning() ||
+ Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap().size() > 1))) {
+ return;
+ }
+
+ DungeonMapStaticParser parsed = parsedDungeon;
+ if (parsed != null) {
+ Position pos = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPosition;
+
+ int size = 80 + Math.round(40 * NotEnoughUpdates.INSTANCE.config.dungeonMap.dmBorderSize);
+ ScaledResolution scaledResolution = Utils.pushGuiScale(2);
+ renderMap(
+ NotEnoughUpdates.INSTANCE.config.dungeonMap,
+ parsed,
+ dungeonMapPlayers,
+ pos.getAbsX(scaledResolution, size / 2) + size / 2,
+ pos.getAbsY(scaledResolution, size / 2) + size / 2
+ );
+ Utils.pushGuiScale(-1);
+
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapDebugOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapDebugOverlay.java
new file mode 100644
index 00000000..74c3b587
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapDebugOverlay.java
@@ -0,0 +1,117 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.config.Position;
+import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
+import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
+import io.github.moulberry.notenoughupdates.overlays.TextOverlay;
+import io.github.moulberry.notenoughupdates.overlays.TextOverlayStyle;
+import io.github.moulberry.notenoughupdates.util.RecencyList;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Map;
+import java.util.TimeZone;
+
+public class DungeonMapDebugOverlay extends TextOverlay {
+ public DungeonMapDebugOverlay(DungeonMap map) {
+ super(new Position(10, 300), null, () -> TextOverlayStyle.BACKGROUND);
+ this.map = map;
+ OverlayManager.textOverlays.add(this);
+ }
+
+ PrintStream logFile = null;
+
+ public void finishDungeon() {
+ if (logFile != null) {
+ logFile.close();
+ logFile = null;
+ }
+ }
+
+ public void newDungeon() {
+ File file = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), String.format(
+ "dungeonlog/log-%s.txt",
+ DateTimeFormatter.ofPattern("dd-MM-yyyy-HH-mm-ss").format(LocalDateTime.now())
+ ));
+ file.getParentFile().mkdirs();
+ try {
+ logFile = new PrintStream(file);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void logAssignmentChange(String info) {
+ currentAssignmentChanges.add(info);
+ }
+
+ DungeonMap map;
+ private RecencyList<String> recentAssignmentChanges = new RecencyList<>(Duration.ofSeconds(5));
+ private List<String> currentAssignmentChanges = new ArrayList<>();
+
+ @Override
+ public void update() {
+ recentAssignmentChanges.addAll(currentAssignmentChanges);
+ if (!NEUDebugFlag.MAP.isSet() || map.dungeonMapPlayers == null) {
+ overlayStrings = null;
+ currentAssignmentChanges.clear();
+ return;
+ }
+ overlayStrings = new ArrayList<>();
+ overlayStrings.add("Icon Mappings:");
+ for (Map.Entry<String, String> entry : map.dungeonMapPlayers.getPlayerNameToIconName().entrySet()) {
+ overlayStrings.add(entry.getValue() + " - " + entry.getKey());
+ }
+
+ overlayStrings.add("");
+
+ overlayStrings.add("Map Coords:");
+ addMap(map.dungeonMapPlayers.getAllMapPositions());
+
+ overlayStrings.add("");
+
+ overlayStrings.add("Player Coords:");
+ addMap(map.dungeonMapPlayers.getRunnerEntityPosition());
+
+ overlayStrings.add("");
+
+ overlayStrings.add("Rendered Coords:");
+ addMap(map.dungeonMapPlayers.getRunnerPositions());
+ overlayStrings.add("");
+
+ overlayStrings.add("Orphaned Coords:");
+ addMap(map.dungeonMapPlayers.getOrphanedMarkers());
+
+ overlayStrings.add("");
+ overlayStrings.add("Recent assignments:");
+
+ if (currentAssignmentChanges.size() > 0) {
+ if (logFile == null) {
+ newDungeon();
+ }
+ overlayStrings.forEach(logFile::println);
+ currentAssignmentChanges.forEach(logFile::println);
+ logFile.println("------------------------");
+ logFile.flush();
+ }
+ currentAssignmentChanges.clear();
+ overlayStrings.addAll(recentAssignmentChanges.getList());
+
+ }
+
+ private void addMap(Map<String, DungeonMapPlayers.PlayerMarker> map) {
+ for (Map.Entry<String, DungeonMapPlayers.PlayerMarker> entry : map.entrySet()) {
+ overlayStrings.add(entry.getKey() + ": " + entry.getValue().x + " " + entry.getValue().z);
+ }
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapPlayers.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapPlayers.java
new file mode 100644
index 00000000..53b2e602
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapPlayers.java
@@ -0,0 +1,267 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import com.google.common.collect.BiMap;
+import com.google.common.collect.HashBiMap;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.entity.AbstractClientPlayer;
+import net.minecraft.client.resources.DefaultPlayerSkin;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.scoreboard.Team;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.Vec4b;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class DungeonMapPlayers {
+
+ public static class Linear {
+ private final float slope;
+ private final float intercept;
+
+ public Linear(float slope, float intercept) {
+ this.slope = slope;
+ this.intercept = intercept;
+ }
+
+ public float getSlope() {
+ return slope;
+ }
+
+ public float getIntercept() {
+ return intercept;
+ }
+
+ public float calculate(float x) {
+ return slope * x + intercept;
+ }
+
+ public float calculateInverse(float y) {
+ return (y - intercept) / slope;
+ }
+ }
+
+ public static Map<String, Linear> FLOOR_MAP_SCALINGS = new HashMap<String, Linear>() {{
+ put("F1", new Linear(1.5F, -215F));
+ put("F2", new Linear(1.5F, -215F));
+ put("F3", new Linear(1.5F, -215F));
+ put("F4", new Linear(1.6F, -206F));
+ put("F5", new Linear(1.6F, -206F));
+ put("F6", new Linear(1.6F, -206F));
+ put("F7", new Linear(1.6F, -206F));
+ }};
+
+ public static class PlayerMarker {
+ public final int x, z;
+ public final float angle;
+
+ public PlayerMarker(int x, int z, float angle) {
+ this.x = x;
+ this.z = z;
+ this.angle = angle;
+ }
+
+ public int squaredDistance(PlayerMarker marker) {
+ int deltaX = marker.x - x;
+ int deltaZ = marker.z - z;
+ return deltaX * deltaX + deltaZ * deltaZ;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(x, z, angle);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ PlayerMarker that = (PlayerMarker) o;
+
+ if (x != that.x) return false;
+ if (z != that.z) return false;
+ return Float.compare(that.angle, angle) == 0;
+ }
+ }
+
+ private final Map<String, PlayerMarker> runnerPositions = new HashMap<>();
+ private final Map<String, PlayerMarker> runnerEntityPosition = new HashMap<>();
+ private final BiMap<String, String> playerNameToIconName = HashBiMap.create();
+ private final Map<String, ResourceLocation> skinMap = new HashMap<>();
+ private final Map<String, PlayerMarker> allMapPositions = new HashMap<>();
+ private final Map<String, PlayerMarker> orphanedMarkers = new HashMap<>();
+ private float mainPlayerRotation;
+ private float mainPlayerX;
+ private float mainPlayerZ;
+
+ private boolean isRealPlayer(String playerName) {
+ return Minecraft.getMinecraft().thePlayer.getWorldScoreboard().getTeams().stream()
+ .anyMatch(it
+ -> it.getMembershipCollection().size() == 1
+ && it.getMembershipCollection().contains(playerName)
+ && it.getTeamName().startsWith("a")
+ && it.getNameTagVisibility() == Team.EnumVisible.ALWAYS);
+ }
+
+ public void parse(DungeonMapStaticParser mapData, DungeonMapPlayers last) {
+ mainPlayerRotation = Minecraft.getMinecraft().thePlayer.rotationYaw;
+ if (last != null) {
+ playerNameToIconName.putAll(last.playerNameToIconName);
+ skinMap.putAll(last.skinMap);
+ }
+
+ if (mapData == null) return;
+
+ parseEntityPositions(mapData);
+
+ Map<String, Vec4b> mapDecorations = mapData.mapDecorations;
+ if (mapDecorations != null) {
+ parseMapPositions(mapDecorations);
+ assignKnownMapMarkers(mapData.dungeonMap);
+ findOrphanedMarkers();
+ } else if (last != null) {
+ // If the map decorations aren't present, then add the past orphaned markers, so those don't flicker.
+ orphanedMarkers.putAll(last.orphanedMarkers);
+ }
+
+ playerNameToIconName.forEach((playerName, markerName) -> {
+ if (runnerEntityPosition.containsKey(playerName)) {
+ runnerPositions.put(playerName, runnerEntityPosition.get(playerName));
+ } else if (allMapPositions.containsKey(markerName)) {
+ runnerPositions.put(playerName, allMapPositions.get(markerName));
+ }
+ });
+ }
+
+ private void findOrphanedMarkers() {
+ for (Map.Entry<String, PlayerMarker> marker : allMapPositions.entrySet()) {
+ if (!playerNameToIconName.containsValue(marker.getKey())) {
+ // We couldn't find a matching player, orphan this marker, so we can render it with the default marker.
+ orphanedMarkers.put(marker.getKey(), marker.getValue());
+ }
+ }
+ }
+
+ private void parseMapPositions(Map<String, Vec4b> mapDecorations) {
+ for (Map.Entry<String, Vec4b> entry : mapDecorations.entrySet()) {
+ byte id = entry.getValue().func_176110_a();
+ if (id != 1 && id != 3) continue;
+ int mapX = (int) entry.getValue().func_176112_b() / 2 + 64;
+ int mapZ = (int) entry.getValue().func_176113_c() / 2 + 64;
+ float angle = entry.getValue().func_176111_d() * 360 / 16F;
+ allMapPositions.put(entry.getKey(), new PlayerMarker(mapX, mapZ, angle));
+ }
+ }
+
+ private static final float DISTANCE_SQUARED_THRESHOLD = 10;
+
+ private void assignKnownMapMarkers(DungeonMap dungeonMap) {
+ for (Map.Entry<String, PlayerMarker> mapPos : allMapPositions.entrySet()) {
+ String oldPlayer = playerNameToIconName.inverse().get(mapPos.getKey());
+ String newPlayer = findExclusivePlayerNextToPoint(mapPos.getValue());
+ if (newPlayer == null && oldPlayer != null) {
+ dungeonMap.dungeonMapDebugOverlay.logAssignmentChange(
+ EnumChatFormatting.GOLD + "Player " + oldPlayer + " is far away from their respective marker (" +
+ mapPos.getKey() + "). Still keeping marker.");
+ }
+
+ if (newPlayer != null && !Objects.equals(newPlayer, oldPlayer)) {
+ if (playerNameToIconName.containsKey(newPlayer)) {
+ String oldMarker = playerNameToIconName.remove(newPlayer);
+ dungeonMap.dungeonMapDebugOverlay.logAssignmentChange(
+ EnumChatFormatting.RED + "Unassigned " + newPlayer + " (previously " +
+ oldMarker + "), but seems to be " + mapPos.getKey());
+ }
+ playerNameToIconName.inverse().remove(mapPos.getKey());
+ playerNameToIconName.put(newPlayer, mapPos.getKey());
+ dungeonMap.dungeonMapDebugOverlay.logAssignmentChange(
+ EnumChatFormatting.GREEN + "Assigned " + newPlayer + " to " + mapPos.getKey() + " (previously " + oldPlayer +
+ ")");
+ }
+ }
+ }
+
+ private String findExclusivePlayerNextToPoint(PlayerMarker referencePoint) {
+ String entityCandidate = null;
+ for (Map.Entry<String, PlayerMarker> entityPos : runnerEntityPosition.entrySet()) {
+ if (referencePoint.squaredDistance(entityPos.getValue()) > DISTANCE_SQUARED_THRESHOLD) continue;
+ if (entityCandidate != null)
+ return null; // Multiple candidates, people stepping on each other (kinda sus ngl)
+ entityCandidate = entityPos.getKey();
+ }
+ return entityCandidate;
+ }
+
+ private void parseEntityPositions(DungeonMapStaticParser mapData) {
+ Linear coordMapping = FLOOR_MAP_SCALINGS.get(mapData.floorName);
+ if (coordMapping == null) return;
+ for (EntityPlayer entity : Minecraft.getMinecraft().theWorld.playerEntities) {
+ if (entity.isPlayerSleeping() || !isRealPlayer(entity.getName())) continue;
+ if (entity instanceof AbstractClientPlayer) {
+ ResourceLocation skin = ((AbstractClientPlayer) entity).getLocationSkin();
+ if (skin != null && !skin.equals(DefaultPlayerSkin.getDefaultSkin(entity.getUniqueID())))
+ skinMap.put(entity.getName(), skin);
+ }
+
+ float x = coordMapping.calculateInverse((float) entity.posX);
+ float z = coordMapping.calculateInverse((float) entity.posZ);
+ if (entity.getName().equals(Minecraft.getMinecraft().thePlayer.getName())) {
+ mainPlayerX = x;
+ mainPlayerZ = z;
+ }
+ runnerEntityPosition.put(entity.getName(), new PlayerMarker(
+ (int) x, (int) z, entity.rotationYaw));
+ }
+ }
+
+ public ResourceLocation getSkin(String name) {
+ return skinMap.getOrDefault(name, DefaultPlayerSkin.getDefaultSkinLegacy());
+ }
+
+ public float getMainPlayerX() {
+ return mainPlayerX;
+ }
+
+ public void setMainPlayerX(float mainPlayerX) {
+ this.mainPlayerX = mainPlayerX;
+ }
+
+ public void setMainPlayerZ(float mainPlayerZ) {
+ this.mainPlayerZ = mainPlayerZ;
+ }
+
+ public void setMainPlayerRotation(float mainPlayerRotation) {
+ this.mainPlayerRotation = mainPlayerRotation;
+ }
+
+ public float getMainPlayerZ() {
+ return mainPlayerZ;
+ }
+
+ public float getMainPlayerRotation() {
+ return mainPlayerRotation;
+ }
+
+ public Map<String, PlayerMarker> getRunnerPositions() {
+ return runnerPositions;
+ }
+
+ public Map<String, PlayerMarker> getAllMapPositions() {
+ return allMapPositions;
+ }
+
+ public BiMap<String, String> getPlayerNameToIconName() {
+ return playerNameToIconName;
+ }
+
+ public Map<String, PlayerMarker> getRunnerEntityPosition() {
+ return runnerEntityPosition;
+ }
+
+ public Map<String, PlayerMarker> getOrphanedMarkers() {
+ return orphanedMarkers;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapRenderer.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapRenderer.java
new file mode 100644
index 00000000..b284a8b6
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapRenderer.java
@@ -0,0 +1,526 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.core.BackgroundBlur;
+import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag;
+import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig;
+import io.github.moulberry.notenoughupdates.util.NEUResourceManager;
+import io.github.moulberry.notenoughupdates.util.SpecialColour;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.gui.ScaledResolution;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.WorldRenderer;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.client.shader.Framebuffer;
+import net.minecraft.client.shader.Shader;
+import net.minecraft.util.Matrix4f;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL14;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+
+import static io.github.moulberry.notenoughupdates.util.Utils.ensureFramebufferSize;
+import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
+import static org.lwjgl.opengl.GL11.GL_PROJECTION;
+
+public class DungeonMapRenderer {
+
+ DungeonMap map;
+
+ public Framebuffer mapFramebuffer1 = null;
+ public Framebuffer mapFramebuffer2 = null;
+ public Matrix4f projectionMatrix = null;
+ public Shader mapShader = null;
+ DungeonMapConfig config;
+ private final HashMap<Integer, Float> borderRadiusCache = new HashMap<>();
+
+ public DungeonMapRenderer(DungeonMap dungeonMap, DungeonMapConfig config) {
+ this.map = dungeonMap;
+ this.config = config;
+ }
+
+ private static void upload(
+ Shader shader,
+ Matrix4f projectionMatrix,
+ int width,
+ int height,
+ int scale,
+ float radiusSq
+ ) {
+ if (shader == null) return;
+ shader.getShaderManager().getShaderUniformOrDefault("ProjMat").set(projectionMatrix);
+ shader.getShaderManager().getShaderUniformOrDefault("InSize").set(width * scale, height * scale);
+ shader.getShaderManager().getShaderUniformOrDefault("OutSize").set(width, height);
+ shader.getShaderManager().getShaderUniformOrDefault("ScreenSize").set((float) width, (float) height);
+ shader.getShaderManager().getShaderUniformOrDefault("radiusSq").set(radiusSq);
+ }
+
+ public void render(int centerX, int centerY, DungeonMapStaticParser data, DungeonMapPlayers players) {
+ boolean useFb = config.dmCompat <= 1 && OpenGlHelper.isFramebufferEnabled();
+ boolean useShd = config.dmCompat <= 0 && OpenGlHelper.areShadersSupported();
+
+ ScaledResolution scaledResolution = Utils.pushGuiScale(2);
+
+ int borderSizeOption = Math.round(config.dmBorderSize);
+
+ int backgroundSize;
+ if (config.dmBorderStyle <= 1) {
+ backgroundSize = 80 + Math.round(40 * config.dmBorderSize);
+ } else {
+ backgroundSize = borderSizeOption == 0 ? 90 : borderSizeOption == 1 ? 120 : borderSizeOption == 2 ? 160 : 240;
+ }
+ int backgroundCenter = backgroundSize / 2;
+ int scaleFactor = 8;
+
+ float mapSize = backgroundSize * config.dmRoomSize;
+ float pixelToMapScale = mapSize / 128F;
+ float renderRoomSize = data.roomSize * pixelToMapScale;
+ float renderConnSize = data.connectorSize * pixelToMapScale;
+
+ projectionMatrix = Utils.createProjectionMatrix(backgroundSize * scaleFactor, backgroundSize * scaleFactor);
+ mapFramebuffer1 = ensureFramebufferSize(
+ mapFramebuffer1,
+ backgroundSize * scaleFactor,
+ backgroundSize * scaleFactor
+ );
+ mapFramebuffer2 = ensureFramebufferSize(
+ mapFramebuffer2,
+ backgroundSize * scaleFactor,
+ backgroundSize * scaleFactor
+ );
+ mapFramebuffer1.framebufferColor[1] = 0;
+ mapFramebuffer1.framebufferColor[2] = 0;
+
+ try {
+ if (mapShader == null) {
+ mapShader = new Shader(new NEUResourceManager(Minecraft.getMinecraft().getResourceManager()),
+ "dungeonmap", mapFramebuffer1, mapFramebuffer2
+ );
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ Utils.pushGuiScale(-1);
+ return;
+ }
+
+ int backgroundColour = SpecialColour.specialToChromaRGB(config.dmBackgroundColour);
+
+ mapFramebuffer1.framebufferColor[0] = ((backgroundColour >> 16) & 0xFF) / 255f;
+ mapFramebuffer1.framebufferColor[1] = ((backgroundColour >> 8) & 0xFF) / 255f;
+ mapFramebuffer1.framebufferColor[2] = (backgroundColour & 0xFF) / 255f;
+ mapFramebuffer2.framebufferColor[0] = ((backgroundColour >> 16) & 0xFF) / 255f;
+ mapFramebuffer2.framebufferColor[1] = ((backgroundColour >> 8) & 0xFF) / 255f;
+ mapFramebuffer2.framebufferColor[2] = (backgroundColour & 0xFF) / 255f;
+
+ try {
+ if (useFb) {
+ mapFramebuffer1.framebufferClear();
+ mapFramebuffer2.framebufferClear();
+ }
+
+ GlStateManager.pushMatrix();
+ {
+ if (useFb) {
+ GlStateManager.matrixMode(GL_PROJECTION);
+ GlStateManager.loadIdentity();
+ GlStateManager.ortho(
+ 0.0D,
+ backgroundSize * scaleFactor,
+ backgroundSize * scaleFactor,
+ 0.0D,
+ 1000.0D,
+ 3000.0D
+ );
+ GlStateManager.matrixMode(GL_MODELVIEW);
+ GlStateManager.loadIdentity();
+ GlStateManager.translate(0.0F, 0.0F, -2000.0F);
+
+ GlStateManager.scale(scaleFactor, scaleFactor, 1);
+ mapFramebuffer1.bindFramebuffer(true);
+
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+ GlStateManager.disableBlend();
+ } else {
+ GL11.glEnable(GL11.GL_SCISSOR_TEST);
+ GL11.glScissor(
+ (centerX - backgroundSize / 2) * 2,
+ Minecraft.getMinecraft().displayHeight - (centerY + backgroundSize / 2) * 2,
+ backgroundSize * 2,
+ backgroundSize * 2
+ );
+
+ GlStateManager.translate(centerX - backgroundSize / 2F, centerY - backgroundSize / 2F, 100);
+ }
+
+ if (config.dmBackgroundBlur > 0.1 && config.dmBackgroundBlur < 100 && config.dmEnable) {
+ GlStateManager.translate(-centerX + backgroundSize / 2F, -centerY + backgroundSize / 2F, 0);
+ BackgroundBlur.renderBlurredBackground(config.dmBackgroundBlur,
+ scaledResolution.getScaledWidth(), scaledResolution.getScaledHeight(),
+ centerX - backgroundSize / 2, centerY - backgroundSize / 2, backgroundSize, backgroundSize
+ );
+ BackgroundBlur.markDirty();
+ GlStateManager.translate(centerX - backgroundSize / 2F, centerY - backgroundSize / 2F, 0);
+ }
+
+ GlStateManager.translate(backgroundCenter, backgroundCenter, 10);
+
+ if (!useFb || config.dmBackgroundBlur > 0.1 && config.dmBackgroundBlur < 100) {
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(
+ GL11.GL_SRC_ALPHA,
+ GL11.GL_ONE_MINUS_SRC_ALPHA,
+ GL11.GL_ONE,
+ GL11.GL_ONE_MINUS_SRC_ALPHA
+ );
+ }
+ Utils.drawRectNoBlend(
+ -backgroundCenter,
+ -backgroundCenter,
+ backgroundCenter,
+ backgroundCenter,
+ backgroundColour
+ );
+
+ float rotation = players.getMainPlayerRotation() + 180;
+
+ if (!config.dmRotatePlayer)
+ rotation = 0F;
+ GlStateManager.rotate(-rotation, 0, 0, 1);
+
+ if (config.dmCenterPlayer) {
+ float x = players.getMainPlayerX() * pixelToMapScale;
+ float y = players.getMainPlayerZ() * pixelToMapScale;
+
+ GlStateManager.translate(-x, -y, 0);
+ } else {
+ GlStateManager.translate(-mapSize / 2F, -mapSize / 2F, 0);
+ }
+
+ for (Map.Entry<RoomOffset, Room> entry : data.roomMap.entrySet()) {
+ Room room = entry.getValue();
+
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(room.posX * pixelToMapScale, room.posY * pixelToMapScale, 0);
+
+ room.render(renderRoomSize, renderConnSize);
+
+ GlStateManager.popMatrix();
+ }
+
+ GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
+
+ for (Map.Entry<RoomOffset, Room> entry : data.roomMap.entrySet()) {
+ Room room = entry.getValue();
+
+ GlStateManager.pushMatrix();
+
+ GlStateManager.translate(room.posX * pixelToMapScale, room.posY * pixelToMapScale, 0);
+ room.renderCheckmark(renderRoomSize, renderConnSize, rotation);
+
+ GlStateManager.popMatrix();
+ }
+
+ Tessellator tessellator = Tessellator.getInstance();
+ WorldRenderer worldrenderer = tessellator.getWorldRenderer();
+ int k = 0;
+ for (Map.Entry<String, DungeonMapPlayers.PlayerMarker> entry : players.getRunnerPositions().entrySet()) {
+ renderPlayer(
+ players,
+ pixelToMapScale,
+ renderRoomSize,
+ tessellator,
+ worldrenderer,
+ k--,
+ entry.getKey(),
+ entry.getValue()
+ );
+ }
+ for (DungeonMapPlayers.PlayerMarker orphanedMarker : players.getOrphanedMarkers().values()) {
+ renderPlayer(
+ players,
+ pixelToMapScale,
+ renderRoomSize,
+ tessellator,
+ worldrenderer,
+ k--,
+ null,
+ orphanedMarker
+ );
+ }
+ if (NEUDebugFlag.MAP.isSet())
+ players.getAllMapPositions().forEach((label, playerMarker) -> {
+ float x = playerMarker.x * pixelToMapScale;
+ float y = playerMarker.z * pixelToMapScale;
+ Utils.drawStringF(label, Minecraft.getMinecraft().fontRendererObj, x, y, true, 0xffd3d3d3);
+ });
+
+ if (useFb) {
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(
+ GL11.GL_SRC_ALPHA,
+ GL11.GL_ONE_MINUS_SRC_ALPHA,
+ GL11.GL_ONE,
+ GL11.GL_ONE_MINUS_SRC_ALPHA
+ );
+ } else {
+ GL11.glDisable(GL11.GL_SCISSOR_TEST);
+ }
+ }
+ GlStateManager.popMatrix();
+
+ if (useFb) {
+ Framebuffer renderFromBuffer = mapFramebuffer1;
+ if (useShd) {
+ GlStateManager.pushMatrix();
+ {
+ try {
+ upload(mapShader, projectionMatrix, backgroundSize, backgroundSize, scaleFactor, getBorderRadius());
+ mapShader.setProjectionMatrix(projectionMatrix);
+ mapShader.loadShader(0);
+ renderFromBuffer = mapFramebuffer2;
+ } catch (Exception ignored) {
+ }
+ }
+ GlStateManager.popMatrix();
+ }
+
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
+
+ Utils.pushGuiScale(2);
+
+ GlStateManager.translate(centerX, centerY, 100);
+
+ renderFromBuffer.bindFramebufferTexture();
+ Utils.drawTexturedRect(-backgroundSize / 2F, -backgroundSize / 2F, backgroundSize, backgroundSize,
+ 0, 1, 1, 0, GL11.GL_NEAREST
+ );
+ GlStateManager.bindTexture(0);
+
+ GlStateManager.translate(-centerX, -centerY, -100);
+
+ Utils.pushGuiScale(-1);
+ }
+
+ GlStateManager.translate(centerX, centerY, 100);
+
+ if (config.dmChromaBorder) {
+ int colour = SpecialColour.specialToChromaRGB(config.dmBorderColour);
+
+ Gui.drawRect(-backgroundCenter - 2, -backgroundCenter - 2, -backgroundCenter, -backgroundCenter,
+ colour
+ ); //topleft
+ Gui.drawRect(-backgroundCenter - 2, backgroundCenter + 2, -backgroundCenter, backgroundCenter,
+ SpecialColour.rotateHue(colour, -180)
+ ); //bottomleft
+ Gui.drawRect(backgroundCenter, -backgroundCenter - 2, backgroundCenter + 2, backgroundCenter,
+ SpecialColour.rotateHue(colour, -180)
+ ); //topright
+ Gui.drawRect(backgroundCenter, backgroundCenter, backgroundCenter + 2, backgroundCenter + 2,
+ colour
+ ); //bottomright
+
+ for (int i = 0; i < 20; i++) {
+ int start1 = SpecialColour.rotateHue(colour, -9 * i);
+ int start2 = SpecialColour.rotateHue(colour, -9 * i - 9);
+ int end1 = SpecialColour.rotateHue(colour, -180 - 9 * i);
+ int end2 = SpecialColour.rotateHue(colour, -180 - 9 * i - 9);
+
+ Utils.drawGradientRect(
+ -backgroundCenter - 2,
+ -backgroundCenter + (int) (backgroundSize * (i / 20f)),
+ -backgroundCenter,
+ -backgroundCenter + (int) (backgroundSize * ((i + 1) / 20f)),
+ start1,
+ start2
+ ); //left
+ Utils.drawGradientRect(
+ backgroundCenter,
+ -backgroundCenter + (int) (backgroundSize * (i / 20f)),
+ backgroundCenter + 2,
+ -backgroundCenter + (int) (backgroundSize * ((i + 1) / 20f)),
+ end1,
+ end2
+ ); //right
+ Utils.drawGradientRectHorz(-backgroundCenter + (int) (backgroundSize * (i / 20f)), -backgroundCenter - 2,
+ -backgroundCenter + (int) (backgroundSize * ((i + 1) / 20f)), -backgroundCenter, start1, start2
+ ); //top
+ Utils.drawGradientRectHorz(-backgroundCenter + (int) (backgroundSize * (i / 20f)),
+ backgroundCenter, -backgroundCenter + (int) (backgroundSize * ((i + 1) / 20f)), backgroundCenter + 2,
+ end1, end2
+ ); //bottom
+ }
+
+ } else {
+ Gui.drawRect(-backgroundCenter - 2, -backgroundCenter, -backgroundCenter, backgroundCenter,
+ SpecialColour.specialToChromaRGB(config.dmBorderColour)
+ ); //left
+ Gui.drawRect(backgroundCenter, -backgroundCenter, backgroundCenter + 2, backgroundCenter,
+ SpecialColour.specialToChromaRGB(config.dmBorderColour)
+ ); //right
+ Gui.drawRect(-backgroundCenter - 2, -backgroundCenter - 2, backgroundCenter + 2, -backgroundCenter,
+ SpecialColour.specialToChromaRGB(config.dmBorderColour)
+ ); //top
+ Gui.drawRect(-backgroundCenter - 2, backgroundCenter, backgroundCenter + 2, backgroundCenter + 2,
+ SpecialColour.specialToChromaRGB(config.dmBorderColour)
+ ); //bottom
+ }
+
+ String sizeId = borderSizeOption == 0 ? "small" : borderSizeOption == 2 ? "large" : "medium";
+
+ ResourceLocation rl = new ResourceLocation("notenoughupdates:dungeon_map/borders/" + sizeId + "/" +
+ config.dmBorderStyle + ".png");
+ if (Minecraft.getMinecraft().getTextureManager().getTexture(rl) != null) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(rl);
+ GlStateManager.color(1, 1, 1, 1);
+
+ int size = borderSizeOption == 0 ? 165 : borderSizeOption == 1 ? 220 : borderSizeOption == 2 ? 300 : 440;
+ Utils.drawTexturedRect(-size / 2, -size / 2, size, size, GL11.GL_NEAREST);
+ }
+
+ GlStateManager.translate(-centerX, -centerY, -100);
+ } catch (Exception e) {
+ e.printStackTrace();
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(true);
+ Minecraft.getMinecraft().entityRenderer.setupOverlayRendering();
+ }
+
+ Utils.pushGuiScale(-1);
+
+ GlStateManager.enableBlend();
+ GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0);
+ GlStateManager.enableDepth();
+ GlStateManager.disableLighting();
+ }
+
+ private void renderPlayer(
+ DungeonMapPlayers players,
+ float pixelToMapScale,
+ float renderRoomSize,
+ Tessellator tessellator,
+ WorldRenderer worldrenderer,
+ int k,
+ String name,
+ DungeonMapPlayers.PlayerMarker player
+ ) {
+
+ float x = player.x * pixelToMapScale;
+ float y = player.z * pixelToMapScale;
+ float angle = player.angle;
+
+ boolean isMainPlayer = name != null && name.equals(Minecraft.getMinecraft().thePlayer.getName());
+ float minU = isMainPlayer ? 1 / 4F : 3 / 4f;
+ float minV = 0;
+
+ float maxU = minU + 1 / 4f;
+ float maxV = minV + 1 / 4f;
+
+ boolean blackBorder = false;
+ boolean headLayer = false;
+ int pixelWidth = 8;
+ int pixelHeight = 8;
+ if (renderRoomSize >= 24) {
+ pixelWidth = pixelHeight = 12;
+ }
+ GlStateManager.color(1, 1, 1, 1);
+ if (config.dmPlayerHeads > 0 && (!isMainPlayer || NotEnoughUpdates.INSTANCE.config.dungeons.showOwnHeadAsMarker) &&
+ name != null) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(players.getSkin(name));
+
+ minU = 8 / 64f;
+ minV = 8 / 64f;
+ maxU = 16 / 64f;
+ maxV = 16 / 64f;
+
+ headLayer = true;
+ if (config.dmPlayerHeads >= 2) {
+ blackBorder = true;
+ }
+ } else {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(DungeonResources.MAP_ICONS);
+ }
+
+ GlStateManager.pushMatrix();
+
+ GlStateManager.disableDepth();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+
+ GlStateManager.translate(x, y, -0.02F);
+ GlStateManager.scale(config.dmIconScale, config.dmIconScale, 1);
+ GlStateManager.rotate(angle, 0.0F, 0.0F, 1.0F);
+
+ if (blackBorder) {
+ Gui.drawRect(-pixelWidth / 2 - 1, -pixelHeight / 2 - 1, pixelWidth / 2 + 1, pixelHeight / 2 + 1, 0xff111111);
+ GlStateManager.color(1, 1, 1, 1);
+ }
+
+ worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
+ worldrenderer.pos(-pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(minU, minV).endVertex();
+ worldrenderer.pos(pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(maxU, minV).endVertex();
+ worldrenderer.pos(pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(maxU, maxV).endVertex();
+ worldrenderer.pos(-pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F)).tex(minU, maxV).endVertex();
+ tessellator.draw();
+
+ if (headLayer) {
+ worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX);
+ worldrenderer
+ .pos(-pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f)
+ .tex(minU + 0.5f, minV)
+ .endVertex();
+ worldrenderer
+ .pos(pixelWidth / 2f, pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f)
+ .tex(maxU + 0.5f, minV)
+ .endVertex();
+ worldrenderer
+ .pos(pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f)
+ .tex(maxU + 0.5f, maxV)
+ .endVertex();
+ worldrenderer
+ .pos(-pixelWidth / 2f, -pixelHeight / 2f, 30 + ((float) k * -0.005F) + 0.001f)
+ .tex(minU + 0.5f, maxV)
+ .endVertex();
+ tessellator.draw();
+ }
+ GlStateManager.popMatrix();
+ }
+
+ public float getBorderRadius() {
+ int borderSizeOption = Math.round(config.dmBorderSize);
+ String sizeId = borderSizeOption == 0 ? "small" : borderSizeOption == 2 ? "large" : "medium";
+
+ int style = config.dmBorderStyle;
+ if (borderRadiusCache.containsKey(style)) {
+ return borderRadiusCache.get(style);
+ }
+
+ try (
+ BufferedReader reader = new BufferedReader(new InputStreamReader(Minecraft
+ .getMinecraft()
+ .getResourceManager()
+ .getResource(
+ new ResourceLocation("notenoughupdates:dungeon_map/borders/" + sizeId + "/" + style + ".json"))
+ .getInputStream(), StandardCharsets.UTF_8))
+ ) {
+ JsonObject json = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, JsonObject.class);
+ float radiusSq = json.get("radiusSq").getAsFloat();
+
+ borderRadiusCache.put(style, radiusSq);
+ return radiusSq;
+ } catch (Exception ignored) {
+ }
+
+ borderRadiusCache.put(style, 1f);
+ return 1f;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapStaticParser.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapStaticParser.java
new file mode 100644
index 00000000..c06d2e7a
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonMapStaticParser.java
@@ -0,0 +1,228 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.util.Vec4b;
+
+import java.awt.*;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class DungeonMapStaticParser {
+
+ public final DungeonMap dungeonMap;
+ public final Color[][] colorMap;
+ public final Map<String, Vec4b> mapDecorations;
+ public final String floorName;
+ public Map<RoomOffset, Room> roomMap = new HashMap<>();
+ int startRoomX, startRoomY;
+ int connectorSize = 5;
+ int roomSize = 0;
+
+ public DungeonMapStaticParser(DungeonMap dungeonMap, String floorName, Color[][] colorMap, Map<String, Vec4b> mapDecorations) {
+ this.dungeonMap = dungeonMap;
+ this.floorName = floorName;
+ this.colorMap = colorMap;
+ this.mapDecorations = mapDecorations;
+ }
+
+ public Color getColor(int x, int y) {
+ if (x < 0 || y < 0) return null;
+ if (x >= colorMap.length || y >= colorMap[0].length) return null;
+ return colorMap[x][y];
+ }
+
+ public Map<Color, Integer> aggregateColorInRectangle(int minX, int minY, int width, int height, int minAlpha) {
+ Map<Color, Integer> map = new HashMap<>();
+ int maxX = Math.min(minX + width, colorMap.length);
+ int maxY = Math.min(minY + height, colorMap[0].length);
+ for (int x = Math.max(0, minX); x < maxX; x++) {
+ for (int y = Math.max(0, minY); y < maxY; y++) {
+ Color color = colorMap[x][y];
+ if (color.getAlpha() < minAlpha) continue;
+ if (map.containsKey(color))
+ map.put(color, map.get(color) + 1);
+ else
+ map.put(color, 1);
+ }
+ }
+
+ return map;
+ }
+
+ public void updateRoomConnections(RoomOffset roomOffset) {
+ if (!roomMap.containsKey(roomOffset)) return;
+
+ Room room = roomMap.get(roomOffset);
+
+ Map<Color, Integer> aggregateColors = aggregateColorInRectangle(
+ startRoomX + roomOffset.x * (roomSize + connectorSize),
+ startRoomY + roomOffset.y * (roomSize + connectorSize),
+ roomSize, roomSize, 0
+ );
+
+ aggregateColors.entrySet().stream().filter(it -> !it.getKey().equals(room.colour))
+ .max(Comparator.comparingInt(Map.Entry::getValue))
+ .filter(it -> (float) it.getValue() / roomSize / connectorSize > 0.05)
+ .ifPresent(it -> {
+ room.checkmark = DungeonResources.Checkmark.valueOfColor(it.getKey());
+ });
+
+ for (int k = 0; k < 4; k++) {
+ boolean isVerticalDirection = (k % 2) == 0;
+
+ int width = isVerticalDirection ? roomSize : connectorSize;
+ int height = isVerticalDirection ? connectorSize : roomSize;
+ int x = startRoomX + roomOffset.x * (roomSize + connectorSize);
+ int y = startRoomY + roomOffset.y * (roomSize + connectorSize);
+
+ if (k == 0) {
+ y -= connectorSize;
+ } else if (k == 1) {
+ x -= connectorSize;
+ } else if (k == 2) {
+ y += roomSize;
+ } else {
+ x += roomSize;
+ }
+
+ Optional<Map.Entry<Color, Integer>> highestColor = aggregateColorInRectangle(x, y, width, height, 40).entrySet().stream().max(Comparator.comparingInt(Map.Entry::getValue));
+ if (!highestColor.isPresent()) continue;
+
+ float proportionFilled = (float) highestColor.get().getValue() / roomSize / connectorSize;
+
+ RoomConnectionType type = RoomConnectionType.WALL;
+ if (proportionFilled > 0.8) {
+ type = RoomConnectionType.ROOM_DIVIDER;
+ } else if (proportionFilled > 0.1) {
+ type = RoomConnectionType.CORRIDOR;
+ }
+ Color color = highestColor.get().getKey();
+ if (k == 0) {
+ room.up = new RoomConnection(type, color);
+ } else if (k == 1) {
+ room.left = new RoomConnection(type, color);
+ } else if (k == 2) {
+ room.down = new RoomConnection(type, color);
+ } else {
+ room.right = new RoomConnection(type, color);
+ }
+ }
+
+ int x = startRoomX + roomOffset.x * (roomSize + connectorSize) + roomSize + connectorSize / 2;
+ int y = startRoomY + roomOffset.y * (roomSize + connectorSize) + roomSize + connectorSize / 2;
+
+ room.fillCorner = false;
+ if (x > 0 && y > 0 && x < colorMap.length && y < colorMap[x].length) {
+ Color pixel = colorMap[x][y];
+ if (pixel.equals(room.colour)) {
+ room.fillCorner = true;
+ }
+ }
+ }
+
+
+ public boolean recalculateStartRoom() {
+ for (int x = 0; x < colorMap.length; x++) {
+ for (int y = 0; y < colorMap[x].length; y++) {
+ Color c = colorMap[x][y];
+ if (c.getAlpha() > 80) {
+ if (Utils.areRGBColorsEquals(c, DungeonResources.RoomColor.GREEN.getColor())) {
+ roomSize = 0;
+ out:
+ for (int xd = 0; xd <= 20; xd++) {
+ for (int yd = 0; yd <= 20; yd++) {
+ Color c2 = getColor(x + xd, y + yd);
+ if (c2 == null) continue;
+
+ if (c2.getGreen() != 124 || c2.getAlpha() <= 80) {
+ if (xd < 10 && yd < 10) {
+ break out;
+ }
+ } else {
+ roomSize = Math.max(roomSize, Math.min(xd + 1, yd + 1));
+ }
+ if (xd == 20 && yd == 20) {
+ if (roomSize == 0) roomSize = 20;
+ startRoomX = x;
+ startRoomY = y;
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ public boolean parseDungeonMap() {
+
+ if (!recalculateStartRoom())
+ return false;
+ recalculateConnectorSize();
+
+ loadNeighbors(new RoomOffset(0, 0));
+ for (RoomOffset offset : roomMap.keySet()) {
+ updateRoomConnections(offset);
+ }
+
+ return !roomMap.isEmpty();
+ }
+
+ public void loadNeighbors(RoomOffset room) {
+ if (roomMap.containsKey(room)) return;
+ int x = startRoomX + room.x * (roomSize + connectorSize);
+ int y = startRoomY + room.y * (roomSize + connectorSize);
+ Color color = getColor(x, y);
+ if (color == null || color.getAlpha() <= 100) return;
+ Room newRoom = new Room();
+ newRoom.colour = color;
+ newRoom.posX = x;
+ newRoom.posY = y;
+ roomMap.put(room, newRoom);
+ for (RoomOffset neighbor : room.getNeighbors()) {
+ loadNeighbors(neighbor);
+ }
+ }
+
+ private void recalculateConnectorSize() {
+ for (int i = 0; i < roomSize; i++) {
+ for (int k = 0; k < 4; k++) {
+ for (int j = 1; j < 8; j++) {
+ int x;
+ int y;
+
+ if (k == 0) {
+ x = startRoomX + i;
+ y = startRoomY - j;
+ } else if (k == 1) {
+ x = startRoomX + roomSize + j - 1;
+ y = startRoomY + i;
+ } else if (k == 2) {
+ x = startRoomX + i;
+ y = startRoomY + roomSize + j - 1;
+ } else {
+ x = startRoomX - j;
+ y = startRoomY + i;
+ }
+
+ if (x > 0 && y > 0 && x < colorMap.length && y < colorMap[x].length) {
+ if (colorMap[x][y].getAlpha() > 80) {
+ if (j == 1) {
+ break;
+ }
+ connectorSize = Math.min(connectorSize, j - 1);
+ }
+ }
+ }
+ }
+ }
+
+ if (connectorSize <= 0) {
+ connectorSize = 4;
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonResources.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonResources.java
new file mode 100644
index 00000000..41a6e064
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/DungeonResources.java
@@ -0,0 +1,86 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.util.ResourceLocation;
+
+import java.awt.Color;
+import java.util.Locale;
+
+public class DungeonResources {
+ public enum Checkmark {
+ CROSS("cross", 255, 0, 0),
+ GREEN("green_check", 0, 124, 0),
+ QUESTION("question", 13, 13, 13),
+ WHITE("white_check", 255, 255, 255);
+
+ public final ResourceLocation texture;
+ public final int r, g, b;
+
+ Checkmark(String name, int r, int g, int b) {
+ texture = new ResourceLocation("notenoughupdates", "dungeon_map/" + name + ".png");
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ }
+
+ public Color getColor() {
+ return new Color(r, g, b);
+ }
+
+ public static Checkmark valueOfColor(Color color) {
+ for (Checkmark checkmark : values()) {
+ if (Utils.areRGBColorsEquals(checkmark.getColor(), color))
+ return checkmark;
+ }
+ return null;
+ }
+ }
+
+ public enum RoomColor {
+ BROWN(114, 67, 27),
+ GRAY(65, 65, 65),
+ GREEN(0, 124, 0),
+ ORANGE(216, 127, 51),
+ PINK(242, 127, 165),
+ PURPLE(178, 76, 216),
+ RED(255, 0, 0),
+ YELLOW(229, 229, 51);
+
+ private final int r, g, b;
+ private final ResourceLocation roomTexture, corridorTexture;
+
+ RoomColor(int r, int g, int b) {
+ this.r = r;
+ this.g = g;
+ this.b = b;
+ this.roomTexture = new ResourceLocation("notenoughupdates", "dungeon_map/rooms_default/" + name().toLowerCase(Locale.ROOT) + "_room.png");
+ this.corridorTexture = new ResourceLocation("notenoughupdates", "dungeon_map/corridors_default/" + name().toLowerCase(Locale.ROOT) + "_corridor.png");
+ }
+
+ public Color getColor() {
+ return new Color(r, g, b);
+ }
+
+ public static RoomColor valueOfColor(Color color) {
+ for (DungeonResources.RoomColor roomColor : DungeonResources.RoomColor.values()) {
+ if (Utils.areRGBColorsEquals(roomColor.getColor(), color)) {
+ return roomColor;
+ }
+ }
+ return null;
+ }
+
+ public ResourceLocation getRoomTexture() {
+ return roomTexture;
+ }
+
+ public ResourceLocation getCorridorTexture() {
+ return corridorTexture;
+ }
+ }
+
+ public static final ResourceLocation MAP_ICONS = new ResourceLocation("textures/map/map_icons.png");
+
+ public static final ResourceLocation DIVIDER_BROWN = new ResourceLocation("notenoughupdates:dungeon_map/dividers_default/brown_divider.png");
+ public static final ResourceLocation CORNER_BROWN = new ResourceLocation("notenoughupdates:dungeon_map/corners_default/brown_corner.png");
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/Room.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/Room.java
new file mode 100644
index 00000000..585f3d72
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/Room.java
@@ -0,0 +1,122 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.Gui;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.Color;
+
+class Room {
+ Color colour = new Color(0, 0, 0, 0);
+ DungeonResources.Checkmark checkmark = null;
+ boolean fillCorner = false;
+ int posX, posY;
+
+ RoomConnection left = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
+ RoomConnection up = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
+ RoomConnection right = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
+ RoomConnection down = new RoomConnection(RoomConnectionType.NONE, new Color(0, true));
+
+ public void renderCheckmark(float roomSize, float connectorSize, float rotation) {
+ if (checkmark == null) return;
+ Minecraft.getMinecraft().getTextureManager().bindTexture(checkmark.texture);
+ float x = roomSize / 2;
+ float y = roomSize / 2;
+
+ if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterCheck) { // TODO extract config option
+ if (fillCorner) {
+ x += (roomSize + connectorSize) / 2F;
+ y += (roomSize + connectorSize) / 2F;
+ }
+ if (down.type == RoomConnectionType.ROOM_DIVIDER && right.type != RoomConnectionType.ROOM_DIVIDER) {
+ y += (roomSize + connectorSize) / 2f;
+ } else if (down.type != RoomConnectionType.ROOM_DIVIDER && right.type == RoomConnectionType.ROOM_DIVIDER) {
+ x += (roomSize + connectorSize) / 2f;
+ }
+ }
+ GlStateManager.translate(x, y, 0);
+ if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmOrientCheck) {
+ GlStateManager.rotate(rotation, 0, 0, 1);
+ }
+ GlStateManager.scale(NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale,
+ NotEnoughUpdates.INSTANCE.config.dungeonMap.dmIconScale, 1);
+ Utils.drawTexturedRect(-5, -5, 10, 10, GL11.GL_NEAREST);
+ }
+
+ public void render(float roomSize, float connectorSize) {
+ DungeonResources.RoomColor roomColor = DungeonResources.RoomColor.valueOfColor(this.colour);
+ if (roomColor != null) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(roomColor.getRoomTexture());
+ GlStateManager.color(1, 1, 1, 1);
+ Utils.drawTexturedRect(0, 0, roomSize, roomSize, GL11.GL_LINEAR);
+ } else {
+ Gui.drawRect(0, 0, (int) roomSize, (int) roomSize, colour.getRGB());
+ }
+
+ if (fillCorner) {
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(DungeonResources.CORNER_BROWN);
+ Utils.drawTexturedRect(roomSize, roomSize, connectorSize, connectorSize, GL11.GL_NEAREST);
+ }
+
+ for (RoomConnection connection : new RoomConnection[]{down, right}) {
+ ResourceLocation corridorTex = null;
+ switch (connection.type) {
+ case CORRIDOR:
+ DungeonResources.RoomColor corridorColor = DungeonResources.RoomColor.valueOfColor(connection.colour);
+ if (corridorColor != null)
+ corridorTex = corridorColor.getCorridorTexture();
+ break;
+ case ROOM_DIVIDER:
+ corridorTex = DungeonResources.DIVIDER_BROWN;
+ break;
+ default:
+ continue;
+ }
+
+ if (corridorTex == null) {
+ int xOffset = 0;
+ int yOffset = 0;
+ int width = 0;
+ int height = 0;
+
+ if (connection == right) {
+ xOffset = (int) roomSize;
+ width = (int) connectorSize;
+ height = (int) roomSize;
+
+ if (connection.type == RoomConnectionType.CORRIDOR) {
+ height = 8;
+ yOffset += 4;
+ }
+ } else if (connection == down) {
+ yOffset = (int) roomSize;
+ width = (int) roomSize;
+ height = (int) connectorSize;
+
+ if (connection.type == RoomConnectionType.CORRIDOR) {
+ width = 8;
+ xOffset += 4;
+ }
+ }
+
+ Gui.drawRect(xOffset, yOffset, xOffset + width + 1, yOffset + height + 1, connection.colour.getRGB());
+ } else {
+ GlStateManager.color(1, 1, 1, 1);
+ Minecraft.getMinecraft().getTextureManager().bindTexture(corridorTex);
+ GlStateManager.pushMatrix();
+ if (connection == right) {
+ GlStateManager.translate(roomSize / 2f, roomSize / 2f, 0);
+ GlStateManager.rotate(-90, 0, 0, 1);
+ GlStateManager.translate(-roomSize / 2f, -roomSize / 2f, 0);
+ }
+ Utils.drawTexturedRect(0, roomSize, roomSize, connectorSize, GL11.GL_NEAREST);
+ GlStateManager.popMatrix();
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnection.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnection.java
new file mode 100644
index 00000000..04f701d2
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnection.java
@@ -0,0 +1,28 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import java.awt.Color;
+import java.util.Objects;
+
+class RoomConnection {
+ RoomConnectionType type;
+ Color colour;
+
+ public RoomConnection(RoomConnectionType type, Color colour) {
+ this.type = type;
+ this.colour = colour;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RoomConnection that = (RoomConnection) o;
+ return type == that.type &&
+ Objects.equals(colour, that.colour);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, colour);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnectionType.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnectionType.java
new file mode 100644
index 00000000..6c283279
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomConnectionType.java
@@ -0,0 +1,5 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+enum RoomConnectionType {
+ NONE, WALL, CORRIDOR, ROOM_DIVIDER
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomOffset.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomOffset.java
new file mode 100644
index 00000000..32bb8e78
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/map/RoomOffset.java
@@ -0,0 +1,46 @@
+package io.github.moulberry.notenoughupdates.dungeons.map;
+
+import java.util.Objects;
+
+class RoomOffset {
+ int x;
+ int y;
+
+ public RoomOffset(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public RoomOffset left() {
+ return new RoomOffset(x - 1, y);
+ }
+
+ public RoomOffset right() {
+ return new RoomOffset(x + 1, y);
+ }
+
+ public RoomOffset up() {
+ return new RoomOffset(x, y - 1);
+ }
+
+ public RoomOffset down() {
+ return new RoomOffset(x, y + 1);
+ }
+
+ public RoomOffset[] getNeighbors() {
+ return new RoomOffset[]{left(), right(), up(), down()};
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ RoomOffset that = (RoomOffset) o;
+ return x == that.x && y == that.y;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(x, y);
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java
index 8e0e4c11..07f9979e 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java
@@ -19,13 +19,54 @@
package io.github.moulberry.notenoughupdates.options.customtypes;
+import io.github.moulberry.notenoughupdates.util.NEUDebugLogger;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
public enum NEUDebugFlag {
// NOTE: Removing enum values causes gson to remove all debugFlags on load if any removed value is present
- METAL,
- WISHING,
+ METAL("Metal Detector Solver"),
+ WISHING("Wishing Compass Solver"),
+ MAP("Dungeon Map Player Information"),
;
- public static final String FLAG_LIST =
- "METAL - Metal Detector Solver\n" +
- "WISHING - Wishing Compass Solver";
+ private final String description;
+
+ NEUDebugFlag(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public boolean isSet() {
+ return NEUDebugLogger.isFlagEnabled(this);
+ }
+
+ public static String getFlagList() {
+ return renderFlagInformation(Arrays.asList(values()));
+ }
+
+ public static String getEnabledFlags() {
+ return renderFlagInformation(Arrays.stream(values())
+ .filter(NEUDebugFlag::isSet)
+ .collect(Collectors.toList()));
+ }
+
+ public static String renderFlagInformation(List<NEUDebugFlag> flags) {
+ int maxNameLength = flags.stream()
+ .mapToInt(it -> it.name().length())
+ .max()
+ .orElse(0);
+ return flags.stream()
+ .map(it -> (CharSequence) String.format(
+ "%-" + maxNameLength + "s" + " - %s",
+ it.name(),
+ it.getDescription()
+ ))
+ .collect(Collectors.joining("\n"));
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
index 230b8ae5..17842f43 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/NEUDebugLogger.java
@@ -38,11 +38,11 @@ public class NEUDebugLogger {
}
public static boolean isFlagEnabled(NEUDebugFlag flag) {
- return NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(flag);
+ return allFlagsEnabled || NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.contains(flag);
}
public static void log(NEUDebugFlag flag, String message) {
- if (logMethod != null && (allFlagsEnabled || isFlagEnabled(flag))) {
+ if (logMethod != null && isFlagEnabled(flag)) {
logAlways(message);
}
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/RecencyList.java b/src/main/java/io/github/moulberry/notenoughupdates/util/RecencyList.java
new file mode 100644
index 00000000..00d555fe
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/RecencyList.java
@@ -0,0 +1,130 @@
+package io.github.moulberry.notenoughupdates.util;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+public class RecencyList<T> {
+
+ public class Entry<T> {
+ private final T value;
+ private Instant timestamp;
+ private boolean toRemove;
+
+ public Entry(T value, Instant timestamp) {
+ this.value = value;
+ this.timestamp = timestamp;
+ }
+
+ public Instant timesOutAt() {
+ return timestamp.plus(timeout);
+ }
+
+ public void refresh() {
+ timestamp = Instant.now();
+ toRemove = false;
+ }
+
+ public boolean isTimedOut(Instant at) {
+ return toRemove || timesOutAt().isBefore(at);
+ }
+
+ @Override
+ @SuppressWarnings({"unchecked"})
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Entry<?> entry = (Entry<?>) o;
+ return Objects.equals(timestamp, entry.timestamp) && Objects.equals(value, entry.value);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(timestamp, value);
+ }
+
+ public T getValue() {
+ return value;
+ }
+ }
+
+ public class Finalized<T> extends AbstractList<T> {
+ private final List<RecencyList<T>.Entry<T>> unmodifiedCopy;
+
+ public Finalized(List<RecencyList<T>.Entry<T>> unmodifiedCopy) {this.unmodifiedCopy = unmodifiedCopy;}
+
+ @Override
+ public T get(int index) {
+ return unmodifiedCopy.get(index).value;
+ }
+
+ @Override
+ public int size() {
+ return unmodifiedCopy.size();
+ }
+
+ public List<RecencyList<T>.Entry<T>> getTimedList() {
+ return unmodifiedCopy;
+ }
+ }
+
+ public RecencyList(Duration keepAliveDuration) {
+ this.timeout = keepAliveDuration;
+ }
+
+ // I feel like a Map<T, Entry<T>> would be faster, but I really don't care.
+ private final Duration timeout;
+ private final List<Entry<T>> entries = new ArrayList<>();
+ private List<Entry<T>> unmodifiedCopy = new ArrayList<>();
+ private Instant nextCheckAt = null;
+ private boolean checkNow = false;
+
+ public void ensureTimedOrdering() {
+ Instant now = Instant.now();
+ if (checkNow || (nextCheckAt != null && nextCheckAt.isBefore(now))) {
+ entries.removeIf(it -> it.isTimedOut(now));
+ entries.sort(Comparator.comparing(Entry::timesOutAt));
+ unmodifiedCopy = new ArrayList<>(entries);
+
+ nextCheckAt = entries.isEmpty() ? null : entries.get(entries.size() - 1).timesOutAt();
+ checkNow = false;
+ }
+ }
+
+ public Finalized<T> getList() {
+ ensureTimedOrdering();
+ return new Finalized<>(unmodifiedCopy);
+ }
+
+ public void add(T value) {
+ for (Entry<T> entry : entries) {
+ if (Objects.equals(entry.value, value)) {
+ entry.refresh();
+ return;
+ }
+ }
+ checkNow = true;
+ entries.add(new Entry<>(value, Instant.now()));
+ }
+
+ public void remove(T value) {
+ for (Entry<T> entry : entries) {
+ if (Objects.equals(entry.value, value)) {
+ entry.toRemove = true;
+ checkNow = true;
+ return;
+ }
+ }
+ }
+
+ public void addAll(Collection<? extends T> collection) {
+ for (T t : collection) {
+ add(t);
+ }
+ }
+}
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 f45b840c..d474b150 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -44,6 +44,7 @@ import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.resources.model.IBakedModel;
+import net.minecraft.client.shader.Framebuffer;
import net.minecraft.event.ClickEvent;
import net.minecraft.event.HoverEvent;
import net.minecraft.init.Items;
@@ -1970,4 +1971,19 @@ public class Utils {
}
return -1;
}
+ public static Framebuffer ensureFramebufferSize(Framebuffer framebuffer, int width, int height) {
+ if (framebuffer == null || framebuffer.framebufferWidth != width || framebuffer.framebufferHeight != height) {
+ if (framebuffer == null) {
+ framebuffer = new Framebuffer(width, height, true);
+ } else {
+ framebuffer.createBindFramebuffer(width, height);
+ }
+ framebuffer.setFramebufferFilter(GL11.GL_NEAREST);
+ }
+ return framebuffer;
+ }
+
+ public static boolean areRGBColorsEquals(Color a, Color b) {
+ return (a.getRGB() & 0xFFFFFF) == (b.getRGB() & 0xFFFFFF);
+ }
}
diff --git a/src/main/resources/assets/notenoughupdates/dungeon_map/corridors_default/black_corridor.png b/src/main/resources/assets/notenoughupdates/dungeon_map/corridors_default/black_corridor.png
new file mode 100644
index 00000000..640c5388
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/dungeon_map/corridors_default/black_corridor.png
Binary files differ