Skip to content

Conversation

akarahdev
Copy link
Contributor

This PR adds 2 Enderman Slayer utilities - Beacon Highlighting & Nukekubi Head highlighting.

Beacon Highlighting

This is the one I'm the least confident in. It checks in a 15x7x15 area around the player every 5 ticks for a beacon, and if there is one, highlight it. It works as needed, the only issue is that the algorithm checks ~1,575 blocks which isn't that expensive, but could be on low-end computers. This can be found in the new BeaconHighlighter class.

Nukekubi Head Highlighting

This one is very simple - it just applies a glowing effect to armorstand entities with the Nukekubi Head item on their armor slots. This can be found in the MobGlow class.

This is my first time actually trying to do something useful in Fabric, so I apologize if this isn't as good code as other parts of the mod.

@kevinthegreat1 kevinthegreat1 added new feature This issue or PR is a new feature reviews needed This PR needs reviews labels Jan 18, 2024
@akarahdev
Copy link
Contributor Author

akarahdev commented Jan 18, 2024

Here is the testing footage: https://youtu.be/CkGuSyab5yw
The video's still uploading so it may need some time to be visible

Copy link
Collaborator

@kevinthegreat1 kevinthegreat1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small things :)

@kevinthegreat1 kevinthegreat1 added changes requested This PR need changes tester needed This is used for a Discord webhook to create a thread and notify the tester. and removed reviews needed This PR needs reviews tester needed This is used for a Discord webhook to create a thread and notify the tester. labels Jan 19, 2024
@kevinthegreat1 kevinthegreat1 added this to the 1.17 milestone Jan 19, 2024
@kevinthegreat1
Copy link
Collaborator

Made some changes, can you make sure this still works?

@kevinthegreat1 kevinthegreat1 added reviews needed This PR needs reviews and removed changes requested This PR need changes labels Jan 21, 2024
@kevinthegreat1
Copy link
Collaborator

There's a merge conflict, so before this can be merged, I need you to do git fetch origin and git rebase origin/master. Then resolve the conflicts and git push -f. (This will force push and override any uncomitted changes!)

Can you also do a quick test to make sure it still works?

@akarahdev
Copy link
Contributor Author

I can't test it tonight, but I can tomorrow. I hope my merge fixes worked.

kevinthegreat1
kevinthegreat1 previously approved these changes Jan 23, 2024
kevinthegreat1
kevinthegreat1 previously approved these changes Jan 23, 2024
@KhafraDev
Copy link
Contributor

Here's an alternative version of the beacon highlighting. It detects when the voidgloom throws the "beacon" and tracks that entity until it despawns, and once it does, it checks a 2x2 radius around where it despawned for the beacon block. Not sure if it's a better approach, but from my testing it is reliable.

Code definitely isn't the greatest but it should be very easy to adapt to Skyblocker's style if needed.

Code
package com.khafra.hypixel.features.slayers.voidgloom;

import com.khafra.hypixel.features.hypixel.Locraw;
import java.awt.*;
import java.util.ArrayList;
import me.x150.renderer.render.Renderer3d;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.Items;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

public class HighlightBeacon {
  private final ArrayList<Beacon> beacons = new ArrayList<>();

  public HighlightBeacon() {
    ClientEntityEvents.ENTITY_UNLOAD.register(this::onEntityDespawn);
    WorldRenderEvents.END.register(this::onWorldRender);
  }

  private void onWorldRender(WorldRenderContext context) {
    if (!this.isEnd() && this.beacons.isEmpty()) return;

    var world = MinecraftClient.getInstance().world;

    this.beacons.removeIf(beacon -> System.currentTimeMillis() - beacon.age > 2000);
    this.beacons.removeIf(
        beacon ->
            beacon.getBeaconPos() == null
                ? false
                : !world.getBlockState(beacon.getBeaconPos()).isOf(Blocks.BEACON));

    for (var entry : this.beacons) {
      if (entry.getBeaconPos() == null) continue;

      Renderer3d.renderThroughWalls();
      Renderer3d.renderEdged(
          context.matrixStack(),
          Color.MAGENTA,
          Color.MAGENTA,
          Vec3d.of(entry.getBeaconPos()),
          new Vec3d(1, 1, 1));
      Renderer3d.stopRenderThroughWalls();
    }
  }

  private void onEntityDespawn(Entity entity, ClientWorld clientWorld) {
    if (!this.isEnd()) return;
    if (entity.getType() != EntityType.ARMOR_STAND
        || !((ArmorStandEntity) entity).getEquippedStack(EquipmentSlot.HEAD).isOf(Items.BEACON))
      return;

    this.beacons.add(new Beacon((ArmorStandEntity) entity));
  }

  private boolean isEnd() {
    return Locraw.hasLocraw() && Locraw.getMode().equals("combat_3");
  }

  public static class Beacon {
    private final ArmorStandEntity entity;
    private final long age;
    private BlockPos blockPos = null;

    public Beacon(ArmorStandEntity entity) {
      this.entity = entity;
      this.age = System.currentTimeMillis();
    }

    public BlockPos getBeaconPos() {
      if (this.blockPos != null || System.currentTimeMillis() - this.age > 500) {
        return this.blockPos;
      }

      var offset = 2;
      var entityPos = this.entity.getPos();

      for (int xOffset = -offset; xOffset <= offset; xOffset++) {
        for (int yOffset = -offset; yOffset <= offset; yOffset++) {
          for (int zOffset = -offset; zOffset <= offset; zOffset++) {
            var pos = entityPos.add(xOffset, yOffset, zOffset);
            var blockPos = BlockPos.ofFloored(pos.getX(), pos.getY(), pos.getZ());

            if (MinecraftClient.getInstance().world.getBlockState(blockPos).isOf(Blocks.BEACON)) {
              return this.blockPos = blockPos;
            }
          }
        }
      }

      return null;
    }
  }
}

@akarahdev
Copy link
Contributor Author

IMO your code looks great, though I'd like to ask what others here think of it just to be safe.

@LifeIsAParadox LifeIsAParadox added merge me please Pull requests that are ready to merge and removed reviews needed This PR needs reviews labels Jan 25, 2024
@LifeIsAParadox LifeIsAParadox merged commit 9e1a614 into SkyblockerMod:master Jan 25, 2024
@AzureAaron AzureAaron removed the merge me please Pull requests that are ready to merge label Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature This issue or PR is a new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants