mirror of
https://github.com/Auxilor/EcoMobs.git
synced 2025-12-21 16:09:24 +00:00
Nearing completion
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<String> args;
|
||||
|
||||
/**
|
||||
* Create a new effect.
|
||||
*
|
||||
* @param args The args.
|
||||
*/
|
||||
protected Effect(@NotNull final List<String> 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());
|
||||
}
|
||||
}
|
||||
@@ -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<String, Function<List<String>, 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<List<String>, 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<String> args) {
|
||||
Function<List<String>, Effect> found = EFFECTS.get(name.toLowerCase());
|
||||
return found == null ? null : found.apply(args);
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<frequency>:<damage>:<radius>";
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<effect>:<chance>:<duration>:<strength>";
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<frequency>:<chance>:<damage>:<radius>";
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<chance>";
|
||||
}
|
||||
|
||||
@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<ItemStack> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<entity>:<chance>";
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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:<range>:<chance>";
|
||||
}
|
||||
|
||||
@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<Location> 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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
@@ -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<String> args) {
|
||||
sender.sendMessage(this.getPlugin().getLangYml().getMessage("invalid-command"));
|
||||
}
|
||||
}
|
||||
@@ -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<String> BOSS_NAMES = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The cached numbers.
|
||||
*/
|
||||
private static final List<String> 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<String> 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<String> tabComplete(@NotNull final CommandSender sender,
|
||||
@NotNull final List<String> args) {
|
||||
List<String> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<String> 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))));
|
||||
}
|
||||
}
|
||||
@@ -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<String> args) {
|
||||
this.getPlugin().reload();
|
||||
this.getPlugin().reload();
|
||||
sender.sendMessage(this.getPlugin().getLangYml().getMessage("reloaded"));
|
||||
}
|
||||
}
|
||||
@@ -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<String> BOSS_NAMES = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The cached numbers.
|
||||
*/
|
||||
private static final List<String> 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<String> 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<String> tabComplete(@NotNull final CommandSender sender,
|
||||
@NotNull final List<String> args) {
|
||||
List<String> 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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,14 @@ val Player.bossHolders: Iterable<Holder>
|
||||
val holders = mutableListOf<Holder>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,8 +84,8 @@ object Bosses {
|
||||
* @return All living bosses.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun getAllAlive(): Set<LivingEntity> {
|
||||
val entities = mutableSetOf<LivingEntity>()
|
||||
fun getAllAlive(): Set<LivingEcoBoss> {
|
||||
val entities = mutableSetOf<LivingEcoBoss>()
|
||||
|
||||
for (boss in values()) {
|
||||
entities.addAll(boss.getAllAlive())
|
||||
|
||||
@@ -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<String> = config.getStrings("config.totem.notInWorlds")
|
||||
|
||||
val autoSpawnInterval = config.getInt("spawn.autospawn.interval")
|
||||
|
||||
val autoSpawnLocations: List<Location> = 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<LivingEntity> {
|
||||
return currentlyAlive.values.mapNotNull { it.entity }.toSet()
|
||||
fun getAllAlive(): Set<LivingEcoBoss> {
|
||||
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<BossTicker> {
|
||||
private fun createTickers(): Set<BossTicker> {
|
||||
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
|
||||
|
||||
@@ -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<BossTicker>
|
||||
) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String>
|
||||
) {
|
||||
sender.sendMessage(plugin.langYml.getMessage("invalid-command"))
|
||||
}
|
||||
|
||||
init {
|
||||
addSubcommand(CommandReload(plugin))
|
||||
.addSubcommand(CommandKillall(plugin))
|
||||
.addSubcommand(CommandSpawn(plugin))
|
||||
.addSubcommand(CommandGive(plugin))
|
||||
}
|
||||
}
|
||||
@@ -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<String>
|
||||
) {
|
||||
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<String>
|
||||
): List<String> {
|
||||
val completions = mutableListOf<String>()
|
||||
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<String>
|
||||
get() = Bosses.values().map { it.id }
|
||||
|
||||
|
||||
/**
|
||||
* The cached numbers.
|
||||
*/
|
||||
private val NUMBERS = listOf(
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"10",
|
||||
"32",
|
||||
"64"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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<String>
|
||||
) {
|
||||
val alive = Bosses.getAllAlive()
|
||||
|
||||
for (boss in alive) {
|
||||
boss.remove()
|
||||
}
|
||||
|
||||
sender.sendMessage(
|
||||
plugin.langYml.getMessage("killall").replace("%amount%", alive.size.toString())
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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<String>
|
||||
) {
|
||||
plugin.reload()
|
||||
sender.sendMessage(plugin.langYml.getMessage("reloaded"))
|
||||
}
|
||||
}
|
||||
@@ -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<String>
|
||||
) {
|
||||
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<String>
|
||||
): List<String> {
|
||||
val completions = mutableListOf<String>()
|
||||
|
||||
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<String>
|
||||
get() = Bosses.values().map { it.id }
|
||||
|
||||
/**
|
||||
* The cached numbers.
|
||||
*/
|
||||
private val TILDE = listOf(
|
||||
"~"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Location>()
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
||||
@@ -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<String>,
|
||||
val radius: Double
|
||||
) {
|
||||
fun broadcast(location: Location) {
|
||||
fun broadcast(location: Location, topDamagers: List<Damager>) {
|
||||
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<Player>()
|
||||
.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")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user