From 2dc7c6d749436f3fea84340e9a00a10d89a5a6aa Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Mon, 9 Oct 2023 20:33:03 +0300 Subject: [PATCH] Rework action targeting to support custom targets --- .../lovetropics/minigames/LoveTropics.java | 2 + .../behavior/EqualizeCurrencyBehavior.java | 2 +- .../behavior/tutorial/BbTutorialAction.java | 36 ++--- .../turtle_race/RaceTrackBehavior.java | 2 +- .../core/game/behavior/GameBehaviorTypes.java | 2 +- .../game/behavior/action/ActionTarget.java | 23 +++ .../behavior/action/ActionTargetTypes.java | 42 +++++ .../game/behavior/action/GameActionList.java | 147 ++++++++---------- .../behavior/action/NoneActionTarget.java | 26 ++++ .../behavior/action/PlayerActionTarget.java | 72 +++++++++ .../behavior/action/PlotActionTarget.java | 69 ++++++++ .../game/behavior/event/GameActionEvents.java | 31 +++- .../action/ApplyGlobalDisguiseAction.java | 2 +- .../instances/action/ChestDropAction.java | 2 +- .../instances/action/CountdownAction.java | 4 +- .../instances/action/RunCommandsAction.java | 2 +- .../instances/action/SetBlocksAction.java | 2 +- .../action/SetExtendingBlocksAction.java | 2 +- .../SpawnEntitiesAtRegionsOverTimeAction.java | 2 +- .../action/SpawnEntityAtRegionsAction.java | 2 +- .../instances/action/SpawnTornadoAction.java | 3 +- .../instances/action/SwapPlayersAction.java | 2 +- .../instances/action/TargetPlayerAction.java | 4 +- .../instances/action/WeatherEventAction.java | 2 +- .../donation/DonationPackageBehavior.java | 7 +- .../donation/DonationThresholdBehavior.java | 2 +- .../trigger/BindControlsBehavior.java | 5 +- .../trigger/GeneralEventsTrigger.java | 4 +- .../instances/trigger/OnDamageTrigger.java | 2 +- .../instances/trigger/OnDeathTrigger.java | 2 +- .../instances/trigger/OnKillTrigger.java | 2 +- .../instances/trigger/PhaseChangeTrigger.java | 4 +- .../trigger/ScheduledActionsTrigger.java | 20 ++- .../trigger/WeatherChangeTrigger.java | 2 +- .../trigger/WhileInRegionTrigger.java | 2 +- 35 files changed, 386 insertions(+), 149 deletions(-) create mode 100644 src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTarget.java create mode 100644 src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTargetTypes.java create mode 100644 src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/NoneActionTarget.java create mode 100644 src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlayerActionTarget.java create mode 100644 src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlotActionTarget.java diff --git a/src/main/java/com/lovetropics/minigames/LoveTropics.java b/src/main/java/com/lovetropics/minigames/LoveTropics.java index 9540108d6..66c7edc50 100644 --- a/src/main/java/com/lovetropics/minigames/LoveTropics.java +++ b/src/main/java/com/lovetropics/minigames/LoveTropics.java @@ -34,6 +34,7 @@ import com.lovetropics.minigames.common.core.dimension.RuntimeDimensions; import com.lovetropics.minigames.common.core.game.IGameManager; import com.lovetropics.minigames.common.core.game.behavior.GameBehaviorTypes; +import com.lovetropics.minigames.common.core.game.behavior.action.ActionTargetTypes; import com.lovetropics.minigames.common.core.game.client_state.GameClientStateTypes; import com.lovetropics.minigames.common.core.game.impl.GameEventDispatcher; import com.lovetropics.minigames.common.core.game.predicate.entity.EntityPredicates; @@ -132,6 +133,7 @@ public LoveTropics() { MinigameItems.init(); GameBehaviorTypes.init(modBus); + ActionTargetTypes.init(modBus); EntityPredicates.init(modBus); GameClientStateTypes.init(modBus); StreamHosts.init(); diff --git a/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/EqualizeCurrencyBehavior.java b/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/EqualizeCurrencyBehavior.java index 45f42ebb7..18b50b86a 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/EqualizeCurrencyBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/EqualizeCurrencyBehavior.java @@ -15,7 +15,7 @@ public class EqualizeCurrencyBehavior implements IGameBehavior { public void register(IGamePhase game, EventRegistrar events) throws GameException { CurrencyManager currency = game.getState().getOrThrow(CurrencyManager.KEY); - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { currency.equalize(); return true; }); diff --git a/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/tutorial/BbTutorialAction.java b/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/tutorial/BbTutorialAction.java index bc138c03b..b97534e75 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/tutorial/BbTutorialAction.java +++ b/src/main/java/com/lovetropics/minigames/common/content/biodiversity_blitz/behavior/tutorial/BbTutorialAction.java @@ -12,6 +12,7 @@ import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; import com.lovetropics.minigames.common.core.game.behavior.event.GameActionEvents; import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents; +import com.mojang.authlib.GameProfile; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; @@ -33,9 +34,11 @@ import net.minecraft.world.level.block.FarmBlock; import net.minecraft.world.level.block.LevelEvent; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.util.FakePlayerFactory; import java.util.HashSet; import java.util.Set; +import java.util.UUID; // TODO: this is extremely hardcoded for now, need to split up! public class BbTutorialAction implements IGameBehavior { @@ -63,22 +66,17 @@ public BbTutorialAction(PlantType diffusa, PlantType grass, PlantType wheat, boo @Override public void register(IGamePhase game, EventRegistrar events) throws GameException { - PlotsState plots = game.getState().getOrThrow(PlotsState.KEY); tutorialActions = new Reference2ObjectOpenHashMap<>(); tutorialPlots = new HashSet<>(); - // TODO: make an "apply to plot" event - events.listen(GameActionEvents.APPLY_TO_PLAYER, (context, target) -> { - Plot playerPlot = plots.getPlotFor(target); - if (playerPlot == null) { - return false; - } - + events.listen(GameActionEvents.APPLY_TO_PLOT, (context, playerPlot) -> { // Don't run the same tutorial twice per plot if (!tutorialPlots.add(playerPlot)) { return false; } + final GameProfile playerProfile = new GameProfile(UUID.randomUUID(), "PlotFakePlayer"); + final ServerPlayer target = FakePlayerFactory.get(game.getWorld(), playerProfile); Long2ObjectMap actions = new Long2ObjectOpenHashMap<>(); tutorialActions.put(target, actions); long ticks = game.ticks() + 4; @@ -102,14 +100,14 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio actions.put(ticks, () -> { BlockPos pos = sample.relative(playerPlot.forward, 12); - Mob entity = new BbTutorialHuskEntity(EntityType.HUSK, target.level(), playerPlot); + Mob entity = new BbTutorialHuskEntity(EntityType.HUSK, game.getWorld(), playerPlot); Direction direction = playerPlot.forward.getOpposite(); entity.moveTo(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, direction.toYRot(), 0); - target.level().addFreshEntity(entity); + game.getWorld().addFreshEntity(entity); - entity.finalizeSpawn(target.serverLevel(), target.level().getCurrentDifficultyAt(pos), MobSpawnType.MOB_SUMMONED, null, null); + entity.finalizeSpawn(game.getWorld(), game.getWorld().getCurrentDifficultyAt(pos), MobSpawnType.MOB_SUMMONED, null, null); }); ticks += 240; @@ -163,7 +161,7 @@ private long placeBlocks(IGamePhase game, ServerPlayer target, Plot playerPlot, // Farmland row for (int i = -1; i < 13; i++) { BlockPos pos = sample.relative(playerPlot.forward, -5).relative(cw, i - 5); - if (playerPlot.plantBounds.contains(pos) && target.level().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { + if (playerPlot.plantBounds.contains(pos) && game.getWorld().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { actions.put(ticks, new SetFarmland(target, pos.below())); ticks += 5; } @@ -172,7 +170,7 @@ private long placeBlocks(IGamePhase game, ServerPlayer target, Plot playerPlot, // Farmland row for (int i = -1; i < 13; i++) { BlockPos pos = sample.relative(playerPlot.forward, -4).relative(cw, i - 5); - if (playerPlot.plantBounds.contains(pos) && target.level().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { + if (playerPlot.plantBounds.contains(pos) && game.getWorld().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { actions.put(ticks, new SetFarmland(target, pos.below())); ticks += 5; } @@ -234,7 +232,7 @@ private long breakBlocks(IGamePhase game, ServerPlayer target, Plot playerPlot, for (int i = -1; i < 13; i++) { BlockPos pos = sample.relative(playerPlot.forward, -4).relative(cw, i - 5); // how does this work??? there's farmland here!! but removing this breaks it?!?! - if (playerPlot.plantBounds.contains(pos) && target.level().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { + if (playerPlot.plantBounds.contains(pos) && game.getWorld().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { actions.put(ticks, new SetGrass(target, pos.below())); ticks += 3; } @@ -243,7 +241,7 @@ private long breakBlocks(IGamePhase game, ServerPlayer target, Plot playerPlot, // Farmland row for (int i = -1; i < 13; i++) { BlockPos pos = sample.relative(playerPlot.forward, -5).relative(cw, i - 5); - if (playerPlot.plantBounds.contains(pos) && target.level().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { + if (playerPlot.plantBounds.contains(pos) && game.getWorld().getBlockState(pos.below()).getBlock() == Blocks.GRASS_BLOCK) { actions.put(ticks, new SetGrass(target, pos.below())); ticks += 3; } @@ -287,8 +285,8 @@ public record SetPlant(IGamePhase game, ServerPlayer target, Plot playerPlot, Bl public void run() { Plant plant = game.invoker(BbEvents.PLACE_PLANT).placePlant(target, playerPlot, sample, type).getObject(); if (plant != null) { - target.level().levelEvent(null, LevelEvent.PARTICLES_DESTROY_BLOCK, sample, Block.getId(target.level().getBlockState(plant.coverage().getOrigin()))); - target.level().playSound(null, sample, sound, SoundSource.BLOCKS, 0.4F, 1.0F); + game.getWorld().levelEvent(null, LevelEvent.PARTICLES_DESTROY_BLOCK, sample, Block.getId(game.getWorld().getBlockState(plant.coverage().getOrigin()))); + game.getWorld().playSound(null, sample, sound, SoundSource.BLOCKS, 0.4F, 1.0F); } } } @@ -303,8 +301,8 @@ public void run() { boolean placed = game.invoker(BbEvents.BREAK_PLANT).breakPlant(target, playerPlot, plant); if (placed) { - target.level().levelEvent(null, LevelEvent.PARTICLES_DESTROY_BLOCK, sample, Block.getId(target.level().getBlockState(plant.coverage().getOrigin()))); - target.level().playSound(null, sample, sound, SoundSource.BLOCKS, 0.4F, 1.0F); + game.getWorld().levelEvent(null, LevelEvent.PARTICLES_DESTROY_BLOCK, sample, Block.getId(game.getWorld().getBlockState(plant.coverage().getOrigin()))); + game.getWorld().playSound(null, sample, sound, SoundSource.BLOCKS, 0.4F, 1.0F); } } } diff --git a/src/main/java/com/lovetropics/minigames/common/content/turtle_race/RaceTrackBehavior.java b/src/main/java/com/lovetropics/minigames/common/content/turtle_race/RaceTrackBehavior.java index 23be68842..65e6e153b 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/turtle_race/RaceTrackBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/content/turtle_race/RaceTrackBehavior.java @@ -162,7 +162,7 @@ private void registerCheckpoints(IGamePhase game, EventRegistrar events) { for (BlockBox region : regions) { registerCheckpoint(region, (player, state) -> { - actions.apply(game, GameActionContext.EMPTY, player); + actions.applyPlayer(game, GameActionContext.EMPTY, player); return false; }); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/GameBehaviorTypes.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/GameBehaviorTypes.java index 6c725c16c..9d88e4e85 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/GameBehaviorTypes.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/GameBehaviorTypes.java @@ -128,7 +128,7 @@ public class GameBehaviorTypes { public static final GameBehaviorEntry ON_DEATH = register("on_death", OnDeathTrigger.CODEC); public static final GameBehaviorEntry ON_DAMAGE = register("on_damage", OnDamageTrigger.CODEC); public static final GameBehaviorEntry WHILE_IN_REGION = register("while_in_region", WhileInRegionTrigger.CODEC); - public static final GameBehaviorEntry SCHEDULED_ACTIONS = register("scheduled_actions", ScheduledActionsTrigger.CODEC); + public static final GameBehaviorEntry> SCHEDULED_ACTIONS = register("scheduled_actions", ScheduledActionsTrigger.CODEC); public static final GameBehaviorEntry PHASE_CHANGE = register("phase_change", PhaseChangeTrigger.CODEC); public static final GameBehaviorEntry ON_KILL = register("on_kill", OnKillTrigger.CODEC); public static final GameBehaviorEntry BIND_CONTROLS = register("bind_controls", BindControlsBehavior.CODEC); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTarget.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTarget.java new file mode 100644 index 000000000..acdff7305 --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTarget.java @@ -0,0 +1,23 @@ +package com.lovetropics.minigames.common.core.game.behavior.action; + +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.event.GameEventListeners; +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import net.minecraft.util.ExtraCodecs; + +import java.util.List; +import java.util.function.Function; + +public interface ActionTarget { + Codec> CODEC = ExtraCodecs.lazyInitializedCodec(() -> ActionTargetTypes.REGISTRY.get().getCodec()) + .dispatch(ActionTarget::type, Function.identity()); + Codec> FALLBACK_PLAYER = ExtraCodecs.xor(CODEC, PlayerActionTarget.Target.CODEC) + .xmap(e -> e.map(Function.identity(), PlayerActionTarget::new), Either::left); + + List resolve(IGamePhase phase, Iterable sources); + + boolean apply(IGamePhase game, GameEventListeners listeners, GameActionContext context, Iterable sources); + + Codec> type(); +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTargetTypes.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTargetTypes.java new file mode 100644 index 000000000..ee22ba01f --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/ActionTargetTypes.java @@ -0,0 +1,42 @@ +package com.lovetropics.minigames.common.core.game.behavior.action; + +import com.lovetropics.minigames.Constants; +import com.lovetropics.minigames.LoveTropics; +import com.lovetropics.minigames.common.core.game.predicate.entity.EntityPredicate; +import com.lovetropics.minigames.common.core.game.predicate.entity.EntityTypeEntityPredicate; +import com.lovetropics.minigames.common.util.registry.LoveTropicsRegistrate; +import com.mojang.serialization.Codec; +import com.tterrag.registrate.util.entry.RegistryEntry; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.RegistryBuilder; +import net.minecraftforge.registries.RegistryObject; + +import java.util.function.Supplier; + +public class ActionTargetTypes { + public static final ResourceKey>>> REGISTRY_KEY = ResourceKey.createRegistryKey(new ResourceLocation(Constants.MODID, "action_target_types")); + public static final DeferredRegister>> REGISTER = DeferredRegister.create(REGISTRY_KEY, Constants.MODID); + + public static final Supplier>>> REGISTRY = REGISTER.makeRegistry(() -> new RegistryBuilder>>() + .disableSync() + .disableSaving()); + + private static final LoveTropicsRegistrate REGISTRATE = LoveTropics.registrate(); + + public static final RegistryObject> PLAYER = register("player", PlayerActionTarget.CODEC); + public static final RegistryObject> PLOT = register("plot", PlotActionTarget.CODEC); + public static final RegistryObject> NONE = register("none", NoneActionTarget.CODEC); + + public static > RegistryObject> register(final String name, final Codec codec) { + return REGISTER.register(name, () -> codec); + } + + public static void init(IEventBus modBus) { + REGISTER.register(modBus); + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionList.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionList.java index ea31f0db9..9ac412b91 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionList.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionList.java @@ -1,6 +1,5 @@ package com.lovetropics.minigames.common.core.game.behavior.action; -import com.google.common.collect.Lists; import com.lovetropics.lib.codec.MoreCodecs; import com.lovetropics.minigames.common.core.game.IGamePhase; import com.lovetropics.minigames.common.core.game.behavior.IGameBehavior; @@ -13,92 +12,72 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.StringRepresentable; import java.util.Arrays; import java.util.List; import java.util.function.Function; +import java.util.function.Supplier; + +public class GameActionList> { + public static final GameActionList EMPTY = new GameActionList<>(List.of(), PlayerActionTarget.SOURCE); + + public static final MapCodec> MAP_CODEC = RecordCodecBuilder.mapCodec(i -> i.group( + MoreCodecs.listOrUnit(IGameBehavior.CODEC).fieldOf("actions").forGetter(list -> list.behaviors), + ActionTarget.FALLBACK_PLAYER.optionalFieldOf("target", PlayerActionTarget.SOURCE).forGetter(list -> list.target) + ).apply(i, GameActionList::new)); + + private static final Codec> SIMPLE_CODEC = MoreCodecs.listOrUnit(IGameBehavior.CODEC) + .flatComapMap( + behaviors -> new GameActionList<>(behaviors, PlayerActionTarget.SOURCE), + list -> { + if (!(list.target instanceof PlayerActionTarget tg) || tg.target() != PlayerActionTarget.Target.SOURCE) { + return DataResult.error(() -> "Cannot encode simple action list with target: " + list.target); + } + return DataResult.success(list.behaviors); + } + ); + + public static final Codec CODEC = Codec.either(SIMPLE_CODEC, MAP_CODEC.codec()) + .xmap(either -> either.map(Function.identity(), Function.identity()), Either::right); + public static final Codec> TYPE_SAFE_CODEC = (Codec>) (Object) CODEC; + + private final List behaviors; + public final A target; + + private final GameEventListeners listeners = new GameEventListeners(); + + public GameActionList(List behaviors, A target) { + this.behaviors = behaviors; + this.target = target; + } + + public void register(IGamePhase game, EventRegistrar events) { + for (IGameBehavior behavior : behaviors) { + behavior.register(game, events.redirect(GameActionEvents::matches, listeners)); + } + } + + public boolean applyPlayer(IGamePhase game, GameActionContext context, ServerPlayer... sources) { + return applyPlayer(game, context, Arrays.asList(sources)); + } + + public boolean applyPlayer(IGamePhase game, GameActionContext context, Iterable sources) { + return this.applyIf(ActionTargetTypes.PLAYER, game, context, sources); + } + + public > boolean applyIf(Supplier> type, IGamePhase phase, GameActionContext context, Iterable sources) { + if (type.get() == target.type()) { + return apply(phase, context, (Iterable) sources); + } + return false; + } + + public boolean apply(IGamePhase phase, GameActionContext context) { + return apply(phase, context, target.resolve(phase, List.of())); + } + + public boolean apply(IGamePhase phase, GameActionContext context, Iterable sources) { + return listeners.invoker(GameActionEvents.APPLY).apply(context) | target.apply(phase, listeners, context, sources); + } -public class GameActionList { - public static final GameActionList EMPTY = new GameActionList(List.of(), Target.SOURCE); - - public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(i -> i.group( - MoreCodecs.listOrUnit(IGameBehavior.CODEC).fieldOf("actions").forGetter(list -> list.behaviors), - Target.CODEC.optionalFieldOf("target", Target.SOURCE).forGetter(list -> list.target) - ).apply(i, GameActionList::new)); - - private static final Codec SIMPLE_CODEC = MoreCodecs.listOrUnit(IGameBehavior.CODEC) - .flatComapMap( - behaviors -> new GameActionList(behaviors, Target.SOURCE), - list -> { - if (list.target != Target.SOURCE) { - return DataResult.error(() -> "Cannot encode simple action list with target: " + list.target.getSerializedName()); - } - return DataResult.success(list.behaviors); - } - ); - - public static final Codec CODEC = Codec.either(SIMPLE_CODEC, MAP_CODEC.codec()) - .xmap(either -> either.map(Function.identity(), Function.identity()), Either::right); - - private final List behaviors; - private final Target target; - - private final GameEventListeners listeners = new GameEventListeners(); - - public GameActionList(List behaviors, Target target) { - this.behaviors = behaviors; - this.target = target; - } - - public void register(IGamePhase game, EventRegistrar events) { - for (IGameBehavior behavior : behaviors) { - behavior.register(game, events.redirect(GameActionEvents::matches, listeners)); - } - } - - public boolean apply(IGamePhase game, GameActionContext context, ServerPlayer... sources) { - return apply(game, context, Arrays.asList(sources)); - } - - public boolean apply(IGamePhase game, GameActionContext context, Iterable sources) { - boolean result = listeners.invoker(GameActionEvents.APPLY).apply(context, sources); - for (ServerPlayer target : target.resolve(game, sources)) { - result |= listeners.invoker(GameActionEvents.APPLY_TO_PLAYER).apply(context, target); - } - return result; - } - - public enum Target implements StringRepresentable { - NONE("none"), - SOURCE("source"), - PARTICIPANTS("participants"), - SPECTATORS("spectators"), - ALL("all"), - ; - - public static final Codec CODEC = MoreCodecs.stringVariants(values(), Target::getSerializedName); - - private final String name; - - Target(String name) { - this.name = name; - } - - public List resolve(IGamePhase game, Iterable sources) { - // Copy the lists because we might otherwise get concurrent modification from whatever the actions do! - return switch (this) { - case NONE -> List.of(); - case SOURCE -> Lists.newArrayList(sources); - case PARTICIPANTS -> Lists.newArrayList(game.getParticipants()); - case SPECTATORS -> Lists.newArrayList(game.getSpectators()); - case ALL -> Lists.newArrayList(game.getAllPlayers()); - }; - } - - @Override - public String getSerializedName() { - return name; - } - } } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/NoneActionTarget.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/NoneActionTarget.java new file mode 100644 index 000000000..544968429 --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/NoneActionTarget.java @@ -0,0 +1,26 @@ +package com.lovetropics.minigames.common.core.game.behavior.action; + +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.event.GameEventListeners; +import com.mojang.serialization.Codec; + +import java.util.List; + +public record NoneActionTarget() implements ActionTarget { + public static final Codec CODEC = Codec.unit(NoneActionTarget::new); + + @Override + public List resolve(IGamePhase phase, Iterable sources) { + return List.of(); + } + + @Override + public boolean apply(IGamePhase game, GameEventListeners listeners, GameActionContext context, Iterable sources) { + return false; + } + + @Override + public Codec> type() { + return ActionTargetTypes.NONE.get(); + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlayerActionTarget.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlayerActionTarget.java new file mode 100644 index 000000000..d682191d5 --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlayerActionTarget.java @@ -0,0 +1,72 @@ +package com.lovetropics.minigames.common.core.game.behavior.action; + +import com.google.common.collect.Lists; +import com.lovetropics.lib.codec.MoreCodecs; +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.event.GameActionEvents; +import com.lovetropics.minigames.common.core.game.behavior.event.GameEventListeners; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.StringRepresentable; + +import java.util.List; + +public record PlayerActionTarget(Target target) implements ActionTarget { + public static final PlayerActionTarget SOURCE = new PlayerActionTarget(Target.SOURCE); + public static final Codec CODEC = RecordCodecBuilder.create(in -> in.group( + Target.CODEC.optionalFieldOf("target", PlayerActionTarget.Target.SOURCE).forGetter(PlayerActionTarget::target) + ).apply(in, PlayerActionTarget::new)); + + @Override + public List resolve(IGamePhase phase, Iterable sources) { + return target.resolve(phase, sources); + } + + @Override + public boolean apply(IGamePhase game, GameEventListeners listeners, GameActionContext actionContext, Iterable sources) { + boolean result = listeners.invoker(GameActionEvents.APPLY_TO_PLAYERS).apply(actionContext, sources); + for (ServerPlayer target : target.resolve(game, sources)) { + result |= listeners.invoker(GameActionEvents.APPLY_TO_PLAYER).apply(actionContext, target); + } + return result; + } + + @Override + public Codec> type() { + return ActionTargetTypes.PLAYER.get(); + } + + public enum Target implements StringRepresentable { + NONE("none"), + SOURCE("source"), + PARTICIPANTS("participants"), + SPECTATORS("spectators"), + ALL("all"), + ; + + public static final Codec CODEC = MoreCodecs.stringVariants(values(), PlayerActionTarget.Target::getSerializedName); + + private final String name; + + Target(String name) { + this.name = name; + } + + public List resolve(IGamePhase game, Iterable sources) { + // Copy the lists because we might otherwise get concurrent modification from whatever the actions do! + return switch (this) { + case NONE -> List.of(); + case SOURCE -> Lists.newArrayList(sources); + case PARTICIPANTS -> Lists.newArrayList(game.getParticipants()); + case SPECTATORS -> Lists.newArrayList(game.getSpectators()); + case ALL -> Lists.newArrayList(game.getAllPlayers()); + }; + } + + @Override + public String getSerializedName() { + return name; + } + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlotActionTarget.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlotActionTarget.java new file mode 100644 index 000000000..5000044ed --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/PlotActionTarget.java @@ -0,0 +1,69 @@ +package com.lovetropics.minigames.common.core.game.behavior.action; + +import com.google.common.collect.Lists; +import com.lovetropics.lib.codec.MoreCodecs; +import com.lovetropics.minigames.common.content.biodiversity_blitz.plot.Plot; +import com.lovetropics.minigames.common.content.biodiversity_blitz.plot.PlotsState; +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.event.GameActionEvents; +import com.lovetropics.minigames.common.core.game.behavior.event.GameEventListeners; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.StringRepresentable; + +import java.util.List; + +public record PlotActionTarget(Target target) implements ActionTarget { + public static final Codec CODEC = RecordCodecBuilder.create(in -> in.group( + Target.CODEC.optionalFieldOf("target", PlotActionTarget.Target.SOURCE).forGetter(PlotActionTarget::target) + ).apply(in, PlotActionTarget::new)); + + @Override + public List resolve(IGamePhase phase, Iterable sources) { + return target.resolve(phase, sources); + } + + @Override + public boolean apply(IGamePhase game, GameEventListeners listeners, GameActionContext actionContext, Iterable sources) { + boolean result = false; + for (Plot target : target.resolve(game, sources)) { + result |= listeners.invoker(GameActionEvents.APPLY_TO_PLOT).apply(actionContext, target); + } + return result; + } + + @Override + public Codec> type() { + return ActionTargetTypes.PLOT.get(); + } + + public enum Target implements StringRepresentable { + NONE("none"), + SOURCE("source"), + ALL("all"), + ; + + public static final Codec CODEC = MoreCodecs.stringVariants(values(), Target::getSerializedName); + + private final String name; + + Target(String name) { + this.name = name; + } + + public List resolve(IGamePhase game, Iterable sources) { + // Copy the lists because we might otherwise get concurrent modification from whatever the actions do! + return switch (this) { + case NONE -> List.of(); + case SOURCE -> Lists.newArrayList(sources); + case ALL -> Lists.newArrayList(game.getState().getOrThrow(PlotsState.KEY)); + }; + } + + @Override + public String getSerializedName() { + return name; + } + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/event/GameActionEvents.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/event/GameActionEvents.java index 4d3fa5c63..630504790 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/event/GameActionEvents.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/event/GameActionEvents.java @@ -1,12 +1,21 @@ package com.lovetropics.minigames.common.core.game.behavior.event; +import com.lovetropics.minigames.common.content.biodiversity_blitz.plot.Plot; import com.lovetropics.minigames.common.core.game.behavior.action.GameActionContext; import net.minecraft.server.level.ServerPlayer; public final class GameActionEvents { - public static final GameEventType APPLY = GameEventType.create(Apply.class, listeners -> (context, sources) -> { + public static final GameEventType APPLY = GameEventType.create(Apply.class, listeners -> context -> { boolean applied = false; for (Apply listener : listeners) { + applied |= listener.apply(context); + } + return applied; + }); + + public static final GameEventType APPLY_TO_PLAYERS = GameEventType.create(ApplyToPlayers.class, listeners -> (context, sources) -> { + boolean applied = false; + for (ApplyToPlayers listener : listeners) { applied |= listener.apply(context, sources); } return applied; @@ -20,18 +29,34 @@ public final class GameActionEvents { return applied; }); + public static final GameEventType APPLY_TO_PLOT = GameEventType.create(ApplyToPlot.class, listeners -> (context, target) -> { + boolean applied = false; + for (ApplyToPlot listener : listeners) { + applied |= listener.apply(context, target); + } + return applied; + }); + private GameActionEvents() { } public static boolean matches(GameEventType type) { - return type == APPLY || type == APPLY_TO_PLAYER; + return type == APPLY || type == APPLY_TO_PLAYERS || type == APPLY_TO_PLOT || type == APPLY_TO_PLAYER; + } + + public interface Apply { + boolean apply(GameActionContext context); } public interface ApplyToPlayer { boolean apply(GameActionContext context, ServerPlayer target); } - public interface Apply { + public interface ApplyToPlayers { boolean apply(GameActionContext context, Iterable sources); } + + public interface ApplyToPlot { + boolean apply(GameActionContext context, Plot plot); + } } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ApplyGlobalDisguiseAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ApplyGlobalDisguiseAction.java index 6e33c3fc8..073a7c2ee 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ApplyGlobalDisguiseAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ApplyGlobalDisguiseAction.java @@ -29,7 +29,7 @@ public ApplyGlobalDisguiseAction(DisguiseType disguise, int durationSeconds) { @Override public void register(IGamePhase game, EventRegistrar events) { - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { if (this.finishTime == -1) { this.apply(game); this.finishTime = game.ticks() + this.durationTicks; diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ChestDropAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ChestDropAction.java index a544d2f73..5054bee06 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ChestDropAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/ChestDropAction.java @@ -60,7 +60,7 @@ public void register(IGamePhase game, EventRegistrar events) { List delayedDrops = new ArrayList<>(); - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { int count = this.count.sample(random); for (int i = 0; i < count; i++) { BlockBox region = Util.getRandom(regions, random); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/CountdownAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/CountdownAction.java index 38ced1e91..0fea8e347 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/CountdownAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/CountdownAction.java @@ -43,7 +43,7 @@ public CountdownAction(long countdown, TemplatedText warning, GameActionList act public void register(IGamePhase game, EventRegistrar events) { actions.register(game, events); - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY_TO_PLAYERS, (context, sources) -> { queue.add(new QueueEntry(game.ticks() + countdown, context, sources)); return true; }); @@ -58,7 +58,7 @@ public void register(IGamePhase game, EventRegistrar events) { private boolean tickQueuedAction(IGamePhase game, QueueEntry entry) { long remainingTicks = entry.time() - game.ticks(); if (remainingTicks <= 0) { - return actions.apply(game, entry.context(), entry.sources()); + return actions.applyPlayer(game, entry.context(), entry.sources()); } else { for (ServerPlayer player : game.getAllPlayers()) { this.tickCountdown(player, remainingTicks); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/RunCommandsAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/RunCommandsAction.java index d3ddc9e18..1e497a508 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/RunCommandsAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/RunCommandsAction.java @@ -45,7 +45,7 @@ public void register(IGamePhase game, EventRegistrar events) { CommandDispatcher dispatcher = game.getServer().getCommands().getDispatcher(); CommandSourceStack source = createCommandSource(game); - events.listen(GameActionEvents.APPLY, (context, sources) -> executeCommands(dispatcher, source, globalCommands)); + events.listen(GameActionEvents.APPLY, (context) -> executeCommands(dispatcher, source, globalCommands)); events.listen(GameActionEvents.APPLY_TO_PLAYER, (context, target) -> { CommandSourceStack targetSource = source.withEntity(target).withPosition(target.position()); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetBlocksAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetBlocksAction.java index 518b30d7e..7657301d5 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetBlocksAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetBlocksAction.java @@ -63,7 +63,7 @@ public void register(IGamePhase game, EventRegistrar events) { throw new GameException(Component.literal("Regions not specified for block set behavior with a set time!")); } - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { for (BlockBox region : regions) { setInRegion(game, region); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetExtendingBlocksAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetExtendingBlocksAction.java index 6974c4c25..b7e4f9281 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetExtendingBlocksAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SetExtendingBlocksAction.java @@ -71,7 +71,7 @@ public void register(IGamePhase game, EventRegistrar events) { throw new GameException(Component.literal("Regions not specified for extending block set behavior!")); } - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { startTime = game.ticks(); return true; }); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntitiesAtRegionsOverTimeAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntitiesAtRegionsOverTimeAction.java index a76038737..ec0cddd8d 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntitiesAtRegionsOverTimeAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntitiesAtRegionsOverTimeAction.java @@ -61,7 +61,7 @@ public void register(IGamePhase game, EventRegistrar events) { events.listen(GamePhaseEvents.TICK, () -> tick(game)); } - private boolean applyPackage(GameActionContext context, Iterable sources) { + private boolean applyPackage(GameActionContext context) { ticksRemaining += ticksToSpawnFor; entityCountRemaining += entityCount; return true; diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntityAtRegionsAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntityAtRegionsAction.java index 2d31f0efe..c253a765e 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntityAtRegionsAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnEntityAtRegionsAction.java @@ -47,7 +47,7 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio regionsToSpawnAt.addAll(regions.get(key)); } - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { if (regionsToSpawnAt.isEmpty()) { return false; } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnTornadoAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnTornadoAction.java index ea49b9aa0..ddad70479 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnTornadoAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SpawnTornadoAction.java @@ -8,7 +8,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.level.ServerPlayer; import net.minecraftforge.fml.InterModComms; public record SpawnTornadoAction(boolean sharknado) implements IGameBehavior { @@ -18,7 +17,7 @@ public record SpawnTornadoAction(boolean sharknado) implements IGameBehavior { @Override public void register(IGamePhase game, EventRegistrar events) throws GameException { - events.listen(GameActionEvents.APPLY, (context, sources) -> spawnTornado(game)); + events.listen(GameActionEvents.APPLY, (context) -> spawnTornado(game)); } private boolean spawnTornado(IGamePhase game) { diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SwapPlayersAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SwapPlayersAction.java index e9f84ab87..65ebc32e8 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SwapPlayersAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/SwapPlayersAction.java @@ -22,7 +22,7 @@ public record SwapPlayersAction(double distanceThreshold) implements IGameBehavi @Override public void register(IGamePhase game, EventRegistrar events) { - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { if (this.distanceThreshold == Double.MAX_VALUE) { this.shufflePlayers(game); } else { diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/TargetPlayerAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/TargetPlayerAction.java index 87cf20252..d48870ebd 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/TargetPlayerAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/TargetPlayerAction.java @@ -23,12 +23,12 @@ public record TargetPlayerAction(UUID id, GameActionList actions) implements IGa public void register(IGamePhase game, EventRegistrar events) { actions.register(game, events); - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { ServerPlayer player = game.getAllPlayers().getPlayerBy(id); if (player == null) { return false; } - return actions.apply(game, context, List.of(player)); + return actions.applyPlayer(game, context, List.of(player)); }); } } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/WeatherEventAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/WeatherEventAction.java index fbc33a63a..7f1a68b9e 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/WeatherEventAction.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/WeatherEventAction.java @@ -32,7 +32,7 @@ public WeatherEventAction(WeatherEventType type, long seconds) { public void register(IGamePhase game, EventRegistrar events) { weather = game.getState().getOrThrow(GameWeatherState.KEY); - events.listen(GameActionEvents.APPLY, (context, sources) -> { + events.listen(GameActionEvents.APPLY, (context) -> { WeatherEvent event = this.tryCreateEvent(ticks); if (event != null) { weather.setEvent(event); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationPackageBehavior.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationPackageBehavior.java index fcb235527..c79a3e9e8 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationPackageBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationPackageBehavior.java @@ -19,7 +19,6 @@ import org.apache.logging.log4j.Logger; import java.util.List; -import java.util.function.Consumer; public final class DonationPackageBehavior implements IGameBehavior { public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( @@ -83,7 +82,7 @@ private InteractionResult receiveSpecific(IGamePhase game, GamePackage gamePacka } GameActionContext context = actionContext(gamePackage); - if (receiveActions.apply(game, context, receivingPlayer)) { + if (receiveActions.applyPlayer(game, context, receivingPlayer)) { data.onReceive(game, receivingPlayer, gamePackage.sendingPlayerName()); return InteractionResult.SUCCESS; @@ -97,7 +96,7 @@ private InteractionResult receiveRandom(IGamePhase game, GamePackage gamePackage final ServerPlayer randomPlayer = players.get(game.getWorld().getRandom().nextInt(players.size())); GameActionContext context = actionContext(gamePackage); - if (receiveActions.apply(game, context, randomPlayer)) { + if (receiveActions.applyPlayer(game, context, randomPlayer)) { data.onReceive(game, randomPlayer, gamePackage.sendingPlayerName()); return InteractionResult.SUCCESS; @@ -108,7 +107,7 @@ private InteractionResult receiveRandom(IGamePhase game, GamePackage gamePackage private InteractionResult receiveAll(IGamePhase game, GamePackage gamePackage) { GameActionContext context = actionContext(gamePackage); - if (!receiveActions.apply(game, context, game.getParticipants())) { + if (!receiveActions.applyPlayer(game, context, game.getParticipants())) { return InteractionResult.FAIL; } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationThresholdBehavior.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationThresholdBehavior.java index 834a72e83..0a9ad1a2f 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationThresholdBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/donation/DonationThresholdBehavior.java @@ -25,7 +25,7 @@ public void register(IGamePhase game, EventRegistrar events) { events.listen(GamePackageEvents.RECEIVE_DONATION, donation -> { if (donation.amount() >= threshold) { GameActionContext context = actionContext(donation); - actions.apply(game, context); + actions.applyPlayer(game, context); } }); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/BindControlsBehavior.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/BindControlsBehavior.java index 03e73d9f7..75e09a14d 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/BindControlsBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/BindControlsBehavior.java @@ -8,7 +8,6 @@ import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; import com.lovetropics.minigames.common.core.game.state.control.ControlCommand; import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; @@ -26,9 +25,9 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio game.getControlCommands().add(control, new ControlCommand(scope, source -> { Entity entity = source.getEntity(); if (entity instanceof ServerPlayer player) { - actions.apply(game, GameActionContext.EMPTY, player); + actions.applyPlayer(game, GameActionContext.EMPTY, player); } else { - actions.apply(game, GameActionContext.EMPTY); + actions.applyPlayer(game, GameActionContext.EMPTY); } })); })); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/GeneralEventsTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/GeneralEventsTrigger.java index faf0582b3..bc9cc3da0 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/GeneralEventsTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/GeneralEventsTrigger.java @@ -83,14 +83,14 @@ private void onPlayerSetRole(IGamePhase game, ServerPlayer player, @Nullable Pla private void invoke(IGamePhase game, String event) { GameActionList actions = eventActions.get(event); if (actions != null) { - actions.apply(game, GameActionContext.EMPTY); + actions.applyPlayer(game, GameActionContext.EMPTY); } } private void invoke(IGamePhase game, String event, ServerPlayer player) { GameActionList actions = eventActions.get(event); if (actions != null) { - actions.apply(game, GameActionContext.EMPTY, player); + actions.applyPlayer(game, GameActionContext.EMPTY, player); } } } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDamageTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDamageTrigger.java index c54fb72dd..0d380e41e 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDamageTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDamageTrigger.java @@ -19,7 +19,7 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio actions.register(game, events); events.listen(GamePlayerEvents.DAMAGE, (player, damageSource, amount) -> { - actions.apply(game, GameActionContext.EMPTY, player); + actions.applyPlayer(game, GameActionContext.EMPTY, player); return InteractionResult.PASS; }); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDeathTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDeathTrigger.java index cb5ebc2f0..bf0f57fd3 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDeathTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnDeathTrigger.java @@ -18,7 +18,7 @@ public void register(IGamePhase game, EventRegistrar events) { actions.register(game, events); events.listen(GamePlayerEvents.DEATH, (player, damageSource) -> { - actions.apply(game, GameActionContext.builder().set(GameActionParameter.KILLED, player).build(), player); + actions.applyPlayer(game, GameActionContext.builder().set(GameActionParameter.KILLED, player).build(), player); return InteractionResult.PASS; }); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnKillTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnKillTrigger.java index ee1e20667..34bf3d641 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnKillTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/OnKillTrigger.java @@ -24,7 +24,7 @@ public void register(IGamePhase game, EventRegistrar events) { .set(GameActionParameter.KILLED, player) .set(GameActionParameter.KILLER, killer) .build(); - actions.apply(game, context, killer); + actions.applyPlayer(game, context, killer); } return InteractionResult.PASS; }); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/PhaseChangeTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/PhaseChangeTrigger.java index d2b453a01..b0e9801d2 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/PhaseChangeTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/PhaseChangeTrigger.java @@ -5,11 +5,9 @@ import com.lovetropics.minigames.common.core.game.behavior.action.GameActionContext; import com.lovetropics.minigames.common.core.game.behavior.action.GameActionList; import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; -import com.lovetropics.minigames.common.core.game.behavior.event.GameLogicEvents; import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents; import com.lovetropics.minigames.common.core.game.state.GameProgressionState; import com.lovetropics.minigames.common.core.game.state.ProgressionPoint; -import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import java.util.ArrayList; @@ -36,7 +34,7 @@ public void register(IGamePhase game, EventRegistrar events) { while (iterator.hasNext()) { Map.Entry entry = iterator.next(); if (progression.isAfter(entry.getKey())) { - entry.getValue().apply(game, GameActionContext.EMPTY); + entry.getValue().applyPlayer(game, GameActionContext.EMPTY); iterator.remove(); } } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/ScheduledActionsTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/ScheduledActionsTrigger.java index 04a63967d..2f468397d 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/ScheduledActionsTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/ScheduledActionsTrigger.java @@ -4,8 +4,10 @@ import com.lovetropics.minigames.common.core.game.GameException; import com.lovetropics.minigames.common.core.game.IGamePhase; import com.lovetropics.minigames.common.core.game.behavior.IGameBehavior; +import com.lovetropics.minigames.common.core.game.behavior.action.ActionTarget; import com.lovetropics.minigames.common.core.game.behavior.action.GameActionContext; import com.lovetropics.minigames.common.core.game.behavior.action.GameActionList; +import com.lovetropics.minigames.common.core.game.behavior.action.PlayerActionTarget; import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents; import com.mojang.serialization.Codec; @@ -14,22 +16,26 @@ import java.util.List; -public record ScheduledActionsTrigger(GameActionList.Target target, Long2ObjectMap scheduledActions) implements IGameBehavior { - public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( - GameActionList.Target.CODEC.optionalFieldOf("target", GameActionList.Target.NONE).forGetter(ScheduledActionsTrigger::target), - MoreCodecs.long2Object(GameActionList.CODEC).fieldOf("actions").forGetter(ScheduledActionsTrigger::scheduledActions) +public record ScheduledActionsTrigger>(A target, Long2ObjectMap> scheduledActions) implements IGameBehavior { + public static final Codec> CODEC = RecordCodecBuilder.create(i -> i.group( + ActionTarget.FALLBACK_PLAYER.optionalFieldOf("target", PlayerActionTarget.SOURCE).forGetter(ScheduledActionsTrigger::target), + MoreCodecs.long2Object(GameActionList.TYPE_SAFE_CODEC).fieldOf("actions").forGetter(ScheduledActionsTrigger::scheduledActions) ).apply(i, ScheduledActionsTrigger::new)); @Override public void register(IGamePhase game, EventRegistrar events) throws GameException { - for (GameActionList actions : scheduledActions.values()) { + for (GameActionList actions : scheduledActions.values()) { actions.register(game, events); } events.listen(GamePhaseEvents.TICK, () -> { - GameActionList actions = scheduledActions.remove(game.ticks()); + GameActionList actions = scheduledActions.remove(game.ticks()); if (actions != null) { - actions.apply(game, GameActionContext.EMPTY, target.resolve(game, List.of())); + if (actions.target.type() == target.type()) { + actions.applyIf(target::type, game, GameActionContext.EMPTY, target.resolve(game, List.of())); + } else { + actions.apply(game, GameActionContext.EMPTY); + } } }); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WeatherChangeTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WeatherChangeTrigger.java index f81f7a528..d97ef2354 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WeatherChangeTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WeatherChangeTrigger.java @@ -33,7 +33,7 @@ public void register(IGamePhase game, EventRegistrar events) { if (event != null) { GameActionList actions = eventActions.get(event.getType()); if (actions != null) { - actions.apply(game, GameActionContext.EMPTY); + actions.applyPlayer(game, GameActionContext.EMPTY); } } }); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WhileInRegionTrigger.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WhileInRegionTrigger.java index 7eb5e3d77..daa3e3d09 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WhileInRegionTrigger.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/trigger/WhileInRegionTrigger.java @@ -34,7 +34,7 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio for (Map.Entry entry : regionActions.entrySet()) { if (isPlayerInRegion(game, player, entry.getKey())) { GameActionList actions = entry.getValue(); - actions.apply(game, GameActionContext.EMPTY, player); + actions.applyPlayer(game, GameActionContext.EMPTY, player); } } });