From 3eab5d0be715f1637b7023555a5b306ab4236533 Mon Sep 17 00:00:00 2001 From: ZXMushroom63 Date: Thu, 5 Dec 2024 14:47:12 +0800 Subject: [PATCH] spawn xp tutorial, fix compiling client link --- docs/tutorials/spawnxp.md | 58 +++++++++++++++++++++++++++++++++++++-- index.html | 2 +- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/docs/tutorials/spawnxp.md b/docs/tutorials/spawnxp.md index d97b3c1..cf6bcdb 100644 --- a/docs/tutorials/spawnxp.md +++ b/docs/tutorials/spawnxp.md @@ -1,5 +1,5 @@ ## /spawnxp command -This tutorial will cover spawning in entities using the `ModAPI.promisify()` API. +This tutorial will cover spawning in entities using the [`ModAPI.promisify()`](../apidoc/promisify.md) API. As usual, we'll start with the boilerplate: ```javascript @@ -10,4 +10,58 @@ As usual, we'll start with the boilerplate: //future code })(); -``` \ No newline at end of file +``` +We'll move context to the server, and add a command listener, and ensure the sender is a player: +```javascript +PluginAPI.dedicatedServer.appendCode(function () { //Run this code on the server + PluginAPI.addEventListener("processcommand", (event) => { //Command processing event + if ( + !ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP") + .instanceOf(event.sender.getRef()) + ) { + return; + } + }); +}); +``` + +Next, we'll check that the command is /spawnxp. If it is, we'll get the current dimension of the player, and spawn an XP orb at the sender's position. To construct the XP orb, we'll get the `EntityXPOrb` class and get the [first constructor](https://nurmarvin.github.io/Minecraft-1.8-JavaDocs/net/minecraft/entity/EntityXPOrb.html) +```javascript +PluginAPI.dedicatedServer.appendCode(function () { //Run this code on the server + PluginAPI.addEventListener("processcommand", (event) => { //Command processing event + if ( + !ModAPI.reflect.getClassById("net.minecraft.entity.player.EntityPlayerMP") //If it isn't a player, exit the method + .instanceOf(event.sender.getRef()) + ) { + return; + } + + if (event.command.toLowerCase().startWith("/spawnxp")) { + const world = event.sender.getServerForPlayer(); //get the current dimension + const senderPos = event.sender.getPosition(); //get the player's current position + + const EntityXP = ModAPI.reflect.getClassByName("EntityXPOrb"); // Get the entity xp orb class + + const xporb = EntityXP.constructors[0](world.getRef(), senderPos.getX(), senderPos.getY(), senderPos.getZ(), 10); //Construct the first constructor, with arguments, World, x, y, z, xp value + + //Get the spawn entity in world method + var spawnEntityInWorldMethod = ModAPI.hooks.methods[ModAPI.util.getMethodFromPackage("net.minecraft.world.World", "spawnEntityInWorld")]; + //Because this method reads and writes data to chunks, it tries to save and load the eaglercraft state, which won't work if eaglercraft is also running its own code. + //To work around this issue, use ModAPI.promisify() to convert the method into one that returns a promise + spawnEntityInWorldMethod = ModAPI.promisify(spawnEntityInWorldMethod); + + //we can now use the spawnEntityInWorld method + //wherever you see getRef(), it means to retrieve the raw, untouched data that TeaVM can use. + spawnEntityInWorldMethod(world.getRef(), xporb).then(result => { + // Get the chat component class + const ChatComponentTextClass = ModAPI.reflect.getClassById("net.minecraft.util.ChatComponentText"); + + // Construct the chat component and send it to the client. + event.sender.addChatMessage(ChatComponentTextClass.constructors[0](ModAPI.util.str("An xp orb has been spawned!"))); + }); + + //Stop the unknown command error + event.preventDefault = true; + } + }); +}); \ No newline at end of file diff --git a/index.html b/index.html index 36202e0..e8cf2f0 100644 --- a/index.html +++ b/index.html @@ -117,7 +117,7 @@ How do I compile my own unobfuscated unsigned Eaglercraft build? - tutorial here + tutorial here
How does this tool work?