mirror of
https://github.com/Auxilor/EcoMobs.git
synced 2025-12-19 23:19:17 +00:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2d6355003 | ||
|
|
b44016d4fe | ||
|
|
74f1953074 | ||
|
|
041e8e070e | ||
|
|
d69b205de5 | ||
|
|
ad827f2b65 | ||
|
|
e8b8dcd2c4 | ||
|
|
e54660cf5e | ||
|
|
7a21d1897d | ||
|
|
64726f665f | ||
|
|
e4fdaeec1d | ||
|
|
3c5fbd6151 | ||
|
|
4329431994 | ||
|
|
c55692e89f | ||
|
|
03466f7892 | ||
|
|
1a6ebd4455 | ||
|
|
486f071dea | ||
|
|
fb4eac5e5e | ||
|
|
49d1d3f054 | ||
|
|
6dc7426146 | ||
|
|
00c5ead347 | ||
|
|
9bd501dfbe | ||
|
|
67d55bbdc2 | ||
|
|
46aa086366 | ||
|
|
9f00334ea4 | ||
|
|
e6db159bfb | ||
|
|
3df7b75737 | ||
|
|
c243a425b3 | ||
|
|
e57fe61d22 | ||
|
|
9830aed484 | ||
|
|
999b89bcb0 | ||
|
|
e7f326efbb | ||
|
|
0cb5b0b7b7 | ||
|
|
8e2d901e9b | ||
|
|
724eede36e | ||
|
|
01a2cc7118 | ||
|
|
20aace3727 | ||
|
|
ec9d4c0dd6 | ||
|
|
b3a0c1fa67 | ||
|
|
88294a17cd | ||
|
|
1ac6a350ec | ||
|
|
a9333cb8b5 | ||
|
|
05cf399e77 | ||
|
|
de2b8f7526 | ||
|
|
23085e74e2 | ||
|
|
80f02a07a4 | ||
|
|
a63625593d | ||
|
|
1dfd7bac1f | ||
|
|
34b983b185 | ||
|
|
33b2fd9e13 | ||
|
|
85cfb542dc | ||
|
|
197f9e91aa | ||
|
|
9d4a91805a | ||
|
|
87b91c46d1 | ||
|
|
4a7e6e9ff1 | ||
|
|
b59e54be01 | ||
|
|
d26f0294cc | ||
|
|
150433d46b | ||
|
|
7de4d75c93 |
@@ -4,7 +4,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,12 +63,12 @@ allprojects {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly 'com.willfp:eco:6.35.1'
|
compileOnly 'com.willfp:eco:6.35.1'
|
||||||
implementation 'com.willfp:libreforge:3.70.0'
|
implementation 'com.willfp:libreforge:3.92.0'
|
||||||
implementation 'org.joml:joml:1.10.4'
|
implementation 'org.joml:joml:1.10.4'
|
||||||
|
|
||||||
compileOnly 'org.jetbrains:annotations:23.0.0'
|
compileOnly 'org.jetbrains:annotations:23.0.0'
|
||||||
|
|
||||||
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.21'
|
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.7.10'
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
@@ -85,6 +85,7 @@ allprojects {
|
|||||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "17"
|
jvmTarget = "17"
|
||||||
|
freeCompilerArgs += ["-Xjvm-default=all"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.willfp.ecobosses.bosses.Bosses
|
|||||||
import com.willfp.ecobosses.bosses.EggDisplay
|
import com.willfp.ecobosses.bosses.EggDisplay
|
||||||
import com.willfp.ecobosses.bosses.bossHolders
|
import com.willfp.ecobosses.bosses.bossHolders
|
||||||
import com.willfp.ecobosses.commands.CommandEcobosses
|
import com.willfp.ecobosses.commands.CommandEcobosses
|
||||||
import com.willfp.ecobosses.config.EcoBossesYml
|
|
||||||
import com.willfp.ecobosses.defence.DamageMultiplierHandler
|
import com.willfp.ecobosses.defence.DamageMultiplierHandler
|
||||||
import com.willfp.ecobosses.defence.ImmunitiesHandler
|
import com.willfp.ecobosses.defence.ImmunitiesHandler
|
||||||
import com.willfp.ecobosses.defence.MountHandler
|
import com.willfp.ecobosses.defence.MountHandler
|
||||||
@@ -26,14 +25,15 @@ import com.willfp.libreforge.LibReforgePlugin
|
|||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
|
|
||||||
class EcoBossesPlugin : LibReforgePlugin() {
|
class EcoBossesPlugin : LibReforgePlugin() {
|
||||||
val ecoBossesYml: EcoBossesYml
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
instance = this
|
instance = this
|
||||||
ecoBossesYml = EcoBossesYml(this)
|
|
||||||
registerHolderProvider { it.bossHolders }
|
registerHolderProvider { it.bossHolders }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun handleEnableAdditional() {
|
||||||
|
this.copyConfigs("bosses")
|
||||||
|
}
|
||||||
|
|
||||||
override fun handleReloadAdditional() {
|
override fun handleReloadAdditional() {
|
||||||
Bosses.getAllAlive().forEach { it.remove() }
|
Bosses.getAllAlive().forEach { it.remove() }
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ val Player.bossHolders: Iterable<Holder>
|
|||||||
|
|
||||||
for (boss in Bosses.values()) {
|
for (boss in Bosses.values()) {
|
||||||
for (livingBoss in boss.getAllAlive()) {
|
for (livingBoss in boss.getAllAlive()) {
|
||||||
val entity = livingBoss.entity ?: continue
|
val entity = livingBoss.entity
|
||||||
|
|
||||||
if (entity.world != this.world) {
|
if (entity.world != this.world) {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package com.willfp.ecobosses.bosses
|
|||||||
import com.google.common.collect.BiMap
|
import com.google.common.collect.BiMap
|
||||||
import com.google.common.collect.HashBiMap
|
import com.google.common.collect.HashBiMap
|
||||||
import com.google.common.collect.ImmutableList
|
import com.google.common.collect.ImmutableList
|
||||||
|
import com.willfp.eco.core.config.ConfigType
|
||||||
|
import com.willfp.eco.core.config.TransientConfig
|
||||||
import com.willfp.eco.core.config.updating.ConfigUpdater
|
import com.willfp.eco.core.config.updating.ConfigUpdater
|
||||||
import com.willfp.ecobosses.EcoBossesPlugin
|
import com.willfp.ecobosses.EcoBossesPlugin
|
||||||
import com.willfp.libreforge.chains.EffectChains
|
|
||||||
import org.bukkit.entity.LivingEntity
|
import org.bukkit.entity.LivingEntity
|
||||||
import java.util.UUID
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
object Bosses {
|
object Bosses {
|
||||||
/**
|
/**
|
||||||
@@ -44,16 +46,18 @@ object Bosses {
|
|||||||
@ConfigUpdater
|
@ConfigUpdater
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun update(plugin: EcoBossesPlugin) {
|
fun update(plugin: EcoBossesPlugin) {
|
||||||
plugin.ecoBossesYml.getSubsections("chains").mapNotNull {
|
|
||||||
EffectChains.compile(it, "Effect Chains")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (boss in values()) {
|
for (boss in values()) {
|
||||||
removeBoss(boss)
|
removeBoss(boss)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (bossConfig in plugin.ecoBossesYml.getSubsections("bosses")) {
|
for ((id, config) in plugin.fetchConfigs("bosses")) {
|
||||||
addNewBoss(EcoBoss(bossConfig, plugin))
|
addNewBoss(EcoBoss(id, config, plugin))
|
||||||
|
}
|
||||||
|
|
||||||
|
val ecoBossesYml = TransientConfig(File(plugin.dataFolder, "ecobosses.yml"), ConfigType.YAML)
|
||||||
|
|
||||||
|
for (bossConfig in ecoBossesYml.getSubsections("bosses")) {
|
||||||
|
addNewBoss(EcoBoss(bossConfig.getString("id"), bossConfig, plugin))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ import com.willfp.eco.core.config.interfaces.Config
|
|||||||
import com.willfp.eco.core.entities.CustomEntity
|
import com.willfp.eco.core.entities.CustomEntity
|
||||||
import com.willfp.eco.core.entities.Entities
|
import com.willfp.eco.core.entities.Entities
|
||||||
import com.willfp.eco.core.entities.TestableEntity
|
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.CustomItem
|
||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.eco.core.items.builder.ItemStackBuilder
|
import com.willfp.eco.core.items.builder.ItemStackBuilder
|
||||||
@@ -16,8 +20,22 @@ import com.willfp.eco.util.NamespacedKeyUtils
|
|||||||
import com.willfp.eco.util.toComponent
|
import com.willfp.eco.util.toComponent
|
||||||
import com.willfp.ecobosses.events.BossKillEvent
|
import com.willfp.ecobosses.events.BossKillEvent
|
||||||
import com.willfp.ecobosses.lifecycle.BossLifecycle
|
import com.willfp.ecobosses.lifecycle.BossLifecycle
|
||||||
import com.willfp.ecobosses.tick.*
|
import com.willfp.ecobosses.tick.BossBarTicker
|
||||||
import com.willfp.ecobosses.util.*
|
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.Holder
|
||||||
import com.willfp.libreforge.conditions.Conditions
|
import com.willfp.libreforge.conditions.Conditions
|
||||||
import com.willfp.libreforge.effects.Effects
|
import com.willfp.libreforge.effects.Effects
|
||||||
@@ -33,11 +51,10 @@ import org.bukkit.persistence.PersistentDataType
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class EcoBoss(
|
class EcoBoss(
|
||||||
|
override val id: String,
|
||||||
val config: Config,
|
val config: Config,
|
||||||
private val plugin: EcoPlugin
|
private val plugin: EcoPlugin
|
||||||
) : Holder {
|
) : Holder {
|
||||||
override val id: String = config.getString("id")
|
|
||||||
|
|
||||||
val displayName: String = config.getString("displayName")
|
val displayName: String = config.getString("displayName")
|
||||||
|
|
||||||
val lifespan = config.getInt("lifespan")
|
val lifespan = config.getInt("lifespan")
|
||||||
@@ -332,7 +349,7 @@ class EcoBoss(
|
|||||||
|
|
||||||
val boss = LivingEcoBoss(
|
val boss = LivingEcoBoss(
|
||||||
plugin,
|
plugin,
|
||||||
mob.uniqueId,
|
mob,
|
||||||
this,
|
this,
|
||||||
createTickers()
|
createTickers()
|
||||||
)
|
)
|
||||||
@@ -345,7 +362,8 @@ class EcoBoss(
|
|||||||
LifespanTicker(),
|
LifespanTicker(),
|
||||||
DisplayNameTicker(),
|
DisplayNameTicker(),
|
||||||
TargetTicker(),
|
TargetTicker(),
|
||||||
TeleportHandler()
|
TeleportHandler(),
|
||||||
|
ChunkTicker()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isBossBarEnabled) {
|
if (isBossBarEnabled) {
|
||||||
@@ -371,7 +389,7 @@ class EcoBoss(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun processRewards(event: BossKillEvent) {
|
fun processRewards(event: BossKillEvent) {
|
||||||
val entity = event.boss.entity ?: return
|
val entity = event.boss.entity
|
||||||
val location = entity.location
|
val location = entity.location
|
||||||
val player = event.killer
|
val player = event.killer
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,12 @@ package com.willfp.ecobosses.bosses
|
|||||||
|
|
||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.ecobosses.tick.BossTicker
|
import com.willfp.ecobosses.tick.BossTicker
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Chunk
|
||||||
import org.bukkit.entity.Mob
|
import org.bukkit.entity.Mob
|
||||||
import java.util.UUID
|
|
||||||
|
|
||||||
class LivingEcoBoss(
|
class LivingEcoBoss(
|
||||||
plugin: EcoPlugin,
|
plugin: EcoPlugin,
|
||||||
private val uuid: UUID,
|
val entity: Mob,
|
||||||
val boss: EcoBoss,
|
val boss: EcoBoss,
|
||||||
private val tickers: Set<BossTicker>
|
private val tickers: Set<BossTicker>
|
||||||
) {
|
) {
|
||||||
@@ -18,15 +17,17 @@ class LivingEcoBoss(
|
|||||||
}
|
}
|
||||||
}.apply { runTaskTimer(1, 1) }
|
}.apply { runTaskTimer(1, 1) }
|
||||||
|
|
||||||
val entity: Mob?
|
val chunk: Chunk
|
||||||
get() = Bukkit.getEntity(uuid) as? Mob
|
get() = entity.location.chunk
|
||||||
|
|
||||||
|
val forceLoadedChunks = mutableListOf<Chunk>()
|
||||||
|
|
||||||
val deathTime = System.currentTimeMillis() + (boss.lifespan * 1000)
|
val deathTime = System.currentTimeMillis() + (boss.lifespan * 1000)
|
||||||
|
|
||||||
private var currentTick = 1 // Start at 1 as 0 is divisible by everything
|
private var currentTick = 1 // Start at 1 as 0 is divisible by everything
|
||||||
|
|
||||||
private fun tick(): Boolean {
|
private fun tick(): Boolean {
|
||||||
if (entity == null || entity?.isDead == true) {
|
if (entity.isDead) {
|
||||||
remove()
|
remove()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -40,13 +41,13 @@ class LivingEcoBoss(
|
|||||||
|
|
||||||
fun remove() {
|
fun remove() {
|
||||||
ticker.cancel()
|
ticker.cancel()
|
||||||
entity?.remove()
|
entity.remove()
|
||||||
tickers.forEach { it.onDeath(this, currentTick) }
|
tickers.forEach { it.onDeath(this, currentTick) }
|
||||||
|
|
||||||
boss.markDead(uuid)
|
boss.markDead(entity.uniqueId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "LivingEcoBoss{boss=${boss}, uuid=${uuid}}"
|
return "LivingEcoBoss{boss=${boss}, uuid=${entity.uniqueId}}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class TargetMode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getTarget(boss: LivingEcoBoss): LivingEntity? {
|
fun getTarget(boss: LivingEcoBoss): LivingEntity? {
|
||||||
val entity = boss.entity ?: return null
|
val entity = boss.entity
|
||||||
|
|
||||||
return function(
|
return function(
|
||||||
entity.getNearbyEntities(
|
entity.getNearbyEntities(
|
||||||
|
|||||||
@@ -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
|
|
||||||
)
|
|
||||||
@@ -34,8 +34,8 @@ class ConsoleLoggers(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val loc = event.boss.entity?.location
|
val loc = event.boss.entity.location
|
||||||
val location = "${loc?.world?.name}: ${loc?.x}, ${loc?.y}, ${loc?.z}"
|
val location = "${loc.world?.name}: ${loc.x}, ${loc.y}, ${loc.z}"
|
||||||
|
|
||||||
plugin.logger.info("&a${event.boss.boss.id}&r was killed by &a${event.killer?.name}&r at &a$location")
|
plugin.logger.info("&a${event.boss.boss.id}&r was killed by &a${event.killer?.name}&r at &a$location")
|
||||||
}
|
}
|
||||||
@@ -48,8 +48,8 @@ class ConsoleLoggers(
|
|||||||
if (!plugin.configYml.getBool("log-spawn-kill")) {
|
if (!plugin.configYml.getBool("log-spawn-kill")) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val loc = event.boss.entity?.location
|
val loc = event.boss.entity.location
|
||||||
val location = "${loc?.world?.name}: ${loc?.x}, ${loc?.y}, ${loc?.z}"
|
val location = "${loc.world?.name}: ${loc.x}, ${loc.y}, ${loc.z}"
|
||||||
|
|
||||||
plugin.logger.info("&a${event.boss.boss.id}&r despawned at &a$location")
|
plugin.logger.info("&a${event.boss.boss.id}&r despawned at &a$location")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.willfp.ecobosses.bosses.Bosses
|
|||||||
import com.willfp.ecobosses.events.BossKillEvent
|
import com.willfp.ecobosses.events.BossKillEvent
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.event.EventHandler
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.EventPriority
|
||||||
import org.bukkit.event.Listener
|
import org.bukkit.event.Listener
|
||||||
import org.bukkit.event.entity.EntityDeathEvent
|
import org.bukkit.event.entity.EntityDeathEvent
|
||||||
|
|
||||||
@@ -25,7 +26,8 @@ class DeathListeners : Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(
|
@EventHandler(
|
||||||
ignoreCancelled = true
|
ignoreCancelled = true,
|
||||||
|
priority = EventPriority.HIGHEST
|
||||||
)
|
)
|
||||||
fun handle(event: EntityDeathEvent) {
|
fun handle(event: EntityDeathEvent) {
|
||||||
val boss = Bosses[event.entity] ?: return
|
val boss = Bosses[event.entity] ?: return
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class LifecycleHandlers : Listener {
|
|||||||
priority = EventPriority.MONITOR
|
priority = EventPriority.MONITOR
|
||||||
)
|
)
|
||||||
fun handle(event: BossKillEvent) {
|
fun handle(event: BossKillEvent) {
|
||||||
val entity = event.boss.entity ?: return
|
val entity = event.boss.entity
|
||||||
|
|
||||||
event.boss.boss.handleLifecycle(BossLifecycle.KILL, entity.location, entity)
|
event.boss.boss.handleLifecycle(BossLifecycle.KILL, entity.location, entity)
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ class LifecycleHandlers : Listener {
|
|||||||
priority = EventPriority.MONITOR
|
priority = EventPriority.MONITOR
|
||||||
)
|
)
|
||||||
fun handle(event: BossDespawnEvent) {
|
fun handle(event: BossDespawnEvent) {
|
||||||
val entity = event.boss.entity ?: return
|
val entity = event.boss.entity
|
||||||
|
|
||||||
event.boss.boss.handleLifecycle(BossLifecycle.DESPAWN, entity.location, entity)
|
event.boss.boss.handleLifecycle(BossLifecycle.DESPAWN, entity.location, entity)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class BossBarTicker(
|
|||||||
private val bar: BossBar
|
private val bar: BossBar
|
||||||
) : BossTicker {
|
) : BossTicker {
|
||||||
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
||||||
val entity = boss.entity ?: return
|
val entity = boss.entity
|
||||||
|
|
||||||
bar.name(entity.customName!!.toComponent())
|
bar.name(entity.customName!!.toComponent())
|
||||||
bar.progress((entity.health / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value).toFloat())
|
bar.progress((entity.health / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value).toFloat())
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.willfp.ecobosses.tick
|
||||||
|
|
||||||
|
import com.willfp.ecobosses.bosses.LivingEcoBoss
|
||||||
|
|
||||||
|
class ChunkTicker : BossTicker {
|
||||||
|
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
||||||
|
val currentChunk = boss.chunk
|
||||||
|
|
||||||
|
if (tick % 10 != 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentChunk.isLoaded && currentChunk.isForceLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentChunk.load()
|
||||||
|
currentChunk.isForceLoaded = true
|
||||||
|
boss.forceLoadedChunks.add(currentChunk)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDeath(boss: LivingEcoBoss, tick: Int) {
|
||||||
|
boss.forceLoadedChunks.forEach { it.isForceLoaded = false }
|
||||||
|
boss.forceLoadedChunks.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ import kotlin.math.ceil
|
|||||||
|
|
||||||
class DisplayNameTicker : BossTicker {
|
class DisplayNameTicker : BossTicker {
|
||||||
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
||||||
val entity = boss.entity ?: return
|
val entity = boss.entity
|
||||||
|
|
||||||
val timeLeft = ceil(
|
val timeLeft = ceil(
|
||||||
(boss.deathTime - System.currentTimeMillis()) / 1000.0
|
(boss.deathTime - System.currentTimeMillis()) / 1000.0
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class LifespanTicker : BossTicker {
|
|||||||
boss.remove()
|
boss.remove()
|
||||||
boss.boss.handleLifecycle(
|
boss.boss.handleLifecycle(
|
||||||
BossLifecycle.DESPAWN,
|
BossLifecycle.DESPAWN,
|
||||||
boss.entity?.location ?: return,
|
boss.entity.location,
|
||||||
boss.entity
|
boss.entity
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import com.willfp.ecobosses.bosses.LivingEcoBoss
|
|||||||
|
|
||||||
class TargetTicker : BossTicker {
|
class TargetTicker : BossTicker {
|
||||||
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
||||||
val entity = boss.entity ?: return
|
val entity = boss.entity
|
||||||
|
|
||||||
if (tick % 10 != 0) {
|
if (tick % 10 != 0) {
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.bukkit.block.BlockFace
|
|||||||
|
|
||||||
class TeleportHandler : BossTicker {
|
class TeleportHandler : BossTicker {
|
||||||
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
override fun tick(boss: LivingEcoBoss, tick: Int) {
|
||||||
val entity = boss.entity ?: return
|
val entity = boss.entity
|
||||||
if (!boss.boss.canTeleport) {
|
if (!boss.boss.canTeleport) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
189
eco-core/core-plugin/src/main/resources/bosses/_example.yml
Normal file
189
eco-core/core-plugin/src/main/resources/bosses/_example.yml
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
# 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
|
||||||
|
# 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
|
||||||
@@ -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
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#libreforge-updater
|
#libreforge-updater
|
||||||
#Fri Jun 24 13:57:52 BST 2022
|
#Thu Sep 01 13:05:26 BST 2022
|
||||||
version=8.55.0
|
version=8.77.0
|
||||||
plugin-name=EcoBosses
|
plugin-name=EcoBosses
|
||||||
|
|||||||
Reference in New Issue
Block a user