9
0
mirror of https://github.com/Auxilor/EcoMobs.git synced 2025-12-19 15:09:17 +00:00

Compare commits

...

83 Commits

Author SHA1 Message Date
Auxilor
b53ab306ed libreforge-updater 2022-12-26 14:01:48 +01:00
Auxilor
33f82117e4 Updated modelengine 2022-12-20 15:20:45 +00:00
Auxilor
a80e060a7e libreforge-updater 2022-12-20 15:15:33 +00:00
Auxilor
a915752922 libreforge-updater 2022-12-12 14:01:34 +00:00
Auxilor
06eb724bd8 libreforge-updater 2022-12-09 17:01:53 +00:00
Auxilor
18c66ef10c libreforge-updater 2022-12-05 10:51:14 +00:00
Auxilor
ae0c8531b0 libreforge-updater 2022-11-30 17:38:55 +00:00
Auxilor
705eafb9af libreforge-updater 2022-11-27 21:45:04 +00:00
Auxilor
e83ede56f0 libreforge-updater 2022-11-26 19:20:59 +00:00
Auxilor
6bddf72111 libreforge-updater 2022-11-24 14:30:48 +00:00
Auxilor
d32d07f4e2 libreforge-updater 2022-11-23 17:25:42 +00:00
Auxilor
8c40d9861d libreforge-updater 2022-11-21 16:03:34 +00:00
Auxilor
03272f794e libreforge-updater 2022-11-17 08:39:07 +00:00
Auxilor
8ff42da43c libreforge-updater 2022-11-12 17:35:11 +00:00
Auxilor
7f61f6a66a libreforge-updater 2022-11-06 19:52:34 +00:00
Auxilor
c1dde026b7 Updated chains 2022-11-06 17:00:48 +00:00
Auxilor
983246a7c4 Added illusioner 2022-11-06 16:56:39 +00:00
Auxilor
ee32897b1c libreforge-updater 2022-11-01 16:23:35 +00:00
Auxilor
67b38896ca libreforge-updater 2022-10-28 11:35:44 +01:00
Auxilor
39b91bc828 libreforge-updater 2022-10-26 22:12:03 +01:00
Auxilor
e2e7b44a75 Fix 2022-10-24 17:11:42 +01:00
Auxilor
3c1e5ee192 libreforge-updater 2022-10-24 17:05:27 +01:00
Auxilor
56789f331b libreforge-updater 2022-10-21 19:26:42 +01:00
Auxilor
e99b96132f libreforge-updater 2022-10-19 20:44:41 +01:00
Auxilor
c0297cd3db libreforge-updater 2022-10-18 14:14:41 +01:00
Auxilor
3b798a8ed7 libreforge-updater 2022-10-16 23:27:19 +01:00
Auxilor
bc73201ec5 libreforge-updater 2022-10-13 20:13:11 +01:00
Auxilor
b1365855af libreforge-updater 2022-10-10 21:04:32 +01:00
Auxilor
1ce50cb0b9 libreforge-updater 2022-10-09 15:03:11 +01:00
Auxilor
2a50868624 libreforge-updater 2022-10-07 19:51:54 +01:00
Auxilor
0a0e7a9661 libreforge-updater 2022-10-06 12:04:55 +01:00
Auxilor
8cd4ccdbd7 libreforge-updater 2022-10-04 15:53:28 +01:00
Auxilor
429bc6a61f libreforge-updater 2022-10-03 18:30:03 +01:00
Auxilor
b92ea06667 Fixed _example.yml 2022-10-02 17:01:40 +01:00
Auxilor
1e332bf845 libreforge-updater 2022-10-02 14:58:47 +01:00
Auxilor
7cec9f3e30 Added separator ambivalence to boss configs and Model Engine animation support 2022-09-29 08:40:30 +01:00
Auxilor
7db3af5dca oops 2022-09-28 17:55:29 +01:00
Auxilor
137f4e3732 libreforge-updater 2022-09-28 17:53:14 +01:00
Auxilor
7338a24b81 Fix 2022-09-28 16:12:42 +01:00
Auxilor
bde5de1d77 Fixed plugin.yml 2022-09-28 16:12:23 +01:00
Auxilor
b48cc66383 Updated to 8.91.1 2022-09-28 16:12:00 +01:00
Auxilor
bf59ba4d4a Improved _example.yml 2022-09-28 16:11:48 +01:00
Auxilor
127a43e032 PR Improvements 2022-09-28 16:10:21 +01:00
Will FP
383893c8f6 Merge pull request #50
fix: boss transformations
2022-09-28 16:01:24 +01:00
Will FP
37926bd016 Merge pull request #52
Feature/modelengine
2022-09-28 16:01:08 +01:00
Will FP
6778058150 Merge pull request #53
fix: handle spawning of bosses from droppers and dispensers
2022-09-28 15:59:45 +01:00
Auxilor
8addad09d2 fix 2022-09-26 18:54:34 +01:00
DaRacci
7fe0eece16 fix: handle spawning of bosses from droppers and dispensers 2022-09-27 01:13:42 +10:00
DaRacci
eca8726323 fix: check if the model exists 2022-09-27 00:10:20 +10:00
DaRacci
16ba41f39a feat: ModelEngine support 2022-09-27 00:07:28 +10:00
Auxilor
685f40a71b Merge branch 'fix/publishing'
# Conflicts:
#	build.gradle
2022-09-26 13:54:00 +01:00
Auxilor
76c6d22a00 libreforge-updater 2022-09-26 10:52:49 +01:00
DaRacci
38629407bc fix: Use component from subproject 2022-09-26 14:44:12 +10:00
DaRacci
1eee00b88e fix: Publishing
Also converted gradle build to kotlin.
Also updated gradle to 7.5.1

Closes: https://github.com/Auxilor/EcoBosses/issues/49, https://github.com/Auxilor/EcoBosses/issues/41
2022-09-25 23:39:05 +10:00
DaRacci
de47ccf159 fix: boss transformations
Closes: https://github.com/Auxilor/EcoBosses/issues/36
2022-09-25 22:27:08 +10:00
Auxilor
b81e7af836 libreforge-updater 2022-09-22 17:31:03 +01:00
Auxilor
fcde21c21a libreforge-updater 2022-09-21 15:29:05 +01:00
Auxilor
405659f293 libreforge-updater 2022-09-20 10:57:39 +01:00
Auxilor
2d6154d11f libreforge-updater 2022-09-17 15:46:02 +01:00
Auxilor
9fad76ffad libreforge-updater 2022-09-15 12:15:47 +01:00
Auxilor
e4a40470b8 libreforge-updater 2022-09-15 12:09:44 +01:00
Auxilor
f966629e21 libreforge-updater 2022-09-14 18:53:14 +01:00
Auxilor
93d09c1f3d libreforge-updater 2022-09-14 15:12:30 +01:00
Auxilor
56763be02d libreforge-updater 2022-09-14 15:09:33 +01:00
Auxilor
bd05d4474f libreforge-updater 2022-09-14 12:59:22 +01:00
Auxilor
aa0f9c195d libreforge-updater 2022-09-13 19:15:06 +01:00
Auxilor
e9e0214d1e libreforge-updater 2022-09-12 21:20:54 +01:00
Auxilor
744e3a943d libreforge-updater 2022-09-12 17:14:59 +01:00
Auxilor
fcaea262e8 libreforge-updater 2022-09-11 19:27:24 +01:00
Auxilor
062d2eea77 libreforge-updater 2022-09-10 12:58:21 +01:00
Auxilor
25844170eb libreforge-updater 2022-09-10 10:51:17 +01:00
Auxilor
00cc509b40 libreforge-updater 2022-09-06 15:43:31 +01:00
Auxilor
77e46ffb55 libreforge-updater 2022-09-06 13:46:10 +01:00
Auxilor
1f72e3b9b3 libreforge-updater 2022-09-06 11:25:17 +01:00
Auxilor
a94a5cc04d libreforge-updater 2022-09-05 18:00:28 +01:00
Auxilor
2b8d8eb20a libreforge-updater 2022-09-04 17:22:44 +01:00
Auxilor
1b4851fb9c libreforge-updater 2022-09-04 16:22:01 +01:00
Auxilor
80181bb66e libreforge-updater 2022-09-03 14:20:18 +01:00
Auxilor
d2d6355003 libreforge-updater 2022-09-01 13:05:26 +01:00
Auxilor
b44016d4fe libreforge-updater 2022-08-31 12:45:30 +01:00
Auxilor
74f1953074 libreforge-updater 2022-08-30 20:29:05 +01:00
Auxilor
041e8e070e libreforge-updater 2022-08-30 19:21:42 +01:00
Auxilor
d69b205de5 libreforge-updater 2022-08-29 10:58:32 +01:00
34 changed files with 1017 additions and 584 deletions

View File

@@ -1,135 +0,0 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
}
}
plugins {
id 'java-library'
id 'com.github.johnrengelman.shadow' version '7.0.0'
id 'maven-publish'
id 'java'
}
dependencies {
implementation project(":eco-core").getSubprojects()
}
allprojects {
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow'
repositories {
mavenCentral()
mavenLocal()
maven { url 'https://jitpack.io' }
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
maven { url 'https://repo.codemc.org/repository/nms/' }
maven { url 'https://repo.codemc.org/repository/maven-public' }
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
maven { url 'https://oss.sonatype.org/content/groups/public/' }
maven { url 'https://maven.enginehub.org/repo/' }
maven { url 'https://ci.ender.zone/plugin/repository/project/' }
maven { url 'https://ci.ender.zone/plugin/repository/everything/' }
maven { url 'https://repo.md-5.net/content/repositories/snapshots/' }
maven { url 'https://repo.dmulloy2.net/nexus/repository/public/' }
maven { url 'https://papermc.io/repo/repository/maven-public/' }
maven { url 'https://repo.maven.apache.org/maven2/' }
maven { url 'https://repo.dustplanet.de/artifactory/ext-release-local/' }
maven { url 'https://maven.seyfahni.de/repository/snapshots/' }
maven { url 'https://libraries.minecraft.net/' }
maven { url 'https://repo.spongepowered.org/maven/' }
maven { url 'https://org.kitteh.pastegg' }
maven { url 'https://repo.mikeprimm.com/' }
maven { url 'https://maven.sk89q.com/repo/' }
maven { url 'https://github.com/factions-site/repo/raw/public/' }
maven { url 'https://repo.extendedclip.com/content/repositories/placeholderapi/' }
}
jar {
onlyIf { !sourceSets.main.allSource.files.isEmpty() }
}
shadowJar {
relocate('com.willfp.libreforge', 'com.willfp.ecobosses.libreforge')
relocate('org.joml', 'com.willfp.ecobosses.libreforge.joml')
}
dependencies {
compileOnly 'com.willfp:eco:6.35.1'
implementation 'com.willfp:libreforge:3.88.0'
implementation 'org.joml:joml:1.10.4'
compileOnly 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.7.10'
}
tasks.withType(JavaCompile) {
options.deprecation = true
options.encoding = 'UTF-8'
}
processResources {
filesNotMatching(["**/*.png", "**/models/**", "**/textures/**", "**lang.yml"]) {
expand projectVersion: project.version
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
kotlinOptions {
jvmTarget = "17"
}
}
java.sourceCompatibility = JavaVersion.VERSION_17
java.targetCompatibility = JavaVersion.VERSION_17
compileJava.options.encoding = 'UTF-8'
compileJava.dependsOn clean
build.dependsOn shadowJar
}
tasks.withType(Jar) {
destinationDirectory = file("$rootDir/bin/")
}
clean.doLast {
file("${rootDir}/bin").deleteDir()
}
shadowJar {
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + ".jar"
}
jar {
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + " " + "unshaded" + ".jar"
}
group = 'com.willfp'
archivesBaseName = project.name
version = findProperty("version")
compileJava.options.encoding = 'UTF-8'
build.dependsOn shadowJar
build.dependsOn publishToMavenLocal
task buyThePlugins {
dependsOn subprojects.build
doLast {
println 'If you like the plugin, please consider buying it on Spigot or Polymart!'
println 'Spigot: https://www.spigotmc.org/resources/authors/auxilor.507394/'
println 'Polymart: https://polymart.org/user/auxilor.1107/'
println 'Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.'
}
}
build.finalizedBy buyThePlugins

131
build.gradle.kts Normal file
View File

@@ -0,0 +1,131 @@
plugins {
java
`java-library`
`maven-publish`
kotlin("jvm") version "1.7.10"
id("com.github.johnrengelman.shadow") version "7.0.0"
}
group = "com.willfp"
version = findProperty("version")!!
base {
archivesName.set(project.name)
}
dependencies {
project(":eco-core").dependencyProject.subprojects {
implementation(this)
}
}
allprojects {
apply(plugin = "java")
apply(plugin = "kotlin")
apply(plugin = "com.github.johnrengelman.shadow")
repositories {
mavenLocal()
mavenCentral()
maven("https://jitpack.io")
maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
maven("https://repo.codemc.org/repository/nms/")
maven("https://repo.codemc.org/repository/maven-public")
maven("https://repo.dmulloy2.net/nexus/repository/public/")
maven("https://papermc.io/repo/repository/maven-public/")
maven("https://mvn.lumine.io/repository/maven-public/")
}
dependencies {
compileOnly("com.willfp:eco:6.44.0")
compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
implementation("com.willfp:libreforge:3.126.3")
implementation("org.joml:joml:1.10.4")
}
java {
withSourcesJar()
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
tasks {
compileKotlin {
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all"
}
}
compileJava {
options.isDeprecation = true
options.encoding = "UTF-8"
dependsOn(clean)
}
processResources {
val ignoreList = listOf("**/*.png", "**/models/**", "**/textures/**", "**lang.yml")
filesNotMatching(ignoreList) {
expand("projectVersion" to project.version)
}
}
build {
dependsOn(shadowJar)
}
shadowJar {
relocate("com.willfp.libreforge", "com.willfp.ecobosses.libreforge")
relocate("org.joml", "com.willfp.ecobosses.libreforge.joml")
}
}
}
tasks {
shadowJar {
destinationDirectory.set(file("$rootDir/bin"))
}
val buyThePlugins by creating {
dependsOn(subprojects.map { it.tasks.getByName("build") })
doLast {
println("If you like the plugin, please consider buying it on Spigot or Polymart!")
println("Spigot: https://www.spigotmc.org/resources/authors/auxilor.507394/")
println("Polymart: https://polymart.org/user/auxilor.1107/")
println("Buying gives you access to support and the plugin auto-updater, and it allows me to keep developing plugins.")
}
}
build {
dependsOn(shadowJar)
dependsOn(publishToMavenLocal)
finalizedBy(buyThePlugins)
}
clean.get().doLast { file("$rootDir/bin").deleteRecursively() }
fun fileName(extra: String): String = buildString {
append(findProperty("plugin-name"))
append(" v")
append(findProperty("version"))
if (extra.isNotEmpty()) {
append(" ")
append(extra)
}
append(".jar")
}
shadowJar.get().archiveFileName.set(fileName(""))
jar.get().archiveFileName.set(fileName("unshaded"))
}
publishing {
publications {
register("maven", MavenPublication::class) {
from(subprojects.first { it.name == "core-plugin" }.components["java"])
}
}
}

View File

@@ -1,2 +0,0 @@
group 'com.willfp'
version rootProject.version

View File

@@ -0,0 +1,2 @@
group = "com.willfp"
version = rootProject.version

View File

@@ -1,8 +0,0 @@
group 'com.willfp'
version rootProject.version
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
compileOnly 'com.github.lokka30:LevelledMobs:3.1.4'
compileOnly 'net.kyori:adventure-api:4.9.3'
}

View File

@@ -0,0 +1,11 @@
group = "com.willfp"
version = rootProject.version
dependencies {
compileOnly("org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT")
compileOnly("net.kyori:adventure-api:4.9.3")
// Integrations
compileOnly("com.github.lokka30:LevelledMobs:3.1.4")
compileOnly("com.ticxo.modelengine:api:R3.1.3")
}

View File

@@ -7,7 +7,6 @@ import com.willfp.ecobosses.bosses.Bosses
import com.willfp.ecobosses.bosses.EggDisplay
import com.willfp.ecobosses.bosses.bossHolders
import com.willfp.ecobosses.commands.CommandEcobosses
import com.willfp.ecobosses.config.EcoBossesYml
import com.willfp.ecobosses.defence.DamageMultiplierHandler
import com.willfp.ecobosses.defence.ImmunitiesHandler
import com.willfp.ecobosses.defence.MountHandler
@@ -26,14 +25,15 @@ import com.willfp.libreforge.LibReforgePlugin
import org.bukkit.event.Listener
class EcoBossesPlugin : LibReforgePlugin() {
val ecoBossesYml: EcoBossesYml
init {
instance = this
ecoBossesYml = EcoBossesYml(this)
registerHolderProvider { it.bossHolders }
}
override fun handleEnableAdditional() {
this.copyConfigs("bosses")
}
override fun handleReloadAdditional() {
Bosses.getAllAlive().forEach { it.remove() }
@@ -61,7 +61,7 @@ class EcoBossesPlugin : LibReforgePlugin() {
DiscoverRecipeListener(this),
TopDamagerListener(),
LifecycleHandlers(),
SpawnEggHandler(),
SpawnEggHandler(this),
DamageMultiplierHandler(),
MountHandler(),
PickupHandler(),
@@ -79,10 +79,6 @@ class EcoBossesPlugin : LibReforgePlugin() {
)
}
override fun getMinimumEcoVersion(): String {
return "6.35.1"
}
companion object {
@JvmStatic
lateinit var instance: EcoBossesPlugin

View File

@@ -3,16 +3,18 @@ package com.willfp.ecobosses.bosses
import com.google.common.collect.BiMap
import com.google.common.collect.HashBiMap
import com.google.common.collect.ImmutableList
import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.readConfig
import com.willfp.eco.core.config.updating.ConfigUpdater
import com.willfp.ecobosses.EcoBossesPlugin
import com.willfp.libreforge.chains.EffectChains
import com.willfp.libreforge.separatorAmbivalent
import org.bukkit.entity.Entity
import org.bukkit.entity.LivingEntity
import java.io.File
import java.util.UUID
object Bosses {
/**
* Registered bosses.
*/
/** Registered bosses. */
private val BY_ID: BiMap<String, EcoBoss> = HashBiMap.create()
/**
@@ -44,16 +46,19 @@ object Bosses {
@ConfigUpdater
@JvmStatic
fun update(plugin: EcoBossesPlugin) {
plugin.ecoBossesYml.getSubsections("chains").mapNotNull {
EffectChains.compile(it, "Effect Chains")
}
for (boss in values()) {
removeBoss(boss)
}
for (bossConfig in plugin.ecoBossesYml.getSubsections("bosses")) {
addNewBoss(EcoBoss(bossConfig, plugin))
for ((id, config) in plugin.fetchConfigs("bosses")) {
addNewBoss(EcoBoss(id, config, plugin))
}
val ecoBossesYml = File(plugin.dataFolder, "ecobosses.yml").readConfig(ConfigType.YAML)
for (bossConfig in ecoBossesYml.getSubsections("bosses")) {
// Boss configs are separator ambivalent in order to preserve backwards compatibility
addNewBoss(EcoBoss(bossConfig.getString("id"), bossConfig.separatorAmbivalent(), plugin))
}
}
@@ -119,4 +124,14 @@ object Bosses {
operator fun get(entity: LivingEntity): LivingEcoBoss? {
return get(entity.uniqueId)
}
/** If an entity is a boss. */
val Entity?.isBoss: Boolean
get() {
if (this !is LivingEntity) {
return false
}
return Bosses[this] != null
}
}

View File

@@ -1,11 +1,16 @@
package com.willfp.ecobosses.bosses
import com.ticxo.modelengine.api.ModelEngineAPI
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.entities.CustomEntity
import com.willfp.eco.core.entities.Entities
import com.willfp.eco.core.entities.TestableEntity
import com.willfp.eco.core.entities.ai.*
import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.EntityGoals
import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.core.entities.ai.TargetGoals
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder
@@ -16,8 +21,22 @@ import com.willfp.eco.util.NamespacedKeyUtils
import com.willfp.eco.util.toComponent
import com.willfp.ecobosses.events.BossKillEvent
import com.willfp.ecobosses.lifecycle.BossLifecycle
import com.willfp.ecobosses.tick.*
import com.willfp.ecobosses.util.*
import com.willfp.ecobosses.tick.BossBarTicker
import com.willfp.ecobosses.tick.BossTicker
import com.willfp.ecobosses.tick.ChunkTicker
import com.willfp.ecobosses.tick.DisplayNameTicker
import com.willfp.ecobosses.tick.LifespanTicker
import com.willfp.ecobosses.tick.TargetTicker
import com.willfp.ecobosses.tick.TeleportHandler
import com.willfp.ecobosses.util.BossDrop
import com.willfp.ecobosses.util.CommandReward
import com.willfp.ecobosses.util.ConfiguredSound
import com.willfp.ecobosses.util.LocalBroadcast
import com.willfp.ecobosses.util.LocalCommands
import com.willfp.ecobosses.util.PlayableSound
import com.willfp.ecobosses.util.SpawnTotem
import com.willfp.ecobosses.util.XpReward
import com.willfp.ecobosses.util.topDamagers
import com.willfp.libreforge.Holder
import com.willfp.libreforge.conditions.Conditions
import com.willfp.libreforge.effects.Effects
@@ -30,15 +49,15 @@ import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
import java.util.*
import java.util.Objects
import java.util.UUID
class EcoBoss(
override val id: String,
val config: Config,
private val plugin: EcoPlugin
) : Holder {
override val id: String = config.getString("id")
val displayName: String = config.getString("displayName")
val displayName: String = config.getString("display-name")
val lifespan = config.getInt("lifespan")
@@ -48,23 +67,23 @@ class EcoBoss(
val targetMode = TargetMode.getByID(config.getString("target.mode"))!!
val isBossBarEnabled = config.getBool("bossBar.enabled")
val isBossBarEnabled = config.getBool("boss-bar.enabled")
val bossBarRadius = config.getDouble("bossBar.radius")
val bossBarRadius = config.getDouble("boss-bar.radius")
val isPreventingMounts = config.getBool("defence.preventMounts")
val isPreventingMounts = config.getBool("defence.prevent-mounts")
val isImmuneToExplosions = config.getBool("defence.explosionImmune")
val isImmuneToExplosions = config.getBool("defence.explosion-immune")
val isImmuneToFire = config.getBool("defence.fireImmune")
val isImmuneToFire = config.getBool("defence.fire-immune")
val isImmuneToDrowning = config.getBool("defence.drowningImmune")
val isImmuneToDrowning = config.getBool("defence.drowning-immune")
val isImmuneToSuffocation = config.getBool("defence.suffocationImmune")
val isImmuneToSuffocation = config.getBool("defence.suffocation-immune")
val meleeDamageMultiplier = config.getDouble("defence.meleeDamageMultiplier")
val meleeDamageMultiplier = config.getDouble("defence.melee-damage-multiplier")
val projectileDamageMultiplier = config.getDouble("defence.projectileDamageMultiplier")
val projectileDamageMultiplier = config.getDouble("defence.projectile-damage-multiplier")
val canTeleport = config.getBool("defence.teleportation.enabled")
@@ -139,7 +158,7 @@ class EcoBoss(
)
}
val disabledTotemWorlds: List<String> = config.getStrings("spawn.totem.notInWorlds")
val disabledTotemWorlds: List<String> = config.getStrings("spawn.totem.not-in-worlds")
val autoSpawnInterval = config.getInt("spawn.autospawn.interval")
@@ -151,26 +170,22 @@ class EcoBoss(
val x = config.getDouble("x")
val y = config.getDouble("y")
val z = config.getDouble("z")
locations.add(
Location(
world, x, y, z
)
)
locations.add(Location(world, x, y, z))
}
locations
}
val hasCustomAI = config.getBool("customai.enabled")
val hasCustomAI = config.getBool("custom-ai.enabled")
val targetGoals = config.getSubsections("customai.target-goals").mapNotNull {
val targetGoals = config.getSubsections("custom-ai.target-goals").mapNotNull {
val key = NamespacedKeyUtils.fromStringOrNull(it.getString("key")) ?: return@mapNotNull null
val deserializer = TargetGoals.getByKey(key) ?: return@mapNotNull null
val goal = deserializer.deserialize(it.getSubsection("args")) ?: return@mapNotNull null
ConfiguredGoal(it.getInt("priority"), goal)
}
val entityGoals = config.getSubsections("customai.ai-goals").mapNotNull {
val entityGoals = config.getSubsections("custom-ai.ai-goals").mapNotNull {
val key = NamespacedKeyUtils.fromStringOrNull(it.getString("key")) ?: return@mapNotNull null
val deserializer = EntityGoals.getByKey(key) ?: return@mapNotNull null
val goal = deserializer.deserialize(it.getSubsection("args")) ?: return@mapNotNull null
@@ -181,17 +196,19 @@ class EcoBoss(
Conditions.compile(it, "$id Spawn Conditions")
}
private val bossBarColor = BossBar.Color.valueOf(config.getString("bossBar.color").uppercase())
private val bossBarColor = BossBar.Color.valueOf(config.getString("boss-bar.color").uppercase())
private val bossBarStyle = BossBar.Overlay.valueOf(config.getString("bossBar.style").uppercase())
private val bossBarStyle = BossBar.Overlay.valueOf(config.getString("boss-bar.style").uppercase())
private val sounds: Map<BossLifecycle, PlayableSound> = run {
val map = mutableMapOf<BossLifecycle, PlayableSound>()
for (value in BossLifecycle.values()) {
map[value] = PlayableSound(config.getSubsections("sounds.${value.name.lowercase()}").map {
ConfiguredSound.fromConfig(it)
})
map[value] = PlayableSound(
config.getSubsections("sounds.${value.name.lowercase()}").map {
ConfiguredSound.fromConfig(it)
}
)
}
map
@@ -222,10 +239,10 @@ class EcoBoss(
private val commandRewards: Map<Int, Iterable<CommandReward>> = run {
val map = mutableMapOf<Int, Iterable<CommandReward>>()
for (rank in config.getSubsection("rewards.topDamagerCommands").getKeys(false)) {
for (rank in config.getSubsection("rewards.top-damager-commands").getKeys(false)) {
val rankRewards = mutableListOf<CommandReward>()
for (config in config.getSubsections("rewards.topDamagerCommands.$rank")) {
for (config in config.getSubsections("rewards.top-damager-commands.$rank")) {
rankRewards.add(
CommandReward(
config.getDouble("chance"),
@@ -240,12 +257,12 @@ class EcoBoss(
map
}
private val nearbyCommandRewardRadius = config.getDouble("rewards.nearbyPlayerCommands.radius")
private val nearbyCommandRewardRadius = config.getDouble("rewards.nearby-player-commands.radius")
private val nearbyCommands: Iterable<CommandReward> = run {
val list = mutableListOf<CommandReward>()
for (config in config.getSubsections("rewards.nearbyPlayerCommands.commands")) {
for (config in config.getSubsections("rewards.nearby-player-commands.commands")) {
list.add(
CommandReward(
config.getDouble("chance"),
@@ -262,7 +279,6 @@ class EcoBoss(
config.getInt("rewards.xp.maximum")
)
private val drops: Iterable<BossDrop> = run {
val list = mutableListOf<BossDrop>()
@@ -283,15 +299,21 @@ class EcoBoss(
private val mob: TestableEntity = Entities.lookup(config.getString("mob"))
private val modelEngineID = config.getStringOrNull("model-engine-id")
private val modelEngineAnimation = config.getStringOrNull("model-engine-animation")
private val currentlyAlive = mutableMapOf<UUID, LivingEcoBoss>()
override val conditions = config.getSubsections("conditions").mapNotNull {
Conditions.compile(it, "Boss ID $id")
}.toSet()
override val conditions = Conditions.compile(
config.getSubsections("conditions"),
"Boss ID $id"
)
override val effects = config.getSubsections("effects").mapNotNull {
Effects.compile(it, "Boss ID $id")
}.toSet()
override val effects = Effects.compile(
config.getSubsections("effects"),
"Boss ID $id"
)
fun markDead(uuid: UUID) {
currentlyAlive.remove(uuid)
@@ -321,8 +343,7 @@ class EcoBoss(
)
if (hasCustomAI) {
val controller = EntityController.getFor(mob)
.clearAllGoals()
val controller = EntityController.getFor(mob).clearAllGoals()
@Suppress("UNCHECKED_CAST") // What could go wrong?
targetGoals.forEach { controller.addTargetGoal(it.priority, it.goal as TargetGoal<in Mob>) }
@@ -330,6 +351,35 @@ class EcoBoss(
entityGoals.forEach { controller.addEntityGoal(it.priority, it.goal as EntityGoal<in Mob>) }
}
if (modelEngineID != null && Bukkit.getPluginManager().isPluginEnabled("ModelEngine")) {
val model = ModelEngineAPI.createActiveModel(modelEngineID)
if (model == null) {
plugin.logger.warning("Invalid Model Engine ID for boss $id")
}
if (modelEngineAnimation != null) {
val animationHandler = model.animationHandler
val animationProperty = animationHandler.getAnimation(modelEngineAnimation)
if (animationProperty != null) {
animationHandler.playAnimation(animationProperty, true)
} else {
plugin.logger.warning("Animation $modelEngineAnimation not found in model $modelEngineID, defaulting to walk!")
val animationPropertyWalk = animationHandler.getAnimation("walk")
if (animationPropertyWalk != null) {
animationHandler.playAnimation(animationPropertyWalk, true)
} else {
plugin.logger.warning("Walk animation not found in $modelEngineID!")
}
}
}
val modelled = ModelEngineAPI.createModeledEntity(mob)
modelled.addModel(model, true)
modelled.isBaseEntityVisible = false
}
val boss = LivingEcoBoss(
plugin,
mob,
@@ -420,7 +470,6 @@ class EcoBoss(
)
}
override fun equals(other: Any?): Boolean {
if (other !is EcoBoss) {
return false
@@ -434,8 +483,10 @@ class EcoBoss(
}
override fun toString(): String {
return ("EcoBoss{"
+ id
+ "}")
return (
"EcoBoss{" +
id +
"}"
)
}
}

View File

@@ -48,6 +48,6 @@ class LivingEcoBoss(
}
override fun toString(): String {
return "LivingEcoBoss{boss=${boss}, uuid=${entity.uniqueId}}"
return "LivingEcoBoss{boss=$boss, uuid=${entity.uniqueId}}"
}
}

View File

@@ -2,6 +2,10 @@ package com.willfp.ecobosses.commands
import com.willfp.eco.core.command.impl.PluginCommand
import com.willfp.ecobosses.EcoBossesPlugin
import com.willfp.ecobosses.bosses.Bosses
import com.willfp.libreforge.lrcdb.CommandExport
import com.willfp.libreforge.lrcdb.CommandImport
import com.willfp.libreforge.lrcdb.ExportableConfig
import org.bukkit.command.CommandSender
class CommandEcobosses(plugin: EcoBossesPlugin) : PluginCommand(
@@ -22,5 +26,14 @@ class CommandEcobosses(plugin: EcoBossesPlugin) : PluginCommand(
.addSubcommand(CommandKillall(plugin))
.addSubcommand(CommandSpawn(plugin))
.addSubcommand(CommandGive(plugin))
.addSubcommand(CommandImport("bosses", plugin))
.addSubcommand(CommandExport(plugin) {
Bosses.values().map {
ExportableConfig(
it.id,
it.config
)
}
})
}
}

View File

@@ -1,12 +0,0 @@
package com.willfp.ecobosses.config
import com.willfp.eco.core.config.BaseConfig
import com.willfp.eco.core.config.ConfigType
import com.willfp.ecobosses.EcoBossesPlugin
class EcoBossesYml(plugin: EcoBossesPlugin) : BaseConfig(
"ecobosses",
plugin,
true,
ConfigType.YAML
)

View File

@@ -1,10 +1,8 @@
package com.willfp.ecobosses.events
import com.willfp.ecobosses.bosses.LivingEcoBoss
import com.willfp.ecobosses.lifecycle.BossLifecycle
import org.bukkit.event.Event
import org.bukkit.event.HandlerList
import org.bukkit.event.entity.EntityDeathEvent
abstract class BossDeathEvent(
val boss: LivingEcoBoss

View File

@@ -1,7 +1,6 @@
package com.willfp.ecobosses.events
import com.willfp.ecobosses.bosses.LivingEcoBoss
import com.willfp.ecobosses.lifecycle.BossLifecycle
import org.bukkit.event.HandlerList
class BossDespawnEvent(

View File

@@ -1,7 +1,6 @@
package com.willfp.ecobosses.events
import com.willfp.ecobosses.bosses.LivingEcoBoss
import com.willfp.ecobosses.lifecycle.BossLifecycle
import org.bukkit.entity.Player
import org.bukkit.event.HandlerList
import org.bukkit.event.entity.EntityDeathEvent

View File

@@ -1,7 +1,6 @@
package com.willfp.ecobosses.events
import com.willfp.ecobosses.bosses.EcoBoss
import com.willfp.ecobosses.bosses.LivingEcoBoss
import org.bukkit.Location
import org.bukkit.entity.Player
import org.bukkit.event.Event
@@ -14,7 +13,7 @@ class BossTryDropItemEvent(
var items: MutableCollection<ItemStack>,
var chance: Double,
val player: Player?
): Event() {
) : Event() {
override fun getHandlers(): HandlerList {
return HANDLERS
}

View File

@@ -1,16 +1,25 @@
package com.willfp.ecobosses.lifecycle
import com.willfp.ecobosses.bosses.Bosses
import org.bukkit.entity.LivingEntity
import com.willfp.ecobosses.bosses.Bosses.isBoss
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.entity.EntityTransformEvent
import org.bukkit.event.entity.SlimeSplitEvent
class CompatibilityListeners : Listener {
@EventHandler
fun handle(event: SlimeSplitEvent) {
if (Bosses[event.entity as? LivingEntity ?: return] != null) {
event.isCancelled = true
if (!event.entity.isBoss) {
return
}
event.isCancelled = true
}
@EventHandler
fun handle(event: EntityTransformEvent) {
if (!event.entity.isBoss) {
return
}
event.isCancelled = true
}
}

View File

@@ -1,7 +1,6 @@
package com.willfp.ecobosses.lifecycle
import com.willfp.ecobosses.bosses.Bosses
import com.willfp.ecobosses.events.BossDeathEvent
import com.willfp.ecobosses.events.BossDespawnEvent
import com.willfp.ecobosses.events.BossKillEvent
import com.willfp.ecobosses.events.BossSpawnEvent

View File

@@ -23,7 +23,7 @@ object AutospawnHandler {
val world = location.world ?: continue
if (plugin.configYml.getBool("autospawn.one-boss-per-world")) {
if (Bosses.getAllAlive().mapNotNull { it.entity }.any { it.world == world }) {
if (Bosses.getAllAlive().map { it.entity }.any { it.world == world }) {
continue
}
}

View File

@@ -1,16 +1,26 @@
package com.willfp.ecobosses.spawn
import com.willfp.ecobosses.EcoBossesPlugin
import com.willfp.ecobosses.bosses.bossEgg
import com.willfp.ecobosses.events.BossSpawnEvent
import com.willfp.libreforge.conditions.isMet
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.block.Container
import org.bukkit.block.data.Directional
import org.bukkit.entity.Player
import org.bukkit.event.Event
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.block.BlockDispenseEvent
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.EquipmentSlot
import org.bukkit.inventory.ItemStack
class SpawnEggHandler : Listener {
class SpawnEggHandler(
private val plugin: EcoBossesPlugin
) : Listener {
@EventHandler(
ignoreCancelled = true
)
@@ -19,28 +29,13 @@ class SpawnEggHandler : Listener {
return
}
val item = event.item ?: return
val boss = item.bossEgg ?: return
if (!this.handleSpawnEgg(event.item, event.clickedBlock?.location?.add(0.0, 1.5, 0.0), event.player)) {
return
}
event.isCancelled = true
event.setUseItemInHand(Event.Result.DENY)
val location = event.clickedBlock?.location?.add(0.0, 1.5, 0.0) ?: return
val player = event.player
if (!boss.spawnConditions.all { it.condition.isConditionMet(player, it.config) }) {
return
}
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG, player)
Bukkit.getPluginManager().callEvent(spawnEvent)
if (spawnEvent.isCancelled) {
return
}
if (event.hand == EquipmentSlot.HAND) {
val hand = event.player.inventory.itemInMainHand
hand.amount = hand.amount - 1
@@ -48,7 +43,56 @@ class SpawnEggHandler : Listener {
val hand = event.player.inventory.itemInOffHand
hand.amount = hand.amount - 1
}
}
@EventHandler(
ignoreCancelled = true
)
fun handle(event: BlockDispenseEvent) {
val facing = (event.block.blockData as Directional).facing
val location = event.block.location.add(facing.direction.multiply(1.7))
if (!this.handleSpawnEgg(event.item, location, null)) return
event.isCancelled = true
val dispenser = event.block.state as? Container ?: return
// This is needed as the event must finish first,
// Otherwise the dispenser/dropper thinks the item is already removed from this event.
plugin.scheduler.run {
val item = dispenser.inventory.find { it?.isSimilar(event.item) == true } ?: return@run
item.amount--
dispenser.update()
}
}
private fun handleSpawnEgg(
item: ItemStack?,
location: Location?,
player: Player?
): Boolean {
val boss = item?.bossEgg ?: return false
if (location == null) {
return false
}
if (player != null) {
if (!boss.spawnConditions.isMet(player)) {
return false
}
}
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG, player)
Bukkit.getPluginManager().callEvent(spawnEvent)
if (spawnEvent.isCancelled) {
return false
}
boss.spawn(location)
return true
}
}
}

View File

@@ -11,7 +11,7 @@ class ChunkTicker : BossTicker {
}
if (currentChunk.isLoaded && currentChunk.isForceLoaded) {
return;
return
}
currentChunk.load()

View File

@@ -1,6 +1,5 @@
package com.willfp.ecobosses.util
import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.util.NumberUtils
import com.willfp.eco.util.savedDisplayName
import com.willfp.ecobosses.EcoBossesPlugin
@@ -32,7 +31,7 @@ data class LocalCommands(
}
for (s in toDispatch) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), s);
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), s)
}
}
}

View File

@@ -0,0 +1,209 @@
# The ID of the boss is the name of the .yml file,
# for example steel_golem.yml has the ID of steel_golem
# You can place bosses anywhere in this folder,
# including in subfolders if you want to organize your boss configs
# _example.yml is not loaded.
# A base mob and modifiers
# View an explanation for this system here: https://plugins.auxilor.io/all-plugins/the-entity-lookup-system
mob: iron_golem attack-damage:90 movement-speed:1.5 follow-range:16 health:1200
# If you're using model engine, you can specify the ID and animation here. You can also specify these in the mob with the lookup system.
model-engine-id: ""
model-engine-animation: ""
# Supported placeholders: %health%, %time% (formats as minutes:seconds, eg 1:56)
display-name: "&8Steel Golem &7| &c%health%♥ &7| &e%time%"
influence: 40 # The distance at which effects will be applied to players
custom-ai: # Custom mob AI using the entity goal system.
enabled: false # If custom AI should be enabled, this will override the vanilla mob behaviour.
target-goals: [ ] # How the boss decides who to attack, if the target mode isn't being used.
ai-goals: [ ] # How the boss should behave.
effects: # Effects are done from the player's perspective: to treat the player as the victim, use the self_as_victim option in args
- id: run_chain
args:
chain: blind
self_as_victim: true
chance: 20
triggers:
- static_20
conditions: [ ] # Conditions to apply effects to players; useful if you don't want to affect low-level players
lifespan: 120 # The lifespan of the boss before it despawns, in seconds. Set to a massive number to disable.
defence:
prevent-mounts: true # If the boss shouldn't be able to get into boats, minecarts, etc
explosion-immune: true # If the boss should be immune to explosions
fire-immune: true # If the boss should be immune to fire damage
drowning-immune: true # If the boss should be immune to drowning damage
suffocation-immune: true # If the boss should be immune to suffocation
melee-damage-multiplier: 0.8 # Incoming melee damage will be multiplied by this value. Set to 0 to render immune against melee
projectile-damage-multiplier: 0.2 # Same as melee multiplier, but for projectiles
teleportation: # Teleport every x ticks in order to avoid being caged in obsidian or similar
enabled: true # If the boss should teleport
interval: 100 # Ticks between teleportation attempts
range: 20 # The range that the boss should check for safe teleportation blocks.
rewards:
xp: # Experience will be randomly generated between these values
minimum: 30000
maximum: 60000
top-damager-commands:
# You can specify as many ranks as you want (adding 4, 5, etc)
# You can use %player% as a placeholder for the player name
1:
- chance: 100 # As a percentage
commands:
- eco give %player% 10000
2: [ ]
3: [ ]
nearby-player-commands:
# Commands to be executed for all players near the boss death location
radius: 10
# Uses the same syntax as top damager commands (chance and a list of commands, can use %player%)
commands: [ ]
# You can specify as many drops as you want, and group several drops together under one chance
drops:
- chance: 100
items:
- diamond_sword unbreaking:1 name:"Example Sword"
target:
# How the boss should choose which player to attack, choices are:
# highest_health, lowest_health, closest, random
mode: highest_health
# The distance to scan for players
range: 40
boss-bar:
# If the boss should have a boss bar
enabled: true
color: white # Options: blue, green, pink, purple, red, white, yellow
style: progress # Options: progress, notched_20, notched_12, notched_10, notched_6
radius: 120 # The distance from the boss where the boss bar is visible
spawn:
# A list of conditions required for a player to be able to spawn a boss, useful to set
# minimum skill levels, etc
conditions: [ ]
autospawn:
# Spawn the boss automatically every x ticks. Picks a random location, but will only
# ever spawn in a world if there are no other bosses of that type in the world.
interval: -1 # The interval in ticks, set to -1 to disable
locations: # Add as many locations as you want
- world: world
x: 100
y: 100
z: 100
totem:
enabled: false # A spawn totem is a set of 3 blocks on top of each other to spawn a boss (like a snow golem)
top: netherite_block
middle: iron_block
bottom: magma_block
not-in-worlds: [ ] # If spawn totems should be disallowed in certain worlds, specify them here
egg:
enabled: true # If the boss should have a spawn egg
item: evoker_spawn_egg unbreaking:1 hide_enchants
name: "&8Steel Golem&f Spawn Egg"
lore:
- ""
- "&8&oPlace on the ground to"
- "&8&osummon a &8Steel Golem"
craftable: true
recipe:
- iron_block
- netherite_block
- iron_block
- air
- ecoitems:boss_core ? nether_star
- air
- iron_block
- netherite_block
- iron_block
commands:
# For each category, you can add as many commands as you want, which will be executed by
# console. Supported placeholders are the same as for messages (see below)
spawn: [ ]
kill: [ ]
despawn: [ ]
injure: [ ]
messages:
# For each category, you can add as many messages as you want, each with their own radius.
# Radius is the distance from the boss where the player will be sent the message
# Set to -1 to broadcast globally to all players online
# Supported placeholders: %x%, %y%, %z% (coordinates)
spawn:
- message:
- ""
- "&fA &8&lSteel Golem&r&f has been spawned!"
- "&fCome fight it at &8%x%&f, &8%y%&f, &8%z%&f!"
- ""
radius: -1
# Supported placeholders: %damage_<x>_player%, %damage_<X>%
# You can include as many ranks as you want - if there is no player at a certain rank,
# it will be replaced with N/A (change in lang.yml)
kill:
- message:
- ""
- "&fThe &8&lSteel Golem&r&f has been killed!"
- "&fMost Damage:"
- "&f - &8%damage_1_player%&f (%damage_1% Damage)"
- "&f - &8%damage_2_player%&f (%damage_2% Damage)"
- "&f - &8%damage_3_player%&f (%damage_3% Damage)"
- ""
radius: -1
despawn:
- message:
- ""
- "&fYou ran out of time to kill the &8&lSteel Golem&r&f!"
- ""
radius: -1
injure: [ ]
# All sounds will be played together at the same time
# A list of sounds can be found here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html
# Volume functions as the distance at which the sound will be heard
# Pitch is any value between 0.5 and 2
# If you don't want the vanilla mob sounds, add 'silent' as an option to the mob
sounds:
spawn:
- sound: entity_iron_golem_death
pitch: 0.8
volume: 100
- sound: entity_iron_golem_hurt
pitch: 0.5
volume: 100
- sound: entity_ender_dragon_growl
pitch: 0.5
volume: 100
kill:
- sound: entity_ender_dragon_death
pitch: 1.8
volume: 100
- sound: entity_wither_death
pitch: 1.2
volume: 100
despawn:
- sound: entity_ender_dragon_ambient
pitch: 0.5
volume: 50
- sound: entity_enderman_death
pitch: 0.5
volume: 50
injure:
- sound: entity_iron_golem_damage
pitch: 0.7
volume: 10

View File

@@ -0,0 +1,210 @@
mob: illusioner attack-damage:50 health:600 hand:"iron_sword sharpness:5"
model-engine-id: ""
model-engine-animation: ""
display-name: "&9Illusioner &7| &c%health%♥ &7| &e%time%"
influence: 40
custom-ai:
enabled: true
target-goals:
- key: minecraft:hurt_by
priority: 0
args:
blacklist: [ ]
- key: minecraft:nearest_attackable
priority: 1
args:
target:
- player
checkVisibility: false
checkCanNavigate: true
reciprocalChance: 300
- key: minecraft:nearest_attackable
priority: 2
args:
target:
- iron_golem
- villager
checkVisibility: false
checkCanNavigate: true
reciprocalChance: 300
ai-goals:
- key: minecraft:float
priority: 0
- key: minecraft:illusioner_mirror_spell
priority: 1
- key: minecraft:melee_attack
priority: 2
args:
speed: 1.6
pauseWhenMobIdle: false
- key: minecraft:random_stroll
priority: 8
args:
speed: 0.6
interval: 80
canDespawn: false
- key: minecraft:look_at_player
priority: 9
args:
range: 6
chance: 1
effects:
- id: run_chain
args:
chain: blind
self_as_victim: true
chance: 20
triggers:
- static_20
conditions: [ ]
lifespan: 120
defence:
prevent-mounts: true
explosion-immune: true
fire-immune: true
drowning-immune: true
suffocation-immune: true
melee-damage-multiplier: 1
projectile-damage-multiplier: 0.8
teleportation:
enabled: true
interval: 200
range: 20
rewards:
xp:
minimum: 20000
maximum: 40000
top-damager-commands:
1:
- chance: 100 # As a percentage
commands:
- eco give %player% 10000
2: [ ]
3: [ ]
nearby-player-commands:
radius: 10
commands: [ ]
drops: []
target:
mode: closest
range: 40
boss-bar:
enabled: true
color: blue
style: notched_20
radius: 120
spawn:
conditions: [ ]
autospawn:
interval: -1
locations: []
totem:
enabled: false
top: carved_pumpkin
middle: beacon
bottom: diamond_block
not-in-worlds: [ ]
egg:
enabled: true
item: dolphin_spawn_egg unbreaking:1 hide_enchants
name: "&9Illusioner&f Spawn Egg"
lore:
- ""
- "&8&oPlace on the ground to"
- "&8&osummon an &9Illusioner"
craftable: true
recipe:
- ""
- fermented_spider_eye 64
- ""
- fermented_spider_eye 64
- ecoitems:boss_core ? nether_star
- fermented_spider_eye 64
- ""
- fermented_spider_eye 64
- ""
commands:
spawn: [ ]
kill: [ ]
despawn: [ ]
injure: [ ]
messages:
spawn:
- message:
- ""
- "&fAn &9&lIllusioner&r&f has been spawned!"
- "&fCome fight it at &9%x%&f, &9%y%&f, &9%z%&f!"
- ""
radius: -1
kill:
- message:
- ""
- "&fThe &9&lIllusioner&r&f has been killed!"
- "&fMost Damage:"
- "&f - &9%damage_1_player%&f (%damage_1% Damage)"
- "&f - &9%damage_2_player%&f (%damage_2% Damage)"
- "&f - &9%damage_3_player%&f (%damage_3% Damage)"
- ""
radius: -1
despawn:
- message:
- ""
- "&fYou ran out of time to kill the &9&lIllusioner&r&f!"
- ""
radius: -1
injure: [ ]
sounds:
spawn:
- sound: entity_illusioner_mirror_move
pitch: 0.5
volume: 100
- sound: entity_wither_spawn
pitch: 2
volume: 100
kill:
- sound: entity_evoker_prepare_wololo
pitch: 0.8
volume: 100
- sound: entity_illusioner_prepare_blindness
pitch: 1
volume: 100
- sound: entity_wither_death
pitch: 2
volume: 100
despawn:
- sound: entity_ender_dragon_ambient
pitch: 0.6
volume: 50
- sound: entity_enderman_death
pitch: 0.8
volume: 50
injure:
- sound: entity_illusioner_cast_spell
pitch: 2
volume: 10

View File

@@ -0,0 +1,16 @@
# Read more about chains: https://plugins.auxilor.io/effects/configuring-an-effect#effect-chains
chains:
- id: blind
effects:
- id: potion_effect
args:
effect: blindness
level: 3
duration: 30
apply_to_player: true
- id: play_sound
args:
sound: entity_dragon_fireball_explode
pitch: 1.5
volume: 4

View File

@@ -30,12 +30,18 @@ cannot-afford-type:
sound: "BLOCK_NOTE_BLOCK_PLING"
pitch: 0.5
point-names: # If you have point names that look ugly (eg g_souls) then you can map them to nice names to be shown to players.
cannot-afford-price:
in-actionbar: true
sound:
enabled: true
sound: "BLOCK_NOTE_BLOCK_PLING"
pitch: 0.5
point-names: # If you have point names that look ugly (e.g. souls) then you can map them to nice names to be shown to players.
example_point: "Nicely Formatted Point"
use-faster-move-trigger: true # Disable if you want move trigger to detect sub-1-block movements
raytrace-distance: 80 # The distance that alt_click should check for a location
block-item-drop-place-check: true # If the block_item_drop trigger should only fire on naturally placed blocks (prevents dupes)
potions:
icon:

View File

@@ -1,205 +0,0 @@
chains:
- id: blind
effects:
- id: teleport
- id: potion_effect
args:
effect: blindness
level: 3
duration: 30
apply_to_player: true
- id: send_message
args:
message: "&cYou have been blinded!"
action_bar: true
- id: play_sound
args:
sound: entity_dragon_fireball_explode
pitch: 1.5
volume: 4
bosses:
- id: steel_golem
# A base mob and modifiers
# View an explanation for this system here: https://plugins.auxilor.io/all-plugins/the-entity-lookup-system
mob: iron_golem attack-damage:90 movement-speed:1.5 follow-range:16 health:1200
# Supported placeholders: %health%, %time% (formats as minutes:seconds, eg 1:56)
displayName: "&8Steel Golem &7| &c%health%♥ &7| &e%time%"
influence: 40 # The distance at which effects will be applied to players
customai: # Custom mob AI using the entity goal system.
enabled: false # If custom AI should be enabled, this will override the vanilla mob behaviour.
target-goals: [ ] # How the boss decides who to attack, if the target mode isn't being used.
ai-goals: [ ] # How the boss should behave.
effects: # Effects are done from the player's perspective: to treat the player as the victim, use the self_as_victim option in args
- id: run_chain
args:
chain: blind
self_as_victim: true
chance: 20
triggers:
- static_20
conditions: [ ] # Conditions to apply effects to players; useful if you don't want to affect low-level players
lifespan: 120 # The lifespan of the boss before it despawns, in seconds. Set to a massive number to disable.
defence:
preventMounts: true # If the boss shouldn't be able to get into boats, minecarts, etc
explosionImmune: true # If the boss should be immune to explosions
fireImmune: true # If the boss should be immune to fire damage
drowningImmune: true # If the boss should be immune to drowning damage
suffocationImmune: true # If the boss should be immune to suffocation
meleeDamageMultiplier: 0.8 # Incoming melee damage will be multiplied by this value. Set to 0 to render immune against melee
projectileDamageMultiplier: 0.2 # Same as melee multiplier, but for projectiles
teleportation: # Teleport every x ticks in order to avoid being caged in obsidian or similar
enabled: true # If the boss should teleport
interval: 100 # Ticks between teleportation attempts
range: 20 # The range that the boss should check for safe teleportation blocks.
rewards:
xp: # Experience will be randomly generated between these values
minimum: 30000
maximum: 60000
topDamagerCommands:
# You can specify as many ranks as you want (adding 4, 5, etc)
# You can use %player% as a placeholder for the player name
1:
- chance: 100 # As a percentage
commands:
- eco give %player% 10000
2: [ ]
3: [ ]
nearbyPlayerCommands:
# Commands to be executed for all players near the boss death location
radius: 10
# Uses the same syntax as top damager commands (chance and a list of commands, can use %player%)
commands: [ ]
# You can specify as many drops as you want, and group several drops together under one chance
drops:
- chance: 100
items:
- diamond_sword unbreaking:1 name:"Example Sword"
target:
# How the boss should choose which player to attack, choices are:
# highest_health, lowest_health, closest, random
mode: highest_health
# The distance to scan for players
range: 40
bossBar:
# If the boss should have a boss bar
enabled: true
color: white # Options: blue, green, pink, purple, red, white, yellow
style: progress # Options: progress, notched_20, notched_12, notched_10, notched_6
radius: 120 # The distance from the boss where the boss bar is visible
spawn:
# A list of conditions required for a player to be able to spawn a boss, useful to set
# minimum skill levels, etc
conditions: [ ]
autospawn:
# Spawn the boss automatically every x ticks. Picks a random location, but will only
# ever spawn in a world if there are no other bosses of that type in the world.
interval: -1 # The interval in ticks, set to -1 to disable
locations: # Add as many locations as you want
- world: world
x: 100
y: 100
z: 100
totem:
enabled: false # A spawn totem is a set of 3 blocks on top of each other to spawn a boss (like a snow golem)
top: netherite_block
middle: iron_block
bottom: magma_block
notInWorlds: [ ] # If spawn totems should be disallowed in certain worlds, specify them here
egg:
enabled: true # If the boss should have a spawn egg
item: evoker_spawn_egg unbreaking:1 hide_enchants
name: "&8Steel Golem&f Spawn Egg"
lore:
- ""
- "&8&oPlace on the ground to"
- "&8&osummon a &8Steel Golem"
craftable: true
recipe:
- iron_block
- netherite_block
- iron_block
- air
- ecoitems:boss_core ? nether_star
- air
- iron_block
- netherite_block
- iron_block
commands:
# For each category, you can add as many commands as you want, which will be executed by
# console. Supported placeholders are the same as for messages (see below)
spawn: [ ]
kill: [ ]
despawn: [ ]
injure: [ ]
messages:
# For each category, you can add as many messages as you want, each with their own radius.
# Radius is the distance from the boss where the player will be sent the message
# Set to -1 to broadcast globally to all players online
# Supported placeholders: %x%, %y%, %z% (coordinates)
spawn:
- message:
- ""
- "&fA &8&lSteel Golem&r&f has been spawned!"
- "&fCome fight it at &8%x%&f, &8%y%&f, &8%z%&f!"
- ""
radius: -1
# Supported placeholders: %damage_<x>_player%, %damage_<X>%
# You can include as many ranks as you want - if there is no player at a certain rank,
# it will be replaced with N/A (change in lang.yml)
kill:
- message:
- ""
- "&fThe &8&lSteel Golem&r&f has been killed!"
- "&fMost Damage:"
- "&f - &8%damage_1_player%&f (%damage_1% Damage)"
- "&f - &8%damage_2_player%&f (%damage_2% Damage)"
- "&f - &8%damage_3_player%&f (%damage_3% Damage)"
- ""
radius: -1
despawn:
- message:
- ""
- "&fYou ran out of time to kill the &8&lSteel Golem&r&f!"
- ""
radius: -1
injure: [ ]
# All sounds will be played together at the same time
# A list of sounds can be found here: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Sound.html
# Volume functions as the distance at which the sound will be heard
# Pitch is any value between 0.5 and 2
# If you don't want the vanilla mob sounds, add 'silent' as an option to the mob
sounds:
spawn:
- sound: entity_iron_golem_death
pitch: 0.8
volume: 100
- sound: entity_iron_golem_hurt
pitch: 0.5
volume: 100
- sound: entity_ender_dragon_growl
pitch: 0.5
volume: 100
kill:
- sound: entity_ender_dragon_death
pitch: 1.8
volume: 100
- sound: entity_wither_death
pitch: 1.2
volume: 100
despawn:
- sound: entity_ender_dragon_ambient
pitch: 0.5
volume: 50
- sound: entity_enderman_death
pitch: 0.5
volume: 50
injure:
- sound: entity_iron_golem_damage
pitch: 0.7
volume: 10

View File

@@ -1,9 +1,22 @@
messages:
prefix: "&9&lEcoBosses &f» "
no-permission: "&cYou don't have permission to do this!"
invalid-command: "&cUnknown subcommand!"
not-player: "&cThis command must be run by a player"
invalid-command: "&cUnknown subcommand!"
reloaded: "Reloaded!"
cannot-afford: "&cYou can't afford to do this! &fCost: &a$$%cost%"
cannot-afford-type: "&cYou can't afford to do this! &fCost: &a%cost% %type%"
cannot-afford-price: "&cYou can't afford to do this! &fPrice: %price%"
on-cooldown: "&cThis effect is on cooldown! &fTime left: &a%seconds% seconds"
cannot-transmit: "&cYou can't transmit here!"
must-specify-lrcdb-id: "&cYou must specify the ID of the config to download! Not sure what this means? Go to &alrcdb.auxilor.io"
lrcdb-import-error: "&cError importing config: &f%message%"
lrcdb-import-success: "&fImported &a%name%&f! Reload the plugin to install it"
must-specify-config-name: "&cYou must specify the config name!"
invalid-config-name: "&cInvalid config name!"
lrcdb-export-error: "&cError exporting config: &f%message%"
lrcdb-export-success: "&fExported &a%name%&f! View it on &alrcdb.auxilor.io&f, or share your config ID: &f%id%"
sent-drop: "Check console for the drop!"
specify-boss: "&cYou must specify a valid boss!"
invalid-location: "&cInvalid location!"
@@ -15,9 +28,5 @@ messages:
invalid-stone: "&cInvalid boss!"
give-success: "Gave &a%boss%&r spawn egg to &a%recipient%"
requirements-not-met: "&cYou can't spawn this boss!"
on-cooldown: "&cThis effect is on cooldown! &fTime left: &a%seconds% seconds"
cannot-afford: "&cYou can't afford to do this! &fCost: &a$$%cost%"
cannot-afford-type: "&cYou can't afford to do this! &fCost: &a%cost% %type%"
cannot-transmit: "&cYou can't transmit here!"
na: "N/A"

View File

@@ -0,0 +1,19 @@
# Options for lrcdb (https://lrcdb.auxilor.io), a website to share configs
# with other server owners, so you can get more configs without making them
# yourself!
author: "Unknown Author" # The name attached to configs you export
# Options about automatically sharing configs you create
share-configs:
# If you want all your configs to automatically be publicly available,
# set this to true. This really helps out other users!
publicly: false
# If you don't want your configs to be usable to gather information about
# plugin usage or to improve the plugins in the future, disable this.
# Nothing identifying is shared.
enabled: true
# If you disable share-configs, you can still share select configs publicly
# with /ecobosses export <config>.

View File

@@ -20,6 +20,8 @@ softdepend:
- EcoItems
- EcoSkills
- Boosters
- ModelEngine
- EcoJobs
commands:
ecobosses:
@@ -40,6 +42,8 @@ permissions:
ecobosses.command.reload: true
ecobosses.command.spawn: true
ecobosses.command.give: true
ecobosses.command.import: true
ecobosses.command.export: true
ecobosses.command.ecobosses:
description: Allows the use of /ecobosses
@@ -59,4 +63,12 @@ permissions:
ecobosses.command.reload:
description: Allows the use of /ecobosses reload
default: op
ecobosses.command.import:
description: Allows the use of /ecobosses import
default: op
ecobosses.command.export:
description: Allows the use of /ecobosses export
default: op

View File

@@ -1,4 +1,4 @@
#libreforge-updater
#Sun Aug 28 15:40:32 BST 2022
version=8.73.0
#Mon Dec 26 14:01:48 CET 2022
version=8.112.3
plugin-name=EcoBosses

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

269
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"