- 35
- 0
Вот код, может проблема даже не в коде, кто знает
ZoneDefenderClient:
package net.catg.zonedefender;
import com.mojang.blaze3d.systems.RenderSystem;
import net.catg.zonedefender.Objects.CloseChunk;
import net.catg.zonedefender.Objects.CloseChunkManager;
import net.catg.zonedefender.Objects.MobsWaveManager;
import net.catg.zonedefender.Objects.OpenChunkManager;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import java.util.*;
public class ZoneDefenderClient implements ClientModInitializer {
public Map<ChunkPos, List<CloseChunk>> closeChunks = new HashMap<>();
@Override
public void onInitializeClient() {
WorldRenderEvents.LAST.register(this::renderChunkRequestText);
}
private void renderChunkRequestText(WorldRenderContext context) {
MinecraftClient client = MinecraftClient.getInstance();
World world = client.world;
ServerWorld world1 = ZoneDefender.world;
assert world != null;
if (world.getRegistryKey() == World.NETHER) {
world1 = ZoneDefender.nether;
} else if (world.getRegistryKey() == World.END) {
world1 = ZoneDefender.end;
}
if (!(world1 instanceof PersistentStateGetter persistentStateGetter)) return;
if (ZoneDefender.world != null) {
MobsWaveManager mobsWaveManager = persistentStateGetter.getMobWaveData(ZoneDefender.world);
if (mobsWaveManager.defeatAnimation > 90) {
return;
}
}
CloseChunkManager chunkManager = persistentStateGetter.getCloseChunkData(world1);
OpenChunkManager openChunkManager = persistentStateGetter.getOpenChunkData(world1);
if (!chunkManager.savingCloseChunks.isEmpty()) {
closeChunks = chunkManager.savingCloseChunks;
}
TextRenderer textRenderer = client.textRenderer;
Vec3d cameraPos = context.camera().getPos();
MatrixStack matrices = context.matrixStack();
try {
for (List<CloseChunk> list : new ArrayList<>(closeChunks.values())) {
for (CloseChunk closeChunk : list) {
if (!closeChunk.isActive()) continue;
assert client.player != null;
if (closeChunk.dimension != client.player.getWorld().getRegistryKey()) continue;
ChunkPos chunkPos = closeChunk.getChunkPos();
double playerY = client.player.getY() + 2;
// Координаты стен чанка
// Проверка соседних чанков
boolean hasOpenNorth = openChunkManager.containsChunk(new ChunkPos(chunkPos.x, chunkPos.z - 1), world1.getRegistryKey());
boolean hasOpenSouth = openChunkManager.containsChunk(new ChunkPos(chunkPos.x, chunkPos.z + 1), world1.getRegistryKey());
boolean hasOpenWest = openChunkManager.containsChunk(new ChunkPos(chunkPos.x - 1, chunkPos.z), world1.getRegistryKey());
boolean hasOpenEast = openChunkManager.containsChunk(new ChunkPos(chunkPos.x + 1, chunkPos.z), world1.getRegistryKey());
// Рисование текста на стенах, соседствующих с открытыми чанками
if (hasOpenNorth) drawTextOnWall(context, matrices, textRenderer, cameraPos, chunkPos, playerY, "north", closeChunk);
if (hasOpenSouth) drawTextOnWall(context, matrices, textRenderer, cameraPos, chunkPos, playerY, "south", closeChunk);
if (hasOpenWest) drawTextOnWall(context, matrices, textRenderer, cameraPos, chunkPos, playerY, "west", closeChunk);
if (hasOpenEast) drawTextOnWall(context, matrices, textRenderer, cameraPos, chunkPos, playerY, "east", closeChunk);
}
}
} catch (Exception e) {
ZoneDefender.LOGGER.warn("oshibochka");
}
}
private void drawTextOnWall(WorldRenderContext context, MatrixStack matrices, TextRenderer textRenderer,
Vec3d cameraPos, ChunkPos chunkPos, double centerY, String wall, CloseChunk closeChunk) {
double centerX = chunkPos.getStartX() + 8.0; // Центр чанка по X
double centerZ = chunkPos.getStartZ() + 8.0; // Центр чанка по Z
double posX = centerX;
double posZ = centerZ;
// Определяем позицию текста в зависимости от стены
switch (wall) {
case "north" -> posZ = chunkPos.getStartZ(); // Северная стена
case "south" -> posZ = chunkPos.getStartZ() + 15; // Южная стена
case "west" -> posX = chunkPos.getStartX(); // Западная стена
case "east" -> posX = chunkPos.getStartX() + 15; // Восточная стена
}
// Вычисляем расстояние до игрока
double distance = Math.sqrt(Math.pow(posX - cameraPos.x, 2) + Math.pow(centerY - cameraPos.y, 2) + Math.pow(posZ - cameraPos.z, 2));
if (distance > 40) return; // Ограничение по дистанции
double offsetX = posX - cameraPos.x;
double baseY = centerY - cameraPos.y; // Базовое положение
String text = generateTextForChunk(closeChunk);
double textHeight = calculateTextHeight(textRenderer, text, 0.05F); // Масштаб текста
double offsetY = baseY + textHeight - 1; // Смещаем весь текст вверх так, чтобы нижняя часть была фиксирована
double offsetZ = posZ - cameraPos.z;
matrices.push();
matrices.translate(offsetX, offsetY, offsetZ);
// Устанавливаем фиксированный угол поворота текста в зависимости от стены
switch (wall) {
case "north" -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(0)); // Поворот на 0° для северной стены
case "south" -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); // Поворот на 180° для южной стены
case "west" -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(90)); // Поворот на 90° для западной стены
case "east" -> matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-90)); // Поворот на -90° для восточной стены
}
matrices.scale(-0.05F, -0.05F, 0.05F); // Размер текста
RenderSystem.enableBlend();
// Генерация текста и отрисовка
String[] lines = text.split("\n");
for (int i = 0; i < lines.length; i++) {
textRenderer.draw(
lines[i],
-textRenderer.getWidth(lines[i]) / 2.0F,
i * 10,
0xFFFFFF,
false,
matrices.peek().getPositionMatrix(),
context.consumers(),
TextRenderer.TextLayerType.NORMAL,
0,
15728880
);
}
RenderSystem.disableBlend();
matrices.pop();
}
private double calculateTextHeight(TextRenderer textRenderer, String text, float scale) {
String[] lines = text.split("\n");
int lineHeight = 9; // Высота одной строки
double totalHeight = lines.length * lineHeight * scale; // Суммарная высота всех строк
return totalHeight;
}
private String generateTextForChunk(CloseChunk closeChunk) {
StringBuilder builder = new StringBuilder(Text.translatable("chunk.requests").getString());
for (Map.Entry<Item, Integer> entry : closeChunk.chunkRequest.entrySet()) {
Item item = entry.getKey();
int required = entry.getValue();
int collected = closeChunk.itemIn.getOrDefault(item, 0);
builder.append("\n")
.append(item.getName().getString()) // Название предмета
.append(": ")
.append(Text.translatable("chunk.progress", collected, required).getString());
}
return builder.toString();
}
}