diff --git a/src/main/java/com/btk5h/skriptmirror/skript/CondChange.java b/src/main/java/com/btk5h/skriptmirror/skript/CondChange.java new file mode 100644 index 0000000..28a2d48 --- /dev/null +++ b/src/main/java/com/btk5h/skriptmirror/skript/CondChange.java @@ -0,0 +1,112 @@ +package com.btk5h.skriptmirror.skript; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.skript.util.Patterns; +import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.eclipse.jdt.annotation.Nullable; + +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; + + +public class CondChange extends Condition { + + private static final Patterns PATTERNS = new Patterns<>(new Object[][] { + {"%classinfos% can be added to %expressions%", ChangeMode.ADD}, + {"%expressions% can be set to %classinfos%", ChangeMode.SET}, + {"%classinfos% can be removed from %expressions%", ChangeMode.REMOVE}, + {"all %classinfos% can be removed from %expressions%", ChangeMode.REMOVE_ALL}, + {"%expressions% can be deleted", ChangeMode.DELETE}, + {"%expressions% can be reset", ChangeMode.RESET} + }); + + static { + Skript.registerCondition(CondChange.class, PATTERNS.getPatterns()); + } + + private ChangeMode desiredChangeMode; + private Expression> desiredTypes; + private Expression> expressions; + + @SuppressWarnings("unchecked") + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + desiredChangeMode = PATTERNS.getInfo(matchedPattern); + switch (desiredChangeMode) { + case ADD: + case REMOVE: + case REMOVE_ALL: + desiredTypes = (Expression>) exprs[0]; + expressions = (Expression>) exprs[1]; + break; + case SET: + expressions = (Expression>) exprs[0]; + desiredTypes = (Expression>) exprs[1]; + break; + case RESET: + case DELETE: + expressions = (Expression>) exprs[0]; + } + return true; + } + + @Override + public boolean check(Event event) { + if (desiredChangeMode == ChangeMode.DELETE || desiredChangeMode == ChangeMode.RESET) { + //noinspection ConstantValue + return expressions.check(event, expr -> expr.acceptChange(desiredChangeMode) != null); + } + return expressions.check(event, expression -> acceptsChange(expression, desiredChangeMode, getDesiredTypes(event))); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + String expressionsString = expressions.toString(event, debug); + String desiredTypesString = desiredTypes == null ? null : desiredTypes.toString(event, debug); + switch (desiredChangeMode) { + case ADD: + return desiredTypesString + " can be added to " + expressionsString; + case SET: + return expressionsString + " can be set to " + desiredTypesString; + case RESET: + return expressionsString + " can be reset"; + case DELETE: + return expressionsString + " can be deleted"; + case REMOVE: + return desiredTypesString + " can be removed from " + expressionsString; + case REMOVE_ALL: + return "all " + desiredTypesString + " can be removed from " + expressionsString; + default: + throw new IllegalStateException(); + } + } + + private boolean acceptsChange(Expression expression, ChangeMode desiredChangeMode, Collection> desiredTypes) { + Class[] acceptableTypes = expression.acceptChange(desiredChangeMode); + for (Class desiredType : desiredTypes) { + boolean multipleDesired = desiredType.isArray(); + if (multipleDesired) + desiredType = desiredType.getComponentType(); + for (Class acceptableType : acceptableTypes) { + if (acceptableType.isArray() + && acceptableType.getComponentType().isAssignableFrom(desiredType)) { + return true; + } else if (!multipleDesired && acceptableType.isAssignableFrom(desiredType)) + return true; + } + } + return false; + } + + private Set> getDesiredTypes(Event event) { + return desiredTypes.stream(event).map(ClassInfo::getC).collect(Collectors.toSet()); + } + +} diff --git a/src/main/java/com/btk5h/skriptmirror/skript/Types.java b/src/main/java/com/btk5h/skriptmirror/skript/Types.java index 8110068..608c9d6 100644 --- a/src/main/java/com/btk5h/skriptmirror/skript/Types.java +++ b/src/main/java/com/btk5h/skriptmirror/skript/Types.java @@ -3,6 +3,7 @@ import ch.njol.skript.classes.ClassInfo; import ch.njol.skript.classes.Parser; import ch.njol.skript.classes.Serializer; +import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ParseContext; import ch.njol.skript.registrations.Classes; import ch.njol.yggdrasil.Fields; @@ -214,6 +215,31 @@ public String getVariableNamePattern() { Classes.registerClass(new ClassInfo<>(Section.class, "section") .user("sections?") ); + + Classes.registerClass(new ClassInfo<>(Expression.class, "expression") + .user("expressions?") + .parser(new Parser>() { + @Override + public boolean canParse(ParseContext context) { + return false; + } + + @Override + public String getDebugMessage(Expression expression) { + return expression.toString(null, true); + } + + @Override + public String toString(Expression expression, int i) { + return expression.toString(null, false); + } + + @Override + public String toVariableNameString(Expression expression) { + return toString(expression, 0); + } + })); + } }