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 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