diff --git a/build.gradle.kts b/build.gradle.kts index 071af6b5..397c8583 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,7 @@ repositories { dependencies { compileOnly("com.hypixel.hytale:Server:${hytaleVersion}") compileOnly("org.jetbrains:annotations:26.0.2") - implementation("com.github.SkriptDev:skript-parser:1.0.1") { + implementation("com.github.SkriptDev:skript-parser:1.0.2") { isTransitive = false } implementation("com.github.Zoltus:TinyMessage:2.0.1") { diff --git a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java b/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java index 55d31164..aee689bd 100644 --- a/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java +++ b/src/main/java/com/github/skriptdev/skript/api/hytale/Block.java @@ -55,9 +55,9 @@ public Block(@NotNull Location location) { return this.type; } - public void setType(@NotNull BlockType type) { + public void setType(@NotNull BlockType type, int settings) { this.type = type; - this.world.setBlock(this.pos.getX(), this.pos.getY(), this.pos.getZ(), type.getId()); + this.world.setBlock(this.pos.getX(), this.pos.getY(), this.pos.getZ(), type.getId(), settings); } public byte getFluidLevel() { @@ -134,9 +134,8 @@ public void setFluid(@NotNull Fluid fluid) { }); } - public void breakBlock() { - int setting = 0; // TODO not sure what to actually use here - this.world.breakBlock(this.pos.getX(), this.pos.getY(), this.pos.getZ(), setting); + public void breakBlock(int settings) { + this.world.breakBlock(this.pos.getX(), this.pos.getY(), this.pos.getZ(), settings); } public @NotNull World getWorld() { diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java b/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java index 50933cb6..7ac41e4c 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/docs/JsonDocPrinter.java @@ -210,7 +210,7 @@ private void printExpressions(BsonDocument mainDocs, SkriptRegistration registra private void printFunctions(BsonDocument mainDocs, SkriptRegistration registration) { String addonKey = registration.getRegisterer().getAddonName().toLowerCase(Locale.ROOT).replace(" ", "_"); BsonArray functionsArray = mainDocs.getArray("functions", new BsonArray()); - Functions.getGlobalFunctions().stream().sorted(Comparator.comparing(Function::getName)).forEach(function -> { + Functions.getJavaFunctions().stream().sorted(Comparator.comparing(Function::getName)).forEach(function -> { if (function instanceof JavaFunction jf) { Documentation documentation = jf.getDocumentation(); if (documentation.isNoDoc()) return; diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/docs/MarkdownDocPrinter.java b/src/main/java/com/github/skriptdev/skript/api/skript/docs/MarkdownDocPrinter.java index a8e27c69..09f03068 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/docs/MarkdownDocPrinter.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/docs/MarkdownDocPrinter.java @@ -141,9 +141,11 @@ private static void printEvents(PrintWriter writer, SkriptRegistration registrat List> valuesForThisEvent = new ArrayList<>(); contextValues.forEach(contextValue -> { - if (event.getContexts().contains(contextValue.getContext())) { - valuesForThisEvent.add(contextValue); - } + event.getContexts().forEach(context -> { + if (contextValue.getContext().isAssignableFrom(context)) { + valuesForThisEvent.add(contextValue); + } + }); }); if (!valuesForThisEvent.isEmpty()) { writer.println("- **ContextValues**:"); @@ -198,7 +200,7 @@ private static void printExpressions(PrintWriter exprWriter, PrintWriter condWri @SuppressWarnings("unchecked") private static void printFunctions(PrintWriter writer) { - Functions.getGlobalFunctions().stream().sorted(Comparator.comparing(Function::getName)).forEach(function -> { + Functions.getJavaFunctions().stream().sorted(Comparator.comparing(Function::getName)).forEach(function -> { if (function instanceof JavaFunction jf) { FunctionParameter[] parameters = jf.getParameters(); diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/event/PlayerContext.java b/src/main/java/com/github/skriptdev/skript/api/skript/event/PlayerContext.java new file mode 100644 index 00000000..746c6288 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/api/skript/event/PlayerContext.java @@ -0,0 +1,13 @@ +package com.github.skriptdev.skript.api.skript.event; + +import com.hypixel.hytale.server.core.entity.entities.Player; +import io.github.syst3ms.skriptparser.lang.TriggerContext; + +/** + * Represents a {@link TriggerContext} which includes a player + */ +public interface PlayerContext extends TriggerContext { + + Player[] getPlayer(); + +} diff --git a/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java b/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java index 3897edc4..ece2a049 100644 --- a/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java +++ b/src/main/java/com/github/skriptdev/skript/api/skript/variables/JsonVariableStorage.java @@ -115,7 +115,17 @@ private void loadVariablesFromFile() { if (this.bsonDocument == null) { this.bsonDocument = new BsonDocument(); } - JsonElement jsonElement = BsonUtil.translateBsonToJson(this.bsonDocument); + BsonDocument variablesDocument; + if (this.bsonDocument.containsKey("variables")) { + variablesDocument = this.bsonDocument.getDocument("variables"); + } else { + // Legacy file format (TODO remove before first release) + this.logger.warn("Your variables file is outdated. HySkript will create a backup then convert for you."); + Files.move(this.file.toPath(), this.file.toPath().resolveSibling(this.file.getName() + ".bak")); + variablesDocument = this.bsonDocument.clone(); + this.bsonDocument = new BsonDocument(); + } + JsonElement jsonElement = BsonUtil.translateBsonToJson(variablesDocument); if (jsonElement instanceof JsonObject jsonObject) { jsonObject.entrySet().forEach(entry -> { String name = entry.getKey(); @@ -167,6 +177,8 @@ protected boolean requiresFile() { protected boolean save(@NotNull String name, @Nullable String type, @Nullable JsonElement value) { BsonDocument myDocument = BsonDocument.parse("{}"); + BsonDocument variablesDocument = this.bsonDocument.getDocument("variables", new BsonDocument()); + if (type != null && value != null) { try { BsonValue bsonValue = BsonUtil.translateJsonToBson(value); @@ -197,11 +209,12 @@ protected boolean save(@NotNull String name, @Nullable String type, @Nullable Js } catch (Exception e) { Utils.error("Failed to parse value: " + value); } + variablesDocument.put(name, myDocument); } else { - this.bsonDocument.remove(name); + variablesDocument.remove(name); } - this.bsonDocument.put(name, myDocument); + this.bsonDocument.put("variables", variablesDocument); this.changes.incrementAndGet(); return true; } @@ -254,6 +267,7 @@ private void readBsonFile() throws IOException { } public void writeBsonFile() throws IOException { + writePluginData(); if (this.type == Type.JSON) { FileWriter fileWriter = new FileWriter(this.file); JsonWriterSettings.Builder indent = JsonWriterSettings.builder().indent(true); @@ -272,4 +286,10 @@ public void writeBsonFile() throws IOException { } } + private void writePluginData() { + BsonDocument pluginData = this.bsonDocument.getDocument("data", new BsonDocument()); + pluginData.put("version", new BsonString(HySk.getInstance().getManifest().getVersion().toString())); + this.bsonDocument.put("data", pluginData); + } + } 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 c452c608..62022aef 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/Skript.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/Skript.java @@ -120,7 +120,7 @@ private void printSyntaxCount() { int expsSize = this.registration.getExpressions().size() + mainRegistration.getExpressions().size(); int secSize = this.registration.getSections().size() + mainRegistration.getSections().size(); int typeSize = this.registration.getTypes().size() + mainRegistration.getTypes().size(); - int funcSize = Functions.getGlobalFunctions().size(); + int funcSize = Functions.getAllFunctions().size(); int total = structureSize + eventSize + effectSize + expsSize + secSize + typeSize + funcSize; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java b/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java index b94c2b77..e04db8c6 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/command/EffectCommands.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.command; +import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.utils.Utils; import com.github.skriptdev.skript.plugin.Skript; import com.hypixel.hytale.component.Ref; @@ -11,13 +12,13 @@ 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.TriggerContext; import io.github.syst3ms.skriptparser.log.LogEntry; import io.github.syst3ms.skriptparser.log.SkriptLogger; import io.github.syst3ms.skriptparser.parsing.ParserState; import io.github.syst3ms.skriptparser.parsing.SyntaxParser; import io.github.syst3ms.skriptparser.registration.context.ContextValue.Usage; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -25,9 +26,6 @@ public class EffectCommands { public static void register(Skript skript, String token, boolean allowOps, String permission) { - skript.getSkriptRegistration().newContextValue(PlayerEffectContext.class, Player.class, true, "player", PlayerEffectContext::getPlayer) - .setUsage(Usage.EXPRESSION_OR_ALONE) - .register(); skript.getSkriptRegistration().newContextValue(PlayerEffectContext.class, Player.class, true, "me", PlayerEffectContext::getPlayer) .setUsage(Usage.EXPRESSION_OR_ALONE) .register(); @@ -37,6 +35,7 @@ public static void register(Skript skript, String token, boolean allowOps, Strin PlayerRef sender = event.getSender(); // PERM CHECK + // Pretty sure the OP stuff doesn't work PermissionsModule perm = PermissionsModule.get(); Set groupsForUser = perm.getGroupsForUser(sender.getUuid()); if (!allowOps) { @@ -49,13 +48,17 @@ public static void register(Skript skript, String token, boolean allowOps, Strin event.setCancelled(true); + // Create dummy ParserState/Logger for effect commands ParserState parserState = new ParserState(); parserState.setCurrentContexts(Set.of(PlayerEffectContext.class)); SkriptLogger skriptLogger = new SkriptLogger(true); + skriptLogger.setFileInfo("dummy_cause_this_doesnt_matter.sk", List.of()); + // Parse effect String effectString = event.getContent().substring(1); Optional optionalEffect = SyntaxParser.parseEffect(effectString, parserState, skriptLogger); + // If no effect available, send logs if (optionalEffect.isEmpty()) { skriptLogger.finalizeLogs(); for (LogEntry logEntry : skriptLogger.close()) { @@ -94,7 +97,7 @@ public static void register(Skript skript, String token, boolean allowOps, Strin }); } - private record PlayerEffectContext(Player player) implements TriggerContext { + private record PlayerEffectContext(Player player) implements PlayerContext { public Player[] getPlayer() { return new Player[]{this.player}; 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 5554c5a9..cdd14e68 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 @@ -1,19 +1,37 @@ package com.github.skriptdev.skript.plugin.elements.effects; 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.entity.EffDropItem; +import com.github.skriptdev.skript.plugin.elements.effects.entity.EffKill; +import com.github.skriptdev.skript.plugin.elements.effects.other.EffSendMessage; +import com.github.skriptdev.skript.plugin.elements.effects.entity.EffTeleport; +import com.github.skriptdev.skript.plugin.elements.effects.player.EffBan; +import com.github.skriptdev.skript.plugin.elements.effects.other.EffBroadcast; +import com.github.skriptdev.skript.plugin.elements.effects.other.EffCancelEvent; +import com.github.skriptdev.skript.plugin.elements.effects.other.EffDelay; +import com.github.skriptdev.skript.plugin.elements.effects.player.EffKick; public class EffectHandler { public static void register(SkriptRegistration registration) { - EffBan.register(registration); + // BLOCK + EffBreakBlock.register(registration); + + // ENTITY + EffDropItem.register(registration); + EffKill.register(registration); + EffTeleport.register(registration); + + // OTHER EffBroadcast.register(registration); EffCancelEvent.register(registration); EffDelay.register(registration); - EffDropItem.register(registration); - EffKick.register(registration); - EffKill.register(registration); EffSendMessage.register(registration); - EffTeleport.register(registration); + + // PLAYER + EffBan.register(registration); + EffKick.register(registration); } } 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 new file mode 100644 index 00000000..3512a9bd --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/block/EffBreakBlock.java @@ -0,0 +1,59 @@ +package com.github.skriptdev.skript.plugin.elements.effects.block; + +import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +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 EffBreakBlock extends Effect { + + public static void register(SkriptRegistration reg) { + reg.newEffect(EffBreakBlock.class, "break %blocks% [with settings %number%]") + .description("Breaks the specified blocks.", + "**Settings**:", + "I don't really know what this does yet, but from testing:", + "- `-1` = Breaks the block without particles and performs update of block above (ie: break if it can't be supported).", + "- `0-3` = Breaks the block with particles.", + "- `4+` = Breaks the block without particles.", + "- `256` = Breaks the block with particles and performs update of block above (default).", + "- Any other number doesn't do anything different than the few stated above.") + .examples("break target block of player with settings 0") + .since("INSERT VERSION") + .register(); + } + + private Expression blocks; + private Expression settings; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.blocks = (Expression) expressions[0]; + if (expressions.length > 1) { + this.settings = (Expression) expressions[1]; + } + return true; + } + + @Override + protected void execute(@NotNull TriggerContext ctx) { + int settings = 256; // Break block with particles and neighboring updates. + if (this.settings != null) { + Number number = this.settings.getSingle(ctx).orElse(null); + if (number != null) settings = number.intValue(); + } + for (Block block : this.blocks.getArray(ctx)) { + block.breakBlock(settings); + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + String settings = this.settings == null ? "" : " with settings " + this.settings.toString(ctx, debug); + return "break " + this.blocks.toString(ctx, debug) + settings; + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDropItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java similarity index 98% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDropItem.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java index 39440adf..0a391039 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDropItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffDropItem.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.entity; import com.github.skriptdev.skript.api.hytale.EntityComponentUtils; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKill.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffKill.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKill.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffKill.java index 20e8826c..c5b3acc5 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKill.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffKill.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.entity; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffTeleport.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffTeleport.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffTeleport.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffTeleport.java index 8f92c0b9..52d74e8d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffTeleport.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/entity/EffTeleport.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.entity; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBroadcast.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBroadcast.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java index 028f2b27..a0e9cec7 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBroadcast.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffBroadcast.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.other; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.universe.Universe; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffCancelEvent.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java similarity index 84% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffCancelEvent.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java index 429e4c34..d1fc5410 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffCancelEvent.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffCancelEvent.java @@ -1,6 +1,7 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.other; import com.github.skriptdev.skript.api.skript.event.CancellableContext; +import com.github.skriptdev.skript.api.utils.Utils; import io.github.syst3ms.skriptparser.lang.Effect; import io.github.syst3ms.skriptparser.lang.Expression; import io.github.syst3ms.skriptparser.lang.TriggerContext; @@ -26,6 +27,10 @@ public static void register(SkriptRegistration registration) { @Override public boolean init(Expression @NotNull [] expressions, int matchedPattern, ParseContext parseContext) { this.cancel = matchedPattern == 0; + Utils.log("Contexts:"); + for (Class currentContext : parseContext.getParserState().getCurrentContexts()) { + Utils.log(" - %s", currentContext.getSimpleName()); + } for (Class currentContext : parseContext.getParserState().getCurrentContexts()) { if (!CancellableContext.class.isAssignableFrom(currentContext)) { parseContext.getLogger().error("This event cannot be cancelled", ErrorType.SEMANTIC_ERROR); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDelay.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java similarity index 98% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDelay.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java index a660d026..468ba060 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffDelay.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffDelay.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.other; 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/effects/EffSendMessage.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java similarity index 76% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffSendMessage.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java index 9122582d..a579c9b9 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffSendMessage.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/other/EffSendMessage.java @@ -1,7 +1,7 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.other; +import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.utils.Utils; -import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerJoin.PlayerEventContext; import com.hypixel.hytale.server.core.Message; import com.hypixel.hytale.server.core.command.system.CommandSender; import com.hypixel.hytale.server.core.receiver.IMessageReceiver; @@ -10,12 +10,14 @@ import io.github.syst3ms.skriptparser.lang.TriggerContext; import io.github.syst3ms.skriptparser.parsing.ParseContext; import io.github.syst3ms.skriptparser.registration.SkriptRegistration; +import io.github.syst3ms.skriptparser.types.TypeManager; import org.jetbrains.annotations.NotNull; public class EffSendMessage extends Effect { public static void register(SkriptRegistration registration) { - registration.newEffect(EffSendMessage.class, "send [message[s]] %strings/messages% [to %-messagereceivers%]") + registration.newEffect(EffSendMessage.class, + "send [message[s]] %objects% [to %-messagereceivers%]") .name("Send Message") .description("Sends a message to a command sender such as a player or the console.") .examples("send \"Welcome to the server\" to player") @@ -39,6 +41,8 @@ public boolean init(Expression[] exprs, int matchedPattern, @NotNull ParseCon @Override protected void execute(@NotNull TriggerContext ctx) { Object[] messages = this.messages.getValues(ctx); + if (messages == null || messages.length == 0) return; + if (this.senders != null) { for (IMessageReceiver commandSender : this.senders.getArray(ctx)) { for (Object value : messages) { @@ -46,17 +50,21 @@ protected void execute(@NotNull TriggerContext ctx) { Utils.sendMessage(commandSender, string); } else if (value instanceof Message message) { commandSender.sendMessage(message); + } else { + Utils.sendMessage(commandSender, TypeManager.toString(new Object[]{value})); } } } } else { - if (ctx instanceof PlayerEventContext playerEventContext) { - for (CommandSender commandSender : playerEventContext.getPlayer()) { + if (ctx instanceof PlayerContext playerContext) { + for (CommandSender commandSender : playerContext.getPlayer()) { for (Object value : messages) { if (value instanceof String string) { Utils.sendMessage(commandSender, string); } else if (value instanceof Message message) { commandSender.sendMessage(message); + } else { + Utils.sendMessage(commandSender, TypeManager.toString(new Object[]{value})); } } } @@ -66,6 +74,8 @@ protected void execute(@NotNull TriggerContext ctx) { Utils.log(s); } else if (value instanceof Message message) { Utils.log(message.getRawText()); + } else { + Utils.log(TypeManager.toString(new Object[]{value})); } } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBan.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffBan.java similarity index 99% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBan.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffBan.java index b22d73cc..d164f8d0 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffBan.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffBan.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.player; import com.github.skriptdev.skript.api.utils.ReflectionUtils; import com.github.skriptdev.skript.api.utils.Utils; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKick.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffKick.java similarity index 97% rename from src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKick.java rename to src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffKick.java index 098c3308..e32723b7 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/EffKick.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/effects/player/EffKick.java @@ -1,4 +1,4 @@ -package com.github.skriptdev.skript.plugin.elements.effects; +package com.github.skriptdev.skript.plugin.elements.effects.player; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.universe.PlayerRef; 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 d92de304..f3690392 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,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events; +import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.elements.events.entity.EvtEntityDamage; import com.github.skriptdev.skript.plugin.elements.events.entity.EvtEntityDeath; @@ -9,6 +10,7 @@ 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.EvtPlayerChat; +import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerDamageBlock; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerDrainFromWorld; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerDropItem; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerDropItemRequest; @@ -17,9 +19,12 @@ import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerMouseMove; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerSetupConnect; import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerSetupDisconnect; +import com.github.skriptdev.skript.plugin.elements.events.player.EvtPlayerUseBlock; import com.github.skriptdev.skript.plugin.elements.events.server.EvtBoot; import com.github.skriptdev.skript.plugin.elements.events.server.EvtShutdown; import com.github.skriptdev.skript.plugin.elements.events.skript.EvtLoad; +import com.hypixel.hytale.server.core.entity.entities.Player; +import io.github.syst3ms.skriptparser.registration.context.ContextValue.Usage; public class EventHandler { @@ -34,6 +39,7 @@ public static void register(SkriptRegistration registration) { EvtPlayerAddToWorld.register(registration); EvtPlayerBreakBlock.register(registration); EvtPlayerChat.register(registration); + EvtPlayerDamageBlock.register(registration); EvtPlayerDrainFromWorld.register(registration); EvtPlayerDropItem.register(registration); EvtPlayerDropItemRequest.register(registration); @@ -42,6 +48,7 @@ public static void register(SkriptRegistration registration) { EvtPlayerMouseMove.register(registration); EvtPlayerSetupConnect.register(registration); EvtPlayerSetupDisconnect.register(registration); + EvtPlayerUseBlock.register(registration); // SERVER EvtBoot.register(registration); @@ -49,6 +56,15 @@ public static void register(SkriptRegistration registration) { // SKRIPT EvtLoad.register(registration); + + // CONTEXT + registerGlobalContexts(registration); + } + + private static void registerGlobalContexts(SkriptRegistration reg) { + reg.newContextValue(PlayerContext.class, Player.class, true, "player", PlayerContext::getPlayer) + .setUsage(Usage.EXPRESSION_OR_ALONE) + .register(); } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerAddToWorld.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerAddToWorld.java index 8519916b..7ea6e2b5 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerAddToWorld.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerAddToWorld.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.events.player; +import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.component.Holder; @@ -27,7 +28,6 @@ public static void register(SkriptRegistration reg) { .register(); reg.addContextValue(AddContext.class, World.class, true, "world", AddContext::getWorld); - reg.addContextValue(AddContext.class, Player.class, true, "player", AddContext::getPlayer); } private static EventRegistration LISTENER; @@ -53,7 +53,7 @@ public String toString(TriggerContext ctx, boolean debug) { return ""; } - private record AddContext(AddPlayerToWorldEvent event) implements TriggerContext { + private record AddContext(AddPlayerToWorldEvent event) implements PlayerContext { public World[] getWorld() { return new World[]{this.event.getWorld()}; 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 c57aae16..8eacb022 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 @@ -2,6 +2,7 @@ import com.github.skriptdev.skript.api.hytale.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; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.hypixel.hytale.component.ArchetypeChunk; @@ -39,7 +40,6 @@ public static void register(SkriptRegistration reg) { .setHandledContexts(BreakBlockEventContext.class) .register(); - reg.addContextValue(BreakBlockEventContext.class, Player.class, true, "player", BreakBlockEventContext::getPlayer); reg.addContextValue(BreakBlockEventContext.class, Block.class, true, "block", BreakBlockEventContext::getBlock); reg.addContextValue(BreakBlockEventContext.class, World.class, true, "world", BreakBlockEventContext::getWorld); reg.addContextValue(BreakBlockEventContext.class, BlockType.class, true, "blocktype", BreakBlockEventContext::getBlockType); @@ -69,9 +69,9 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return "player block break"; } - private record BreakBlockEventContext(BreakBlockEvent event, Player player) implements TriggerContext, CancellableContext { + private record BreakBlockEventContext(BreakBlockEvent event, Player player) implements PlayerContext, CancellableContext { - private Player[] getPlayer() { + public Player[] getPlayer() { return new Player[]{this.player}; } 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 new file mode 100644 index 00000000..92c794e3 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDamageBlock.java @@ -0,0 +1,140 @@ +package com.github.skriptdev.skript.plugin.elements.events.player; + +import com.github.skriptdev.skript.api.hytale.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; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.ArchetypeChunk; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.component.query.Query; +import com.hypixel.hytale.component.system.EntityEventSystem; +import com.hypixel.hytale.math.vector.Vector3i; +import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.ecs.DamageBlockEvent; +import com.hypixel.hytale.server.core.inventory.ItemStack; +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.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.TriggerMap; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class EvtPlayerDamageBlock extends SystemEvent> { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtPlayerDamageBlock.class, + "player damage block", "block damaged by player") + .setHandledContexts(DamageBlockContext.class) + .name("Block Damage") + .description("Called when a block is damaged by a player.") + .since("INSERT VERSION") + .register(); + + reg.addContextValue(DamageBlockContext.class, Block.class, true, "block", DamageBlockContext::getBlock); + reg.addContextValue(DamageBlockContext.class, BlockType.class, true, "blocktype", DamageBlockContext::getBlockType); + reg.addContextValue(DamageBlockContext.class, ItemStack.class, true, "itemstack-in-hand", DamageBlockContext::getItemStackInHand); + reg.addContextValue(DamageBlockContext.class, Number.class, true, "damage", DamageBlockContext::getDamage); + reg.addContextValue(DamageBlockContext.class, Number.class, true, "current-damage", DamageBlockContext::getCurrentDamage); + } + + private static DamageBlockSystem SYSTEM; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + if (SYSTEM == null) { + SYSTEM = new DamageBlockSystem(); + applySystem(SYSTEM); + } + return true; + } + + @Override + public boolean check(TriggerContext ctx) { + return ctx instanceof DamageBlockContext; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "player damage block"; + } + + public record DamageBlockContext(DamageBlockEvent event, Player player) + implements PlayerContext, CancellableContext { + + @Override + public Player[] getPlayer() { + return new Player[]{this.player}; + } + + public ItemStack[] getItemStackInHand() { + return new ItemStack[]{this.event.getItemInHand()}; + } + + public Block[] getBlock() { + Vector3i targetBlock = this.event.getTargetBlock(); + World world = this.player.getWorld(); + if (world == null) return null; + return new Block[]{new Block(world, targetBlock, this.event.getBlockType())}; + } + + public BlockType[] getBlockType() { + return new BlockType[]{this.event.getBlockType()}; + } + + public Number[] getDamage() { + return new Number[]{this.event.getDamage()}; + } + + public Number[] getCurrentDamage() { + return new Number[]{this.event.getCurrentDamage()}; + } + + @Override + public boolean isCancelled() { + return this.event.isCancelled(); + } + + @Override + public void setCancelled(boolean cancelled) { + this.event.setCancelled(cancelled); + } + + @Override + public String getName() { + return "damage block context"; + } + } + + public static class DamageBlockSystem extends EntityEventSystem { + + protected DamageBlockSystem() { + super(DamageBlockEvent.class); + } + + @Override + public void handle(int i, @NotNull ArchetypeChunk archetypeChunk, @NotNull Store store, + @NotNull CommandBuffer commandBuffer, @NotNull DamageBlockEvent event) { + + if (event.getBlockType() == BlockType.EMPTY) return; + + Ref ref = archetypeChunk.getReferenceTo(i); + Player player = store.getComponent(ref, Player.getComponentType()); + if (player == null) return; + + DamageBlockContext context = new DamageBlockContext(event, player); + TriggerMap.callTriggersByContext(context); + } + + @Override + public @Nullable Query getQuery() { + return Player.getComponentType(); + } + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItem.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItem.java index 57dcf7ec..528a018b 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItem.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItem.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events.player; 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; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; @@ -36,7 +37,6 @@ public static void register(SkriptRegistration reg) { .since("1.0.0") .register(); - reg.addContextValue(DropItemContext.class, Player.class, true, "player", DropItemContext::getPlayer); reg.addContextValue(DropItemContext.class, Float.class, true, "throw-speed", DropItemContext::getThrowSpeed); reg.addContextValue(DropItemContext.class, Item.class, true, "dropped-item", DropItemContext::getItem); reg.addContextValue(DropItemContext.class, ItemStack.class, true, "dropped-itemstack", DropItemContext::getItemStack); @@ -63,7 +63,7 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return "player drop item event"; } - private record DropItemContext(Player player, Drop drop) implements TriggerContext, CancellableContext { + private record DropItemContext(Player player, Drop drop) implements PlayerContext, CancellableContext { public Player[] getPlayer() { return new Player[]{this.player}; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItemRequest.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItemRequest.java index 276d91ab..4c4be00a 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItemRequest.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerDropItemRequest.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events.player; 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; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; @@ -37,7 +38,6 @@ public static void register(SkriptRegistration reg) { .since("1.0.0") .register(); - reg.addContextValue(RequestDropItemContext.class, Player.class, true, "player", RequestDropItemContext::getPlayer); reg.addContextValue(RequestDropItemContext.class, Integer.class, true, "slot-id", RequestDropItemContext::getSlotId); reg.addContextValue(RequestDropItemContext.class, Integer.class, true, "inventory-section-id", RequestDropItemContext::getInventorySectionId); reg.addContextValue(RequestDropItemContext.class, Item.class, true, "item", RequestDropItemContext::getItem); @@ -66,7 +66,7 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { } private record RequestDropItemContext(Player player, DropItemEvent.PlayerRequest request) - implements TriggerContext, CancellableContext { + implements PlayerContext, CancellableContext { public Player[] getPlayer() { return new Player[]{this.player}; diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerJoin.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerJoin.java index d4aca09c..a3bc6a2f 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerJoin.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerJoin.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.events.player; +import com.github.skriptdev.skript.api.skript.event.PlayerContext; import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.event.EventRegistration; import com.hypixel.hytale.event.EventRegistry; @@ -13,7 +14,6 @@ import io.github.syst3ms.skriptparser.lang.event.SkriptEvent; import io.github.syst3ms.skriptparser.parsing.ParseContext; import io.github.syst3ms.skriptparser.registration.SkriptRegistration; -import io.github.syst3ms.skriptparser.registration.context.ContextValue; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,10 +26,6 @@ public static void register(SkriptRegistration registration) { .since("1.0.0") .setHandledContexts(PlayerEventContext.class) .register(); - - registration.newContextValue(PlayerEventContext.class, Player.class, true, "player", PlayerEventContext::getPlayer) - .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) - .register(); } private static EventRegistration CONNECT_LISTENER; @@ -83,7 +79,7 @@ public String toString(@Nullable TriggerContext ctx, boolean debug) { return "player " + t; } - public static class PlayerEventContext implements TriggerContext { + public static class PlayerEventContext implements PlayerContext { private final Player player; private final int pattern; @@ -94,11 +90,11 @@ public PlayerEventContext(Player player, int pattern) { } public Player[] getPlayer() { - return new Player[]{player}; + return new Player[]{this.player}; } public int getPattern() { - return pattern; + return this.pattern; } @Override diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseClick.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseClick.java index e74738b6..2e586870 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseClick.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseClick.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events.player; 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.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.event.EventRegistration; @@ -31,7 +32,6 @@ public static void register(SkriptRegistration reg) { .setHandledContexts(MouseClickContext.class) .register(); - reg.addContextValue(MouseClickContext.class, Player.class, true, "player", MouseClickContext::getPlayer); reg.addContextValue(MouseClickContext.class, Item.class, true, "item", MouseClickContext::getItemInHand); reg.addContextValue(MouseClickContext.class, Entity.class, true, "target-entity", MouseClickContext::getTargetEntity); reg.addContextValue(MouseClickContext.class, Vector3i.class, true, "target-block", MouseClickContext::getTargetBlock); @@ -64,9 +64,9 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return "player mouse click"; } - private record MouseClickContext(PlayerMouseButtonEvent event) implements TriggerContext, CancellableContext { + private record MouseClickContext(PlayerMouseButtonEvent event) implements PlayerContext, CancellableContext { - private Player[] getPlayer() { + public Player[] getPlayer() { return new Player[]{this.event.getPlayer()}; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseMove.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseMove.java index ba02bc88..ab6d234c 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseMove.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerMouseMove.java @@ -1,6 +1,7 @@ package com.github.skriptdev.skript.plugin.elements.events.player; 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.registration.SkriptRegistration; import com.github.skriptdev.skript.plugin.HySk; import com.hypixel.hytale.event.EventRegistration; @@ -29,7 +30,6 @@ public static void register(SkriptRegistration reg) { .setHandledContexts(MouseMoveContext.class) .register(); - reg.addContextValue(MouseMoveContext.class, Player.class, true, "player", MouseMoveContext::getPlayer); reg.addContextValue(MouseMoveContext.class, Item.class, true, "item", MouseMoveContext::getItemInHand); reg.addContextValue(MouseMoveContext.class, Entity.class, true, "target-entity", MouseMoveContext::getTargetEntity); reg.addContextValue(MouseMoveContext.class, Vector3i.class, true, "target-block", MouseMoveContext::getTargetBlock); @@ -60,9 +60,9 @@ public String toString(@NotNull TriggerContext ctx, boolean debug) { return "player mouse motion event"; } - private record MouseMoveContext(PlayerMouseMotionEvent event) implements TriggerContext, CancellableContext { + private record MouseMoveContext(PlayerMouseMotionEvent event) implements PlayerContext, CancellableContext { - private Player[] getPlayer() { + public Player[] getPlayer() { return new Player[]{this.event.getPlayer()}; } 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 new file mode 100644 index 00000000..8f208a8d --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerUseBlock.java @@ -0,0 +1,189 @@ +package com.github.skriptdev.skript.plugin.elements.events.player; + +import com.github.skriptdev.skript.api.hytale.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; +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.component.ArchetypeChunk; +import com.hypixel.hytale.component.CommandBuffer; +import com.hypixel.hytale.component.Ref; +import com.hypixel.hytale.component.Store; +import com.hypixel.hytale.component.query.Query; +import com.hypixel.hytale.component.system.EntityEventSystem; +import com.hypixel.hytale.protocol.InteractionType; +import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.ecs.UseBlockEvent; +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.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.TriggerMap; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; + +public class EvtPlayerUseBlock extends SystemEvent> { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtPlayerUseBlock.class, + "player use block", + "pre player use block", + "before player uses block", + "post player use block", + "after player uses block") + .setHandledContexts(PreUseBlockContext.class, PostUseBlockContext.class) + .name("Player Use Block") + .description("Called when a player uses a block.", + "Pre is cancellable, post is not.") + .since("INSERT VERSION") + .register(); + + reg.addContextValue(UseBlockContext.class, BlockType.class, true, "blocktype", UseBlockContext::getBlockType); + reg.addContextValue(UseBlockContext.class, Block.class, true, "block", UseBlockContext::getBlock); + reg.addContextValue(UseBlockContext.class, InteractionType.class, true, "interaction-type", UseBlockContext::getInteractionType); + } + + private static PreUseBlockSystem PRE_SYSTEM; + private static PostUseBlockSystem POST_SYSTEM; + private boolean pre; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + if (PRE_SYSTEM == null) { + PRE_SYSTEM = new PreUseBlockSystem(); + applySystem(PRE_SYSTEM); + } + if (POST_SYSTEM == null) { + POST_SYSTEM = new PostUseBlockSystem(); + applySystem(POST_SYSTEM); + } + this.pre = matchedPattern < 3; + parseContext.getParserState().setCurrentContexts(this.pre ? Collections.singleton(PreUseBlockContext.class) : Collections.singleton(PostUseBlockContext.class)); + return true; + } + + @Override + public boolean check(TriggerContext ctx) { + if (this.pre) return ctx instanceof PreUseBlockContext; + return ctx instanceof PostUseBlockContext; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "player use block"; + } + + public static abstract class UseBlockContext implements PlayerContext { + + final T event; + final Player player; + + public UseBlockContext(T event, Player player) { + this.event = event; + this.player = player; + } + + @Override + public Player[] getPlayer() { + return new Player[]{this.player}; + } + + public BlockType[] getBlockType() { + return new BlockType[]{this.event.getBlockType()}; + } + + public InteractionType[] getInteractionType() { + return new InteractionType[]{this.event.getInteractionType()}; + } + + public Block[] getBlock() { + World world = this.player.getWorld(); + if (world == null) return null; + return new Block[]{new Block(world, this.event.getTargetBlock(), this.event.getBlockType())}; + } + } + + public static class PreUseBlockContext extends UseBlockContext implements CancellableContext { + + public PreUseBlockContext(UseBlockEvent.Pre event, Player player) { + super(event, player); + } + + @Override + public boolean isCancelled() { + return this.event.isCancelled(); + } + + @Override + public void setCancelled(boolean cancelled) { + this.event.setCancelled(cancelled); + } + + @Override + public String getName() { + return "pre use block context"; + } + } + + public static class PostUseBlockContext extends UseBlockContext { + + public PostUseBlockContext(UseBlockEvent.Post event, Player player) { + super(event, player); + } + + @Override + public String getName() { + return "post use block context"; + } + } + + public static class PreUseBlockSystem extends EntityEventSystem { + + protected PreUseBlockSystem() { + super(UseBlockEvent.Pre.class); + } + + @Override + public @Nullable Query getQuery() { + return Player.getComponentType(); + } + + @Override + public void handle(int i, @NotNull ArchetypeChunk archetypeChunk, @NotNull Store store, @NotNull CommandBuffer commandBuffer, @NotNull UseBlockEvent.Pre pre) { + + Ref ref = archetypeChunk.getReferenceTo(i); + Player player = store.getComponent(ref, Player.getComponentType()); + if (player == null) return; + + TriggerMap.callTriggersByContext(new PreUseBlockContext(pre, player)); + } + } + + public static class PostUseBlockSystem extends EntityEventSystem { + + protected PostUseBlockSystem() { + super(UseBlockEvent.Post.class); + } + + @Override + public @Nullable Query getQuery() { + return Player.getComponentType(); + } + + @Override + public void handle(int i, @NotNull ArchetypeChunk archetypeChunk, @NotNull Store store, + @NotNull CommandBuffer commandBuffer, @NotNull UseBlockEvent.Post post) { + + Ref ref = archetypeChunk.getReferenceTo(i); + Player player = store.getComponent(ref, Player.getComponentType()); + if (player == null) return; + + TriggerMap.callTriggersByContext(new PostUseBlockContext(post, player)); + } + } + +} 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 f6e3cb79..c9b891c1 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 @@ -7,18 +7,23 @@ 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.ExprTargetBlockOfPlayer; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprActiveSlot; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityHealth; import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprEntityStat; +import com.github.skriptdev.skript.plugin.elements.expressions.entity.ExprHeldItem; 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.item.ExprInventory; 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.ExprItemStack; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemType; import com.github.skriptdev.skript.plugin.elements.expressions.item.ExprItemsInInventory; +import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprCast; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprClassInfoOf; +import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprDistance; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprLocationDirection; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprLocationOf; import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprMessage; @@ -51,8 +56,10 @@ public static void register(SkriptRegistration registration) { ExprTargetBlockOfPlayer.register(registration); // ENTITY + ExprActiveSlot.register(registration); ExprEntityHealth.register(registration); ExprEntityStat.register(registration); + ExprHeldItem.register(registration); ExprName.register(registration); ExprNPCType.register(registration); ExprTargetEntityOfEntity.register(registration); @@ -60,13 +67,16 @@ public static void register(SkriptRegistration registration) { // ITEM ExprInventory.register(registration); ExprInventorySlot.register(registration); + ExprInventorySlots.register(registration); ExprItemContainer.register(registration); ExprItemsInInventory.register(registration); ExprItemStack.register(registration); ExprItemType.register(registration); // OTHER + ExprCast.register(registration); ExprClassInfoOf.register(registration); + ExprDistance.register(registration); ExprLocationDirection.register(registration); ExprLocationOf.register(registration); ExprMessage.register(registration); 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 f1103835..04d5d615 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 @@ -17,9 +17,14 @@ public class ExprBlockTypeOfBlock implements Expression { public static void register(SkriptRegistration reg) { reg.newExpression(ExprBlockTypeOfBlock.class, BlockType.class, false, - "block[ ]type of %blocks%") + "block[ ]type of %blocks% [with settings %number%]") .name("Block Type of Block") - .description("Get/set the BlockType of a block.") + .description("Get/set the BlockType of a block.", + "**Settings**:", + "I don't really know what this does yet, but from testing:", + "- `0` = Without block update, with particles).", + "- `4` = Without block update, without particles (default)", + "- `256` = With block update, with particles.") .examples("on player block break:", "\tif context-blocktype = ore_copper_stone:", "\t\tcancel event", @@ -31,11 +36,13 @@ public static void register(SkriptRegistration reg) { } private Expression blocks; + private Expression settings; @SuppressWarnings("unchecked") @Override public boolean init(Expression @NotNull [] expressions, int matchedPattern, @NotNull ParseContext parseContext) { this.blocks = (Expression) expressions[0]; + if (expressions.length > 1) this.settings = (Expression) expressions[1]; return true; } @@ -62,8 +69,14 @@ public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, if (!(changeWith[0] instanceof BlockType type)) return; + int settings = 4; // No particles, no updates + if (this.settings != null) { + Optional single = this.settings.getSingle(ctx); + if (single.isPresent()) settings = single.get().intValue(); + } + for (Block block : this.blocks.getArray(ctx)) { - block.setType(type); + block.setType(type, settings); } } @@ -74,7 +87,8 @@ public boolean isSingle() { @Override public String toString(@NotNull TriggerContext ctx, boolean debug) { - return "blocktype of " + this.blocks.toString(ctx, debug); + String settings = this.settings == null ? "" : " with settings " + this.settings.toString(ctx, debug); + return "blocktype of " + this.blocks.toString(ctx, debug) + settings; } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprActiveSlot.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprActiveSlot.java new file mode 100644 index 00000000..bbd906fc --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprActiveSlot.java @@ -0,0 +1,96 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.entity; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.LivingEntity; +import com.hypixel.hytale.server.core.inventory.Inventory; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import io.github.syst3ms.skriptparser.types.changers.ChangeMode; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class ExprActiveSlot implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprActiveSlot.class, Number.class, false, + "active hot[ ]bar slot of %livingentities%", + "active (utility|off[ ]hand) slot of %livingentities%", + "active tool slot of %livingentities%") + .name("Active Slot") + .description("Get/set the active slot of a living entity.", + "**Note**: This seems extremely borked on the server, so please use with caution.") + .since("INSERT VERSION") + .register(); + } + + private int slot; + private Expression entity; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.slot = matchedPattern; + this.entity = (Expression) expressions[0]; + return true; + } + + @Override + public Number[] getValues(@NotNull TriggerContext ctx) { + LivingEntity[] entityArray = this.entity.getArray(ctx); + Byte[] s = new Byte[entityArray.length]; + for (int i = 0; i < entityArray.length; i++) { + Inventory inventory = entityArray[i].getInventory(); + if (this.slot == 0) { + s[i] = inventory.getActiveHotbarSlot(); + } else if (this.slot == 1) { + s[i] = inventory.getActiveUtilitySlot(); + } else if (this.slot == 2) { + s[i] = inventory.getActiveToolsSlot(); + } + } + return s; + } + + @Override + public Optional[]> acceptsChange(@NotNull ChangeMode mode) { + if (mode == ChangeMode.SET) return Optional.of(new Class[]{Number.class}); + return Optional.empty(); + } + + @SuppressWarnings("ConstantValue") + @Override + public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { + if (changeWith == null) return; + if (!(changeWith[0] instanceof Number number)) return; + byte slot = number.byteValue(); + + + for (LivingEntity entity : this.entity.getArray(ctx)) { + Inventory inventory = entity.getInventory(); + if (this.slot == 0) { + byte clamp = (byte) Math.clamp(slot, 0, Inventory.DEFAULT_HOTBAR_CAPACITY - 1); + inventory.setActiveHotbarSlot(clamp); + } else if (this.slot == 1) { + byte clamp = (byte) Math.clamp(slot, -1, Inventory.DEFAULT_UTILITY_CAPACITY - 1); + inventory.setActiveUtilitySlot(clamp); + } else if (this.slot == 2) { + byte clamp = (byte) Math.clamp(slot, -1, Inventory.DEFAULT_TOOLS_CAPACITY - 1); + inventory.setActiveToolsSlot(clamp); + } + } + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + String type = switch (this.slot) { + case 0 -> "hotbar"; + case 1 -> "utility"; + case 2 -> "tool"; + default -> "unknown"; + }; + return "active " + type + " slot of " + this.entity.toString(ctx, debug); + } + +} 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 new file mode 100644 index 00000000..dce16ba9 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprHeldItem.java @@ -0,0 +1,121 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.entity; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.entity.LivingEntity; +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; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import io.github.syst3ms.skriptparser.types.changers.ChangeMode; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class ExprHeldItem implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprHeldItem.class, ItemStack.class, true, + "(held|hot[ ]bar) item of %livingentities%", + "(utility|off[ ]hand) item of %livingentities%", + "tool [item] of %livingentities%") + .name("Held Item") + .description("Get/set the item in the hotbar, utility or tool slot of a living entity.", + "**Slots**:", + "- **Hotbar**: The item in your main hand.", + "- **Utility**: The off-hand slot, used for secondary items like shields or tools." + + "When setting, if you don't actively have your utility slot in use, the first slot will be set and used.", + "- **Tool**: Not really sure what this is.") + .examples("set held item of player to itemstack of ingredient_poop", + "set utility item of player to itemstack of furniture_crude_torch") + .since("INSERT VERSION") + .register(); + } + + private int pattern; + private Expression entities; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.pattern = matchedPattern; + this.entities = (Expression) expressions[0]; + return true; + } + + @Override + public ItemStack[] getValues(@NotNull TriggerContext ctx) { + LivingEntity[] entities = this.entities.getArray(ctx); + ItemStack[] items = new ItemStack[entities.length]; + + for (int i = 0; i < entities.length; i++) { + Inventory inventory = entities[i].getInventory(); + if (this.pattern == 0) { + items[i] = inventory.getActiveHotbarItem(); + } else if (this.pattern == 1) { + items[i] = inventory.getUtilityItem(); + } else if (this.pattern == 2) { + items[i] = inventory.getActiveToolItem(); + } + } + return items; + } + + @Override + public Optional[]> acceptsChange(@NotNull ChangeMode mode) { + if (mode == ChangeMode.SET || mode == ChangeMode.DELETE) return Optional.of(new Class[]{ItemStack.class}); + return Optional.empty(); + } + + @SuppressWarnings("ConstantValue") + @Override + public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, Object @NotNull [] changeWith) { + if (changeWith == null) return; + + ItemStack itemStack = ((ItemStack) changeWith[0]); + + for (LivingEntity livingEntity : this.entities.getArray(ctx)) { + Inventory inventory = livingEntity.getInventory(); + if (this.pattern == 0) { + ItemContainer hotbar = inventory.getHotbar(); + byte activeHotbarSlot = inventory.getActiveHotbarSlot(); + hotbar.setItemStackForSlot(activeHotbarSlot, itemStack); + } else if (this.pattern == 1) { + ItemContainer utility = inventory.getUtility(); + byte activeUtilitySlot = inventory.getActiveUtilitySlot(); + if (activeUtilitySlot < 0) { + activeUtilitySlot = 0; + inventory.setActiveToolsSlot((byte) 0); + } + utility.setItemStackForSlot(activeUtilitySlot, itemStack); + } else if (this.pattern == 2) { + ItemContainer tools = inventory.getTools(); + byte activeToolSlot = inventory.getActiveToolsSlot(); + if (activeToolSlot < 0) { + inventory.setUsingToolsItem(true); + inventory.setActiveToolsSlot((byte) 1); + activeToolSlot = 1; + } + tools.setItemStackForSlot(activeToolSlot, itemStack); + } + } + } + + @Override + public boolean isSingle() { + return this.entities.isSingle(); + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + String type = switch (this.pattern) { + case 0 -> "hotbar"; + case 1 -> "utility"; + case 2 -> "tool"; + default -> "unknown"; + }; + return type + " item of " + this.entities.toString(ctx, debug); + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprInventorySlots.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprInventorySlots.java new file mode 100644 index 00000000..1eafd760 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/item/ExprInventorySlots.java @@ -0,0 +1,63 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.item; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.server.core.inventory.Inventory; +import com.hypixel.hytale.server.core.inventory.container.ItemContainer; +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.Optional; + +public class ExprInventorySlots implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprInventorySlots.class, Number.class, false, + "slots (of|in) %inventory/itemcontainer%") + .name("Inventory Slots") + .description("Returns all slots in an Inventory or ItemContainer as numbers.") + .examples("loop slots of inventory of player:", + "loop slots of hotbar item container of inventory of player:") + .since("INSERT VERSION") + .register(); + } + + private Expression object; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.object = expressions[0]; + return true; + } + + @Override + public Number[] getValues(@NotNull TriggerContext ctx) { + Optional single = this.object.getSingle(ctx); + if (single.isEmpty()) return null; + Object object = single.get(); + + List slots = new ArrayList<>(); + if (object instanceof Inventory inventory) { + int containersSize = inventory.getCombinedEverything().getContainersSize(); + for (int i = 0; i < containersSize; i++) { + slots.add(i); + } + } else if (object instanceof ItemContainer itemContainer) { + short capacity = itemContainer.getCapacity(); + for (short i = 0; i < capacity; i++) { + slots.add(i); + } + } + + return slots.toArray(Number[]::new); + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "slots of " + this.object.toString(ctx, debug); + } + +} 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 0a2d05ee..d41b3d1d 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,26 +1,35 @@ package com.github.skriptdev.skript.plugin.elements.expressions.item; +import com.github.skriptdev.skript.api.hytale.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; import io.github.syst3ms.skriptparser.lang.properties.PropertyExpression; import io.github.syst3ms.skriptparser.registration.SkriptRegistration; import org.jetbrains.annotations.Nullable; -public class ExprItemType extends PropertyExpression { +public class ExprItemType extends PropertyExpression { public static void register(SkriptRegistration registration) { registration.newPropertyExpression(ExprItemType.class, Item.class, - "item[[ ]type]", "itemstack") + "item[[ ]type]", "itemstack/blocktype/block") .name("Item Type") - .description("Returns the item type of an itemstack.") - .examples("set {_item} to itemtype of {_item}") + .description("Returns the item type of an ItemStack, BlockType or Block.", + "If the Block/BlockType doesn't have an associated item, it returns null.") + .examples("set {_item} to itemtype of {_item}", + "set {_item} to itemtype of block at player's location") .since("1.0.0") .register(); } @Override - public @Nullable Item getProperty(ItemStack owner) { - return owner.getItem(); + public @Nullable Item getProperty(Object owner) { + return switch (owner) { + case ItemStack itemStack -> itemStack.getItem(); + case BlockType blockType -> blockType.getItem(); + case Block block -> block.getType().getItem(); + default -> null; + }; } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprCast.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprCast.java new file mode 100644 index 00000000..51f20a50 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprCast.java @@ -0,0 +1,69 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.other; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import io.github.syst3ms.skriptparser.lang.Expression; +import io.github.syst3ms.skriptparser.lang.Literal; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.log.ErrorType; +import io.github.syst3ms.skriptparser.parsing.ParseContext; +import io.github.syst3ms.skriptparser.types.Type; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Function; + +public class ExprCast implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprCast.class, Object.class, true, + "<.+> as %*type%") + .name("Cast") + .description("Casts an object to a specific type.") + .examples("set {_i} to ingredient_poop as Item", + "set {_bt} to ingredient_poop as BlockType", + "set {_f} to 1 as Float") + .since("INSERT VERSION") + .register(); + } + + private String castable; + private Type type; + private Function parser; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + this.castable = parseContext.getMatches().getFirst().group(); + Literal> expression = (Literal>) expressions[0]; + this.type = expression.getSingle().orElse(null); + if (this.type == null) { + // This shouldn't happen, but let's be safe; + parseContext.getLogger().error("Type cannot be null for cast expression initialization.", ErrorType.SEMANTIC_ERROR); + return false; + } + if (this.type.getLiteralParser().isEmpty()) { + String baseName = this.type.getBaseName(); + parseContext.getLogger().error("The type '" + baseName + "' cannot be casted.", ErrorType.SEMANTIC_ERROR); + return false; + } + this.parser = this.type.getLiteralParser().get(); + + return true; + } + + @Override + public Object[] getValues(@NotNull TriggerContext ctx) { + Object apply = this.parser.apply(castable); + return new Object[]{apply}; + } + + @Override + public Class getReturnType() { + return this.type.getTypeClass(); + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return this.castable + " as " + this.type; + } + +} diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprDistance.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprDistance.java new file mode 100644 index 00000000..0e5c96f0 --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprDistance.java @@ -0,0 +1,49 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.other; + +import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.math.vector.Location; +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.Optional; + +public class ExprDistance implements Expression { + + public static void register(SkriptRegistration reg) { + reg.newExpression(ExprDistance.class, Number.class, true, + "distance between %location% and %location%") + .name("Distance Between Locations") + .description("Returns the distance between two locations.") + .examples("set {_distance} to distance between player's location and location of target block") + .since("INSERT VERSION") + .register(); + } + + private Expression loc1, loc2; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { + this.loc1 = (Expression) expressions[0]; + this.loc2 = (Expression) expressions[1]; + return true; + } + + @Override + public Number[] getValues(@NotNull TriggerContext ctx) { + Optional single = this.loc1.getSingle(ctx); + Optional single2 = this.loc2.getSingle(ctx); + if (single.isEmpty() || single2.isEmpty()) return null; + Location loc1 = single.get(); + Location loc2 = single2.get(); + return new Number[]{loc1.getPosition().distanceTo(loc2.getPosition())}; + } + + @Override + public String toString(@NotNull TriggerContext ctx, boolean debug) { + return "distance between " + this.loc1.toString(ctx, debug) + " and " + this.loc2.toString(ctx, debug); + } + +} 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 5ca4021a..09e44f8e 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 @@ -18,7 +18,8 @@ public static void register(SkriptRegistration reg) { "location %direction% [of] %location%", "location %number% [block[s]] %direction% [of] %location%") .name("Location Direction") - .description("Returns a location at the specified direction and location with an optional offset.") + .description("Returns a location at the specified direction and location with an optional offset.", + "The parser is broken, and even thought 'of' is optional, you have to put it.") .examples("set {_loc} to location above {_loc}", "set {_loc} to location 3 north of location of player", "set {_loc} to location 3 blocks below location of player") 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 f45e8dc8..c522b044 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 @@ -5,21 +5,16 @@ import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent; 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.parsing.ParseContext; +import io.github.syst3ms.skriptparser.lang.properties.PropertyExpression; import io.github.syst3ms.skriptparser.registration.SkriptRegistration; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; - -public class ExprLocationOf implements Expression { +public class ExprLocationOf extends PropertyExpression { public static void register(SkriptRegistration registration) { - registration.newExpression(ExprLocationOf.class, Location.class, false, - "location[s] of %blocks/entities%", - "%entities/blocks%'[s] location[s]") + registration.newPropertyExpression(ExprLocationOf.class, Location.class, + "location", "blocks/entities") .name("Location of Block/Entity") .description("Returns the location of a block or entity.") .examples("set {_loc} to location of context-player") @@ -27,40 +22,18 @@ public static void register(SkriptRegistration registration) { .register(); } - private Expression objects; - - @Override - public boolean init(Expression[] expressions, int matchedPattern, @NotNull ParseContext parseContext) { - this.objects = expressions[0]; - return true; - } - @SuppressWarnings("removal") @Override - public Location[] getValues(@NotNull TriggerContext ctx) { - List locations = new ArrayList<>(); - for (Object o : this.objects.getArray(ctx)) { - if (o instanceof Entity entity) { - World world = entity.getWorld(); - assert world != null; - TransformComponent transform = entity.getTransformComponent(); - locations.add(new Location(world.getName(), transform.getPosition())); - } else if (o instanceof Block block) { - locations.add(block.getLocation()); - } + public @Nullable Location getProperty(@NotNull Object owner) { + if (owner instanceof Entity entity) { + World world = entity.getWorld(); + assert world != null; + TransformComponent transform = entity.getTransformComponent(); + return new Location(world.getName(), transform.getPosition()); + } else if (owner instanceof Block block) { + return block.getLocation(); } - return locations.toArray(new Location[0]); - } - - @Override - public boolean isSingle() { - return this.objects.isSingle(); - } - - @Override - public String toString(@NotNull TriggerContext ctx, boolean debug) { - String plural = this.objects.isSingle() ? "" : "s"; - return "location" + plural + " of " + this.objects.toString(ctx, debug); + return null; } } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprMessage.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprMessage.java index 0737f908..a5f750c2 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprMessage.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/other/ExprMessage.java @@ -14,10 +14,10 @@ public class ExprMessage implements Expression { public static void register(SkriptRegistration registration) { registration.newExpression(ExprMessage.class, Message.class, true, - "[new] [raw] message from %string%", - "[new] translated message from %string%", - "[new] message translation from %string%", - "[new] formatted message from %string%") + "[new] [raw] message [from] %string%", + "[new] translated message [from] %string%", + "[new] message translation [from] %string%", + "[new] formatted [message] [from] %string%") .name("Message") .description("Create a new message from a string.", "The translated option will use a translation key from the game's lang file instead of a raw string.", 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 f1927500..f46be281 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,7 +1,9 @@ package com.github.skriptdev.skript.plugin.elements.types; import com.github.skriptdev.skript.api.hytale.Block; +import com.github.skriptdev.skript.api.skript.registration.EnumRegistry; import com.github.skriptdev.skript.api.skript.registration.SkriptRegistration; +import com.hypixel.hytale.protocol.InteractionType; public class TypesBlock { @@ -12,6 +14,11 @@ static void register(SkriptRegistration registration) { .since("1.0.0") .toStringFunction(Block::toTypeString) .register(); + EnumRegistry.register(registration, InteractionType.class, "interactiontype", "interactiontype@s") + .name("Interaction Type") + .description("Represents the types of interactions that can be performed on a block.") + .since("INSERT VERSION") + .register(); } }