diff --git a/.github/workflows/archive-docs.yml b/.github/workflows/archive-docs.yml
new file mode 100644
index 00000000000..e183f748d78
--- /dev/null
+++ b/.github/workflows/archive-docs.yml
@@ -0,0 +1,45 @@
+name: Archive documentation
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+jobs:
+ archive-docs:
+ if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')"
+ needs: release-docs
+ runs-on: ubuntu-latest
+ steps:
+ - name: Configure workflow
+ id: configuration
+ run: |
+ echo "BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
+ echo "DOCS_OUTPUT_DIR=${GITHUB_WORKSPACE}/skript-docs/docs/archives/${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
+ echo "DOCS_REPO_DIR=${GITHUB_WORKSPACE}/skript-docs" >> $GITHUB_OUTPUT
+ echo "SKRIPT_REPO_DIR=${GITHUB_WORKSPACE}/skript" >> $GITHUB_OUTPUT
+ - name: Checkout Skript
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ path: skript
+ - name: Setup documentation environment
+ uses: ./skript/.github/workflows/docs/setup-docs
+ with:
+ docs_deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
+ docs_output_dir: ${{ steps.configuration.outputs.DOCS_OUTPUT_DIR }}
+ - name: Generate documentation
+ uses: ./skript/.github/workflows/docs/generate-docs
+ with:
+ docs_output_dir: ${{ steps.configuration.outputs.DOCS_OUTPUT_DIR }}
+ docs_repo_dir: ${{ steps.configuration.outputs.DOCS_REPO_DIR }}
+ skript_repo_dir: ${{ steps.configuration.outputs.SKRIPT_REPO_DIR }}
+ is_release: true
+ generate_javadocs: true
+ - name: Push archive documentation
+ uses: ./skript/.github/workflows/docs/push-docs
+ with:
+ docs_repo_dir: ${{ steps.configuration.outputs.DOCS_REPO_DIR }}
+ git_name: Archive Docs Bot
+ git_email: archivedocs@skriptlang.org
+ git_commit_message: "Update ${{ steps.configuration.outputs.BRANCH_NAME }} archive docs"
diff --git a/.github/workflows/docs/generate-docs/action.yml b/.github/workflows/docs/generate-docs/action.yml
index e033996868e..2470f852450 100644
--- a/.github/workflows/docs/generate-docs/action.yml
+++ b/.github/workflows/docs/generate-docs/action.yml
@@ -69,7 +69,7 @@ runs:
cd $SKRIPT_REPO_DIR
if [[ "${IS_RELEASE}" == "true" ]]; then
- ./gradlew genReleaseDocs releaseJavadoc
+ ./gradlew genReleaseDocs javadoc
elif [[ "${GENERATE_JAVADOCS}" == "true" ]]; then
./gradlew genNightlyDocs javadoc
else
@@ -77,7 +77,7 @@ runs:
fi
if [ -d "${DOCS_OUTPUT_DIR}" ]; then
- if [[ "${GENERATE_JAVADOCS}" == "true" ]]; then
+ if [[ "${GENERATE_JAVADOCS}" == "true" ]] || [[ "${IS_RELEASE}" == "true" ]] ; then
mkdir -p "${SKRIPT_DOCS_OUTPUT_DIR}/javadocs" && cp -a "./build/docs/javadoc/." "$_"
fi
diff --git a/.github/workflows/java-8-builds.yml b/.github/workflows/java-11-builds.yml
similarity index 92%
rename from .github/workflows/java-8-builds.yml
rename to .github/workflows/java-11-builds.yml
index 0120b950f94..443aa925d0c 100644
--- a/.github/workflows/java-8-builds.yml
+++ b/.github/workflows/java-11-builds.yml
@@ -1,4 +1,4 @@
-name: Java 8 CI (MC 1.13-1.16)
+name: Java 11 CI (MC 1.13-1.16)
on:
push:
@@ -26,7 +26,7 @@ jobs:
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build Skript and run test scripts
- run: ./gradlew clean skriptTestJava8
+ run: ./gradlew clean skriptTestJava11
- name: Upload Nightly Build
uses: actions/upload-artifact@v4
if: success()
diff --git a/.github/workflows/junit-8-builds.yml b/.github/workflows/junit-11-builds.yml
similarity index 94%
rename from .github/workflows/junit-8-builds.yml
rename to .github/workflows/junit-11-builds.yml
index ec2fef19869..cdf75e4c43a 100644
--- a/.github/workflows/junit-8-builds.yml
+++ b/.github/workflows/junit-11-builds.yml
@@ -26,4 +26,4 @@ jobs:
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build Skript and run JUnit
- run: ./gradlew clean JUnitJava8
+ run: ./gradlew clean JUnitJava11
diff --git a/.github/workflows/release-docs.yml b/.github/workflows/release-docs.yml
index f6f7ebc8a27..9cfe198ba93 100644
--- a/.github/workflows/release-docs.yml
+++ b/.github/workflows/release-docs.yml
@@ -3,6 +3,7 @@ name: Release documentation
on:
release:
types: [published]
+ workflow_dispatch:
jobs:
release-docs:
@@ -33,6 +34,7 @@ jobs:
docs_repo_dir: ${{ steps.configuration.outputs.DOCS_REPO_DIR }}
skript_repo_dir: ${{ steps.configuration.outputs.SKRIPT_REPO_DIR }}
is_release: true
+ generate_javadocs: true
cleanup_pattern: "!(nightly|archives|templates)"
- name: Push release documentation
uses: ./skript/.github/workflows/docs/push-docs
@@ -41,40 +43,3 @@ jobs:
git_name: Release Docs Bot
git_email: releasedocs@skriptlang.org
git_commit_message: "Update release docs to ${{ steps.configuration.outputs.BRANCH_NAME }}"
-
- archive-docs:
- if: "! contains(toJSON(github.event.commits.*.message), '[ci skip]')"
- needs: release-docs
- runs-on: ubuntu-latest
- steps:
- - name: Configure workflow
- id: configuration
- run: |
- echo "BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
- echo "DOCS_OUTPUT_DIR=${GITHUB_WORKSPACE}/skript-docs/docs/archives/${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- echo "DOCS_REPO_DIR=${GITHUB_WORKSPACE}/skript-docs" >> $GITHUB_OUTPUT
- echo "SKRIPT_REPO_DIR=${GITHUB_WORKSPACE}/skript" >> $GITHUB_OUTPUT
- - name: Checkout Skript
- uses: actions/checkout@v4
- with:
- submodules: recursive
- path: skript
- - name: Setup documentation environment
- uses: ./skript/.github/workflows/docs/setup-docs
- with:
- docs_deploy_key: ${{ secrets.DOCS_DEPLOY_KEY }}
- docs_output_dir: ${{ steps.configuration.outputs.DOCS_OUTPUT_DIR }}
- - name: Generate documentation
- uses: ./skript/.github/workflows/docs/generate-docs
- with:
- docs_repo_dir: ${{ steps.configuration.outputs.DOCS_REPO_DIR }}
- docs_output_dir: ${{ steps.configuration.outputs.DOCS_OUTPUT_DIR }}
- skript_repo_dir: ${{ steps.configuration.outputs.SKRIPT_REPO_DIR }}
- is_release: true
- - name: Push archive documentation
- uses: ./skript/.github/workflows/docs/push-docs
- with:
- docs_repo_dir: ${{ steps.configuration.outputs.DOCS_REPO_DIR }}
- git_name: Archive Docs Bot
- git_email: archivedocs@skriptlang.org
- git_commit_message: "Update ${{ steps.configuration.outputs.BRANCH_NAME }} archive docs"
diff --git a/README.md b/README.md
index 2dba8104819..b4ab6c4e48f 100644
--- a/README.md
+++ b/README.md
@@ -16,11 +16,11 @@ Skript requires **Spigot** to work. You heard it right, **CraftBukkit** does *no
**Paper**, which is a fork of Spigot, is recommended; it is required for some
parts of Skript to be available.
-Skript supports only the **latest** patch versions of Minecraft 1.9+.
+Skript supports only the **latest** patch versions of Minecraft 1.13+.
For example, this means that 1.16.5 is supported, but 1.16.4 is *not*.
Testing with all old patch versions is not feasible for us.
-Minecraft 1.8 and earlier are not, and will not be supported. New Minecraft
+Minecraft 1.12 and earlier are not, and will not be supported. New Minecraft
versions will be supported as soon as possible.
## Download
@@ -77,15 +77,15 @@ Skript has some tests written in Skript. Running them requires a Minecraft
server, but our build script will create one for you. Running the tests is easy:
```
-./gradlew (quickTest|skriptTest|skriptTestJava8|skriptTestJava17|skriptTestJava21)
+./gradlew (quickTest|skriptTest|skriptTestJava11|skriptTestJava17|skriptTestJava21)
```
quickTest
runs the test suite on newest supported server version.
skriptTestJava21
(1.20.6+) runs the tests on Java 21 supported versions.
skriptTestJava17
(1.17-1.20.4) runs the tests on Java 17 supported versions.
-skriptTestJava8
(1.13-1.16) runs the tests on Java 8 supported versions.
+skriptTestJava11
(1.13-1.16) runs the tests on Java 11 supported versions.
skriptTest
runs the tests on all versions.
-That is, it runs skriptTestJava8, skriptTestJava17, and skriptTestJava21.
+That is, it runs skriptTestJava11, skriptTestJava17, and skriptTestJava21.
By running the tests, you agree to Mojang's End User License Agreement.
@@ -164,7 +164,7 @@ dependencies {
}
```
-An example of the version tag would be ```dev37c```.
+An example of the version tag would be ```2.8.5```.
> Note: If Gradle isn't able to resolve Skript's dependencies, just [disable the resolution of transitive dependencies](https://docs.gradle.org/current/userguide/resolution_rules.html#sec:disabling_resolution_transitive_dependencies) for Skript in your project.
diff --git a/build.gradle b/build.gradle
index 4cc665864db..d6a60fa9e37 100644
--- a/build.gradle
+++ b/build.gradle
@@ -70,7 +70,7 @@ task build(overwrite: true, type: ShadowJar) {
from sourceSets.main.output
}
-// Excludes the tests for the build task. Should be using junit, junitJava17, junitJava8, skriptTest, quickTest.
+// Excludes the tests for the build task. Should be using junit, junitJava17, junitJava11, skriptTest, quickTest.
// We do not want tests to run for building. That's time consuming and annoying. Especially in development.
test {
exclude '**/*'
@@ -140,15 +140,6 @@ publishing {
}
}
-task releaseJavadoc(type: Javadoc) {
- title = project.name + ' ' + project.property('version')
- source = sourceSets.main.allJava
- classpath = configurations.compileClasspath
- options.encoding = 'UTF-8'
- // currently our javadoc has a lot of errors, so we need to suppress the linter
- options.addStringOption('Xdoclint:none', '-quiet')
-}
-
// Task to check that test scripts are named correctly
tasks.register('testNaming') {
doLast {
@@ -188,7 +179,7 @@ void createTestTask(String name, String desc, String environments, int javaVersi
if (junit) {
artifact += 'Skript-JUnit.jar'
} else if (releaseDocs) {
- artifact += 'Skript-github.jar'
+ artifact += 'Skript-' + version + '.jar'
} else {
artifact += 'Skript-nightly.jar'
}
@@ -233,7 +224,7 @@ void createTestTask(String name, String desc, String environments, int javaVersi
if (!gradle.taskGraph.hasTask(":tasks") && !gradle.startParameter.dryRun && modifiers.contains(Modifiers.PROFILE)) {
if (!project.hasProperty('profiler'))
throw new MissingPropertyException('Add parameter -Pprofiler=', 'profiler', String.class)
-
+
args += '-agentpath:' + project.property('profiler') + '=port=8849,nowait'
}
}
@@ -242,11 +233,11 @@ void createTestTask(String name, String desc, String environments, int javaVersi
def java21 = 21
def java17 = 17
-def java8 = 8
+def java11 = 11
def latestEnv = 'java21/paper-1.20.6.json'
def latestJava = java21
-def oldestJava = java8
+def oldestJava = java11
def latestJUnitEnv = 'java17/paper-1.20.4.json'
def latestJUnitJava = java17
@@ -269,14 +260,14 @@ int envJava = project.property('testEnvJavaVersion') == null ? latestJava : Inte
createTestTask('quickTest', 'Runs tests on one environment being the latest supported Java and Minecraft.', environments + latestEnv, latestJava, 0)
createTestTask('skriptTestJava21', 'Runs tests on all Java 21 environments.', environments + 'java21', java21, 0)
createTestTask('skriptTestJava17', 'Runs tests on all Java 17 environments.', environments + 'java17', java17, 0)
-createTestTask('skriptTestJava8', 'Runs tests on all Java 8 environments.', environments + 'java8', java8, 0)
+createTestTask('skriptTestJava11', 'Runs tests on all Java 11 environments.', environments + 'java11', java11, 0)
createTestTask('skriptTestDev', 'Runs testing server and uses \'system.in\' for command input, stop server to finish.', environments + env, envJava, 0, Modifiers.DEV_MODE, Modifiers.DEBUG)
createTestTask('skriptProfile', 'Starts the testing server with JProfiler support.', environments + latestEnv, latestJava, -1, Modifiers.PROFILE)
createTestTask('genNightlyDocs', 'Generates the Skript documentation website html files.', environments + env, envJava, 0, Modifiers.GEN_NIGHTLY_DOCS)
createTestTask('genReleaseDocs', 'Generates the Skript documentation website html files for a release.', environments + env, envJava, 0, Modifiers.GEN_RELEASE_DOCS)
tasks.register('skriptTest') {
description = 'Runs tests on all environments.'
- dependsOn skriptTestJava8, skriptTestJava17, skriptTestJava21
+ dependsOn skriptTestJava11, skriptTestJava17, skriptTestJava21
}
createTestTask('JUnitQuick', 'Runs JUnit tests on one environment being the latest supported Java and Minecraft.', environments + latestJUnitEnv, latestJUnitJava, 0, Modifiers.JUNIT)
@@ -284,10 +275,10 @@ createTestTask('JUnitQuick', 'Runs JUnit tests on one environment being the late
// However, we are currently using 5.0.1 (see https://github.com/SkriptLang/Skript/pull/6204#discussion_r1405302009)
//createTestTask('JUnitJava21', 'Runs JUnit tests on all Java 21 environments.', environments + 'java21', java21, 0, Modifiers.JUNIT)
createTestTask('JUnitJava17', 'Runs JUnit tests on all Java 17 environments.', environments + 'java17', java17, 0, Modifiers.JUNIT)
-createTestTask('JUnitJava8', 'Runs JUnit tests on all Java 8 environments.', environments + 'java8', java8, 0, Modifiers.JUNIT)
+createTestTask('JUnitJava11', 'Runs JUnit tests on all Java 11 environments.', environments + 'java11', java11, 0, Modifiers.JUNIT)
tasks.register('JUnit') {
description = 'Runs JUnit tests on all environments.'
- dependsOn JUnitJava8, JUnitJava17//, JUnitJava21
+ dependsOn JUnitJava11, JUnitJava17//, JUnitJava21
}
// Build flavor configurations
@@ -367,7 +358,7 @@ task nightlyResources(type: ProcessResources) {
'today' : '' + LocalTime.now(),
'release-flavor' : 'skriptlang-nightly', // SkriptLang build, automatically done by CI
'release-channel' : 'prerelease', // No update checking, but these are VERY unstable
- 'release-updater' : 'ch.njol.skript.update.NoUpdateChecker', // No autoupdates for now
+ 'release-updater' : 'ch.njol.skript.update.NoUpdateChecker', // No auto updates for now
'release-source' : '',
'release-download': 'null'
]
@@ -389,8 +380,8 @@ task nightlyRelease(type: ShadowJar) {
}
javadoc {
- dependsOn nightlyResources
-
+ mustRunAfter(tasks.withType(ProcessResources))
+ title = 'Skript ' + project.property('version')
source = sourceSets.main.allJava
exclude("ch/njol/skript/conditions/**")
@@ -403,10 +394,9 @@ javadoc {
exclude("ch/njol/skript/lang/function/ExprFunctionCall.java")
exclude("ch/njol/skript/hooks/**")
exclude("ch/njol/skript/test/**")
-
+
classpath = configurations.compileClasspath + sourceSets.main.output
options.encoding = 'UTF-8'
// currently our javadoc has a lot of errors, so we need to suppress the linter
options.addStringOption('Xdoclint:none', '-quiet')
}
-
diff --git a/code-conventions.md b/code-conventions.md
index 25c6d5c4417..3bcf17c6c9f 100644
--- a/code-conventions.md
+++ b/code-conventions.md
@@ -194,7 +194,7 @@ Your comments should look something like these:
## Language Features
### Compatibility
-[//]: # (To be updated after feature/2.9 for Java 17)
+[//]: # (To be updated for 2.10 for Java 17)
* Contributions should maintain Java 11 source/binary compatibility, even though compiling Skript requires Java 21
- Users must not need JRE newer than version 11
* Versions up to and including Java 21 should work too
diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
index 6131def1eec..76e098cb602 100644
--- a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
+++ b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java
@@ -41,6 +41,7 @@
import ch.njol.skript.util.slot.InventorySlot;
import ch.njol.skript.util.slot.Slot;
import com.destroystokyo.paper.event.block.AnvilDamagedEvent;
+import com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent;
import com.destroystokyo.paper.event.entity.ProjectileCollideEvent;
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
import io.papermc.paper.event.entity.EntityMoveEvent;
@@ -691,6 +692,15 @@ public Entity get(LightningStrikeEvent event) {
return event.getLightning();
}
}, 0);
+ // EndermanAttackPlayerEvent
+ if (Skript.classExists("com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent")) {
+ EventValues.registerEventValue(EndermanAttackPlayerEvent.class, Player.class, new Getter() {
+ @Override
+ public Player get(EndermanAttackPlayerEvent event) {
+ return event.getPlayer();
+ }
+ }, EventValues.TIME_NOW);
+ }
// --- PlayerEvents ---
EventValues.registerEventValue(PlayerEvent.class, Player.class, new Getter() {
diff --git a/src/main/java/ch/njol/skript/classes/data/DefaultOperations.java b/src/main/java/ch/njol/skript/classes/data/DefaultOperations.java
index e3f9965c1c4..860c7ee1030 100644
--- a/src/main/java/ch/njol/skript/classes/data/DefaultOperations.java
+++ b/src/main/java/ch/njol/skript/classes/data/DefaultOperations.java
@@ -20,6 +20,7 @@
import ch.njol.skript.util.Date;
import ch.njol.skript.util.Timespan;
+import ch.njol.skript.util.Timespan.TimePeriod;
import ch.njol.skript.util.Utils;
import ch.njol.util.Math2;
import org.bukkit.util.Vector;
@@ -85,9 +86,9 @@ public class DefaultOperations {
});
// Timespan - Timespan
- Arithmetics.registerOperation(Operator.ADDITION, Timespan.class, (left, right) -> new Timespan(Math2.addClamped(left.getMilliSeconds(), right.getMilliSeconds())));
- Arithmetics.registerOperation(Operator.SUBTRACTION, Timespan.class, (left, right) -> new Timespan(Math.max(0, left.getMilliSeconds() - right.getMilliSeconds())));
- Arithmetics.registerDifference(Timespan.class, (left, right) -> new Timespan(Math.abs(left.getMilliSeconds() - right.getMilliSeconds())));
+ Arithmetics.registerOperation(Operator.ADDITION, Timespan.class, (left, right) -> new Timespan(Math2.addClamped(left.getAs(TimePeriod.MILLISECOND), right.getAs(TimePeriod.MILLISECOND))));
+ Arithmetics.registerOperation(Operator.SUBTRACTION, Timespan.class, (left, right) -> new Timespan(Math.max(0, left.getAs(TimePeriod.MILLISECOND) - right.getAs(TimePeriod.MILLISECOND))));
+ Arithmetics.registerDifference(Timespan.class, (left, right) -> new Timespan(Math.abs(left.getAs(TimePeriod.MILLISECOND) - right.getAs(TimePeriod.MILLISECOND))));
Arithmetics.registerDefaultValue(Timespan.class, Timespan::new);
// Timespan - Number
@@ -96,20 +97,24 @@ public class DefaultOperations {
long scalar = right.longValue();
if (scalar < 0)
return null;
- return new Timespan(Math2.multiplyClamped(left.getMilliSeconds(), scalar));
+ return new Timespan(Math2.multiplyClamped(left.getAs(TimePeriod.MILLISECOND), scalar));
}, (left, right) -> {
long scalar = left.longValue();
if (scalar < 0)
return null;
- return new Timespan(scalar * right.getMilliSeconds());
+ return new Timespan(scalar * right.getAs(TimePeriod.MILLISECOND));
});
Arithmetics.registerOperation(Operator.DIVISION, Timespan.class, Number.class, (left, right) -> {
long scalar = right.longValue();
if (scalar <= 0)
return null;
- return new Timespan(left.getMilliSeconds() / scalar);
+ return new Timespan(left.getAs(TimePeriod.MILLISECOND) / scalar);
});
+ // Timespan / Timespan = Number
+ Arithmetics.registerOperation(Operator.DIVISION, Timespan.class, Timespan.class, Number.class,
+ (left, right) -> left.getAs(TimePeriod.MILLISECOND) / (double) right.getAs(TimePeriod.MILLISECOND));
+
// Date - Timespan
Arithmetics.registerOperation(Operator.ADDITION, Date.class, Timespan.class, Date::plus);
Arithmetics.registerOperation(Operator.SUBTRACTION, Date.class, Timespan.class, Date::minus);
diff --git a/src/main/java/ch/njol/skript/events/SimpleEvents.java b/src/main/java/ch/njol/skript/events/SimpleEvents.java
index 23f819ea890..c470d68a07d 100644
--- a/src/main/java/ch/njol/skript/events/SimpleEvents.java
+++ b/src/main/java/ch/njol/skript/events/SimpleEvents.java
@@ -797,6 +797,22 @@ public class SimpleEvents {
.since("INSERT VERSION")
.requiredPlugins("Spigot 1.19.4+");
}
+
+ if (Skript.classExists("com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent")) {
+ Skript.registerEvent("Enderman Enrage", SimpleEvent.class, com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent.class, "enderman (enrage|anger)")
+ .description(
+ "Called when an enderman gets mad because a player looked at them.",
+ "Note: This does not stop enderman from targeting the player as a result of getting damaged."
+ )
+ .examples(
+ "# Stops endermen from getting angry players with the permission \"safeFrom.enderman\"",
+ "on enderman enrage:",
+ "\tif player has permission \"safeFrom.enderman\":",
+ "\t\tcancel event"
+ )
+ .since("INSERT VERSION")
+ .requiredPlugins("Paper");
+ }
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprTernary.java b/src/main/java/ch/njol/skript/expressions/ExprTernary.java
index 3992f308623..dc4f5b518c6 100644
--- a/src/main/java/ch/njol/skript/expressions/ExprTernary.java
+++ b/src/main/java/ch/njol/skript/expressions/ExprTernary.java
@@ -122,8 +122,10 @@ public boolean isSingle() {
}
@Override
- public String toString(Event e, boolean debug) {
- return ifTrue.toString(e, debug) + " if " + condition + " otherwise " + ifFalse.toString(e, debug);
+ public String toString(Event event, boolean debug) {
+ return ifTrue.toString(event, debug)
+ + " if " + condition.toString(event, debug)
+ + " otherwise " + ifFalse.toString(event, debug);
}
}
diff --git a/src/main/java/ch/njol/skript/expressions/ExprWhether.java b/src/main/java/ch/njol/skript/expressions/ExprWhether.java
new file mode 100644
index 00000000000..4817551e181
--- /dev/null
+++ b/src/main/java/ch/njol/skript/expressions/ExprWhether.java
@@ -0,0 +1,78 @@
+/**
+ * This file is part of Skript.
+ *
+ * Skript is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Skript is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Skript. If not, see .
+ *
+ * Copyright Peter Güttinger, SkriptLang team and contributors
+ */
+package ch.njol.skript.expressions;
+
+import ch.njol.skript.Skript;
+import ch.njol.skript.doc.Description;
+import ch.njol.skript.doc.Examples;
+import ch.njol.skript.doc.Name;
+import ch.njol.skript.doc.Since;
+import ch.njol.skript.lang.Condition;
+import ch.njol.skript.lang.Expression;
+import ch.njol.skript.lang.ExpressionType;
+import ch.njol.skript.lang.SkriptParser.ParseResult;
+import ch.njol.skript.lang.util.SimpleExpression;
+import ch.njol.util.Kleenean;
+import org.bukkit.event.Event;
+import org.jetbrains.annotations.UnknownNullability;
+
+@Name("Whether")
+@Description("A shorthand for returning the result of a condition (true or false). This is functionally identical to using `true if else false`.")
+@Examples({
+ "set {fly} to whether player can fly",
+ "broadcast \"Flying: %whether player is flying%\""
+})
+@Since("INSERT VERSION")
+public class ExprWhether extends SimpleExpression {
+
+ static {
+ Skript.registerExpression(ExprWhether.class, Boolean.class, ExpressionType.PATTERN_MATCHES_EVERYTHING,
+ "whether <.+>");
+ }
+
+ private @UnknownNullability Condition condition;
+
+ @Override
+ public boolean init(Expression>[] expressions, int pattern, Kleenean delayed, ParseResult result) {
+ String input = result.regexes.get(0).group();
+ this.condition = Condition.parse(input, "Can't understand this condition: " + input);
+ return condition != null;
+ }
+
+ @Override
+ protected Boolean[] get(Event event) {
+ return new Boolean[] {condition.check(event)};
+ }
+
+ @Override
+ public Class extends Boolean> getReturnType() {
+ return Boolean.class;
+ }
+
+ @Override
+ public boolean isSingle() {
+ return true;
+ }
+
+ @Override
+ public String toString(Event event, boolean debug) {
+ return "whether " + condition.toString(event, debug);
+ }
+
+}
diff --git a/src/main/java/ch/njol/skript/structures/StructCommand.java b/src/main/java/ch/njol/skript/structures/StructCommand.java
index c9d96de4799..4348e23bb1f 100644
--- a/src/main/java/ch/njol/skript/structures/StructCommand.java
+++ b/src/main/java/ch/njol/skript/structures/StructCommand.java
@@ -341,7 +341,9 @@ private void scheduleCommandSync() {
if (SYNC_COMMANDS.get()) {
SYNC_COMMANDS.set(false);
if (DELAY_COMMAND_SYNCING) {
- Bukkit.getScheduler().runTask(Skript.getInstance(), this::forceCommandSync);
+ // if the plugin is disabled, the server is likely closing and delaying will cause an error.
+ if (Bukkit.getPluginManager().isPluginEnabled(Skript.getInstance()))
+ Bukkit.getScheduler().runTask(Skript.getInstance(), this::forceCommandSync);
} else {
forceCommandSync();
}
diff --git a/src/main/java/ch/njol/skript/util/Timespan.java b/src/main/java/ch/njol/skript/util/Timespan.java
index a73f1ce6aaf..ff70f8b365f 100644
--- a/src/main/java/ch/njol/skript/util/Timespan.java
+++ b/src/main/java/ch/njol/skript/util/Timespan.java
@@ -44,6 +44,7 @@ public class Timespan implements YggdrasilSerializable, Comparable { /
public enum TimePeriod {
+ MILLISECOND(1L),
TICK(50L),
SECOND(1000L),
MINUTE(SECOND.time * 60L),
diff --git a/src/main/resources/lang/default.lang b/src/main/resources/lang/default.lang
index 90a37eb9e32..701cd9d07b9 100644
--- a/src/main/resources/lang/default.lang
+++ b/src/main/resources/lang/default.lang
@@ -344,6 +344,7 @@ tree types:
# -- Time --
time:
+ millisecond: millisecond¦s
tick: tick¦s
second: second¦s
minute: minute¦s
diff --git a/src/test/skript/environments/java8/paper-1.13.2.json b/src/test/skript/environments/java11/paper-1.13.2.json
similarity index 100%
rename from src/test/skript/environments/java8/paper-1.13.2.json
rename to src/test/skript/environments/java11/paper-1.13.2.json
diff --git a/src/test/skript/environments/java8/paper-1.14.4.json b/src/test/skript/environments/java11/paper-1.14.4.json
similarity index 100%
rename from src/test/skript/environments/java8/paper-1.14.4.json
rename to src/test/skript/environments/java11/paper-1.14.4.json
diff --git a/src/test/skript/environments/java8/paper-1.15.2.json b/src/test/skript/environments/java11/paper-1.15.2.json
similarity index 100%
rename from src/test/skript/environments/java8/paper-1.15.2.json
rename to src/test/skript/environments/java11/paper-1.15.2.json
diff --git a/src/test/skript/environments/java8/paper-1.16.5.json b/src/test/skript/environments/java11/paper-1.16.5.json
similarity index 100%
rename from src/test/skript/environments/java8/paper-1.16.5.json
rename to src/test/skript/environments/java11/paper-1.16.5.json
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprArithmetic.sk b/src/test/skript/tests/syntaxes/expressions/ExprArithmetic.sk
index 9d1276f4f85..ef17ec0d979 100644
--- a/src/test/skript/tests/syntaxes/expressions/ExprArithmetic.sk
+++ b/src/test/skript/tests/syntaxes/expressions/ExprArithmetic.sk
@@ -224,7 +224,13 @@ test "timespan arithmetic":
assert (2 * {_t1}) is (2 seconds) with "2 * 1 second is not 2 seconds"
assert (2 / {_t1}) is not set with "number divided by timespan is set"
- assert ({_t1} + 2) is not set with "timespan plus number is set"
+ assert ({_t1} + 2) is not set with "timespan plus number is set"
+
+ assert {_t1} / {_t2} is 0.5 with "timespan / timespan failed"
+ assert {_t1} / 1 tick is 20 with "timespan / timespan of different units failed"
+ assert 0 seconds / {_t2} is 0 with "0 timespan / timespan failed"
+ assert {_t1} / 0 seconds is infinity value with "timespan / 0 timespan failed"
+ assert isNaN(0 seconds / 0 ticks) is true with "0 timespan / 0 timespan failed", expected NaN value, got (0 seconds / 0 ticks)
test "date arithmetic":
set {_d1} to now
diff --git a/src/test/skript/tests/syntaxes/expressions/ExprWhether.sk b/src/test/skript/tests/syntaxes/expressions/ExprWhether.sk
new file mode 100644
index 00000000000..83001203599
--- /dev/null
+++ b/src/test/skript/tests/syntaxes/expressions/ExprWhether.sk
@@ -0,0 +1,14 @@
+test "whether":
+ set {_number} to 5
+ set {_okay} to whether {_number} is greater than 3
+ assert {_okay} is true with "Condition didn't evaluate correctly"
+ set {_okay} to whether {_number} is less than 6
+ assert {_okay} is true with "Condition didn't evaluate correctly"
+ set {_okay} to whether {_number} is 5
+ assert {_okay} is true with "Condition didn't evaluate correctly"
+ delete {_okay}
+ spawn a pig at spawn of "world":
+ set {_pig} to event-entity
+ assert (whether {_pig} is alive) is true with "Condition didn't evaluate correctly"
+ assert (whether health of {_pig} is greater than 0) is true with "Condition didn't evaluate correctly"
+ delete the last spawned pig