feat: implemented debug renderer entities
This commit is contained in:
parent
bdc0aeb31e
commit
ac61442dda
@ -29,6 +29,7 @@ public class DebugCommands {
|
||||
registerPosCommand();
|
||||
registerTeleportCommand();
|
||||
registerGameModeCommand();
|
||||
DebugRendererCommand.register();
|
||||
|
||||
log.info("Registered debug commands");
|
||||
}
|
||||
|
||||
@ -0,0 +1,62 @@
|
||||
package ru.dragonestia.msb3.api.command;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.command.builder.Command;
|
||||
import net.minestom.server.command.builder.CommandContext;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentEnum;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentString;
|
||||
import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||
import net.minestom.server.entity.Player;
|
||||
import ru.dragonestia.msb3.api.player.MsbPlayer;
|
||||
|
||||
public class DebugRendererCommand extends Command {
|
||||
|
||||
private final ArgumentEnum<Option> argOption = ArgumentType.Enum("option", Option.class).setFormat(ArgumentEnum.Format.LOWER_CASED);
|
||||
private final ArgumentString argLayerName = ArgumentType.String("layer");
|
||||
|
||||
public DebugRendererCommand() {
|
||||
super("debug_render");
|
||||
setDefaultExecutor(this::defaultExecutor);
|
||||
|
||||
argOption.setCallback((sender, ex) -> {
|
||||
sender.sendMessage(Component.text("Invalid option", NamedTextColor.RED));
|
||||
});
|
||||
|
||||
addSyntax(this::execute, argOption, argLayerName);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
MinecraftServer.getCommandManager().register(new DebugRendererCommand());
|
||||
}
|
||||
|
||||
private void defaultExecutor(CommandSender sender, CommandContext ctx) {
|
||||
var player = (Player) sender;
|
||||
|
||||
player.sendMessage("Debug Render commands:");
|
||||
player.sendMessage("/debug_render show <layer> - Show debug layer");
|
||||
player.sendMessage("/debug_render hide <layer> - Hide debug layer");
|
||||
}
|
||||
|
||||
private void execute(CommandSender sender, CommandContext ctx) {
|
||||
var player = (MsbPlayer) sender;
|
||||
var option = ctx.get(argOption);
|
||||
var layerName = ctx.get(argLayerName);
|
||||
|
||||
if (option == Option.SHOW) {
|
||||
player.addDebugRenderLayer(layerName);
|
||||
player.sendMessage(Component.text("Debug layer '%s' was showed for you".formatted(layerName), NamedTextColor.YELLOW));
|
||||
return;
|
||||
}
|
||||
|
||||
player.removeDebugRenderLayer(layerName);
|
||||
player.sendMessage(Component.text("Debug layer '%s' was hidden for you".formatted(layerName), NamedTextColor.YELLOW));
|
||||
}
|
||||
|
||||
public enum Option {
|
||||
SHOW,
|
||||
HIDE,
|
||||
}
|
||||
}
|
||||
11
api/src/main/java/ru/dragonestia/msb3/api/debug/Debug.java
Normal file
11
api/src/main/java/ru/dragonestia/msb3/api/debug/Debug.java
Normal file
@ -0,0 +1,11 @@
|
||||
package ru.dragonestia.msb3.api.debug;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import ru.dragonestia.msb3.api.util.Env;
|
||||
|
||||
@UtilityClass
|
||||
public class Debug {
|
||||
|
||||
@Getter private final boolean enabled = Env.bool("MSB3_DEBUG").orElse(false);
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package ru.dragonestia.msb3.api.util;
|
||||
package ru.dragonestia.msb3.api.debug;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
@ -11,10 +11,8 @@ import net.minestom.server.sound.SoundEvent;
|
||||
@UtilityClass
|
||||
public class DebugMessage {
|
||||
|
||||
private final boolean disabled = !Env.bool("MSB3_DEBUG").orElse(false);
|
||||
|
||||
public void send(Player player, String message) {
|
||||
if (disabled) return;
|
||||
if (!Debug.isEnabled()) return;
|
||||
|
||||
player.sendMessage(Component.text()
|
||||
.append(Component.text("[DEBUG] ", TextColor.color(0xFFC909), TextDecoration.BOLD))
|
||||
@ -23,7 +21,7 @@ public class DebugMessage {
|
||||
}
|
||||
|
||||
public void sendError(Player player, String message) {
|
||||
if (disabled) return;
|
||||
if (!Debug.isEnabled()) return;
|
||||
|
||||
var sound = Sound.sound(SoundEvent.BLOCK_NOTE_BLOCK_BIT, Sound.Source.NEUTRAL, 1f, 0f);
|
||||
player.playSound(sound);
|
||||
@ -14,7 +14,7 @@ import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
||||
import ru.dragonestia.msb3.api.ui.TalksThemes;
|
||||
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
||||
import ru.dragonestia.msb3.api.ui.dialogue.DialogueTheme;
|
||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.debug.DebugMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -10,7 +10,7 @@ import net.minestom.server.entity.Player;
|
||||
import ru.dragonestia.msb3.api.player.PlayerContext;
|
||||
import ru.dragonestia.msb3.api.player.defaults.TalksContext;
|
||||
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.debug.DebugMessage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -7,7 +7,7 @@ import lombok.Setter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.minestom.server.entity.Player;
|
||||
import ru.dragonestia.msb3.api.ui.dialogue.DialogueRenderer;
|
||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.debug.DebugMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import lombok.extern.log4j.Log4j2;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import ru.dragonestia.msb3.api.dialog.DialogButtonClick;
|
||||
import ru.dragonestia.msb3.api.dialog.DialogRegistry;
|
||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.debug.DebugMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
package ru.dragonestia.msb3.api.entity;
|
||||
|
||||
import net.minestom.server.coordinate.Point;
|
||||
|
||||
public interface OffsetPosition {
|
||||
|
||||
void setOffsetPosition(Point offset);
|
||||
|
||||
Point getOffsetPosition();
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package ru.dragonestia.msb3.api.entity.debug;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.metadata.display.BlockDisplayMeta;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
public class DebugCollider extends DebugRendererEntity {
|
||||
|
||||
private DebugHologram hologram;
|
||||
|
||||
public DebugCollider(String layerName, Block block, Point size) {
|
||||
super(EntityType.BLOCK_DISPLAY, layerName);
|
||||
|
||||
var meta = (BlockDisplayMeta) getEntityMeta();
|
||||
meta.setScale(Vec.fromPoint(size));
|
||||
meta.setBlockState(block);
|
||||
meta.setScale(Vec.fromPoint(size));
|
||||
}
|
||||
|
||||
public DebugCollider(String layerName, Block block, Point size, Component text) {
|
||||
this(layerName, block, size);
|
||||
|
||||
var meta = (BlockDisplayMeta) getEntityMeta();
|
||||
addNestedEntity(hologram = new DebugHologram(layerName, text), meta.getScale().div(2));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package ru.dragonestia.msb3.api.entity.debug;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.metadata.display.AbstractDisplayMeta;
|
||||
import net.minestom.server.entity.metadata.display.TextDisplayMeta;
|
||||
|
||||
public class DebugHologram extends DebugRendererEntity {
|
||||
|
||||
public DebugHologram(String layerName, Component text) {
|
||||
super(EntityType.TEXT_DISPLAY, layerName);
|
||||
|
||||
var meta = (TextDisplayMeta) getEntityMeta();
|
||||
meta.setText(text);
|
||||
meta.setBillboardRenderConstraints(AbstractDisplayMeta.BillboardConstraints.CENTER);
|
||||
meta.setSeeThrough(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
package ru.dragonestia.msb3.api.entity.debug;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.network.packet.server.play.ParticlePacket;
|
||||
import net.minestom.server.particle.Particle;
|
||||
|
||||
@Log4j2
|
||||
public class DebugLine extends DebugRendererEntity {
|
||||
|
||||
@Getter private Point startPos;
|
||||
@Getter private Point endPos;
|
||||
private double dist;
|
||||
private long lastTick = 0;
|
||||
private final Particle particle;
|
||||
|
||||
public DebugLine(String layerName, Point start, Point end, TextColor color) {
|
||||
super(EntityType.TEXT_DISPLAY, layerName);
|
||||
this.startPos = start;
|
||||
this.endPos = end;
|
||||
updateDist();
|
||||
|
||||
particle = Particle.DUST.withColor(color).withScale(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(long time) {
|
||||
super.tick(time);
|
||||
|
||||
if (time - lastTick < 500) return;
|
||||
lastTick = time;
|
||||
|
||||
if (getViewers().isEmpty()) return;
|
||||
|
||||
double currentDist = 0;
|
||||
while ((currentDist += 0.7) < dist) {
|
||||
var pos = Vec.fromPoint(endPos.sub(startPos))
|
||||
.normalize()
|
||||
.mul(currentDist)
|
||||
.add(startPos);
|
||||
|
||||
var pk = new ParticlePacket(particle, pos.x(), pos.y(), pos.z(), 0, 0, 0, 0, 1);
|
||||
getViewers().forEach(player -> player.sendPacket(pk));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDist() {
|
||||
dist = endPos.distance(startPos);
|
||||
}
|
||||
|
||||
public void setStartPos(Point startPos) {
|
||||
this.startPos = startPos;
|
||||
updateDist();
|
||||
}
|
||||
|
||||
public void setEndPos(Point endPos) {
|
||||
this.endPos = endPos;
|
||||
updateDist();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package ru.dragonestia.msb3.api.entity.debug;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.metadata.display.AbstractDisplayMeta;
|
||||
import net.minestom.server.entity.metadata.display.BlockDisplayMeta;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
|
||||
public class DebugMarker extends DebugRendererEntity {
|
||||
|
||||
public DebugMarker(String layerName, Block block) {
|
||||
super(EntityType.BLOCK_DISPLAY, layerName);
|
||||
|
||||
var meta = (BlockDisplayMeta) getEntityMeta();
|
||||
meta.setBlockState(block);
|
||||
meta.setBillboardRenderConstraints(AbstractDisplayMeta.BillboardConstraints.CENTER);
|
||||
meta.setTranslation(new Pos(-0.5, -0.5, -0.5));
|
||||
meta.setLeftRotation(new float[] { 0.33333f, 0.33333f, 0.33333f, 0.8f });
|
||||
}
|
||||
|
||||
public DebugMarker(String layerName, Block block, Component text) {
|
||||
this(layerName, block);
|
||||
|
||||
addNestedEntity(new DebugHologram(layerName, text));
|
||||
}
|
||||
|
||||
public void setScale(double x, double y, double z) {
|
||||
var meta = (BlockDisplayMeta) getEntityMeta();
|
||||
meta.setScale(new Vec(x, y, z));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package ru.dragonestia.msb3.api.entity.debug;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.metadata.display.AbstractDisplayMeta;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.dragonestia.msb3.api.debug.Debug;
|
||||
import ru.dragonestia.msb3.api.entity.OffsetPosition;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
@Getter
|
||||
public class DebugRendererEntity extends Entity implements OffsetPosition {
|
||||
|
||||
private final String layerName;
|
||||
private final List<Entity> nestedEntities = new ArrayList<>();
|
||||
private Point offsetPosition = Pos.ZERO;
|
||||
|
||||
public DebugRendererEntity(@NotNull EntityType entityType, String layerName) {
|
||||
super(entityType);
|
||||
this.layerName = layerName;
|
||||
|
||||
setNoGravity(true);
|
||||
if (getEntityMeta() instanceof AbstractDisplayMeta meta) {
|
||||
meta.setBrightnessOverride(1);
|
||||
meta.setBrightness(15, 15);
|
||||
}
|
||||
}
|
||||
|
||||
public void addNestedEntity(Entity entity) {
|
||||
nestedEntities.add(entity);
|
||||
}
|
||||
|
||||
public void addNestedEntity(Entity entity, Point offset) {
|
||||
if (entity instanceof OffsetPosition target) target.setOffsetPosition(offset);
|
||||
nestedEntities.add(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) {
|
||||
return super.setInstance(instance, spawnPosition)
|
||||
.thenRun(() -> {
|
||||
if (!Debug.isEnabled()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
for (var entity: nestedEntities) {
|
||||
if (entity instanceof OffsetPosition offsetPosition) {
|
||||
entity.setInstance(instance, spawnPosition.add(offsetPosition.getOffsetPosition()));
|
||||
} else {
|
||||
entity.setInstance(instance, spawnPosition);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull CompletableFuture<Void> teleport(@NotNull Pos position, long @Nullable [] chunks, int flags, boolean shouldConfirm) {
|
||||
return super.teleport(position, chunks, flags, shouldConfirm)
|
||||
.thenRun(() -> {
|
||||
for (var entity: nestedEntities) {
|
||||
if (entity instanceof OffsetPosition offsetPosition) {
|
||||
entity.teleport(position.add(offsetPosition.getOffsetPosition()), chunks, flags, shouldConfirm);
|
||||
} else {
|
||||
entity.teleport(position, chunks, flags, shouldConfirm);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
for (var entity: nestedEntities) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOffsetPosition(Point offset) {
|
||||
offsetPosition = offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Point getOffsetPosition() {
|
||||
return offsetPosition;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package ru.dragonestia.msb3.api.entity.rule;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class PlayerViewerRule {
|
||||
|
||||
private final UUID id = UUID.randomUUID();
|
||||
|
||||
public final UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public abstract boolean canView(Entity entity);
|
||||
|
||||
@Override
|
||||
public final int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(Object obj) {
|
||||
if (obj == this) return true;
|
||||
if (obj == null) return false;
|
||||
if (obj instanceof PlayerViewerRule other) {
|
||||
return this.id.equals(other.id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package ru.dragonestia.msb3.api.math;
|
||||
|
||||
import net.minestom.server.coordinate.Vec;
|
||||
|
||||
public record Quaternion(float w, float x, float y, float z) {
|
||||
|
||||
public static Quaternion fromVec(Vec vec, double angle) {
|
||||
double halfAngle = angle / 2.0;
|
||||
double sinHalfAngle = Math.sin(halfAngle);
|
||||
|
||||
double qX = vec.x() * sinHalfAngle;
|
||||
double qY = vec.y() * sinHalfAngle;
|
||||
double qZ = vec.z() * sinHalfAngle;
|
||||
double qW = Math.cos(halfAngle);
|
||||
|
||||
return new Quaternion((float) qW, (float) qX, (float) qY, (float) qZ);
|
||||
}
|
||||
}
|
||||
@ -5,19 +5,23 @@ import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.player.GameProfile;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import ru.dragonestia.msb3.api.entity.debug.DebugRendererEntity;
|
||||
import ru.dragonestia.msb3.api.entity.rule.PlayerViewerRule;
|
||||
import ru.dragonestia.msb3.api.util.UncheckedRunnable;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class MsbPlayer extends Player {
|
||||
|
||||
private final Map<String, PlayerContext> contexts = new LinkedHashMap<>();
|
||||
@Getter private final Instant startSessionTime = Instant.now();
|
||||
private final Set<PlayerViewerRule> viewerRules = Collections.synchronizedSet(new HashSet<>());
|
||||
private final Set<String> debugRenderLayers = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
public MsbPlayer(@NotNull PlayerConnection playerConnection, @NotNull GameProfile gameProfile) {
|
||||
super(playerConnection, gameProfile);
|
||||
updateViewerRules();
|
||||
}
|
||||
|
||||
void putContext(PlayerContext ctx) {
|
||||
@ -55,4 +59,38 @@ public class MsbPlayer extends Player {
|
||||
UncheckedRunnable.runIgnoreException(ctx::dispose);
|
||||
}
|
||||
}
|
||||
|
||||
public void addDebugRenderLayer(String layerName) {
|
||||
debugRenderLayers.add(layerName);
|
||||
updateViewerRules();
|
||||
}
|
||||
|
||||
public void removeDebugRenderLayer(String layerName) {
|
||||
debugRenderLayers.remove(layerName);
|
||||
updateViewerRules();
|
||||
}
|
||||
|
||||
public void appendViewRule(PlayerViewerRule rule) {
|
||||
viewerRules.add(rule);
|
||||
updateViewerRules();
|
||||
}
|
||||
|
||||
public void removeViewRule(PlayerViewerRule rule) {
|
||||
viewerRules.remove(rule);
|
||||
updateViewerRules();
|
||||
}
|
||||
|
||||
private void updateViewerRules() {
|
||||
updateViewerRule(entity -> {
|
||||
if (entity instanceof DebugRendererEntity debugRenderer) {
|
||||
return debugRenderLayers.contains(debugRenderer.getLayerName());
|
||||
}
|
||||
|
||||
for (var rule: viewerRules) {
|
||||
if (!rule.canView(entity)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ import ru.dragonestia.msb3.api.item.ItemUtil;
|
||||
import ru.dragonestia.msb3.api.resource.dialog.ButtonNumber;
|
||||
import ru.dragonestia.msb3.api.resource.dialog.GlyphPositions;
|
||||
import ru.dragonestia.msb3.api.resource.dialog.TextureProperties;
|
||||
import ru.dragonestia.msb3.api.util.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.debug.DebugMessage;
|
||||
import ru.dragonestia.msb3.api.util.StringUtil;
|
||||
import ru.dragonestia.msb3.resource.glyph.GlyphComponent;
|
||||
import ru.dragonestia.msb3.resource.glyph.GlyphComponentBuilder;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user