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'); var MiniMessage = Java.type('net.kyori.adventure.text.minimessage.MiniMessage'); server.log("NPC Text script initializing..."); const pos = [ [49.5, 63, -75.5], [35.5, 63, -75.5], [48.5, 63, -70.5], [36.5, 63, -70.5], [47.5, 63, -65.5], [37.5, 63, -65.5], [42.5, 63, -64.5] ]; const text = [ "<#bb00ff>&lGHAST &r&7(1.21+)", "&7idk", "&7", "<#bb00ff>⏩ Line 1", "<#bb00ff>⏩ Line 2", "&7", "&7(Click me to join <#bb00ff>&n0&r&7 others&r&7)" ]; // Join all lines with newline for the display var fullDisplayText = text.join("\n"); // Run sequentially to prevent race conditions function spawnNext(index) { if (index >= pos.length) { server.log("All NPCs spawned."); return; } var loc = pos[index]; var x = loc[0]; var y = loc[1]; var z = loc[2]; // Use the full text for every NPC var displayString = fullDisplayText; var instanceManager = MinecraftServer.getInstanceManager(); var instances = instanceManager.getInstances(); if (instances.isEmpty()) { server.log("No instances found!"); return; } var instance = instances.iterator().next(); var position = new Pos(x, y, z); // Retrieve EntityTypes var HUSK = server.getEntityType('HUSK'); var TEXT_DISPLAY = server.getEntityType('TEXT_DISPLAY'); // 1. Create the "NPC" (Host) var npc = new Entity(HUSK); npc.setNoGravity(true); // 2. Create the TextDisplay (Passenger) var textDisplay = new Entity(TEXT_DISPLAY); textDisplay.setNoGravity(true); // Ensure text doesn't fall var meta = textDisplay.getEntityMeta(); meta.setText(MiniMessage.miniMessage().deserialize(displayString)); meta.setBillboardRenderConstraints(BillboardConstraints.CENTER); meta.setScale(new Vec(1.0, 1.0, 1.0)); meta.setBackgroundColor(0); // 3. Spawn entities server.log("Spawning NPC " + (index + 1) + "/" + pos.length + " at " + x + "," + y + "," + z + "..."); npc.setInstance(instance, position).thenAccept(function() { textDisplay.setInstance(instance, position.add(0, 2.5, 0)).thenAccept(function() { try { npc.addPassenger(textDisplay); server.log("Successfully spawned NPC + Text at " + x + "," + y + "," + z); } catch (e) { server.log("Error adding passenger: " + e); } // Spawn next spawnNext(index + 1); }).exceptionally(function(e) { server.log("TextDisplay spawn failed: " + e); spawnNext(index + 1); // Continue anyway return null; }); }).exceptionally(function(e) { server.log("NPC spawn failed: " + e); spawnNext(index + 1); // Continue anyway return null; }); } try { spawnNext(0); } catch (e) { server.log("Error starting spawn loop: " + e); }