package net.minecraft.advancements.triggers; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; import net.minecraft.advancements.predicates.ContextAwarePredicate; import net.minecraft.advancements.predicates.entity.EntityPredicate; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LightningBolt; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.level.storage.loot.Validatable; import net.minecraft.world.level.storage.loot.ValidationContextSource; public class LightningStrikeTrigger extends SimpleCriterionTrigger { @Override public Codec codec() { return LightningStrikeTrigger.TriggerInstance.CODEC; } public void trigger(final ServerPlayer player, final LightningBolt lightning, final List entitiesAround) { List entitiesAroundContexts = (List)entitiesAround.stream() .map(v -> EntityPredicate.createContext(player, v)) .collect(Collectors.toList()); LootContext lightningContext = EntityPredicate.createContext(player, lightning); this.trigger(player, t -> t.matches(lightningContext, entitiesAroundContexts)); } public record TriggerInstance(Optional player, Optional lightning, Optional bystander) implements SimpleCriterionTrigger.SimpleInstance { public static final Codec CODEC = RecordCodecBuilder.create( i -> i.group( EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("player").forGetter(LightningStrikeTrigger.TriggerInstance::player), EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("lightning").forGetter(LightningStrikeTrigger.TriggerInstance::lightning), EntityPredicate.ADVANCEMENT_CODEC.optionalFieldOf("bystander").forGetter(LightningStrikeTrigger.TriggerInstance::bystander) ) .apply(i, LightningStrikeTrigger.TriggerInstance::new) ); public static Criterion lightningStrike( final Optional lightning, final Optional bystander ) { return CriteriaTriggers.LIGHTNING_STRIKE .createCriterion(new LightningStrikeTrigger.TriggerInstance(Optional.empty(), EntityPredicate.wrap(lightning), EntityPredicate.wrap(bystander))); } public boolean matches(final LootContext bolt, final List entitiesAround) { return this.lightning.isPresent() && !((ContextAwarePredicate)this.lightning.get()).matches(bolt) ? false : !this.bystander.isPresent() || !entitiesAround.stream().noneMatch(((ContextAwarePredicate)this.bystander.get())::matches); } @Override public void validate(final ValidationContextSource validator) { SimpleCriterionTrigger.SimpleInstance.super.validate(validator); Validatable.validate(validator.entityContext(), "lightning", this.lightning); Validatable.validate(validator.entityContext(), "bystander", this.bystander); } } }