Unicopia/src/main/java/com/minelittlepony/unicopia/advancement/SendViaDragonBreathScrollCriterion.java

82 lines
4 KiB
Java
Raw Normal View History

2023-09-09 19:46:41 +02:00
package com.minelittlepony.unicopia.advancement;
import java.util.Optional;
import java.util.function.BiConsumer;
import com.minelittlepony.unicopia.entity.player.Pony;
2023-12-30 11:55:26 +01:00
import com.minelittlepony.unicopia.util.CodecUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
2023-09-09 19:46:41 +02:00
import net.fabricmc.fabric.api.util.TriState;
import net.minecraft.advancement.criterion.AbstractCriterion;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
2023-12-30 11:55:26 +01:00
import net.minecraft.predicate.entity.EntityPredicate;
2023-09-09 19:46:41 +02:00
import net.minecraft.predicate.entity.LootContextPredicate;
import net.minecraft.predicate.item.ItemPredicate;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.TypeFilter;
2023-12-30 11:55:26 +01:00
import net.minecraft.util.dynamic.Codecs;
2023-09-09 19:46:41 +02:00
public class SendViaDragonBreathScrollCriterion extends AbstractCriterion<SendViaDragonBreathScrollCriterion.Conditions> {
@Override
2023-12-30 11:55:26 +01:00
public Codec<Conditions> getConditionsCodec() {
return Conditions.CODEC;
2023-09-09 19:46:41 +02:00
}
public void triggerSent(PlayerEntity player, ItemStack payload, String recipient, BiConsumer<String, Integer> counterCallback) {
if (player instanceof ServerPlayerEntity spe) {
trigger(spe, c -> {
if (c.test(spe, payload, recipient, false)) {
c.counter.ifPresent(counter -> {
counterCallback.accept(counter, Pony.of(spe).getAdvancementProgress().compute(counter, (key, i) -> i == null ? 1 : i + 1));
});
return true;
}
return false;
});
}
}
public void triggerReceived(LivingEntity recipient, ItemStack payload) {
if (recipient instanceof ServerPlayerEntity spe) {
trigger(spe, c -> c.test(spe, payload, recipient.getDisplayName().getString(), true));
}
}
2023-12-30 11:55:26 +01:00
public record Conditions (
Optional<LootContextPredicate> player,
Optional<ItemPredicate> item,
boolean isReceivingEnd,
Optional<String> recipientName,
TriState recipientPresent,
Optional<String> counter,
RacePredicate races
) implements AbstractCriterion.Conditions {
public static final Codec<Conditions> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codecs.createStrictOptionalFieldCodec(EntityPredicate.LOOT_CONTEXT_PREDICATE_CODEC, "player").forGetter(Conditions::player),
ItemPredicate.CODEC.optionalFieldOf("item").forGetter(Conditions::item),
Codec.BOOL.optionalFieldOf("is_receiving_end", false).forGetter(Conditions::isReceivingEnd),
Codec.STRING.optionalFieldOf("recipient_name").forGetter(Conditions::recipientName),
CodecUtils.tristateOf("recipient_present").forGetter(Conditions::recipientPresent),
Codec.STRING.optionalFieldOf("counter").forGetter(Conditions::counter),
2024-02-08 23:08:26 +01:00
RacePredicate.CODEC.optionalFieldOf("races", RacePredicate.EMPTY).forGetter(Conditions::races)
2023-12-30 11:55:26 +01:00
).apply(instance, Conditions::new));
2023-09-09 19:46:41 +02:00
public boolean test(ServerPlayerEntity player, ItemStack payload, String recipient, boolean receiving) {
return isReceivingEnd == receiving
&& races.test(player)
2023-09-29 20:15:04 +02:00
&& (item.isEmpty() || item.get().test(payload))
2023-09-09 19:46:41 +02:00
&& recipientName.map(expectedRecipientname -> recipient.equalsIgnoreCase(expectedRecipientname)).orElse(true)
&& (recipientPresent == TriState.DEFAULT || isRecipientAbsent(player.getServerWorld(), recipient) != recipientPresent.get());
}
private boolean isRecipientAbsent(ServerWorld world, String recipient) {
return world.getEntitiesByType(TypeFilter.instanceOf(LivingEntity.class), e -> e.hasCustomName() && e.getCustomName().getString().equalsIgnoreCase(recipient)).isEmpty();
}
}
}