diff options
Diffstat (limited to 'src/main/java/de')
30 files changed, 638 insertions, 226 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index 4e110e15..5e573598 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -2,6 +2,8 @@ package de.hysky.skyblocker; import com.google.gson.Gson; import com.google.gson.GsonBuilder; + +import de.hysky.skyblocker.config.ConfigNullFieldsFix; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.datafixer.ConfigDataFixer; import de.hysky.skyblocker.debug.Debug; @@ -109,13 +111,14 @@ public class SkyblockerMod implements ClientModInitializer { ConfigDataFixer.apply(); Utils.init(); SkyblockerConfigManager.init(); + ConfigNullFieldsFix.init(); //DO NOT INIT ANY CLASS THAT USES CONFIG FIELDS BEFORE THIS! SkyblockerScreen.initClass(); ProfileViewerScreen.initClass(); Tips.init(); NEURepoManager.init(); //ImageRepoLoader.init(); ItemRepository.init(); - PlayerHeadHashCache.init(); + SkyblockItemData.init(); HotbarSlotLock.init(); ItemTooltip.init(); AccessoriesHelper.init(); diff --git a/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java new file mode 100644 index 00000000..a16b3359 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/config/ConfigNullFieldsFix.java @@ -0,0 +1,63 @@ +package de.hysky.skyblocker.config; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Map; + +import org.slf4j.Logger; + +import com.mojang.logging.LogUtils; + +import dev.isxander.yacl3.config.v2.api.SerialEntry; + +/** + * While this sounds like a data fixer it isn't. - It's the only reasonable solution to deal with the mine field + * that is YACL's null handling. + */ +public class ConfigNullFieldsFix { + private static final Logger LOGGER = LogUtils.getLogger(); + private static final String CONFIGS_PACKAGE = "de.hysky.skyblocker.config.configs"; + + public static void init() { + SkyblockerConfig current = SkyblockerConfigManager.get(); + SkyblockerConfig clean = new SkyblockerConfig(); + + try { + fixNullFields(current, clean); + SkyblockerConfigManager.save(); + } catch (Exception e) { + LOGGER.error("[Skyblocker Config Null Fields Fixer] Failed to ensure that the config has no null fields! You may encounter crashes :(", e); + } + } + + /** + * Traverse through every config field to ensure that is isn't null, if it is then reset the value. + */ + private static void fixNullFields(Object target, Object source) throws Exception { + for (Field field : target.getClass().getDeclaredFields()) { + if (field.isAnnotationPresent(SerialEntry.class)) { + field.setAccessible(true); + + Object targetValue = field.get(target); + Object sourceValue = field.get(source); + + if (targetValue == null && sourceValue != null) { + field.set(target, sourceValue); + } else if (targetValue != null && sourceValue != null && isFixable(field.getType())) { + fixNullFields(targetValue, sourceValue); + } + } + } + } + + private static boolean isFixable(Class<?> clazz) { + return !clazz.isPrimitive() + && !clazz.isEnum() + && !clazz.isRecord() + && !clazz.equals(String.class) + && !Number.class.isAssignableFrom(clazz) + && !Map.class.isAssignableFrom(clazz) + && !Collection.class.isAssignableFrom(clazz) + && clazz.getPackageName().startsWith(CONFIGS_PACKAGE); + } +} diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java index bea570e5..ff089432 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java @@ -229,6 +229,14 @@ public class GeneralCategory { newValue -> config.general.itemTooltip.showEssenceCost = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue.@Tooltip"))) + .binding(defaults.general.itemTooltip.enableEstimatedItemValue, + () -> config.general.itemTooltip.enableEstimatedItemValue, + newValue -> config.general.itemTooltip.enableEstimatedItemValue = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .build()) //Item Info Display @@ -326,6 +334,14 @@ public class GeneralCategory { newValue -> config.general.specialEffects.rareDungeonDropEffects = newValue) .controller(ConfigUtils::createBooleanController) .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.config.general.specialEffects.rareDyeDropEffects")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.general.specialEffects.rareDyeDropEffects.@Tooltip"))) + .binding(defaults.general.specialEffects.rareDyeDropEffects, + () -> config.general.specialEffects.rareDyeDropEffects, + newValue -> config.general.specialEffects.rareDyeDropEffects = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) .build()) //Hitboxes diff --git a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java index 61386452..92206c49 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java @@ -135,6 +135,9 @@ public class GeneralConfig { @SerialEntry public boolean showEssenceCost = false; + + @SerialEntry + public boolean enableEstimatedItemValue = true; } public enum Average { @@ -241,6 +244,9 @@ public class GeneralConfig { public static class SpecialEffects { @SerialEntry public boolean rareDungeonDropEffects = true; + + @SerialEntry + public boolean rareDyeDropEffects = true; } public static class Hitbox { diff --git a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java index fd7c30f3..ac3e5a72 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/QuickNavigationConfig.java @@ -65,6 +65,15 @@ public class QuickNavigationConfig { public QuickNavItem button14 = new QuickNavItem(new ItemData(Items.CRAFTING_TABLE), "Craft Item", "/craft", "Crafting Table"); public static class QuickNavItem { + /** + * Default constructor or else gson skips initialization. + */ + private QuickNavItem() {} + + public QuickNavItem(ItemData itemData, String clickEvent, String tooltip) { + this(itemData, "none", clickEvent, tooltip); + } + public QuickNavItem(ItemData itemData, @Language("RegExp") String uiTitle, String clickEvent, String tooltip) { this.itemData = itemData; this.uiTitle = uiTitle; @@ -72,10 +81,6 @@ public class QuickNavigationConfig { this.tooltip = tooltip; } - public QuickNavItem(ItemData itemData, String clickEvent, String tooltip) { - this(itemData, "none", clickEvent, tooltip); - } - @SerialEntry public boolean render = true; @@ -86,7 +91,7 @@ public class QuickNavigationConfig { public String uiTitle; @SerialEntry - public String tooltip; + public String tooltip = ""; @SerialEntry public String clickEvent; diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java index f1240a1c..fff12619 100644 --- a/src/main/java/de/hysky/skyblocker/debug/Debug.java +++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java @@ -8,11 +8,14 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; import de.hysky.skyblocker.utils.Constants; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; +import de.hysky.skyblocker.utils.networth.NetworthCalculator; +import net.azureaaron.networth.Calculation; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.item.ItemStack; @@ -49,20 +52,25 @@ public class Debug { ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("debug") .then(dumpPlayersCommand()) .then(ItemUtils.dumpHeldItemCommand()) + .then(ItemUtils.dumpHeldItemNetworthCalculationsCommand()) .then(toggleShowingInvisibleArmorStands()) .then(dumpArmorStandHeadTextures()) .then(toggleWebSocketDebug()) ))); ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> { if (screen instanceof HandledScreen<?> handledScreen) { - ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> { - Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot(); - if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) { - client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow()))); - } - }); - } - }); + ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> { + Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot(); + if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) { + if (!Screen.hasShiftDown()) { + client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow()))); + } else { + client.player.sendMessage(Text.literal("[Skyblocker Debug] Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(focusedSlot.getStack()).calculations()).getOrThrow()))); + } + } + }); + } + }); } } @@ -108,4 +116,4 @@ public class Debug { return Command.SINGLE_SUCCESS; }); } -} +}
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java index 67928b07..0b188a37 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java @@ -7,6 +7,7 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor; import de.hysky.skyblocker.mixins.accessors.ScreenAccessor; import de.hysky.skyblocker.utils.ItemUtils; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.networth.NetworthCalculator; import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair; import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents; import net.fabricmc.fabric.api.client.screen.v1.Screens; @@ -192,7 +193,7 @@ public class ChestValue { if (!priceData.rightBoolean()) hasIncompleteData = true; - value += priceData.leftDouble() * stack.getCount(); + value += NetworthCalculator.getItemNetworth(stack).price(); } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java index 12954118..db91996a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CroesusProfit.java @@ -20,7 +20,7 @@ import java.util.regex.Pattern; public class CroesusProfit extends SimpleContainerSolver { private static final Pattern ESSENCE_PATTERN = Pattern.compile("(?<type>[A-Za-z]+) Essence x(?<amount>\\d+)"); public CroesusProfit() { - super(".*Catacombs - Floor.*"); + super(".*The Catacombs - Flo.*"); } @Override diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java index 511827b9..f81fae0c 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/waterboard/Waterboard.java @@ -282,13 +282,13 @@ public class Waterboard extends DungeonPuzzle { // Check if left down is in range and is closer than right down. // Note 1: The yarn name "getFlowSpeed" is incorrect as it actually returns the maximum distance that water will check for a hole to flow towards. // Note 2: Skyblock's maximum offset is 5 instead of 4 for some reason. - if (-leftFlowDownOffset <= ((WaterFluid) Fluids.WATER).getFlowSpeed(null) + 1 && -leftFlowDownOffset < rightFlowDownOffset) { + if (-leftFlowDownOffset <= ((WaterFluid) Fluids.WATER).getMaxFlowDistance(null) + 1 && -leftFlowDownOffset < rightFlowDownOffset) { result.putPath(water, leftFlowDownOffset); water.add(leftFlowDownOffset, 1); continue; } // Check if right down is in range and closer than left down. - if (rightFlowDownOffset <= ((WaterFluid) Fluids.WATER).getFlowSpeed(null) + 1 && rightFlowDownOffset < -leftFlowDownOffset) { + if (rightFlowDownOffset <= ((WaterFluid) Fluids.WATER).getMaxFlowDistance(null) + 1 && rightFlowDownOffset < -leftFlowDownOffset) { result.putPath(water, rightFlowDownOffset); water.add(rightFlowDownOffset, 1); continue; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java index 11f31f34..fbe99909 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonManager.java @@ -22,6 +22,7 @@ import de.hysky.skyblocker.utils.Tickable; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.command.argumenttypes.blockpos.ClientBlockPosArgumentType; import de.hysky.skyblocker.utils.command.argumenttypes.blockpos.ClientPosArgument; +import de.hysky.skyblocker.utils.render.RenderHelper; import de.hysky.skyblocker.utils.scheduler.Scheduler; import it.unimi.dsi.fastutil.objects.Object2ByteMap; import it.unimi.dsi.fastutil.objects.Object2ByteMaps; @@ -41,7 +42,6 @@ import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandSource; import net.minecraft.command.argument.TextArgumentType; import net.minecraft.component.DataComponentTypes; -import net.minecraft.entity.Entity; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.AmbientEntity; @@ -59,12 +59,14 @@ import net.minecraft.util.Identifier; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import net.minecraft.world.World; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.joml.Vector2i; import org.joml.Vector2ic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -77,11 +79,11 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; import java.util.zip.InflaterInputStream; +import static de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonMapUtils.*; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument; import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; @@ -89,7 +91,11 @@ public class DungeonManager { protected static final Logger LOGGER = LoggerFactory.getLogger(DungeonManager.class); private static final String DUNGEONS_PATH = "dungeons"; private static Path CUSTOM_WAYPOINTS_DIR; - private static final Pattern KEY_FOUND = Pattern.compile("^(?:\\[.+] )?(?<name>\\w+) has obtained (?<type>Wither|Blood) Key!$"); + private static final Pattern KEY_FOUND = Pattern.compile("^RIGHT CLICK on (?:the BLOOD DOOR|a WITHER door) to open it. This key can only be used to open 1 door!$"); + private static final Pattern WITHER_DOOR_OPENED = Pattern.compile("^\\w+ opened a WITHER door!$"); + private static final String BLOOD_DOOR_OPENED = "The BLOOD DOOR has been opened!"; + protected static final float[] RED_COLOR_COMPONENTS = {1, 0, 0}; + protected static final float[] GREEN_COLOR_COMPONENTS = {0, 1, 0}; /** * Maps the block identifier string to a custom numeric block id used in dungeon rooms data. * @@ -152,6 +158,10 @@ public class DungeonManager { private static Room currentRoom; @NotNull private static DungeonBoss boss = DungeonBoss.NONE; + @Nullable + private static Box bloodRushDoorBox; + private static boolean bloodOpened; + private static boolean hasKey; public static boolean isRoomsLoaded() { return roomsLoaded != null && roomsLoaded.isDone(); @@ -551,6 +561,8 @@ public class DungeonManager { LOGGER.info("[Skyblocker Dungeon Secrets] Started dungeon with map room size {}, map entrance pos {}, player pos {}, and physical entrance pos {}", mapRoomSize, mapEntrancePos, client.player.getPos(), physicalEntrancePos); } + getBloodRushDoorPos(map); + Vector2ic physicalPos = DungeonMapUtils.getPhysicalRoomPos(client.player.getPos()); Vector2ic mapPos = DungeonMapUtils.getMapPosFromPhysical(physicalEntrancePos, mapEntrancePos, mapRoomSize, physicalPos); Room room = rooms.get(physicalPos); @@ -565,12 +577,6 @@ public class DungeonManager { } } if (room != null && currentRoom != room) { - if (currentRoom != null && room.getType() == Room.Type.FAIRY) { - currentRoom.nextRoom = room; - if (currentRoom.keyFound) { - room.keyFound = true; - } - } currentRoom = room; } currentRoom.tick(client); @@ -604,14 +610,24 @@ public class DungeonManager { if (shouldProcess() && currentRoom != null) { currentRoom.render(context); } + + if (bloodRushDoorBox != null && !bloodOpened && SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight) { + float[] colorComponents = hasKey ? GREEN_COLOR_COMPONENTS : RED_COLOR_COMPONENTS; + switch (SkyblockerConfigManager.get().dungeons.doorHighlight.doorHighlightType) { + case HIGHLIGHT -> RenderHelper.renderFilled(context, bloodRushDoorBox, colorComponents, 0.5f, true); + case OUTLINED_HIGHLIGHT -> { + RenderHelper.renderFilled(context, bloodRushDoorBox, colorComponents, 0.5f, true); + RenderHelper.renderOutline(context, bloodRushDoorBox, colorComponents, 5, true); + } + case OUTLINE -> RenderHelper.renderOutline(context, bloodRushDoorBox, colorComponents, 5, true); + } + } } /** * Calls {@link Room#onChatMessage(String)} on {@link #currentRoom} if the message is an overlay message and {@link #isCurrentRoomMatched()} and processes key obtained messages. * <p>Used to detect when all secrets in a room are found and detect when a wither or blood door is unlocked. * To process key obtained messages, this method checks if door highlight is enabled and if the message matches a key obtained message. - * Then, it calls {@link Room#keyFound()} on {@link #currentRoom} if the client's player is the one who obtained the key. - * Otherwise, it calls {@link Room#keyFound()} on the room the player who obtained the key is in. */ private static void onChatMessage(Text text, boolean overlay) { if (!shouldProcess()) { @@ -625,30 +641,17 @@ public class DungeonManager { } // Process key found messages for door highlight - if (SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight) { - Matcher matcher = KEY_FOUND.matcher(message); - if (matcher.matches()) { - String name = matcher.group("name"); - MinecraftClient client = MinecraftClient.getInstance(); - if (client.player != null && client.player.getGameProfile().getName().equals(name)) { - if (currentRoom != null) { - currentRoom.keyFound(); - } else { - LOGGER.warn("[Skyblocker Dungeon Door] The current room at the current player {} does not exist", name); - } - } else if (client.world != null) { - Optional<Vec3d> posOptional = client.world.getPlayers().stream().filter(player -> player.getGameProfile().getName().equals(name)).findAny().map(Entity::getPos); - if (posOptional.isPresent()) { - Room room = getRoomAtPhysical(posOptional.get()); - if (room != null) { - room.keyFound(); - } else { - LOGGER.warn("[Skyblocker Dungeon Door] Failed to find room at player {} with position {}", name, posOptional.get()); - } - } else { - LOGGER.warn("[Skyblocker Dungeon Door] Failed to find player {}", name); - } - } + if (SkyblockerConfigManager.get().dungeons.doorHighlight.enableDoorHighlight && !bloodOpened) { + if (BLOOD_DOOR_OPENED.equals(message)) { + bloodOpened = true; + } + + if (KEY_FOUND.matcher(message).matches()) { + hasKey = true; + } + + if (WITHER_DOOR_OPENED.matcher(message).matches()) { + hasKey = false; } } @@ -770,5 +773,49 @@ public class DungeonManager { rooms.clear(); currentRoom = null; boss = DungeonBoss.NONE; + bloodRushDoorBox = null; + bloodOpened = false; + hasKey = false; + } + + /** + * Determines where the current door of interest is + * + * @implNote Relies on the minimap to check for doors + */ + private static void getBloodRushDoorPos(@NotNull MapState map) { + if (mapEntrancePos == null || mapRoomSize == 0) { + LOGGER.error("[Skyblocker Dungeon Secrets] Dungeon map info missing with map entrance pos {} and map room size {}", mapEntrancePos, mapRoomSize); + return; + } + + Vector2i nWMostRoom = getMapPosForNWMostRoom(mapEntrancePos, mapRoomSize); + + for (int x = nWMostRoom.x + mapRoomSize / 2; x < 128; x += mapRoomSize + 4) { + for (int y = nWMostRoom.y + mapRoomSize; y < 128; y += mapRoomSize + 4) { + byte color = getColor(map, x, y); + + // 119 is the black found on wither doors on the map, 18 is the blood door red + if (color == 119 || color == 18) { + Vector2ic doorPos = getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, new Vector2i(x - mapRoomSize / 2, y - mapRoomSize)); + bloodRushDoorBox = new Box(doorPos.x() + 14, 69, doorPos.y() + 30, doorPos.x() + 17, 73, doorPos.y() + 33); + + return; + } + } + } + + for (int x = nWMostRoom.x + mapRoomSize; x < 128; x += mapRoomSize + 4) { + for (int y = nWMostRoom.y + mapRoomSize / 2; y < 128; y += mapRoomSize + 4) { + byte color = getColor(map, x, y); + + if (color == 119 || color == 18) { + Vector2ic doorPos = getPhysicalPosFromMap(mapEntrancePos, mapRoomSize, physicalEntrancePos, new Vector2i(x - mapRoomSize, y - mapRoomSize / 2)); + bloodRushDoorBox = new Box(doorPos.x() + 30, 69, doorPos.y() + 14, doorPos.x() + 33, 73, doorPos.y() + 17); + + return; + } + } + } } } |
