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 5f8363fe..20339533 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 @@ -12,6 +12,7 @@ import com.github.skriptdev.skript.plugin.elements.events.entity.EvtLivingEntityInvChange; 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; 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; @@ -43,6 +44,7 @@ public static void register(SkriptRegistration registration) { // PLAYER EvtPlayerAddToWorld.register(registration); EvtPlayerBreakBlock.register(registration); + EvtPlayerChangeGameMode.register(registration); EvtPlayerChat.register(registration); EvtPlayerDamageBlock.register(registration); EvtPlayerDrainFromWorld.register(registration); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerChangeGameMode.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerChangeGameMode.java new file mode 100644 index 00000000..f366f8be --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/events/player/EvtPlayerChangeGameMode.java @@ -0,0 +1,124 @@ +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.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.GameMode; +import com.hypixel.hytale.server.core.entity.entities.Player; +import com.hypixel.hytale.server.core.event.events.ecs.ChangeGameModeEvent; +import com.hypixel.hytale.server.core.universe.PlayerRef; +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 io.github.syst3ms.skriptparser.registration.context.ContextValue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class EvtPlayerChangeGameMode extends SystemEvent> { + + public static void register(SkriptRegistration reg) { + reg.newEvent(EvtPlayerChangeGameMode.class, "[player(s| )] game[(-| )]mode change[s]") + .setHandledContexts(PlayerChangeGameModeContext.class) + .name("Player Change GameMode") + .description("Called when a player's game-mode is changed.") + .since("INSERT VERSION") + .register(); + + reg.newSingleContextValue(PlayerChangeGameModeContext.class, GameMode.class, "game[(-| )]mode", PlayerChangeGameModeContext::getOldGameMode) + .setState(ContextValue.State.PAST) + .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) + .register(); + reg.newSingleContextValue(PlayerChangeGameModeContext.class, GameMode.class, "game[(-| )]mode", PlayerChangeGameModeContext::getNewGameMode) + .setState(ContextValue.State.PRESENT) + .setUsage(ContextValue.Usage.EXPRESSION_OR_ALONE) + .addSetter(PlayerChangeGameModeContext::setNewGameMode) + .register(); + } + + private static ChangeGameModeEventSystem SYSTEM; + + @Override + public boolean init(Expression[] expressions, int matchedPattern, ParseContext parseContext) { + if (SYSTEM == null) { + SYSTEM = new ChangeGameModeEventSystem(ChangeGameModeEvent.class); + applySystem(SYSTEM); + } + return true; + } + + @Override + public boolean check(@NotNull TriggerContext triggerContext) { + return triggerContext instanceof PlayerChangeGameModeContext; + } + + @Override + public String toString(@Nullable TriggerContext triggerContext, boolean debug) { + return "player change gamemode"; + } + + private record PlayerChangeGameModeContext(ChangeGameModeEvent event, Player player) + implements PlayerContext, CancellableContext { + + public Player getPlayer() { + return this.player; + } + + public GameMode getNewGameMode() { + return event.getGameMode(); + } + + public GameMode getOldGameMode() { + return getPlayer().getGameMode(); + } + + public void setNewGameMode(GameMode gameMode) { + event.setGameMode(gameMode); + } + + @Override + public String getName() { + return "player change gamemode context"; + } + + @Override + public boolean isCancelled() { + return event.isCancelled(); + } + + @Override + public void setCancelled(boolean cancelled) { + event.setCancelled(cancelled); + } + } + + private static final class ChangeGameModeEventSystem extends EntityEventSystem { + + private ChangeGameModeEventSystem(@NotNull Class eventType) { + super(eventType); + } + + @Override + public void handle(int i, @NotNull ArchetypeChunk archetypeChunk, @NotNull Store store, @NotNull CommandBuffer commandBuffer, @NotNull ChangeGameModeEvent event) { + + Ref ref = archetypeChunk.getReferenceTo(i); + Player player = store.getComponent(ref, Player.getComponentType()); + if (player == null) return; + + TriggerMap.callTriggersByContext(new PlayerChangeGameModeContext(event, player)); + } + + @Override + public @NotNull Query getQuery() { + return PlayerRef.getComponentType(); + } + } +} 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 c647b549..0bc119cf 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 @@ -46,6 +46,7 @@ import com.github.skriptdev.skript.plugin.elements.expressions.other.ExprVector3i; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprAllPlayers; 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.ExprPlayerPermissionGroup; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerPermissions; import com.github.skriptdev.skript.plugin.elements.expressions.player.ExprPlayerSpawns; @@ -114,6 +115,7 @@ public static void register(SkriptRegistration registration) { // PLAYER ExprAllPlayers.register(registration); ExprChatMessage.register(registration); + ExprGameMode.register(registration); ExprPlayerPermissionGroup.register(registration); ExprPlayerPermissions.register(registration); ExprPlayerSpawns.register(registration); diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java index dafb1883..541d599d 100644 --- a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/entity/ExprName.java @@ -1,5 +1,6 @@ package com.github.skriptdev.skript.plugin.elements.expressions.entity; +import com.hypixel.hytale.protocol.GameMode; import com.hypixel.hytale.server.core.entity.Entity; import com.hypixel.hytale.server.core.entity.entities.Player; import com.hypixel.hytale.server.core.universe.PlayerRef; @@ -28,6 +29,7 @@ public static void register(SkriptRegistration registration) { case Player player -> player.getDisplayName(); case Entity entity -> entity.getLegacyDisplayName(); case World world -> world.getName(); + case GameMode gameMode -> gameMode.name(); default -> null; }; } diff --git a/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprGameMode.java b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprGameMode.java new file mode 100644 index 00000000..5ab49d4b --- /dev/null +++ b/src/main/java/com/github/skriptdev/skript/plugin/elements/expressions/player/ExprGameMode.java @@ -0,0 +1,56 @@ +package com.github.skriptdev.skript.plugin.elements.expressions.player; + +import com.hypixel.hytale.protocol.GameMode; +import com.hypixel.hytale.server.core.entity.entities.Player; +import io.github.syst3ms.skriptparser.lang.TriggerContext; +import io.github.syst3ms.skriptparser.lang.properties.PropertyExpression; +import io.github.syst3ms.skriptparser.registration.SkriptRegistration; +import io.github.syst3ms.skriptparser.types.changers.ChangeMode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ExprGameMode extends PropertyExpression { + + public static void register(SkriptRegistration registration) { + registration.newPropertyExpression(ExprGameMode.class, GameMode.class, "game[(-| )]mode", "players") + .name("GameMode of a player") + .description("Returns the game mode of a player.") + .examples("set {_gm} to game-mode of context-player") + .since("INSERT VERSION") + .register(); + } + + @Override + public @Nullable GameMode getProperty(@NotNull Object owner) { + if (owner instanceof Player player) { + return player.getGameMode(); + } + return null; + } + + @Override + public Optional[]> acceptsChange(@NotNull ChangeMode mode) { + if (mode == ChangeMode.SET) return Optional.of(new Class[]{GameMode.class}); + return Optional.empty(); + } + + @SuppressWarnings("ConstantConditions") + @Override + public void change(@NotNull TriggerContext ctx, @NotNull ChangeMode changeMode, @NotNull Object[] changeWith) { + if (changeMode != ChangeMode.SET || changeWith == null) return; + GameMode newGameMode = changeWith[0] instanceof GameMode ? (GameMode) changeWith[0] : null; + if (newGameMode == null) return; + + Optional owner = getOwner().getSingle(ctx); + if (!(owner.isPresent() && owner.get() instanceof Player player)) return; + + Player.setGameMode(player.getReference(), newGameMode, player.getReference().getStore()); + } + + @Override + public Class getReturnType() { + return GameMode.class; + } +} 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 c97ca8bc..d17fad82 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 @@ -9,6 +9,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.GameMode; import com.hypixel.hytale.protocol.Vector2f; import com.hypixel.hytale.server.core.HytaleServer; import com.hypixel.hytale.server.core.Message; @@ -18,6 +19,7 @@ import com.hypixel.hytale.server.core.receiver.IMessageReceiver; import io.github.syst3ms.skriptparser.types.changers.TypeSerializer; import org.bson.BsonDocument; +import org.bson.BsonInt32; import org.bson.BsonString; import org.bson.BsonValue; import org.jetbrains.annotations.NotNull; @@ -175,6 +177,9 @@ public Location deserialize(@NotNull Gson gson, @NotNull JsonElement element) { }) .since("1.0.0") .register(); + registration.newType(GameMode.class, "gamemode", "gamemode@s") + .name("GameMode") + .description("Represents a game mode.") + .since("INSERT VERSION").register(); } - }