diff --git a/src/generated/resources/assets/ltminigames/lang/en_ud.json b/src/generated/resources/assets/ltminigames/lang/en_ud.json index 3558d9859..68fb4da23 100644 --- a/src/generated/resources/assets/ltminigames/lang/en_ud.json +++ b/src/generated/resources/assets/ltminigames/lang/en_ud.json @@ -408,10 +408,10 @@ "ltminigames.minigame.river_race.cant_place_collectable": "ssǝɹboɹd oʇ ǝuoz ʇɔǝɹɹoɔ ǝɥʇ ɟo puǝ ǝɥʇ ʇɐ ʇuǝɯnuoW ǝɥʇ uı ǝɔɐןԀ", "ltminigames.minigame.river_race.shop": "doɥS", "ltminigames.minigame.river_race.trivia.collectable_given": "¡ʇuǝɯnuoɯ ǝɥʇ oʇuı ǝɔɐןd oʇ ǝןqɐʇɔǝןןoɔ ɐ uǝʌıb uǝǝq ǝʌ,noʎ", - "ltminigames.minigame.river_race.trivia.collectable_placed": "˙spuoɔǝs %s uı ʇɹɐʇs ןןıʍ sǝɯɐb-oɹɔıɯ ǝɥ⟘ ¡ǝןqɐʇɔǝןןoɔ %s ǝɥʇ ǝɔɐןd oʇ ʇsɹıɟ ǝɹɐ ɯɐǝʇ %s", - "ltminigames.minigame.river_race.trivia.collectable_placed_title": "¡ǝןqɐʇɔǝןןoɔ %s ǝɥʇ ǝɔɐןd oʇ ʇsɹıɟ ǝɹɐ ɯɐǝʇ %s", + "ltminigames.minigame.river_race.trivia.collectable_placed.subtitle": "ǝuoz %ǝɯɐu% pǝʇǝןdɯoƆ", + "ltminigames.minigame.river_race.trivia.collectable_placed.title": "¡%ɯɐǝʇ% o⅁", "ltminigames.minigame.river_race.trivia.correct": "¡ʎןʇɔǝɹɹoɔ pǝɹǝʍsuɐ uoıʇsǝnb ɐıʌıɹ⟘", - "ltminigames.minigame.river_race.trivia.games_start_in": ")s(puoɔǝs %s uı ʇɹɐʇs sǝɯɐboɹɔıW", + "ltminigames.minigame.river_race.trivia.games_start_in": "%ǝɯıʇ% uı ʇɹɐʇs sǝɯɐboɹɔıW", "ltminigames.minigame.river_race.trivia.incorrect": "¡spuoɔǝs %s ɹoɟ ʇno pǝʞɔoן ʍou sı uoıʇsǝnb sıɥ⟘ ¡ʇɔǝɹɹoɔuI", "ltminigames.minigame.river_race.trivia.loot_given": "¡pǝʞɔoןun uǝǝq sɐɥ ʇooꞀ", "ltminigames.minigame.river_race.trivia.victory_point_change": ")s(ʇuıoԀ ʎɹoʇɔıΛ %s+", diff --git a/src/generated/resources/assets/ltminigames/lang/en_us.json b/src/generated/resources/assets/ltminigames/lang/en_us.json index 249530ea7..19b58c6a5 100644 --- a/src/generated/resources/assets/ltminigames/lang/en_us.json +++ b/src/generated/resources/assets/ltminigames/lang/en_us.json @@ -408,10 +408,10 @@ "ltminigames.minigame.river_race.cant_place_collectable": "Place in the Monument at the end of the correct zone to progress", "ltminigames.minigame.river_race.shop": "Shop", "ltminigames.minigame.river_race.trivia.collectable_given": "You've been given a collectable to place into the monument!", - "ltminigames.minigame.river_race.trivia.collectable_placed": "%s team are first to place the %s collectable! The micro-games will start in %s seconds.", - "ltminigames.minigame.river_race.trivia.collectable_placed_title": "%s team are first to place the %s collectable!", + "ltminigames.minigame.river_race.trivia.collectable_placed.subtitle": "Completed %name% zone", + "ltminigames.minigame.river_race.trivia.collectable_placed.title": "Go %team%!", "ltminigames.minigame.river_race.trivia.correct": "Trivia question answered correctly!", - "ltminigames.minigame.river_race.trivia.games_start_in": "Microgames start in %s second(s)", + "ltminigames.minigame.river_race.trivia.games_start_in": "Microgames start in %time%", "ltminigames.minigame.river_race.trivia.incorrect": "Incorrect! This question is now locked out for %s seconds!", "ltminigames.minigame.river_race.trivia.loot_given": "Loot has been unlocked!", "ltminigames.minigame.river_race.trivia.victory_point_change": "+%s Victory Point(s)", diff --git a/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRace.java b/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRace.java index 82d98a333..886d53235 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRace.java +++ b/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRace.java @@ -40,6 +40,7 @@ public class RiverRace { public static final GameBehaviorEntry RIVER_RACE_PROGRESS_BEHAVIOUR = REGISTRATE.object("river_race_progress").behavior(ProgressBehaviour.CODEC).register(); public static final GameBehaviorEntry COLLECTABLES_BEHAVIOUR = REGISTRATE.object("river_race_collectables").behavior(CollectablesBehaviour.CODEC).register(); public static final GameBehaviorEntry PREVENT_BREAK_BEHAVIOUR = REGISTRATE.object("prevent_break").behavior(PreventBreakBehaviour.CODEC).register(); + public static final GameBehaviorEntry UNLOCK_ZONE_ACTION = REGISTRATE.object("unlock_zone").behavior(UnlockZoneAction.CODEC).register(); public static final GameClientTweakEntry BAR_STATE = REGISTRATE.object("river_race_bar") .clientState(RiverRaceClientBarState.CODEC).streamCodec(RiverRaceClientBarState.STREAM_CODEC) diff --git a/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRaceTexts.java b/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRaceTexts.java index e9c082f2c..c3890e0ae 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRaceTexts.java +++ b/src/main/java/com/lovetropics/minigames/common/content/river_race/RiverRaceTexts.java @@ -22,24 +22,20 @@ public final class RiverRaceTexts { .withStyle(ChatFormatting.GOLD); public static final Component LOOT_GIVEN = KEYS.add("trivia.loot_given", "Loot has been unlocked!") .withStyle(ChatFormatting.GOLD); - public static final TranslationCollector.Fun2 COLLECTABLE_PLACED_TITLE = KEYS.add2("trivia.collectable_placed_title", "%s team are first to place the %s collectable!") - .withStyle(ChatFormatting.GREEN); - public static final TranslationCollector.Fun3 COLLECTABLE_PLACED = KEYS.add3("trivia.collectable_placed", "%s team are first to place the %s collectable! The micro-games will start in %s seconds.") - .withStyle(ChatFormatting.GREEN); public static final TranslationCollector.Fun1 VICTORY_POINT_CHANGE = KEYS.add1("trivia.victory_point_change", "+%s Victory Point(s)") .withStyle(ChatFormatting.GREEN); - public static final TranslationCollector.Fun1 GAMES_START_IN = KEYS.add1("trivia.games_start_in", "Microgames start in %s second(s)") - .withStyle(ChatFormatting.GREEN); - public static final Component CANT_PLACE_COLLECTABLE = KEYS.add("cant_place_collectable", "Place in the Monument at the end of the correct zone to progress") .withStyle(ChatFormatting.RED); public static final Component TRIVIA_BLOCK_ALREADY_USED = KEYS.add("trivia_block_already_used", "This Trivia Block has already been used!") .withStyle(ChatFormatting.RED); public static void collectTranslations(BiConsumer consumer) { - KEYS.forEach(consumer); + KEYS.add("trivia.collectable_placed.title", "Go %team%!"); + KEYS.add("trivia.collectable_placed.subtitle", "Completed %name% zone"); + KEYS.add("trivia.games_start_in", "Microgames start in %time%"); + KEYS.forEach(consumer); consumer.accept(LoveTropics.ID + ".minigame.river_race", "River Race"); } } diff --git a/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/CollectablesBehaviour.java b/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/CollectablesBehaviour.java index 99726a803..b35e31c28 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/CollectablesBehaviour.java +++ b/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/CollectablesBehaviour.java @@ -3,12 +3,12 @@ import com.lovetropics.lib.codec.MoreCodecs; import com.lovetropics.lib.entity.FireworkPalette; import com.lovetropics.minigames.common.content.river_race.RiverRaceTexts; -import com.lovetropics.minigames.common.content.river_race.event.RiverRaceEvents; 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.GameActionContext; import com.lovetropics.minigames.common.core.game.behavior.action.GameActionList; +import com.lovetropics.minigames.common.core.game.behavior.action.GameActionParameter; import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents; import com.lovetropics.minigames.common.core.game.behavior.event.GamePlayerEvents; @@ -25,8 +25,6 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.ChatFormatting; -import net.minecraft.SharedConstants; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; @@ -46,8 +44,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; -import java.util.function.Consumer; public final class CollectablesBehaviour implements IGameBehavior, IGameState { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( @@ -55,7 +51,6 @@ public final class CollectablesBehaviour implements IGameBehavior, IGameState { ).apply(i, CollectablesBehaviour::new)); public static final GameStateKey COLLECTABLES = GameStateKey.create("collectables"); - public static final int COUNTDOWN_SECONDS = 45; private final List collectables; public CollectablesBehaviour(List collectables) { @@ -66,8 +61,6 @@ public CollectablesBehaviour(List collectables) { private final LongSet placedCollectables = new LongOpenHashSet(); private final Map firstTeamToCollect = new HashMap<>(); - @Nullable - private Countdown countdown; @Nullable public Collectable getCollectableForZone(String zone) { @@ -101,11 +94,6 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio } } - events.listen(GamePhaseEvents.TICK, () -> { - if (countdown != null){ - countdown.tick(game); - } - }); events.listen(GamePhaseEvents.CREATE, () -> monumentSlots.forEach((pos, collectable) -> spawnCollectableDisplay(game, collectable, pos.getCenter())) ); @@ -156,27 +144,17 @@ private InteractionResult tryPlaceCollectable(IGamePhase game, TeamState teams, private InteractionResult onCollectablePlaced(IGamePhase game, GameTeam team, Collectable collectable, BlockPos slotPos) { if (firstTeamToCollect.putIfAbsent(collectable.zone, team.key()) == null) { - addEffectsForPlacedCollectable(game, collectable, team); - // Start microgames countdown - countdown = new Countdown(game.ticks() + (SharedConstants.TICKS_PER_SECOND * COUNTDOWN_SECONDS), (unused) -> { - collectable.onCompleteAction.apply(game, GameActionContext.EMPTY); - collectable.unlocksZone.ifPresent(zone -> game.invoker(RiverRaceEvents.UNLOCK_ZONE).onUnlockZone(zone)); - countdown = null; - }); + GameActionContext context = GameActionContext.builder() + .set(GameActionParameter.TEAM, team) + .set(GameActionParameter.NAME, Component.literal(collectable.zoneDisplayName())) + .build(); + collectable.onCompleteAction.apply(game, context, game.allPlayers()); } game.statistics().forTeam(team.key()).incrementInt(StatisticKey.VICTORY_POINTS, collectable.victoryPoints); FireworkPalette.DYE_COLORS.spawn(slotPos.above(), game.level()); return InteractionResult.PASS; } - private static void addEffectsForPlacedCollectable(IGamePhase game, Collectable collectable, GameTeam team) { - Component teamName = team.config().styledName(); - game.allPlayers().showTitle(null, RiverRaceTexts.COLLECTABLE_PLACED_TITLE.apply(teamName, collectable.zoneDisplayName()), 20, 40, 20); - game.allPlayers().sendMessage(RiverRaceTexts.COLLECTABLE_PLACED.apply(teamName, collectable.zoneDisplayName(), COUNTDOWN_SECONDS)); - - game.allPlayers().playSound(SoundEvents.RAID_HORN.value(), SoundSource.NEUTRAL, 1f, 1); - } - @Nullable private Collectable getMatchingCollectable(ItemStack itemStack) { for (Collectable collectable : collectables) { @@ -191,44 +169,16 @@ public List collectables() { return collectables; } - private static class Countdown { - - private final long endTicks; - private final Consumer end; - - public Countdown(long endTicks, Consumer end) { - this.endTicks = endTicks; - this.end = end; - } - - public void tick(IGamePhase game){ - long ticks = game.ticks(); - if(ticks >= endTicks){ - end.accept(null); - } else if(ticks % 20 == 0) { - long remainingTicks = endTicks - ticks; - long remainingSeconds = (remainingTicks / SharedConstants.TICKS_PER_SECOND); - if(remainingSeconds == 30 || remainingSeconds == 15 || remainingSeconds == 10) { - game.allPlayers().sendMessage(RiverRaceTexts.GAMES_START_IN.apply(remainingSeconds).withStyle(ChatFormatting.GREEN)); - } else if((remainingTicks / SharedConstants.TICKS_PER_SECOND) <= 5) { - game.allPlayers().playSound(SoundEvents.UI_BUTTON_CLICK.value(), SoundSource.NEUTRAL, 0.2f, 1f); - game.allPlayers().showTitle(Component.literal(remainingTicks / SharedConstants.TICKS_PER_SECOND + "").withStyle(ChatFormatting.GREEN), 10, 20, 10); - } - } - } - } - - public record Collectable(String zone, Optional unlocksZone, String zoneDisplayName, ItemStack collectable, + public record Collectable(String zone, String zoneDisplayName, ItemStack collectable, List monumentSlotRegions, - int victoryPoints, GameActionList onCompleteAction) { + int victoryPoints, GameActionList onCompleteAction) { public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( Codec.STRING.fieldOf("zone").forGetter(Collectable::zone), - Codec.STRING.optionalFieldOf("unlocks_zone").forGetter(Collectable::unlocksZone), Codec.STRING.fieldOf("zone_display_name").forGetter(Collectable::zoneDisplayName), MoreCodecs.ITEM_STACK.fieldOf("item").forGetter(Collectable::collectable), ExtraCodecs.nonEmptyList(Codec.STRING.listOf()).fieldOf("monument_slot_region").forGetter(Collectable::monumentSlotRegions), Codec.INT.fieldOf("victory_points").forGetter(Collectable::victoryPoints), - GameActionList.VOID_CODEC.fieldOf("on_complete").forGetter(Collectable::onCompleteAction) + GameActionList.PLAYER_CODEC.fieldOf("on_complete").forGetter(Collectable::onCompleteAction) ).apply(i, Collectable::new)); } } diff --git a/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/UnlockZoneAction.java b/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/UnlockZoneAction.java new file mode 100644 index 000000000..508defb71 --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/content/river_race/behaviour/UnlockZoneAction.java @@ -0,0 +1,36 @@ +package com.lovetropics.minigames.common.content.river_race.behaviour; + +import com.lovetropics.minigames.common.content.river_race.RiverRace; +import com.lovetropics.minigames.common.content.river_race.event.RiverRaceEvents; +import com.lovetropics.minigames.common.core.game.GameException; +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.GameBehaviorType; +import com.lovetropics.minigames.common.core.game.behavior.IGameBehavior; +import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar; +import com.lovetropics.minigames.common.core.game.behavior.event.GameActionEvents; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import java.util.function.Supplier; + +public record UnlockZoneAction( + String zone +) implements IGameBehavior { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( + Codec.STRING.fieldOf("zone").forGetter(UnlockZoneAction::zone) + ).apply(i, UnlockZoneAction::new)); + + @Override + public void register(IGamePhase game, EventRegistrar events) throws GameException { + events.listen(GameActionEvents.APPLY, context -> { + game.invoker(RiverRaceEvents.UNLOCK_ZONE).onUnlockZone(zone); + return true; + }); + } + + @Override + public Supplier> behaviorType() { + return RiverRace.UNLOCK_ZONE_ACTION; + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/content/river_race/render/RiverRaceBarRenderer.java b/src/main/java/com/lovetropics/minigames/common/content/river_race/render/RiverRaceBarRenderer.java index b9cabc55b..8c1f97b29 100644 --- a/src/main/java/com/lovetropics/minigames/common/content/river_race/render/RiverRaceBarRenderer.java +++ b/src/main/java/com/lovetropics/minigames/common/content/river_race/render/RiverRaceBarRenderer.java @@ -5,15 +5,21 @@ import com.lovetropics.minigames.common.content.river_race.RiverRace; import com.lovetropics.minigames.common.content.river_race.client_state.RiverRaceClientBarState; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; import it.unimi.dsi.fastutil.ints.IntList; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.FastColor; import net.minecraft.world.item.DyeColor; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; +import net.neoforged.neoforge.client.event.RenderGuiLayerEvent; import net.neoforged.neoforge.client.gui.VanillaGuiLayers; +@EventBusSubscriber(modid = LoveTropics.ID, value = Dist.CLIENT) public final class RiverRaceBarRenderer { private static final int MAP_TOP = 3; @@ -44,6 +50,22 @@ public static void registerOverlays(RegisterGuiLayersEvent event) { }); } + @SubscribeEvent + public static void onRenderLayerPre(RenderGuiLayerEvent.Pre event) { + if (event.getName().equals(VanillaGuiLayers.BOSS_OVERLAY) && ClientGameStateManager.getOrNull(RiverRace.BAR_STATE) != null) { + PoseStack pose = event.getGuiGraphics().pose(); + pose.pushPose(); + pose.translate(0.0f, MAP_HEIGHT + POINTER_SIZE, 0.0f); + } + } + + @SubscribeEvent + public static void onRenderLayerPost(RenderGuiLayerEvent.Post event) { + if (event.getName().equals(VanillaGuiLayers.BOSS_OVERLAY) && ClientGameStateManager.getOrNull(RiverRace.BAR_STATE) != null) { + event.getGuiGraphics().pose().popPose(); + } + } + private static void render(GuiGraphics graphics, RiverRaceClientBarState barState) { RenderSystem.enableBlend(); 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 5089de0d4..cee6427c3 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 @@ -66,6 +66,7 @@ import com.lovetropics.minigames.common.core.game.behavior.instances.action.SpawnParticlesAroundPlayerAction; import com.lovetropics.minigames.common.core.game.behavior.instances.action.SpawnTornadoAction; import com.lovetropics.minigames.common.core.game.behavior.instances.action.SpectatorActivityAction; +import com.lovetropics.minigames.common.core.game.behavior.instances.action.StartProgressChannelAction; import com.lovetropics.minigames.common.core.game.behavior.instances.action.SwapPlayersAction; import com.lovetropics.minigames.common.core.game.behavior.instances.action.TargetPlayerAction; import com.lovetropics.minigames.common.core.game.behavior.instances.action.TransformPlayerTornadoAction; @@ -282,6 +283,7 @@ public class GameBehaviorTypes { public static final GameBehaviorEntry ADD_COLLIDERS = register("add_colliders", AddCollidersAction.CODEC); public static final GameBehaviorEntry REMOVE_COLLIDERS = register("remove_colliders", RemoveCollidersAction.CODEC); public static final GameBehaviorEntry INCREMENT_STATISTIC = register("increment_statistic", IncrementStatisticAction.CODEC); + public static final GameBehaviorEntry START_PROGRESS_CHANNEL = register("start_progress_channel", StartProgressChannelAction.CODEC); public static final GameBehaviorEntry SETUP_INTEGRATIONS = register("setup_integrations", SetupIntegrationsBehavior.CODEC); public static final GameBehaviorEntry ASSIGN_PLAYER_ROLES = register("assign_player_roles", AssignPlayerRolesBehavior.CODEC); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionParameter.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionParameter.java index 1950d7e40..840e8b3fa 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionParameter.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/action/GameActionParameter.java @@ -2,6 +2,7 @@ import com.lovetropics.minigames.common.core.game.state.team.GameTeam; import com.lovetropics.minigames.common.core.integration.game_actions.GamePackage; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; @@ -16,6 +17,7 @@ public class GameActionParameter { public static final GameActionParameter COUNT = GameActionParameter.create(); public static final GameActionParameter ITEM = GameActionParameter.create(); public static final GameActionParameter TEAM = GameActionParameter.create(); + public static final GameActionParameter NAME = GameActionParameter.create(); private GameActionParameter() { } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/GameProgressionBehavior.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/GameProgressionBehavior.java index 27581004b..1653051b9 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/GameProgressionBehavior.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/GameProgressionBehavior.java @@ -28,7 +28,8 @@ public class GameProgressionBehavior implements IGameBehavior { Codec.unboundedMap(Codec.STRING, Codec.FLOAT).optionalFieldOf("named_points", Map.of()).forGetter(b -> b.namedPoints), Codec.INT.optionalFieldOf("max_time_step", 1).forGetter(b -> b.maxTimeStep), MoreCodecs.listOrUnit(ProgressionPeriod.CODEC).optionalFieldOf("fixed_time_step", List.of()).forGetter(b -> b.fixedTimeStep), - PlayerConstraint.CODEC.listOf().optionalFieldOf("time_by_player_count", List.of()).forGetter(b -> b.playerConstraints) + PlayerConstraint.CODEC.listOf().optionalFieldOf("time_by_player_count", List.of()).forGetter(b -> b.playerConstraints), + Codec.BOOL.optionalFieldOf("start", true).forGetter(b -> b.start) ).apply(i, GameProgressionBehavior::new)); private ProgressHolder progressHolder; @@ -38,17 +39,19 @@ public class GameProgressionBehavior implements IGameBehavior { private final int maxTimeStep; private final List fixedTimeStep; private final List playerConstraints; + private final boolean start; private Float2FloatFunction playerCountToTime = key -> 0.0f; private int debugTimeMultiplier = 1; - public GameProgressionBehavior(ProgressChannel channel, Map namedPoints, int maxTimeStep, List fixedTimeStep, List playerConstraints) { + public GameProgressionBehavior(ProgressChannel channel, Map namedPoints, int maxTimeStep, List fixedTimeStep, List playerConstraints, boolean start) { this.channel = channel; this.namedPoints = namedPoints; this.maxTimeStep = maxTimeStep; this.fixedTimeStep = fixedTimeStep; this.playerConstraints = playerConstraints; + this.start = start; } @Override @@ -63,9 +66,15 @@ public void register(IGamePhase game, EventRegistrar events) { if (!playerConstraints.isEmpty()) { playerCountToTime = resolvePlayerConstraints(playerConstraints, game.participants().size(), progressHolder); } + if (start) { + progressHolder.start(); + } }); events.listen(GamePhaseEvents.TICK, () -> { + if (!progressHolder.isStarted()) { + return; + } int newTime = tickTime(game, progressHolder.time()); progressHolder.set(newTime); }); diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/StartProgressChannelAction.java b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/StartProgressChannelAction.java new file mode 100644 index 000000000..5ecea5c5f --- /dev/null +++ b/src/main/java/com/lovetropics/minigames/common/core/game/behavior/instances/action/StartProgressChannelAction.java @@ -0,0 +1,37 @@ +package com.lovetropics.minigames.common.core.game.behavior.instances.action; + +import com.lovetropics.minigames.common.core.game.GameException; +import com.lovetropics.minigames.common.core.game.IGamePhase; +import com.lovetropics.minigames.common.core.game.behavior.GameBehaviorType; +import com.lovetropics.minigames.common.core.game.behavior.GameBehaviorTypes; +import com.lovetropics.minigames.common.core.game.behavior.IGameBehavior; +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.state.progress.ProgressChannel; +import com.lovetropics.minigames.common.core.game.state.progress.ProgressHolder; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import java.util.function.Supplier; + +public record StartProgressChannelAction( + ProgressChannel channel +) implements IGameBehavior { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( + ProgressChannel.CODEC.fieldOf("channel").forGetter(StartProgressChannelAction::channel) + ).apply(i, StartProgressChannelAction::new)); + + @Override + public void register(IGamePhase game, EventRegistrar events) throws GameException { + ProgressHolder holder = channel.getOrThrow(game); + events.listen(GameActionEvents.APPLY, context -> { + holder.start(); + return true; + }); + } + + @Override + public Supplier> behaviorType() { + return GameBehaviorTypes.START_PROGRESS_CHANNEL; + } +} diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/state/progress/ProgressHolder.java b/src/main/java/com/lovetropics/minigames/common/core/game/state/progress/ProgressHolder.java index b72a80fed..5e3fc1d09 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/state/progress/ProgressHolder.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/state/progress/ProgressHolder.java @@ -4,13 +4,19 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; public final class ProgressHolder implements ProgressionPoint.NamedResolver { + public static final int NOT_STARTED_TIME = -1; + private final Object2IntMap namedPoints = new Object2IntOpenHashMap<>(); - private int time; + private int time = NOT_STARTED_TIME; public void addNamedPoint(String name, int value) { namedPoints.put(name, value); } + public void start() { + time = 0; + } + public void set(int time) { this.time = time; } @@ -19,6 +25,10 @@ public int time() { return time; } + public boolean isStarted() { + return time != NOT_STARTED_TIME; + } + public boolean is(ProgressionPeriod period) { return isAfter(period.start()) && isBefore(period.end()); } diff --git a/src/main/java/com/lovetropics/minigames/common/core/game/util/TemplatedText.java b/src/main/java/com/lovetropics/minigames/common/core/game/util/TemplatedText.java index 2e7017219..e6757bbda 100644 --- a/src/main/java/com/lovetropics/minigames/common/core/game/util/TemplatedText.java +++ b/src/main/java/com/lovetropics/minigames/common/core/game/util/TemplatedText.java @@ -34,6 +34,8 @@ private static void addValuesFromContext(GameActionContext context, Map values.put("target", player.getDisplayName())); context.get(GameActionParameter.COUNT).ifPresent(count -> values.put("count", Component.literal(String.valueOf(count)))); context.get(GameActionParameter.ITEM).ifPresent(item -> values.put("item", item.getHoverName())); + context.get(GameActionParameter.TEAM).ifPresent(team -> values.put("team", team.config().styledName())); + context.get(GameActionParameter.NAME).ifPresent(name -> values.put("name", name)); } public Component apply(Map values) {