Skip to content

Commit

Permalink
Merge pull request #714 from viciscat/diana
Browse files Browse the repository at this point in the history
Estimated diana burrow pos thing
  • Loading branch information
kevinthegreat1 authored Sep 6, 2024
2 parents 18be2e1 + cef0d46 commit f7c414a
Showing 1 changed file with 132 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.particle.ParticleType;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
Expand All @@ -37,6 +38,8 @@
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.apache.commons.math3.geometry.euclidean.twod.Line;
import org.apache.commons.math3.geometry.euclidean.twod.Vector2D;
import org.apache.commons.math3.stat.regression.SimpleRegression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -51,6 +54,7 @@
public class MythologicalRitual {
private static final Pattern GRIFFIN_BURROW_DUG = Pattern.compile("(?<message>You dug out a Griffin Burrow!|You finished the Griffin burrow chain!) \\((?<index>\\d)/4\\)");
private static final float[] ORANGE_COLOR_COMPONENTS = ColorUtils.getFloatComponents(DyeColor.ORANGE);
private static final float[] RED_COLOR_COMPONENTS = ColorUtils.getFloatComponents(DyeColor.RED);
private static long lastEchoTime;
private static final Map<BlockPos, GriffinBurrow> griffinBurrows = new HashMap<>();
@Nullable
Expand Down Expand Up @@ -85,54 +89,110 @@ public static void init() {

public static void onParticle(ParticleS2CPacket packet) {
if (isActive()) {
if (ParticleTypes.CRIT.equals(packet.getParameters().getType()) || ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) {
BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down();
if (MinecraftClient.getInstance().world == null || !MinecraftClient.getInstance().world.getBlockState(pos).isOf(Blocks.GRASS_BLOCK)) {
return;
}
GriffinBurrow burrow = griffinBurrows.computeIfAbsent(pos, GriffinBurrow::new);
if (ParticleTypes.CRIT.equals(packet.getParameters().getType())) burrow.critParticle++;
if (ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) burrow.enchantParticle++;
if (burrow.critParticle >= 5 && burrow.enchantParticle >= 5 && burrow.confirmed == TriState.FALSE) {
griffinBurrows.get(pos).init();
}
} else if (ParticleTypes.DUST.equals(packet.getParameters().getType())) {
BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ());
GriffinBurrow burrow = griffinBurrows.get(pos.down(2));
if (burrow == null) {
return;
}
burrow.regression.addData(packet.getX(), packet.getZ());
double slope = burrow.regression.getSlope();
if (Double.isNaN(slope)) {
return;
}
Vec3d nextBurrowDirection = new Vec3d(100, 0, slope * 100).normalize();
if (burrow.nextBurrowLine == null) {
burrow.nextBurrowLine = new Vec3d[1001];
}
fillLine(burrow.nextBurrowLine, Vec3d.ofCenter(pos.up()), nextBurrowDirection);
} else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType()) && packet.getCount() == 2) {
if (System.currentTimeMillis() > lastEchoTime + 10_000) {
return;
}
if (previousBurrow.echoBurrowDirection == null) {
previousBurrow.echoBurrowDirection = new Vec3d[2];
}
previousBurrow.echoBurrowDirection[0] = previousBurrow.echoBurrowDirection[1];
previousBurrow.echoBurrowDirection[1] = new Vec3d(packet.getX(), packet.getY(), packet.getZ());
if (previousBurrow.echoBurrowDirection[0] == null || previousBurrow.echoBurrowDirection[1] == null) {
return;
}
Vec3d echoBurrowDirection = previousBurrow.echoBurrowDirection[1].subtract(previousBurrow.echoBurrowDirection[0]).normalize();
if (previousBurrow.echoBurrowLine == null) {
previousBurrow.echoBurrowLine = new Vec3d[1001];
}
fillLine(previousBurrow.echoBurrowLine, previousBurrow.echoBurrowDirection[0], echoBurrowDirection);
switch (packet.getParameters().getType()) {
case ParticleType<?> type when ParticleTypes.CRIT.equals(type) || ParticleTypes.ENCHANT.equals(type) -> handleBurrowParticle(packet);
case ParticleType<?> type when ParticleTypes.DUST.equals(type) -> handleNextBurrowParticle(packet);
case ParticleType<?> type when ParticleTypes.DRIPPING_LAVA.equals(type) && packet.getCount() == 2 -> handleEchoBurrowParticle(packet);
case null, default -> {}
}
}
}

/**
* Updates the crit and enchant particle counts and initializes the burrow if both counts are greater or equal to 5.
*/
private static void handleBurrowParticle(ParticleS2CPacket packet) {
BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ()).down();
if (MinecraftClient.getInstance().world == null || !MinecraftClient.getInstance().world.getBlockState(pos).isOf(Blocks.GRASS_BLOCK)) {
return;
}
GriffinBurrow burrow = griffinBurrows.computeIfAbsent(pos, GriffinBurrow::new);
if (ParticleTypes.CRIT.equals(packet.getParameters().getType())) burrow.critParticle++;
if (ParticleTypes.ENCHANT.equals(packet.getParameters().getType())) burrow.enchantParticle++;
if (burrow.critParticle >= 5 && burrow.enchantParticle >= 5 && burrow.confirmed == TriState.FALSE) {
griffinBurrows.get(pos).init();
}
}

/**
* Updates the regression of the burrow (if a burrow exists), tries to {@link #estimateNextBurrow(GriffinBurrow) estimate the next burrow}, and updates the line in the direction of the next burrow.
*/
private static void handleNextBurrowParticle(ParticleS2CPacket packet) {
BlockPos pos = BlockPos.ofFloored(packet.getX(), packet.getY(), packet.getZ());
GriffinBurrow burrow = griffinBurrows.get(pos.down(2));
if (burrow == null) {
return;
}
burrow.regression.addData(packet.getX(), packet.getZ());
double slope = burrow.regression.getSlope();
if (Double.isNaN(slope)) {
return;
}
Vec3d nextBurrowDirection = new Vec3d(100, 0, slope * 100).normalize();

// Save the line of the next burrow and try to estimate the next burrow
Vector2D pos2D = new Vector2D(pos.getX() + 0.5, pos.getZ() + 0.5);
burrow.nextBurrowLineEstimation = new Line(pos2D, pos2D.add(new Vector2D(nextBurrowDirection.x, nextBurrowDirection.z)), 0.0001);
estimateNextBurrow(burrow);

// Fill line in the direction of the next burrow
if (burrow.nextBurrowLine == null) {
burrow.nextBurrowLine = new Vec3d[1001];
}
fillLine(burrow.nextBurrowLine, Vec3d.ofCenter(pos.up()), nextBurrowDirection);
}

/**
* Saves the echo particle in {@link GriffinBurrow#echoBurrowDirection}, if the player used echo within 10 seconds.
* Tries to {@link #estimateNextBurrow(GriffinBurrow) estimate the next burrow} and updates the line through the two echo burrow particles if there is already a particle saved in {@link GriffinBurrow#echoBurrowDirection}.
*/
private static void handleEchoBurrowParticle(ParticleS2CPacket packet) {
if (System.currentTimeMillis() > lastEchoTime + 10_000) {
return;
}
if (previousBurrow.echoBurrowDirection == null) {
previousBurrow.echoBurrowDirection = new Vec3d[2];
}
previousBurrow.echoBurrowDirection[0] = previousBurrow.echoBurrowDirection[1];
previousBurrow.echoBurrowDirection[1] = new Vec3d(packet.getX(), packet.getY(), packet.getZ());
if (previousBurrow.echoBurrowDirection[0] == null || previousBurrow.echoBurrowDirection[1] == null) {
return;
}

// Save the line of the echo burrow and try to estimate the next burrow
Vector2D pos1 = new Vector2D(previousBurrow.echoBurrowDirection[0].x, previousBurrow.echoBurrowDirection[0].z);
Vector2D pos2 = new Vector2D(previousBurrow.echoBurrowDirection[1].x, previousBurrow.echoBurrowDirection[1].z);
previousBurrow.echoBurrowLineEstimation = new Line(pos1, pos2, 0.0001);
estimateNextBurrow(previousBurrow);

// Fill line in the direction of the echo burrow
Vec3d echoBurrowDirection = previousBurrow.echoBurrowDirection[1].subtract(previousBurrow.echoBurrowDirection[0]).normalize();
if (previousBurrow.echoBurrowLine == null) {
previousBurrow.echoBurrowLine = new Vec3d[1001];
}
fillLine(previousBurrow.echoBurrowLine, previousBurrow.echoBurrowDirection[0], echoBurrowDirection);
}

/**
* Tries to estimate the position of the next burrow
* by intersecting the line of the next burrow and
* the line of the echo burrow and saves the result in the burrow.
* @param burrow The burrow to estimate the next burrow for
*/
private static void estimateNextBurrow(GriffinBurrow burrow) {
if (burrow.nextBurrowLineEstimation == null || burrow.echoBurrowLineEstimation == null) {
return;
}
Vector2D intersection = burrow.nextBurrowLineEstimation.intersection(burrow.echoBurrowLineEstimation);
burrow.nextBurrowEstimatedPos = BlockPos.ofFloored(intersection.getX(), 5, intersection.getY());
}

/**
* Fills the {@link Vec3d} array to form a line centered on {@code start} with step sizes of {@code direction}
* @param line The line to fill
* @param start The center of the line
* @param direction The step size of the line
*/
static void fillLine(Vec3d[] line, Vec3d start, Vec3d direction) {
assert line.length % 2 == 1;
int middle = line.length / 2;
Expand All @@ -156,6 +216,9 @@ public static void render(WorldRenderContext context) {
if (burrow.echoBurrowLine != null) {
RenderHelper.renderLinesFromPoints(context, burrow.echoBurrowLine, ORANGE_COLOR_COMPONENTS, 0.5F, 5F, false);
}
if (burrow.nextBurrowEstimatedPos != null && burrow.confirmed == TriState.DEFAULT) {
RenderHelper.renderFilledWithBeaconBeam(context, burrow.nextBurrowEstimatedPos, RED_COLOR_COMPONENTS, 0.5f, true);
}
}
}
}
Expand Down Expand Up @@ -196,7 +259,7 @@ public static void onChatMessage(Text message, boolean overlay) {
private static boolean isActive() {
return SkyblockerConfigManager.get().helpers.mythologicalRitual.enableMythologicalRitualHelper && Utils.getLocation() == Location.HUB;
}

private static void reset() {
griffinBurrows.clear();
lastDugBurrowPos = null;
Expand All @@ -210,14 +273,35 @@ private static void reset() {
private static class GriffinBurrow extends Waypoint {
private int critParticle;
private int enchantParticle;
/**
* The state of the burrow where {@link TriState#FALSE} means the burrow has been dug, is not the last dug burrow, and should not be rendered,
* {@link TriState#DEFAULT} means the burrow is not confirmed by particles or
* has been dug but is the last dug burrow and has to render the line pointing to the next burrow and the line from echo burrow, and
* {@link TriState#TRUE} means the burrow is confirmed by particles and is waiting to be dug.
*/
private TriState confirmed = TriState.FALSE;
private final SimpleRegression regression = new SimpleRegression();
@Nullable
private Vec3d[] nextBurrowLine;
/**
* The positions of the last two echo burrow particles.
*/
@Nullable
private Vec3d[] echoBurrowDirection;
@Nullable
private Vec3d[] echoBurrowLine;
@Nullable
private BlockPos nextBurrowEstimatedPos;
/**
* The line in the direction of the next burrow estimated by the previous burrow particles.
*/
@Nullable
private Line nextBurrowLineEstimation;
/**
* The line in the direction of the next burrow estimated by the echo ability.
*/
@Nullable
private Line echoBurrowLineEstimation;

private GriffinBurrow(BlockPos pos) {
super(pos, Type.WAYPOINT, ORANGE_COLOR_COMPONENTS, 0.25F);
Expand All @@ -228,6 +312,9 @@ private void init() {
regression.clear();
}

/**
* @return {@code true} only if the burrow is confirmed by particles and is waiting to be dug
*/
@Override
public boolean shouldRender() {
return super.shouldRender() && confirmed == TriState.TRUE;
Expand Down

0 comments on commit f7c414a

Please sign in to comment.