package tc.oc.pgm.kits; import java.util.Collection; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import tc.oc.commons.core.util.Optionals; import tc.oc.pgm.compose.All; import tc.oc.pgm.compose.Composition; import tc.oc.pgm.compose.None; import tc.oc.pgm.compose.Unit; import tc.oc.pgm.filters.Filter; import tc.oc.pgm.filters.matcher.StaticFilter; import tc.oc.pgm.filters.query.TransientPlayerQuery; import tc.oc.pgm.match.MatchPlayer; import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Optional.empty; public interface KitNode extends Kit { static KitNode of(Stream<Kit> kits) { return new KitNodeImpl(Stream.empty(), new All<>(kits.map(Unit::new)), StaticFilter.ALLOW, empty(), empty()); } static KitNode of(Kit... kits) { return of(Stream.of(kits)); } static KitNode of(Collection<Kit> kits) { return of(kits.stream()); } KitNode EMPTY = new KitNodeImpl(Stream.empty(), new None<>(), StaticFilter.ALLOW, empty(), empty()); } class KitNodeImpl extends Kit.Impl implements KitNode, Kit { private final @Inspect List<Kit> parents; private final @Inspect Composition<Kit> kits; private final @Inspect Filter filter; private final @Inspect Optional<Boolean> force; private final @Inspect Optional<Boolean> potionParticles; public KitNodeImpl(Stream<Kit> parents, Composition<Kit> kits, Filter filter, Optional<Boolean> force, Optional<Boolean> potionParticles) { this.parents = parents.collect(Collectors.toList()); this.kits = kits; this.filter = checkNotNull(filter); this.force = force; this.potionParticles = potionParticles; } @Inspect private Optional<Filter> filter() { // Hide default value return Optionals.filter(filter, f -> !Objects.equals(f, StaticFilter.ALLOW)); } @Override public Stream<? extends Kit> dependencies() { return Stream.concat(parents.stream(), kits.dependencies()); } @Override public void apply(MatchPlayer player, boolean force, ItemKitApplicator items) { if(this.filter.query(player).isAllowed()) { for(Kit kit : parents) { kit.apply(player, this.force.orElse(force), items); } kits.elements(new TransientPlayerQuery(player)).forEach( kit -> kit.apply(player, this.force.orElse(force), items) ); potionParticles.ifPresent(player.getBukkit()::setPotionParticles); } } @Override public boolean isRemovable() { return kits.isConstant(); } @Override public void remove(MatchPlayer player) { kits.elements(new TransientPlayerQuery(player)).forEach( kit -> kit.remove(player) ); } }