aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de/hysky/skyblocker/skyblock/crimson
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock/crimson')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/DojoManager.java15
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/StaminaTestHelper.java240
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/crimson/dojo/SwiftnessTestHelper.java1
3 files changed, 254 insertions, 2 deletions
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);
}
}