From baa2b6718e3ea87afb563b81f200197c5403f468 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Sat, 5 Feb 2022 18:57:56 +0000 Subject: [PATCH] Continued rewrite --- .../bosses/tick/tickers/BossBarTicker.java | 64 --------- .../bosses/tick/tickers/DeathTimeTicker.java | 35 ----- .../tick/tickers/NamePlaceholderTicker.java | 30 ----- .../bosses/tick/tickers/TargetTicker.java | 57 -------- .../bosses/util/obj/ArgumentedEffectName.java | 8 -- .../willfp/ecobosses/bosses/BossLifecycle.kt | 4 +- .../com/willfp/ecobosses/bosses/EcoBoss.kt | 125 ++++++++++++++++-- .../willfp/ecobosses/tick/BossBarTicker.kt | 45 +++++++ .../willfp/ecobosses/util/LocalBroadcast.kt | 33 +++++ .../willfp/ecobosses/util/PlayableSound.kt | 12 +- .../com/willfp/ecobosses/util/Rewards.kt | 50 +++++++ .../src/main/resources/ecobosses.yml | 76 ++++++++++- 12 files changed, 327 insertions(+), 212 deletions(-) delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/BossBarTicker.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/DeathTimeTicker.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/NamePlaceholderTicker.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/TargetTicker.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/ArgumentedEffectName.java create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/BossBarTicker.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/LocalBroadcast.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/Rewards.kt diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/BossBarTicker.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/BossBarTicker.java deleted file mode 100644 index 412f920..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/BossBarTicker.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.willfp.ecobosses.bosses.tick.tickers; - -import com.willfp.eco.util.PlayerUtils; -import com.willfp.eco.util.StringUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.tick.BossTicker; -import net.kyori.adventure.bossbar.BossBar; -import org.bukkit.Bukkit; -import org.bukkit.attribute.Attribute; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public class BossBarTicker implements BossTicker { - /** - * The boss bar. - */ - private final BossBar bossBar; - - /** - * The radius that the boss bar should be visible in. - */ - private final double radius; - - /** - * Create new boss bar ticker. - * @param bossBar The boss bar. - * @param radius The radius. - */ - public BossBarTicker(@NotNull final BossBar bossBar, - final double radius) { - this.bossBar = bossBar; - this.radius = radius; - } - - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - bossBar.name(StringUtils.toComponent(entity.getCustomName())); - bossBar.progress((float) (entity.getHealth() / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue())); - - if (tick % 40 == 0) { - for (Player player : Bukkit.getOnlinePlayers()) { - PlayerUtils.getAudience(player).hideBossBar(bossBar); - } - entity.getNearbyEntities(radius, radius, radius).forEach(entity1 -> { - if (entity1 instanceof Player) { - PlayerUtils.getAudience((Player) entity1).showBossBar(bossBar); - } - }); - } - } - - @Override - public void onDeath(@NotNull final EcoBoss boss, - @Nullable final LivingEntity entity, - final long tick) { - for (Player player : Bukkit.getOnlinePlayers()) { - PlayerUtils.getAudience(player).hideBossBar(bossBar); - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/DeathTimeTicker.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/DeathTimeTicker.java deleted file mode 100644 index c49803b..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/DeathTimeTicker.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.willfp.ecobosses.bosses.tick.tickers; - -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.util.obj.OptionedSound; -import com.willfp.ecobosses.tick.BossTicker; -import org.bukkit.Bukkit; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -public class DeathTimeTicker implements BossTicker { - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - if (boss.getTimeToLive() < 0) { - return; - } - - int timeLeft; - timeLeft = (int) (entity.getMetadata("death-time").get(0).asLong() - System.currentTimeMillis()); - timeLeft = (int) Math.ceil(timeLeft / 1000D); - if (timeLeft <= 0) { - entity.remove(); - boss.removeLivingBoss(entity); - - for (String despawnMessage : boss.getDespawnMessages()) { - Bukkit.broadcastMessage(despawnMessage); - } - - for (OptionedSound sound : boss.getDespawnSounds()) { - entity.getWorld().playSound(entity.getLocation(), sound.sound(), sound.volume(), sound.pitch()); - } - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/NamePlaceholderTicker.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/NamePlaceholderTicker.java deleted file mode 100644 index 3e5bf1b..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/NamePlaceholderTicker.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.willfp.ecobosses.bosses.tick.tickers; - -import com.willfp.eco.util.StringUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.tick.BossTicker; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -public class NamePlaceholderTicker implements BossTicker { - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - int timeLeft = -1; - if (boss.getTimeToLive() > 0) { - timeLeft = (int) (entity.getMetadata("death-time").get(0).asLong() - System.currentTimeMillis()); - timeLeft = (int) Math.ceil(timeLeft / 1000D); - } - - String time = ""; - if (timeLeft > 0) { - time = String.format("%d:%02d", timeLeft/60, timeLeft%60); - } - entity.setCustomName( - boss.getDisplayName() - .replace("%health%", StringUtils.internalToString(entity.getHealth())) - .replace("%time%", time) - ); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/TargetTicker.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/TargetTicker.java deleted file mode 100644 index 97ed0bf..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/tick/tickers/TargetTicker.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.willfp.ecobosses.bosses.tick.tickers; - -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.tick.BossTicker; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Mob; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -public class TargetTicker implements BossTicker { - /** - * The targeting mode. - */ - private final TargetMode mode; - - /** - * The maximum range. - */ - private final double range; - - /** - * Create new target ticker. - * - * @param mode The targeting mode. - * @param range The range. - */ - public TargetTicker(@NotNull final TargetMode mode, - final double range) { - this.mode = mode; - this.range = range; - } - - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - Mob mob = (Mob) entity; - if (tick % 10 == 0) { - List nearbyPlayers = new ArrayList<>(); - for (Entity nearbyEntity : entity.getNearbyEntities(range, range, range)) { - if (nearbyEntity instanceof Player) { - nearbyPlayers.add((Player) nearbyEntity); - } - } - - if (nearbyPlayers.isEmpty()) { - return; - } - - mob.setTarget(mode.getTarget(nearbyPlayers, entity)); - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/ArgumentedEffectName.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/ArgumentedEffectName.java deleted file mode 100644 index 9fbb1b7..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/ArgumentedEffectName.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.willfp.ecobosses.bosses.util.obj; - -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public record ArgumentedEffectName(@NotNull String name, @NotNull List args) { -} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossLifecycle.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossLifecycle.kt index 38c82d2..b642c4d 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossLifecycle.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossLifecycle.kt @@ -3,6 +3,6 @@ package com.willfp.ecobosses.bosses enum class BossLifecycle { SPAWN, KILL, - DESPAWN + DESPAWN, + INJURE } - diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/EcoBoss.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/EcoBoss.kt index 487e239..96a8be1 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/EcoBoss.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/EcoBoss.kt @@ -4,16 +4,23 @@ import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.entities.Entities import com.willfp.eco.core.entities.TestableEntity +import com.willfp.eco.core.items.Items +import com.willfp.eco.util.toComponent +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.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.XpReward import com.willfp.libreforge.Holder import com.willfp.libreforge.conditions.ConfiguredCondition -import com.willfp.libreforge.effects.ConfiguredEffect import com.willfp.libreforge.effects.Effects +import net.kyori.adventure.bossbar.BossBar import org.bukkit.Location import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player @@ -36,6 +43,14 @@ class EcoBoss( val targetMode = TargetMode.getByID(config.getString("target.mode"))!! + val isBossBarEnabled = config.getBool("bossBar.enabled") + + val bossBarRadius = config.getDouble("bossBar.radius") + + private val bossBarColor = BossBar.Color.valueOf(config.getString("bossBar.color").uppercase()) + + private val bossBarStyle = BossBar.Overlay.valueOf(config.getString("bossBar.style").uppercase()) + private val sounds: Map = run { val map = mutableMapOf() @@ -48,6 +63,79 @@ class EcoBoss( map } + private val messages: Map> = run { + val map = mutableMapOf>() + + for (value in BossLifecycle.values()) { + map[value] = config.getSubsections("messages.${value.name.lowercase()}").map { + LocalBroadcast.fromConfig(it) + } + } + + map + } + + private val commandRewards: Map> = run { + val map = mutableMapOf>() + + for (rank in config.getSubsection("rewards.topDamagerCommands").getKeys(false)) { + val rankRewards = mutableListOf() + + for (config in config.getSubsections("rewards.topDamagerCommands.$rank")) { + rankRewards.add( + CommandReward( + config.getDouble("chance"), + config.getStrings("commands") + ) + ) + } + + map[rank.toInt()] = rankRewards + } + + map + } + + private val nearbyCommandRewardRadius = config.getDouble("rewards.nearbyPlayerCommands.radius") + + private val nearbyCommands: Iterable = run { + val list = mutableListOf() + + for (config in config.getSubsections("rewards.nearbyPlayerCommands.commands")) { + list.add( + CommandReward( + config.getDouble("chance"), + config.getStrings("commands") + ) + ) + } + + list + } + + private val xp = XpReward( + config.getInt("rewards.xp.minimum"), + config.getInt("rewards.xp.maximum") + ) + + + private val drops: Iterable = run { + val list = mutableListOf() + + for (config in config.getSubsections("rewards.drops")) { + list.add( + BossDrop( + config.getDouble("chance"), + config.getStrings("items") + .map { Items.lookup(it) } + .map { it.item } + ) + ) + } + + list + } + private val mob: TestableEntity = Entities.lookup(config.getString("mob")) private val currentlyAlive = mutableMapOf() @@ -85,15 +173,39 @@ class EcoBoss( } private fun createTickersFor(entity: LivingEntity): Set { - return setOf( + val tickers = mutableSetOf( LifespanTicker(), DisplayNameTicker(), TargetTicker() ) + + if (isBossBarEnabled) { + tickers.add( + BossBarTicker( + BossBar.bossBar( + this.displayName.toComponent(), + 1.0f, + bossBarColor, + bossBarStyle + ) + ) + ) + } + + return tickers } - fun handleLifecycle(player: Player, lifecycle: BossLifecycle) { - sounds[lifecycle]?.play(player) + fun handleLifecycle(lifecycle: BossLifecycle, location: Location) { + sounds[lifecycle]?.play(location) + messages[lifecycle]?.forEach { it.broadcast(location) } + } + + fun processRewards(player: Player, location: Location) { + for (drop in drops) { + drop.drop(location, player) + } + + xp.drop(location, player) } override fun equals(other: Any?): Boolean { @@ -114,8 +226,3 @@ class EcoBoss( + "}") } } - -class SimpleHolder( - override val conditions: Set, - override val effects: Set -) : Holder \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/BossBarTicker.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/BossBarTicker.kt new file mode 100644 index 0000000..17e748d --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/BossBarTicker.kt @@ -0,0 +1,45 @@ +package com.willfp.ecobosses.tick + +import com.willfp.eco.util.asAudience +import com.willfp.eco.util.toComponent +import com.willfp.ecobosses.bosses.LivingEcoBoss +import net.kyori.adventure.bossbar.BossBar +import org.bukkit.Bukkit +import org.bukkit.attribute.Attribute +import org.bukkit.entity.Player + +class BossBarTicker( + private val bar: BossBar +) : BossTicker { + override fun tick(boss: LivingEcoBoss, tick: Int) { + val entity = boss.entity ?: return + + bar.name(entity.customName!!.toComponent()) + bar.progress((entity.health / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH)!!.value).toFloat()) + + if (tick % 40 == 0) { + for (player in Bukkit.getOnlinePlayers()) { + player.asAudience().hideBossBar(bar) + } + entity.getNearbyEntities( + boss.boss.bossBarRadius, + boss.boss.bossBarRadius, + boss.boss.bossBarRadius + ).filterIsInstance() + .map { it.asAudience() } + .forEach { it.showBossBar(bar) } + } + + if (tick % 10 != 0) { + return + } + + entity.target = boss.boss.targetMode.getTarget(boss) ?: return + } + + override fun onDeath(boss: LivingEcoBoss, tick: Int) { + for (player in Bukkit.getOnlinePlayers()) { + player.asAudience().hideBossBar(bar) + } + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/LocalBroadcast.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/LocalBroadcast.kt new file mode 100644 index 0000000..f518abf --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/LocalBroadcast.kt @@ -0,0 +1,33 @@ +package com.willfp.ecobosses.util + +import com.willfp.eco.core.config.interfaces.Config +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.entity.Player + +data class LocalBroadcast( + val messages: Iterable, + val radius: Double +) { + fun broadcast(location: Location) { + if (radius < 0) { + for (message in messages) { + Bukkit.broadcastMessage(message) + } + } else { + val world = location.world ?: return + world.getNearbyEntities(location, radius, radius, radius) + .filterIsInstance() + .forEach { player -> messages.forEach { player.sendMessage(it) } } + } + } + + companion object { + fun fromConfig(config: Config): LocalBroadcast { + return LocalBroadcast( + config.getFormattedStrings("message"), + config.getDouble("radius") + ) + } + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/PlayableSound.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/PlayableSound.kt index b774013..6b46a9e 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/PlayableSound.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/PlayableSound.kt @@ -1,16 +1,16 @@ package com.willfp.ecobosses.util import com.willfp.eco.core.config.interfaces.Config +import org.bukkit.Location import org.bukkit.Sound -import org.bukkit.entity.Player data class ConfiguredSound( private val sound: Sound, private val pitch: Double, private val volume: Double ) { - fun play(player: Player) { - player.playSound(player.location, sound, volume.toFloat(), pitch.toFloat()) + fun play(location: Location) { + location.world?.playSound(location, sound, volume.toFloat(), pitch.toFloat()) } companion object { @@ -27,9 +27,9 @@ data class ConfiguredSound( data class PlayableSound( val sounds: Iterable ) { - fun play(player: Player) { + fun play(location: Location) { for (sound in sounds) { - sound.play(player) + sound.play(location) } } -} \ No newline at end of file +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/Rewards.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/Rewards.kt new file mode 100644 index 0000000..6df4a9f --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/Rewards.kt @@ -0,0 +1,50 @@ +package com.willfp.ecobosses.util + +import com.willfp.eco.core.drops.DropQueue +import com.willfp.eco.util.NumberUtils +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack + +data class BossDrop( + val chance: Double, + val drops: Collection +) { + fun drop(location: Location, player: Player) { + if (NumberUtils.randFloat(0.0, 100.0) < chance) { + DropQueue(player) + .setLocation(location) + .addItems(drops) + .push() + } + } +} + +data class CommandReward( + val chance: Double, + val commands: Collection +) { + fun reward(player: Player) { + if (NumberUtils.randFloat(0.0, 100.0) < chance) { + for (command in commands) { + Bukkit.getServer().dispatchCommand( + Bukkit.getConsoleSender(), + command.replace("%player%", player.name) + ) + } + } + } +} + +data class XpReward( + val minimum: Int, + val maximum: Int +) { + fun drop(location: Location, player: Player) { + DropQueue(player) + .setLocation(location) + .addXP(NumberUtils.randInt(minimum, maximum)) + .push() + } +} diff --git a/eco-core/core-plugin/src/main/resources/ecobosses.yml b/eco-core/core-plugin/src/main/resources/ecobosses.yml index 5e13420..de85a59 100644 --- a/eco-core/core-plugin/src/main/resources/ecobosses.yml +++ b/eco-core/core-plugin/src/main/resources/ecobosses.yml @@ -22,4 +22,78 @@ bosses: - id: steel_golem mob: iron_golem displayName: "&8Steel Golem &7| &c%health%♥ &7| &e%time%" - effects: [ ] \ No newline at end of file + effects: [ ] + rewards: + xp: + minimum: 30000 + maximum: 60000 + topDamagerCommands: + 1: [] + 2: [] + 3: [] + nearbyPlayerCommands: + radius: 10 + commands: [] + drops: [] + target: + mode: highest_health + range: 40 + bossBar: + enabled: true + color: white + style: solid + radius: 120 + messages: + 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 + 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: [ ] + 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 \ No newline at end of file