From c246a0e2005c7a89223b9ba711d4e70167b4087b Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Sun, 1 Mar 2026 15:36:17 -0800 Subject: [PATCH 01/28] Add some map marker stuff --- .../hytale/objects/UserMapMarkerOverride.java | 46 +++++ .../elements/effects/EffectHandler.java | 2 + .../effects/server/EffRemoveMapMarker.java | 100 ++++++++++ .../expressions/ExpressionHandler.java | 2 + .../expressions/server/ExprMapMarkerIds.java | 84 ++++++++ .../elements/functions/DefaultFunctions.java | 17 ++ .../elements/sections/SectionHandler.java | 4 + .../sections/server/SecMapMarker.java | 185 ++++++++++++++++++ .../plugin/elements/types/TypesServer.java | 6 + 9 files changed, 446 insertions(+) create mode 100644 src/main/java/com/github/skriptdev/skript/api/hytale/objects/UserMapMarkerOverride.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/effects/server/EffRemoveMapMarker.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/server/ExprMapMarkerIds.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/sections/server/SecMapMarker.java diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/objects/UserMapMarkerOverride.java b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/UserMapMarkerOverride.java new file mode 100644 index 00000000..c5e870ca --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/UserMapMarkerOverride.java @@ -0,0 +1,46 @@ +package com.github.skriptdev.skript.api.hytale.objects; + +import com.hypixel.hytale.math.vector.Vector3d; +import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem; +import com.hypixel.hytale.protocol.packets.worldmap.MapMarker; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.user.UserMapMarker; + +import java.util.ArrayList; +import java.util.List; + +/** + * Override of {@link UserMapMarker}. + *
Hytale lacks y-coordinates in map markers, so this class adds them. + *
This class also adds context menu items. + */ +public class UserMapMarkerOverride extends UserMapMarker { + + private float blockY; + private MapMarker cachedMarker; + private final List contextMenuItems = new ArrayList<>(); + + public void setPosition(Vector3d pos) { + this.blockY = (float) pos.getY(); + super.setPosition((float) pos.getX(), (float) pos.getZ()); + } + + public void addContextMenuItem(ContextMenuItem contextMenuItem) { + this.contextMenuItems.add(contextMenuItem); + } + + @Override + public MapMarker toProtocolMarker() { + if (this.cachedMarker == null) { + this.cachedMarker = super.toProtocolMarker(); + + assert this.cachedMarker.transform.position != null; + this.cachedMarker.transform.position.y = this.blockY; + if (!this.contextMenuItems.isEmpty()) { + this.cachedMarker.contextMenuItems = this.contextMenuItems.toArray(new ContextMenuItem[0]); + } + } + + return this.cachedMarker; + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java index faa95cde..b837c637 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java @@ -27,6 +27,7 @@ import com.github.skriptdev.skript.plugin.elements.effects.player.EffConnect; import com.github.skriptdev.skript.plugin.elements.effects.player.EffKick; import com.github.skriptdev.skript.plugin.elements.effects.player.EffOpenItemContainer; +import com.github.skriptdev.skript.plugin.elements.effects.server.EffRemoveMapMarker; import com.github.skriptdev.skript.plugin.elements.effects.server.EffServerShutdown; import com.github.skriptdev.skript.plugin.elements.effects.world.EffChunkLoadAsync; import com.github.skriptdev.skript.plugin.elements.effects.world.EffChunkRegenerate; @@ -72,6 +73,7 @@ public static void register(SkriptRegistration registration) { EffOpenItemContainer.register(registration); // SERVER + EffRemoveMapMarker.register(registration); EffServerShutdown.register(registration); // WORLD diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/server/EffRemoveMapMarker.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/server/EffRemoveMapMarker.java new file mode 100644 index 00000000..8128c7f4 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/server/EffRemoveMapMarker.java @@ -0,0 +1,100 @@ +package com.github.skriptdev.skript.plugin.elements.effects.server; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerWorldData; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.worldstore.WorldMarkersResource; +import io.github.syst3ms.skriptparser.lang.Effect; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class EffRemoveMapMarker extends Effect { + + public static void register(SkriptRegistration reg) { + reg.newEffect(EffRemoveMapMarker.class, + "remove map marker with id[s] %strings% (of|from) %worlds/players%", + "remove all map markers (of|from) %worlds/players%") + .name("Remove Map Markers") + .description("Removes map markers from worlds/players.", + "You can specify multiple ids to remove multiple markers at once or remove all markers from a world/player.") + .examples("remove map marker with id \"marker1\" from event-world", + "remove map markers with ids \"marker1\", \"marker2\" from player", + "remove all map markers from world world(\"default\")") + .since("INSERT VERSION") + .register(); + } + + private Expression ids; + private Expression owners; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + if (matchedPattern == 0) { + this.ids = (Expression) expressions[0]; + this.owners = expressions[1]; + } else { + this.owners = expressions[0]; + } + return true; + } + + @Override + protected void execute(@NotNull TriggerContext ctx) { + List markers = this.ids != null ? new ArrayList<>(Arrays.asList(this.ids.getArray(ctx))) : null; + + for (Object owner : this.owners.getArray(ctx)) { + if (owner instanceof World world) { + Runnable worldRunnable = () -> { + Store store = world.getChunkStore().getStore(); + WorldMarkersResource worldMarkersResource = store.getResource(WorldMarkersResource.getResourceType()); + if (markers == null) { + worldMarkersResource.setUserMapMarkers(null); + } else { + markers.forEach(worldMarkersResource::removeUserMapMarker); + } + }; + if (world.isInThread()) { + worldRunnable.run(); + } else { + world.execute(worldRunnable); + } + } else if (owner instanceof Player player) { + World world = player.getWorld(); + assert world != null; + Runnable worldRunnable = () -> { + PlayerWorldData perWorldData = player.getPlayerConfigData().getPerWorldData(world.getName()); + if (markers == null) { + perWorldData.setUserMapMarkers(null); + } else { + markers.forEach(perWorldData::removeUserMapMarker); + } + }; + if (world.isInThread()) { + worldRunnable.run(); + } else { + world.execute(worldRunnable); + } + } + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + if (this.ids == null) { + return "remove all map markers from " + this.owners.toString(ctx, debug); + } + return "remove map markers with id " + this.ids.toString(ctx, debug) + " from " + this.owners.toString(ctx, debug); + } + +} + diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java index dab7fbf4..a7a35739 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java @@ -82,6 +82,7 @@ import com.github.skriptdev.skript.plugin.elements.expressions.ref.ExprRefComponent; import com.github.skriptdev.skript.plugin.elements.expressions.ref.ExprRefInRadius; import com.github.skriptdev.skript.plugin.elements.expressions.server.ExprConsole; +import com.github.skriptdev.skript.plugin.elements.expressions.server.ExprMapMarkerIds; import com.github.skriptdev.skript.plugin.elements.expressions.server.ExprServerViewRadius; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprAllWorlds; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprChunkAtLocation; @@ -194,6 +195,7 @@ public static void register(SkriptRegistration registration) { // SERVER ExprConsole.register(registration); + ExprMapMarkerIds.register(registration); ExprServerViewRadius.register(registration); // WORLD diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/server/ExprMapMarkerIds.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/server/ExprMapMarkerIds.java new file mode 100644 index 00000000..e00e03c3 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/server/ExprMapMarkerIds.java @@ -0,0 +1,84 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.server; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerWorldData; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.user.UserMapMarker; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.worldstore.WorldMarkersResource; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class ExprMapMarkerIds implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprMapMarkerIds.class, String.class, false, + "map marker ids of %worlds/players%") + .name("Map Marker Ids") + .description("Get the IDs of all map markers of a world or player.") + .examples("set {_ids::*} to map marker ids of player") + .since("INSERT VERSION") + .register(); + } + + private Expression owners; + + @SuppressWarnings("NullableProblems") + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + this.owners = expressions[0]; + return true; + } + + @Override + public String[] getValues(@NotNull TriggerContext ctx) { + List markers = new ArrayList<>(); + + for (Object owner : this.owners.getArray(ctx)) { + if (owner instanceof World world) { + markers.addAll(getMarkers(world)); + } else if (owner instanceof Player player) { + markers.addAll(getMarkers(player)); + } + } + + return markers.toArray(new String[0]); + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "map marker ids of " + this.owners.toString(ctx, debug); + } + + private List getMarkers(World world) { + if (world.isInThread()) { + Store store = world.getChunkStore().getStore(); + WorldMarkersResource worldMarkersResource = store.getResource(WorldMarkersResource.getResourceType()); + return worldMarkersResource.getUserMapMarkers().stream().map(UserMapMarker::getId).toList(); + } else { + return CompletableFuture.supplyAsync(() -> getMarkers(world), world).join(); + } + } + + private List getMarkers(Player player) { + World world = player.getWorld(); + if (world == null) { + return List.of(); + } + if (world.isInThread()) { + PlayerWorldData perWorldData = player.getPlayerConfigData().getPerWorldData(world.getName()); + return perWorldData.getUserMapMarkers().stream().map(UserMapMarker::getId).toList(); + } else { + return CompletableFuture.supplyAsync(() -> getMarkers(player), world).join(); + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/functions/DefaultFunctions.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/functions/DefaultFunctions.java index 7cb01748..9746b7a1 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/functions/DefaultFunctions.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/functions/DefaultFunctions.java @@ -5,6 +5,7 @@ import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3f; import com.hypixel.hytale.math.vector.Vector3i; +import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem; import com.hypixel.hytale.server.core.asset.type.item.config.Item; import com.hypixel.hytale.server.core.entity.LivingEntity; import com.hypixel.hytale.server.core.inventory.Inventory; @@ -27,6 +28,7 @@ public static void register(SkriptRegistration reg) { itemFunctions(reg); mathFunctions(reg); positionFunctions(reg); + serverFunctions(reg); } private static void dateTimeFunctions(SkriptRegistration reg) { @@ -287,4 +289,19 @@ private static void positionFunctions(SkriptRegistration reg) { .register(); } + private static void serverFunctions(SkriptRegistration reg) { + reg.newJavaFunction("contextMenuItem", ContextMenuItem.class, true) + .parameter("name", String.class, true) + .parameter("command", String.class, true) + .executeSingle(params -> { + String name = (String) params[0][0]; + String command = (String) params[1][0]; + return new ContextMenuItem(name, command); + }) + .name("Context Menu Itme") + .description("Create a ContextMenuItem to be used with map markers") + .since("INSERT VERSION") + .register(); + } + } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java index 572ce00a..cdd73c9e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.sections; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.github.skriptdev.skript.plugin.elements.sections.server.SecMapMarker; public class SectionHandler { @@ -14,6 +15,9 @@ public static void register(SkriptRegistration registration) { SecSendNotification.register(registration); SecSendTitle.register(registration); SecSpawnNPC.register(registration); + + // SERVER + SecMapMarker.register(registration); } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/server/SecMapMarker.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/server/SecMapMarker.java new file mode 100644 index 00000000..ebe40631 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/server/SecMapMarker.java @@ -0,0 +1,185 @@ +package com.github.skriptdev.skript.plugin.elements.sections.server; + +import com.github.skriptdev.skript.api.hytale.objects.UserMapMarkerOverride; +import com.github.skriptdev.skript.api.hytale.utils.PlayerUtils; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.math.vector.Location; +import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerWorldData; +import com.hypixel.hytale.server.core.universe.PlayerRef; +import com.hypixel.hytale.server.core.universe.Universe; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.user.UserMapMarker; +import com.hypixel.hytale.server.core.universe.world.worldmap.markers.worldstore.WorldMarkersResource; +import io.github.syst3ms.skriptparser.file.FileSection; +import io.github.syst3ms.skriptparser.lang.CodeSection; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.Statement; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.entries.SectionConfiguration; +import io.github.syst3ms.skriptparser.log.SkriptLogger; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import io.github.syst3ms.skriptparser.parsing.ParserState; +import io.github.syst3ms.skriptparser.util.color.Color; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class SecMapMarker extends CodeSection { + + public static void register(SkriptRegistration reg) { + reg.newSection(SecMapMarker.class, "create map marker") + .description("Creates a map marker for a world/player.", + "**Entries**:", + " - `id` = The id of the map marker. Must be unique (required).", + " - `name` = The name of the map marker [optional].", + " - `icon` = The icon which will be seen on the map (required).", + " - `location` = The location of the marker (required).", + " - `tint` = The color of the marker [optional].", + " - `player` = The player to create the map marker for [optional].", + " - If a player is used, the marker will only be visible to that player, and it will save in their player config.", + " - If no player is used, the marker will be visible to all players in the world, and it will save in the world config.", + " - `context_menu_items` = The context menu items to show when right clicking the marker [optional list].", + " - `created_by` = The player who created the marker [optional, will allow the player to delete it].", + "", + "**Icons**:", + " - Icons are found in the Assets file under `Common/UI/WorldMap/MapMarkers`.", + " - Current icons: Campfire, Coordinate, Death, Home, OutsideViewMarker, Player, PlayerAbove, PlayerBelow, " + + "Portal, PortalInvasion, Prefab, Spawn, Temple_Gateway, UserA, UserB, UserC, UserD, UserE, UserF, Warp.", + " - Custom icons are supported.") + .examples("create map marker:", + "\tid: \"le_map_marker\"", + "\ticon: \"Campfire.png\"", + "\tlocation: location of player", + "\tname: \"Warming Spot!\"", + "\ttint: color from hex \"#f0750a\"") + .since("INSERT VERSION") + .register(); + } + + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + return true; + } + + SectionConfiguration config = new SectionConfiguration.Builder() + .addExpression("id", String.class, false) + .addOptionalExpression("name", String.class, false) + .addExpression("icon", String.class, false) + .addExpression("location", Location.class, false) + .addOptionalExpression("tint", Color.class, false) + .addOptionalExpression("player", Player.class, false) + .addOptionalExpression("context_menu_items", ContextMenuItem.class, true) + .addOptionalExpression("created_by", Player.class, false) + .build(); + + @Override + public boolean loadSection(@NotNull FileSection section, @NotNull ParserState parserState, @NotNull SkriptLogger logger) { + return this.config.loadConfiguration(null, section, parserState, logger); + } + + @Override + public Optional walk(@NotNull TriggerContext ctx) { + Optional nextStatement = getNext(); + + // EXPRESSIONS + Expression idExpr = this.config.getExpression("id", String.class).orElse(null); + if (idExpr == null) return nextStatement; + + Expression nameExpr = this.config.getExpression("name", String.class).orElse(null); + + Expression iconExpr = this.config.getExpression("icon", String.class).orElse(null); + if (iconExpr == null) return nextStatement; + + Expression locationExpr = this.config.getExpression("location", Location.class).orElse(null); + if (locationExpr == null) return nextStatement; + + Expression tintExpr = this.config.getExpression("tint", Color.class).orElse(null); + + Expression playerExpr = this.config.getExpression("player", Player.class).orElse(null); + + Expression contextExpr = this.config.getExpression("context_menu_items", ContextMenuItem.class).orElse(null); + + Expression createdByExpr = this.config.getExpression("created_by", Player.class).orElse(null); + + // OBJECTS + String id = idExpr.getSingle(ctx).orElse(null); + if (id == null) return nextStatement; + + String name = nameExpr != null ? nameExpr.getSingle(ctx).orElse(null) : null; + + String icon = iconExpr.getSingle(ctx).orElse(null); + if (icon == null) return nextStatement; + + if (!icon.endsWith(".png")) { + icon += ".png"; + } + + Location location = locationExpr.getSingle(ctx).orElse(null); + if (location == null) return nextStatement; + + World world = Universe.get().getWorld(location.getWorld()); + if (world == null) return nextStatement; + + UserMapMarkerOverride userMapMarker = new UserMapMarkerOverride(); + userMapMarker.setId(id); + userMapMarker.setName(name); + userMapMarker.setIcon(icon); + userMapMarker.setPosition(location.getPosition()); + + if (contextExpr != null) { + for (ContextMenuItem contextMenuItem : contextExpr.getArray(ctx)) { + userMapMarker.addContextMenuItem(contextMenuItem); + } + } + if (createdByExpr != null) { + Player player = createdByExpr.getSingle(ctx).orElse(null); + if (player != null) { + PlayerRef playerRef = PlayerUtils.getPlayerRef(player); + if (playerRef != null) { + userMapMarker.withCreatedByName(playerRef.getUsername()); + userMapMarker.withCreatedByUuid(playerRef.getUuid()); + } + } + } + + if (tintExpr != null) { + Color color = tintExpr.getSingle(ctx).orElse(null); + if (color != null) { + com.hypixel.hytale.protocol.Color hytaleColor = new com.hypixel.hytale.protocol.Color( + (byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()); + userMapMarker.setColorTint(hytaleColor); + } + } + if (playerExpr != null) { + Player player = playerExpr.getSingle(ctx).orElse(null); + if (player != null) { + PlayerWorldData perWorldData = player.getPlayerConfigData().getPerWorldData(world.getName()); + UserMapMarker oldMarker = perWorldData.getUserMapMarker(id); + if (oldMarker != null) { + perWorldData.removeUserMapMarker(id); + } + perWorldData.addUserMapMarker(userMapMarker); + } + } else { + Store store = world.getChunkStore().getStore(); + WorldMarkersResource worldMarkersResource = store.getResource(WorldMarkersResource.getResourceType()); + UserMapMarker oldMarker = worldMarkersResource.getUserMapMarker(id); + if (oldMarker != null) { + worldMarkersResource.removeUserMapMarker(id); + } + worldMarkersResource.addUserMapMarker(userMapMarker); + } + + return nextStatement; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "create map marker"; + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java index a9c04c78..4fa17e1d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesServer.java @@ -11,6 +11,7 @@ import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.protocol.Vector2f; import com.hypixel.hytale.protocol.packets.interface_.NotificationStyle; +import com.hypixel.hytale.protocol.packets.worldmap.ContextMenuItem; import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.command.system.CommandSender; @@ -39,6 +40,11 @@ static void register(SkriptRegistration registration) { .since("1.0.0") .toStringFunction(CommandSender::getDisplayName) .register(); + registration.newType(ContextMenuItem.class, "contextmenuitem", "contextMenuItem@s") + .name("Context Menu Item") + .description("Represents a context menu item that can be used in the world map marker.") + .since("INSERT VERSION") + .register(); registration.newType(Damage.class, "damage", "damage@s") .name("Damage") .description("Represents information about damage dealt to an entity.") From a6b002d3190e9990cd5ff4e49580d906c4a97c6e Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Sun, 1 Mar 2026 15:36:26 -0800 Subject: [PATCH 02/28] Add some map marker stuff - test --- .../elements/hyskript/sections/server/SecMapMarker.sk | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/test/skript/tests/elements/hyskript/sections/server/SecMapMarker.sk diff --git a/src/test/skript/tests/elements/hyskript/sections/server/SecMapMarker.sk b/src/test/skript/tests/elements/hyskript/sections/server/SecMapMarker.sk new file mode 100644 index 00000000..16c5e620 --- /dev/null +++ b/src/test/skript/tests/elements/hyskript/sections/server/SecMapMarker.sk @@ -0,0 +1,11 @@ +test "SecMapMarker": + create map marker: + id: "test_marker" + name: "Test Marker" + icon: "Campfire.png" + location: world spawn of event-world + + assert map marker ids of event-world contains "test_marker" with "The marker should be there" + + remove map marker with id "test_marker" from event-world + assert map marker ids of event-world does not contain "test_marker" with "The marker should be gone" From ba8ebc839177fa6d5e085e2fcdb3c6812f7a92e1 Mon Sep 17 00:00:00 2001 From: Shane Bee Date: Mon, 2 Mar 2026 08:03:14 -0800 Subject: [PATCH 03/28] Merge pull request #19 from SkriptDev/dev/addon-loader Add secondary addon registration option --- build.gradle.kts | 6 ++ .../skript/api/skript/addon/AddonLoader.java | 86 ++++++++++++++----- .../skript/api/skript/addon/Manifest.java | 12 +++ .../github/skriptdev/skript/plugin/HySk.java | 6 +- .../skriptdev/skript/plugin/Skript.java | 45 ++++++++-- 5 files changed, 127 insertions(+), 28 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0997a0b1..7bf16799 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -141,3 +141,9 @@ publishing { } } } + +tasks.withType().configureEach { + // This resolves the "implicit dependency" failure by forcing + // metadata generation to wait for the JAR task. + mustRunAfter(tasks.named("jar")) +} diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/addon/AddonLoader.java b/src/main/java/com/github/skriptdev/skript/api/skript/addon/AddonLoader.java index 370f8722..4bad07b8 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/addon/AddonLoader.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/addon/AddonLoader.java @@ -4,9 +4,11 @@ import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.codec.ExtraInfo; import com.hypixel.hytale.codec.util.RawJsonReader; +import com.hypixel.hytale.common.plugin.AuthorInfo; +import com.hypixel.hytale.common.plugin.PluginManifest; +import com.hypixel.hytale.server.core.plugin.JavaPlugin; import io.github.syst3ms.skriptparser.log.ErrorType; import io.github.syst3ms.skriptparser.log.LogEntry; -import io.github.syst3ms.skriptparser.registration.SkriptAddon; import java.io.File; import java.io.IOException; @@ -16,14 +18,24 @@ import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; public class AddonLoader { + private final Map loadedAddons = new LinkedHashMap<>(); private int addonCount = 0; + public void loadAddons() { + loadAddonsFromFolder(); + startAddons(); + } + public void loadAddonsFromFolder() { Utils.log("Loading addons..."); Path resolve = HySk.getInstance().getDataDirectory().resolve("addons"); @@ -47,13 +59,14 @@ public void loadAddonsFromFolder() { .filter(File::isFile) .filter(f -> f.getName().endsWith(".jar")) .toList()) { - loadAddon(file); + loadAddonFromFile(file); } String plural = this.addonCount == 1 ? "" : "s"; Utils.log("Finished loading %s addon%s!", this.addonCount, plural); } - private void loadAddon(File file) { + @SuppressWarnings("unchecked") + private void loadAddonFromFile(File file) { try (JarFile jarFile = new JarFile(file)) { JarEntry jarEntry = jarFile.getJarEntry("manifest.json"); if (jarEntry == null) { @@ -81,33 +94,64 @@ private void loadAddon(File file) { Utils.error("Main class not found in addon " + file.getName()); return; } - Object mainClassIntance; - try { - mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(manifest.getName()); - } catch (ReflectiveOperationException e) { - Utils.error("Failed to create instance of addon " + file.getName(), ErrorType.EXCEPTION); + if (!HySkriptAddon.class.isAssignableFrom(externalClass)) { + Utils.error("Main class is not an instance of HySkriptAddon in addon " + file.getName()); return; } - if (mainClassIntance instanceof HySkriptAddon addon) { - addon.setManifest(manifest); - addon.start(); - this.addonCount++; - // Finalize registration and logging - for (LogEntry logEntry : addon.getSkriptRegistration().register()) { - Utils.log(null, logEntry); - } - } + initializeAddon((Class) externalClass, manifest); + } catch (IOException e) { Utils.error("Failed to load addon " + file.getName(), ErrorType.EXCEPTION); } } - public void shutdownAddons() { - for (SkriptAddon addon : SkriptAddon.getAddons()) { - if (addon instanceof HySkriptAddon hySkriptAddon) { - hySkriptAddon.shutdown(); + private void startAddons() { + this.loadedAddons.forEach((_, addon) -> { + addon.start(); + // Finalize registration and logging + for (LogEntry logEntry : addon.getSkriptRegistration().register()) { + Utils.log(null, logEntry); } + }); + } + + public T registerAddon(JavaPlugin plugin, Class addonClass) { + PluginManifest pluginManifest = plugin.getManifest(); + String name = pluginManifest.getName(); + List authors = new ArrayList<>(); + for (AuthorInfo author : pluginManifest.getAuthors()) { + authors.add(author.getName()); } + Manifest addonManifest = new Manifest(null, + name, + pluginManifest.getVersion().toString(), + pluginManifest.getDescription(), + authors.toArray(new String[0]), + pluginManifest.getWebsite()); + + return initializeAddon(addonClass, addonManifest); + } + + @SuppressWarnings("unchecked") + private T initializeAddon(Class externalClass, Manifest manifest) { + HySkriptAddon mainClassIntance; + String name = manifest.getName(); + try { + mainClassIntance = externalClass.getDeclaredConstructor(String.class).newInstance(name); + } catch (ReflectiveOperationException e) { + Utils.error("Failed to create instance of addon " + name, ErrorType.EXCEPTION); + return null; + } + HySkriptAddon addon = mainClassIntance; + addon.setManifest(manifest); + this.loadedAddons.put(name, addon); + this.addonCount++; + return (T) addon; + } + + public void shutdownAddons() { + this.loadedAddons.forEach((name, addon) -> addon.shutdown()); + this.loadedAddons.clear(); } } diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/addon/Manifest.java b/src/main/java/com/github/skriptdev/skript/api/skript/addon/Manifest.java index 7ccd54a6..a73b0d3c 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/addon/Manifest.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/addon/Manifest.java @@ -40,6 +40,18 @@ public class Manifest { private String[] authors; private String website; + private Manifest() { + } + + public Manifest(String mainClass, String name, String version, String description, String[] authors, String website) { + this.mainClass = mainClass; + this.name = name; + this.version = version; + this.description = description; + this.authors = authors; + this.website = website; + } + @ApiStatus.Internal public String getMainClass() { return this.mainClass; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/HySk.java b/src/main/java/com/github/skriptdev/skript/plugin/HySk.java index 7a70b5eb..01325e46 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/HySk.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/HySk.java @@ -30,7 +30,8 @@ public HySk(@NotNull JavaPluginInit init) { */ @Override protected void setup() { - // Unused - for now + // Setup early so addons can register from this + this.skript = new Skript(this); } /** @@ -38,7 +39,8 @@ protected void setup() { */ @Override protected void start() { - this.skript = new Skript(this); + // After addons load, startup Skript + this.skript.start(); new SkriptCommand(getCommandRegistry()); BstatsMetrics.registerMetrics(this); } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java index c604b073..c21a6274 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java @@ -3,6 +3,7 @@ import com.github.skriptdev.skript.api.skript.ErrorHandler; import com.github.skriptdev.skript.api.skript.ScriptsLoader; import com.github.skriptdev.skript.api.skript.addon.AddonLoader; +import com.github.skriptdev.skript.api.skript.addon.HySkriptAddon; import com.github.skriptdev.skript.api.skript.command.ArgUtils; import com.github.skriptdev.skript.api.skript.config.SkriptConfig; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; @@ -15,6 +16,7 @@ import com.github.skriptdev.skript.plugin.elements.events.EventHandler; import com.github.skriptdev.skript.plugin.elements.events.server.EvtBoot; import com.hypixel.hytale.server.core.event.events.BootEvent; +import com.hypixel.hytale.server.core.plugin.JavaPlugin; import io.github.syst3ms.skriptparser.config.Config.ConfigSection; import io.github.syst3ms.skriptparser.lang.TriggerMap; import io.github.syst3ms.skriptparser.log.LogEntry; @@ -33,19 +35,27 @@ public class Skript extends SkriptAddon { public static Skript INSTANCE; private final HySk hySk; - private final SkriptConfig skriptConfig; + private final AddonLoader addonLoader; private final Path scriptsPath; + private SkriptConfig skriptConfig; private SkriptRegistration registration; private ElementRegistration elementRegistration; - private AddonLoader addonLoader; private ScriptsLoader scriptsLoader; + private boolean isAcceptingRegistrations = true; Skript(HySk hySk) { super("HySkript"); - long start = System.currentTimeMillis(); INSTANCE = this; this.hySk = hySk; + this.addonLoader = new AddonLoader(); this.scriptsPath = hySk.getDataDirectory().resolve("scripts"); + } + + void start() { + // Stop accepting registrations after Skript starts to load + this.isAcceptingRegistrations = false; + + long start = System.currentTimeMillis(); Utils.log(" "); Utils.log("Setting up HySkript!"); @@ -86,8 +96,7 @@ private void setupSkript() { Utils.log("HySkript setup completed in %sms!", fin); // LOAD ADDONS - this.addonLoader = new AddonLoader(); - this.addonLoader.loadAddonsFromFolder(); + this.addonLoader.loadAddons(); // SETUP ERROR HANDLER Utils.debug("Setting up error handler..."); @@ -187,6 +196,32 @@ private void loadVariables() { return this.registration; } + /** + * Check if HySkript is accepting registrations. + * + * @return True if HySkript is accepting registrations, false otherwise. + */ + public boolean isAcceptingRegistrations() { + return this.isAcceptingRegistrations; + } + + /** + * Register an addon to HySkript. + *
ONLY use this when registering a plugin/mod as an addon. + *
Regular addons are self registering. + * + * @param plugin Main plugin instance + * @param addonClass Class of the addon + * @param Type of the addon + * @return New instance of the addon + */ + public T registerAddon(@NotNull JavaPlugin plugin, @NotNull Class addonClass) { + if (!this.isAcceptingRegistrations) { + throw new IllegalStateException("Cannot register addons after HySkript has started!"); + } + return this.addonLoader.registerAddon(plugin, addonClass); + } + public ElementRegistration getElementRegistration() { return this.elementRegistration; } From 7ec82178e00ce19bf4193af66d29c4153b11ea82 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 08:05:05 -0800 Subject: [PATCH 04/28] Skript - make shutdown inaccessible outside --- src/main/java/com/github/skriptdev/skript/plugin/Skript.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java index c21a6274..09161e08 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java @@ -126,7 +126,7 @@ private void setupSkript() { }); } - public void shutdown() { + void shutdown() { // SHUTDOWN LISTENERS EventHandler.shutdown(); From b42bc0821ef3a5d676672b3b860de0fdb8755e32 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 08:09:58 -0800 Subject: [PATCH 05/28] BstatsMetrics - make inaccessible --- .../java/com/github/skriptdev/skript/plugin/BstatsMetrics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/BstatsMetrics.java b/src/main/java/com/github/skriptdev/skript/plugin/BstatsMetrics.java index 0e56ac72..b65bc429 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/BstatsMetrics.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/BstatsMetrics.java @@ -9,7 +9,7 @@ import java.util.HashMap; import java.util.Map; -public class BstatsMetrics { +class BstatsMetrics { static void registerMetrics(HySk plugin) { Metrics metrics = new Metrics(plugin, 29735); From 6246fcacdd6f2acf035a7994ba26734ef77e3363 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 08:10:32 -0800 Subject: [PATCH 06/28] Block/Direction - move to objects package --- .../github/skriptdev/skript/api/hytale/{ => objects}/Block.java | 2 +- .../skriptdev/skript/api/hytale/{ => objects}/Direction.java | 2 +- .../github/skriptdev/skript/api/skript/event/BlockContext.java | 2 +- .../plugin/elements/conditions/block/CondBlockIsSolid.java | 2 +- .../skript/plugin/elements/effects/block/EffBreakBlock.java | 2 +- .../skript/plugin/elements/effects/block/EffDamageBlock.java | 2 +- .../skript/plugin/elements/effects/entity/EffRide.java | 2 +- .../skriptdev/skript/plugin/elements/events/EventHandler.java | 2 +- .../plugin/elements/events/player/EvtPlayerBreakBlock.java | 2 +- .../plugin/elements/events/player/EvtPlayerDamageBlock.java | 2 +- .../plugin/elements/events/player/EvtPlayerPlaceBlock.java | 2 +- .../skript/plugin/elements/events/player/EvtPlayerUseBlock.java | 2 +- .../skript/plugin/elements/expressions/block/ExprBlockAt.java | 2 +- .../plugin/elements/expressions/block/ExprBlockFluid.java | 2 +- .../plugin/elements/expressions/block/ExprBlockFluidLevel.java | 2 +- .../plugin/elements/expressions/block/ExprBlockHealth.java | 2 +- .../plugin/elements/expressions/block/ExprBlockIterator.java | 2 +- .../plugin/elements/expressions/block/ExprBlockRotation.java | 2 +- .../plugin/elements/expressions/block/ExprBlockSphere.java | 2 +- .../skript/plugin/elements/expressions/block/ExprBlockTint.java | 2 +- .../plugin/elements/expressions/block/ExprBlockTypeOfBlock.java | 2 +- .../plugin/elements/expressions/block/ExprHighestBlock.java | 2 +- .../elements/expressions/block/ExprTargetBlockOfPlayer.java | 2 +- .../skript/plugin/elements/expressions/item/ExprItemType.java | 2 +- .../elements/expressions/other/ExprLocationDirection.java | 2 +- .../plugin/elements/expressions/other/ExprLocationOf.java | 2 +- .../skriptdev/skript/plugin/elements/types/TypesBlock.java | 2 +- .../skriptdev/skript/plugin/elements/types/TypesCustom.java | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) rename src/main/java/com/github/skriptdev/skript/api/hytale/{ => objects}/Block.java (99%) rename src/main/java/com/github/skriptdev/skript/api/hytale/{ => objects}/Direction.java (97%) diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/Block.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/api/hytale/Block.java rename to src/main/java/com/github/skriptdev/skript/api/hytale/objects/Block.java index e3a1de85..625d6945 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/Block.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.api.hytale; +package com.github.skriptdev.skript.api.hytale.objects; import com.github.skriptdev.skript.api.hytale.utils.StoreUtils; import com.hypixel.hytale.component.CommandBuffer; diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/Direction.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java rename to src/main/java/com/github/skriptdev/skript/api/hytale/objects/Direction.java index 6c54bd21..9e63fc33 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/Direction.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/objects/Direction.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.api.hytale; +package com.github.skriptdev.skript.api.hytale.objects; import com.github.skriptdev.skript.api.hytale.utils.LocationUtils; import com.hypixel.hytale.math.vector.Location; diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/event/BlockContext.java b/src/main/java/com/github/skriptdev/skript/api/skript/event/BlockContext.java index d2bedd68..298d0351 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/event/BlockContext.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/event/BlockContext.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.api.skript.event; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import io.github.syst3ms.skriptparser.lang.TriggerContext; /** diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/block/CondBlockIsSolid.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/block/CondBlockIsSolid.java index 6a6cd318..145f52e8 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/block/CondBlockIsSolid.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/conditions/block/CondBlockIsSolid.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.conditions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.protocol.BlockMaterial; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffBreakBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffBreakBlock.java index 97345468..a0ea32b8 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffBreakBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffBreakBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.effects.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import io.github.syst3ms.skriptparser.lang.Effect; import io.github.syst3ms.skriptparser.lang.Expression; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffDamageBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffDamageBlock.java index 6f365119..43b3f28d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffDamageBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffDamageBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.effects.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.entity.LivingEntity; import com.hypixel.hytale.server.core.inventory.ItemStack; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffRide.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffRide.java index b60a18f1..3db60c9f 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffRide.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffRide.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.effects.entity; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.hytale.utils.EntityUtils; import com.github.skriptdev.skript.api.hytale.utils.StoreUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java index c7a82bb5..285909fa 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java @@ -1,7 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.event.BlockContext; import com.github.skriptdev.skript.api.skript.event.LocationContext; import com.github.skriptdev.skript.api.skript.event.PlayerContext; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerBreakBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerBreakBlock.java index 2d7daa42..66ab29b9 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerBreakBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerBreakBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.events.player; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.event.CancellableContext; import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.event.SystemEvent; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDamageBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDamageBlock.java index f1af6639..aec9bd22 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDamageBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDamageBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.events.player; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.event.CancellableContext; import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.event.SystemEvent; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerPlaceBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerPlaceBlock.java index b852c99f..4c430917 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerPlaceBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerPlaceBlock.java @@ -1,7 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events.player; import com.github.skriptdev.skript.api.hytale.utils.AssetStoreUtils; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.event.BlockContext; import com.github.skriptdev.skript.api.skript.event.CancellableContext; import com.github.skriptdev.skript.api.skript.event.PlayerContext; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerUseBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerUseBlock.java index d5c23a28..5ad1f217 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerUseBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerUseBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.events.player; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.event.CancellableContext; import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.event.SystemEvent; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockAt.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockAt.java index 2779fdc1..ea0b2474 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockAt.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockAt.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.math.vector.Vector3i; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluid.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluid.java index 90e5991c..f0c9a1a2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluid.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluid.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.server.core.asset.type.fluid.Fluid; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluidLevel.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluidLevel.java index 227016af..6f03404e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluidLevel.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockFluidLevel.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Location; import io.github.syst3ms.skriptparser.lang.Expression; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockHealth.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockHealth.java index 17eefe11..99fed933 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockHealth.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockHealth.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import io.github.syst3ms.skriptparser.lang.Expression; import io.github.syst3ms.skriptparser.lang.TriggerContext; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockIterator.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockIterator.java index eadcfecf..80902305 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockIterator.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockIterator.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.iterator.LineIterator; import com.hypixel.hytale.math.vector.Location; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockRotation.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockRotation.java index 3ca3d999..fe665366 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockRotation.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockRotation.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Vector3i; import io.github.syst3ms.skriptparser.lang.Expression; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockSphere.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockSphere.java index 4e854268..efcd7240 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockSphere.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockSphere.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.block.BlockSphereUtil; import com.hypixel.hytale.math.vector.Location; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTint.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTint.java index 86267ba4..c5b52e16 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTint.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTint.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.universe.world.World; import io.github.syst3ms.skriptparser.lang.TriggerContext; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTypeOfBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTypeOfBlock.java index 0192eb77..da956f9b 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTypeOfBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprBlockTypeOfBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import io.github.syst3ms.skriptparser.lang.Expression; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprHighestBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprHighestBlock.java index 50b4d61f..cf41633a 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprHighestBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprHighestBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.util.ChunkUtil; import com.hypixel.hytale.math.vector.Location; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java index 305d997e..43f3bda2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/block/ExprTargetBlockOfPlayer.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.block; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.config.SkriptConfig; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.api.utils.Utils; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprItemType.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprItemType.java index d41b3d1d..0961d577 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprItemType.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprItemType.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.item; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.item.config.Item; import com.hypixel.hytale.server.core.inventory.ItemStack; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationDirection.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationDirection.java index 09e44f8e..73ab9b7d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationDirection.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationDirection.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.other; -import com.github.skriptdev.skript.api.hytale.Direction; +import com.github.skriptdev.skript.api.hytale.objects.Direction; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.math.vector.Location; import io.github.syst3ms.skriptparser.lang.Expression; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationOf.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationOf.java index 795672fd..736d22ab 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationOf.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprLocationOf.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.other; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java index 628efd61..17c43a2d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesBlock.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.types; -import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.hytale.objects.Block; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.protocol.InteractionType; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java index 0906c0ad..6b59eeb9 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesCustom.java @@ -1,6 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.types; -import com.github.skriptdev.skript.api.hytale.Direction; +import com.github.skriptdev.skript.api.hytale.objects.Direction; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; public class TypesCustom { From f52d1f238d5e8160e0ff2e4764edb5aae11b39f2 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 19:41:19 -0800 Subject: [PATCH 07/28] Add some inventory events --- .../skript/event/SlotTransactionContext.java | 52 ++++++ .../plugin/elements/events/EventHandler.java | 38 ++++ .../entity/EvtLivingEntityInvChange.java | 13 +- .../events/inventory/EvtInventoryMove.java | 167 ++++++++++++++++++ .../EvtItemStackSlotTransaction.java | 75 ++++++++ .../inventory/EvtItemStackTransaction.java | 87 +++++++++ .../events/inventory/EvtSlotTransaction.java | 54 ++++++ .../events/inventory/InventoryListener.java | 48 +++++ .../plugin/elements/types/TypesItem.java | 11 +- 9 files changed, 532 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/github/skriptdev/skript/api/skript/event/SlotTransactionContext.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtInventoryMove.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackSlotTransaction.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackTransaction.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtSlotTransaction.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/InventoryListener.java diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/event/SlotTransactionContext.java b/src/main/java/com/github/skriptdev/skript/api/skript/event/SlotTransactionContext.java new file mode 100644 index 00000000..c35eba60 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/api/skript/event/SlotTransactionContext.java @@ -0,0 +1,52 @@ +package com.github.skriptdev.skript.api.skript.event; + +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.ItemStack; +import com.hypixel.hytale.server.core.inventory.container.ItemContainer; +import com.hypixel.hytale.server.core.inventory.transaction.ActionType; +import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction; + +public abstract class SlotTransactionContext implements PlayerContext { + + private final LivingEntityInventoryChangeEvent event; + private final SlotTransaction slotTransaction; + private final Player player; + + public SlotTransactionContext(LivingEntityInventoryChangeEvent event, + SlotTransaction slotTransaction, Player player) { + this.event = event; + this.slotTransaction = slotTransaction; + this.player = player; + } + + public ItemContainer getContainer() { + return this.event.getItemContainer(); + } + + public ActionType getActionType() { + return this.slotTransaction.getAction(); + } + + public int getSlot() { + return this.slotTransaction.getSlot(); + } + + public ItemStack getSlotBefore() { + return this.slotTransaction.getSlotBefore(); + } + + public ItemStack getSlotAfter() { + return this.slotTransaction.getSlotAfter(); + } + + public ItemStack getOutput() { + return this.slotTransaction.getOutput(); + } + + @Override + public Player getPlayer() { + return this.player; + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java index 285909fa..65720a61 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/EventHandler.java @@ -7,6 +7,7 @@ import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.event.PlayerRefContext; import com.github.skriptdev.skript.api.skript.event.RefContext; +import com.github.skriptdev.skript.api.skript.event.SlotTransactionContext; import com.github.skriptdev.skript.api.skript.event.WorldContext; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.elements.events.entity.EvtEntityDamage; @@ -14,6 +15,10 @@ import com.github.skriptdev.skript.plugin.elements.events.entity.EvtEntityPickupItem; import com.github.skriptdev.skript.plugin.elements.events.entity.EvtEntityRemove; import com.github.skriptdev.skript.plugin.elements.events.entity.EvtLivingEntityInvChange; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtInventoryMove; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtItemStackSlotTransaction; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtSlotTransaction; +import com.github.skriptdev.skript.plugin.elements.events.inventory.InventoryListener; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerAddToWorld; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerBreakBlock; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerChangeGameMode; @@ -41,8 +46,12 @@ import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.inventory.ItemStack; +import com.hypixel.hytale.server.core.inventory.container.ItemContainer; +import com.hypixel.hytale.server.core.inventory.transaction.ActionType; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.world.World; +import io.github.syst3ms.skriptparser.registration.context.ContextValue; import io.github.syst3ms.skriptparser.registration.context.ContextValue.Usage; public class EventHandler { @@ -55,6 +64,12 @@ public static void register(SkriptRegistration registration) { EvtEntityRemove.register(registration); EvtLivingEntityInvChange.register(registration); + // INVENTORY + InventoryListener.registerListener(registration); + EvtInventoryMove.register(registration); + EvtItemStackSlotTransaction.register(registration); + EvtSlotTransaction.register(registration); + // PLAYER EvtPlayerAddToWorld.register(registration); EvtPlayerBreakBlock.register(registration); @@ -89,6 +104,7 @@ public static void register(SkriptRegistration registration) { // CONTEXT registerGlobalContexts(registration); + registerInventoryContexts(registration); } public static void shutdown() { @@ -120,4 +136,26 @@ private static void registerGlobalContexts(SkriptRegistration reg) { .register(); } + private static void registerInventoryContexts(SkriptRegistration reg) { + reg.newSingleContextValue(SlotTransactionContext.class, ItemContainer.class, + "item-container", SlotTransactionContext::getContainer) + .register(); + reg.newSingleContextValue(SlotTransactionContext.class, ActionType.class, + "action-type", SlotTransactionContext::getActionType) + .register(); + reg.newSingleContextValue(SlotTransactionContext.class, Number.class, + "slot", SlotTransactionContext::getSlot) + .register(); + reg.newSingleContextValue(SlotTransactionContext.class, ItemStack.class, + "itemstack", SlotTransactionContext::getSlotBefore) + .setState(ContextValue.State.PAST) + .register(); + reg.newSingleContextValue(SlotTransactionContext.class, ItemStack.class, + "itemstack", SlotTransactionContext::getSlotAfter) + .register(); + reg.newSingleContextValue(SlotTransactionContext.class, ItemStack.class, + "output", SlotTransactionContext::getOutput) + .register(); + } + } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtLivingEntityInvChange.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtLivingEntityInvChange.java index 30afdaf5..daed4d02 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtLivingEntityInvChange.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtLivingEntityInvChange.java @@ -2,15 +2,12 @@ import com.github.skriptdev.skript.api.skript.event.WorldContext; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; -import com.github.skriptdev.skript.plugin.HySk; -import com.hypixel.hytale.event.EventRegistration; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; import com.hypixel.hytale.server.core.inventory.container.ItemContainer; import com.hypixel.hytale.server.core.universe.world.World; import io.github.syst3ms.skriptparser.lang.Expression; import io.github.syst3ms.skriptparser.lang.TriggerContext; -import io.github.syst3ms.skriptparser.lang.TriggerMap; import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; import io.github.syst3ms.skriptparser.parsing.ParseContext; import org.jetbrains.annotations.NotNull; @@ -31,16 +28,8 @@ public static void register(SkriptRegistration reg) { // TODO add transaction } - private static EventRegistration LISTENER; - @Override public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { - if (LISTENER == null) { - LISTENER = HySk.getInstance().getEventRegistry().registerGlobal(LivingEntityInventoryChangeEvent.class, event -> { - InvChangeContext ctx = new InvChangeContext(event); - TriggerMap.callTriggersByContext(ctx); - }); - } return true; } @@ -54,7 +43,7 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return "living entity inventory change"; } - private record InvChangeContext(LivingEntityInventoryChangeEvent event) implements TriggerContext, WorldContext { + public record InvChangeContext(LivingEntityInventoryChangeEvent event) implements TriggerContext, WorldContext { private Entity getEntity() { return this.event.getEntity(); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtInventoryMove.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtInventoryMove.java new file mode 100644 index 00000000..4db4d97f --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtInventoryMove.java @@ -0,0 +1,167 @@ +package com.github.skriptdev.skript.plugin.elements.events.inventory; + +import com.github.skriptdev.skript.api.skript.event.PlayerContext; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.ItemStack; +import com.hypixel.hytale.server.core.inventory.container.ItemContainer; +import com.hypixel.hytale.server.core.inventory.transaction.ActionType; +import com.hypixel.hytale.server.core.inventory.transaction.MoveTransaction; +import com.hypixel.hytale.server.core.inventory.transaction.MoveType; +import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import io.github.syst3ms.skriptparser.registration.context.ContextValue; +import org.jetbrains.annotations.NotNull; + +public class EvtInventoryMove extends SkriptEvent { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtInventoryMove.class, "inventory move", + "inventory pickup", + "inventory (put|place) down") + .name("Inventory Move") + .description("Called when an item is moved in an inventory window.", + "**Types**:", + " - move = Called after an item is moved from one slot to another (fired twice).", + " - pickup = Called when an item is picked up from the inventory (fired once after the item is put down).", + " - place down = Called when an item is placed down in the inventory (fired once).") + .since("INSERT VERSION") + .setHandledContexts(InventoryMoveContext.class) + .register(); + + reg.newSingleContextValue(InventoryMoveContext.class, ItemStack.class, + "itemstack", InventoryMoveContext::getSlotBefore) + .setState(ContextValue.State.PAST) + .description("Represents the ItemStack in the slot before the action.") + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, ItemStack.class, + "itemstack", InventoryMoveContext::getSlotAfter) + .description("Represents the ItemStack in the slot after the action.") + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, ItemStack.class, + "output", InventoryMoveContext::getOutput) + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, ActionType.class, + "action", InventoryMoveContext::getActionType) + .description("Represents the type of action performed in the inventory move.") + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, Integer.class, + "slot", InventoryMoveContext::getSlot) + .description("Represents the slot number involved in the inventory move.") + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, ItemContainer.class, + "item-container", InventoryMoveContext::getPastContainer) + .description("Represents the container before the inventory move.") + .setState(ContextValue.State.PAST) + .register(); + reg.newSingleContextValue(InventoryMoveContext.class, ItemContainer.class, + "item-container", InventoryMoveContext::getContainer) + .description("Represents the container after the inventory move.") + .register(); + } + + private int pattern; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + this.pattern = matchedPattern; + return true; + } + + @SuppressWarnings("RedundantIfStatement") + @Override + public boolean check(TriggerContext ctx) { + if (!(ctx instanceof InventoryMoveContext context)) return false; + if (this.pattern == 0) { + return true; + } else if (this.pattern == 1 && context.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return true; + } else if (this.pattern == 2 && context.transaction.getMoveType() == MoveType.MOVE_TO_SELF) { + return true; + } + + return false; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return switch (pattern) { + case 0 -> "inventory move"; + case 1 -> "inventory pickup"; + case 2 -> "inventory put down"; + default -> "unknown"; + }; + } + + public record InventoryMoveContext(LivingEntityInventoryChangeEvent event, MoveTransaction transaction, Player player) + implements PlayerContext { + + @Override + public Player getPlayer() { + return this.player; + } + + public ItemStack getSlotBefore() { + if (this.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return this.transaction.getRemoveTransaction().getSlotBefore(); + } else if (this.transaction.getAddTransaction() instanceof SlotTransaction slotTransaction) { + return slotTransaction.getSlotBefore(); + } + return null; + } + + public ItemStack getSlotAfter() { + if (this.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return this.transaction.getRemoveTransaction().getSlotAfter(); + } else if (this.transaction.getAddTransaction() instanceof SlotTransaction slotTransaction) { + return slotTransaction.getSlotAfter(); + } + return null; + } + + public ItemStack getOutput() { + if (this.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return this.transaction.getRemoveTransaction().getOutput(); + } else if (this.transaction.getAddTransaction() instanceof SlotTransaction slotTransaction) { + return slotTransaction.getOutput(); + } + return null; + } + + public ActionType getActionType() { + if (this.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return this.transaction.getRemoveTransaction().getAction(); + } else if (this.transaction.getAddTransaction() instanceof SlotTransaction slotTransaction) { + return slotTransaction.getAction(); + } + return null; + } + + public int getSlot() { + if (this.transaction.getMoveType() == MoveType.MOVE_FROM_SELF) { + return this.transaction.getRemoveTransaction().getSlot(); + } else if (this.transaction.getAddTransaction() instanceof SlotTransaction slotTransaction) { + return slotTransaction.getSlot(); + } + return -1; + } + + public ItemContainer getPastContainer() { + return this.event.getItemContainer(); + } + + public ItemContainer getContainer() { + return this.transaction.getOtherContainer(); + } + + @Override + public String getName() { + return "inventory move context"; + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackSlotTransaction.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackSlotTransaction.java new file mode 100644 index 00000000..5ceb15bb --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackSlotTransaction.java @@ -0,0 +1,75 @@ +package com.github.skriptdev.skript.plugin.elements.events.inventory; + +import com.github.skriptdev.skript.api.skript.event.SlotTransactionContext; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.ItemStack; +import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EvtItemStackSlotTransaction extends SkriptEvent { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtItemStackSlotTransaction.class, + "inventory item[stack] slot transaction") + .name("Inventory Item Slot Transaction") + .description("Called when there is an inventory transaction involving an ItemStack in a slot.") + .since("INSERT VERSION") + .setHandledContexts(ItemStackSlotContext.class) + .register(); + + reg.newSingleContextValue(ItemStackSlotContext.class, ItemStack.class, + "output", ItemStackSlotContext::getOutput) + .register(); + + reg.newSingleContextValue(ItemStackSlotContext.class, ItemStack.class, + "remainder", ItemStackSlotContext::getRemainder) + .register(); + } + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + return true; + } + + @Override + public boolean check(TriggerContext ctx) { + return ctx instanceof ItemStackSlotContext; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "inventory item slot transaction"; + } + + public static class ItemStackSlotContext extends SlotTransactionContext { + + private final ItemStackSlotTransaction transaction; + + ItemStackSlotContext(LivingEntityInventoryChangeEvent event, + ItemStackSlotTransaction transaction, + Player player) { + super(event, transaction, player); + this.transaction = transaction; + } + + public ItemStack getQuery() { + return this.transaction.getQuery(); + } + + public ItemStack getRemainder() { + return this.transaction.getRemainder(); + } + + @Override + public String getName() { + return "itemstack slot context"; + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackTransaction.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackTransaction.java new file mode 100644 index 00000000..a9da4735 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtItemStackTransaction.java @@ -0,0 +1,87 @@ +package com.github.skriptdev.skript.plugin.elements.events.inventory; + +import com.github.skriptdev.skript.api.skript.event.PlayerContext; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.ItemStack; +import com.hypixel.hytale.server.core.inventory.container.ItemContainer; +import com.hypixel.hytale.server.core.inventory.transaction.ActionType; +import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EvtItemStackTransaction extends SkriptEvent { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtItemStackTransaction.class, "inventory item[stack] transaction") + .name("Inventory ItemStack Transaction") + .description("Called when there is an inventory transaction involving an ItemStack.") + .since("INSERT VERSION") + .setHandledContexts(ItemStackTransactionContext.class) + .register(); + + reg.newSingleContextValue(ItemStackTransactionContext.class, ItemContainer.class, + "item-container", ItemStackTransactionContext::getContainer) + .register(); + reg.newSingleContextValue(ItemStackTransactionContext.class, ActionType.class, + "action-type", ItemStackTransactionContext::getActionType) + .register(); + reg.newSingleContextValue(ItemStackTransactionContext.class, ItemStack.class, + "query", ItemStackTransactionContext::getQuery) + .register(); + reg.newSingleContextValue(ItemStackTransactionContext.class, ItemStack.class, + "remainder", ItemStackTransactionContext::getRemainder) + .register(); + } + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + return true; + } + + @Override + public boolean check(TriggerContext ctx) { + return ctx instanceof ItemStackTransactionContext; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "inventory itemstack transaction"; + } + + public record ItemStackTransactionContext(LivingEntityInventoryChangeEvent event, + ItemStackTransaction transaction, + Player player) implements PlayerContext { + + public ItemContainer getContainer() { + return this.event.getItemContainer(); + } + + public ActionType getActionType() { + return this.transaction.getAction(); + } + + public ItemStack getQuery() { + return this.transaction.getQuery(); + } + + public ItemStack getRemainder() { + return this.transaction.getRemainder(); + } + + @Override + public Player getPlayer() { + return this.player; + } + + @Override + public String getName() { + return "itemstack transaction context"; + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtSlotTransaction.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtSlotTransaction.java new file mode 100644 index 00000000..76e2b8ae --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/EvtSlotTransaction.java @@ -0,0 +1,54 @@ +package com.github.skriptdev.skript.plugin.elements.events.inventory; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EvtSlotTransaction extends SkriptEvent { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtSlotTransaction.class, + "inventory item[stack] slot transaction") + .name("Inventory Item Slot Transaction") + .description("Called when there is an inventory transaction involving a slot.") + .since("INSERT VERSION") + .setHandledContexts(SlotTransactionContext.class) + .register(); + } + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + return true; + } + + @Override + public boolean check(TriggerContext ctx) { + return ctx instanceof SlotTransactionContext; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "inventory slot transaction"; + } + + public static class SlotTransactionContext + extends com.github.skriptdev.skript.api.skript.event.SlotTransactionContext { + + public SlotTransactionContext(LivingEntityInventoryChangeEvent event, + SlotTransaction slotTransaction, Player player) { + super(event, slotTransaction, player); + } + + @Override + public String getName() { + return "slot transaction context"; + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/InventoryListener.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/InventoryListener.java new file mode 100644 index 00000000..7eece13f --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/inventory/InventoryListener.java @@ -0,0 +1,48 @@ +package com.github.skriptdev.skript.plugin.elements.events.inventory; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.github.skriptdev.skript.plugin.elements.events.entity.EvtLivingEntityInvChange.InvChangeContext; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtInventoryMove.InventoryMoveContext; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtItemStackSlotTransaction.ItemStackSlotContext; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtItemStackTransaction.ItemStackTransactionContext; +import com.github.skriptdev.skript.plugin.elements.events.inventory.EvtSlotTransaction.SlotTransactionContext; +import com.hypixel.hytale.event.EventRegistry; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.entity.LivingEntityInventoryChangeEvent; +import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction; +import com.hypixel.hytale.server.core.inventory.transaction.ItemStackTransaction; +import com.hypixel.hytale.server.core.inventory.transaction.MoveTransaction; +import com.hypixel.hytale.server.core.inventory.transaction.SlotTransaction; +import com.hypixel.hytale.server.core.inventory.transaction.Transaction; +import io.github.syst3ms.skriptparser.lang.TriggerMap; + +public class InventoryListener { + + public static void registerListener(SkriptRegistration reg) { + EventRegistry eventRegistry = reg.getSkript().getPlugin().getEventRegistry(); + + eventRegistry.registerGlobal(LivingEntityInventoryChangeEvent.class, event -> { + InvChangeContext ctx = new InvChangeContext(event); + TriggerMap.callTriggersByContext(ctx); + + if (event.getEntity() instanceof Player player) { + Transaction transaction = event.getTransaction(); + + if (transaction instanceof MoveTransaction move) { + InventoryMoveContext context = new InventoryMoveContext(event, move, player); + TriggerMap.callTriggersByContext(context); + } else if (transaction instanceof ItemStackSlotTransaction slot) { + ItemStackSlotContext context = new ItemStackSlotContext(event, slot, player); + TriggerMap.callTriggersByContext(context); + } else if (transaction instanceof ItemStackTransaction stack) { + ItemStackTransactionContext context = new ItemStackTransactionContext(event, stack, player); + TriggerMap.callTriggersByContext(context); + } else if (transaction instanceof SlotTransaction slotTransaction) { + SlotTransactionContext context = new SlotTransactionContext(event, slotTransaction, player); + TriggerMap.callTriggersByContext(context); + } + } + }); + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java index 15aa8783..82376bbe 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/TypesItem.java @@ -12,6 +12,7 @@ import com.hypixel.hytale.server.core.inventory.container.EmptyItemContainer; import com.hypixel.hytale.server.core.inventory.container.ItemContainer; import com.hypixel.hytale.server.core.inventory.container.SimpleItemContainer; +import com.hypixel.hytale.server.core.inventory.transaction.ActionType; import com.hypixel.hytale.server.core.modules.entity.item.ItemComponent; import io.github.syst3ms.skriptparser.types.changers.TypeSerializer; import org.bson.BsonDocument; @@ -47,6 +48,11 @@ public Inventory deserialize(@NotNull Gson gson, @NotNull JsonElement element) { .description("Represents the types of actions that can be performed in an inventory.") .since("1.0.0") .register(); + reg.newEnumType(ActionType.class, "inventorytransactionactiontype", "inventoryTransactionActionType@s") + .name("Inventory Transaction Action Type") + .description("Represents the types of actions that can be performed in an inventory transaction.") + .since("INSERT VERSION") + .register(); reg.newType(ItemComponent.class, "itemcomponent", "itemComponent@s") .name("Item Component") .description("Represents the component of a dropped item.") @@ -58,7 +64,10 @@ public Inventory deserialize(@NotNull Gson gson, @NotNull JsonElement element) { .name("Item Container") .description("Represents an item container within an inventory (such as the armor container).") .since("1.0.0") - .toStringFunction(ItemContainer::toString) + .toStringFunction((itemContainer) -> + String.format("%s{capacity=%d}", + itemContainer.getClass().getSimpleName(), + itemContainer.getCapacity())) .serializer(new TypeSerializer<>() { @Override public JsonElement serialize(@NotNull Gson gson, @NotNull ItemContainer value) { From 2c42deee08a105a73bdf28be430a206fe924a37e Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 21:23:20 -0800 Subject: [PATCH 08/28] EffEntityAttitude - fix NPE --- .../plugin/elements/effects/entity/EffEntityAttitude.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityAttitude.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityAttitude.java index f275743f..8dd25629 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityAttitude.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffEntityAttitude.java @@ -81,7 +81,12 @@ protected void execute(@NotNull TriggerContext ctx) { EntityUtils.clearMarkedEntity(npcEntity, target); // Override attitude - worldSupport.overrideAttitude(targetRef, attitude, durationSeconds); + try { + worldSupport.overrideAttitude(targetRef, attitude, durationSeconds); + } catch (NullPointerException ignored) { + // If the entity cannot have an attitude adjustment, it throws NPE + // Appears there is no way to pre check this + } } } } From d3488dd14e840095ef45e97ba2d5f5536adaaab8 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 21:23:35 -0800 Subject: [PATCH 09/28] Window/Page stuff --- .../elements/effects/EffectHandler.java | 4 ++ .../effects/player/EffCloseWindows.java | 63 +++++++++++++++++ .../elements/effects/player/EffOpenPage.java | 69 +++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffCloseWindows.java create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffOpenPage.java diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java index b837c637..f4209932 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java @@ -24,9 +24,11 @@ import com.github.skriptdev.skript.plugin.elements.effects.other.EffSendMessage; import com.github.skriptdev.skript.plugin.elements.effects.other.EffSendTitle; import com.github.skriptdev.skript.plugin.elements.effects.player.EffBan; +import com.github.skriptdev.skript.plugin.elements.effects.player.EffCloseWindows; import com.github.skriptdev.skript.plugin.elements.effects.player.EffConnect; import com.github.skriptdev.skript.plugin.elements.effects.player.EffKick; import com.github.skriptdev.skript.plugin.elements.effects.player.EffOpenItemContainer; +import com.github.skriptdev.skript.plugin.elements.effects.player.EffOpenPage; import com.github.skriptdev.skript.plugin.elements.effects.server.EffRemoveMapMarker; import com.github.skriptdev.skript.plugin.elements.effects.server.EffServerShutdown; import com.github.skriptdev.skript.plugin.elements.effects.world.EffChunkLoadAsync; @@ -68,9 +70,11 @@ public static void register(SkriptRegistration registration) { // PLAYER EffBan.register(registration); + EffCloseWindows.register(registration); EffConnect.register(registration); EffKick.register(registration); EffOpenItemContainer.register(registration); + EffOpenPage.register(registration); // SERVER EffRemoveMapMarker.register(registration); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffCloseWindows.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffCloseWindows.java new file mode 100644 index 00000000..697c4126 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffCloseWindows.java @@ -0,0 +1,63 @@ +package com.github.skriptdev.skript.plugin.elements.effects.player; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.protocol.packets.interface_.Page; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import io.github.syst3ms.skriptparser.lang.Effect; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EffCloseWindows extends Effect { + + public static void register(SkriptRegistration reg) { + reg.newEffect(EffCloseWindows.class, "close [all] [open] windows of %players%") + .name("Close Windows") + .description("Close all open windows/pages of a player.") + .examples("close open windows of player") + .since("INSERT VERSION") + .register(); + } + + private Expression players; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.players = (Expression) expressions[0]; + return true; + } + + @Override + protected void execute(@NotNull TriggerContext ctx) { + for (Player player : this.players.getArray(ctx)) { + Ref reference = player.getReference(); + if (reference == null) continue; + + Runnable inWorld = () -> { + Store store = reference.getStore(); + player.getWindowManager().closeAllWindows(reference, store); + player.getPageManager().setPage(reference, store, Page.None, false); + }; + + World world = player.getWorld(); + if (world == null) continue; + if (world.isInThread()) { + inWorld.run(); + } else { + world.execute(inWorld); + } + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "close all open windows of " + this.players.toString(ctx, debug); + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffOpenPage.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffOpenPage.java new file mode 100644 index 00000000..55db1532 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffOpenPage.java @@ -0,0 +1,69 @@ +package com.github.skriptdev.skript.plugin.elements.effects.player; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.protocol.packets.interface_.Page; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; +import io.github.syst3ms.skriptparser.lang.Effect; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EffOpenPage extends Effect { + + public static void register(SkriptRegistration reg) { + reg.newEffect(EffOpenPage.class, "open page %page% to %players%") + .name("Open Page") + .description("Opens a page to the specified players.") + .examples("open page inventory to player", + "open page map to all players") + .since("INSERT VERSION") + .register(); + } + + private Expression page; + private Expression players; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.page = (Expression) expressions[0]; + this.players = (Expression) expressions[1]; + return true; + } + + @Override + protected void execute(@NotNull TriggerContext ctx) { + Page page = this.page.getSingle(ctx).orElse(null); + if (page == null || page == Page.Custom) return; + + for (Player player : this.players.getArray(ctx)) { + Ref reference = player.getReference(); + if (reference == null) continue; + + Runnable inWorld = () -> { + Store store = reference.getStore(); + player.getPageManager().setPage(reference, store, page, true); + }; + + World world = player.getWorld(); + if (world == null) continue; + + if (world.isInThread()) { + inWorld.run(); + } else { + world.execute(inWorld); + } + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "open page " + this.page.toString(ctx, debug) + " to " + this.players.toString(ctx, debug); + } + +} From 79dceb3f7198b21ccb038cc84254e212fa23398a Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 22:01:55 -0800 Subject: [PATCH 10/28] SecSpawnNPC - fix multiple issues: - fix errors when doing things to the entity in the section (this is because they're not yet actually an entity/reference - fix execution not working after first run --- .../plugin/elements/sections/SecSpawnNPC.java | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java index 08dc7a5c..f30d0cfb 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java @@ -32,10 +32,10 @@ public class SecSpawnNPC extends CodeSection { public record SpawnMobContext(Entity entity) implements TriggerContext { @Override - public String getName() { - return "spawn_mob"; - } + public String getName() { + return "spawn_mob"; } + } public static void register(SkriptRegistration registration) { registration.newSection(SecSpawnNPC.class, "spawn [a|an] %npcrole% at %location%") @@ -100,33 +100,35 @@ public Optional walk(@NotNull TriggerContext ctx) { AtomicReference vars = new AtomicReference<>(); VariableMap variableMap = Variables.copyLocalVariables(ctx); vars.set(variableMap); + Variables.clearLocalVariables(ctx); + + NPCPlugin.get().spawnEntity(store, roleSingle.get().index(), location.getPosition().clone(), rotation, null, null, + (npcEntity, entityStoreRef, entityStoreStore) -> { + SpawnMobContext spawnMobContext = new SpawnMobContext(npcEntity); - NPCPlugin.get().spawnEntity(store, roleSingle.get().index(), location.getPosition().clone(), rotation, null, (npcEntity, _, _) -> { - SpawnMobContext spawnMobContext = new SpawnMobContext(npcEntity); + // Copy the locals from the previous trigger into this context + Variables.setLocalVariables(spawnMobContext, vars.get()); - // Copy the locals from the previous trigger into this context - Variables.setLocalVariables(spawnMobContext, vars.get()); + firstStatement.ifPresent(statement -> + Statement.runAll(statement, spawnMobContext)); - setNext(null); - firstStatement.ifPresent(statement -> - Statement.runAll(statement, spawnMobContext)); + // After that is run, copy them back + VariableMap map = Variables.copyLocalVariables(spawnMobContext); + vars.set(map); - // After that is run, copy them back - VariableMap map = Variables.copyLocalVariables(spawnMobContext); - vars.set(map); + // Clear locals from the no longer used SpawnMobContext + Variables.clearLocalVariables(spawnMobContext); - // Clear locals from the no longer used SpawnMobContext - Variables.clearLocalVariables(spawnMobContext); - }, (npcEntity, entityStoreRef, entityStoreStore) -> { - nextStatement.ifPresent(statement -> { - // Take the previous local variables and use them again in this context - Variables.setLocalVariables(ctx, vars.get()); - Statement.runAll(statement, ctx); + nextStatement.ifPresent(statement -> { + // Take the previous local variables and use them again in this context + Variables.setLocalVariables(ctx, vars.get()); + Statement.runAll(statement, ctx); + }); // Now we're done, we can clear them out Variables.clearLocalVariables(ctx); + vars.get().clearVariables(); }); - }); return Optional.empty(); } From c0703a37244b2e91e023a54fe1ee377074ec77b3 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 23:39:10 -0800 Subject: [PATCH 11/28] EffAttackOverrides - add --- .../elements/effects/EffectHandler.java | 2 + .../effects/entity/EffAttackOverrides.java | 71 +++++++++++++++++++ .../expressions/ExpressionHandler.java | 24 +++---- 3 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffAttackOverrides.java diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java index f4209932..9de4faad 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffectHandler.java @@ -3,6 +3,7 @@ import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.elements.effects.block.EffBreakBlock; import com.github.skriptdev.skript.plugin.elements.effects.block.EffDamageBlock; +import com.github.skriptdev.skript.plugin.elements.effects.entity.EffAttackOverrides; import com.github.skriptdev.skript.plugin.elements.effects.entity.EffDamage; import com.github.skriptdev.skript.plugin.elements.effects.entity.EffDropItem; import com.github.skriptdev.skript.plugin.elements.effects.entity.EffEntityAttitude; @@ -45,6 +46,7 @@ public static void register(SkriptRegistration registration) { EffDamageBlock.register(registration); // ENTITY + EffAttackOverrides.register(registration); EffDamage.register(registration); EffDropItem.register(registration); EffEntityAttitude.register(registration); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffAttackOverrides.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffAttackOverrides.java new file mode 100644 index 00000000..39419f79 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffAttackOverrides.java @@ -0,0 +1,71 @@ +package com.github.skriptdev.skript.plugin.elements.effects.entity; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.modules.interaction.interaction.config.Interaction; +import com.hypixel.hytale.server.npc.entities.NPCEntity; +import com.hypixel.hytale.server.npc.role.Role; +import com.hypixel.hytale.server.npc.role.support.CombatSupport; +import io.github.syst3ms.skriptparser.lang.Effect; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; + +public class EffAttackOverrides extends Effect { + + public static void register(SkriptRegistration reg) { + reg.newEffect(EffAttackOverrides.class, + "apply attack override %interaction% to %npcentities%", + "clear attack overrides of %npcentities%") + .name("NPC Attack Overrides") + .description("Applies an attack override to NPCs or clears their attack overrides.") + .examples("apply attack override Gun_Shoot to {_e}", + "clear attack overrides of {_e}") + .register(); + } + + private Expression interaction; + private Expression npcs; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + if (matchedPattern == 0) { + this.interaction = (Expression) expressions[0]; + this.npcs = (Expression) expressions[1]; + } else { + this.npcs = (Expression) expressions[0]; + } + return true; + } + + + @Override + protected void execute(@NotNull TriggerContext ctx) { + Interaction interaction = null; + if (this.interaction != null) { + interaction = this.interaction.getSingle(ctx).orElse(null); + } + + for (NPCEntity entity : this.npcs.getArray(ctx)) { + Role role = entity.getRole(); + assert role != null; + + CombatSupport combatSupport = role.getCombatSupport(); + if (interaction == null) { + combatSupport.clearAttackOverrides(); + } else { + combatSupport.addAttackOverride(interaction.getId()); + } + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + if (this.interaction != null) { + return "apply attack override " + this.interaction.toString(ctx, debug) + " to " + this.npcs.toString(ctx, debug); + } + return "clear attack overrides of " + this.npcs.toString(ctx, debug); + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java index a7a35739..daaca6d9 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/ExpressionHandler.java @@ -3,6 +3,7 @@ import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockAt; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockFluid; +import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockFluidLevel; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockHealth; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockIterator; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockRotation; @@ -10,37 +11,33 @@ import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockTint; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockTypeAtLocation; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockTypeOfBlock; -import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprBlockFluidLevel; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprHighestBlock; import com.github.skriptdev.skript.plugin.elements.expressions.block.ExprTargetBlockOfPlayer; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprActiveSlot; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntitiesInRadius; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityAttitude; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityComponents; -import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityModel; -import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityStamina; -import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprLockedTarget; -import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemQuality; -import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprValueWithin; -import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerDefenseLevel; -import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerMovementBaseSpeed; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityHeadRotation; -import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityScale; -import com.github.skriptdev.skript.plugin.elements.expressions.entityeffect.ExprActiveEntityEffectDuration; -import com.github.skriptdev.skript.plugin.elements.expressions.entityeffect.ExprActiveEntityEffects; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityHealth; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityModel; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityScale; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityStamina; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityStat; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityVelocity; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprHeldItem; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprLockedTarget; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprNPCType; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprName; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprTargetEntityOfEntity; +import com.github.skriptdev.skript.plugin.elements.expressions.entityeffect.ExprActiveEntityEffectDuration; import com.github.skriptdev.skript.plugin.elements.expressions.entityeffect.ExprActiveEntityEffectEffect; +import com.github.skriptdev.skript.plugin.elements.expressions.entityeffect.ExprActiveEntityEffects; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprInventory; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprInventoryAmountOfItems; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprInventorySlot; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprInventorySlots; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemContainer; +import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemQuality; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemStack; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemStackName; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemStackQuantity; @@ -63,6 +60,7 @@ import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprMessageProperties; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprUUID; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprUUIDRandom; +import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprValueWithin; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprVector3d; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprVector3f; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprVector3i; @@ -70,6 +68,8 @@ import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprChatMessage; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprGameMode; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerClientViewRadius; +import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerDefenseLevel; +import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerMovementBaseSpeed; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerMovementFlySpeed; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerMovementJumpForce; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerMovementMass; @@ -91,9 +91,9 @@ import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorld; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldCurrentMSPT; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldCurrentTPS; +import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldDateTime; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldOf; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldSpawn; -import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldDateTime; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldTPS; import com.github.skriptdev.skript.plugin.elements.expressions.world.ExprWorldTimeDurations; From 0ac02285df49ec906821a80979ca90d4f7a505d6 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Mon, 2 Mar 2026 23:43:03 -0800 Subject: [PATCH 12/28] Sections - reorganize --- .../elements/sections/SectionHandler.java | 22 +++++++++++++++---- .../{ => entity}/SecApplyStatModifier.java | 2 +- .../sections/{ => entity}/SecDropItem.java | 2 +- .../sections/{ => entity}/SecSpawnNPC.java | 2 +- .../sections/{ => player}/SecPlaySound.java | 2 +- .../{ => player}/SecSendNotification.java | 2 +- .../sections/{ => player}/SecSendTitle.java | 2 +- .../sections/{ => world}/SecCreateWorld.java | 2 +- .../{ => world}/SecExecuteInWorld.java | 2 +- .../sections/{ => world}/SecParticle.java | 2 +- 10 files changed, 27 insertions(+), 13 deletions(-) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => entity}/SecApplyStatModifier.java (98%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => entity}/SecDropItem.java (99%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => entity}/SecSpawnNPC.java (98%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => player}/SecPlaySound.java (98%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => player}/SecSendNotification.java (99%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => player}/SecSendTitle.java (99%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => world}/SecCreateWorld.java (99%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => world}/SecExecuteInWorld.java (97%) rename src/main/java/com/github/skriptdev/skript/plugin/elements/sections/{ => world}/SecParticle.java (99%) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java index cdd73c9e..53faa6fc 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SectionHandler.java @@ -1,23 +1,37 @@ package com.github.skriptdev.skript.plugin.elements.sections; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.github.skriptdev.skript.plugin.elements.sections.entity.SecApplyStatModifier; +import com.github.skriptdev.skript.plugin.elements.sections.entity.SecDropItem; +import com.github.skriptdev.skript.plugin.elements.sections.entity.SecSpawnNPC; +import com.github.skriptdev.skript.plugin.elements.sections.player.SecPlaySound; +import com.github.skriptdev.skript.plugin.elements.sections.player.SecSendNotification; +import com.github.skriptdev.skript.plugin.elements.sections.player.SecSendTitle; import com.github.skriptdev.skript.plugin.elements.sections.server.SecMapMarker; +import com.github.skriptdev.skript.plugin.elements.sections.world.SecCreateWorld; +import com.github.skriptdev.skript.plugin.elements.sections.world.SecExecuteInWorld; +import com.github.skriptdev.skript.plugin.elements.sections.world.SecParticle; public class SectionHandler { public static void register(SkriptRegistration registration) { + // ENTITY SecApplyStatModifier.register(registration); - SecCreateWorld.register(registration); SecDropItem.register(registration); - SecExecuteInWorld.register(registration); - SecParticle.register(registration); + SecSpawnNPC.register(registration); + + // PLAYER SecPlaySound.register(registration); SecSendNotification.register(registration); SecSendTitle.register(registration); - SecSpawnNPC.register(registration); // SERVER SecMapMarker.register(registration); + + // WORLD + SecCreateWorld.register(registration); + SecExecuteInWorld.register(registration); + SecParticle.register(registration); } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecApplyStatModifier.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecApplyStatModifier.java similarity index 98% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecApplyStatModifier.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecApplyStatModifier.java index f3cd9621..83c3a8ca 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecApplyStatModifier.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecApplyStatModifier.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.entity; import com.github.skriptdev.skript.api.hytale.utils.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecDropItem.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecDropItem.java index 1f92bfb1..2bbb4129 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecDropItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecDropItem.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.entity; import com.github.skriptdev.skript.api.hytale.utils.EntityUtils; import com.github.skriptdev.skript.api.skript.event.RefContext; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java similarity index 98% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java index f30d0cfb..e411833f 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSpawnNPC.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.entity; import com.github.skriptdev.skript.api.skript.registration.NPCRegistry; import com.hypixel.hytale.component.Store; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecPlaySound.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java similarity index 98% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecPlaySound.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java index 634852fe..d32ddf11 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecPlaySound.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.player; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendNotification.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendNotification.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendNotification.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendNotification.java index 9311101f..9fceb42e 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendNotification.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendNotification.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.player; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Store; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendTitle.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendTitle.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendTitle.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendTitle.java index e8670fc7..34f703cb 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecSendTitle.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecSendTitle.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.player; import com.github.skriptdev.skript.api.hytale.utils.EntityUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecCreateWorld.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecCreateWorld.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecCreateWorld.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecCreateWorld.java index f4b5aedb..b6452674 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecCreateWorld.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecCreateWorld.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.world; import com.github.skriptdev.skript.api.skript.event.WorldContext; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecExecuteInWorld.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecExecuteInWorld.java index 50a63288..975a5a5a 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecExecuteInWorld.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecExecuteInWorld.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.world; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.server.core.universe.world.World; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecParticle.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecParticle.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecParticle.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecParticle.java index 98c508d0..115982e9 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/SecParticle.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/world/SecParticle.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.sections; +package com.github.skriptdev.skript.plugin.elements.sections.world; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; From bf36243e73dfd18f6e46e57731474dff55a3cd61 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 08:16:06 -0800 Subject: [PATCH 13/28] ExprEntityHealth - fix setting for a list of entities --- .../expressions/entity/ExprEntityHealth.java | 72 +++++++++---------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java index c7829eb0..bcbd7b59 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprEntityHealth.java @@ -65,51 +65,49 @@ public Optional[]> acceptsChange(@NotNull ChangeMode mode) { @Override public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { - Optional single = getOwner().getSingle(ctx); - if (single.isEmpty()) return; + for (LivingEntity entity : getOwner().getArray(ctx)) { + World world = entity.getWorld(); + if (world == null) continue; - LivingEntity entity = single.get(); - World world = entity.getWorld(); - if (world == null) return; + Runnable healthRunnable = () -> { - Runnable healthRunnable = () -> { + EntityStatMap statMap = EntityUtils.getEntityStatMap(entity); + if (statMap == null) return; - EntityStatMap statMap = EntityUtils.getEntityStatMap(entity); - if (statMap == null) return; - - if (changeMode == ChangeMode.RESET) { - statMap.resetStatValue(HEALTH_STAT_INDEX); - return; - } - - float newValue; - if (changeWith.length > 0 && changeWith[0] instanceof Number number) { - newValue = number.floatValue(); - } else { - newValue = 0f; - } - - if (changeMode != ChangeMode.SET) { - EntityStatValue healthStat = statMap.get(HEALTH_STAT_INDEX); - if (healthStat == null) return; - float oldHealthValue = healthStat.get(); + if (changeMode == ChangeMode.RESET) { + statMap.resetStatValue(HEALTH_STAT_INDEX); + return; + } - if (changeMode == ChangeMode.ADD) { - newValue += oldHealthValue; - } else if (changeMode == ChangeMode.REMOVE) { - newValue = oldHealthValue - newValue; - } else if (changeMode == ChangeMode.DELETE) { + float newValue; + if (changeWith.length > 0 && changeWith[0] instanceof Number number) { + newValue = number.floatValue(); + } else { newValue = 0f; } - } - statMap.setStatValue(HEALTH_STAT_INDEX, newValue); - }; + if (changeMode != ChangeMode.SET) { + EntityStatValue healthStat = statMap.get(HEALTH_STAT_INDEX); + if (healthStat == null) return; + float oldHealthValue = healthStat.get(); + + if (changeMode == ChangeMode.ADD) { + newValue += oldHealthValue; + } else if (changeMode == ChangeMode.REMOVE) { + newValue = oldHealthValue - newValue; + } else if (changeMode == ChangeMode.DELETE) { + newValue = 0f; + } + } + + statMap.setStatValue(HEALTH_STAT_INDEX, newValue); + }; - if (world.isInThread()) { - healthRunnable.run(); - } else { - world.execute(healthRunnable); + if (world.isInThread()) { + healthRunnable.run(); + } else { + world.execute(healthRunnable); + } } } From c9b7e722fecc9dc88d59844deeca73023b501008 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 10:33:03 -0800 Subject: [PATCH 14/28] EvtEntityDamage - fix event not being cancellable --- .../events/entity/EvtEntityDamage.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDamage.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDamage.java index d934ab37..788d4fa5 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDamage.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDamage.java @@ -8,6 +8,8 @@ import com.hypixel.hytale.component.CommandBuffer; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.component.dependency.Dependency; +import com.hypixel.hytale.component.dependency.RootDependency; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.modules.entity.damage.Damage; @@ -23,25 +25,27 @@ import io.github.syst3ms.skriptparser.parsing.ParseContext; import org.jetbrains.annotations.NotNull; +import java.util.Collections; +import java.util.Set; + public class EvtEntityDamage extends SkriptEvent { public static void register(SkriptRegistration reg) { reg.newEvent(EvtEntityDamage.class, "entity damage", "entity damaged") .setHandledContexts(EntityDamageContext.class) .name("Entity Damage") - .description("Called when an entity takes damage.", - "**NOTE**: This event is cancellable but doesn't appear to work when trying to cancel.") + .description("Called when an entity takes damage.") .examples("on entity damage:", "\tbroadcast \"Poor %context-victim%\" was damaged by %context-damage-amount%") .since("1.0.0") .register(); reg.newSingleContextValue(EntityDamageContext.class, Entity.class, - "victim", EntityDamageContext::getVictim) + "victim", EntityDamageContext::getVictim) .description("The entity that was damaged.") .register(); reg.newSingleContextValue(EntityDamageContext.class, Entity.class, - "attacker", EntityDamageContext::getAttacker) + "attacker", EntityDamageContext::getAttacker) .description("The entity that dealt the damage.") .register(); reg.newSingleContextValue(EntityDamageContext.class, Float.class, @@ -50,11 +54,11 @@ public static void register(SkriptRegistration reg) { .addSetter(EntityDamageContext::setDamage) .register(); reg.newSingleContextValue(EntityDamageContext.class, Damage.Source.class, - "damage-source", EntityDamageContext::getDamageSource) + "damage-source", EntityDamageContext::getDamageSource) .description("The source of the damage.") .register(); reg.newSingleContextValue(EntityDamageContext.class, DamageCause.class, - "damage-cause", EntityDamageContext::getDamageCause) + "damage-cause", EntityDamageContext::getDamageCause) .description("The cause of the damage.") .register(); } @@ -93,8 +97,7 @@ public Entity getAttacker() { if (source instanceof Damage.EntitySource entitySource) { Player player = this.store.getComponent(entitySource.getRef(), Player.getComponentType()); if (player != null) return player; - NPCEntity npc = this.store.getComponent(entitySource.getRef(), NPCEntity.getComponentType()); - if (npc != null) return npc; + return this.store.getComponent(entitySource.getRef(), NPCEntity.getComponentType()); } return null; } @@ -139,6 +142,11 @@ public void setCancelled(boolean cancelled) { private static class EntityDamageSystem extends DamageSystems.ApplyDamage { + @Override + public @NotNull Set> getDependencies() { + return Collections.singleton(RootDependency.first()); + } + @SuppressWarnings("DataFlowIssue") @Override public void handle(int index, @NotNull ArchetypeChunk archetypeChunk, From 6d0277900cb9031e0feee28abd49ba208c51060c Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 10:57:49 -0800 Subject: [PATCH 15/28] EvtEntityDeath - fix priority --- .../events/entity/EvtEntityDeath.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java index bea0612f..29d31726 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java @@ -4,8 +4,11 @@ import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.ComponentAccessor; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.component.dependency.Dependency; +import com.hypixel.hytale.component.dependency.RootDependency; import com.hypixel.hytale.component.query.Query; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.asset.type.item.config.Item; @@ -30,7 +33,9 @@ import org.jetbrains.annotations.Nullable; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Set; public class EvtEntityDeath extends SkriptEvent { @@ -123,6 +128,11 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { private static class EntityDeathListener extends DeathSystems.OnDeathSystem { + @Override + public @NotNull Set> getDependencies() { + return Collections.singleton(RootDependency.first()); + } + @SuppressWarnings("DataFlowIssue") @Override public void onComponentAdded(@NotNull Ref ref, @NotNull DeathComponent deathComponent, @@ -204,8 +214,8 @@ public boolean isShowDeathMenu() { } public void setShowDeathMenu(boolean showDeathMenu) { - // this.component.setShowDeathMenu(showDeathMenu); (doesn't seem to work) - // So let's respawn instead + this.component.setShowDeathMenu(showDeathMenu); + // We have to respawn the player or they get locked in a death pose if (!showDeathMenu && this.getVictim() instanceof Player player) { Ref reference = player.getReference(); DeathComponent.respawn(reference.getStore(), reference); @@ -218,6 +228,13 @@ public Message getDeathMessage() { public void setDeathMessage(Message deathMessage) { this.component.setDeathMessage(deathMessage); + // Hytale doesn't seem to actually use the `getDeathMessge` in the death screen + this.component.getDeathInfo().setSource(new Damage.Source() { + @Override + public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, @NotNull ComponentAccessor componentAccessor) { + return deathMessage; + } + }); } public String getDeathMessageString() { @@ -225,7 +242,7 @@ public String getDeathMessageString() { } public void setDeathMessageString(String deathMessage) { - this.component.setDeathMessage(Message.raw(deathMessage)); + setDeathMessage(Message.raw(deathMessage)); } @Override From e1b6ca5be450678f05f3d83547b36ff8ba5308c8 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 11:23:30 -0800 Subject: [PATCH 16/28] ExprHeldItem - fix deleting --- .../plugin/elements/expressions/entity/ExprHeldItem.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprHeldItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprHeldItem.java index dfbb6b41..93d4a6d2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprHeldItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprHeldItem.java @@ -71,9 +71,10 @@ public Optional[]> acceptsChange(@NotNull ChangeMode mode) { @SuppressWarnings("ConstantValue") @Override public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { - if (changeWith == null) return; - - ItemStack itemStack = ((ItemStack) changeWith[0]); + ItemStack itemStack = ItemStack.EMPTY; + if (changeWith != null && changeWith.length > 0 && changeWith[0] instanceof ItemStack stack) { + itemStack = stack; + } for (LivingEntity livingEntity : this.entities.getArray(ctx)) { Inventory inventory = livingEntity.getInventory(); From 6cd7921afe29e7fcc9530f755cc9776997c4c63b Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 12:03:17 -0800 Subject: [PATCH 17/28] EvtEntityDeath - checkstyle --- .../skript/plugin/elements/events/entity/EvtEntityDeath.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java index 29d31726..8444d96a 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java @@ -231,7 +231,8 @@ public void setDeathMessage(Message deathMessage) { // Hytale doesn't seem to actually use the `getDeathMessge` in the death screen this.component.getDeathInfo().setSource(new Damage.Source() { @Override - public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, @NotNull ComponentAccessor componentAccessor) { + public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, + @NotNull ComponentAccessor componentAccessor) { return deathMessage; } }); From e6b8b2d184f7d8c601f97f4ff3cd3cf831a3fcf5 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 12:59:46 -0800 Subject: [PATCH 18/28] EvtEntityDeath - some fixes/cleanup --- .../events/entity/EvtEntityDeath.java | 89 +++++++++++++------ 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java index 8444d96a..b2706d91 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java @@ -57,12 +57,14 @@ public static void register(SkriptRegistration reg) { .register(); reg.newSingleContextValue(EntityDeathContext.class, - Entity.class, "victim", EntityDeathContext::getVictim) + Entity.class, "victim", EntityDeathContext::getVictim) .description("The entity that died.") + .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) .register(); reg.newSingleContextValue(EntityDeathContext.class, - Entity.class, "attacker", EntityDeathContext::getAttacker) + Entity.class, "attacker", EntityDeathContext::getAttacker) .description("The entity that killed the victim.") + .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) .register(); reg.addSingleContextValue(EntityDeathContext.class, Damage.Source.class, "damage-source", EntityDeathContext::getDamageSource); @@ -71,7 +73,7 @@ public static void register(SkriptRegistration reg) { reg.addSingleContextValue(EntityDeathContext.class, Damage.class, "death-info", EntityDeathContext::getDamage); reg.newListContextValue(EntityDeathContext.class, - Item.class, "lost-items", EntityDeathContext::getItemsLostOnDeath) + Item.class, "lost-items", EntityDeathContext::getItemsLostOnDeath) .description("The Item types of the ItemStacks lost on death.") .register(); reg.newListContextValue(EntityDeathContext.class, @@ -82,6 +84,8 @@ public static void register(SkriptRegistration reg) { .register(); reg.newSingleContextValue(EntityDeathContext.class, Boolean.class, "show-death-menu", EntityDeathContext::isShowDeathMenu) + .description("Whether the death menu should be shown to the player. " + + "Disabling this will respawn the player.") .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) .addSetter(EntityDeathContext::setShowDeathMenu) .register(); @@ -162,31 +166,31 @@ public void onComponentAdded(@NotNull Ref ref, @NotNull DeathCompon } @SuppressWarnings("DataFlowIssue") - private record EntityDeathContext(int pattern, Entity victim, DeathComponent component) - implements TriggerContext, WorldContext { + private static class EntityDeathContext implements TriggerContext, WorldContext { + + private final int pattern; + private final Entity victim; + private final DeathComponent component; + private final OverridingDamageSource damageSource; + + EntityDeathContext(int pattern, Entity victim, DeathComponent component) { + this.pattern = pattern; + this.victim = victim; + this.component = component; + this.damageSource = new OverridingDamageSource(component.getDeathInfo().getSource()); + this.component.getDeathInfo().setSource(this.damageSource); + } public Entity getVictim() { return this.victim; } public Entity getAttacker() { - Entity attacker = null; - if (this.component.getDeathInfo().getSource() instanceof Damage.EntitySource entitySource) { - Ref attackerRef = entitySource.getRef(); - Store store = attackerRef.getStore(); - Player player = store.getComponent(attackerRef, Player.getComponentType()); - if (player != null) { - attacker = player; - } else { - NPCEntity npc = store.getComponent(attackerRef, NPCEntity.getComponentType()); - if (npc != null) attacker = npc; - } - } - return attacker; + return this.damageSource.getAttacker(); } public Damage.Source getDamageSource() { - return this.component.getDeathInfo().getSource(); + return this.damageSource.parentSource; } public DamageCause getDamageCause() { @@ -228,14 +232,7 @@ public Message getDeathMessage() { public void setDeathMessage(Message deathMessage) { this.component.setDeathMessage(deathMessage); - // Hytale doesn't seem to actually use the `getDeathMessge` in the death screen - this.component.getDeathInfo().setSource(new Damage.Source() { - @Override - public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, - @NotNull ComponentAccessor componentAccessor) { - return deathMessage; - } - }); + this.damageSource.setDeathMessage(deathMessage); } public String getDeathMessageString() { @@ -257,4 +254,42 @@ public String getName() { } } + public static class OverridingDamageSource implements Damage.Source { + + private final Damage.Source parentSource; + private Message deathMessage; + + public OverridingDamageSource(Damage.Source parentSource) { + this.parentSource = parentSource; + } + + @Override + public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, @NotNull ComponentAccessor componentAccessor) { + if (this.deathMessage != null) return this.deathMessage; + return this.parentSource.getDeathMessage(info, targetRef, componentAccessor); + } + + public void setDeathMessage(Message deathMessage) { + this.deathMessage = deathMessage; + } + + @SuppressWarnings("DataFlowIssue") + public Entity getAttacker() { + Entity attacker = null; + if (this.parentSource instanceof Damage.EntitySource entitySource) { + Ref attackerRef = entitySource.getRef(); + Store store = attackerRef.getStore(); + Player player = store.getComponent(attackerRef, Player.getComponentType()); + if (player != null) { + attacker = player; + } else { + NPCEntity npc = store.getComponent(attackerRef, NPCEntity.getComponentType()); + if (npc != null) attacker = npc; + } + } + return attacker; + } + + } + } From 72cf52aad039bbe525ad3777be57c084317e78d4 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 13:00:36 -0800 Subject: [PATCH 19/28] EvtEntityDeath - checkstyle --- .../skript/plugin/elements/events/entity/EvtEntityDeath.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java index b2706d91..3be5ef1c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/entity/EvtEntityDeath.java @@ -264,7 +264,8 @@ public OverridingDamageSource(Damage.Source parentSource) { } @Override - public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, @NotNull ComponentAccessor componentAccessor) { + public @NotNull Message getDeathMessage(@NotNull Damage info, @NotNull Ref targetRef, + @NotNull ComponentAccessor componentAccessor) { if (this.deathMessage != null) return this.deathMessage; return this.parentSource.getDeathMessage(info, targetRef, componentAccessor); } From ce6be323127b27ceb02c1b4ba35e566d9e8daa38 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 21:49:13 -0800 Subject: [PATCH 20/28] SecSpawnNPC - fix again --- .../plugin/elements/sections/entity/SecSpawnNPC.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java index e411833f..b7092f8c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java @@ -113,21 +113,18 @@ public Optional walk(@NotNull TriggerContext ctx) { Statement.runAll(statement, spawnMobContext)); // After that is run, copy them back - VariableMap map = Variables.copyLocalVariables(spawnMobContext); - vars.set(map); + VariableMap sectionVariables = Variables.copyLocalVariables(spawnMobContext); // Clear locals from the no longer used SpawnMobContext Variables.clearLocalVariables(spawnMobContext); nextStatement.ifPresent(statement -> { // Take the previous local variables and use them again in this context - Variables.setLocalVariables(ctx, vars.get()); + Variables.setLocalVariables(ctx, sectionVariables); Statement.runAll(statement, ctx); - }); // Now we're done, we can clear them out Variables.clearLocalVariables(ctx); - vars.get().clearVariables(); }); return Optional.empty(); From b437a9192029960d1d82efc6bb3a103daec36425 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 21:57:18 -0800 Subject: [PATCH 21/28] test fixes --- .../skript/tests/elements/hyskript/effects/entity/EffTame.sk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/skript/tests/elements/hyskript/effects/entity/EffTame.sk b/src/test/skript/tests/elements/hyskript/effects/entity/EffTame.sk index 54101af7..80573c5a 100644 --- a/src/test/skript/tests/elements/hyskript/effects/entity/EffTame.sk +++ b/src/test/skript/tests/elements/hyskript/effects/entity/EffTame.sk @@ -5,5 +5,4 @@ test "EffTame": tame {_e} wait 5 tick - # assert {_e} is tamed with "The sheep should be tamed now, but found '%npc role of {_e}%'" - # TODO broken, chunk loading issue + assert {_e} is tamed with "The sheep should be tamed now, but found '%npc role of {_e}%'" From 45f73420db366240605d079a3017301adc48bbcf Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 22:00:59 -0800 Subject: [PATCH 22/28] TestRunner - force load our starting chunk - i dont think this is fully working --- .../skript/api/skript/testing/TestRunner.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java b/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java index b4665b9c..d993be45 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java @@ -2,10 +2,14 @@ import com.github.skriptdev.skript.api.skript.testing.elements.EvtTest.TestContext; import com.github.skriptdev.skript.api.utils.Utils; +import com.hypixel.hytale.math.util.ChunkUtil; +import com.hypixel.hytale.math.vector.Transform; +import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.universe.Universe; import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider; import com.hypixel.hytale.server.core.util.MessageUtil; import fi.sulku.hytale.TinyMsg; import io.github.syst3ms.skriptparser.lang.Statement; @@ -23,6 +27,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; +import java.util.UUID; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -51,7 +56,17 @@ public void start() { if (this.world.isPaused()) this.world.setPaused(false); // Run our tests in the world to make sure we have access to blocks/entities - this.world.execute(runTestsRunnable); + this.world.execute(() -> { + ISpawnProvider spawnProvider = this.world.getWorldConfig().getSpawnProvider(); + Transform spawnPoint = spawnProvider.getSpawnPoint(this.world, UUID.randomUUID()); + Vector3i pos = spawnPoint.getPosition().toVector3i(); + long index = ChunkUtil.indexChunkFromBlock(pos.getX(), pos.getZ()); + this.world.getChunkAsync(index).thenApply(worldChunk -> { + worldChunk.addKeepLoaded(); + runTestsRunnable.run(); + return null; + }); + }); }; // Delay start to make sure the server has finished loading From 5a923e5c92baad4bf8d71cc30bf893e64a98f1bd Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Tue, 3 Mar 2026 22:38:15 -0800 Subject: [PATCH 23/28] SecPlaySound - fixes + examples --- .../sections/player/SecPlaySound.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java index d32ddf11..22abdfb1 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/player/SecPlaySound.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.sections.player; +import com.github.skriptdev.skript.api.hytale.utils.PlayerUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; @@ -7,6 +8,7 @@ import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.protocol.SoundCategory; import com.hypixel.hytale.server.core.asset.type.soundevent.config.SoundEvent; +import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.universe.PlayerRef; import com.hypixel.hytale.server.core.universe.Universe; import com.hypixel.hytale.server.core.universe.world.SoundUtil; @@ -40,13 +42,23 @@ public static void register(SkriptRegistration reg) { " - `3d` = Whether the sound should be 3D ([optional, `location` is required for this] default: false).", " - `sound-category` = The category of the sound ([optional] default: ambient).") .experimental("This seems a bit messy/buggy and may change in the future.") + .examples("play sound SFX_Bear_Grizzly_Hurt:", + "\tto-players: event-player", + "\tvolume: 5.0", + "\tsound-category: Ambient", + "", + "play sound SFX_Wood_Walk:", + "\tlocation: location of player", + "\tvolume: 5.0", + "\tpitch: 0.5", + "\tsound-category: SFX") .since("1.0.0") .register(); } SectionConfiguration sectionConfig = new SectionConfiguration.Builder() .addOptionalExpression("to-players", PlayerRef.class, true) - .addOptionalKey("location") + .addOptionalExpression("location", Location.class, false) .addOptionalLiteral("volume", Number.class) .addOptionalLiteral("pitch", Number.class) .addOptionalLiteral("3d", Boolean.class) @@ -76,15 +88,21 @@ public Optional walk(@NotNull TriggerContext ctx) { int soundIndex = SoundEvent.getAssetMap().getIndex(soundEvent.getId()); if (soundIndex < 0) return nextStatement; - Location location = this.sectionConfig.getValue("location", Location.class).orElse(null); - Expression playerExpr = this.sectionConfig.getExpression("to-players", PlayerRef.class).orElse(null); + Expression playerExpr = this.sectionConfig.getExpression("to-players", Object.class).orElse(null); + + Location location = null; + Expression locExpr = this.sectionConfig.getExpression("location", Location.class).orElse(null); + if (locExpr != null) { + location = locExpr.getSingle(ctx).orElse(null); + } + Number volume = this.sectionConfig.getValue("volume", Number.class).orElse(1.0f); Number pitch = this.sectionConfig.getValue("pitch", Number.class).orElse(1.0f); boolean is3d = this.sectionConfig.getValue("3d", Boolean.class).orElse(false); SoundCategory soundCategory = this.sectionConfig.getValue("sound-category", SoundCategory.class).orElse(SoundCategory.Ambient); if (playerExpr != null) { - PlayerRef[] playerRefs = playerExpr.getArray(ctx); + Object[] playerRefs = playerExpr.getArray(ctx); playSoundToPlayer(playerRefs, location, soundIndex, soundCategory, is3d, volume.floatValue(), pitch.floatValue()); } else if (location != null) { playSoundAtLocation(location, soundIndex, soundCategory, is3d, volume.floatValue(), pitch.floatValue()); @@ -97,19 +115,29 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return ""; } - public void playSoundToPlayer(@NotNull PlayerRef[] players, @Nullable Location location, int soundEvent, + public void playSoundToPlayer(@NotNull Object[] players, @Nullable Location location, int soundEvent, SoundCategory category, boolean is3d, float volume, float pitch) { - for (PlayerRef player : players) { + for (Object o : players) { + PlayerRef playerRef; + if (o instanceof PlayerRef ref) { + playerRef = ref; + } else if (o instanceof Player player) { + playerRef = PlayerUtils.getPlayerRef(player); + } else { + continue; + } + if (playerRef == null) continue; + if (is3d && location != null) { Vector3d pos = location.getPosition(); - Ref reference = player.getReference(); + Ref reference = playerRef.getReference(); if (reference == null || !reference.isValid()) continue; Store store = reference.getStore(); SoundUtil.playSoundEvent3dToPlayer(reference, soundEvent, category, pos.getX(), pos.getY(), pos.getZ(), volume, pitch, store); } else { - SoundUtil.playSoundEvent2dToPlayer(player, soundEvent, category, volume, pitch); + SoundUtil.playSoundEvent2dToPlayer(playerRef, soundEvent, category, volume, pitch); } } } From e959c2776420aa583b01e48cdd63bc9b97158b5c Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Wed, 4 Mar 2026 06:30:56 -0800 Subject: [PATCH 24/28] SecSpawnNPC - fix... AGAIN --- .../skript/plugin/elements/sections/entity/SecSpawnNPC.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java index b7092f8c..d74df389 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/sections/entity/SecSpawnNPC.java @@ -105,6 +105,7 @@ public Optional walk(@NotNull TriggerContext ctx) { NPCPlugin.get().spawnEntity(store, roleSingle.get().index(), location.getPosition().clone(), rotation, null, null, (npcEntity, entityStoreRef, entityStoreStore) -> { SpawnMobContext spawnMobContext = new SpawnMobContext(npcEntity); + setNext(null); // Copy the locals from the previous trigger into this context Variables.setLocalVariables(spawnMobContext, vars.get()); From a72f62e7f3083996a7499867edf3921063a3908b Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Wed, 4 Mar 2026 06:31:34 -0800 Subject: [PATCH 25/28] EvtTest - add event-location --- .../skript/api/skript/testing/TestRunner.java | 26 ++++++++++--------- .../api/skript/testing/elements/EvtTest.java | 14 +++++++++- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java b/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java index d993be45..7f61e754 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/testing/TestRunner.java @@ -9,6 +9,7 @@ import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.universe.Universe; import com.hypixel.hytale.server.core.universe.world.World; +import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk; import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider; import com.hypixel.hytale.server.core.util.MessageUtil; import fi.sulku.hytale.TinyMsg; @@ -42,10 +43,6 @@ public class TestRunner { @SuppressWarnings("DataFlowIssue") public void start() { - Runnable runTestsRunnable = () -> { - Utils.log("Running tests in world 'default'..."); - runTests(); - }; Runnable loadTestsRunnable = () -> { Utils.log("Testing has started!"); Utils.log("Loading test scripts..."); @@ -60,12 +57,17 @@ public void start() { ISpawnProvider spawnProvider = this.world.getWorldConfig().getSpawnProvider(); Transform spawnPoint = spawnProvider.getSpawnPoint(this.world, UUID.randomUUID()); Vector3i pos = spawnPoint.getPosition().toVector3i(); - long index = ChunkUtil.indexChunkFromBlock(pos.getX(), pos.getZ()); - this.world.getChunkAsync(index).thenApply(worldChunk -> { - worldChunk.addKeepLoaded(); - runTestsRunnable.run(); - return null; - }); + + + for (int x = pos.getX() - 64; x < pos.getX() + 64; x += 32) { + for (int z = pos.getZ() - 64; z < pos.getZ() + 64; z += 32) { + long index = ChunkUtil.indexChunkFromBlock(x, z); + WorldChunk chunk = this.world.getChunk(index); + chunk.addKeepLoaded(); + } + } + Utils.log("Running tests in world 'default'..."); + runTests(this.world, pos); }); }; @@ -78,7 +80,7 @@ private void loadTests() { loadScripts(path); } - private void runTests() { + private void runTests(World world, Vector3i pos) { // Catch exceptions and treat them as failures Statement.setExceptionHandler(e -> this.testResults.addFailure("Exception", @@ -86,7 +88,7 @@ private void runTests() { // Run all the test triggers for (Trigger allTrigger : TriggerMap.getAllTriggers()) { - TestContext context = new TestContext(this.testResults, this.world); + TestContext context = new TestContext(this.testResults, world, pos); Statement.runAll(allTrigger, context); Variables.clearLocalVariables(context); } diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/testing/elements/EvtTest.java b/src/main/java/com/github/skriptdev/skript/api/skript/testing/elements/EvtTest.java index 1cb48831..69566f36 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/testing/elements/EvtTest.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/testing/elements/EvtTest.java @@ -4,6 +4,9 @@ import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.api.skript.testing.TestResults; import com.github.skriptdev.skript.api.utils.Utils; +import com.hypixel.hytale.math.vector.Location; +import com.hypixel.hytale.math.vector.Vector3f; +import com.hypixel.hytale.math.vector.Vector3i; import com.hypixel.hytale.server.core.universe.world.World; import io.github.syst3ms.skriptparser.lang.Expression; import io.github.syst3ms.skriptparser.lang.TriggerContext; @@ -19,6 +22,9 @@ public static void register(SkriptRegistration reg) { .setHandledContexts(TestContext.class) .noDoc() .register(); + + reg.addSingleContextValue(TestContext.class, Location.class, + "location",TestContext::getLocation); } private String testSubject; @@ -47,10 +53,12 @@ public static final class TestContext implements WorldContext { private final TestResults testResults; private String testSubject; private final World world; + private final Location location; - public TestContext(TestResults testResults, World world) { + public TestContext(TestResults testResults, World world, Vector3i pos) { this.testResults = testResults; this.world = world; + this.location = new Location(world.getName(), pos.toVector3d(), Vector3f.ZERO); } public void setTestSubject(String testSubject) { @@ -70,6 +78,10 @@ public World getWorld() { return this.world; } + public Location getLocation() { + return this.location; + } + @Override public String getName() { return "test context"; From 04a01f73507382369b64ee2817db7929ad5dcee5 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Wed, 4 Mar 2026 06:51:28 -0800 Subject: [PATCH 26/28] Add converters/comps to fix NPCRole - ModelAsset issues --- .../plugin/elements/types/DefaultComparators.java | 12 ++++++++++++ .../plugin/elements/types/DefaultConverters.java | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultComparators.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultComparators.java index e706a234..9771f994 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultComparators.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultComparators.java @@ -1,7 +1,9 @@ package com.github.skriptdev.skript.plugin.elements.types; +import com.github.skriptdev.skript.api.skript.registration.NPCRegistry; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.item.config.Item; +import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset; import com.hypixel.hytale.server.core.inventory.Inventory; import com.hypixel.hytale.server.core.inventory.ItemStack; import com.hypixel.hytale.server.core.inventory.container.ItemContainer; @@ -15,10 +17,20 @@ public class DefaultComparators { public static void register() { + assetStore(); block(); inventory(); } + private static void assetStore() { + Comparators.registerComparator(NPCRegistry.NPCRole.class, ModelAsset.class, new Comparator<>(false) { + @Override + public Relation apply(@NotNull NPCRegistry.NPCRole npcRole, @NotNull ModelAsset modelAsset) { + return Relation.get(npcRole.name().equals(modelAsset.getId())); + } + }); + } + private static void block() { Comparators.registerComparator(BlockType.class, BlockType.class, new Comparator<>(false) { @Override diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java index 867a8b94..bcdacc02 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/types/DefaultConverters.java @@ -1,12 +1,14 @@ package com.github.skriptdev.skript.plugin.elements.types; import com.github.skriptdev.skript.api.hytale.utils.EntityUtils; +import com.github.skriptdev.skript.api.skript.registration.NPCRegistry; import com.hypixel.hytale.math.vector.Location; import com.hypixel.hytale.math.vector.Vector3d; import com.hypixel.hytale.math.vector.Vector3f; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; import com.hypixel.hytale.server.core.asset.type.item.config.Item; +import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; @@ -20,11 +22,19 @@ public class DefaultConverters { public static void register() { + assetStore(); entity(); inventory(); other(); } + private static void assetStore() { + Converters.registerConverter(ModelAsset.class, NPCRegistry.NPCRole.class, modelAsset -> + Optional.ofNullable(NPCRegistry.parse(modelAsset.getId()))); + Converters.registerConverter(NPCRegistry.NPCRole.class, ModelAsset.class, (npcRole) -> + Optional.ofNullable(ModelAsset.getAssetMap().getAsset(npcRole.name()))); + } + @SuppressWarnings("removal") private static void entity() { // Player to PlayerRef From 74ffe48c34a7d55ff6187546ceb4863e46a3663c Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Wed, 4 Mar 2026 06:52:40 -0800 Subject: [PATCH 27/28] ExprMutableList.sk - fix comparing in test --- .../elements/skript-parser/expressions/ExprMutableList.sk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/skript/tests/elements/skript-parser/expressions/ExprMutableList.sk b/src/test/skript/tests/elements/skript-parser/expressions/ExprMutableList.sk index 82f27b35..4fb0e6d2 100644 --- a/src/test/skript/tests/elements/skript-parser/expressions/ExprMutableList.sk +++ b/src/test/skript/tests/elements/skript-parser/expressions/ExprMutableList.sk @@ -1,7 +1,7 @@ test "skript-parser-ExprMutableList": set {_a::*} to "nine", "three", "four" and "ten" set {_a::*} to sorted {_a::*} - assert 1st element of {_a::*} = "four" with "Four should have been the first after sorting" + assert (1st element of {_a::*}) = "four" with "Four should have been the first after sorting" set {_a::*} to reversed {_a::*} - assert 1st element of {_a::*} = "three" with "Three should have been the first after reversing" + assert (1st element of {_a::*}) = "three" with "Three should have been the first after reversing" From e5f202f1a285cf5e1d9af6cfcfaf67c607b40dd3 Mon Sep 17 00:00:00 2001 From: ShaneBeee Date: Wed, 4 Mar 2026 07:47:39 -0800 Subject: [PATCH 28/28] build.gradle.kts - update parser --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7bf16799..8172510f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { implementation("org.bstats:bstats-hytale:3.2.1") // Skript-Parser - implementation("com.github.SkriptDev:skript-parser:1.0.11") { + implementation("com.github.SkriptDev:skript-parser:1.0.12") { isTransitive = false } implementation("com.github.Zoltus:TinyMessage:2.0.1") {