diff options
Diffstat (limited to 'src/main/java/de')
5 files changed, 265 insertions, 2 deletions
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java index 49850403..e8127a0e 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/CrimsonIsleCategory.java @@ -94,6 +94,14 @@ public class CrimsonIsleCategory { .controller(ConfigUtils::createBooleanController) .build()) .option(Option.<Boolean>createBuilder() + .name(Text.translatable("skyblocker.crimson.dojo.staminaHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.staminaHelper.@Tooltip"))) + .binding(config.crimsonIsle.dojo.enableStaminaHelper, + () -> config.crimsonIsle.dojo.enableStaminaHelper, + newValue -> config.crimsonIsle.dojo.enableStaminaHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.<Boolean>createBuilder() .name(Text.translatable("skyblocker.crimson.dojo.masteryHelper")) .description(OptionDescription.of(Text.translatable("skyblocker.crimson.dojo.masteryHelper.@Tooltip"))) .binding(config.crimsonIsle.dojo.enableMasteryHelper, diff --git a/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java index 0bf334a1..451d1983 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/CrimsonIsleConfig.java @@ -42,6 +42,9 @@ public class CrimsonIsleConfig { public boolean enableForceHelper = true; @SerialEntry + public boolean enableStaminaHelper = true; + + @SerialEntry public boolean enableMasteryHelper = true; @SerialEntry diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/DojoManager.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/DojoManager.java index 22bfe8c3..bf4bbedd 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/DojoManager.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/DojoManager.java @@ -3,6 +3,7 @@ package de.hysky.skyblocker.skyblock.crimson.dojo; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.utils.Location; import de.hysky.skyblocker.utils.Utils; +import de.hysky.skyblocker.utils.scheduler.Scheduler; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; @@ -41,6 +42,7 @@ public class DojoManager { protected enum DojoChallenges { NONE("none", enabled -> false), FORCE("Force", enabled -> SkyblockerConfigManager.get().crimsonIsle.dojo.enableForceHelper), + STAMINA("Stamina", enabled -> SkyblockerConfigManager.get().crimsonIsle.dojo.enableStaminaHelper), MASTERY("Mastery", enabled -> SkyblockerConfigManager.get().crimsonIsle.dojo.enableMasteryHelper), DISCIPLINE("Discipline", enabled -> SkyblockerConfigManager.get().crimsonIsle.dojo.enableDisciplineHelper), SWIFTNESS("Swiftness", enabled -> SkyblockerConfigManager.get().crimsonIsle.dojo.enableSwiftnessHelper), @@ -70,6 +72,7 @@ public class DojoManager { ClientEntityEvents.ENTITY_LOAD.register(DojoManager::onEntitySpawn); ClientEntityEvents.ENTITY_UNLOAD.register(DojoManager::onEntityDespawn); AttackEntityCallback.EVENT.register(DojoManager::onEntityAttacked); + Scheduler.INSTANCE.scheduleCyclic(DojoManager::update, 3); } private static void reset() { @@ -80,6 +83,7 @@ public class DojoManager { TenacityTestHelper.reset(); ForceTestHelper.reset(); ControlTestHelper.reset(); + StaminaTestHelper.reset(); } /** @@ -92,7 +96,6 @@ public class DojoManager { if (Utils.getLocation() != Location.CRIMSON_ISLE || overlay) { return; } - System.out.println(Formatting.strip(text.getString())); if (Objects.equals(Formatting.strip(text.getString()), START_MESSAGE)) { inArena = true; return; @@ -118,6 +121,15 @@ public class DojoManager { } } + private static void update() { + if (Utils.getLocation() != Location.CRIMSON_ISLE || !inArena) { + return; + } + if (currentChallenge == DojoChallenges.STAMINA) { + StaminaTestHelper.update(); + } + } + /** * called from the {@link de.hysky.skyblocker.skyblock.entity.MobGlow} class and checks the current challenge to see if zombies should be glowing * @@ -217,6 +229,7 @@ public class DojoManager { } switch (currentChallenge) { case FORCE -> ForceTestHelper.render(context); + case STAMINA -> StaminaTestHelper.render(context); case SWIFTNESS -> SwiftnessTestHelper.render(context); case TENACITY -> TenacityTestHelper.render(context); case MASTERY -> MasteryTestHelper.render(context); diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/StaminaTestHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/StaminaTestHelper.java new file mode 100644 index 00000000..b1126f99 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/StaminaTestHelper.java @@ -0,0 +1,240 @@ +package de.hysky.skyblocker.skyblock.crimson.dojo; + +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class StaminaTestHelper { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + private static final int WALL_THRESHOLD_VALUE = 13; + private static final float[] INCOMING_COLOR = new float[]{0f, 1f, 0f, 0f}; + private static final float[] OUTGOING_COLOR = new float[]{1f, 0.64f, 0f, 0f}; + + private static final List<BlockPos> wallHoles = new ArrayList<>(); + private static final List<BlockPos> lastHoles = new ArrayList<>(); + private static final Map<BlockPos, wallDirections> holeDirections = new HashMap<>(); + private static BlockPos middleBase; + + private enum wallDirections { + POSITIVE_X, + POSITIVE_Z, + NEGATIVE_X, + NEGATIVE_Z, + NEW, + UNCHANGED; + } + + protected static void reset() { + wallHoles.clear(); + lastHoles.clear(); + holeDirections.clear(); + middleBase = null; + } + + protected static void update() { + if (CLIENT == null || CLIENT.player == null || CLIENT.world == null) { + return; + } + //search the world around the player for walls 30 x 10 x 30 area centered on player + BlockPos playerPos = CLIENT.player.getBlockPos(); + //find the center first before starting to look for walls + if (middleBase == null) { + for (int x = playerPos.getX() - 10; x < playerPos.getX() + 10; x++) { + for (int y = playerPos.getY() - 5; y < playerPos.getY(); y++) { + for (int z = playerPos.getZ() - 10; z < playerPos.getZ() + 10; z++) { + BlockPos pos = new BlockPos(x, y, z); + BlockState state = CLIENT.world.getBlockState(pos); + if (state.isOf(Blocks.CHISELED_STONE_BRICKS)) { + middleBase = pos; + return; + } + } + } + } + return; + } + List<BlockPos> currentBottomWallLocations = new ArrayList<>(); + for (int x = middleBase.getX() - 15; x < middleBase.getX() + 15; x++) { + for (int z = middleBase.getZ() - 15; z < middleBase.getZ() + 15; z++) { + BlockPos pos = new BlockPos(x, middleBase.getY() + 1, z); + BlockState state = CLIENT.world.getBlockState(pos); + //find the bottom of walls + if (!state.isAir()) { + currentBottomWallLocations.add(pos); + } + } + } + + //find walls + List<Box> walls = findWalls(currentBottomWallLocations); + + //find air then holes and add whole to list + lastHoles.clear(); + lastHoles.addAll(wallHoles); + wallHoles.clear(); + for (Box wall : walls) { + wallHoles.addAll(findAirInBox(wall)); + } + // get direction for the holes + Map<BlockPos, wallDirections> lastHoleDirections = new HashMap<>(holeDirections); + holeDirections.clear(); + for (BlockPos hole : wallHoles) { + wallDirections holeDirection = getWholeDirection(hole); + if (holeDirection == wallDirections.UNCHANGED) { + holeDirections.put(hole, lastHoleDirections.get(hole)); + continue; + } + holeDirections.put(hole, holeDirection); + } + } + + private static List<Box> findWalls(List<BlockPos> currentBottomWallLocations) { + Map<Integer, List<BlockPos>> possibleWallsX = new HashMap<>(); + Map<Integer, List<BlockPos>> possibleWallsZ = new HashMap<>(); + for (BlockPos andesite : currentBottomWallLocations) { + //add to the x walls + int x = andesite.getX(); + if (!possibleWallsX.containsKey(x)) { + possibleWallsX.put(x, new ArrayList<>()); + + } + possibleWallsX.get(x).add(andesite); + //add to the z walls + int z = andesite.getZ(); + if (!possibleWallsZ.containsKey(z)) { + possibleWallsZ.put(z, new ArrayList<>()); + + } + possibleWallsZ.get(z).add(andesite); + } + + //extract only the lines that are long enough to be a wall and not from walls overlapping + List<List<BlockPos>> walls = new ArrayList<>(); + for (List<BlockPos> line : possibleWallsX.values()) { + if (line.size() >= WALL_THRESHOLD_VALUE) { + walls.add(line); + } + } + for (List<BlockPos> line : possibleWallsZ.values()) { + if (line.size() >= WALL_THRESHOLD_VALUE) { + walls.add(line); + } + } + + //final find the maximum values for each wall to output a box for them + List<Box> wallBoxes = new ArrayList<>(); + for (List<BlockPos> wall : walls) { + BlockPos minPos = wall.getFirst(); + BlockPos maxPos = wall.getFirst(); + for (BlockPos pos : wall) { + if (pos.getX() < minPos.getX()) { + minPos = new BlockPos(pos.getX(), minPos.getY(), minPos.getZ()); + } + if (pos.getZ() < minPos.getZ()) { + minPos = new BlockPos(minPos.getX(), minPos.getY(), pos.getZ()); + } + + if (pos.getX() > maxPos.getX()) { + maxPos = new BlockPos(pos.getX(), maxPos.getY(), maxPos.getZ()); + } + if (pos.getZ() > maxPos.getZ()) { + maxPos = new BlockPos(maxPos.getX(), maxPos.getY(), pos.getZ()); + } + } + //expand wall to top + maxPos = new BlockPos(maxPos.getX(), maxPos.getY() + 5, maxPos.getZ()); + + wallBoxes.add(Box.enclosing(minPos, maxPos)); + } + + return wallBoxes; + } + + private static List<BlockPos> findAirInBox(Box box) { + List<BlockPos> air = new ArrayList<>(); + if (CLIENT == null || CLIENT.player == null || CLIENT.world == null) { + return air; + } + for (int x = (int) box.minX; x < box.maxX; x++) { + for (int y = (int) box.minY; y < box.maxY; y++) { + for (int z = (int) box.minZ; z < box.maxZ; z++) { + BlockPos pos = new BlockPos(x, y, z); + BlockState state = CLIENT.world.getBlockState(pos); + if (state.isAir()) { + air.add(pos); + } + } + } + } + return air; + } + + private static List<Box> combineAir(List<BlockPos> airLocations) { + //todo + List<Box> holes = new ArrayList<>(); + //check if air is conected to existing whole and if so + for (BlockPos airLocation : airLocations) { + holes.add(Box.enclosing(airLocation, airLocation)); + } + return holes; + } + + private static wallDirections getWholeDirection(BlockPos hole) { + //the value has not changed since last time + if (lastHoles.contains(hole)) { + return wallDirections.UNCHANGED; + } + //check each direction to work out which way the whole is going + BlockPos posX = hole.add(1, 0, 0); + if (lastHoles.contains(posX)) { + return wallDirections.POSITIVE_X; + } + BlockPos negX = hole.add(-1, 0, 0); + if (lastHoles.contains(negX)) { + System.out.println("positiveX"); + return wallDirections.NEGATIVE_X; + } + BlockPos posZ = hole.add(0, 0, 1); + if (lastHoles.contains(posZ)) { + return wallDirections.POSITIVE_Z; + } + BlockPos negZ = hole.add(0, 0, -1); + if (lastHoles.contains(negZ)) { + return wallDirections.NEGATIVE_Z; + } + // if pos can not be found mark as new + return wallDirections.NEW; + + } + + protected static void render(WorldRenderContext context) { + if (wallHoles.isEmpty() || CLIENT == null || CLIENT.player == null) { + return; + } + BlockPos playerPos = CLIENT.player.getBlockPos(); + for (BlockPos hole : wallHoles) { + float[] color = isHoleIncoming(hole,holeDirections.get(hole),playerPos) ? INCOMING_COLOR : OUTGOING_COLOR; + RenderHelper.renderFilled(context, hole, color, 0.3f, true); + } + } + + private static boolean isHoleIncoming(BlockPos holePos, wallDirections holeDirection, BlockPos playerPos) { + return switch (holeDirection) { + case POSITIVE_X -> playerPos.getX() < holePos.getX(); + case POSITIVE_Z -> playerPos.getZ() < holePos.getZ(); + case NEGATIVE_X -> playerPos.getX() > holePos.getX(); + case NEGATIVE_Z -> playerPos.getZ() > holePos.getZ(); + + default -> true; + }; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/SwiftnessTestHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/SwiftnessTestHelper.java index fd2364d1..8e3f2a32 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/SwiftnessTestHelper.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/SwiftnessTestHelper.java @@ -28,7 +28,6 @@ public class SwiftnessTestHelper { if (lastBlock == null) { return; } - System.out.println("render" + lastBlock); RenderHelper.renderFilled(context, lastBlock, new float[]{0f, 1f, 0f}, 0.5f, true); } } |