1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
package me.xmrvizzy.skyblocker.skyblock.dungeon;
import it.unimi.dsi.fastutil.objects.ObjectIntPair;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.utils.RenderHelper;
import me.xmrvizzy.skyblocker.utils.RenderUtils;
import me.xmrvizzy.skyblocker.utils.Utils;
import me.xmrvizzy.skyblocker.utils.color.QuadColor;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.predicate.entity.EntityPredicates;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* This class provides functionality to render outlines around Blaze entities
*/
public class DungeonBlaze {
private static final Logger LOGGER = LoggerFactory.getLogger(DungeonBlaze.class.getName());
private static final float[] WHITE_COLOR_COMPONENTS = {1.0f, 1.0f, 1.0f};
private static final QuadColor outlineColorGreen = QuadColor.single(0.0F, 1.0f, 0.0f, 1f);
private static final QuadColor outlineColorWhite = QuadColor.single(1.0f, 1.0f, 1.0f, 1.0f);
private static ArmorStandEntity highestBlaze = null;
private static ArmorStandEntity lowestBlaze = null;
private static ArmorStandEntity nextHighestBlaze = null;
private static ArmorStandEntity nextLowestBlaze = null;
private static boolean renderHooked = false;
/**
* Updates the state of Blaze entities and triggers the rendering process if necessary.
*/
public static void update() {
ClientWorld world = MinecraftClient.getInstance().world;
ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (world == null || player == null || !Utils.isInDungeons()) return;
if (!renderHooked) {
WorldRenderEvents.BEFORE_DEBUG_RENDER.register(DungeonBlaze::blazeRenderer);
renderHooked = true;
}
List<ObjectIntPair<ArmorStandEntity>> blazes = getBlazesInWorld(world, player);
sortBlazes(blazes);
updateBlazeEntities(blazes);
}
/**
* Retrieves Blaze entities in the world and parses their health information.
*
* @param world The client world to search for Blaze entities.
* @return A list of Blaze entities and their associated health.
*/
private static List<ObjectIntPair<ArmorStandEntity>> getBlazesInWorld(ClientWorld world, ClientPlayerEntity player) {
List<ObjectIntPair<ArmorStandEntity>> blazes = new ArrayList<>();
for (ArmorStandEntity blaze : world.getEntitiesByClass(ArmorStandEntity.class, player.getBoundingBox().expand(500D), EntityPredicates.NOT_MOUNTED)) {
String blazeName = blaze.getName().getString();
if (blazeName.contains("Blaze") && blazeName.contains("/")) {
try {
int health = Integer.parseInt(blazeName.substring(blazeName.indexOf("/") + 1, blazeName.length() - 1));
blazes.add(ObjectIntPair.of(blaze, health));
} catch (NumberFormatException e) {
handleException(e);
}
}
}
return blazes;
}
/**
* Sorts the Blaze entities based on their health values.
*
* @param blazes The list of Blaze entities to be sorted.
*/
private static void sortBlazes(List<ObjectIntPair<ArmorStandEntity>> blazes) {
blazes.sort(Comparator.comparingInt(ObjectIntPair::rightInt));
}
/**
* Updates information about Blaze entities based on sorted list.
*
* @param blazes The sorted list of Blaze entities with associated health values.
*/
private static void updateBlazeEntities(List<ObjectIntPair<ArmorStandEntity>> blazes) {
if (!blazes.isEmpty()) {
lowestBlaze = blazes.get(0).left();
int highestIndex = blazes.size() - 1;
highestBlaze = blazes.get(highestIndex).left();
if (blazes.size() > 1) {
nextLowestBlaze = blazes.get(1).left();
nextHighestBlaze = blazes.get(highestIndex - 1).left();
}
}
}
/**
* Renders outlines for Blaze entities based on health and position.
*
* @param wrc The WorldRenderContext used for rendering.
*/
public static void blazeRenderer(WorldRenderContext wrc) {
try {
if (highestBlaze != null && lowestBlaze != null && highestBlaze.isAlive() && lowestBlaze.isAlive() && SkyblockerConfig.get().locations.dungeons.blazesolver) {
if (highestBlaze.getY() < 69) {
renderBlazeOutline(highestBlaze, nextHighestBlaze, wrc);
}
if (lowestBlaze.getY() > 69) {
renderBlazeOutline(lowestBlaze, nextLowestBlaze, wrc);
}
}
} catch (Exception e) {
handleException(e);
}
}
/**
* Renders outlines for Blaze entities and connections between them.
*
* @param blaze The Blaze entity for which to render an outline.
* @param nextBlaze The next Blaze entity for connection rendering.
* @param wrc The WorldRenderContext used for rendering.
*/
private static void renderBlazeOutline(ArmorStandEntity blaze, ArmorStandEntity nextBlaze, WorldRenderContext wrc) {
Box blazeBox = blaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
RenderUtils.drawBoxOutline(blazeBox, DungeonBlaze.outlineColorGreen, 5f);
if (nextBlaze != null && nextBlaze.isAlive() && nextBlaze != blaze) {
Box nextBlazeBox = nextBlaze.getBoundingBox().expand(0.3, 0.9, 0.3).offset(0, -1.1, 0);
RenderUtils.drawBoxOutline(nextBlazeBox, DungeonBlaze.outlineColorWhite, 5f);
Vec3d blazeCenter = blazeBox.getCenter();
Vec3d nextBlazeCenter = nextBlazeBox.getCenter();
RenderHelper.renderLinesFromPoints(wrc, new Vec3d[]{blazeCenter, nextBlazeCenter}, WHITE_COLOR_COMPONENTS, 1f, 5f);
}
}
/**
* Handles exceptions by logging and printing stack traces.
*
* @param e The exception to handle.
*/
private static void handleException(Exception e) {
LOGGER.warn("[Skyblocker BlazeRenderer] Encountered an unknown exception", e);
}
}
|