From 676857d650103ecac18ac3ff2f4c1493bab3e84e Mon Sep 17 00:00:00 2001 From: Zephrynis Date: Mon, 26 Jan 2026 23:42:41 +0000 Subject: [PATCH] Add NPC Text script and enhance ScriptApi with entity type retrieval --- scripts/npc_text.js | 61 +++++++++++++++++++ src/main/java/net/jstom/Main.java | 1 + src/main/java/net/jstom/script/ScriptApi.java | 25 +++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 scripts/npc_text.js diff --git a/scripts/npc_text.js b/scripts/npc_text.js new file mode 100644 index 0000000..beadf88 --- /dev/null +++ b/scripts/npc_text.js @@ -0,0 +1,61 @@ +var Entity = Java.type('net.minestom.server.entity.Entity'); +var Pos = Java.type('net.minestom.server.coordinate.Pos'); +var Vec = Java.type('net.minestom.server.coordinate.Vec'); +var Component = Java.type('net.kyori.adventure.text.Component'); +var NamedTextColor = Java.type('net.kyori.adventure.text.format.NamedTextColor'); +var BillboardConstraints = Java.type('net.minestom.server.entity.metadata.display.AbstractDisplayMeta.BillboardConstraints'); +var MinecraftServer = Java.type('net.minestom.server.MinecraftServer'); + +server.log("NPC Text script initializing..."); + +function spawnFixedNPC() { + var instanceManager = MinecraftServer.getInstanceManager(); + var instances = instanceManager.getInstances(); + + if (instances.isEmpty()) { + server.log("No instances found to spawn NPC!"); + return; + } + + var instance = instances.iterator().next(); + var pos = new Pos(45.5, 65.0, -80.5); + + // Retrieve EntityTypes via Java helper + var HUSK = server.getEntityType('HUSK'); + var TEXT_DISPLAY = server.getEntityType('TEXT_DISPLAY'); + + if (HUSK == null || TEXT_DISPLAY == null) { + server.log("Failed to resolve EntityTypes! HUSK=" + HUSK + ", TEXT_DISPLAY=" + TEXT_DISPLAY); + return; + } + + // 1. Create the "NPC" (Host) - Husk + var npc = new Entity(HUSK); + + // 2. Create the TextDisplay (Passenger) + var textDisplay = new Entity(TEXT_DISPLAY); + var meta = textDisplay.getEntityMeta(); + + // Configure the text display + meta.setText(Component.text("I am a fixed NPC!").color(NamedTextColor.YELLOW)); + meta.setBillboardRenderConstraints(BillboardConstraints.CENTER); + meta.setScale(new Vec(1.0, 1.0, 1.0)); + meta.setBackgroundColor(0); // Transparent + + // 3. Spawn entities + npc.setInstance(instance, pos).thenAccept(function() { + textDisplay.setInstance(instance, pos.add(0, 2.5, 0)).thenAccept(function() { + // 4. Make the TextDisplay ride the NPC + npc.addPassenger(textDisplay); + server.log("Spawned fixed NPC at " + pos); + }); + }); +} + +// Run immediately +try { + spawnFixedNPC(); +} catch (e) { + server.log("Error spawning NPC: " + e); + e.printStackTrace(); +} diff --git a/src/main/java/net/jstom/Main.java b/src/main/java/net/jstom/Main.java index 65a640b..c77df61 100644 --- a/src/main/java/net/jstom/Main.java +++ b/src/main/java/net/jstom/Main.java @@ -11,6 +11,7 @@ import net.minestom.server.event.server.ServerListPingEvent; import net.minestom.server.instance.InstanceContainer; import net.minestom.server.instance.InstanceManager; import net.minestom.server.instance.LightingChunk; +import net.minestom.server.instance.Chunk; import net.minestom.server.instance.anvil.AnvilLoader; import net.minestom.server.instance.block.Block; import net.minestom.server.ping.Status; diff --git a/src/main/java/net/jstom/script/ScriptApi.java b/src/main/java/net/jstom/script/ScriptApi.java index 73e1794..7067531 100644 --- a/src/main/java/net/jstom/script/ScriptApi.java +++ b/src/main/java/net/jstom/script/ScriptApi.java @@ -3,14 +3,32 @@ package net.jstom.script; import net.minestom.server.MinecraftServer; import net.minestom.server.event.Event; import net.minestom.server.event.EventNode; +import net.minestom.server.entity.EntityType; import org.graalvm.polyglot.Value; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; +import java.util.Map; +import java.util.HashMap; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; public class ScriptApi { private final List> registeredNodes = new ArrayList<>(); + private static final Map entityTypes = new HashMap<>(); + + static { + for (Field field : EntityType.class.getFields()) { + if (Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()) && field.getType() == EntityType.class) { + try { + field.setAccessible(true); + entityTypes.put(field.getName(), (EntityType) field.get(null)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + } /** * Registers an event listener from JavaScript. @@ -64,4 +82,9 @@ public class ScriptApi { public void log(String message) { System.out.println("[JS] " + message); } + + public EntityType getEntityType(String name) { + if (name == null) return null; + return entityTypes.get(name.toUpperCase()); + } }