package net.minecraft.advancements.critereon; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.Collection; import java.util.Optional; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.Criterion; import net.minecraft.advancements.critereon.SimpleCriterionTrigger.SimpleInstance; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.projectile.FishingHook; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.parameters.LootContextParams; public class FishingRodHookedTrigger extends SimpleCriterionTrigger { @Override public Codec codec() { return FishingRodHookedTrigger.TriggerInstance.CODEC; } public void trigger(ServerPlayer player, ItemStack rod, FishingHook entity, Collection stacks) { LootContext lootContext = EntityPredicate.createContext(player, (Entity)(entity.getHookedIn() != null ? entity.getHookedIn() : entity)); this.trigger(player, triggerInstance -> triggerInstance.matches(rod, lootContext, stacks)); } public record TriggerInstance( Optional player, Optional rod, Optional entity, Optional item ) implements SimpleInstance { public static final Codec CODEC = RecordCodecBuilder.create( instance -> instance.group( EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(FishingRodHookedTrigger.TriggerInstance::player), ItemPredicate.CODEC.optionalFieldOf("rod").forGetter(FishingRodHookedTrigger.TriggerInstance::rod), EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("entity").forGetter(FishingRodHookedTrigger.TriggerInstance::entity), ItemPredicate.CODEC.optionalFieldOf("item").forGetter(FishingRodHookedTrigger.TriggerInstance::item) ) .apply(instance, FishingRodHookedTrigger.TriggerInstance::new) ); public static Criterion fishedItem( Optional rod, Optional entity, Optional item ) { return CriteriaTriggers.FISHING_ROD_HOOKED .createCriterion(new FishingRodHookedTrigger.TriggerInstance(Optional.empty(), rod, EntityPredicate.wrap(entity), item)); } public boolean matches(ItemStack rod, LootContext context, Collection stacks) { if (this.rod.isPresent() && !((ItemPredicate)this.rod.get()).test(rod)) { return false; } else if (this.entity.isPresent() && !((ContextAwarePredicate)this.entity.get()).matches(context)) { return false; } else { if (this.item.isPresent()) { boolean bl = false; Entity entity = context.getOptionalParameter(LootContextParams.THIS_ENTITY); if (entity instanceof ItemEntity itemEntity && ((ItemPredicate)this.item.get()).test(itemEntity.getItem())) { bl = true; } for (ItemStack itemStack : stacks) { if (((ItemPredicate)this.item.get()).test(itemStack)) { bl = true; break; } } if (!bl) { return false; } } return true; } } @Override public void validate(CriterionValidator validator) { SimpleInstance.super.validate(validator); validator.validateEntity(this.entity, ".entity"); } } }