Only count progressive advancements for the triggered id

This commit is contained in:
Sollace 2024-10-12 21:23:23 +01:00
parent 3297480b3f
commit 78c090e037
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
4 changed files with 26 additions and 39 deletions

View file

@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Predicate;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.advancement.PlayerAdvancementTracker; import net.minecraft.advancement.PlayerAdvancementTracker;
@ -40,7 +42,7 @@ public abstract class AbstractRepeatingCriterion<T extends AbstractRepeatingCrit
progressions.remove(tracker); progressions.remove(tracker);
} }
protected void trigger(ServerPlayerEntity player, BiPredicate<Integer, T> predicate) { protected void trigger(ServerPlayerEntity player, Predicate<T> shouldCount, BiPredicate<Integer, T> predicate) {
PlayerAdvancementTracker tracker = player.getAdvancementTracker(); PlayerAdvancementTracker tracker = player.getAdvancementTracker();
TriggerCountTracker counter = Pony.of(player).getAdvancementProgress(); TriggerCountTracker counter = Pony.of(player).getAdvancementProgress();
counter.removeGranted(player, tracker); counter.removeGranted(player, tracker);
@ -52,7 +54,7 @@ public abstract class AbstractRepeatingCriterion<T extends AbstractRepeatingCrit
for (var condition : advancements) { for (var condition : advancements) {
T conditions = condition.conditions(); T conditions = condition.conditions();
if (predicate.test(counter.update(condition.advancement(), condition.id()), conditions)) { if (shouldCount.test(conditions) && predicate.test(counter.update(condition.advancement(), condition.id()), conditions)) {
var playerPredicate = conditions.player(); var playerPredicate = conditions.player();
if (playerPredicate.isEmpty() || playerPredicate.get().test(lootContext)) { if (playerPredicate.isEmpty() || playerPredicate.get().test(lootContext)) {
if (matches == null) { if (matches == null) {

View file

@ -25,7 +25,10 @@ public class CustomEventCriterion extends AbstractRepeatingCriterion<CustomEvent
public CustomEventCriterion.Trigger createTrigger(String name) { public CustomEventCriterion.Trigger createTrigger(String name) {
return player -> { return player -> {
if (player instanceof ServerPlayerEntity p) { if (player instanceof ServerPlayerEntity p) {
trigger(p, (count, condition) -> condition.test(name, count, p)); trigger(p,
condition -> condition.event().equalsIgnoreCase(name),
(count, condition) -> condition.test(count, p)
);
} }
}; };
} }
@ -64,12 +67,11 @@ public class CustomEventCriterion extends AbstractRepeatingCriterion<CustomEvent
Codec.INT.optionalFieldOf("repeatCount", 0).forGetter(Conditions::repeatCount) Codec.INT.optionalFieldOf("repeatCount", 0).forGetter(Conditions::repeatCount)
).apply(instance, Conditions::new)); ).apply(instance, Conditions::new));
public boolean test(String event, int count, ServerPlayerEntity player) { public boolean test(int count, ServerPlayerEntity player) {
boolean isFlying = Pony.of(player).getPhysics().isFlying(); boolean isFlying = Pony.of(player).getPhysics().isFlying();
return this.event.equalsIgnoreCase(event) return races.test(player)
&& races.test(player)
&& flying.orElse(isFlying) == isFlying && flying.orElse(isFlying) == isFlying
&& (repeatCount < 0 || repeatCount == count); && (repeatCount < 0 || repeatCount <= count);
} }
} }
} }

View file

@ -26,21 +26,16 @@ public class SendViaDragonBreathScrollCriterion extends AbstractRepeatingCriteri
public void triggerSent(PlayerEntity player, ItemStack payload, String recipient, BiConsumer<String, Integer> counterCallback) { public void triggerSent(PlayerEntity player, ItemStack payload, String recipient, BiConsumer<String, Integer> counterCallback) {
if (player instanceof ServerPlayerEntity spe) { if (player instanceof ServerPlayerEntity spe) {
trigger(spe, (count, c) -> { trigger(spe, c -> c.test(spe, payload, recipient, false), (count, c) -> {
if (c.test(spe, payload, recipient, false)) { c.counter.ifPresent(counter -> counterCallback.accept(counter, count));
c.counter.ifPresent(counter -> {
counterCallback.accept(counter, count);
});
return true; return true;
}
return false;
}); });
} }
} }
public void triggerReceived(LivingEntity recipient, ItemStack payload) { public void triggerReceived(LivingEntity recipient, ItemStack payload) {
if (recipient instanceof ServerPlayerEntity spe) { if (recipient instanceof ServerPlayerEntity spe) {
trigger(spe, (count, c) -> c.test(spe, payload, recipient.getDisplayName().getString(), true)); trigger(spe, c -> c.test(spe, payload, recipient.getDisplayName().getString(), true), (count, c) -> true);
} }
} }

View file

@ -1,13 +1,13 @@
package com.minelittlepony.unicopia.advancement; package com.minelittlepony.unicopia.advancement;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.util.Copyable; import com.minelittlepony.unicopia.util.Copyable;
import com.mojang.serialization.Codec; import com.mojang.serialization.Codec;
import com.mojang.serialization.DataResult;
import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.advancement.AdvancementEntry; import net.minecraft.advancement.AdvancementEntry;
@ -16,22 +16,25 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class TriggerCountTracker implements Copyable<TriggerCountTracker> { public class TriggerCountTracker implements Copyable<TriggerCountTracker> {
public static final Codec<TriggerCountTracker> CODEC = Codec.unboundedMap(Key.CODEC, Codec.INT).xmap(TriggerCountTracker::new, tracker -> tracker.entries); public static final Codec<TriggerCountTracker> CODEC = Codec.unboundedMap(
Identifier.CODEC,
Codec.unboundedMap(Codec.STRING, Codec.INT).xmap(i -> (Object2IntMap<String>)new Object2IntOpenHashMap<>(i), Function.identity())
).xmap(TriggerCountTracker::new, tracker -> tracker.entries);
private final Object2IntMap<Key> entries = new Object2IntOpenHashMap<>(); private final Map<Identifier, Object2IntMap<String>> entries = new HashMap<>();
public TriggerCountTracker(Map<Key, Integer> entries) { public TriggerCountTracker(Map<Identifier, Object2IntMap<String>> entries) {
this.entries.putAll(entries); this.entries.putAll(entries);
} }
public int update(AdvancementEntry advancement, String criterionName) { public int update(AdvancementEntry advancement, String criterionName) {
return entries.computeInt(new Key(advancement.id(), criterionName), (key, initial) -> (initial == null ? 0 : initial) + 1); return entries.computeIfAbsent(advancement.id(), id -> new Object2IntOpenHashMap<>()).computeInt(criterionName, (key, initial) -> (initial == null ? 0 : initial) + 1);
} }
public void removeGranted(ServerPlayerEntity player, PlayerAdvancementTracker tracker) { public void removeGranted(ServerPlayerEntity player, PlayerAdvancementTracker tracker) {
entries.keySet().removeIf(key -> { entries.entrySet().removeIf(entry -> {
@Nullable @Nullable
AdvancementEntry a = player.getServer().getAdvancementLoader().get(key.advancement()); AdvancementEntry a = player.getServer().getAdvancementLoader().get(entry.getKey());
return a == null || tracker.getProgress(a).isDone(); return a == null || tracker.getProgress(a).isDone();
}); });
} }
@ -41,19 +44,4 @@ public class TriggerCountTracker implements Copyable<TriggerCountTracker> {
entries.clear(); entries.clear();
entries.putAll(other.entries); entries.putAll(other.entries);
} }
record Key(Identifier advancement, String criterion) {
public static final Codec<Key> CODEC = Codec.STRING.flatXmap(s -> {
String[] parts = s.split(":");
return parts.length == 3
? DataResult.success(new Key(Identifier.of(parts[0], parts[1]), parts[2]))
: DataResult.error(() -> "String '" + s + "' was in the wrong format");
}, key -> DataResult.success(key.toString()));
@Override
public String toString() {
return advancement.toString() + ":" + criterion;
}
}
} }