diff options
| author | olim <bobq4582@gmail.com> | 2024-02-20 12:11:17 +0000 |
|---|---|---|
| committer | olim <bobq4582@gmail.com> | 2024-02-20 12:11:17 +0000 |
| commit | 9a3deba1170b8ba4c5fdccc0a6df0788123ce041 (patch) | |
| tree | d19d7cf6e87def4c9c724c5ca1ce672c40b782ea | |
| parent | 28299e61238d90d690541e713e1c059e6ec00ed0 (diff) | |
| parent | 20117e764d3a4f444efd06c846449395caac20aa (diff) | |
| download | Skyblocker-9a3deba1170b8ba4c5fdccc0a6df0788123ce041.tar.gz Skyblocker-9a3deba1170b8ba4c5fdccc0a6df0788123ce041.tar.bz2 Skyblocker-9a3deba1170b8ba4c5fdccc0a6df0788123ce041.zip | |
Merge remote-tracking branch 'upstream/master' into chat-rules
32 files changed, 921 insertions, 216 deletions
diff --git a/.github/workflows/beta.yml b/.github/workflows/beta.yml index 9f0b8490..7e444cb8 100644 --- a/.github/workflows/beta.yml +++ b/.github/workflows/beta.yml @@ -19,9 +19,9 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 with: result-encoding: string script: | @@ -31,13 +31,13 @@ jobs: fs.writeFileSync("./gradle.properties", file); - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'microsoft' java-version: '17' - name: Initialize caches - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ~/.gradle/caches @@ -53,7 +53,7 @@ jobs: - name: Build with Gradle run: ./gradlew build - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 id: fname with: result-encoding: string @@ -61,7 +61,7 @@ jobs: const fs = require("fs") return fs.readdirSync("build/libs/").filter(e => !e.endsWith("dev.jar") && !e.endsWith("sources.jar") && e.endsWith(".jar"))[0].replace(".jar", ""); - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ${{ steps.fname.outputs.result }} path: build/libs/ diff --git a/.github/workflows/buildrelease.yml b/.github/workflows/buildrelease.yml index 4a15fe57..b062d079 100644 --- a/.github/workflows/buildrelease.yml +++ b/.github/workflows/buildrelease.yml @@ -17,9 +17,9 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'microsoft' java-version: '17' @@ -30,7 +30,7 @@ jobs: - name: Build with Gradle run: ./gradlew build - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: Artifacts path: build/libs/ @@ -46,55 +46,29 @@ jobs: CHANGELOGtmp="${CHANGELOGtmp//$'\n'/'%0A'}" CHANGELOGtmp="${CHANGELOGtmp//$'\r'/'%0D'}" - echo "::set-output name=changelog::$CHANGELOGtmp" + # changelog for Github release + echo "changelog=$CHANGELOGtmp" >> $GITHUB_OUTPUT - echo "Changelog:\n$CHANGELOG" + #echo "Changelog:\n$CHANGELOG" # for debugging changelog="${CHANGELOG}" + highlight_section=$(echo "$changelog" | awk '/## Highlight/{flag=1;next}/^$/{flag=0}flag') + highlight_section="# Highlight\n$highlight_section\n\nhttps://hysky.de/" - # Because of the 2000 char limit in Discord shorten the changelog - - # Calculate the number of characters to delete - delete_chars=$((${#changelog} + 350 - 2000 - 15)) + # Format highlight_section with printf + highlight_section=$(printf "%s" "$highlight_section") - # Check if delete_chars is greater than 0 - if [ $delete_chars -gt 0 ]; then - - # Extract the "What's Changed" section from the changelog - changed_section=$(echo "$changelog" | awk '/## What'\''s Changed/{flag=1;next}/^$/{flag=0}flag') - - # Trim the changed_section based on the delete_chars value and remove the last line - modified_section="${changed_section::-delete_chars}" - modified_section=$(echo "$modified_section" | sed '$d') - - # Add "[...] and more" at the end of modified_section - modified_section+="\n[...] and more" - - # Format modified_section with printf - modified_section=$(printf "%s" "$modified_section") - - # Generate the modified_changelog by inserting modified_section after the "What's Changed" section - modified_changelog=$(awk -v modified_section="$modified_section" ' - /^## What'\''s Changed/ { print; print modified_section; f=1; next } - f && /^$/ { f=0 } - !f { print } - END { if (f) print "" } - ' ORS='\n' <<< "$changelog") - - # Format the modified_changelog by removing "@" characters and enclosing URLs in "<>" - # modified_changelog=$(echo "$modified_changelog" | sed -e 's/@//g' -e 's|https\?://[^[:space:]]*|<\0>|g') - - # Store the modified_changelog in the CHANGELOG variable - CHANGELOG=$(echo -n "$modified_changelog") - fi + # Store the highlight_section in the CHANGELOG variable + CHANGELOG=$(echo -n "$highlight_section") CHANGELOG="${CHANGELOG//'%'/'%25'}" CHANGELOG="${CHANGELOG//$'\n'/'%0A'}" CHANGELOG="${CHANGELOG//$'\r'/'%0D'}" - echo "::set-output name=changelog_discord::$CHANGELOG" + # changelog for rest + echo "changelog_highlight=$CHANGELOG" >> $GITHUB_OUTPUT - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 id: fname with: result-encoding: string @@ -110,35 +84,13 @@ jobs: token: ${{ secrets.GH_RELEASE }} files: build/libs/${{ steps.fname.outputs.result }} - - name: Publish to Modrinth - id: modrinth + - name: Publish using mod-publish-plugin + run: ./gradlew build publishMods env: - MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} - CHANGELOG: ${{ steps.read_changelog.outputs.changelog }} - run: ./gradlew modrinth - - - name: Get version tag - id: version_tag - run: | - [[ ! "$GITHUB_REF" =~ refs/tags ]] && exit - echo "::set-output name=value::${GITHUB_REF#refs/tags/}" - - - name: Discord notification - shell: bash - run: | - OUTPUT=" - <@&1134565945482948638> - ## Skyblocker ${{ steps.version_tag.outputs.value }} - - ${{ steps.read_changelog.outputs.changelog_discord }} - - :inbox_tray: Download latest version on Modrinth or Github: - <:modrinth:900697862206287882> ${{ steps.modrinth.outputs.url }} - <:github:900697885706952725> ${{ steps.uploadrelease.outputs.url }} - - https://hysky.de/" - - curl -H "Content-Type: application/json" -d '{"content":"'"${OUTPUT//$'\n'/\\n}"'", "flags": 4}' "${{ secrets.DISCORD_WEBHOOK }}" + CHANGELOG: ${{ steps.read_changelog.outputs.changelog_highlight }} + DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} + MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} + CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_TOKEN }} - name: Trigger Modpack shell: bash diff --git a/.github/workflows/webhook_translate.yml b/.github/workflows/webhook_translate.yml index c901c056..5d1208fa 100644 --- a/.github/workflows/webhook_translate.yml +++ b/.github/workflows/webhook_translate.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 2 @@ -22,7 +22,7 @@ jobs: with: go-version: '1.20' - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-pkg-mod-${{ hashFiles('go.sum') }} diff --git a/build.gradle b/build.gradle index b8349360..d7b37bfe 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'fabric-loom' version '1.5-SNAPSHOT' id 'maven-publish' - id 'com.modrinth.minotaur' version '2.+' + id "me.modmuss50.mod-publish-plugin" version "0.5.1" } version = "${project.mod_version}+${project.minecraft_version}" @@ -92,13 +92,6 @@ processResources { } tasks.withType(JavaCompile).configureEach { - // ensure that the encoding is set to UTF-8, no matter what the system default is - // this fixes some edge cases with special characters not displaying correctly - // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html - // If Javadoc is generated, this must be specified in that task too. - - - // Minecraft 1.18 upwards uses Java 17. it.options.release = 17 } @@ -122,30 +115,39 @@ test { useJUnitPlatform() } -modrinth { - token = System.getenv('MODRINTH_TOKEN') - projectId = project.modrinth_id - versionNumber = "v${project.version}" - versionName = "Skyblocker ${project.mod_version} for ${project.minecraft_version}" - uploadFile = remapJar - gameVersions = [project.minecraft_version] - loaders = ["fabric"] - versionType = "release" - dependencies { - required.project "fabric-api" - optional.project "modmenu" - optional.project "rei" - optional.project "emi" - } +publishMods { + file = remapJar.archiveFile changelog = System.getenv('CHANGELOG') - syncBodyFrom = rootProject.file("MRREADME.md").text -} + version = "v${project.version}" + displayName = "Skyblocker ${mod_version} for ${minecraft_version}" + modLoaders.add("fabric") + type = STABLE + + modrinth { + accessToken = System.getenv("MODRINTH_TOKEN") + projectId = modrinth_id + minecraftVersions.add(minecraft_version) + announcementTitle = "<:modrinth:900697862206287882> Download from Modrinth" + requires("fabric-api") + optional("modmenu", "rei", "emi") + } -tasks.modrinth.doLast { - println "::set-output name=url::https://modrinth.com/mod/skyblocker-liap/version/$uploadInfo.id" -} + curseforge { + accessToken = System.getenv("CURSEFORGE_TOKEN") + projectId = curseforge_id + minecraftVersions.add(minecraft_version) + announcementTitle = "<:curseforge:900697838453936149> Download from CurseForge" + projectSlug = "skyblocker" + requires("fabric-api") + optional("roughly-enough-items", "emi") + } -tasks.modrinth.dependsOn(tasks.modrinthSyncBody) + discord { + webhookUrl = System.getenv("DISCORD_WEBHOOK") + username = "Changelog" + content = changelog.map { "<@&1134565945482948638>\n## Skyblocker v${mod_version}\n" + it} + } +} // configure the maven publication publishing { diff --git a/gradle.properties b/gradle.properties index 8459bf8e..07340c99 100644 --- a/gradle.properties +++ b/gradle.properties @@ -37,4 +37,5 @@ commons_math_version = 3.6.1 mod_version = 1.17.0 maven_group = de.hysky archives_base_name = skyblocker -modrinth_id=y6DuFGwJ
\ No newline at end of file +modrinth_id=y6DuFGwJ +curseforge_id=936169
\ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java index fc72ea3f..edd4241e 100644 --- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java +++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java @@ -10,25 +10,23 @@ import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; import de.hysky.skyblocker.skyblock.chat.ChatRulesHandler; import de.hysky.skyblocker.skyblock.dungeon.*; import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; +import de.hysky.skyblocker.skyblock.dungeon.puzzle.*; import de.hysky.skyblocker.skyblock.dungeon.puzzle.boulder.Boulder; -import de.hysky.skyblocker.skyblock.dungeon.puzzle.CreeperBeams; -import de.hysky.skyblocker.skyblock.dungeon.puzzle.DungeonBlaze; -import de.hysky.skyblocker.skyblock.dungeon.puzzle.TicTacToe; import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Waterboard; import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker; import de.hysky.skyblocker.skyblock.dwarven.CrystalsHud; import de.hysky.skyblocker.skyblock.dwarven.CrystalsLocationsManager; import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud; -import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.end.BeaconHighlighter; +import de.hysky.skyblocker.skyblock.end.TheEnd; import de.hysky.skyblocker.skyblock.item.*; import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview; import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip; import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; import de.hysky.skyblocker.skyblock.quicknav.QuickNav; import de.hysky.skyblocker.skyblock.rift.TheRift; -import de.hysky.skyblocker.skyblock.searchOverlay.SearchOverManager; +import de.hysky.skyblocker.skyblock.searchoverlay.SearchOverManager; import de.hysky.skyblocker.skyblock.shortcut.Shortcuts; import de.hysky.skyblocker.skyblock.special.SpecialEffects; import de.hysky.skyblocker.skyblock.tabhud.TabHud; @@ -121,6 +119,8 @@ public class SkyblockerMod implements ClientModInitializer { DungeonManager.init(); DungeonBlaze.init(); Waterboard.init(); + Silverfish.init(); + IceFill.init(); DungeonScore.init(); PartyFinderScreen.initClass(); ChestValue.init(); diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java index ea1f7d43..4a1fe614 100644 --- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java @@ -723,6 +723,12 @@ public class SkyblockerConfig { public boolean solveBoulder = true; @SerialEntry + public boolean solveIceFill = true; + + @SerialEntry + public boolean solveSilverfish = true; + + @SerialEntry public boolean fireFreezeStaffTimer = true; @SerialEntry diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java index 5eb9a066..3ebd5d76 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java @@ -417,6 +417,20 @@ public class DungeonsCategory { .controller(ConfigUtils::createBooleanController) .build()) .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.solveIceFill")) + .binding(defaults.locations.dungeons.solveIceFill, + () -> config.locations.dungeons.solveIceFill, + newValue -> config.locations.dungeons.solveIceFill = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() + .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.solveSilverfish")) + .binding(defaults.locations.dungeons.solveSilverfish, + () -> config.locations.dungeons.solveSilverfish, + newValue -> config.locations.dungeons.solveSilverfish = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.fireFreezeStaffTimer")) .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.fireFreezeStaffTimer.@Tooltip"))) .binding(defaults.locations.dungeons.fireFreezeStaffTimer, diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java index 2a4c38a7..ceda9ed4 100644 --- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayerEntityMixin.java @@ -6,8 +6,8 @@ import de.hysky.skyblocker.skyblock.dungeon.partyfinder.PartyFinderScreen; import de.hysky.skyblocker.skyblock.item.HotbarSlotLock; import de.hysky.skyblocker.skyblock.item.ItemProtection; import de.hysky.skyblocker.skyblock.rift.HealingMelonIndicator; -import de.hysky.skyblocker.skyblock.searchOverlay.OverlayScreen; -import de.hysky.skyblocker.skyblock.searchOverlay.SearchOverManager; +import de.hysky.skyblocker.skyblock.searchoverlay.OverlayScreen; +import de.hysky.skyblocker.skyblock.searchoverlay.SearchOverManager; import de.hysky.skyblocker.utils.Utils; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.client.MinecraftClient; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java index 033a919d..5bc98894 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/kuudra/Kuudra.java @@ -10,7 +10,6 @@ import net.minecraft.text.Text; import net.minecraft.util.Formatting; public class Kuudra { - public static final String LOCATION = "kuudra"; static KuudraPhase phase = KuudraPhase.OTHER; public static void init() { diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/IceFill.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/IceFill.java new file mode 100644 index 00000000..57386674 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/IceFill.java @@ -0,0 +1,170 @@ +package de.hysky.skyblocker.skyblock.dungeon.puzzle; + +import com.google.common.primitives.Booleans; +import com.mojang.brigadier.Command; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.debug.Debug; +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.skyblock.dungeon.secrets.Room; +import de.hysky.skyblocker.utils.Constants; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.client.MinecraftClient; +import net.minecraft.util.DyeColor; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import org.joml.Vector2i; +import org.joml.Vector2ic; + +import java.util.*; +import java.util.concurrent.CompletableFuture; + +import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal; + +public class IceFill extends DungeonPuzzle { + public static final IceFill INSTANCE = new IceFill(); + private static final float[] RED_COLOR_COMPONENTS = DyeColor.RED.getColorComponents(); + private static final BlockPos[] BOARD_ORIGINS = { + new BlockPos(16, 70, 9), + new BlockPos(17, 71, 16), + new BlockPos(18, 72, 25) + }; + private CompletableFuture<Void> solve; + private final boolean[][][] iceFillBoards = {new boolean[3][3], new boolean[5][5], new boolean[7][7]}; + private final List<List<Vector2ic>> iceFillPaths = List.of(new ArrayList<>(), new ArrayList<>(), new ArrayList<>()); + + private IceFill() { + super("ice-fill", "ice-path"); + } + + public static void init() { + if (Debug.debugEnabled()) { + ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("dungeons").then(literal("puzzle").then(literal(INSTANCE.puzzleName) + .then(literal("printBoard1").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(boardToString(INSTANCE.iceFillBoards[0]))); + return Command.SINGLE_SUCCESS; + })).then(literal("printBoard2").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(boardToString(INSTANCE.iceFillBoards[1]))); + return Command.SINGLE_SUCCESS; + })).then(literal("printBoard3").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(boardToString(INSTANCE.iceFillBoards[2]))); + return Command.SINGLE_SUCCESS; + })).then(literal("printPath1").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(INSTANCE.iceFillPaths.get(0).toString())); + return Command.SINGLE_SUCCESS; + })).then(literal("printPath2").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(INSTANCE.iceFillPaths.get(1).toString())); + return Command.SINGLE_SUCCESS; + })).then(literal("printPath3").executes(context -> { + context.getSource().sendFeedback(Constants.PREFIX.get().append(INSTANCE.iceFillPaths.get(2).toString())); + return Command.SINGLE_SUCCESS; + })) + ))))); + } + } + + private static String boardToString(boolean[][] iceFillBoard) { + StringBuilder sb = new StringBuilder(); + for (boolean[] row : iceFillBoard) { + sb.append("\n"); + for (boolean cell : row) { + sb.append(cell ? '#' : '.'); + } + } + return sb.toString(); + } + + @Override + public void tick(MinecraftClient client) { + if (!SkyblockerConfigManager.get().locations.dungeons.solveIceFill || client.world == null || !DungeonManager.isCurrentRoomMatched() || solve != null && !solve.isDone()) { + return; + } + Room room = DungeonManager.getCurrentRoom(); + + solve = CompletableFuture.runAsync(() -> { + BlockPos.Mutable pos = new BlockPos.Mutable(); + for (int i = 0; i < 3; i++) { + if (updateBoard(client.world, room, iceFillBoards[i], pos.set(BOARD_ORIGINS[i]))) { + solve(iceFillBoards[i], iceFillPaths.get(i)); + } + } + }); + } + + private boolean updateBoard(World world, Room room, boolean[][] iceFillBoard, BlockPos.Mutable pos) { + boolean boardChanged = false; + for (int row = 0; row < iceFillBoard.length; pos.move(iceFillBoard[row].length, 0, -1), row++) { + for (int col = 0; col < iceFillBoard[row].length; pos.move(Direction.WEST), col++) { + BlockPos actualPos = room.relativeToActual(pos); + boolean isBlock = !world.getBlockState(actualPos).isAir(); + if (iceFillBoard[row][col] != isBlock) { + iceFillBoard[row][col] = isBlock; + boardChanged = true; + } + } + } + return boardChanged; + } + + void solve(boolean[][] iceFillBoard, List<Vector2ic> iceFillPath) { + Vector2ic start = new Vector2i(iceFillBoard.length - 1, iceFillBoard[0].length / 2); + int count = iceFillBoard.length * iceFillBoard[0].length - Arrays.stream(iceFillBoard).mapToInt(Booleans::countTrue).sum(); + + List<Vector2ic> newPath = solveDfs(iceFillBoard, count - 1, new ArrayList<>(List.of(start)), new HashSet<>(List.of(start))); + if (newPath != null) { + iceFillPath.clear(); + iceFillPath.addAll(newPath); + } + } + + private List<Vector2ic> solveDfs(boolean[][] iceFillBoard, int count, List<Vector2ic> path, Set<Vector2ic> visited) { + Vector2ic pos = path.get(path.size() - 1); + if (count == 0) { + if (pos.x() == 0 && pos.y() == iceFillBoard[0].length / 2) { + return path; + } else { + return null; + } + } + + Vector2ic[] newPosArray = {pos.add(1, 0, new Vector2i()), pos.add(-1, 0, new Vector2i()), pos.add(0, 1, new Vector2i()), pos.add(0, -1, new Vector2i())}; + for (Vector2ic newPos : newPosArray) { + if (newPos.x() >= 0 && newPos.x() < iceFillBoard.length && newPos.y() >= 0 && newPos.y() < iceFillBoard[0].length && !iceFillBoard[newPos.x()][newPos.y()] && !visited.contains(newPos)) { + path.add(newPos); + visited.add(newPos); + List<Vector2ic> newPath = solveDfs(iceFillBoard, count - 1, path, visited); + if (newPath != null) { + return newPath; + } + path.remove(path.size() - 1); + visited.remove(newPos); + } + } + + return null; + } + + @Override + public void render(WorldRenderContext context) { + if (!SkyblockerConfigManager.get().locations.dungeons.solveIceFill || !DungeonManager.isCurrentRoomMatched()) { + return; + } + Room room = DungeonManager.getCurrentRoom(); + for (int i = 0; i < 3; i++) { + renderPath(context, room, iceFillPaths.get(i), BOARD_ORIGINS[i]); + } + } + + private void renderPath(WorldRenderContext context, Room room, List<Vector2ic> iceFillPath, BlockPos originPos) { + BlockPos.Mutable pos = new BlockPos.Mutable(); + for (int i = 0; i < iceFillPath.size() - 1; i++) { + Vec3d start = Vec3d.ofCenter(room.relativeToActual(pos.set(originPos).move(-iceFillPath.get(i).y(), 0, -iceFillPath.get(i).x()))); + Vec3d end = Vec3d.ofCenter(room.relativeToActual(pos.set(originPos).move(-iceFillPath.get(i + 1).y(), 0, -iceFillPath.get(i + 1).x()))); + RenderHelper.renderLinesFromPoints(context, new Vec3d[]{start, end}, RED_COLOR_COMPONENTS, 1f, 5f, true); + } + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/Silverfish.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/Silverfish.java new file mode 100644 index 00000000..b5cbc8ee --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/puzzle/Silverfish.java @@ -0,0 +1,181 @@ +package de.hysky.skyblocker.skyblock.dungeon.puzzle; + +import com.mojang.brigadier.Command; +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.debug.Debug; +import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager; +import de.hysky.skyblocker.skyblock.dungeon.secrets.Room; +impor |
