HTTPS
https://git.nageyqma.icu/nageyqma/blade-addons-next.git
SSH
git@git.nageyqma.icu:nageyqma/blade-addons-next.git
HTTPS 链接可直接 git clone;推送代码请使用 SSH。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
package blade.addon.features.dungeon.f7;
import blade.addon.utils.Location;
import blade.addon.utils.Misc;
import blade.addon.utils.Waypoint;
import blade.addon.utils.config.FolderUtility;
import blade.addon.utils.config.values.Floor7;
import blade.addon.utils.data.EntityUtil;
import blade.addon.utils.dungeon.Phase;
import blade.addon.utils.rendering.RenderUtils;
import blade.addon.utils.rendering.RenderingEvents;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderContext;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.minecraft.core.BlockPos;
import net.minecraft.gizmos.GizmoStyle;
import net.minecraft.gizmos.Gizmos;
import net.minecraft.network.chat.Component;
import net.minecraft.util.ARGB;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.CopyOnWriteArrayList;
public class BossWaypoints {
private static final String filePath = FolderUtility.OLD_PATH + FolderUtility.WAYPOINTS_NAME;
private static final String WAYPOINTS_NAME = "waypoints";
public static final CopyOnWriteArrayList<Waypoint> waypoints = new CopyOnWriteArrayList<>();
private static boolean ignoreBoss = false;
private static boolean place = false;
public static void init() {
load();
RenderingEvents.FILLED.register(BossWaypoints::render);
RenderingEvents.FILLED_NO_DEPTH.register(BossWaypoints::renderThroughWall);
UseBlockCallback.EVENT.register(BossWaypoints::onBlock);
}
public static boolean isInValidArea() {
if (!Floor7.enableBossWaypoints) return false;
if (ignoreBoss) return true;
return Location.inDungeon() && Phase.inBoss();
}
public static boolean getPlace() {
return place;
}
public static boolean getIgnoreBoss() {
return ignoreBoss;
}
public static void setPlace(boolean shouldPlace) {
place = shouldPlace;
Misc.addChatMessage(Component.literal("Edit mode: ").append(Misc.getStatusText(place)));
}
public static void setIgnoreBoss(boolean shouldIgnoreBoss) {
ignoreBoss = shouldIgnoreBoss;
Misc.addChatMessage(Component.literal("Ignore boss: ").append(Misc.getStatusText(ignoreBoss)));
}
public static void togglePlace() {
setPlace(!place);
}
public static void toggleIgnoreBoss() {
setIgnoreBoss(!ignoreBoss);
}
public static void attemptAddWaypoint(double x, double y, double z, double dx, double dy, double dz) {
if (waypointExists(x, y, z)) return;
addWaypoint(x, y, z, dx, dy, dz);
}
private static void addWaypoint(double x, double y, double z, double dx, double dy, double dz) {
float[] colorAsFloat = RenderUtils.toFloats(Floor7.nextWaypointColor);
waypoints.add(new Waypoint(x, y, z, dx, dy, dz, colorAsFloat[0], colorAsFloat[1], colorAsFloat[2], colorAsFloat[3], Floor7.nextWaypointThroughWall));
save();
}
public static Waypoint getWaypoint(double x, double y, double z) {
for (Waypoint waypoint : waypoints) {
if (waypoint.samePosition(x, y, z)) return waypoint;
}
return null;
}
public static void removeWaypoints(double x, double y, double z, double range) {
for (int i = waypoints.size() - 1; i >= 0; i--) {
if (waypoints.get(i).inRange(x, y, z, range)) {
waypoints.remove(i);
}
}
save();
}
public static void removeWaypoint(double x, double y, double z) {
Waypoint waypoint = getWaypoint(x, y, z);
if (waypoint == null) return;
waypoints.remove(waypoint);
save();
}
private static InteractionResult onBlock(Player playerEntity, Level world, InteractionHand hand, BlockHitResult blockHitResult) {
if (!isInValidArea() || !EntityUtil.isClientPlayer(playerEntity)) return InteractionResult.PASS;
if (hand == InteractionHand.OFF_HAND) return InteractionResult.PASS;
BlockPos pos = blockHitResult.getBlockPos();
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
if (!place) return InteractionResult.PASS;
Waypoint waypoint = getWaypoint(x, y, z);
if (waypoint == null) {
addWaypoint(pos.getX(), pos.getY(), pos.getZ(), 1, 1, 1);
} else {
waypoints.remove(waypoint);
}
save();
return InteractionResult.PASS;
}
private static void renderThroughWall(LevelRenderContext context, PoseStack matrixStack, VertexConsumer consumer) {
if (!isInValidArea()) return;
waypoints.forEach(waypoint -> {
if (waypoint.isThroughWall()) {
waypoint.Render(consumer, matrixStack);
}
});
}
private static void render(LevelRenderContext context, PoseStack matrixStack, VertexConsumer consumer) {
if (!isInValidArea()) return;
waypoints.forEach(waypoint -> {
if (!waypoint.isThroughWall()) {
float[] color = waypoint.getColor();
Gizmos.cuboid(waypoint.getBox(), GizmoStyle.fill(ARGB.colorFromFloat(color[3], color[0], color[1], color[2])));
}
});
}
public static boolean waypointExists(double x, double y, double z) {
for (Waypoint waypoint : waypoints) {
if (waypoint.samePosition(x, y, z)) return true;
}
return false;
}
public static void save() {
JsonObject obj = new JsonObject();
Gson gson = new Gson();
obj.add(WAYPOINTS_NAME, gson.toJsonTree(waypoints));
JsonElement tree = gson.toJsonTree(obj);
try (FileWriter writer = new FileWriter(filePath)) {
writer.write(tree.toString());
} catch (IOException ignored) {
}
}
public static void load() {
String jsonContent;
try {
jsonContent = new String(Files.readAllBytes(Paths.get(filePath)));
} catch (IOException ignored) {
return;
}
Gson gson = new Gson();
JsonObject object = gson.fromJson(jsonContent, JsonObject.class);
JsonElement element = object.get(WAYPOINTS_NAME);
if (!element.isJsonArray()) return;
JsonArray array = element.getAsJsonArray();
for (JsonElement waypointElement : array) {
JsonObject waypoint = waypointElement.getAsJsonObject();
try {
if (!waypoint.has("x") || !waypoint.has("y") || !waypoint.has("z")
|| !waypoint.has("dx") || !waypoint.has("dy") || !waypoint.has("dz")
|| !waypoint.has("r") || !waypoint.has("g") || !waypoint.has("b") || !waypoint.has("a")
|| !waypoint.has("throughWall")) continue;
double x = waypoint.get("x").getAsDouble();
double y = waypoint.get("y").getAsDouble();
double z = waypoint.get("z").getAsDouble();
double dx = waypoint.get("dx").getAsDouble();
double dy = waypoint.get("dy").getAsDouble();
double dz = waypoint.get("dz").getAsDouble();
float r = waypoint.get("r").getAsFloat();
float g = waypoint.get("g").getAsFloat();
float b = waypoint.get("b").getAsFloat();
float a = waypoint.get("a").getAsFloat();
boolean throughWall = waypoint.get("throughWall").getAsBoolean();
waypoints.add(new Waypoint(x, y, z, dx, dy, dz, r, g, b, a, throughWall));
} catch (NumberFormatException e) {
System.out.println("msg: " + e.getMessage());
}
}
}
}