9
0
mirror of https://github.com/Auxilor/EcoMobs.git synced 2025-12-20 15:39:31 +00:00

Compare commits

..

76 Commits

Author SHA1 Message Date
Auxilor
ab6d297222 Updated eco/kotlin/libreforge 2022-04-20 11:46:01 +01:00
Auxilor
9626588c66 Updated libreforge 2022-04-16 15:45:37 +01:00
Auxilor
c4eda19d78 Updated to 8.20.4 2022-04-12 11:35:01 +01:00
Auxilor
691326577a Updated to 8.20.4 2022-04-11 14:51:47 +01:00
Auxilor
e2086387e7 Fixed custom AI not working 2022-04-11 14:51:36 +01:00
Auxilor
13a72f849d Updated to 8.20.2 2022-04-09 14:42:29 +01:00
Auxilor
6346975e77 Updated to 8.20.2 2022-04-08 18:03:48 +01:00
Auxilor
0d846d9dff Added autospawn.one-boss-per-world option 2022-04-08 18:03:39 +01:00
Auxilor
31610383c4 Updated libreforge 2022-04-06 14:18:41 +01:00
Auxilor
d7c16ad3cc Updated libreforge 2022-04-04 10:23:34 +01:00
Auxilor
afe9095276 Updated libreforge 2022-04-02 14:04:56 +01:00
Auxilor
31a782581f Updated libreforge 2022-03-31 20:20:00 +01:00
Auxilor
8aad221450 Updated libreforge 2022-03-30 20:38:08 +01:00
Auxilor
b0bff24263 Updated libreforge 2022-03-28 19:05:19 +01:00
Auxilor
04b00fa01b Merge remote-tracking branch 'origin/master'
# Conflicts:
#	build.gradle
#	gradle.properties
2022-03-28 19:05:11 +01:00
Auxilor
276ba4616a Updated libreforge 2022-03-25 09:31:29 +00:00
Auxilor
d8e5fb9cd0 Updated to 8.14.0 2022-03-21 12:40:12 +00:00
Auxilor
9f05a6504a Added support for custom entity AI 2022-03-21 12:39:09 +00:00
Auxilor
322a6bb41b Updated libreforge 2022-03-21 12:24:06 +00:00
Auxilor
4dbc8afdf4 Updated libreforge 2022-03-19 16:42:59 +00:00
Auxilor
7ffa6ff4f4 Updated libreforge 2022-03-17 08:57:55 +00:00
Auxilor
3769684bb0 Updated libreforge 2022-03-16 09:05:56 +00:00
Auxilor
7bb931e027 Updated libreforge 2022-03-13 11:59:46 +00:00
Auxilor
879d6dd72d Updated libreforge 2022-03-12 12:22:54 +00:00
Auxilor
0a4aff45ad Updated libreforge 2022-03-10 15:13:28 +00:00
Auxilor
5929da1f48 Updated libreforge 2022-03-09 12:50:07 +00:00
Will FP
6db5de581b Update README.md 2022-03-09 12:47:33 +00:00
Auxilor
9ce1bb7ddf Updated libreforge 2022-03-08 20:20:01 +00:00
Auxilor
351d34de9f Updated libreforge 2022-03-07 14:01:18 +00:00
Auxilor
4d2b726aa0 Updated to 8.7.1 2022-03-04 16:59:39 +00:00
Auxilor
ff20b70784 Improved PDC storage 2022-03-04 16:59:31 +00:00
Auxilor
f31cd20200 Updated to 8.7.0 2022-03-03 17:02:43 +00:00
Auxilor
0ad2d3cfc7 Adapted pull request 2022-03-03 17:01:19 +00:00
Will FP
ccc7c5797a Merge pull request #28
Add commands ran for lifecycle
2022-03-03 16:54:00 +00:00
Auxilor
a218fa96c0 Updated libreforge 2022-03-01 16:26:17 +00:00
Auxilor
13c0a4d83a Updated to 8.5.2 2022-02-28 10:16:04 +00:00
Auxilor
62e7177b1b Fixed autospawn 2022-02-28 10:15:52 +00:00
Auxilor
752b30b4a2 Fixed spawn event not being called with totems 2022-02-28 10:14:11 +00:00
Auxilor
be4d6156e3 Fixed spawn totems some more 2022-02-28 10:12:12 +00:00
Auxilor
fed6dcafd7 Fixed spawn totems 2022-02-28 10:09:31 +00:00
Auxilor
36f944c58c Updated libreforge 2022-02-28 10:04:53 +00:00
Auxilor
1bc35656fe Fixed bosses attacking creative and spectator mode players 2022-02-28 10:04:38 +00:00
casper
1216e83a39 Add commands ran for lifecycle 2022-02-26 15:31:52 -05:00
Auxilor
4723c7982c Updated libreforge 2022-02-25 11:24:50 +00:00
Auxilor
8ba3c7834c Updated libreforge 2022-02-20 17:25:32 +00:00
Auxilor
76530a1617 Updated libreforge 2022-02-19 15:58:02 +00:00
Auxilor
bf41554846 build.gradle messages 2022-02-18 15:10:11 +00:00
Auxilor
a741c78b6b Fixed compatibility with other plugins 2022-02-18 14:37:01 +00:00
Auxilor
0f8dce74da Updated libreforge 2022-02-18 14:36:11 +00:00
Auxilor
0d31556b84 Updated libreforge 2022-02-15 16:49:03 +00:00
Auxilor
f8544c284e Updated libreforge 2022-02-14 17:18:16 +00:00
Auxilor
512a477fc6 Updated libreforge 2022-02-13 15:41:22 +00:00
Auxilor
8a1b473837 Updated libreforge 2022-02-12 10:51:41 +00:00
Auxilor
7464133c74 Updated to 8.3.0 2022-02-10 12:07:23 +00:00
Auxilor
1e00b28a8b Added BossTryDropItemEvent 2022-02-10 12:07:09 +00:00
Auxilor
b152313f87 Updated to 8.2.1 2022-02-10 11:57:40 +00:00
Auxilor
ec6d7175b9 Updated loggers 2022-02-10 11:57:32 +00:00
Auxilor
804a0e88b9 Updated libreforge 2022-02-10 10:57:25 +00:00
Auxilor
ff2de5aebe Updated to 8.1.8 2022-02-09 21:10:18 +00:00
Auxilor
990ad363eb Improved logging readability 2022-02-09 21:10:07 +00:00
Auxilor
d958b94fb0 Updated libreforge 2022-02-09 20:21:57 +00:00
Auxilor
e4f2a91968 Updated to 8.1.6 2022-02-09 13:10:57 +00:00
Auxilor
f1d50d6222 Added logging 2022-02-09 13:10:50 +00:00
Auxilor
035550db06 Added player to boss spawn event 2022-02-09 13:07:47 +00:00
Auxilor
f4bd64c192 Removed empty drops 2022-02-08 20:21:32 +00:00
Auxilor
4b8e1c0579 Updated to 8.1.5 2022-02-08 20:19:11 +00:00
Auxilor
d8cf08eb25 Fixed mob properties not being set 2022-02-08 20:19:05 +00:00
Auxilor
a94c96e5d4 Updated libreforge 2022-02-08 20:12:30 +00:00
Auxilor
dddf2d8a20 Added support for names without lookup string 2022-02-08 20:07:04 +00:00
Auxilor
7e67620c8c Updated libreforge 2022-02-08 20:03:01 +00:00
Auxilor
8c44303cdc Updated libreforge 2022-02-08 13:53:48 +00:00
Auxilor
97c1045243 Updated to 8.1.2 2022-02-08 13:53:31 +00:00
Auxilor
c47019f3c5 Updated to 8.1.1 2022-02-07 16:04:34 +00:00
Auxilor
1ffedfcb2e Fixed spawn totems 2022-02-07 16:04:25 +00:00
Auxilor
17705e9fdb Updated libreforge 2022-02-07 11:29:13 +00:00
Auxilor
7087feefbc Updated libreforge 2022-02-06 17:40:31 +00:00
21 changed files with 315 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
<h1 align="center">
<br>
<img src="https://i.imgur.com/A2qieC3.png" alt="EcoBosses logo" width="256">
<img src="https://i.imgur.com/3n3ssb4.png" alt="EcoBosses logo" width="256">
<br>
</h1>

View File

@@ -4,7 +4,7 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21"
}
}
@@ -61,12 +61,12 @@ allprojects {
}
dependencies {
compileOnly 'com.willfp:eco:6.24.0'
implementation 'com.willfp:libreforge:3.15.1'
compileOnly 'com.willfp:eco:6.34.0'
implementation 'com.willfp:libreforge:3.34.1'
compileOnly 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.0'
compileOnly 'org.jetbrains.kotlin:kotlin-stdlib:1.6.21'
}
tasks.withType(JavaCompile) {
@@ -119,3 +119,15 @@ 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

View File

@@ -12,6 +12,7 @@ import com.willfp.ecobosses.defence.MountHandler
import com.willfp.ecobosses.defence.PickupHandler
import com.willfp.ecobosses.integrations.levelledmobs.IntegrationLevelledMobs
import com.willfp.ecobosses.lifecycle.CompatibilityListeners
import com.willfp.ecobosses.lifecycle.ConsoleLoggers
import com.willfp.ecobosses.lifecycle.DeathListeners
import com.willfp.ecobosses.lifecycle.LifecycleHandlers
import com.willfp.ecobosses.spawn.AutospawnHandler
@@ -61,7 +62,8 @@ class EcoBossesPlugin : LibReforgePlugin(525, 10635, "&9") {
ImmunitiesHandler(),
CompatibilityListeners(),
SpawnTotemHandler(),
DeathListeners()
DeathListeners(),
ConsoleLoggers(this)
)
}

View File

@@ -0,0 +1,8 @@
package com.willfp.ecobosses.bosses
import com.willfp.eco.core.entities.ai.Goal
data class ConfiguredGoal<T : Goal<*>>(
val priority: Int,
val goal: T
)

View File

@@ -5,29 +5,19 @@ 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.items.CustomItem
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder
import com.willfp.eco.core.recipe.Recipes
import com.willfp.eco.core.recipe.parts.EmptyTestableItem
import com.willfp.eco.core.recipe.recipes.CraftingRecipe
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.BossBarTicker
import com.willfp.ecobosses.tick.BossTicker
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.PlayableSound
import com.willfp.ecobosses.util.SpawnTotem
import com.willfp.ecobosses.util.XpReward
import com.willfp.ecobosses.util.topDamagers
import com.willfp.ecobosses.tick.*
import com.willfp.ecobosses.util.*
import com.willfp.libreforge.Holder
import com.willfp.libreforge.conditions.Conditions
import com.willfp.libreforge.effects.Effects
@@ -36,10 +26,11 @@ import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import java.util.Objects
import java.util.UUID
import org.bukkit.persistence.PersistentDataType
import java.util.*
class EcoBoss(
val config: Config,
@@ -93,8 +84,15 @@ class EcoBoss(
return@run null
}
val name = config.getFormattedStringOrNull("spawn.egg.name")
val item = ItemStackBuilder(lookup)
.addLoreLines(config.getFormattedStrings("spawn.egg.lore"))
.apply {
if (name != null) {
setDisplayName(name)
}
}
.build().apply { bossEgg = this@EcoBoss }
val key = plugin.namespacedKeyFactory.create("${this.id}_spawn_egg")
@@ -135,9 +133,9 @@ class EcoBoss(
}
SpawnTotem(
Material.getMaterial(config.getString("spawn.totem.top")) ?: return@run null,
Material.getMaterial(config.getString("spawn.totem.middle")) ?: return@run null,
Material.getMaterial(config.getString("spawn.totem.bottom")) ?: return@run null
Material.getMaterial(config.getString("spawn.totem.top").uppercase()) ?: return@run null,
Material.getMaterial(config.getString("spawn.totem.middle").uppercase()) ?: return@run null,
Material.getMaterial(config.getString("spawn.totem.bottom").uppercase()) ?: return@run null
)
}
@@ -163,6 +161,22 @@ class EcoBoss(
locations
}
val hasCustomAI = config.getBool("customai.enabled")
val targetGoals = config.getSubsections("customai.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 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
ConfiguredGoal(it.getInt("priority"), goal)
}
val spawnConditions = config.getSubsections("spawn.conditions").mapNotNull {
Conditions.compile(it, "$id Spawn Conditions")
}
@@ -195,6 +209,16 @@ class EcoBoss(
map
}
private val commands: Map<BossLifecycle, LocalCommands> = run {
val map = mutableMapOf<BossLifecycle, LocalCommands>()
for (value in BossLifecycle.values()) {
map[value] = LocalCommands(config.getStrings("commands.${value.name.lowercase()}"))
}
map
}
private val commandRewards: Map<Int, Iterable<CommandReward>> = run {
val map = mutableMapOf<Int, Iterable<CommandReward>>()
@@ -248,6 +272,7 @@ class EcoBoss(
config.getDouble("chance"),
config.getStrings("items")
.map { Items.lookup(it) }
.filter { it !is EmptyTestableItem }
.map { it.item }
)
)
@@ -285,7 +310,26 @@ class EcoBoss(
}
fun spawn(location: Location): LivingEcoBoss {
val mob = mob.spawn(location) as LivingEntity
val mob = mob.spawn(location) as Mob
mob.isPersistent = true
mob.isCustomNameVisible = true
mob.removeWhenFarAway = false
mob.persistentDataContainer.set(
plugin.namespacedKeyFactory.create("boss"),
PersistentDataType.STRING,
this.id
)
if (hasCustomAI) {
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>) }
@Suppress("UNCHECKED_CAST")
entityGoals.forEach { controller.addEntityGoal(it.priority, it.goal as EntityGoal<in Mob>) }
}
val boss = LivingEcoBoss(
plugin,
mob.uniqueId,
@@ -323,6 +367,7 @@ class EcoBoss(
fun handleLifecycle(lifecycle: BossLifecycle, location: Location, entity: LivingEntity?) {
sounds[lifecycle]?.play(location)
messages[lifecycle]?.forEach { it.broadcast(location, entity?.topDamagers ?: emptyList()) }
commands[lifecycle]?.dispatch(location, entity?.topDamagers ?: emptyList())
}
fun processRewards(event: BossKillEvent) {
@@ -331,7 +376,7 @@ class EcoBoss(
val player = event.killer
for (drop in drops) {
drop.drop(location, player)
drop.drop(this, location, player)
}
xp.modify(event.event)

View File

@@ -3,6 +3,7 @@ package com.willfp.ecobosses.bosses
import com.google.common.collect.BiMap
import com.google.common.collect.HashBiMap
import com.google.common.collect.ImmutableList
import org.bukkit.GameMode
import org.bukkit.entity.Entity
import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player
@@ -23,7 +24,9 @@ class TargetMode(
boss.boss.targetRange,
boss.boss.targetRange,
boss.boss.targetRange
).filterIsInstance<Player>(),
).filterIsInstance<Player>()
.filter { listOf(GameMode.SURVIVAL, GameMode.ADVENTURE).contains(it.gameMode) }
.ifEmpty { return null },
entity
)
}

View File

@@ -110,7 +110,8 @@ class CommandSpawn(plugin: EcoBossesPlugin) : Subcommand(
val event = BossSpawnEvent(
boss,
location,
BossSpawnEvent.SpawnReason.COMMAND
BossSpawnEvent.SpawnReason.COMMAND,
null
)
Bukkit.getPluginManager().callEvent(event)

View File

@@ -2,6 +2,7 @@ package com.willfp.ecobosses.events
import com.willfp.ecobosses.bosses.EcoBoss
import org.bukkit.Location
import org.bukkit.entity.Player
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList
@@ -9,7 +10,8 @@ import org.bukkit.event.HandlerList
class BossSpawnEvent(
val boss: EcoBoss,
val location: Location,
val reason: SpawnReason
val reason: SpawnReason,
val spawner: Player?
) : Event(), Cancellable {
private var isCancelled: Boolean = false
@@ -29,6 +31,7 @@ class BossSpawnEvent(
TOTEM,
EGG,
COMMAND,
AUTOSPAWN,
UNKNOWN
}

View File

@@ -0,0 +1,30 @@
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
import org.bukkit.event.HandlerList
import org.bukkit.inventory.ItemStack
class BossTryDropItemEvent(
val boss: EcoBoss,
val location: Location,
var items: MutableCollection<ItemStack>,
var chance: Double,
val player: Player?
): Event() {
override fun getHandlers(): HandlerList {
return HANDLERS
}
companion object {
private val HANDLERS = HandlerList()
@JvmStatic
fun getHandlerList(): HandlerList {
return HANDLERS
}
}
}

View File

@@ -0,0 +1,56 @@
package com.willfp.ecobosses.lifecycle
import com.willfp.ecobosses.events.BossDespawnEvent
import com.willfp.ecobosses.events.BossKillEvent
import com.willfp.ecobosses.events.BossSpawnEvent
import com.willfp.libreforge.LibReforgePlugin
import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
class ConsoleLoggers(
private val plugin: LibReforgePlugin
) : Listener {
@EventHandler(
ignoreCancelled = true,
priority = EventPriority.MONITOR
)
fun handle(event: BossSpawnEvent) {
if (!plugin.configYml.getBool("log-spawn-kill")) {
return
}
val location = "${event.location.world?.name}: ${event.location.x}, ${event.location.y}, ${event.location.z}"
plugin.logger.info("&a${event.boss.id}&r was spawned by &a${event.spawner?.name}&r at &a$location")
}
@EventHandler(
ignoreCancelled = true,
priority = EventPriority.MONITOR
)
fun handle(event: BossKillEvent) {
if (!plugin.configYml.getBool("log-spawn-kill")) {
return
}
val loc = event.boss.entity?.location
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")
}
@EventHandler(
ignoreCancelled = true,
priority = EventPriority.MONITOR
)
fun handle(event: BossDespawnEvent) {
if (!plugin.configYml.getBool("log-spawn-kill")) {
return
}
val loc = event.boss.entity?.location
val location = "${loc?.world?.name}: ${loc?.x}, ${loc?.y}, ${loc?.z}"
plugin.logger.info("&a${event.boss.boss.id}&r despawned at &a$location")
}
}

View File

@@ -2,6 +2,8 @@ package com.willfp.ecobosses.spawn
import com.willfp.eco.core.EcoPlugin
import com.willfp.ecobosses.bosses.Bosses
import com.willfp.ecobosses.events.BossSpawnEvent
import org.bukkit.Bukkit
object AutospawnHandler {
private var tick = 1
@@ -20,11 +22,19 @@ object AutospawnHandler {
val location = boss.autoSpawnLocations.randomOrNull() ?: continue
val world = location.world ?: continue
if (Bosses.getAllAlive().mapNotNull { it.entity }.any { it.world == world }) {
continue
if (plugin.configYml.getBool("autospawn.one-boss-per-world")) {
if (Bosses.getAllAlive().mapNotNull { it.entity }.any { it.world == world }) {
continue
}
}
boss.spawn(location)
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.AUTOSPAWN, null)
Bukkit.getPluginManager().callEvent(spawnEvent)
if (!spawnEvent.isCancelled) {
boss.spawn(location)
}
}
tick++

View File

@@ -33,7 +33,7 @@ class SpawnEggHandler : Listener {
return
}
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG)
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG, player)
Bukkit.getPluginManager().callEvent(spawnEvent)

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.util.containsIgnoreCase
import com.willfp.ecobosses.bosses.Bosses
import com.willfp.ecobosses.events.BossSpawnEvent
import com.willfp.ecobosses.util.SpawnTotem
import org.bukkit.Bukkit
import org.bukkit.Material
import org.bukkit.block.Block
import org.bukkit.event.EventHandler
@@ -16,36 +17,36 @@ class SpawnTotemHandler : Listener {
)
fun handle(event: BlockPlaceEvent) {
for (i in 0..2) {
lateinit var block1: Block
lateinit var block2: Block
lateinit var block3: Block
lateinit var top: Block
lateinit var middle: Block
lateinit var bottom: Block
// I know this code sucks ass, but I can't be arsed to write it nicely
when (i) {
0 -> {
block3 = event.block
block2 = event.block.getRelative(0, -1, 0)
block1 = event.block.getRelative(0, -2, 0)
top = event.block
middle = event.block.getRelative(0, -1, 0)
bottom = event.block.getRelative(0, -2, 0)
}
1 -> {
block1 = event.block
block2 = event.block.getRelative(0, 1, 0)
block3 = event.block.getRelative(0, 2, 0)
top = event.block.getRelative(0, 2, 0)
middle = event.block.getRelative(0, 1, 0)
bottom = event.block
}
2 -> {
block2 = event.block
block1 = event.block.getRelative(0, -1, 0)
block3 = event.block.getRelative(0, 1, 0)
top = event.block.getRelative(0, 1, 0)
middle = event.block
bottom = event.block.getRelative(0, -1, 0)
}
}
val placedTotem = SpawnTotem(block1.type, block2.type, block3.type)
val placedTotem = SpawnTotem(top.type, middle.type, bottom.type)
for (boss in Bosses.values()) {
if (boss.totem == null || boss.disabledTotemWorlds.containsIgnoreCase(event.block.world.name)) {
continue
}
if (boss.totem != placedTotem) {
if (!boss.totem.matches(placedTotem)) {
continue
}
@@ -55,12 +56,14 @@ class SpawnTotemHandler : Listener {
return
}
val spawnEvent = BossSpawnEvent(boss, event.block.location, BossSpawnEvent.SpawnReason.TOTEM)
val spawnEvent = BossSpawnEvent(boss, event.block.location, BossSpawnEvent.SpawnReason.TOTEM, player)
Bukkit.getPluginManager().callEvent(spawnEvent)
if (!spawnEvent.isCancelled) {
block1.type = Material.AIR
block2.type = Material.AIR
block3.type = Material.AIR
top.type = Material.AIR
middle.type = Material.AIR
bottom.type = Material.AIR
boss.spawn(event.block.location.add(0.0, 1.5, 0.0))
}

View File

@@ -0,0 +1,38 @@
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
import org.bukkit.Bukkit
import org.bukkit.Location
data class LocalCommands(
val commands: Iterable<String>,
) {
fun dispatch(location: Location, topDamagers: List<Damager>) {
val toDispatch = commands.toMutableList()
toDispatch.replaceAll {
var command = it
for (i in 1..20) {
val damager = topDamagers.getOrNull(i - 1)
val damage = if (damager?.damage != null) NumberUtils.format(damager.damage) else
EcoBossesPlugin.instance.langYml.getFormattedString("na")
val player = if (damager?.uuid != null) Bukkit.getOfflinePlayer(damager.uuid).savedDisplayName else
EcoBossesPlugin.instance.langYml.getFormattedString("na")
command = command.replace("%damage_${i}%", damage)
.replace("%damage_${i}_player%", player)
}
command.replace("%x%", location.blockX.toString())
.replace("%y%", location.blockY.toString())
.replace("%z%", location.blockZ.toString())
}
for (s in toDispatch) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), s);
}
}
}

View File

@@ -2,6 +2,8 @@ package com.willfp.ecobosses.util
import com.willfp.eco.core.drops.DropQueue
import com.willfp.eco.util.NumberUtils
import com.willfp.ecobosses.bosses.EcoBoss
import com.willfp.ecobosses.events.BossTryDropItemEvent
import org.bukkit.Bukkit
import org.bukkit.Location
import org.bukkit.entity.Player
@@ -12,15 +14,19 @@ data class BossDrop(
val chance: Double,
val drops: Collection<ItemStack>
) {
fun drop(location: Location, player: Player?) {
if (NumberUtils.randFloat(0.0, 100.0) < chance) {
fun drop(boss: EcoBoss, location: Location, player: Player?) {
val event = BossTryDropItemEvent(boss, location, drops.toMutableList(), chance, player)
Bukkit.getPluginManager().callEvent(event)
if (NumberUtils.randFloat(0.0, 100.0) < event.chance) {
if (player != null) {
DropQueue(player)
.setLocation(location)
.addItems(drops)
.setLocation(event.location)
.addItems(event.items)
.push()
} else {
for (drop in drops) {
for (drop in event.items) {
location.world?.dropItemNaturally(location, drop)
}
}

View File

@@ -6,4 +6,10 @@ data class SpawnTotem(
val top: Material,
val middle: Material,
val bottom: Material
)
) {
fun matches(totem: SpawnTotem): Boolean {
return this.top == totem.top
&& this.middle == totem.middle
&& this.bottom == totem.bottom
}
}

View File

@@ -4,6 +4,10 @@
#
discover-recipes: true
log-spawn-kill: true
autospawn:
one-boss-per-world: true # If only one boss can auto-spawn per world at once.
cooldown:
in-actionbar: true
@@ -32,3 +36,14 @@ point-names: # If you have point names that look ugly (eg g_souls) then you can
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:
permanent: true
triggered: true
ambient:
permanent: false
triggered: true
particles:
permanent: false
triggered: true

View File

@@ -26,6 +26,10 @@ bosses:
# 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:
@@ -106,7 +110,8 @@ bosses:
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"
item: evoker_spawn_egg unbreaking:1 hide_enchants
name: "&8Steel Golem&f Spawn Egg"
lore:
- ""
- "&8&oPlace on the ground to"
@@ -122,6 +127,13 @@ bosses:
- 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

View File

@@ -18,5 +18,6 @@ messages:
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

@@ -14,6 +14,8 @@ softdepend:
- Jobs
- mcMMO
- Vault
- ShopGUIPlus
- DeluxeSellwands
commands:
ecobosses:

View File

@@ -1,2 +1,2 @@
version = 8.0.0
version = 8.21.1
plugin-name = EcoBosses