From e575df9f37cd632288bc8853e4e30dc5b1ddfd51 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Sun, 6 Feb 2022 12:51:33 +0000 Subject: [PATCH] Nearing completion --- .../com/willfp/ecobosses/bosses/EcoBoss.java | 1 - .../ecobosses/bosses/effects/Effect.java | 103 --------- .../ecobosses/bosses/effects/Effects.java | 53 ----- .../effects/EffectDamageNearbyPlayers.java | 46 ---- .../effects/EffectGivePotionEffect.java | 48 ---- .../EffectLightningNearbyEntities.java | 51 ----- .../effects/effects/EffectShuffleHotbar.java | 54 ----- .../bosses/effects/effects/EffectSummon.java | 65 ------ .../effects/effects/EffectTeleport.java | 75 ------- .../bosses/listeners/SpawnListeners.java | 1 - .../ecobosses/bosses/util/obj/SpawnTotem.java | 9 - .../ecobosses/commands/CommandEcobosses.java | 29 --- .../ecobosses/commands/CommandGive.java | 148 ------------- .../ecobosses/commands/CommandKillall.java | 31 --- .../ecobosses/commands/CommandReload.java | 27 --- .../ecobosses/commands/CommandSpawn.java | 206 ------------------ .../events/EcoBossSpawnTotemEvent.java | 1 - .../com/willfp/ecobosses/EcoBossesPlugin.kt | 6 +- .../com/willfp/ecobosses/bosses/BossUtils.kt | 6 +- .../com/willfp/ecobosses/bosses/Bosses.kt | 4 +- .../com/willfp/ecobosses/bosses/EcoBoss.kt | 102 ++++++++- .../willfp/ecobosses/bosses/LivingEcoBoss.kt | 25 +-- .../ecobosses/commands/CommandEcobosses.kt | 26 +++ .../willfp/ecobosses/commands/CommandGive.kt | 115 ++++++++++ .../ecobosses/commands/CommandKillall.kt | 28 +++ .../ecobosses/commands/CommandReload.kt | 20 ++ .../willfp/ecobosses/commands/CommandSpawn.kt | 178 +++++++++++++++ .../defence/DamageMultiplierHandler.kt | 8 + .../willfp/ecobosses/events/BossDeathEvent.kt | 3 +- .../willfp/ecobosses/events/BossKillEvent.kt | 4 +- .../ecobosses/lifecycle/BossLifecycle.kt | 12 +- .../lifecycle/CompatibilityListeners.kt | 16 ++ .../ecobosses/lifecycle/DeathListeners.kt | 17 +- .../ecobosses/lifecycle/LifecycleHandlers.kt | 8 +- .../ecobosses/spawn/SpawnTotemHandler.kt | 64 ++++++ .../willfp/ecobosses/tick/LifespanTicker.kt | 2 +- .../willfp/ecobosses/tick/TeleportHandler.kt | 49 +++++ .../willfp/ecobosses/util/LocalBroadcast.kt | 21 +- .../com/willfp/ecobosses/util/SpawnTotem.kt | 9 + .../src/main/resources/bosses/steel_golem.yml | 2 +- .../src/main/resources/ecobosses.yml | 50 ++++- 41 files changed, 716 insertions(+), 1007 deletions(-) delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effect.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effects.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectDamageNearbyPlayers.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectGivePotionEffect.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectLightningNearbyEntities.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectShuffleHotbar.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectSummon.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectTeleport.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/SpawnTotem.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandEcobosses.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandGive.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandKillall.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandReload.java delete mode 100644 eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandSpawn.java create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandEcobosses.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandGive.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandKillall.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandReload.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandSpawn.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/CompatibilityListeners.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnTotemHandler.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/TeleportHandler.kt create mode 100644 eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/SpawnTotem.kt diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/EcoBoss.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/EcoBoss.java index fe0aa92..5932bef 100644 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/EcoBoss.java +++ b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/EcoBoss.java @@ -27,7 +27,6 @@ import com.willfp.ecobosses.bosses.util.obj.EquipmentPiece; import com.willfp.ecobosses.bosses.util.obj.ExperienceOptions; import com.willfp.ecobosses.bosses.util.obj.ImmunityOptions; import com.willfp.ecobosses.bosses.util.obj.OptionedSound; -import com.willfp.ecobosses.bosses.util.obj.SpawnTotem; import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effect.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effect.java deleted file mode 100644 index 3aa33e3..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effect.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.willfp.ecobosses.bosses.effects; - -import com.willfp.ecobosses.bosses.EcoBoss; -import lombok.Getter; -import org.bukkit.Bukkit; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Objects; - -public abstract class Effect implements BossTicker { - /** - * The effect args. - */ - @Getter - private final List args; - - /** - * Create a new effect. - * - * @param args The args. - */ - protected Effect(@NotNull final List args) { - this.args = args; - } - - /** - * Show a config error. - * - * @param message The error message. - */ - public void showConfigError(@NotNull final String message) { - Bukkit.getLogger().warning("An effect is configured incorrectly!"); - Bukkit.getLogger().warning(message); - Bukkit.getLogger().warning("Usage: " + getUsage()); - } - - /** - * Get effect usage. - * - * @return The usage. - */ - public abstract String getUsage(); - - /** - * Handle the boss attacking a player. - * - * @param boss The boss. - * @param entity The boss entity. - * @param player The player. - */ - public void onAttack(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - @NotNull final Player player) { - // Override when needed. - } - - /** - * Tick the effect. - * - * @param boss The boss. - * @param entity The boss entity. - * @param tick The current tick: counts up from zero. - */ - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - // Override when needed. - } - - /** - * On boss death. - * - * @param boss The boss. - * @param entity The boss entity. - * @param tick The current tick: counts up from zero. - */ - @Override - public void onDeath(@NotNull final EcoBoss boss, - @Nullable final LivingEntity entity, - final long tick) { - // Override when needed. - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Effect effect)) { - return false; - } - return Objects.equals(getArgs(), effect.getArgs()); - } - - @Override - public int hashCode() { - return Objects.hash(getArgs()); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effects.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effects.java deleted file mode 100644 index bf94497..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/Effects.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.willfp.ecobosses.bosses.effects; - -import com.willfp.ecobosses.bosses.effects.effects.*; -import lombok.experimental.UtilityClass; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; - -@UtilityClass -public class Effects { - /** - * Registered effects. - */ - private static final Map, Effect>> EFFECTS = new HashMap<>(); - - static { - register("damage-nearby-players", EffectDamageNearbyPlayers::new); - register("lightning-nearby-entities", EffectLightningNearbyEntities::new); - register("summon", EffectSummon::new); - register("give-potion-effect", EffectGivePotionEffect::new); - register("shuffle-hotbar", EffectShuffleHotbar::new); - register("teleport", EffectTeleport::new); - } - - /** - * Register new effect. - * - * @param name The effect name. - * @param creator Function to create an instance of the effect given args. - */ - public void register(@NotNull final String name, - @NotNull final Function, Effect> creator) { - EFFECTS.put(name, creator); - } - - /** - * Get effect matching name. - * - * @param name The effect name. - * @param args The args. - * @return The found effect, or null. - */ - @Nullable - public Effect getEffect(@NotNull final String name, - @NotNull final List args) { - Function, Effect> found = EFFECTS.get(name.toLowerCase()); - return found == null ? null : found.apply(args); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectDamageNearbyPlayers.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectDamageNearbyPlayers.java deleted file mode 100644 index 3a111bd..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectDamageNearbyPlayers.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class EffectDamageNearbyPlayers extends Effect { - private final int frequency; - private final double damage; - private final double radius; - - public EffectDamageNearbyPlayers(@NotNull final List args) { - super(args); - - if (args.size() < 3) { - showConfigError("Incorrect amount of arguments!"); - } - - frequency = Integer.parseInt(args.get(0)); - radius = Double.parseDouble(args.get(1)); - damage = Double.parseDouble(args.get(2)); - } - - @Override - public String getUsage() { - return "damage-nearby-players:::"; - } - - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - if (tick % frequency == 0) { - for (Entity nearbyEntity : entity.getNearbyEntities(radius, radius, radius)) { - if (nearbyEntity instanceof Player) { - ((Player) nearbyEntity).damage(damage, entity); - } - } - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectGivePotionEffect.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectGivePotionEffect.java deleted file mode 100644 index f45e222..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectGivePotionEffect.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.eco.util.NumberUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class EffectGivePotionEffect extends Effect { - private final PotionEffectType type; - private final double chance; - private final int duration; - private final int strength; - - public EffectGivePotionEffect(@NotNull final List args) { - super(args); - - if (args.size() < 4) { - showConfigError("Incorrect amount of arguments!"); - } - - type = PotionEffectType.getByName(args.get(0).toUpperCase()); - chance = Double.parseDouble(args.get(1)); - duration = Integer.parseInt(args.get(2)); - strength = Integer.parseInt(args.get(3)); - } - - @Override - public String getUsage() { - return "give-potion-effect::::"; - } - - @Override - public void onAttack(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - @NotNull final Player player) { - if (NumberUtils.randFloat(0, 100) > this.chance) { - return; - } - - player.addPotionEffect(new PotionEffect(type, duration, strength - 1)); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectLightningNearbyEntities.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectLightningNearbyEntities.java deleted file mode 100644 index 674b9b7..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectLightningNearbyEntities.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.eco.util.LightningUtils; -import com.willfp.eco.util.NumberUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class EffectLightningNearbyEntities extends Effect { - private final int frequency; - private final double chance; - private final double damage; - private final double radius; - - public EffectLightningNearbyEntities(@NotNull final List args) { - super(args); - - if (args.size() < 4) { - showConfigError("Incorrect amount of arguments!"); - } - - frequency = Integer.parseInt(args.get(0)); - chance = Double.parseDouble(args.get(1)); - radius = Double.parseDouble(args.get(2)); - damage = Double.parseDouble(args.get(3)); - } - - @Override - public String getUsage() { - return "lightning-nearby-entities::::"; - } - - @Override - public void tick(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - final long tick) { - if (tick % frequency == 0) { - for (Entity nearbyEntity : entity.getNearbyEntities(radius, radius, radius)) { - if (NumberUtils.randFloat(0, 100) < chance) { - if (nearbyEntity instanceof LivingEntity) { - LightningUtils.strike((LivingEntity) nearbyEntity, damage); - } - } - } - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectShuffleHotbar.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectShuffleHotbar.java deleted file mode 100644 index b01a67a..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectShuffleHotbar.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.eco.util.NumberUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import org.bukkit.Sound; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class EffectShuffleHotbar extends Effect { - private final double chance; - - public EffectShuffleHotbar(@NotNull final List args) { - super(args); - - if (args.size() < 1) { - showConfigError("Incorrect amount of arguments!"); - } - - chance = Double.parseDouble(args.get(0)); - } - - @Override - public String getUsage() { - return "shuffle-hotbar:"; - } - - @Override - public void onAttack(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - @NotNull final Player player) { - if (NumberUtils.randFloat(0, 100) > this.chance) { - return; - } - - List hotbar = new ArrayList<>(); - for (int i = 0; i < 9; i++) { - hotbar.add(player.getInventory().getItem(i)); - } - Collections.shuffle(hotbar); - int i2 = 0; - for (ItemStack item : hotbar) { - player.getInventory().setItem(i2, item); - i2++; - } - player.playSound(player.getLocation(), Sound.ENTITY_ENDER_PEARL_THROW, 1, 0.5f); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectSummon.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectSummon.java deleted file mode 100644 index 963add6..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectSummon.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.eco.core.entities.Entities; -import com.willfp.eco.core.entities.TestableEntity; -import com.willfp.eco.util.NumberUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import com.willfp.ecobosses.bosses.util.obj.OptionedSound; -import org.bukkit.Location; -import org.bukkit.Material; -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.List; - -public class EffectSummon extends Effect { - private final TestableEntity type; - private final double chance; - - public EffectSummon(@NotNull final List args) { - super(args); - - if (args.size() < 2) { - showConfigError("Incorrect amount of arguments!"); - } - - type = Entities.lookup(args.get(0)); - chance = Double.parseDouble(args.get(1)); - } - - @Override - public String getUsage() { - return "summon::"; - } - - @Override - public void onAttack(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - @NotNull final Player player) { - if (NumberUtils.randFloat(0, 100) > this.chance) { - return; - } - - Location loc = player.getLocation().add(NumberUtils.randInt(2, 6), 0, NumberUtils.randInt(2, 6)); - for (int i = 0; i < 15; i++) { - if (loc.getBlock().getType() == Material.AIR) { - break; - } - - loc.add(0, 1, 0); - } - - Entity summonedEntity = type.spawn(loc); - if (summonedEntity instanceof Mob) { - ((Mob) summonedEntity).setTarget(player); - } - - for (OptionedSound sound : boss.getSummonSounds()) { - player.getWorld().playSound(entity.getLocation(), sound.sound(), sound.volume(), sound.pitch()); - } - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectTeleport.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectTeleport.java deleted file mode 100644 index 1ffa1b4..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/effects/effects/EffectTeleport.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.willfp.ecobosses.bosses.effects.effects; - -import com.willfp.eco.util.NumberUtils; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.effects.Effect; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class EffectTeleport extends Effect { - private final int range; - private final double chance; - - public EffectTeleport(@NotNull final List args) { - super(args); - - if (args.size() < 2) { - showConfigError("Incorrect amount of arguments!"); - } - - range = Integer.parseInt(args.get(0)); - chance = Double.parseDouble(args.get(1)); - } - - @Override - public String getUsage() { - return "teleport::"; - } - - @Override - public void onAttack(@NotNull final EcoBoss boss, - @NotNull final LivingEntity entity, - @NotNull final Player player) { - if (NumberUtils.randFloat(0, 100) > this.chance) { - return; - } - - List valid = new ArrayList<>(); - for (int x = -range; x <= range; x++) { - for (int y = -range; y <= range; y++) { - for (int z = -range; z <= range; z++) { - Location location = entity.getLocation().clone(); - location.setX(location.getX() + x); - location.setY(location.getY() + y); - location.setZ(location.getZ() + z); - - Block block = location.getBlock(); - - if (block.getType() == Material.AIR - && block.getRelative(BlockFace.UP).getType() == Material.AIR - && !(block.getRelative(BlockFace.DOWN).isLiquid() || block.getRelative(BlockFace.DOWN).getType() == Material.AIR)) { - valid.add(location); - } - } - } - } - - if (valid.isEmpty()) { - return; - } - - Collections.shuffle(valid); - Location location = valid.get(0); - - entity.teleport(location); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/listeners/SpawnListeners.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/listeners/SpawnListeners.java index 42906d4..d764db2 100644 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/listeners/SpawnListeners.java +++ b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/listeners/SpawnListeners.java @@ -4,7 +4,6 @@ import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.PluginDependent; import com.willfp.ecobosses.bosses.EcoBoss; import com.willfp.ecobosses.bosses.EcoBosses; -import com.willfp.ecobosses.bosses.util.obj.SpawnTotem; import com.willfp.ecobosses.events.EcoBossSpawnEggEvent; import com.willfp.ecobosses.events.EcoBossSpawnTotemEvent; import org.bukkit.Material; diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/SpawnTotem.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/SpawnTotem.java deleted file mode 100644 index fa0ca3b..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/bosses/util/obj/SpawnTotem.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.willfp.ecobosses.bosses.util.obj; - -import lombok.Data; -import org.bukkit.Material; - -public record SpawnTotem(Material bottom, - Material middle, - Material top) { -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandEcobosses.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandEcobosses.java deleted file mode 100644 index d555776..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandEcobosses.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.willfp.ecobosses.commands; - -import com.willfp.eco.core.command.impl.PluginCommand; -import com.willfp.ecobosses.EcoBossesPlugin; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class CommandEcobosses extends PluginCommand { - /** - * Instantiate a new executor for /ebdrop. - * - * @param plugin The plugin to manage the execution for. - */ - public CommandEcobosses(@NotNull final EcoBossesPlugin plugin) { - super(plugin, "ecobosses", "ecobosses.command.ecobosses", false); - this.addSubcommand(new CommandReload(plugin)) - .addSubcommand(new CommandKillall(plugin)) - .addSubcommand(new CommandSpawn(plugin)) - .addSubcommand(new CommandGive(plugin)); - } - - @Override - public void onExecute(@NotNull final CommandSender sender, - @NotNull final List args) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-command")); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandGive.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandGive.java deleted file mode 100644 index 766a965..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandGive.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.willfp.ecobosses.commands; - - -import com.willfp.eco.core.EcoPlugin; -import com.willfp.eco.core.command.impl.Subcommand; -import com.willfp.eco.core.config.updating.ConfigUpdater; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.EcoBosses; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public class CommandGive extends Subcommand { - /** - * The cached names. - */ - private static final List BOSS_NAMES = new ArrayList<>(); - - /** - * The cached numbers. - */ - private static final List NUMBERS = Arrays.asList( - "1", - "2", - "3", - "4", - "5", - "10", - "32", - "64" - ); - - /** - * Instantiate a new command handler. - * - * @param plugin The plugin for the commands to listen for. - */ - public CommandGive(@NotNull final EcoPlugin plugin) { - super(plugin, "give", "ecobosses.command.give", false); - } - - /** - * Called on reload. - */ - @ConfigUpdater - public static void reload() { - BOSS_NAMES.clear(); - BOSS_NAMES.addAll(EcoBosses.values().stream() - .filter(boss -> boss.getSpawnEgg() != null) - .map(EcoBoss::getId) - .collect(Collectors.toList())); - } - - @Override - public void onExecute(@NotNull final CommandSender sender, - @NotNull final List args) { - if (args.isEmpty()) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("needs-player")); - return; - } - - if (args.size() == 1) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("needs-boss")); - return; - } - - int amount = 1; - - if (args.size() > 2) { - try { - amount = Integer.parseInt(args.get(2)); - } catch (NumberFormatException ignored) { - // do nothing - } - } - - String recieverName = args.get(0); - Player reciever = Bukkit.getPlayer(recieverName); - - if (reciever == null) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-player")); - return; - } - - String key = args.get(1); - - EcoBoss boss = EcoBosses.getByName(key); - - if (boss == null || boss.getSpawnEgg() == null) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-boss")); - return; - } - - String message = this.getPlugin().getLangYml().getMessage("give-success"); - message = message.replace("%boss%", boss.getId()).replace("%recipient%", reciever.getName()); - sender.sendMessage(message); - - ItemStack itemStack = boss.getSpawnEgg(); - itemStack.setAmount(amount); - reciever.getInventory().addItem(itemStack); - } - - @Override - public List tabComplete(@NotNull final CommandSender sender, - @NotNull final List args) { - List completions = new ArrayList<>(); - - if (args.isEmpty()) { - // Currently, this case is not ever reached - return BOSS_NAMES; - } - - if (args.size() == 1) { - StringUtil.copyPartialMatches(args.get(0), Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()), completions); - return completions; - } - - if (args.size() == 2) { - StringUtil.copyPartialMatches(args.get(1), BOSS_NAMES, completions); - - Collections.sort(completions); - return completions; - } - - if (args.size() == 3) { - StringUtil.copyPartialMatches(args.get(2), NUMBERS, completions); - - completions.sort((s1, s2) -> { - int t1 = Integer.parseInt(s1); - int t2 = Integer.parseInt(s2); - return t1 - t2; - }); - - return completions; - } - - return new ArrayList<>(0); - } -} \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandKillall.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandKillall.java deleted file mode 100644 index 77abb5c..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandKillall.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.willfp.ecobosses.commands; - -import com.willfp.eco.core.command.impl.Subcommand; -import com.willfp.ecobosses.EcoBossesPlugin; -import com.willfp.ecobosses.bosses.util.BossUtils; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class CommandKillall extends Subcommand { - /** - * Instantiate a new executor for /ebspawn. - * - * @param plugin The plugin to manage the execution for. - */ - public CommandKillall(@NotNull final EcoBossesPlugin plugin) { - super(plugin, "killall", "ecobosses.command.killall", false); - } - - @Override - public void onExecute(@NotNull final CommandSender sender, - @NotNull final List args) { - boolean force = false; - if (args.size() == 1) { - force = args.get(0).equalsIgnoreCase("force"); - } - - sender.sendMessage(this.getPlugin().getLangYml().getMessage("killall").replace("%amount%", String.valueOf(BossUtils.killAllBosses(force)))); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandReload.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandReload.java deleted file mode 100644 index 914498e..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandReload.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.willfp.ecobosses.commands; - -import com.willfp.eco.core.command.impl.Subcommand; -import com.willfp.ecobosses.EcoBossesPlugin; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public class CommandReload extends Subcommand { - /** - * Instantiate a new executor for /ebreload. - * - * @param plugin The plugin to manage the execution for. - */ - public CommandReload(@NotNull final EcoBossesPlugin plugin) { - super(plugin, "reload", "ecobosses.command.reload", false); - } - - @Override - public void onExecute(@NotNull final CommandSender sender, - @NotNull final List args) { - this.getPlugin().reload(); - this.getPlugin().reload(); - sender.sendMessage(this.getPlugin().getLangYml().getMessage("reloaded")); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandSpawn.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandSpawn.java deleted file mode 100644 index 8594ccf..0000000 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/commands/CommandSpawn.java +++ /dev/null @@ -1,206 +0,0 @@ -package com.willfp.ecobosses.commands; - -import com.willfp.eco.core.command.impl.Subcommand; -import com.willfp.eco.core.config.updating.ConfigUpdater; -import com.willfp.ecobosses.EcoBossesPlugin; -import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.EcoBosses; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -public class CommandSpawn extends Subcommand { - /** - * The cached names. - */ - private static final List BOSS_NAMES = new ArrayList<>(); - - /** - * The cached numbers. - */ - private static final List TILDE = Arrays.asList( - "~" - ); - - /** - * Instantiate a new executor for /ebspawn. - * - * @param plugin The plugin to manage the execution for. - */ - public CommandSpawn(@NotNull final EcoBossesPlugin plugin) { - super(plugin, "spawn", "ecobosses.command.spawn", false); - reload(); - } - - /** - * Called on reload. - */ - @ConfigUpdater - public static void reload() { - BOSS_NAMES.clear(); - BOSS_NAMES.addAll(EcoBosses.values().stream().map(EcoBoss::getId).collect(Collectors.toList())); - } - - @Override - public void onExecute(@NotNull final CommandSender sender, - @NotNull final List args) { - if (args.isEmpty()) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("specify-boss")); - return; - } - - String bossName = args.get(0); - - EcoBoss boss = EcoBosses.getByName(bossName.toLowerCase()); - - if (boss == null) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("specify-boss")); - return; - } - - Location location = null; - - if (sender instanceof Player) { - location = ((Player) sender).getLocation(); - } - - if (args.size() >= 4) { - String xString = args.get(1); - String yString = args.get(2); - String zString = args.get(3); - - double xPos; - double yPos; - double zPos; - - if (xString.startsWith("~") && sender instanceof Player) { - String xDiff = xString.replace("~", ""); - String yDiff = yString.replace("~", ""); - String zDiff = zString.replace("~", ""); - - if (xDiff.isEmpty()) { - xPos = ((Player) sender).getLocation().getX(); - } else { - try { - xPos = ((Player) sender).getLocation().getX() + Double.parseDouble(xDiff); - } catch (NumberFormatException e) { - xPos = ((Player) sender).getLocation().getX(); - } - } - - if (yDiff.isEmpty()) { - yPos = ((Player) sender).getLocation().getY(); - } else { - try { - yPos = ((Player) sender).getLocation().getY() + Double.parseDouble(yDiff); - } catch (NumberFormatException e) { - yPos = ((Player) sender).getLocation().getY(); - } - } - - if (zDiff.isEmpty()) { - zPos = ((Player) sender).getLocation().getZ(); - } else { - try { - zPos = ((Player) sender).getLocation().getZ() + Double.parseDouble(yDiff); - } catch (NumberFormatException e) { - zPos = ((Player) sender).getLocation().getZ(); - } - } - } else { - try { - xPos = Double.parseDouble(xString); - yPos = Double.parseDouble(yString); - zPos = Double.parseDouble(zString); - } catch (NumberFormatException e) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-location")); - return; - } - } - - location = new Location(null, xPos, yPos, zPos); - } - - World world = null; - if (sender instanceof Player) { - world = ((Player) sender).getWorld(); - } - - if (args.size() >= 5) { - world = Bukkit.getWorld(args.get(4)); - } - - if (location == null) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-location")); - return; - } - - location.setWorld(world); - - if (world == null) { - sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-world")); - return; - } - - boss.spawn(location); - sender.sendMessage(this.getPlugin().getLangYml().getMessage("spawned")); - } - - @Override - public List tabComplete(@NotNull final CommandSender sender, - @NotNull final List args) { - List completions = new ArrayList<>(); - - if (args.isEmpty()) { - // Currently, this case is not ever reached - return new ArrayList<>(); - } - - if (args.size() == 1) { - StringUtil.copyPartialMatches(args.get(0), BOSS_NAMES, completions); - - Collections.sort(completions); - return completions; - } - - if (args.size() == 2) { - StringUtil.copyPartialMatches(args.get(1), TILDE, completions); - - Collections.sort(completions); - return completions; - } - - if (args.size() == 3) { - StringUtil.copyPartialMatches(args.get(2), TILDE, completions); - - Collections.sort(completions); - return completions; - } - - if (args.size() == 4) { - StringUtil.copyPartialMatches(args.get(3), TILDE, completions); - - Collections.sort(completions); - return completions; - } - - if (args.size() == 5) { - StringUtil.copyPartialMatches(args.get(4), Bukkit.getWorlds().stream().map(World::getName).collect(Collectors.toList()), completions); - - Collections.sort(completions); - return completions; - } - - return new ArrayList<>(0); - } -} diff --git a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/events/EcoBossSpawnTotemEvent.java b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/events/EcoBossSpawnTotemEvent.java index decdb15..67b494b 100644 --- a/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/events/EcoBossSpawnTotemEvent.java +++ b/eco-core/core-plugin/src/main/java/com/willfp/ecobosses/events/EcoBossSpawnTotemEvent.java @@ -1,7 +1,6 @@ package com.willfp.ecobosses.events; import com.willfp.ecobosses.bosses.EcoBoss; -import com.willfp.ecobosses.bosses.util.obj.SpawnTotem; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.HandlerList; diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/EcoBossesPlugin.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/EcoBossesPlugin.kt index b178055..5efe960 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/EcoBossesPlugin.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/EcoBossesPlugin.kt @@ -11,8 +11,10 @@ import com.willfp.ecobosses.defence.ImmunitiesHandler 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.LifecycleHandlers import com.willfp.ecobosses.spawn.SpawnEggHandler +import com.willfp.ecobosses.spawn.SpawnTotemHandler import com.willfp.ecobosses.util.DiscoverRecipeListener import com.willfp.ecobosses.util.TopDamagerListener import com.willfp.libreforge.LibReforgePlugin @@ -46,7 +48,9 @@ class EcoBossesPlugin : LibReforgePlugin(525, 10635, "&9") { DamageMultiplierHandler(), MountHandler(), PickupHandler(), - ImmunitiesHandler() + ImmunitiesHandler(), + CompatibilityListeners(), + SpawnTotemHandler() ) } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossUtils.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossUtils.kt index 7592443..58670c3 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossUtils.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/BossUtils.kt @@ -12,12 +12,14 @@ val Player.bossHolders: Iterable val holders = mutableListOf() for (boss in Bosses.values()) { - for (entity in boss.getAllAlive()) { + for (livingBoss in boss.getAllAlive()) { + val entity = livingBoss.entity ?: continue + if (entity.world != this.world) { continue } - if (entity.location.distanceSquared(this.location) <= boss.influenceRadius.pow(2)) { + if (entity.location.distanceSquared(this.location) <= boss.influence.pow(2)) { holders.add(boss) } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/Bosses.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/Bosses.kt index 5b7519d..5390e53 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/Bosses.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/Bosses.kt @@ -84,8 +84,8 @@ object Bosses { * @return All living bosses. */ @JvmStatic - fun getAllAlive(): Set { - val entities = mutableSetOf() + fun getAllAlive(): Set { + val entities = mutableSetOf() for (boss in values()) { entities.addAll(boss.getAllAlive()) 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 078002a..9d9565b 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,19 +4,25 @@ 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.CustomItem import com.willfp.eco.core.items.Items +import com.willfp.eco.core.recipe.Recipes +import com.willfp.eco.core.recipe.recipes.CraftingRecipe 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.libreforge.Holder @@ -25,9 +31,10 @@ import com.willfp.libreforge.effects.Effects import net.kyori.adventure.bossbar.BossBar import org.bukkit.Bukkit import org.bukkit.Location +import org.bukkit.Material import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player -import org.bukkit.event.entity.EntityDeathEvent +import org.bukkit.inventory.ItemStack import java.util.Objects import java.util.UUID @@ -41,7 +48,7 @@ class EcoBoss( val lifespan = config.getInt("lifespan") - val influenceRadius = config.getDouble("influenceRadius") + val influence = config.getDouble("influence") val targetRange = config.getDouble("target.range") @@ -65,6 +72,74 @@ class EcoBoss( val projectileDamageMultiplier = config.getDouble("defence.projectileDamageMultiplier") + val canTeleport = config.getBool("defence.teleportation.enabled") + + val teleportRange = config.getInt("defence.teleportation.range") + + val teleportInterval = config.getInt("defence.teleportation.interval") + + private val spawnEggBacker: ItemStack? = run { + val enabled = config.getBool("spawn.egg.enabled") + if (!enabled) { + return@run null + } + + val item = Items.lookup("spawn.egg.item").item.apply { + bossEgg = this@EcoBoss + } + + val key = plugin.namespacedKeyFactory.create("${this.id}_spawn_egg") + + Items.registerCustomItem( + key, + CustomItem( + key, + { it.bossEgg == this }, + item + ) + ) + + item + } + + val spawnEgg: ItemStack? + get() = this.spawnEggBacker?.clone() + + val recipe: CraftingRecipe? = run { + if (spawnEggBacker == null || !config.getBool("spawn.egg.craftable")) { + return@run null + } + + val recipe = Recipes.createAndRegisterRecipe( + this@EcoBoss.plugin, + "${this.id}_spawn_egg", + spawnEggBacker, + config.getStrings("spawn.egg.recipe") + ) + + recipe + } + + val totem: SpawnTotem? = run { + if (!config.getBool("spawn.totem.enabled")) { + return@run null + } + + SpawnTotem( + Material.getMaterial(config.getString("config.totem.top")) ?: return@run null, + Material.getMaterial(config.getString("config.totem.middle")) ?: return@run null, + Material.getMaterial(config.getString("config.totem.bottom")) ?: return@run null + ) + } + + val disabledTotemWorlds: List = config.getStrings("config.totem.notInWorlds") + + val autoSpawnInterval = config.getInt("spawn.autospawn.interval") + + val autoSpawnLocations: List = run { + + } + private val bossBarColor = BossBar.Color.valueOf(config.getString("bossBar.color").uppercase()) private val bossBarStyle = BossBar.Overlay.valueOf(config.getString("bossBar.style").uppercase()) @@ -176,8 +251,8 @@ class EcoBoss( return currentlyAlive[entity.uniqueId] } - fun getAllAlive(): Set { - return currentlyAlive.values.mapNotNull { it.entity }.toSet() + fun getAllAlive(): Set { + return currentlyAlive.values.toSet() } fun spawn(location: Location) { @@ -186,15 +261,16 @@ class EcoBoss( plugin, mob.uniqueId, this, - createTickersFor(mob) + createTickers() ) } - private fun createTickersFor(entity: LivingEntity): Set { + private fun createTickers(): Set { val tickers = mutableSetOf( LifespanTicker(), DisplayNameTicker(), - TargetTicker() + TargetTicker(), + TeleportHandler() ) if (isBossBarEnabled) { @@ -213,17 +289,21 @@ class EcoBoss( return tickers } - fun handleLifecycle(lifecycle: BossLifecycle, location: Location) { + fun handleLifecycle(lifecycle: BossLifecycle, location: Location, entity: LivingEntity?) { sounds[lifecycle]?.play(location) - messages[lifecycle]?.forEach { it.broadcast(location) } + messages[lifecycle]?.forEach { it.broadcast(location, entity?.topDamagers ?: emptyList()) } } - fun processRewards(player: Player?, location: Location, entity: LivingEntity, event: EntityDeathEvent) { + fun processRewards(event: BossKillEvent) { + val entity = event.boss.entity ?: return + val location = entity.location + val player = event.killer + for (drop in drops) { drop.drop(location, player) } - xp.modify(event) + xp.modify(event.event) for ((index, damager) in entity.topDamagers.withIndex()) { val rewards = commandRewards[index] ?: continue diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/LivingEcoBoss.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/LivingEcoBoss.kt index ed1582e..6bd1810 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/LivingEcoBoss.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/bosses/LivingEcoBoss.kt @@ -1,7 +1,6 @@ package com.willfp.ecobosses.bosses import com.willfp.eco.core.EcoPlugin -import com.willfp.ecobosses.lifecycle.BossLifecycle import com.willfp.ecobosses.tick.BossTicker import org.bukkit.Bukkit import org.bukkit.entity.Mob @@ -13,13 +12,11 @@ class LivingEcoBoss( val boss: EcoBoss, val tickers: Set ) { - init { - plugin.runnableFactory.create { - if (tick()) { - it.cancel() - } + private val ticker = plugin.runnableFactory.create { + if (tick()) { + it.cancel() } - } + }.apply { runTaskTimer(1, 1) } val entity: Mob? get() = Bukkit.getEntity(uuid) as? Mob @@ -30,10 +27,7 @@ class LivingEcoBoss( private fun tick(): Boolean { if (entity == null || entity?.isDead == true) { - for (ticker in tickers) { - ticker.onDeath(this, currentTick) - } - boss.markDead(uuid) + remove() return true } @@ -44,12 +38,11 @@ class LivingEcoBoss( return false } - fun kill(reason: BossLifecycle) { - if (reason == BossLifecycle.SPAWN) { - throw IllegalArgumentException("Spawn is not a death lifecycle!") - } - + fun remove() { + ticker.cancel() entity?.remove() + tickers.forEach { it.onDeath(this, currentTick) } + boss.markDead(uuid) } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandEcobosses.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandEcobosses.kt new file mode 100644 index 0000000..4d4c334 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandEcobosses.kt @@ -0,0 +1,26 @@ +package com.willfp.ecobosses.commands + +import com.willfp.eco.core.command.impl.PluginCommand +import com.willfp.ecobosses.EcoBossesPlugin +import org.bukkit.command.CommandSender + +class CommandEcobosses(plugin: EcoBossesPlugin) : PluginCommand( + plugin, + "ecobosses", + "ecobosses.command.ecobosses", + false +) { + override fun onExecute( + sender: CommandSender, + args: List + ) { + sender.sendMessage(plugin.langYml.getMessage("invalid-command")) + } + + init { + addSubcommand(CommandReload(plugin)) + .addSubcommand(CommandKillall(plugin)) + .addSubcommand(CommandSpawn(plugin)) + .addSubcommand(CommandGive(plugin)) + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandGive.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandGive.kt new file mode 100644 index 0000000..891dcaa --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandGive.kt @@ -0,0 +1,115 @@ +package com.willfp.ecobosses.commands + +import com.willfp.eco.core.EcoPlugin +import com.willfp.eco.core.command.impl.Subcommand +import com.willfp.ecobosses.bosses.Bosses +import com.willfp.ecobosses.bosses.EcoBosses +import org.bukkit.Bukkit +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.util.StringUtil +import java.util.stream.Collectors + +class CommandGive(plugin: EcoPlugin) : Subcommand( + plugin, + "give", + "ecobosses.command.give", + false +) { + override fun onExecute( + sender: CommandSender, + args: List + ) { + if (args.isEmpty()) { + sender.sendMessage(plugin.langYml.getMessage("needs-player")) + return + } + if (args.size == 1) { + sender.sendMessage(plugin.langYml.getMessage("needs-boss")) + return + } + var amount = 1 + if (args.size > 2) { + amount = args[2].toIntOrNull() ?: amount + } + + val recieverName = args[0] + val reciever = Bukkit.getPlayer(recieverName) + if (reciever == null) { + sender.sendMessage(plugin.langYml.getMessage("invalid-player")) + return + } + val key = args[1] + val boss = EcoBosses.getByName(key) + + if (boss?.spawnEgg == null) { + sender.sendMessage(plugin.langYml.getMessage("invalid-boss")) + return + } + + var message = plugin.langYml.getMessage("give-success") + message = message.replace("%boss%", boss.id).replace("%recipient%", reciever.name) + sender.sendMessage(message) + + val itemStack = boss.spawnEgg!! + + itemStack.amount = amount + reciever.inventory.addItem(itemStack) + } + + override fun tabComplete( + sender: CommandSender, + args: List + ): List { + val completions = mutableListOf() + if (args.isEmpty()) { + return BOSS_NAMES + } + + if (args.size == 1) { + StringUtil.copyPartialMatches(args[0], Bukkit.getOnlinePlayers().stream().map { obj: Player -> obj.name } + .collect(Collectors.toList()), completions) + return completions + } + + if (args.size == 2) { + StringUtil.copyPartialMatches(args[1], BOSS_NAMES, completions) + completions.sort() + return completions + } + + if (args.size == 3) { + StringUtil.copyPartialMatches(args[2], NUMBERS, completions) + completions.sortWith { s1: String, s2: String -> + val t1 = s1.toInt() + val t2 = s2.toInt() + t1 - t2 + } + return completions + } + return ArrayList(0) + } + + companion object { + /** + * The cached names. + */ + private val BOSS_NAMES: List + get() = Bosses.values().map { it.id } + + + /** + * The cached numbers. + */ + private val NUMBERS = listOf( + "1", + "2", + "3", + "4", + "5", + "10", + "32", + "64" + ) + } +} \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandKillall.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandKillall.kt new file mode 100644 index 0000000..9e5077c --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandKillall.kt @@ -0,0 +1,28 @@ +package com.willfp.ecobosses.commands + +import com.willfp.eco.core.command.impl.Subcommand +import com.willfp.ecobosses.EcoBossesPlugin +import com.willfp.ecobosses.bosses.Bosses +import org.bukkit.command.CommandSender + +class CommandKillall(plugin: EcoBossesPlugin) : Subcommand( + plugin, + "killall", + "ecobosses.command.killall", + false +) { + override fun onExecute( + sender: CommandSender, + args: List + ) { + val alive = Bosses.getAllAlive() + + for (boss in alive) { + boss.remove() + } + + sender.sendMessage( + plugin.langYml.getMessage("killall").replace("%amount%", alive.size.toString()) + ) + } +} \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandReload.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandReload.kt new file mode 100644 index 0000000..5bcd3e5 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandReload.kt @@ -0,0 +1,20 @@ +package com.willfp.ecobosses.commands + +import com.willfp.eco.core.command.impl.Subcommand +import com.willfp.ecobosses.EcoBossesPlugin +import org.bukkit.command.CommandSender + +class CommandReload(plugin: EcoBossesPlugin) : Subcommand( + plugin, + "reload", + "ecobosses.command.reload", + false +) { + override fun onExecute( + sender: CommandSender, + args: List + ) { + plugin.reload() + sender.sendMessage(plugin.langYml.getMessage("reloaded")) + } +} \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandSpawn.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandSpawn.kt new file mode 100644 index 0000000..9bd09b7 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/commands/CommandSpawn.kt @@ -0,0 +1,178 @@ +package com.willfp.ecobosses.commands + +import com.willfp.eco.core.command.impl.Subcommand +import com.willfp.ecobosses.EcoBossesPlugin +import com.willfp.ecobosses.bosses.Bosses +import com.willfp.ecobosses.bosses.EcoBosses +import com.willfp.ecobosses.events.BossSpawnEvent +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.World +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player +import org.bukkit.util.StringUtil + +class CommandSpawn(plugin: EcoBossesPlugin) : Subcommand( + plugin, + "spawn", + "ecobosses.command.spawn", + false +) { + override fun onExecute( + sender: CommandSender, + args: List + ) { + if (args.isEmpty()) { + sender.sendMessage(plugin.langYml.getMessage("specify-boss")) + return + } + + val bossName = args[0] + val boss = EcoBosses.getByName(bossName.lowercase()) + if (boss == null) { + sender.sendMessage(plugin.langYml.getMessage("specify-boss")) + return + } + + var location: Location? = null + if (sender is Player) { + location = sender.location + } + + if (args.size >= 4) { + val xString = args[1] + val yString = args[2] + val zString = args[3] + val xPos: Double + val yPos: Double + val zPos: Double + if (xString.startsWith("~") && sender is Player) { + val xDiff = xString.replace("~", "") + val yDiff = yString.replace("~", "") + val zDiff = zString.replace("~", "") + xPos = if (xDiff.isEmpty()) { + sender.location.x + } else { + try { + sender.location.x + xDiff.toDouble() + } catch (e: NumberFormatException) { + sender.location.x + } + } + yPos = if (yDiff.isEmpty()) { + sender.location.y + } else { + try { + sender.location.y + yDiff.toDouble() + } catch (e: NumberFormatException) { + sender.location.y + } + } + zPos = if (zDiff.isEmpty()) { + sender.location.z + } else { + try { + sender.location.z + yDiff.toDouble() + } catch (e: NumberFormatException) { + sender.location.z + } + } + } else { + try { + xPos = xString.toDouble() + yPos = yString.toDouble() + zPos = zString.toDouble() + } catch (e: NumberFormatException) { + sender.sendMessage(plugin.langYml.getMessage("invalid-location")) + return + } + } + location = Location(null, xPos, yPos, zPos) + } + var world: World? = null + if (sender is Player) { + world = sender.world + } + if (args.size >= 5) { + world = Bukkit.getWorld(args[4]) + } + if (location == null) { + sender.sendMessage(plugin.langYml.getMessage("invalid-location")) + return + } + + location.world = world + + if (world == null) { + sender.sendMessage(plugin.langYml.getMessage("invalid-world")) + return + } + + val event = BossSpawnEvent( + boss, + location, + BossSpawnEvent.SpawnReason.COMMAND + ) + + Bukkit.getPluginManager().callEvent(event) + + if (!event.isCancelled) { + boss.spawn(location) + } + + sender.sendMessage(plugin.langYml.getMessage("spawned")) + } + + override fun tabComplete( + sender: CommandSender, + args: List + ): List { + val completions = mutableListOf() + + if (args.isEmpty()) { + return emptyList() + } + + if (args.size == 1) { + StringUtil.copyPartialMatches(args[0], BOSS_NAMES, completions) + completions.sort() + return completions + } + if (args.size == 2) { + StringUtil.copyPartialMatches(args[1], TILDE, completions) + completions.sort() + return completions + } + if (args.size == 3) { + StringUtil.copyPartialMatches(args[2], TILDE, completions) + completions.sort() + return completions + } + if (args.size == 4) { + StringUtil.copyPartialMatches(args[3], TILDE, completions) + completions.sort() + return completions + } + if (args.size == 5) { + StringUtil.copyPartialMatches(args[4], Bukkit.getWorlds().map { it.name }, completions) + completions.sort() + return completions + } + return ArrayList(0) + } + + companion object { + /** + * The cached names. + */ + private val BOSS_NAMES: List + get() = Bosses.values().map { it.id } + + /** + * The cached numbers. + */ + private val TILDE = listOf( + "~" + ) + } +} \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/defence/DamageMultiplierHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/defence/DamageMultiplierHandler.kt index 20043f0..944a18d 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/defence/DamageMultiplierHandler.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/defence/DamageMultiplierHandler.kt @@ -18,10 +18,18 @@ class DamageMultiplierHandler : Listener { if (event.damager is Player) { event.damage *= boss.meleeDamageMultiplier + + if (boss.meleeDamageMultiplier == 0.0) { + event.isCancelled = true + } } if (event.damager is Projectile) { event.damage *= boss.projectileDamageMultiplier + + if (boss.projectileDamageMultiplier == 0.0) { + event.isCancelled = true + } } } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossDeathEvent.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossDeathEvent.kt index 5335b82..5ad1baa 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossDeathEvent.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossDeathEvent.kt @@ -4,9 +4,10 @@ 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, + val boss: LivingEcoBoss ) : Event() { override fun getHandlers(): HandlerList { return HANDLERS diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossKillEvent.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossKillEvent.kt index bdff221..62cf2d8 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossKillEvent.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/events/BossKillEvent.kt @@ -4,10 +4,12 @@ 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 class BossKillEvent( boss: LivingEcoBoss, - killer: Player? + val killer: Player?, + val event: EntityDeathEvent ) : BossDeathEvent(boss) { override fun getHandlers(): HandlerList { return HANDLERS diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/BossLifecycle.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/BossLifecycle.kt index 6291f4f..cb419fe 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/BossLifecycle.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/BossLifecycle.kt @@ -1,8 +1,10 @@ package com.willfp.ecobosses.lifecycle -enum class BossLifecycle { - SPAWN, - KILL, - DESPAWN, - INJURE +enum class BossLifecycle( + val isDeath: Boolean +) { + SPAWN(false), + KILL(true), + DESPAWN(true), + INJURE(false) } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/CompatibilityListeners.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/CompatibilityListeners.kt new file mode 100644 index 0000000..b69e2d9 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/CompatibilityListeners.kt @@ -0,0 +1,16 @@ +package com.willfp.ecobosses.lifecycle + +import com.willfp.ecobosses.bosses.Bosses +import org.bukkit.entity.LivingEntity +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +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 + } + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/DeathListeners.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/DeathListeners.kt index 6807415..5e66a80 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/DeathListeners.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/DeathListeners.kt @@ -9,16 +9,16 @@ import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.entity.EntityDeathEvent -class DeathListeners: Listener { +class DeathListeners : Listener { @EventHandler( ignoreCancelled = true ) fun handle(event: EntityDeathByEntityEvent) { val boss = Bosses[event.victim] ?: return - boss.kill(BossLifecycle.KILL) + boss.remove(BossLifecycle.KILL) - val deathEvent = BossKillEvent(boss, event.killer.tryAsPlayer()) + val deathEvent = BossKillEvent(boss, event.killer.tryAsPlayer(), event.deathEvent) Bukkit.getPluginManager().callEvent(deathEvent) } @@ -28,9 +28,16 @@ class DeathListeners: Listener { fun handle(event: EntityDeathEvent) { val boss = Bosses[event.entity] ?: return - boss.kill(BossLifecycle.KILL) + boss.remove(BossLifecycle.KILL) - val deathEvent = BossKillEvent(boss, null) + val deathEvent = BossKillEvent(boss, null, event) Bukkit.getPluginManager().callEvent(deathEvent) } + + @EventHandler( + ignoreCancelled = true + ) + fun handle(event: BossKillEvent) { + event.boss.boss.processRewards(event) + } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/LifecycleHandlers.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/LifecycleHandlers.kt index 9f51266..58a3e6c 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/LifecycleHandlers.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/lifecycle/LifecycleHandlers.kt @@ -18,7 +18,7 @@ class LifecycleHandlers : Listener { val entity = event.entity as? LivingEntity ?: return val boss = Bosses[entity] ?: return - boss.boss.handleLifecycle(BossLifecycle.INJURE, entity.location) + boss.boss.handleLifecycle(BossLifecycle.INJURE, entity.location, entity) } @EventHandler( @@ -26,7 +26,9 @@ class LifecycleHandlers : Listener { priority = EventPriority.MONITOR ) fun onInjure(event: BossDeathEvent) { - event.boss.boss.handleLifecycle(event.lifecycle, event.boss.entity?.location ?: return) + val entity = event.boss.entity ?: return + + event.boss.boss.handleLifecycle(event.lifecycle, entity.location, entity) } @EventHandler( @@ -34,6 +36,6 @@ class LifecycleHandlers : Listener { priority = EventPriority.MONITOR ) fun onInjure(event: BossSpawnEvent) { - event.boss.handleLifecycle(BossLifecycle.SPAWN, event.location) + event.boss.handleLifecycle(BossLifecycle.SPAWN, event.location, null) } } \ No newline at end of file diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnTotemHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnTotemHandler.kt new file mode 100644 index 0000000..dcbb908 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/spawn/SpawnTotemHandler.kt @@ -0,0 +1,64 @@ +package com.willfp.ecobosses.spawn + +import com.willfp.eco.util.containsIgnoreCase +import com.willfp.ecobosses.bosses.EcoBosses +import com.willfp.ecobosses.events.BossSpawnEvent +import com.willfp.ecobosses.util.SpawnTotem +import org.bukkit.Material +import org.bukkit.block.Block +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.block.BlockPlaceEvent + +class SpawnTotemHandler : Listener { + @EventHandler( + ignoreCancelled = true + ) + fun handle(event: BlockPlaceEvent) { + for (i in 0..2) { + lateinit var block1: Block + lateinit var block2: Block + lateinit var block3: 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) + } + 1 -> { + block1 = event.block + block2 = event.block.getRelative(0, 1, 0) + block3 = event.block.getRelative(0, 2, 0) + } + 2 -> { + block2 = event.block + block1 = event.block.getRelative(0, -1, 0) + block3 = event.block.getRelative(0, 1, 0) + } + } + + val placedTotem = SpawnTotem(block1.type, block2.type, block3.type) + for (boss in EcoBosses.values()) { + if (boss.totem == null || boss.disabledTotemWorlds.containsIgnoreCase(event.block.world.name)) { + continue + } + + if (boss.totem != placedTotem) { + continue + } + + val spawnEvent = BossSpawnEvent(boss, event.block.location, BossSpawnEvent.SpawnReason.TOTEM) + + if (!spawnEvent.isCancelled) { + block1.type = Material.AIR + block2.type = Material.AIR + block3.type = Material.AIR + + boss.spawn(event.block.location.add(0.0, 1.5, 0.0)) + } + } + } + } +} diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/LifespanTicker.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/LifespanTicker.kt index 3cac9e1..dfa9e3a 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/LifespanTicker.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/LifespanTicker.kt @@ -8,7 +8,7 @@ class LifespanTicker : BossTicker { val timeLeft = (boss.deathTime - System.currentTimeMillis()) / 1000.0 if (timeLeft <= 0) { - boss.kill(BossLifecycle.DESPAWN) + boss.remove(BossLifecycle.DESPAWN) } } } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/TeleportHandler.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/TeleportHandler.kt new file mode 100644 index 0000000..c4ae83c --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/tick/TeleportHandler.kt @@ -0,0 +1,49 @@ +package com.willfp.ecobosses.tick + +import com.willfp.ecobosses.bosses.LivingEcoBoss +import org.bukkit.Location +import org.bukkit.Material +import org.bukkit.block.BlockFace + +class TeleportHandler : BossTicker { + override fun tick(boss: LivingEcoBoss, tick: Int) { + val entity = boss.entity ?: return + if (!boss.boss.canTeleport) { + return + } + + if (tick % boss.boss.teleportInterval != 0) { + return + } + + val range = boss.boss.teleportRange + + val validLocations = mutableListOf() + + for (x in -range..range) { + for (y in -range..range) { + for (z in -range..range) { + val location = entity.location.clone().apply { + this.x += x + this.y += y + this.z += z + } + val block = location.block + + if (block.type == Material.AIR && block.getRelative(BlockFace.UP).type == Material.AIR && !(block.getRelative( + BlockFace.DOWN + ).isLiquid || block.getRelative(BlockFace.DOWN).type == Material.AIR) + ) { + validLocations.add(location) + } + } + } + } + + if (validLocations.isEmpty()) { + return + } + + entity.teleport(validLocations.random()) + } +} 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 index f518abf..59961ba 100644 --- 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 @@ -1,6 +1,8 @@ package com.willfp.ecobosses.util import com.willfp.eco.core.config.interfaces.Config +import com.willfp.eco.util.formatEco +import com.willfp.eco.util.savedDisplayName import org.bukkit.Bukkit import org.bukkit.Location import org.bukkit.entity.Player @@ -9,23 +11,34 @@ data class LocalBroadcast( val messages: Iterable, val radius: Double ) { - fun broadcast(location: Location) { + fun broadcast(location: Location, topDamagers: List) { + val toBroadcast = messages.toMutableList() + toBroadcast.replaceAll { + var message = it + for ((index, damager) in topDamagers.withIndex()) { + message = message.replace("%damage_${index + 1}%", damager.damage.toString()) + .replace("%damage_${index + 1}_player%", Bukkit.getOfflinePlayer(damager.uuid).savedDisplayName) + } + + message.formatEco() + } + if (radius < 0) { - for (message in messages) { + for (message in toBroadcast) { Bukkit.broadcastMessage(message) } } else { val world = location.world ?: return world.getNearbyEntities(location, radius, radius, radius) .filterIsInstance() - .forEach { player -> messages.forEach { player.sendMessage(it) } } + .forEach { player -> toBroadcast.forEach { player.sendMessage(it) } } } } companion object { fun fromConfig(config: Config): LocalBroadcast { return LocalBroadcast( - config.getFormattedStrings("message"), + config.getStrings("message"), config.getDouble("radius") ) } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/SpawnTotem.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/SpawnTotem.kt new file mode 100644 index 0000000..47422f0 --- /dev/null +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobosses/util/SpawnTotem.kt @@ -0,0 +1,9 @@ +package com.willfp.ecobosses.util + +import org.bukkit.Material + +data class SpawnTotem( + val top: Material, + val middle: Material, + val bottom: Material +) diff --git a/eco-core/core-plugin/src/main/resources/bosses/steel_golem.yml b/eco-core/core-plugin/src/main/resources/bosses/steel_golem.yml index 631c162..76dd6b0 100644 --- a/eco-core/core-plugin/src/main/resources/bosses/steel_golem.yml +++ b/eco-core/core-plugin/src/main/resources/bosses/steel_golem.yml @@ -1,7 +1,7 @@ enabled: true name: "&8Steel Golem &7| &c%health%♥ &7| &e%time%" # Display name -base-mob: iron_golem +base-mob: iron_golem attack-damage:90 movement-speed:1.5 follow-range:16 health:1200 baby: false # If set to true: will make the boss mob baby (if possible) bossbar: diff --git a/eco-core/core-plugin/src/main/resources/ecobosses.yml b/eco-core/core-plugin/src/main/resources/ecobosses.yml index 51662ed..8633c06 100644 --- a/eco-core/core-plugin/src/main/resources/ecobosses.yml +++ b/eco-core/core-plugin/src/main/resources/ecobosses.yml @@ -20,8 +20,9 @@ chains: bosses: - id: steel_golem - mob: iron_golem + mob: iron_golem attack-damage:90 movement-speed:1.5 follow-range:16 health:1200 displayName: "&8Steel Golem &7| &c%health%♥ &7| &e%time%" + influence: 40 effects: [ ] defence: preventMounts: true @@ -32,18 +33,23 @@ bosses: meleeDamageMultiplier: 0.8 projectileDamageMultiplier: 0.2 + + teleportation: + enabled: true + interval: 100 + range: 20 rewards: xp: minimum: 30000 maximum: 60000 topDamagerCommands: - 1: [] - 2: [] - 3: [] + 1: [ ] + 2: [ ] + 3: [ ] nearbyPlayerCommands: radius: 10 - commands: [] - drops: [] + commands: [ ] + drops: [ ] target: mode: highest_health range: 40 @@ -52,6 +58,38 @@ bosses: color: white style: solid radius: 120 + spawn: + autospawn: + interval: -1 + locations: + - world: world + x: 100 + y: 100 + z: 100 + totem: + enabled: false + top: netherite_block + middle: iron_block + bottom: magma_block + notInWorlds: [ ] + egg: + enabled: true + 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 messages: spawn: - message: