|
| 1 | +package org.skriptlang.skript.lang.properties; |
| 2 | + |
| 3 | +import ch.njol.skript.Skript; |
| 4 | +import ch.njol.skript.lang.Condition; |
| 5 | +import ch.njol.skript.lang.Expression; |
| 6 | +import ch.njol.skript.lang.SkriptParser.ParseResult; |
| 7 | +import ch.njol.skript.lang.util.SimpleExpression; |
| 8 | +import ch.njol.util.Kleenean; |
| 9 | +import org.bukkit.event.Event; |
| 10 | +import org.jetbrains.annotations.Nullable; |
| 11 | +import org.skriptlang.skript.lang.comparator.Comparators; |
| 12 | +import org.skriptlang.skript.lang.comparator.Relation; |
| 13 | +import org.skriptlang.skript.lang.properties.Property.ContainsHandler; |
| 14 | +import org.skriptlang.skript.lang.properties.PropertyUtils.PropertyMap; |
| 15 | + |
| 16 | +public class PropCondContains extends Condition { |
| 17 | + |
| 18 | + static { |
| 19 | + Skript.registerCondition(PropCondContains.class, |
| 20 | + "property %inventories% (has|have) %itemtypes% [in [(the[ir]|his|her|its)] inventory]", |
| 21 | + "property %inventories% (doesn't|does not|do not|don't) have %itemtypes% [in [(the[ir]|his|her|its)] inventory]", |
| 22 | + "property %inventories/strings/objects% contain[(1¦s)] %itemtypes/strings/objects%", |
| 23 | + "property %inventories/strings/objects% (doesn't|does not|do not|don't) contain %itemtypes/strings/objects%"); |
| 24 | + } |
| 25 | + |
| 26 | + private Expression<?> haystack; |
| 27 | + private Expression<?> needles; |
| 28 | + private PropertyMap<ContainsHandler<?, ?>> properties; |
| 29 | + |
| 30 | + boolean explicitSingle = false; |
| 31 | + |
| 32 | + @Override |
| 33 | + public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { |
| 34 | + |
| 35 | + this.haystack = PropertyUtils.asProperty(Property.CONTAINS, expressions[0]); |
| 36 | + if (haystack == null) { |
| 37 | + Skript.error("The expression " + expressions[0] + " returns types that do not contain anything."); |
| 38 | + return false; |
| 39 | + } |
| 40 | + // determine if the expression truly has a name property |
| 41 | + |
| 42 | + properties = PropertyUtils.getPossiblePropertyInfos(Property.CONTAINS, haystack); |
| 43 | + if (properties.isEmpty()) { |
| 44 | + Skript.error("The expression " + haystack + " returns types that do not contain anything."); |
| 45 | + return false; // no name property found |
| 46 | + } |
| 47 | + // determine possible return types |
| 48 | +// elementTypes = getElementTypes(properties); |
| 49 | + this.needles = expressions[1]; |
| 50 | + explicitSingle = matchedPattern == 2 && parseResult.mark != 1 || haystack.isSingle(); |
| 51 | + |
| 52 | + needles = expressions[1]; |
| 53 | + return true; |
| 54 | + } |
| 55 | + |
| 56 | + private Class<?>[][] getElementTypes(PropertyMap<ContainsHandler<?, ?>> properties) { |
| 57 | + return properties.values().stream() |
| 58 | + .map((propertyInfo) -> propertyInfo.handler().elementTypes()) |
| 59 | + .toArray(Class<?>[][]::new); |
| 60 | + } |
| 61 | + |
| 62 | + @Override |
| 63 | + public boolean check(Event event) { |
| 64 | + Object[] haystacks = haystack.getAll(event); |
| 65 | + boolean haystackAnd = haystack.getAnd(); |
| 66 | + Object[] needles = this.needles.getAll(event); |
| 67 | + boolean needlesAnd = this.needles.getAnd(); |
| 68 | + if (haystacks.length == 0) { |
| 69 | + return isNegated(); |
| 70 | + } |
| 71 | + |
| 72 | + // We should compare the contents of the haystacks to the needles |
| 73 | + if (explicitSingle) { |
| 74 | + // use properties |
| 75 | + return SimpleExpression.check(haystacks, (haystack) -> { |
| 76 | + // for each haystack, determine property |
| 77 | + //noinspection unchecked |
| 78 | + var handler = (ContainsHandler<Object, Object>) properties.getHandler(haystack.getClass()); |
| 79 | + if (handler == null) { |
| 80 | + return false; |
| 81 | + } |
| 82 | + // if found, use it to check against needles |
| 83 | + return SimpleExpression.check(needles, (needle) -> |
| 84 | + handler.canContain(needle.getClass()) |
| 85 | + && handler.contains(haystack, needle), |
| 86 | + false, needlesAnd); |
| 87 | + }, isNegated(), haystackAnd); |
| 88 | + |
| 89 | + // compare the haystacks themselves to the needles |
| 90 | + } else { |
| 91 | + return this.needles.check(event, o1 -> { |
| 92 | + for (Object o2 : haystacks) { |
| 93 | + if (Comparators.compare(o1, o2) == Relation.EQUAL) |
| 94 | + return true; |
| 95 | + } |
| 96 | + return false; |
| 97 | + }, isNegated()); |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + @Override |
| 102 | + public String toString(@Nullable Event event, boolean debug) { |
| 103 | + return "x contains y"; |
| 104 | + } |
| 105 | +} |
0 commit comments