diff --git a/build.gradle.kts b/build.gradle.kts index 55ff0dd..bca9834 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,6 +23,9 @@ dependencies { // Logging implementation("org.slf4j:slf4j-simple:2.0.9") + // Adventure MiniMessage + implementation("net.kyori:adventure-text-minimessage:4.17.0") + // Config implementation("org.yaml:snakeyaml:2.2") } diff --git a/scripts/npc_text.js b/scripts/npc_text.js index beadf88..c1758c0 100644 --- a/scripts/npc_text.js +++ b/scripts/npc_text.js @@ -5,57 +5,102 @@ 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..."); -function spawnFixedNPC() { +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 to spawn NPC!"); + server.log("No instances found!"); return; } - var instance = instances.iterator().next(); - var pos = new Pos(45.5, 65.0, -80.5); + var position = new Pos(x, y, z); - // Retrieve EntityTypes via Java helper + // Retrieve EntityTypes 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 + // 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(); - // Configure the text display - meta.setText(Component.text("I am a fixed NPC!").color(NamedTextColor.YELLOW)); + meta.setText(MiniMessage.miniMessage().deserialize(displayString)); meta.setBillboardRenderConstraints(BillboardConstraints.CENTER); meta.setScale(new Vec(1.0, 1.0, 1.0)); - meta.setBackgroundColor(0); // Transparent + meta.setBackgroundColor(0); // 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); + 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; }); } -// Run immediately try { - spawnFixedNPC(); + spawnNext(0); } catch (e) { - server.log("Error spawning NPC: " + e); - e.printStackTrace(); + server.log("Error starting spawn loop: " + e); }