diff --git a/src/main/java/xyz/nucleoid/extras/lobby/PlayerLobbyState.java b/src/main/java/xyz/nucleoid/extras/lobby/PlayerLobbyState.java index fd3a44d..bcaf5cc 100644 --- a/src/main/java/xyz/nucleoid/extras/lobby/PlayerLobbyState.java +++ b/src/main/java/xyz/nucleoid/extras/lobby/PlayerLobbyState.java @@ -99,13 +99,13 @@ private ActionResult collectTater(Block block, ItemStack stack, PlayerEntity pla } player.sendMessage(message, true); - triggerCollectCriterion((ServerPlayerEntity) player, Registries.BLOCK.getId(tater), this.collectedTaters.size()); + triggerCollectCriterion((ServerPlayerEntity) player, tater, this.collectedTaters.size()); return alreadyAdded ? ActionResult.FAIL : ActionResult.SUCCESS; } - private static void triggerCollectCriterion(ServerPlayerEntity player, Identifier taterId, int count) { - NECriteria.TATER_COLLECTED.trigger(player, taterId, count); + private static void triggerCollectCriterion(ServerPlayerEntity player, TinyPotatoBlock tater, int count) { + NECriteria.TATER_COLLECTED.trigger(player, tater, count); } private static boolean isFickle(ActionResult result, Block block, PlayerEntity player) { diff --git a/src/main/java/xyz/nucleoid/extras/lobby/block/tater/TinyPotatoBlock.java b/src/main/java/xyz/nucleoid/extras/lobby/block/tater/TinyPotatoBlock.java index ebabdb6..1e73b1b 100644 --- a/src/main/java/xyz/nucleoid/extras/lobby/block/tater/TinyPotatoBlock.java +++ b/src/main/java/xyz/nucleoid/extras/lobby/block/tater/TinyPotatoBlock.java @@ -1,16 +1,19 @@ package xyz.nucleoid.extras.lobby.block.tater; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; import eu.pb4.polymer.core.api.block.PolymerBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.particle.ParticleEffect; +import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.Properties; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.dynamic.Codecs; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; @@ -21,6 +24,14 @@ import java.util.List; public abstract class TinyPotatoBlock extends Block implements PolymerBlock { + public static final Codec> ENTRY_CODEC = Codecs.validate(Registries.BLOCK.createEntryCodec(), block -> { + if (block.value() instanceof TinyPotatoBlock) { + return DataResult.success(block); + } + + return DataResult.error(() -> "Not a tater: " + block); + }); + public static final List TATERS = new ArrayList<>(); private final ParticleEffect particleEffect; diff --git a/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCollectedCriterion.java b/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCollectedCriterion.java index 0256cf3..5b837e0 100644 --- a/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCollectedCriterion.java +++ b/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCollectedCriterion.java @@ -1,21 +1,19 @@ package xyz.nucleoid.extras.lobby.criterion; -import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.block.Block; import net.minecraft.predicate.entity.LootContextPredicate; -import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.Identifier; -import xyz.nucleoid.extras.lobby.block.tater.CubicPotatoBlock; +import net.minecraft.util.dynamic.Codecs; import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock; import java.util.Optional; public class TaterCollectedCriterion extends AbstractCriterion { - public void trigger(ServerPlayerEntity player, Identifier tater, int count) { + public void trigger(ServerPlayerEntity player, TinyPotatoBlock tater, int count) { this.trigger(player, conditions -> conditions.matches(tater, count)); } @@ -27,33 +25,23 @@ public Codec getConditionsCodec() { @SuppressWarnings("OptionalUsedAsFieldOrParameterType") public static class Conditions implements AbstractCriterion.Conditions { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("tater").forGetter(Conditions::getTater), - Codec.INT.optionalFieldOf("count").forGetter(i -> i.optionalCount) + Codecs.createStrictOptionalFieldCodec(TinyPotatoBlock.ENTRY_CODEC, "tater").forGetter(i -> i.tater), + Codecs.createStrictOptionalFieldCodec(TaterCount.CODEC, "count").forGetter(i -> i.count) ).apply(instance, Conditions::new)); - private final Identifier tater; - private final Integer count; - private final Optional optionalCount; - - public Conditions(Identifier tater, Optional count) { - this.tater = tater; - this.count = count.orElse(TinyPotatoBlock.TATERS.size()); - this.optionalCount = count; - } - - public Identifier getTater() { - return tater; - } - - public Integer getCount() { - return count; - } - - public boolean matches(Identifier tater, int count) { - boolean taterMatches = getTater() == null || getTater().equals(tater); - boolean countMatches = getCount() == null || getCount() <= count; - return taterMatches && countMatches; - } + private final Optional> tater; + private final Optional count; + + public Conditions(Optional> tater, Optional count) { + this.tater = tater; + this.count = count; + } + + public boolean matches(TinyPotatoBlock tater, int count) { + boolean taterMatches = this.tater.isEmpty() || this.tater.get().value() == tater; + boolean countMatches = this.count.isEmpty() || this.count.get().matches(count); + return taterMatches && countMatches; + } @Override public Optional player() { diff --git a/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCount.java b/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCount.java new file mode 100644 index 0000000..5de9fc4 --- /dev/null +++ b/src/main/java/xyz/nucleoid/extras/lobby/criterion/TaterCount.java @@ -0,0 +1,51 @@ +package xyz.nucleoid.extras.lobby.criterion; + +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import net.minecraft.util.dynamic.Codecs; +import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock; + +import java.util.function.Function; + +public sealed interface TaterCount { + static final Codec CODEC = Codecs.either(Value.CODEC, All.CODEC).xmap(either -> { + return either.map(Function.identity(), Function.identity()); + }, count -> { + return count instanceof Value ? Either.left((Value) count) : Either.right((All) count); + }); + + int count(); + + default boolean matches(int count) { + return this.count() <= count; + } + + record Value(int count) implements TaterCount { + private static final Codec CODEC = Codecs.NONNEGATIVE_INT.xmap(Value::new, Value::count); + + public Value { + if (count < 0) { + throw new IllegalArgumentException("Count must be non-negative: " + count); + } + } + } + + record All() implements TaterCount { + private static final String STRING = "all"; + private static final All INSTANCE = new All(); + + private static final Codec CODEC = Codec.STRING.comapFlatMap(string -> { + if (STRING.equals(string)) { + return DataResult.success(All.INSTANCE); + } + + return DataResult.error(() -> "Not an 'all' count"); + }, string -> STRING); + + @Override + public int count() { + return TinyPotatoBlock.TATERS.size(); + } + } +} diff --git a/src/main/java/xyz/nucleoid/extras/lobby/criterion/WearTaterCriterion.java b/src/main/java/xyz/nucleoid/extras/lobby/criterion/WearTaterCriterion.java index 4af99f2..17a891a 100644 --- a/src/main/java/xyz/nucleoid/extras/lobby/criterion/WearTaterCriterion.java +++ b/src/main/java/xyz/nucleoid/extras/lobby/criterion/WearTaterCriterion.java @@ -1,15 +1,14 @@ package xyz.nucleoid.extras.lobby.criterion; -import com.google.gson.JsonObject; -import com.google.gson.JsonSyntaxException; -import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.block.Block; import net.minecraft.predicate.entity.LootContextPredicate; -import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.util.Identifier; +import net.minecraft.util.dynamic.Codecs; +import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock; import java.util.Calendar; import java.util.Date; @@ -19,7 +18,7 @@ public class WearTaterCriterion extends AbstractCriterion { public static final Calendar CALENDAR = Calendar.getInstance(); - public void trigger(ServerPlayerEntity player, Identifier tater) { + public void trigger(ServerPlayerEntity player, TinyPotatoBlock tater) { CALENDAR.setTime(new Date()); this.trigger(player, conditions -> conditions.matches(tater, CALENDAR.get(Calendar.DAY_OF_WEEK))); } @@ -55,16 +54,17 @@ public Codec getConditionsCodec() { return Conditions.CODEC; } - public record Conditions(Identifier tater, int dayOfWeek) implements AbstractCriterion.Conditions { + public record Conditions(Optional> tater, Optional dayOfWeek) implements AbstractCriterion.Conditions { + private static final Codec DAY_OF_WEEK_CODEC = Codec.STRING.xmap(WearTaterCriterion::dayOfWeekToInt, WearTaterCriterion::dayOfWeekToString); + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Identifier.CODEC.fieldOf("tater").forGetter(Conditions::tater), - Codec.STRING.xmap(WearTaterCriterion::dayOfWeekToInt, WearTaterCriterion::dayOfWeekToString) - .fieldOf("day_of_week").forGetter(Conditions::dayOfWeek) + Codecs.createStrictOptionalFieldCodec(TinyPotatoBlock.ENTRY_CODEC, "tater").forGetter(Conditions::tater), + Codecs.createStrictOptionalFieldCodec(DAY_OF_WEEK_CODEC, "day_of_week").forGetter(Conditions::dayOfWeek) ).apply(instance, Conditions::new)); - public boolean matches(Identifier tater, int dayOfWeek) { - boolean taterMatches = tater() == null || tater().equals(tater); - boolean dayOfWeekMatches = dayOfWeek() == dayOfWeek; + public boolean matches(TinyPotatoBlock tater, int dayOfWeek) { + boolean taterMatches = this.tater.isEmpty() || this.tater.get().value() == tater; + boolean dayOfWeekMatches = this.dayOfWeek.isEmpty() || this.dayOfWeek.get() == dayOfWeek; return taterMatches && dayOfWeekMatches; } diff --git a/src/main/java/xyz/nucleoid/extras/mixin/lobby/ServerPlayerEntityMixin.java b/src/main/java/xyz/nucleoid/extras/mixin/lobby/ServerPlayerEntityMixin.java index fe4826a..1c7546e 100644 --- a/src/main/java/xyz/nucleoid/extras/mixin/lobby/ServerPlayerEntityMixin.java +++ b/src/main/java/xyz/nucleoid/extras/mixin/lobby/ServerPlayerEntityMixin.java @@ -28,8 +28,8 @@ public ServerPlayerEntityMixin(World world, BlockPos pos, float yaw, GameProfile if (helmet.getItem() instanceof TaterBoxItem) { if (TaterBoxItem.getSelectedTater(helmet) instanceof CubicPotatoBlock tinyPotatoBlock) { ServerPlayerEntity player = (ServerPlayerEntity) (Object) this; - NECriteria.WEAR_TATER.trigger(player, TaterBoxItem.getSelectedTaterId(helmet)); - NECriteria.TATER_COLLECTED.trigger(player, TaterBoxItem.getSelectedTaterId(helmet), PlayerLobbyState.get(this).collectedTaters.size()); + NECriteria.WEAR_TATER.trigger(player, tinyPotatoBlock); + NECriteria.TATER_COLLECTED.trigger(player, tinyPotatoBlock, PlayerLobbyState.get(this).collectedTaters.size()); if (this.age % tinyPotatoBlock.getPlayerParticleRate(player) == 0) { tinyPotatoBlock.spawnPlayerParticles(player); }