diff options
Diffstat (limited to 'src/main')
22 files changed, 787 insertions, 59 deletions
diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/DungeonContext.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/DungeonContext.java index 59ce37c6..7a6d704f 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/DungeonContext.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/DungeonContext.java @@ -5,12 +5,11 @@ import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessor; import lombok.Getter; import lombok.Setter; import net.minecraft.util.BlockPos; +import net.minecraft.util.IntegerCache; import net.minecraft.world.World; import java.awt.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; @@ -32,6 +31,14 @@ public class DungeonContext { @Getter private List<RoomProcessor> globalRoomProcessors = new ArrayList<RoomProcessor>(); + @Getter + private Map<String, Integer> deaths = new HashMap<String, Integer>(); + @Getter + private List<String[]> milestoneReached = new ArrayList<String[]>(); + @Getter + @Setter + private int BossRoomEnterSeconds; + public DungeonContext(World world) { this.world = world; mapProcessor = new MapProcessor(this); diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/MapProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/MapProcessor.java index 698b78ab..0bf0d9e5 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/MapProcessor.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/MapProcessor.java @@ -4,9 +4,10 @@ import com.google.common.collect.Sets; import kr.syeyoung.dungeonsguide.e; import kr.syeyoung.dungeonsguide.SkyblockStatus; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; -import kr.syeyoung.dungeonsguide.dungeon.doorfinder.DoorFinderRegistry; -import kr.syeyoung.dungeonsguide.dungeon.doorfinder.StartDoorFinder; +import kr.syeyoung.dungeonsguide.dungeon.doorfinder.DungeonSpecificDataProviderRegistry; +import kr.syeyoung.dungeonsguide.dungeon.doorfinder.DungeonSpecificDataProvider; import kr.syeyoung.dungeonsguide.utils.MapUtils; +import lombok.Getter; import net.minecraft.client.Minecraft; import net.minecraft.item.ItemMap; import net.minecraft.item.ItemStack; @@ -35,12 +36,21 @@ public class MapProcessor { private boolean axisMatch = false; + @Getter + private int undiscoveredRoom = 0; + public MapProcessor(DungeonContext context) { this.context = context; } private static final Set<Vector2d> directions = Sets.newHashSet(new Vector2d(0,1), new Vector2d(0, -1), new Vector2d(1, 0), new Vector2d(-1 , 0)); + public boolean isInBossRoom() { + Point roomPt = worldPointToRoomPoint(Minecraft.getMinecraft().thePlayer.getPosition()); + Point mapPt = roomPointToMapPoint(roomPt); + return mapPt.x < 0 || mapPt.y < 0 || mapPt.x > 128 || mapPt.y > 128; + } + private int waitCnt = 0; private void buildMap(final byte[] mapData) { final Point startroom = MapUtils.findFirstColorWithIn(mapData, (byte) 30, new Rectangle(0,0,128,128)); @@ -98,13 +108,13 @@ public class MapProcessor { } // determine door location based on npc, and determine map min from there { - StartDoorFinder doorFinder = DoorFinderRegistry.getDoorFinder(((SkyblockStatus) e.getDungeonsGuide().getSkyblockStatus()).getDungeonName()); + DungeonSpecificDataProvider doorFinder = DungeonSpecificDataProviderRegistry.getDoorFinder(((SkyblockStatus) e.getDungeonsGuide().getSkyblockStatus()).getDungeonName()); if (doorFinder == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cCouldn't find door processor for "+e.getDungeonsGuide().getSkyblockStatus().getDungeonName())); bugged = true; return; } - BlockPos door = doorFinder.find(context.getWorld()); + BlockPos door = doorFinder.findDoor(context.getWorld(), e.getDungeonsGuide().getSkyblockStatus().getDungeonName()); if (door == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("§eDungeons Guide §7:: §cCouldn't determine door of the room, disabling mod for this dungeon run")); bugged = true; @@ -117,7 +127,7 @@ public class MapProcessor { unitPoint.translate(unitPoint.x + 1, unitPoint.y + 1); unitPoint.translate((int)doorDir.x, (int)doorDir.y); - Vector2d offset = doorFinder.offset(context.getWorld()); + Vector2d offset = doorFinder.findDoorOffset(context.getWorld(), e.getDungeonsGuide().getSkyblockStatus().getDungeonName()); axisMatch = doorDir.equals(offset); int worldX = unitPoint.x * 16; @@ -155,14 +165,34 @@ public class MapProcessor { private void processMap(byte[] mapData) { int height = (int)((128.0 - topLeftMapPoint.y) / (unitRoomDimension.height + doorDimension.height)); int width = (int) ((128.0 - topLeftMapPoint.x) / (unitRoomDimension.width + doorDimension.height)); + undiscoveredRoom = 0; if (MapUtils.getMapColorAt(mapData,0,0) != 0) return; for (int y = 0; y <= height; y++){ for (int x = 0; x <= width; x++) { - if (roomsFound.contains(new Point(x,y))) continue; - 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 == 30 || color == 18) { + dungeonRoom.setCurrentState(DungeonRoom.RoomState.FINISHED); + } else { + 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) { + 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 rooms = buildRoom(mapData, new Point(x,y)); @@ -185,11 +215,12 @@ public class MapProcessor { } if (rooms.getRoomProcessor() != null && rooms.getRoomProcessor().readGlobalChat()) context.getGlobalRoomProcessors().add(rooms.getRoomProcessor()); + } else if (color == 85){ + undiscoveredRoom++; } } } - } private DungeonRoom buildRoom(byte[] mapData, Point unitPoint) { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/DungeonRoomInfo.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/DungeonRoomInfo.java index 05cd57d6..71b51255 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/DungeonRoomInfo.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/data/DungeonRoomInfo.java @@ -38,4 +38,5 @@ public class DungeonRoomInfo implements Serializable { private Map<String, Object> properties = new HashMap<String, Object>(); private Map<String, DungeonMechanic> mechanics = new HashMap<String, DungeonMechanic>(); + private int totalSecrets = -1; } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/CatacombDoorFinder.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/CatacombDataProvider.java index b73fa2aa..7f4e9813 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/CatacombDoorFinder.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/CatacombDataProvider.java @@ -2,23 +2,21 @@ package kr.syeyoung.dungeonsguide.dungeon.doorfinder; import com.google.common.base.Predicate; import com.google.common.collect.Sets; -import net.minecraft.client.Minecraft; import net.minecraft.entity.item.EntityArmorStand; import net.minecraft.init.Blocks; import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentText; import net.minecraft.world.World; import javax.vecmath.Vector2d; import java.util.Collection; import java.util.Set; -public class CatacombDoorFinder implements StartDoorFinder { +public class CatacombDataProvider implements DungeonSpecificDataProvider { private static final Set<Vector2d> directions = Sets.newHashSet(new Vector2d(0,1), new Vector2d(0, -1), new Vector2d(1, 0), new Vector2d(-1 , 0)); @Override - public BlockPos find(World w) { + public BlockPos findDoor(World w, String dungeonName) { Collection<EntityArmorStand> armorStand = w.getEntities(EntityArmorStand.class, new Predicate<EntityArmorStand>() { @Override public boolean apply(EntityArmorStand input) { @@ -43,7 +41,7 @@ public class CatacombDoorFinder implements StartDoorFinder { } @Override - public Vector2d offset(World w) { + public Vector2d findDoorOffset(World w, String dungeonName) { Collection<EntityArmorStand> armorStand = w.getEntities(EntityArmorStand.class, new Predicate<EntityArmorStand>() { @Override public boolean apply(EntityArmorStand input) { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java deleted file mode 100755 index 0fb3c89a..00000000 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DoorFinderRegistry.java +++ /dev/null @@ -1,20 +0,0 @@ -package kr.syeyoung.dungeonsguide.dungeon.doorfinder; - -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - -public class DoorFinderRegistry { - private static final Map<Pattern, StartDoorFinder> doorFinders = new HashMap<Pattern, StartDoorFinder>(); - - static { - doorFinders.put(Pattern.compile("The Catacombs (?:F[0-9]|E)"), new CatacombDoorFinder()); - } - - public static StartDoorFinder getDoorFinder(String dungeonName) { - for (Map.Entry<Pattern, StartDoorFinder> doorFinderEntry :doorFinders.entrySet()){ - if (doorFinderEntry.getKey().matcher(dungeonName).matches()) return doorFinderEntry.getValue(); - } - return null; - } -} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/StartDoorFinder.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DungeonSpecificDataProvider.java index ee1ccdaa..cc97d73a 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/StartDoorFinder.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DungeonSpecificDataProvider.java @@ -5,7 +5,7 @@ import net.minecraft.world.World; import javax.vecmath.Vector2d; -public interface StartDoorFinder { - BlockPos find(World w); - Vector2d offset(World w); +public interface DungeonSpecificDataProvider { + BlockPos findDoor(World w, String dungeonName); + Vector2d findDoorOffset(World w, String dungeonName); } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DungeonSpecificDataProviderRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DungeonSpecificDataProviderRegistry.java new file mode 100755 index 00000000..41048bd2 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/doorfinder/DungeonSpecificDataProviderRegistry.java @@ -0,0 +1,20 @@ +package kr.syeyoung.dungeonsguide.dungeon.doorfinder; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +public class DungeonSpecificDataProviderRegistry { + private static final Map<Pattern, DungeonSpecificDataProvider> doorFinders = new HashMap<Pattern, DungeonSpecificDataProvider>(); + + static { + doorFinders.put(Pattern.compile("The Catacombs (?:F[0-9]|E)"), new CatacombDataProvider()); + } + + public static DungeonSpecificDataProvider getDoorFinder(String dungeonName) { + for (Map.Entry<Pattern, DungeonSpecificDataProvider> doorFinderEntry :doorFinders.entrySet()){ + if (doorFinderEntry.getKey().matcher(dungeonName).matches()) return doorFinderEntry.getValue(); + } + return null; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoom.java b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoom.java index c6afb59f..6b0322ee 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoom.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/dungeon/roomfinder/DungeonRoom.java @@ -8,7 +8,9 @@ import kr.syeyoung.dungeonsguide.dungeon.doorfinder.DungeonDoor; import kr.syeyoung.dungeonsguide.roomprocessor.ProcessorFactory; import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessor; import kr.syeyoung.dungeonsguide.roomprocessor.RoomProcessorGenerator; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.Setter; import net.minecraft.block.Block; import net.minecraft.util.BlockPos; @@ -36,6 +38,17 @@ public class DungeonRoom { private final int unitWidth; // X private final int unitHeight; // Z + @Setter + private int totalSecrets = -1; + @Setter + private RoomState currentState = RoomState.DISCOVERED; + + @AllArgsConstructor + @Getter + public static enum RoomState { + DISCOVERED(0), COMPLETE_WITHOUT_SECRETS(0), FINISHED(0), FAILED(-14); + private int scoreModifier; + } private RoomProcessor roomProcessor; @@ -55,7 +68,6 @@ public class DungeonRoom { unitWidth = (int) Math.ceil(max.getX() - min.getX() / 32.0); unitHeight = (int) Math.ceil(max.getZ() - min.getZ() / 32.0); - buildDoors(); buildRoom(); updateRoomProcessor(); @@ -88,6 +100,7 @@ public class DungeonRoom { dungeonRoomInfo = roomMatcher.createNew(); this.dungeonRoomInfo = dungeonRoomInfo; + totalSecrets = dungeonRoomInfo.getTotalSecrets(); } public void updateRoomProcessor() { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/DungeonListener.java b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/DungeonListener.java index 3651593a..7998c893 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/DungeonListener.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/DungeonListener.java @@ -31,6 +31,7 @@ import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.lwjgl.opengl.GL11; import java.awt.*; @@ -80,12 +81,14 @@ public class DungeonListener { SkyblockStatus skyblockStatus = (SkyblockStatus) e.getDungeonsGuide().getSkyblockStatus(); if (!skyblockStatus.isOnDungeon()) return; if (FeatureRegistry.DEBUG.isEnabled()) { + GL11.glPushMatrix(); int[] textureData = dynamicTexture.getTextureData(); MapUtils.getImage().getRGB(0, 0, 128, 128, textureData, 0, 128); dynamicTexture.updateDynamicTexture(); Minecraft.getMinecraft().getTextureManager().bindTexture(location); GlStateManager.enableAlpha(); GuiScreen.drawModalRectWithCustomSizedTexture(0, 0, 0, 0, 128, 128, 128, 128); + GL11.glPopMatrix(); } if (skyblockStatus.getContext() != null) { @@ -100,9 +103,10 @@ public class DungeonListener { fontRenderer.drawString("Where are you?!", 5, 128, 0xFFFFFF); } else { if (FeatureRegistry.DEBUG.isEnabled()) { - fontRenderer.drawString("you're in the room... " + dungeonRoom.getColor() + " / " + dungeonRoom.getShape(), 5, 128, 0xFFFFFF); + fontRenderer.drawString("you're in the room... color/shape " + dungeonRoom.getColor() + " / " + dungeonRoom.getShape(), 5, 128, 0xFFFFFF); fontRenderer.drawString("room uuid: " + dungeonRoom.getDungeonRoomInfo().getUuid() + (dungeonRoom.getDungeonRoomInfo().isRegistered() ? "" : " (not registered)"), 5, 138, 0xFFFFFF); fontRenderer.drawString("room name: " + dungeonRoom.getDungeonRoomInfo().getName(), 5, 148, 0xFFFFFF); + fontRenderer.drawString("room state / max secret: " + dungeonRoom.getCurrentState() + " / "+dungeonRoom.getTotalSecrets(), 5, 158, 0xFFFFFF); } if (dungeonRoom.getRoomProcessor() != null) { dungeonRoom.getRoomProcessor().drawScreen(postRender.partialTicks); @@ -118,7 +122,6 @@ public class DungeonListener { @SubscribeEvent public void onChatReceived(ClientChatReceivedEvent clientChatReceivedEvent) { try { - if (clientChatReceivedEvent.type == 2) return; SkyblockStatus skyblockStatus = (SkyblockStatus) e.getDungeonsGuide().getSkyblockStatus(); if (!skyblockStatus.isOnDungeon()) return; @@ -133,13 +136,19 @@ public class DungeonListener { DungeonRoom dungeonRoom = context.getRoomMapper().get(roomPt); if (dungeonRoom != null) { if (dungeonRoom.getRoomProcessor() != null) { + if (clientChatReceivedEvent.type == 2) { + dungeonRoom.getRoomProcessor().actionbarReceived(clientChatReceivedEvent.message); + roomProcessor = dungeonRoom.getRoomProcessor(); + } else { dungeonRoom.getRoomProcessor().chatReceived(clientChatReceivedEvent.message); roomProcessor = dungeonRoom.getRoomProcessor(); + } } } } catch (Throwable t) { t.printStackTrace(); } + if (clientChatReceivedEvent.type == 2) return; for (RoomProcessor globalRoomProcessor : context.getGlobalRoomProcessors()) { if (globalRoomProcessor == roomProcessor) continue;; try { diff --git a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java index 2e8e8adc..11531352 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/eventlistener/FeatureListener.java @@ -1,10 +1,12 @@ package kr.syeyoung.dungeonsguide.eventlistener; import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.config.guiconfig.GuiGuiLocationConfig; import kr.syeyoung.dungeonsguide.e; import kr.syeyoung.dungeonsguide.features.*; import kr.syeyoung.dungeonsguide.features.AbstractFeature; import kr.syeyoung.dungeonsguide.features.listener.*; +import net.minecraft.client.Minecraft; import net.minecraftforge.client.event.*; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -14,12 +16,14 @@ public class FeatureListener { @SubscribeEvent public void onRender(RenderGameOverlayEvent.Post postRender) { try { + boolean isLocConfig = Minecraft.getMinecraft().currentScreen instanceof GuiGuiLocationConfig; + if (postRender.type != RenderGameOverlayEvent.ElementType.ALL) return; SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); if (!skyblockStatus.isOnSkyblock()) return; for (AbstractFeature abstractFeature : FeatureRegistry.getFeatureList()) { - if (abstractFeature instanceof ScreenRenderListener) { + if (abstractFeature instanceof ScreenRenderListener && (!isLocConfig || !(abstractFeature instanceof GuiFeature))) { ((ScreenRenderListener) abstractFeature).drawScreen(postRender.partialTicks); } } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java index 6a66a13f..04e938ab 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/FeatureRegistry.java @@ -30,6 +30,9 @@ public class FeatureRegistry { return abstractFeature; } + public static final SimpleFeature DEBUG = register(new SimpleFeature("hidden", "Debug", "Toggles debug mode", "debug", false)); + + public static final SimpleFeature ADVANCED_ROOMEDIT = register(new SimpleFeature("advanced", "Room Edit", "Allow editing dungeon rooms\n\nWarning: using this feature can break or freeze your Minecraft\nThis is only for advanced users only", "advanced.roomedit", false)); public static final SimpleFeature SOLVER_RIDDLE = register(new SimpleFeature("solver", "Riddle Puzzle (3 weirdo) Solver", "Highlights the correct box after clicking on all 3 weirdos", "solver.riddle")); public static final SimpleFeature SOLVER_KAHOOT = register(new SimpleFeature("solver", "Trivia Puzzle (Omnicrescent) Solver", "Highlights the correct solution for trivia puzzle", "solver.trivia")); @@ -42,17 +45,21 @@ public class FeatureRegistry { public static final SimpleFeature SOLVER_CREEPER = register(new SimpleFeature("solver", "Creeper Puzzle Solver", "Draws line between prismarine lamps in creeper room", "solver.creeper")); public static final SimpleFeature SOLVER_TELEPORT = register(new SimpleFeature("solver", "Teleport Puzzle Solver", "Shows teleport pads you've visited in a teleport maze room", "solver.teleport")); - public static final FeatureTooltipDungeonStat TOOLTIP_DUNGEONSTAT = register(new FeatureTooltipDungeonStat()); - public static final FeatureTooltipPrice TOOLTIP_PRICE = register(new FeatureTooltipPrice()); - - public static final SimpleFeature ADVANCED_ROOMEDIT = register(new SimpleFeature("advanced", "Room Edit", "Allow editing dungeon rooms\n\nWarning: using this feature can break or freeze your Minecraft\nThis is only for advanced users only", "advanced.roomedit", false)); + public static final FeatureTooltipDungeonStat ETC_DUNGEONSTAT = register(new FeatureTooltipDungeonStat()); + public static final FeatureTooltipPrice ETC_PRICE = register(new FeatureTooltipPrice()); + public static final FeatureCooldownCounter ETC_COOLDOWN = register(new FeatureCooldownCounter()); + public static final SimpleFeature FIX_SPIRIT_BOOTS = register(new SimpleFeature("fixes", "Spirit Boots Fixer", "Fix Spirit boots messing up with inventory", "fixes.spirit", true)); - public static final SimpleFeature DEBUG = register(new SimpleFeature("hidden", "Debug", "Toggles debug mode", "debug", false)); + public static final SimpleFeature BOSSFIGHT_CHESTPRICE = register(new FeatureChestPrice()); - public static final FeatureCooldownCounter HUD_COOLDOWN = register(new FeatureCooldownCounter()); public static final FeatureInstaCloseChest DUNGEON_INSTACLOSE = register(new FeatureInstaCloseChest()); public static final FeatureBoxSkelemaster DUNGEON_BOXSKELEMASTER = register(new FeatureBoxSkelemaster()); - public static final SimpleFeature FIX_SPIRIT_BOOTS = register(new SimpleFeature("fixes", "Spirit Boots Fixer", "Fix Spirit boots messing up with inventory", "fixes.spirit", true)); - public static final SimpleFeature BOSSFIGHT_CHESTPRICE = register(new FeatureChestPrice()); + public static final FeatureDungeonDeaths DUNGEON_DEATHS = register(new FeatureDungeonDeaths()); + public static final FeatureDungeonMilestone DUNGEON_MILESTONE = register(new FeatureDungeonMilestone()); + public static final FeatureDungeonRealTime DUNGEON_REALTIME = register(new FeatureDungeonRealTime()); + public static final FeatureDungeonSBTime DUNGEON_SBTIME = register(new FeatureDungeonSBTime()); + public static final FeatureDungeonSecrets DUNGEON_SECRETS = register(new FeatureDungeonSecrets()); + public static final FeatureDungeonTombs DUNGEON_TOMBS = register(new FeatureDungeonTombs()); + public static final FeatureDungeonScore DUNGEON_SCORE = register(new FeatureDungeonScore()); } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/GuiFeature.java b/src/main/java/kr/syeyoung/dungeonsguide/features/GuiFeature.java index d9d964c1..192ad10c 100644 --- a/src/main/java/kr/syeyoung/dungeonsguide/features/GuiFeature.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/GuiFeature.java @@ -9,6 +9,7 @@ import lombok.Setter; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import org.lwjgl.opengl.GL11; @@ -39,21 +40,18 @@ public abstract class GuiFeature extends AbstractFeature implements ScreenRender @Override public void drawScreen(float partialTicks) { if (!isEnabled()) return; - GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS); + GL11.glPushMatrix(); +// GL11.glColor4f(1,1,1,1); + GlStateManager.disableFog(); + GlStateManager.disableLighting(); clip(new ScaledResolution(Minecraft.getMinecraft()), featureRect.x, featureRect.y, featureRect.width, featureRect.height); GL11.glEnable(GL11.GL_SCISSOR_TEST); -// GL11.glEnable(GL11.GL_BLEND); -// OpenGlHelper.glBlendFunc(770, 771, 1, 0); -// GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - GL11.glPushMatrix(); GL11.glTranslated(featureRect.x, featureRect.y, 0); drawHUD(partialTicks); - GL11.glPopMatrix(); GL11.glDisable(GL11.GL_SCISSOR_TEST); - GL11.glPopAttrib(); + GL11.glPopMatrix(); } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonDeaths.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonDeaths.java new file mode 100644 index 00000000..ff3be74b --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonDeaths.java @@ -0,0 +1,96 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.features.listener.ChatListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class FeatureDungeonDeaths extends GuiFeature implements ChatListener { + public FeatureDungeonDeaths() { + super("Dungeon", "Display Deaths", "Display names of player and death count in dungeon run", "dungeon.stats.deaths", false, getFontRenderer().getStringWidth("longestplayernamepos: 100"), getFontRenderer().FONT_HEIGHT * 6); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + @Override + public void drawHUD(float partialTicks) { + if (!skyblockStatus.isOnDungeon()) return; + DungeonContext context = skyblockStatus.getContext(); + if (context == null) return; + Map<String, Integer> deaths = context.getDeaths(); + int i = 0; + int deathsCnt = 0; + FontRenderer fr = getFontRenderer(); + for (Map.Entry<String, Integer> death:deaths.entrySet()) { + fr.drawString(death.getKey()+": "+death.getValue(), 0,i, this.<Color>getParameter("color").getValue().getRGB()); + i += 8; + deathsCnt += death.getValue(); + } + fr.drawString("Total Deaths: "+deathsCnt, 0,i, this.<Color>getParameter("color").getValue().getRGB()); + } + + public int getTotalDeaths() { + if (!skyblockStatus.isOnDungeon()) return 0; + DungeonContext context = skyblockStatus.getContext(); + if (context == null) return 0; + int d = 0; + for (Integer value : context.getDeaths().values()) { + d += value; + } + return d; + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + fr.drawString("syeyoung: -130", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + fr.drawString("notsyeyoung: -13", 0,8, this.<Color>getParameter("color").getValue().getRGB()); + fr.drawString("dungeonsguide: -42", 0,16, this.<Color>getParameter("color").getValue().getRGB()); + fr.drawString("--not more--", 0,24, this.<Color>getParameter("color").getValue().getRGB()); + fr.drawString("--maybe more--", 0,32, this.<Color>getParameter("color").getValue().getRGB()); + fr.drawString("Total Deaths: 0", 0,40, this.<Color>getParameter("color").getValue().getRGB()); + } + + Pattern deathPattern = Pattern.compile("§r§c ☠ (.+?)§r§7 .+and became a ghost.+"); + Pattern meDeathPattern = Pattern.compile("§r§c ☠ §r§7You .+and became a ghost.+"); + + @Override + public void onChat(ClientChatReceivedEvent clientChatReceivedEvent) { + if (clientChatReceivedEvent.type == 2) return; + System.out.println("HUH"); + if (!skyblockStatus.isOnDungeon()) return; + DungeonContext context = skyblockStatus.getContext(); + if (context == null) return; + + String txt = clientChatReceivedEvent.message.getFormattedText(); + System.out.println(txt); + Matcher m = deathPattern.matcher(txt); + if (m.matches()) { + String nickname = TextUtils.stripColor(m.group(1)); + int deaths = context.getDeaths().containsKey(nickname) ? context.getDeaths().get(nickname) : 0; + context.getDeaths().put(nickname, deaths + 1); + e.sendDebugChat(new ChatComponentText("Death verified :: "+nickname+" / "+(deaths + 1))); + } + Matcher m2 = meDeathPattern.matcher(txt); + if (m2.matches()) { + String nickname = "me"; + int deaths = context.getDeaths().containsKey(nickname) ? context.getDeaths().get(nickname) : 0; + context.getDeaths().put(nickname, deaths + 1); + e.sendDebugChat(new ChatComponentText("Death verified :: me / "+(deaths + 1))); + } + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonMilestone.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonMilestone.java new file mode 100644 index 00000000..9ccd5e18 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonMilestone.java @@ -0,0 +1,74 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.features.listener.ChatListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.regex.Pattern; + +public class FeatureDungeonMilestone extends GuiFeature implements ChatListener { + public FeatureDungeonMilestone() { + super("Dungeon", "Display Current Class Milestone", "Display current class milestone of yourself", "dungeon.stats.milestone", true, getFontRenderer().getStringWidth("Milestone: 12"), getFontRenderer().FONT_HEIGHT); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + @Override + public void drawHUD(float partialTicks) { + if (!skyblockStatus.isOnDungeon()) return; + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + for (NetworkPlayerInfo networkPlayerInfoIn : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { + String name = networkPlayerInfoIn.getDisplayName() != null ? networkPlayerInfoIn.getDisplayName().getFormattedText() : ScorePlayerTeam.formatPlayerName(networkPlayerInfoIn.getPlayerTeam(), networkPlayerInfoIn.getGameProfile().getName()); + if (name.startsWith("§r Milestone: §r")) { + String milestone = TextUtils.stripColor(name).substring(13); + fr.drawString("Milestone: "+milestone, 0,0, this.<Color>getParameter("color").getValue().getRGB()); + return; + } + } + fr.drawString("Milestone: ?", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Milestone: 9", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + public static final Pattern milestone_pattern = Pattern.compile("§r§e§l(.+) Milestone §r§e(.)§r§7: .+ §r§a(.+)§r"); + + + @Override + public void onChat(ClientChatReceivedEvent clientChatReceivedEvent) { + if (clientChatReceivedEvent.type == 2) return;; + if (!skyblockStatus.isOnDungeon()) return; + DungeonContext context = skyblockStatus.getContext(); + if (context == null) return; + String txt = clientChatReceivedEvent.message.getFormattedText(); + System.out.println(txt); + if (milestone_pattern.matcher(txt).matches()) { + context.getMilestoneReached().add(new String[] { + TextUtils.formatTime(FeatureRegistry.DUNGEON_REALTIME.getTimeElapsed()), + TextUtils.formatTime(FeatureRegistry.DUNGEON_SBTIME.getTimeElapsed()) + }); + e.sendDebugChat(new ChatComponentText("Reached Milestone At " + TextUtils.formatTime(FeatureRegistry.DUNGEON_REALTIME.getTimeElapsed()) + " / "+TextUtils.formatTime(FeatureRegistry.DUNGEON_SBTIME.getTimeElapsed()))); + } + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonRealTime.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonRealTime.java new file mode 100644 index 00000000..9b2620e4 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonRealTime.java @@ -0,0 +1,57 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.features.listener.ChatListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.gui.FontRenderer; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.text.SimpleDateFormat; + +public class FeatureDungeonRealTime extends GuiFeature implements TickListener { + public FeatureDungeonRealTime() { + super("Dungeon", "Display Real Time-Dungeon Time", "Display how much real time has passed since dungeon run started", "dungeon.stats.realtime", true, getFontRenderer().getStringWidth("Time(Real): 59m 59s"), getFontRenderer().FONT_HEIGHT); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + private long started = -1; + @Override + public void drawHUD(float partialTicks) { + if (started == -1) return; + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Time(Real): "+TextUtils.formatTime(getTimeElapsed()), 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + public long getTimeElapsed() { + return System.currentTimeMillis() - started; + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Time(Real): -42h", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + private boolean wasInDungeon = false; + @Override + public void onTick() { + if (wasInDungeon && !skyblockStatus.isOnDungeon()) { + if (skyblockStatus.isOnSkyblock()) started = -1; + } else if (!wasInDungeon && skyblockStatus.isOnDungeon()) { + started = System.currentTimeMillis(); + } + wasInDungeon = skyblockStatus.isOnDungeon(); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSBTime.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSBTime.java new file mode 100644 index 00000000..65f06f58 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSBTime.java @@ -0,0 +1,92 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.features.listener.ChatListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.scoreboard.Score; +import net.minecraft.scoreboard.ScoreObjective; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.scoreboard.Scoreboard; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.Collection; + +public class FeatureDungeonSBTime extends GuiFeature implements TickListener { + public FeatureDungeonSBTime() { + super("Dungeon", "Display Ingame Dungeon Time", "Display how much time skyblock thinks has passed since dungeon run started", "dungeon.stats.igtime", true, getFontRenderer().getStringWidth("Time(IG): 1h 59m 59s"), getFontRenderer().FONT_HEIGHT); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + private long started = -1; + @Override + public void drawHUD(float partialTicks) { + if (started == -1) return; + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); + ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1); + Collection<Score> scores = scoreboard.getSortedScores(objective); + String time = "idkyet"; + for (Score sc:scores) { + ScorePlayerTeam scorePlayerTeam = scoreboard.getPlayersTeam(sc.getPlayerName()); + String strippedLine = TextUtils.keepScoreboardCharacters(TextUtils.stripColor(ScorePlayerTeam.formatPlayerName(scorePlayerTeam, sc.getPlayerName()))).trim(); + if (strippedLine.startsWith("Time Elapsed: ")) { + time = strippedLine.substring(14); + } + } + fr.drawString("Time(Ig): "+time, 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + public int getTimeElapsed() { + Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); + ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1); + Collection<Score> scores = scoreboard.getSortedScores(objective); + String time = "idkyet"; + for (Score sc:scores) { + ScorePlayerTeam scorePlayerTeam = scoreboard.getPlayersTeam(sc.getPlayerName()); + String strippedLine = TextUtils.keepScoreboardCharacters(TextUtils.stripColor(ScorePlayerTeam.formatPlayerName(scorePlayerTeam, sc.getPlayerName()))).trim(); + if (strippedLine.startsWith("Time Elapsed: ")) { + time = strippedLine.substring(14); + } + } + time = time.replace(" ", ""); + int hour = time.indexOf('h') == -1 ? 0 : Integer.parseInt(time.substring(0, time.indexOf('h'))); + if (time.contains("h")) time = time.substring(time.indexOf('h') + 1); + int minute = time.indexOf('m') == -1 ? 0 : Integer.parseInt(time.substring(0, time.indexOf('m'))); + if (time.contains("m")) time = time.substring(time.indexOf('m') + 1); + int second = time.indexOf('s') == -1 ? 0 : Integer.parseInt(time.substring(0, time.indexOf('s'))); + + int time2 = hour * 60 * 60 + minute * 60 + second; + return time2 * 1000; + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + + fr.drawString("Time(Ig): -42h", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + private boolean wasInDungeon = false; + @Override + public void onTick() { + if (wasInDungeon && !skyblockStatus.isOnDungeon()) { + if (skyblockStatus.isOnSkyblock()) started = -1; + } else if (!wasInDungeon && skyblockStatus.isOnDungeon()) { + started = System.currentTimeMillis(); + } + wasInDungeon = skyblockStatus.isOnDungeon(); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonScore.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonScore.java new file mode 100644 index 00000000..024ccb67 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonScore.java @@ -0,0 +1,167 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import lombok.AllArgsConstructor; +import lombok.Data; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.util.MathHelper; +import org.lwjgl.opengl.GL11; + +import java.awt.*; + +public class FeatureDungeonScore extends GuiFeature { + public FeatureDungeonScore() { + super("Dungeon", "Display Current Score", "Calculate and Display current score\nThis data is from pure calculation and can be different from actual score.", "dungeon.stats.score", false, 200, getFontRenderer().FONT_HEIGHT * 4); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + parameters.put("verbose", new FeatureParameter<Boolean>("verbose", "Show each score instead of sum", "Skill: 100 Explore: 58 S->S+(5 tombs) instead of Score: 305", true, "boolean")); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + @Override + public void drawHUD(float partialTicks) { + if (!skyblockStatus.isOnDungeon()) return; + FontRenderer fr = getFontRenderer(); + ScoreCalculation score = calculateScore(); + int sum = score.time + score.skill + score.explorer + score.bonus; + if (this.<Boolean>getParameter("verbose").getValue()) { + String req = buildRequirement(score); + int rgb = this.<Color>getParameter("color").getValue().getRGB(); + fr.drawString("Skill: "+score.skill+" ("+score.deaths+" Deaths)", 0, 0, rgb); + fr.drawString("Explorer: "+score.explorer+" (Rooms "+(score.fullyCleared ? "O" : "X") + " secrets "+score.secrets+"/"+score.totalSecrets+(score.totalSecretsKnown ? "": "?")+")", 0, 8, rgb); + fr.drawString("Time: "+score.time+" Bonus: "+score.bonus+" ::: Total: "+sum, 0, 16, rgb); + fr.drawString(req, 0, 24, rgb); + } else { + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + String letter = getLetter(sum); + fr.drawString("Score: "+score + "("+letter+")", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + if (this.<Boolean>getParameter("verbose").getValue()) { + int rgb = this.<Color>getParameter("color").getValue().getRGB(); + fr.drawString("Skill: 100 (0 Deaths)", 0, 0, rgb); + fr.drawString("Explorer: 99 (Rooms O 39/40)", 0, 8, rgb); + fr.drawString("Time: 100 Bonus: 0 Total: 299", 0, 16, rgb); + fr.drawString("S->S+ (1 Required 1 tomb)", 0, 24, rgb); + } else { + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Score: 305 (S+)", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + } + + @Data + @AllArgsConstructor + public static class ScoreCalculation { + private int skill, explorer, time, bonus, tombs; + private boolean fullyCleared; + private int secrets, totalSecrets; + private boolean totalSecretsKnown; + private int deaths; + } + + public ScoreCalculation calculateScore() { + if (!skyblockStatus.isOnDungeon()) return null; + DungeonContext context = skyblockStatus.getContext(); + if (context == null) return null; + int skill = 100; + int deaths = 0; + { + deaths = FeatureRegistry.DUNGEON_DEATHS.getTotalDeaths(); + skill -= FeatureRegistry.DUNGEON_DEATHS.getTotalDeaths() * 2; + for (DungeonRoom dungeonRoom : context.getDungeonRoomList()) { + skill += dungeonRoom.getCurrentState().getScoreModifier(); + } + } + int explorer = 0; + boolean fullyCleared = false; + boolean totalSecretsKnown = true; + int totalSecrets = 0; + int secrets = 0; + { + int clearedRooms = 0; + for (DungeonRoom dungeonRoom : context.getDungeonRoomList()) { + if (!(dungeonRoom.getCurrentState() == DungeonRoom.RoomState.DISCOVERED)) { + clearedRooms ++; + } + if (dungeonRoom.getTotalSecrets() != -1) + totalSecrets += dungeonRoom.getTotalSecrets(); + else totalSecretsKnown = false; + } + fullyCleared = clearedRooms == context.getDungeonRoomList().size() && context.getMapProcessor().getUndiscoveredRoom() == 0; + explorer += MathHelper.clamp_int((int) Math.floor(60 * (clearedRooms / ((double)context.getDungeonRoomList().size() + context.getMapProcessor().getUndiscoveredRoom()))), 0, 60); + explorer += MathHelper.clamp_int((int) Math.floor(40 * ((secrets = FeatureRegistry.DUNGEON_SECRETS.getSecretsFound()) / (double)totalSecrets)),0,40); + } + int time = 0; + { + double timeModifier; + if (context.getMapProcessor().isInBossRoom()) { + timeModifier = Math.max(0, context.getBossRoomEnterSeconds() - 1200); + } else { + timeModifier = Math.max(0, FeatureRegistry.DUNGEON_SBTIME.getTimeElapsed() / 1000 - 1200); + } + time = (int) Math.floor(100 - 2.2 * timeModifier); + } + int bonus = 0; + int tombs; + { + bonus += tombs = MathHelper.clamp_int(FeatureRegistry.DUNGEON_TOMBS.getTombsFound(), 0, 5); + } + + // amazing thing + return new ScoreCalculation(skill, explorer, time, bonus, tombs, fullyCleared, secrets, totalSecrets, totalSecretsKnown, deaths); + } + public String getLetter(int score) { + if (score <= 99) return "D"; + if (score <= 159) return "C"; + if (score <= 229) return "B"; + if (score <= 269) return "A"; + if (score <= 299) return "S"; + return "S+"; + } + public int getScoreRequirement(String letter) { + if (letter.equals("D")) return 0; + if (letter.equals("C")) return 100; + if (letter.equals("B")) return 160; + if (letter.equals("A")) return 230; + if (letter.equals("S")) return 270; + if (letter.equals("S+")) return 300; + return -1; + } + public String getNextLetter(String letter) { + if (letter.equals("D")) return "C"; + if (letter.equals("C")) return "B"; + if (letter.equals("B")) return "A"; + if (letter.equals("A")) return "S"; + if (letter.equals("S")) return "S+"; + else return null; + } + public String buildRequirement(ScoreCalculation calculation) { + int current = calculation.time + calculation.bonus + calculation.explorer + calculation.skill; + String currentLetter = getLetter(current); + String nextLetter= getNextLetter(currentLetter); + if (nextLetter == null) return "S+ Expected"; + int req = getScoreRequirement(nextLetter); + int reqPT2 = req- current; + int reqPT = req - current; + + int tombsBreakable = Math.min(5 - calculation.tombs, reqPT); + reqPT -= tombsBreakable; + + double secretPer = 40.0 / calculation.totalSecrets; + int secrets = (int) Math.ceil(reqPT / secretPer); + + return currentLetter+"->"+nextLetter+" ("+reqPT2+" Req "+tombsBreakable+" crypts "+secrets+" secrets"+(calculation.totalSecretsKnown ? "" : "?")+")"; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSecrets.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSecrets.java new file mode 100644 index 00000000..afe8da07 --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonSecrets.java @@ -0,0 +1,71 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; +import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.FeatureRegistry; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.features.listener.ChatListener; +import kr.syeyoung.dungeonsguide.features.listener.TickListener; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.scoreboard.ScorePlayerTeam; +import net.minecraft.util.ChatComponentText; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.regex.Pattern; + +public class FeatureDungeonSecrets extends GuiFeature { + public FeatureDungeonSecrets() { + super("Dungeon", "Display #Secrets", "Display how much total secrets have been found in a dungeon run.\n+ sign means DG does not know the correct number, but it's somewhere above that number.", "dungeon.stats.secrets", true, getFontRenderer().getStringWidth("Secrets: 999/999+"), getFontRenderer().FONT_HEIGHT); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + @Override + public void drawHUD(float partialTicks) { + if (!skyblockStatus.isOnDungeon()) return; + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Secrets: "+getSecretsFound() +"/"+getTotalSecrets(), 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Secrets: 999/2+", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + public int getSecretsFound() { + for (NetworkPlayerInfo networkPlayerInfoIn : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { + String name = networkPlayerInfoIn.getDisplayName() != null ? networkPlayerInfoIn.getDisplayName().getFormattedText() : ScorePlayerTeam.formatPlayerName(networkPlayerInfoIn.getPlayerTeam(), networkPlayerInfoIn.getGameProfile().getName()); + if (name.startsWith("§r Secrets Found: §r§b")) { + String noColor = TextUtils.stripColor(name); + return Integer.parseInt(noColor.substring(16)); + } + } + return 0; + } + + public String getTotalSecrets() { + DungeonContext context = skyblockStatus.getContext(); + int totalSecrets = 0; + boolean allknown = true; + for (DungeonRoom dungeonRoom : context.getDungeonRoomList()) { + if (dungeonRoom.getTotalSecrets() != -1) + totalSecrets += dungeonRoom.getTotalSecrets(); + else allknown = false; + } + return totalSecrets + (allknown ? "":"+"); + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonTombs.java b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonTombs.java new file mode 100644 index 00000000..511e971f --- /dev/null +++ b/src/main/java/kr/syeyoung/dungeonsguide/features/impl/FeatureDungeonTombs.java @@ -0,0 +1,50 @@ +package kr.syeyoung.dungeonsguide.features.impl; + +import kr.syeyoung.dungeonsguide.SkyblockStatus; +import kr.syeyoung.dungeonsguide.e; +import kr.syeyoung.dungeonsguide.features.FeatureParameter; +import kr.syeyoung.dungeonsguide.features.GuiFeature; +import kr.syeyoung.dungeonsguide.utils.TextUtils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.network.NetworkPlayerInfo; +import net.minecraft.scoreboard.ScorePlayerTeam; +import org.lwjgl.opengl.GL11; + +import java.awt.*; + +public class FeatureDungeonTombs extends GuiFeature { + public FeatureDungeonTombs() { + super("Dungeon", "Display #Crypts", "Display how much total crypts have been blown up in a dungeon run", "dungeon.stats.tombs", true, getFontRenderer().getStringWidth("Crypts: 42"), getFontRenderer().FONT_HEIGHT); + this.setEnabled(false); + parameters.put("color", new FeatureParameter<Color>("color", "Color", "Color of text", Color.orange, "color")); + } + + SkyblockStatus skyblockStatus = e.getDungeonsGuide().getSkyblockStatus(); + @Override + public void drawHUD(float partialTicks) { + if (!skyblockStatus.isOnDungeon()) return; + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Crypts: "+getTombsFound(), 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + @Override + public void drawDemo(float partialTicks) { + FontRenderer fr = getFontRenderer(); + double scale = getFeatureRect().getHeight() / fr.FONT_HEIGHT; + GL11.glScaled(scale, scale, 0); + fr.drawString("Crypts: 42", 0,0, this.<Color>getParameter("color").getValue().getRGB()); + } + + public int getTombsFound() { + for (NetworkPlayerInfo networkPlayerInfoIn : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { + String name = networkPlayerInfoIn.getDisplayName() != null ? networkPlayerInfoIn.getDisplayName().getFormattedText() : ScorePlayerTeam.formatPlayerName(networkPlayerInfoIn.getPlayerTeam(), networkPlayerInfoIn.getGameProfile().getName()); + if (name.startsWith("§r Crypts: §r§6")) { + return Integer.parseInt(TextUtils.stripColor(name).substring(9)); + } + } + return 0; + } +} diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java index 541d5ccc..a46ea8cb 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/GeneralRoomProcessor.java @@ -1,13 +1,17 @@ package kr.syeyoung.dungeonsguide.roomprocessor; import kr.syeyoung.dungeonsguide.config.Config; +import kr.syeyoung.dungeonsguide.dungeon.DungeonContext; import kr.syeyoung.dungeonsguide.dungeon.mechanics.DungeonMechanic; import kr.syeyoung.dungeonsguide.dungeon.roomfinder.DungeonRoom; +import kr.syeyoung.dungeonsguide.e; import kr.syeyoung.dungeonsguide.features.FeatureRegistry; import kr.syeyoung.dungeonsguide.roomedit.EditingContext; import kr.syeyoung.dungeonsguide.roomedit.gui.GuiDungeonRoomEdit; import lombok.Getter; import lombok.Setter; +import net.minecraft.client.Minecraft; +import net.minecraft.util.BlockPos; import net.minecraft.util.IChatComponent; import java.awt.*; @@ -48,6 +52,35 @@ public class GeneralRoomProcessor implements RoomProcessor { } @Override + public void actionbarReceived(IChatComponent chat) { + if (dungeonRoom.getTotalSecrets() != -1) return; + BlockPos pos = Minecraft.getMinecraft().thePlayer.getPosition(); + DungeonContext context = e.getDungeonsGuide().getSkyblockStatus().getContext(); + Point pt1 = context.getMapProcessor().worldPointToRoomPoint(pos.add(2,0,2)); + Point pt2 = context.getMapProcessor().worldPointToRoomPoint(pos.add(-2,0,-2)); + if (!pt1.equals(pt2)) { + return; + } + + + String text = chat.getFormattedText(); + int secretsIndex = text.indexOf("Secrets"); + if (secretsIndex == -1) { + dungeonRoom.setTotalSecrets(0); + return; + } + int theindex = 0; + for (int i = secretsIndex; i > 0; i--) { + if (text.startsWith("§7", i)) { + theindex = i; + } + } + String it = text.substring(theindex + 2, secretsIndex- 1); + int maxSecret = Integer.parseInt(it.split("/")[1]); + dungeonRoom.setTotalSecrets(maxSecret); + } + + @Override public boolean readGlobalChat() { return false; } diff --git a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java index f768ac40..e922cfd1 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/roomprocessor/RoomProcessor.java @@ -8,6 +8,7 @@ public interface RoomProcessor { void drawScreen(float partialTicks); void drawWorld(float partialTicks); void chatReceived(IChatComponent chat); + void actionbarReceived(IChatComponent chat); boolean readGlobalChat(); }
\ No newline at end of file diff --git a/src/main/java/kr/syeyoung/dungeonsguide/utils/TextUtils.java b/src/main/java/kr/syeyoung/dungeonsguide/utils/TextUtils.java index 300cf6ba..a27a1695 100755 --- a/src/main/java/kr/syeyoung/dungeonsguide/utils/TextUtils.java +++ b/src/main/java/kr/syeyoung/dungeonsguide/utils/TextUtils.java @@ -62,4 +62,23 @@ public class TextUtils { return hasDecimal ? ((truncated / 10.0D) + suffix) : ((truncated / 10L) + suffix); } + public static String formatTime(long ms) { + long seconds = ms / 1000; + long hr = seconds / (60 * 60); seconds -= hr * 60 * 60; + long min = seconds / 60; seconds -= min * 60; + + StringBuilder stringBuilder = new StringBuilder(); + if (hr > 0) { + stringBuilder.append(hr).append("h "); + } + if (hr > 0 || min > 0) { + stringBuilder.append(min).append("m "); + } + if (hr > 0 || min > 0 || seconds > 0) { + stringBuilder.append(seconds).append("s "); + } + + return stringBuilder.toString(); + } + }
\ No newline at end of file |