From 6f00f738c29dd296fe962c990b0221092d29fb53 Mon Sep 17 00:00:00 2001 From: syeyoung Date: Mon, 23 Jan 2023 00:12:17 +0900 Subject: - taught dg about procrastination => Lazy dungeon building => Fixes #233 => Fixes #264 Signed-off-by: syeyoung --- .../syeyoung/dungeonsguide/mod/SkyblockStatus.java | 4 +- .../dungeonsguide/mod/commands/CommandDgDebug.java | 176 +++---- .../mod/discord/DiscordIntegrationManager.java | 2 +- .../dungeonsguide/mod/dungeon/DungeonContext.java | 168 ++++--- .../dungeonsguide/mod/dungeon/MapProcessor.java | 543 --------------------- .../mod/dungeon/events/DungeonEventRecorder.java | 58 +++ .../events/impl/DungeonRoomDiscoverEvent.java | 4 - .../dungeon/events/impl/DungeonRoomMatchEvent.java | 46 ++ .../dungeon/map/DungeonMapConstantRetreiver.java | 139 ++++++ .../mod/dungeon/map/DungeonMapData.java | 139 ------ .../mod/dungeon/map/DungeonMapLayout.java | 70 +++ .../mod/dungeon/map/DungeonRoomScaffoldParser.java | 265 ++++++++++ .../mod/dungeon/map/MapPlayerProcessor.java | 177 +++++++ .../mod/dungeon/roomfinder/DungeonRoom.java | 69 ++- .../mod/dungeon/roomfinder/RoomMatcher.java | 1 + .../roomprocessor/GeneralRoomProcessor.java | 4 +- .../mod/events/impl/MapUpdateEvent.java | 35 ++ .../mod/events/listener/DungeonListener.java | 249 +++++----- .../mod/events/listener/PacketInjector.java | 1 + .../mod/events/listener/PacketListener.java | 6 + .../features/impl/advanced/FeatureDebugTrap.java | 2 +- .../impl/advanced/FeatureRoomCoordDisplay.java | 9 +- .../impl/advanced/FeatureRoomDebugInfo.java | 5 +- .../features/impl/boss/FeatureWarningOnPortal.java | 6 +- .../features/impl/dungeon/FeatureCollectScore.java | 3 +- .../impl/dungeon/FeatureDungeonDeaths.java | 31 +- .../features/impl/dungeon/FeatureDungeonMap.java | 36 +- .../impl/dungeon/FeatureDungeonMilestone.java | 11 +- .../impl/dungeon/FeatureDungeonRoomName.java | 8 +- .../features/impl/dungeon/FeatureDungeonScore.java | 18 +- .../impl/dungeon/FeatureDungeonSecrets.java | 15 +- .../impl/dungeon/FeatureWatcherWarning.java | 5 +- .../mod/features/impl/party/FeaturePartyReady.java | 4 +- .../mod/features/impl/secret/FeatureActions.java | 10 +- .../impl/secret/FeatureSoulRoomWarning.java | 6 +- .../mechanicbrowser/FeatureMechanicBrowse.java | 20 +- .../mod/parallelUniverse/map/MapDataManager.java | 49 ++ 37 files changed, 1319 insertions(+), 1075 deletions(-) delete mode 100755 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/MapProcessor.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/DungeonEventRecorder.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomMatchEvent.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapConstantRetreiver.java delete mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapData.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapLayout.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonRoomScaffoldParser.java create mode 100755 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/MapPlayerProcessor.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/events/impl/MapUpdateEvent.java create mode 100644 mod/src/main/java/kr/syeyoung/dungeonsguide/mod/parallelUniverse/map/MapDataManager.java (limited to 'mod/src/main/java') diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/SkyblockStatus.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/SkyblockStatus.java index dc48415f..e74b69da 100755 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/SkyblockStatus.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/SkyblockStatus.java @@ -41,6 +41,8 @@ import java.util.Set; public class SkyblockStatus { boolean wasOnHypixel = false; + public static String locationName; + @SubscribeEvent public void onTick(TickEvent.ClientTickEvent ev) { @@ -144,7 +146,7 @@ public class SkyblockStatus { } } if (sc.getJustTeam().startsWith(" §7⏣")) { - DungeonContext.setDungeonName(strippedLine.trim()); + locationName = strippedLine.trim(); } } diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java index 45eb7dd2..b6742c9c 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/commands/CommandDgDebug.java @@ -24,23 +24,17 @@ import kr.syeyoung.dungeonsguide.dungeon.mechanics.*; import kr.syeyoung.dungeonsguide.dungeon.mechanics.dunegonmechanic.DungeonMechanic; import kr.syeyoung.dungeonsguide.launcher.Main; import kr.syeyoung.dungeonsguide.mod.DungeonsGuide; +import kr.syeyoung.dungeonsguide.mod.SkyblockStatus; import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter; import kr.syeyoung.dungeonsguide.mod.config.guiconfig.NestedCategory; import kr.syeyoung.dungeonsguide.mod.dungeon.DungeonContext; -import kr.syeyoung.dungeonsguide.mod.dungeon.MapProcessor; -import kr.syeyoung.dungeonsguide.mod.dungeon.doorfinder.DungeonSpecificDataProvider; -import kr.syeyoung.dungeonsguide.mod.dungeon.doorfinder.DungeonSpecificDataProviderRegistry; import kr.syeyoung.dungeonsguide.mod.dungeon.events.DungeonEventHolder; -import kr.syeyoung.dungeonsguide.mod.dungeon.roomedit.EditingContext; -import kr.syeyoung.dungeonsguide.mod.dungeon.roomedit.gui.GuiDungeonRoomEdit; import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom; import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoomInfoRegistry; import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.GeneralRoomProcessor; -import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.bossfight.BossfightProcessor; import kr.syeyoung.dungeonsguide.mod.events.impl.DungeonLeftEvent; import kr.syeyoung.dungeonsguide.mod.features.AbstractFeature; import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; -import kr.syeyoung.dungeonsguide.mod.features.impl.dungeon.FeatureDungeonMap; import kr.syeyoung.dungeonsguide.mod.guiv2.GuiScreenAdapter; import kr.syeyoung.dungeonsguide.mod.guiv2.view.TestView; import kr.syeyoung.dungeonsguide.mod.parallelUniverse.scoreboard.Score; @@ -51,30 +45,19 @@ import kr.syeyoung.dungeonsguide.mod.party.PartyContext; import kr.syeyoung.dungeonsguide.mod.party.PartyManager; import kr.syeyoung.dungeonsguide.mod.utils.AhUtils; import kr.syeyoung.dungeonsguide.mod.utils.MapUtils; -import kr.syeyoung.dungeonsguide.mod.utils.ShortUtils; -import kr.syeyoung.dungeonsguide.mod.utils.TabListUtil; import kr.syeyoung.dungeonsguide.mod.wsresource.StaticResourceCache; -import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.client.network.NetworkPlayerInfo; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.scoreboard.ScorePlayerTeam; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.Tuple; -import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; -import javax.vecmath.Vector2d; import java.awt.*; import java.io.*; import java.nio.file.Files; @@ -82,7 +65,6 @@ import java.security.*; import java.security.cert.CertificateException; import java.util.List; import java.util.*; -import java.util.regex.Pattern; public class CommandDgDebug extends CommandBase { @Override @@ -179,9 +161,9 @@ public class CommandDgDebug extends CommandBase { EntityPlayerSP thePlayer = Minecraft.getMinecraft().thePlayer; if (thePlayer == null) return; if (context.getBossfightProcessor() != null) context.getBossfightProcessor().tick(); - Point roomPt = context.getMapProcessor().worldPointToRoomPoint(thePlayer.getPosition()); + Point roomPt = context.getScaffoldParser().getDungeonMapLayout().worldPointToRoomPoint(thePlayer.getPosition()); - DungeonRoom dungeonRoom = context.getRoomMapper().get(roomPt); + DungeonRoom dungeonRoom = context.getScaffoldParser().getRoomMap().get(roomPt); GeneralRoomProcessor grp = (GeneralRoomProcessor) dungeonRoom.getRoomProcessor(); grp.pathfind("COMMAND", args[1], args[2], FeatureRegistry.SECRET_LINE_PROPERTIES_GLOBAL.getRouteProperties()); } catch (Throwable t) { @@ -283,7 +265,7 @@ public class CommandDgDebug extends CommandBase { } else if ("partyid".equals(arg)) { sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fInternal Party id: " + Optional.ofNullable(PartyManager.INSTANCE.getPartyContext()).map(PartyContext::getPartyID).orElse(null))); } else if ("loc".equals(arg)) { - sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fYou're in " + DungeonContext.getDungeonName())); + sender.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §fYou're in " + SkyblockStatus.locationName)); } else if ("saverun".equals(arg)) { try { File f = Main.getConfigDir(); @@ -300,7 +282,7 @@ public class CommandDgDebug extends CommandBase { DungeonEventHolder dungeonEventHolder = new DungeonEventHolder(); dungeonEventHolder.setDate(dungeonContext.getInit()); dungeonEventHolder.setPlayers(dungeonContext.getPlayers()); - dungeonEventHolder.setEventDataList(dungeonContext.getEvents()); + dungeonEventHolder.setEventDataList(dungeonContext.getRecorder().getEvents()); ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(runFile.toPath())); @@ -318,80 +300,80 @@ public class CommandDgDebug extends CommandBase { sender.addChatMessage(new ChatComponentText(a.getResourceID() + ": " + a.getValue() + ": " + a.isExists())); }); } else if ("createfakeroom".equals(arg)) {// load schematic - File f = new File(Main.getConfigDir(), "schematics/new roonm-b2df250c-4af2-4201-963c-0ee1cb6bd3de-5efb1f0c-c05f-4064-bde7-cad0874fdf39.schematic"); - NBTTagCompound compound; - try { - compound = CompressedStreamTools.readCompressed(new FileInputStream(f)); - } catch (IOException e) { - e.printStackTrace(); - return; - } - - byte[] blocks = compound.getByteArray("Blocks"); - byte[] meta = compound.getByteArray("Data"); - for (int x = 0; x < compound.getShort("Width"); x++) { - for (int y = 0; y < compound.getShort("Height"); y++) { - for (int z = 0; z < compound.getShort("Length"); z++) { - int index = x + (y * compound.getShort("Length") + z) * compound.getShort("Width"); - BlockPos pos = new BlockPos(x, y, z); - World w = MinecraftServer.getServer().getEntityWorld(); - w.setBlockState(pos, Block.getBlockById(blocks[index] & 0xFF).getStateFromMeta(meta[index] & 0xFF), 2); - } - } - } - - - DungeonSpecificDataProviderRegistry.doorFinders.put(Pattern.compile("TEST DG"), new DungeonSpecificDataProvider() { - @Override - public BlockPos findDoor(World w, String dungeonName) { - return new BlockPos(0, 0, 0); - } - - @Override - public Vector2d findDoorOffset(World w, String dungeonName) { - return null; - } - - @Override - public BossfightProcessor createBossfightProcessor(World w, String dungeonName) { - return null; - } - - @Override - public boolean isTrapSpawn(String dungeonName) { - return false; - } - - @Override - public double secretPercentage(String dungeonName) { - return 0; - } - - @Override - public int speedSecond(String dungeonName) { - return 0; - } - }); - DungeonContext.setDungeonName("TEST DG"); - DungeonContext fakeContext = new DungeonContext(Minecraft.getMinecraft().theWorld); - DungeonsGuide.getDungeonsGuide().getDungeonFacade().setContext(fakeContext); - DungeonsGuide.getDungeonsGuide().getSkyblockStatus().setForceIsOnDungeon(true); - MapProcessor mapProcessor = fakeContext.getMapProcessor(); - mapProcessor.setUnitRoomDimension(new Dimension(16, 16)); - mapProcessor.setBugged(false); - mapProcessor.setDoorDimensions(new Dimension(4, 4)); - mapProcessor.setTopLeftMapPoint(new Point(0, 0)); - fakeContext.setDungeonMin(new BlockPos(0, 70, 0)); - - DungeonRoom dungeonRoom = new DungeonRoom(Arrays.asList(new Point(0, 0)), ShortUtils.topLeftifyInt((short) 1), (byte) 63, new BlockPos(0, 70, 0), new BlockPos(31, 70, 31), fakeContext, Collections.emptySet()); - - fakeContext.getDungeonRoomList().add(dungeonRoom); - for (Point p : Arrays.asList(new Point(0, 0))) { - fakeContext.getRoomMapper().put(p, dungeonRoom); - } - - EditingContext.createEditingContext(dungeonRoom); - EditingContext.getEditingContext().openGui(new GuiDungeonRoomEdit(dungeonRoom)); +// File f = new File(Main.getConfigDir(), "schematics/new roonm-b2df250c-4af2-4201-963c-0ee1cb6bd3de-5efb1f0c-c05f-4064-bde7-cad0874fdf39.schematic"); +// NBTTagCompound compound; +// try { +// compound = CompressedStreamTools.readCompressed(new FileInputStream(f)); +// } catch (IOException e) { +// e.printStackTrace(); +// return; +// } +// +// byte[] blocks = compound.getByteArray("Blocks"); +// byte[] meta = compound.getByteArray("Data"); +// for (int x = 0; x < compound.getShort("Width"); x++) { +// for (int y = 0; y < compound.getShort("Height"); y++) { +// for (int z = 0; z < compound.getShort("Length"); z++) { +// int index = x + (y * compound.getShort("Length") + z) * compound.getShort("Width"); +// BlockPos pos = new BlockPos(x, y, z); +// World w = MinecraftServer.getServer().getEntityWorld(); +// w.setBlockState(pos, Block.getBlockById(blocks[index] & 0xFF).getStateFromMeta(meta[index] & 0xFF), 2); +// } +// } +// } +// +// +// DungeonSpecificDataProviderRegistry.doorFinders.put(Pattern.compile("TEST DG"), new DungeonSpecificDataProvider() { +// @Override +// public BlockPos findDoor(World w, String dungeonName) { +// return new BlockPos(0, 0, 0); +// } +// +// @Override +// public Vector2d findDoorOffset(World w, String dungeonName) { +// return null; +// } +// +// @Override +// public BossfightProcessor createBossfightProcessor(World w, String dungeonName) { +// return null; +// } +// +// @Override +// public boolean isTrapSpawn(String dungeonName) { +// return false; +// } +// +// @Override +// public double secretPercentage(String dungeonName) { +// return 0; +// } +// +// @Override +// public int speedSecond(String dungeonName) { +// return 0; +// } +// }); +// DungeonContext.setDungeonName("TEST DG"); +// DungeonContext fakeContext = new DungeonContext(Minecraft.getMinecraft().theWorld); +// DungeonsGuide.getDungeonsGuide().getDungeonFacade().setContext(fakeContext); +// DungeonsGuide.getDungeonsGuide().getSkyblockStatus().setForceIsOnDungeon(true); +// MapPlayerProcessor mapProcessor = fakeContext.getp(); +// mapProcessor.setUnitRoomDimension(new Dimension(16, 16)); +// mapProcessor.setBugged(false); +// mapProcessor.setDoorDimensions(new Dimension(4, 4)); +// mapProcessor.setTopLeftMapPoint(new Point(0, 0)); +// fakeContext.setDungeonMin(new BlockPos(0, 70, 0)); +// +// DungeonRoom dungeonRoom = new DungeonRoom(Arrays.asList(new Point(0, 0)), ShortUtils.topLeftifyInt((short) 1), (byte) 63, new BlockPos(0, 70, 0), new BlockPos(31, 70, 31), fakeContext, Collections.emptySet()); +// +// fakeContext.getDungeonRoomList().add(dungeonRoom); +// for (Point p : Arrays.asList(new Point(0, 0))) { +// fakeContext.getRoomMapper().put(p, dungeonRoom); +// } +// +// EditingContext.createEditingContext(dungeonRoom); +// EditingContext.getEditingContext().openGui(new GuiDungeonRoomEdit(dungeonRoom)); } else if ("closecontext".equals(arg)) { DungeonsGuide.getDungeonsGuide().getSkyblockStatus().setForceIsOnDungeon(false); diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java index 601783cd..35684242 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/discord/DiscordIntegrationManager.java @@ -199,7 +199,7 @@ public class DiscordIntegrationManager implements IPCListener { if (!skyblockStatus.isOnHypixel() || !FeatureRegistry.DISCORD_RICHPRESENCE.isEnabled() || (!skyblockStatus.isOnSkyblock() && FeatureRegistry.DISCORD_RICHPRESENCE.getParameter("disablenotskyblock").getValue())) { sendRichPresence(null); } else { - String name = DungeonContext.getDungeonName() == null ? "" : DungeonContext.getDungeonName(); + String name = SkyblockStatus.locationName == null ? "" : SkyblockStatus.locationName; if (!skyblockStatus.isOnSkyblock()) name ="Somewhere on Hypixel"; if (name.trim().equals("Your Island")) name = "Private Island"; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/DungeonContext.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/DungeonContext.java index 8041f6ac..037eb442 100755 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/DungeonContext.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/DungeonContext.java @@ -22,17 +22,20 @@ package kr.syeyoung.dungeonsguide.mod.dungeon; import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter; import kr.syeyoung.dungeonsguide.mod.dungeon.doorfinder.DungeonSpecificDataProvider; import kr.syeyoung.dungeonsguide.mod.dungeon.doorfinder.DungeonSpecificDataProviderRegistry; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.DungeonEvent; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.DungeonEventData; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonCryptBrokenEvent; +import kr.syeyoung.dungeonsguide.mod.dungeon.events.DungeonEventRecorder; import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonNodataEvent; import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonPuzzleFailureEvent; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonSecretCountChangeEvent; +import kr.syeyoung.dungeonsguide.mod.dungeon.map.DungeonMapConstantRetreiver; +import kr.syeyoung.dungeonsguide.mod.dungeon.map.DungeonMapLayout; +import kr.syeyoung.dungeonsguide.mod.dungeon.map.DungeonRoomScaffoldParser; +import kr.syeyoung.dungeonsguide.mod.dungeon.map.MapPlayerProcessor; import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom; import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.RoomProcessor; import kr.syeyoung.dungeonsguide.mod.dungeon.roomprocessor.bossfight.BossfightProcessor; import kr.syeyoung.dungeonsguide.mod.events.impl.BossroomEnterEvent; +import kr.syeyoung.dungeonsguide.mod.events.impl.MapUpdateEvent; import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.mod.utils.MapUtils; import kr.syeyoung.dungeonsguide.mod.utils.TabListUtil; import kr.syeyoung.dungeonsguide.mod.utils.TextUtils; import lombok.Getter; @@ -45,72 +48,52 @@ import net.minecraft.world.World; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.common.MinecraftForge; +import javax.vecmath.Vector2d; import java.awt.*; import java.util.List; import java.util.*; public class DungeonContext { - /** - * This is static because its used in the constructor, - * it means we cannot set the name without having an object, - * and we cannot create an object without the name - * so its static :) - */ @Getter @Setter - private static String dungeonName; - @Getter - @Setter - public int percentage; + private String dungeonName; @Getter private final World world; @Getter - private final MapProcessor mapProcessor; - - @Getter - @Setter - private BlockPos dungeonMin; - + private final MapPlayerProcessor mapPlayerMarkerProcessor; @Getter - private final Map roomMapper = new HashMap<>(); + private DungeonRoomScaffoldParser scaffoldParser; @Getter - private final List dungeonRoomList = new ArrayList<>(); + private DungeonEventRecorder recorder = new DungeonEventRecorder(); + @Getter private final List globalRoomProcessors = new ArrayList<>(); - @Getter - private final Map deaths = new HashMap<>(); - @Getter - private final List milestoneReached = new ArrayList<>(); - @Getter - @Setter - private long BossRoomEnterSeconds = -1; - @Getter - @Setter + // bunch of statistics + @Getter @Setter + private long bossRoomEnterSeconds = -1; + @Getter @Setter private long init = -1; - @Getter - @Setter + @Getter @Setter private BlockPos bossroomSpawnPos = null; - @Getter - @Setter + private boolean gotMimic = false; + + + // general info + @Getter @Setter private boolean trapRoomGen = false; - @Getter - private boolean gotMimic = false; + @Getter private int maxSpeed = 600; + @Getter private double secretPercentage = 1.0; - private int latestSecretCnt = 0; - private int latestTotalSecret = 0; - private int latestCrypts = 0; + @Getter @Setter + public int percentage; - @Getter - private int maxSpeed = 600; - @Getter - private double secretPercentage = 1.0; public void setGotMimic(boolean gotMimic) { this.gotMimic = gotMimic; - createEvent(new DungeonNodataEvent("MIMIC_KILLED")); + recorder.createEvent(new DungeonNodataEvent("MIMIC_KILLED")); } @Getter @@ -120,40 +103,43 @@ public class DungeonContext { @Getter private final Set players = new HashSet<>(); - @Getter - private final List events = new ArrayList<>(); - public DungeonContext(World world) { + private Vector2d doorOffset; + private BlockPos door; + + public DungeonContext(String dungeonName, World world) { + this.dungeonName = dungeonName; this.world = world; - createEvent(new DungeonNodataEvent("DUNGEON_CONTEXT_CREATION")); - mapProcessor = new MapProcessor(this); + recorder.createEvent(new DungeonNodataEvent("DUNGEON_CONTEXT_CREATION")); + mapPlayerMarkerProcessor = new MapPlayerProcessor(this); DungeonSpecificDataProvider doorFinder = DungeonSpecificDataProviderRegistry.getDoorFinder(getDungeonName()); if (doorFinder != null) { trapRoomGen = doorFinder.isTrapSpawn(getDungeonName()); - secretPercentage = doorFinder.secretPercentage(getDungeonName()); maxSpeed = doorFinder.speedSecond(getDungeonName()); } else { - mapProcessor.setBugged(true); + throw new IllegalStateException("No door finder found"); } + + doorOffset = doorFinder.findDoorOffset(world, getDungeonName()); + door = doorFinder.findDoor(world, getDungeonName()); + + if (doorOffset == null || door == null) throw new IllegalStateException("?"); + + init = System.currentTimeMillis(); } - public void createEvent(DungeonEventData eventData) { -// events.add(new DungeonEvent(eventData)); - } private final Rectangle roomBoundary = new Rectangle(-10, -10, 138, 138); public void tick() { - - - if (mapProcessor.isInitialized() && BossRoomEnterSeconds == -1 && !roomBoundary.contains(mapProcessor.worldPointToMapPoint(Minecraft.getMinecraft().thePlayer.getPositionVector()))) { - BossRoomEnterSeconds = FeatureRegistry.DUNGEON_SBTIME.getTimeElapsed() / 1000; + if (scaffoldParser != null && bossRoomEnterSeconds == -1 && !roomBoundary.contains(scaffoldParser.getDungeonMapLayout().worldPointToMapPoint(Minecraft.getMinecraft().thePlayer.getPositionVector()))) { + bossRoomEnterSeconds = FeatureRegistry.DUNGEON_SBTIME.getTimeElapsed() / 1000; bossroomSpawnPos = Minecraft.getMinecraft().thePlayer.getPosition(); MinecraftForge.EVENT_BUS.post(new BossroomEnterEvent()); - createEvent(new DungeonNodataEvent("BOSSROOM_ENTER")); + recorder.createEvent(new DungeonNodataEvent("BOSSROOM_ENTER")); DungeonSpecificDataProvider doorFinder = DungeonSpecificDataProviderRegistry.getDoorFinder(getDungeonName()); if (doorFinder != null) { bossfightProcessor = doorFinder.createBossfightProcessor(world, getDungeonName()); @@ -162,23 +148,55 @@ public class DungeonContext { } } + if (scaffoldParser != null) { + for (DungeonRoom dungeonRoom : scaffoldParser.getDungeonRoomList()) { + if (!dungeonRoom.isMatched()) { + dungeonRoom.tryRematch(); + } + } + } + players.clear(); players.addAll(TabListUtil.getPlayersInDungeon()); + } - if (latestSecretCnt != FeatureRegistry.DUNGEON_SECRETS.getSecretsFound()) { - int newSecretCnt = FeatureRegistry.DUNGEON_SECRETS.getSecretsFound(); - createEvent(new DungeonSecretCountChangeEvent(latestSecretCnt, newSecretCnt, latestTotalSecret, FeatureRegistry.DUNGEON_SECRETS.sureOfTotalSecrets())); - latestSecretCnt = newSecretCnt; + private boolean processed = false; + private void processFinishedMap(byte[] mapData) { + if (MapUtils.getMapColorAt(mapData, 0, 0) == 0) { + return; } - if (latestTotalSecret != FeatureRegistry.DUNGEON_SECRETS.getTotalSecretsInt()) { - latestTotalSecret = FeatureRegistry.DUNGEON_SECRETS.getTotalSecretsInt(); - createEvent(new DungeonSecretCountChangeEvent(latestSecretCnt, latestSecretCnt, latestTotalSecret, FeatureRegistry.DUNGEON_SECRETS.sureOfTotalSecrets())); + if (processed) { + return; } - if (latestCrypts != FeatureRegistry.DUNGEON_TOMBS.getTombsFound()) { - int newlatestCrypts = FeatureRegistry.DUNGEON_TOMBS.getTombsFound(); - createEvent(new DungeonCryptBrokenEvent(latestCrypts, newlatestCrypts)); - this.latestCrypts = newlatestCrypts; + processed = true; + + MapUtils.clearMap(); + MapUtils.record(mapData, 0, 0, Color.GREEN); + + + FeatureRegistry.ETC_COLLECT_SCORE.collectDungeonRunData(mapData, this); + } + private int mapId = -1; + public void onMapUpdate(MapUpdateEvent mapUpdateEvent) { + if (mapUpdateEvent.getMapId() > 10000) return; // tictactoe + if (mapId == -1) { + mapId = mapUpdateEvent.getMapId(); + } + if (mapId != mapUpdateEvent.getMapId()) return; + + if (isEnded()) { + processFinishedMap(mapUpdateEvent.getMapData().colors); + } + if (getScaffoldParser() == null) { + DungeonMapLayout layout = DungeonMapConstantRetreiver.beginParsingMap(mapUpdateEvent.getMapData().colors, door, doorOffset); + if (layout != null) + scaffoldParser = new DungeonRoomScaffoldParser( + layout, + this + ); + } else { + getScaffoldParser().processMap(mapUpdateEvent.getMapData()); } } @@ -199,18 +217,18 @@ public class DungeonContext { int x = Integer.parseInt(coords.split("/")[0]); int z = Integer.parseInt(coords.split("/")[1]); int secrets2 = Integer.parseInt(secrets); - Point roomPt = mapProcessor.worldPointToRoomPoint(new BlockPos(x, 70, z)); + Point roomPt = scaffoldParser.getDungeonMapLayout().worldPointToRoomPoint(new BlockPos(x, 70, z)); ChatTransmitter.sendDebugChat(new ChatComponentText("Message from Other dungeons guide :: " + roomPt.x + " / " + roomPt.y + " total secrets " + secrets2)); - DungeonRoom dr = roomMapper.get(roomPt); + DungeonRoom dr = scaffoldParser.getRoomMap().get(roomPt); if (dr != null) { dr.setTotalSecrets(secrets2); } } else if (formatted.contains("$DG-Mimic")) { setGotMimic(true); } else if (formatted.startsWith("§r§c§lPUZZLE FAIL! ") && formatted.endsWith(" §r§4Y§r§ci§r§6k§r§ee§r§as§r§2!§r")) { - createEvent(new DungeonPuzzleFailureEvent(TextUtils.stripColor(formatted.split(" ")[2]), formatted)); + recorder.createEvent(new DungeonPuzzleFailureEvent(TextUtils.stripColor(formatted.split(" ")[2]), formatted)); } else if (formatted.contains("§6> §e§lEXTRA STATS §6<")) { - createEvent(new DungeonNodataEvent("DUNGEON_END")); + recorder.createEvent(new DungeonNodataEvent("DUNGEON_END")); ended = true; } else if (formatted.contains("§r§c☠ §r§eDefeated ")) { defeated = true; diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/MapProcessor.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/MapProcessor.java deleted file mode 100755 index 84adf8a0..00000000 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/MapProcessor.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod - * Copyright (C) 2021 cyoung06 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package kr.syeyoung.dungeonsguide.mod.dungeon; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.ThreadFactoryBuilder; -import kr.syeyoung.dungeonsguide.mod.DungeonsGuide; -import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter; -import kr.syeyoung.dungeonsguide.mod.dungeon.doorfinder.EDungeonDoorType; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.SerializableBlockPos; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonMapUpdateEvent; -import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonRoomDiscoverEvent; -import kr.syeyoung.dungeonsguide.mod.dungeon.map.DungeonMapData; -import kr.syeyoung.dungeonsguide.mod.dungeon.roomfinder.DungeonRoom; -import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; -import kr.syeyoung.dungeonsguide.mod.utils.MapUtils; -import lombok.Getter; -import lombok.Setter; -import net.minecraft.client.Minecraft; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemMap; -import net.minecraft.item.ItemStack; -import net.minecraft.util.*; -import net.minecraft.world.storage.MapData; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.vecmath.Vector2d; -import java.awt.*; -import java.util.List; -import java.util.Queue; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class MapProcessor { - - private static final Set directions = Sets.newHashSet(new Vector2d(0, 1), new Vector2d(0, -1), new Vector2d(1, 0), new Vector2d(-1, 0)); - private static final Set door_dirs = Sets.newHashSet(new Vector2d(0, 0.5), new Vector2d(0, -0.5), new Vector2d(0.5, 0), new Vector2d(-0.5, 0)); - private static final Minecraft mc = Minecraft.getMinecraft(); - private final DungeonContext context; - @Getter - private final BiMap mapIconToPlayerMap = HashBiMap.create(); - private final List roomsFound = new ArrayList<>(); - Logger logger = LogManager.getLogger("MapProcessor"); - /** - * If the player on the map is closer than value this it won't save it - * this should be done with render-distance but whateva - */ - int clossnessDistance = 50; - @Getter - @Setter - private Dimension unitRoomDimension; - @Getter @Setter - private Dimension doorDimensions; // width: width of door, height: gap between rooms - @Getter - @Setter - private Point topLeftMapPoint; - @Setter - private boolean bugged = false; - @Getter - private boolean initialized = false; - @Getter - private int undiscoveredRoom = 0; - private boolean processed = false; - @Getter - private MapData latestMapData; - private int waitDelay = 0; - private boolean processlock; - - public MapProcessor(DungeonContext context) { - this.context = context; - } - - private static void error(String prefix) { - ChatTransmitter.addToQueue(new ChatComponentText(ChatTransmitter.prefix + prefix)); - } - - - ExecutorService es = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() - .setThreadFactory(DungeonsGuide.THREAD_FACTORY) - .setNameFormat("Dg-MapProcessor-%d").build()); - - - int processMapThroddle; - - public void tick() { - if (waitDelay < 5) { - waitDelay++; - return; - } - if (bugged) { - return; - } - ItemStack stack = Minecraft.getMinecraft().thePlayer.inventory.getStackInSlot(8); - - if (stack == null || !(stack.getItem() instanceof ItemMap)) { - return; - } - - MapData mapData = ((ItemMap) stack.getItem()).getMapData(stack, mc.theWorld); - - if (mapData != null) { - - if(processMapThroddle > 5 && !processlock){ - processMapData(mapData); - processMapThroddle = 0; - } - processMapThroddle++; - - } - - latestMapData = mapData; - - if (latestMapData != null && mapIconToPlayerMap.size() < context.getPlayers().size() && initialized) { - getPlayersFromMap(latestMapData); - } - - } - - private void processMapData(MapData mapData) { - byte[] mapColorData = mapData.colors; - - // i just cant get this to work sad - if (isThereDifference(latestMapData, mapColorData)) { - context.createEvent(new DungeonMapUpdateEvent(mapColorData)); - - es.execute(() -> { - processlock = true; - if (doorDimensions == null || !initialized) { - assembleMap(mapColorData); - } else { - processMap(mapColorData); - } - - if (context.isEnded()) { - processFinishedMap(mapColorData); - } - processlock = false; - }); - - } - - } - - void assembleMap(final byte[] mapData){ - DungeonMapData data = new DungeonMapData(context, Minecraft.getMinecraft()); - - data.eat(mapData); - - bugged = data.bugged; - - unitRoomDimension = data.unitRoomDimension; - - topLeftMapPoint = data.topLeftMapPoint; - - initialized = data.initialized; - - doorDimensions = data.doorDimensions; - - } - - - public static Point mapPointToRoomPoint(Point mapPoint, Point topLeftMapPoint, Dimension unitRoomDimension, Dimension doorDimensions) { - int x = (int) ((mapPoint.x - topLeftMapPoint.x) / ((double) unitRoomDimension.width + doorDimensions.height)); - int y = (int) ((mapPoint.y - topLeftMapPoint.y) / ((double) unitRoomDimension.height + doorDimensions.height)); - return new Point(x, y); - } - - public BlockPos mapPointToWorldPoint(Point mapPoint) { - int x = (int) ((mapPoint.x - topLeftMapPoint.x) / ((double) unitRoomDimension.width + doorDimensions.height) * 32 + context.getDungeonMin().getX()); - int y = (int) ((mapPoint.y - topLeftMapPoint.y) / ((double) unitRoomDimension.height + doorDimensions.height) * 32 + context.getDungeonMin().getZ()); - return new BlockPos(x, 70, y); - } - - public Point roomPointToMapPoint(Point roomPoint) { - return new Point(roomPoint.x * (unitRoomDimension.width + doorDimensions.height) + topLeftMapPoint.x, roomPoint.y * (unitRoomDimension.height + doorDimensions.height) + topLeftMapPoint.y); - } - - public BlockPos roomPointToWorldPoint(Point roomPoint) { - return new BlockPos(context.getDungeonMin().getX() + (roomPoint.x * 32), context.getDungeonMin().getY(), context.getDungeonMin().getZ() + (roomPoint.y * 32)); - } - - public Point worldPointToRoomPoint(BlockPos worldPoint) { - if (context.getDungeonMin() == null) return null; - return new Point((worldPoint.getX() - context.getDungeonMin().getX()) / 32, (worldPoint.getZ() - context.getDungeonMin().getZ()) / 32); - } - - public Point worldPointToMapPoint(Vec3 worldPoint) { - if (context.getDungeonMin() == null) return null; - return new Point(topLeftMapPoint.x + (int) ((worldPoint.xCoord - context.getDungeonMin().getX()) / 32.0f * (unitRoomDimension.width + doorDimensions.height)), topLeftMapPoint.y + (int) ((worldPoint.zCoord - context.getDungeonMin().getZ()) / 32.0f * (unitRoomDimension.height + doorDimensions.height))); - } - - public Vector2d worldPointToMapPointFLOAT(Vec3 worldPoint) { - if (context.getDungeonMin() == null) return null; - double x = topLeftMapPoint.x + ((worldPoint.xCoord - context.getDungeonMin().getX()) / 32.0f * (unitRoomDimension.width + doorDimensions.height)); - double y = topLeftMapPoint.y + ((worldPoint.zCoord - context.getDungeonMin().getZ()) / 32.0f * (unitRoomDimension.height + doorDimensions.height)); - return new Vector2d(x, y); - } - - private void processMap(byte[] mapData) { - int roomHeight = (int) ((128.0 - topLeftMapPoint.y) / (unitRoomDimension.height + doorDimensions.height)); - int roomWidth = (int) ((128.0 - topLeftMapPoint.x) / (unitRoomDimension.width + doorDimensions.height)); - if (MapUtils.getMapColorAt(mapData, 0, 0) != 0) return; - undiscoveredRoom = 0; - for (int y = 0; y <= roomHeight; y++) { - for (int x = 0; x <= roomWidth; x++) { - Point mapPoint = roomPointToMapPoint(new Point(x, y)); - byte color = MapUtils.getMapColorAt(mapData, mapPoint.x, mapPoint.y); - MapUtils.record(mapData, mapPoint.x, mapPoint.y, new Color(255, 255, 0, 80)); - if (roomsFound.contains(new Point(x, y))) { - DungeonRoom dungeonRoom = context.getRoomMapper().get(new Point(x, y)); - if (color == 18 && dungeonRoom.getCurrentState() != DungeonRoom.RoomState.FINISHED) { - dungeonRoom.setCurrentState(DungeonRoom.RoomState.COMPLETE_WITHOUT_SECRETS); - dungeonRoom.setTotalSecrets(0); - } else if (color == 30) { - dungeonRoom.setCurrentState(DungeonRoom.RoomState.FINISHED); - dungeonRoom.setTotalSecrets(0); - } else if (dungeonRoom.getCurrentState() != DungeonRoom.RoomState.FINISHED) { - byte centerColor = MapUtils.getMapColorAt(mapData, mapPoint.x + unitRoomDimension.width / 2, mapPoint.y + unitRoomDimension.height / 2); - MapUtils.record(mapData, mapPoint.x + unitRoomDimension.width / 2, mapPoint.y + unitRoomDimension.height / 2, new Color(0, 255, 0, 80)); - if (centerColor == 34) { - dungeonRoom.setCurrentState(DungeonRoom.RoomState.COMPLETE_WITHOUT_SECRETS); - } else if (centerColor == 30) { - dungeonRoom.setCurrentState(DungeonRoom.RoomState.FINISHED); - } else if (centerColor == 18) { // red - dungeonRoom.setCurrentState(DungeonRoom.RoomState.FAILED); - } - } - if (dungeonRoom.getTotalSecrets() == -1) { - if (dungeonRoom.getColor() == 82 || dungeonRoom.getColor() == 74) { - dungeonRoom.setTotalSecrets(0); - } - MapUtils.record(mapData, mapPoint.x, mapPoint.y + 1, new Color(0, 255, 0, 80)); - } - continue; - } - - if (color != 0 && color != 85) { - MapUtils.record(mapData, mapPoint.x, mapPoint.y, new Color(0, 255, 255, 80)); - DungeonRoom room = buildRoom(mapData, new Point(x, y)); - - - // USELESS DEBUG CODE - context.createEvent(new DungeonRoomDiscoverEvent(room.getUnitPoints().get(0), room.getRoomMatcher().getRotation(), new SerializableBlockPos(room.getMin()), new SerializableBlockPos(room.getMax()), room.getShape(), room.getColor(), room.getDungeonRoomInfo().getUuid(), room.getDungeonRoomInfo().getName(), room.getDungeonRoomInfo().getProcessorId())); - ChatTransmitter.sendDebugChat(new ChatComponentText("New Map discovered! shape: " + room.getShape() + " color: " + room.getColor() + " unitPos: " + x + "," + y)); - ChatTransmitter.sendDebugChat(new ChatComponentText("New Map discovered! mapMin: " + room.getMin() + " mapMx: " + room.getMax())); - StringBuilder builder = new StringBuilder(); - for (int dy = 0; dy < 4; dy++) { - builder.append("\n"); - for (int dx = 0; dx < 4; dx++) { - boolean isSet = ((room.getShape() >> (dy * 4 + dx)) & 0x1) != 0; - builder.append(isSet ? "O" : "X"); - } - } - ChatTransmitter.sendDebugChat(new ChatComponentText("Shape visual: " + builder)); - // END - - - context.getDungeonRoomList().add(room); - for (Point p : room.getUnitPoints()) { - roomsFound.add(p); - context.getRoomMapper().put(p, room); - } - if (room.getRoomProcessor() != null && room.getRoomProcessor().readGlobalChat()) { - context.getGlobalRoomProcessors().add(room.getRoomProcessor()); - } - } else if (color == 85) { - undiscoveredRoom++; - } - - } - } - } - - private DungeonRoom buildRoom(byte[] mapData, Point unitPoint) { - Queue toCheck = new LinkedList<>(); - toCheck.add(new Point[]{unitPoint, unitPoint}); // requestor, target - Set checked = new HashSet<>(); - List ayConnected = new ArrayList<>(); - - int minX = Integer.MAX_VALUE; - int minY = Integer.MAX_VALUE; - int maxX = 0; - int maxY = 0; - while (toCheck.peek() != null) { - Point[] check = toCheck.poll(); - if (checked.contains(check[1])) { - continue; - } - checked.add(check[1]); - - if (checkIfConnected(mapData, check[0], check[1])) { - ayConnected.add(check[1]); - if (check[1].x < minX) minX = check[1].x; - if (check[1].y < minY) minY = check[1].y; - if (check[1].x > maxX) maxX = check[1].x; - if (check[1].y > maxY) maxY = check[1].y; - for (Vector2d dir : directions) { - Point newPt = new Point(check[1].x + (int) dir.x, check[1].y + (int) dir.y); - toCheck.add(new Point[]{check[1], newPt}); - } - } - } - - short shape = 0; - for (Point p : ayConnected) { - int localX = p.x - minX; - int localY = p.y - minY; - shape |= 1 << (localY * 4 + localX); - } - Set doors = new HashSet<>(); - for (Point p : ayConnected) { - for (Vector2d v : door_dirs) { - Vector2d v2 = new Vector2d(p.x + v.x, p.y + v.y); - if (doors.contains(v2)) doors.remove(v2); - else doors.add(v2); - } - } - Point pt2 = roomPointToMapPoint(ayConnected.get(0)); - byte unit1 = MapUtils.getMapColorAt(mapData, pt2.x, pt2.y); - - // 0: none 1: open door 2. unopen door 3: wither door 4. red door - Set> doorsAndStates = new HashSet<>(); - final int halfWidth = unitRoomDimension.width + 4; - for (Vector2d door : doors) { - int floorX = (int) Math.floor(door.x); - int floorY = (int) Math.floor(door.y); - Point mapPt = roomPointToMapPoint(new Point(floorX, floorY)); - Point target = new Point(mapPt.x + unitRoomDimension.width / 2 + (int) (halfWidth * (door.x - floorX)), mapPt.y + unitRoomDimension.height / 2 + (int) (halfWidth * (door.y - floorY))); - MapUtils.record(mapData, target.x, target.y, Color.green); - - byte color = MapUtils.getMapColorAt(mapData, target.x, target.y); - - Vector2d vector2d = new Vector2d(door.x - minX, door.y - minY); - - if (color == 0) { - doorsAndStates.add(new Tuple<>(vector2d, EDungeonDoorType.NONE)); - } else if (color == 85) { - doorsAndStates.add(new Tuple<>(vector2d, EDungeonDoorType.UNOPEN)); - } else if (color == 119) { - doorsAndStates.add(new Tuple<>(vector2d, EDungeonDoorType.WITHER)); - } else if (color == 18 && unit1 != 18) { - doorsAndStates.add(new Tuple<>(vector2d, EDungeonDoorType.BLOOD)); - } else { - doorsAndStates.add(new Tuple<>(vector2d, EDungeonDoorType.ENTRANCE)); - } - - } - - - return new DungeonRoom(ayConnected, shape, unit1, roomPointToWorldPoint(new Point(minX, minY)), roomPointToWorldPoint(new Point(maxX + 1, maxY + 1)).add(-1, 0, -1), context, doorsAndStates); - - } - - private boolean checkIfConnected(byte[] mapData, Point unitPoint1, Point unitPoint2) { - if (unitPoint1 == unitPoint2) return true; - if (unitPoint1.equals(unitPoint2)) return true; - - - Point high; - if (unitPoint2.y > unitPoint1.y) { - high = unitPoint2; - } else { - if (unitPoint2.x > unitPoint1.x) { - high = unitPoint2; - } else { - high = unitPoint1; - } - } - - Point low; - if (high == unitPoint2) { - low = unitPoint1; - } else { - low = unitPoint2; - } - - int xOff = low.x - high.x; - int yOff = low.y - high.y; - Point pt = roomPointToMapPoint(high); - Point pt2 = roomPointToMapPoint(low); - byte unit1 = MapUtils.getMapColorAt(mapData, pt.x, pt.y); - byte unit2 = MapUtils.getMapColorAt(mapData, pt2.x, pt2.y); - pt.translate(xOff, yOff); - byte unit3 = MapUtils.getMapColorAt(mapData, pt.x, pt.y); - - return unit1 == unit2 && unit2 == unit3 && unit1 != 0; - } - - public boolean isThereDifference(MapData latestMapData, byte[] colorData1) { - byte[] colorData = null; - - if(latestMapData != null){ - colorData = latestMapData.colors; - } - - return true; -// boolean equals = Arrays.equals(colorData1, colorData); -// -// boolean foundDIffrentThen0 = false; -// -// -// for (byte colorDatum : colorData) { -// if(colorDatum != 0){ -// foundDIffrentThen0 = true; -// break; -// } -// } -// -// -// return !(equals && foundDIffrentThen0); - } - - private void processFinishedMap(byte[] mapData) { - if (MapUtils.getMapColorAt(mapData, 0, 0) == 0) { - return; - } - if (processed) { - return; - } - processed = true; - - MapUtils.clearMap(); - MapUtils.record(mapData, 0, 0, Color.GREEN); - - - FeatureRegistry.ETC_COLLECT_SCORE.collectDungeonRunData(mapData, context); - - } - - private void getPlayersFromMap(MapData mapdata) { - - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("Getting players from map"); - - for (Map.Entry stringVec4bEntry : mapdata.mapDecorations.entrySet()) { - String mapDecString = stringVec4bEntry.getKey(); - Vec4b vec4 = stringVec4bEntry.getValue(); - - if (!mapIconToPlayerMap.containsValue(mapDecString)) { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("mapIconToPlayerMap dosent have Player"); - - int x = vec4.func_176112_b() / 2 + 64; - int y = vec4.func_176113_c() / 2 + 64; - BlockPos mapPos = mapPointToWorldPoint(new Point(x, y)); - String potentialPlayer = null; - - for (String player : context.getPlayers()) { - if (DungeonsGuide.getDungeonsGuide().verbose) - logger.info("Player: {} isNear: {} ", player, isPlayerNear(player, mapPos)); -// if (!mapIconToPlayerMap.containsKey(player) && isPlayerNear(player, mapPos)) { - if (!mapIconToPlayerMap.containsKey(player)) { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("Potential profile is: " + player); - potentialPlayer = player; - break; - } - } - - - if (potentialPlayer != null) { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("potentialPlayer is not null"); - boolean shouldSave = true; - - for (Map.Entry vec4bEntry : mapdata.mapDecorations.entrySet()) { -// String aaa = vec4bEntry.getKey(); - Vec4b bbb = vec4bEntry.getValue(); - -// if (mapIconToPlayerMap.containsValue(aaa) || mapDecString.equals(aaa)) { -// shouldSave = false; -// break; -// } -// else { - int x2 = bbb.func_176112_b() / 2 + 64; - int y2 = bbb.func_176113_c() / 2 + 64; - int dx = x2 - x; - int dy = y2 - y; - if (dx * dx + dy * dy < clossnessDistance) { - shouldSave = false; - break; - } -// } - } - - if (shouldSave) { - if (DungeonsGuide.getDungeonsGuide().verbose) - logger.info("added {} to mapIconPlayerMap with {}", potentialPlayer, stringVec4bEntry.getKey()); - if (mapIconToPlayerMap.containsKey(potentialPlayer)) { - mapIconToPlayerMap.replace(potentialPlayer, stringVec4bEntry.getKey()); - } else { - mapIconToPlayerMap.put(potentialPlayer, stringVec4bEntry.getKey()); - } - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("mapIconToPlayerMap:"); - if (DungeonsGuide.getDungeonsGuide().verbose) - mapIconToPlayerMap.forEach((key, value) -> logger.info(" {}: {}", key, value)); - } else { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("shouldSave is false"); - } - - - } else { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("potentialPlayer is null"); - } - - } else { - if (DungeonsGuide.getDungeonsGuide().verbose) logger.info("mapIconToPlayerMap has player "); - } - } - - - } - - private boolean isPlayerNear(String player, BlockPos mapPos) { - EntityPlayer entityPlayer = Minecraft.getMinecraft().theWorld.getPlayerEntityByName(player); - - if (entityPlayer != null && !entityPlayer.isInvisible()) { - BlockPos pos = entityPlayer.getPosition(); - int dx = mapPos.getX() - pos.getX(); - int dz = mapPos.getZ() - pos.getZ(); - return dx * dx + dz * dz < clossnessDistance; - - } - - return false; - } -} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/DungeonEventRecorder.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/DungeonEventRecorder.java new file mode 100644 index 00000000..ff3061e5 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/DungeonEventRecorder.java @@ -0,0 +1,58 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.mod.dungeon.events; + +import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonCryptBrokenEvent; +import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonSecretCountChangeEvent; +import kr.syeyoung.dungeonsguide.mod.features.FeatureRegistry; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +public class DungeonEventRecorder { + private int latestSecretCnt = 0; + private int latestTotalSecret = 0; + private int latestCrypts = 0; + + @Getter + private final List events = new ArrayList<>(); + + + public void tick() { + if (latestSecretCnt != FeatureRegistry.DUNGEON_SECRETS.getSecretsFound()) { + int newSecretCnt = FeatureRegistry.DUNGEON_SECRETS.getSecretsFound(); + createEvent(new DungeonSecretCountChangeEvent(latestSecretCnt, newSecretCnt, latestTotalSecret, FeatureRegistry.DUNGEON_SECRETS.sureOfTotalSecrets())); + latestSecretCnt = newSecretCnt; + } + if (latestTotalSecret != FeatureRegistry.DUNGEON_SECRETS.getTotalSecretsInt()) { + latestTotalSecret = FeatureRegistry.DUNGEON_SECRETS.getTotalSecretsInt(); + createEvent(new DungeonSecretCountChangeEvent(latestSecretCnt, latestSecretCnt, latestTotalSecret, FeatureRegistry.DUNGEON_SECRETS.sureOfTotalSecrets())); + } + if (latestCrypts != FeatureRegistry.DUNGEON_TOMBS.getTombsFound()) { + int newlatestCrypts = FeatureRegistry.DUNGEON_TOMBS.getTombsFound(); + createEvent(new DungeonCryptBrokenEvent(latestCrypts, newlatestCrypts)); + this.latestCrypts = newlatestCrypts; + } + } + + public void createEvent(DungeonEventData eventData) { + events.add(new DungeonEvent(eventData)); + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomDiscoverEvent.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomDiscoverEvent.java index 09fd64a5..49f065bb 100644 --- a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomDiscoverEvent.java +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomDiscoverEvent.java @@ -30,14 +30,10 @@ import java.util.UUID; @AllArgsConstructor public class DungeonRoomDiscoverEvent implements DungeonEventData { private Point unitPt; - private int rotation; private SerializableBlockPos min; private SerializableBlockPos max; private int shape; private int color; - private UUID roomUID; - private String roomName; - private String roomProc; @Override public String getEventName() { diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomMatchEvent.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomMatchEvent.java new file mode 100644 index 00000000..1aa98601 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/events/impl/DungeonRoomMatchEvent.java @@ -0,0 +1,46 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2021 cyoung06 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.mod.dungeon.events.impl; + +import kr.syeyoung.dungeonsguide.mod.dungeon.events.DungeonEventData; +import kr.syeyoung.dungeonsguide.mod.dungeon.events.SerializableBlockPos; +import lombok.AllArgsConstructor; +import lombok.Data; + +import java.awt.*; +import java.util.UUID; + +@Data +@AllArgsConstructor +public class DungeonRoomMatchEvent implements DungeonEventData { + private Point unitPt; + private int rotation; + private SerializableBlockPos min; + private SerializableBlockPos max; + private int shape; + private int color; + private UUID roomUID; + private String roomName; + private String roomProc; + + @Override + public String getEventName() { + return "ROOM_DISCOVER"; + } +} diff --git a/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapConstantRetreiver.java b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapConstantRetreiver.java new file mode 100644 index 00000000..34e12e05 --- /dev/null +++ b/mod/src/main/java/kr/syeyoung/dungeonsguide/mod/dungeon/map/DungeonMapConstantRetreiver.java @@ -0,0 +1,139 @@ +/* + * Dungeons Guide - The most intelligent Hypixel Skyblock Dungeons Mod + * Copyright (C) 2023 cyoung06 (syeyoung) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package kr.syeyoung.dungeonsguide.mod.dungeon.map; + +import com.google.common.collect.Sets; +import kr.syeyoung.dungeonsguide.mod.chat.ChatTransmitter; +import kr.syeyoung.dungeonsguide.mod.dungeon.events.impl.DungeonNodataEvent; +import kr.syeyoung.dungeonsguide.mod.events.impl.DungeonContextInitializationEvent; +import kr.syeyoung.dungeonsguide.mod.utils.MapUtils; +import net.minecraft.util.BlockPos; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.common.MinecraftForge; + +import javax.vecmath.Vector2d; +import java.awt.*; +import java.util.Set; + + +// This class is responsible for matching the world to hand held map. +public class DungeonMapConstantRetreiver { + public static DungeonMapLayout beginParsingMap(byte[] mapData, BlockPos worldDoorLocation, Vector2d worldDoorDirection) { + if (worldDoorLocation == null || worldDoorDirection == null) return null; + +// context.createEvent(new DungeonNodataEvent("MAP_PROCESSOR_INIT")); +// MinecraftForge.EVENT_BUS.post(new DungeonContextInitializationEvent()); + + Rectangle firstRoom = obtainStartingRoom(mapData); + if (firstRoom == null) return null; + Dimension unitRoomSize = firstRoom.getSize(); + Vector2d mapDoorDirection = obtainStartingRoomToFirstRoomDoorDirection(mapData, firstRoom); + if (mapDoorDirection == null) return null; + Dimension mapDoorDimension = obtainMapDoorDimensions(mapData, firstRoom, mapDoorDirection); + if (mapDoorDimension == null) return null; + int mapDoorWidth = mapDoorDimension.width; + int mapRoomGap = mapDoorDimension.height; + + Point mapOriginPoint = obtainTopLeft(mapData, firstRoom, mapDoorDimension); + BlockPos worldMin = obtainWorldMin(mapData, firstRoom, mapOriginPoint, mapDoorDimension, + mapDoorDirection, worldDoorDirection, worldDoorLocation); + + ChatTransmitter.sendDebugChat(new ChatComponentText("door Pos:" + worldDoorDirection)); + + + ChatTransmitter.sendDebugChat(new ChatComponentText("Found Green room:" + firstRoom)); + ChatTransmitter.sendDebugChat(new C