Skip to content

Add accepts change condition #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ jobs:
uses: SkriptLang/[email protected]
with:
test_script_directory: src/test/scripts
skript_repo_ref: 2.8.2
skript_repo_ref: dev/patch
extra_plugins_directory: extra-plugins/
123 changes: 123 additions & 0 deletions src/main/java/com/btk5h/skriptmirror/skript/CondAcceptsChange.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
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.lang.UnparsedLiteral;
import ch.njol.skript.util.Patterns;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;


public class CondAcceptsChange extends Condition {

private static final Patterns<ChangeMode> PATTERNS = new Patterns<>(new Object[][] {
{"%classinfo% can be added to %expressions%", ChangeMode.ADD},
{"%classinfo% (can't|cannot) be added to %expressions%", ChangeMode.ADD},
Comment on lines +20 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{"%classinfo% can be added to %expressions%", ChangeMode.ADD},
{"%classinfo% (can't|cannot) be added to %expressions%", ChangeMode.ADD},
{"%classinfo% can be (added|given) to %expressions%", ChangeMode.ADD},
{"%classinfo% (can't|cannot) be (added|given) to %expressions%", ChangeMode.ADD},

Not sure if it's worth doing this, but if you agree, the other modes should be done as well, like clear for DELETE

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like a good idea. i can't recall if skript has a dirt can be given to player type syntax though. i'll have to double check so we dont accidentally cause a conflict if there is

{"%expressions% can be set to %classinfo%", ChangeMode.SET},
{"%expressions% (can't|cannot) be set to %classinfo%", ChangeMode.SET},
{"%classinfo% can be removed from %expressions%", ChangeMode.REMOVE},
{"%classinfo% (can't|cannot) be removed from %expressions%", ChangeMode.REMOVE},
{"all %classinfo% can be removed from %expressions%", ChangeMode.REMOVE_ALL},
{"all %classinfo% (can't|cannot) be removed from %expressions%", ChangeMode.REMOVE_ALL},
{"%expressions% can be deleted", ChangeMode.DELETE},
{"%expressions% (can't|cannot) be deleted", ChangeMode.DELETE},
{"%expressions% can be reset", ChangeMode.RESET},
{"%expressions% (can't|cannot) be reset", ChangeMode.RESET}
});

static {
Skript.registerCondition(CondAcceptsChange.class, PATTERNS.getPatterns());
}

private ChangeMode desiredChangeMode;
private boolean desiredTypeIsPlural;
private Expression<ClassInfo<?>> desiredType;
private Expression<Expression<?>> expressions;

@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
setNegated((matchedPattern % 2) != 0);
desiredChangeMode = PATTERNS.getInfo(matchedPattern);
Expression<?> desiredType = null;
switch (desiredChangeMode) {
case ADD:
case REMOVE:
case REMOVE_ALL:
desiredType = exprs[0];
expressions = (Expression<Expression<?>>) exprs[1];
break;
case SET:
expressions = (Expression<Expression<?>>) exprs[0];
desiredType = exprs[1];
break;
case RESET:
case DELETE:
expressions = (Expression<Expression<?>>) exprs[0];
}
if (desiredType != null) {
Expression<?> desiredTypeSource = desiredType.getSource();
if (desiredTypeSource instanceof UnparsedLiteral) {
UnparsedLiteral unparsedDesiredType = (UnparsedLiteral) desiredTypeSource;
desiredTypeIsPlural = Utils.getEnglishPlural(unparsedDesiredType.getData()).getSecond();
}
this.desiredType = (Expression<ClassInfo<?>>) desiredType;
}
return true;
}

@Override
public boolean check(Event event) {
if (desiredChangeMode == ChangeMode.DELETE || desiredChangeMode == ChangeMode.RESET)
//noinspection ConstantValue
return expressions.check(event, expressions -> expressions.acceptChange(desiredChangeMode) != null, isNegated());
ClassInfo<?> desiredType = this.desiredType.getSingle(event);
if (desiredType == null)
return false;
return expressions.check(event, expression -> acceptsChange(expression, desiredChangeMode, desiredType.getC(), desiredTypeIsPlural), isNegated());
}

@Override
public String toString(@Nullable Event event, boolean debug) {
String expressionsString = expressions.toString(event, debug);
String desiredTypesString = desiredType == null ? null : desiredType.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, Class<?> desiredType, boolean typeIsPlural) {
Class<?>[] acceptableTypes = expression.acceptChange(desiredChangeMode);
//noinspection ConstantValue
if (acceptableTypes != null) {
for (Class<?> acceptableType : acceptableTypes) {
if (acceptableType.isArray()
&& acceptableType.getComponentType().isAssignableFrom(desiredType)) {
return true;
} else if (!typeIsPlural && acceptableType.isAssignableFrom(desiredType))
return true;
}
}
return false;
}

}
26 changes: 26 additions & 0 deletions src/main/java/com/btk5h/skriptmirror/skript/Types.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -214,6 +215,31 @@ public String getVariableNamePattern() {
Classes.registerClass(new ClassInfo<>(Section.class, "section")
.user("sections?")
);

Classes.registerClass(new ClassInfo<>(Expression.class, "expression")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skript-reflect actually already returns unwrapped Expression objects, but there hasn't been a registered classinfo for it

.user("expressions?")
.parser(new Parser<Expression<?>>() {
@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);
}
}));

}

}
2 changes: 1 addition & 1 deletion src/main/java/com/btk5h/skriptmirror/util/SkriptUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ public static ClassInfo<?> getUserClassInfo(String name) {
}

/**
* @return the pair of the {@link ClassInfo} in the given string, and whether is is singular.
* @return the pair of the {@link ClassInfo} in the given string, and whether it is singular.
*/
public static NonNullPair<ClassInfo<?>, Boolean> getUserClassInfoAndPlural(String name) {
NonNullPair<String, Boolean> wordData = Utils.getEnglishPlural(name);
Expand Down
33 changes: 33 additions & 0 deletions src/test/scripts/CondChange.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
test "CondChange - set":
assert raw ({_v}) can be set to a string with "a variable should be settable to a string"
assert raw (location of (random player out of all players)) can't be set to a string with "the location expression shouldn't be settable to a string"
assert raw (name of {_v}) can be set to a string with "the name expression should be settable to a string"
assert raw (name of {_v}) can't be set to an integer with "the name expression shouldn't be settable to an integer"
assert raw (name of {_v}) can't be set to strings with "the name expression shouldn't be settable to multiple strings"
assert raw ({_v::*}) can be set to strings with "a list variable should be settable to multiple strings"
assert raw ({_v}) can't be set to strings with "a non-list variable should not be settable to multiple strings"

test "CondChange - reset":
assert raw (uppercase "") can't be reset with "the uppercase expression shouldn't be resettable"
assert raw (portal cooldown of {_v}) can be reset with "the portal cooldown expression should be resettable"

test "CondChange - delete":
assert raw ({_v}) can be deleted with "a variable should be deletable"
assert raw (uppercase "") can't be deleted with "the uppercase expression shouldn't be deletable"

test "CondChange - add":
assert an integer can be added to raw ({_v}) with "an integer should be addable to a variable"
assert integers can be added to raw ({_v}) with "multiple integers should be addable to a variable"
assert a string can't be added to raw (all players) with "a string shouldn't be addable to all players"

test "CondChange - remove":
assert a player can be removed from raw ({_v::*}) with "a player should be removable from a variable"
assert players can be removed from raw ({_v::*}) with "multiple players should be removable from a variable"
assert a player can't be removed from raw (block at {_v}) with "a player shouldn't be removable the block expression"
assert a integer can be removed from raw (durability of {_v}) with "an integer should be removable from the durability expression"

test "CondChange - remove all":
assert all player can be removed from raw ({_v::*}) with "all integer should be removable from a variable"
assert all players can be removed from raw ({_v::*}) with "all integers should be removable from a variable"
assert all strings can't be removed from raw (name of {_v}) with "all strings shouldn't be removable from the name expression"
assert all players can't be removed from raw (name of {_v}) with "all players shouldn't be removable from the name expression"