mirror of
https://github.com/Auxilor/EcoMobs.git
synced 2025-12-21 07:59:28 +00:00
Completed rewrite
This commit is contained in:
@@ -4,6 +4,5 @@ version rootProject.version
|
||||
dependencies {
|
||||
compileOnly 'org.spigotmc:spigot-api:1.17.1-R0.1-SNAPSHOT'
|
||||
compileOnly 'com.github.lokka30:LevelledMobs:3.1.4'
|
||||
compileOnly 'io.lumine.xikage:MythicMobs:4.9.1'
|
||||
compileOnly 'net.kyori:adventure-api:4.9.3'
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package com.willfp.ecobosses;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.command.impl.PluginCommand;
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||
import com.willfp.ecobosses.bosses.listeners.AttackListeners;
|
||||
import com.willfp.ecobosses.bosses.listeners.AutoSpawnTimer;
|
||||
import com.willfp.ecobosses.bosses.listeners.DeathListeners;
|
||||
import com.willfp.ecobosses.bosses.listeners.PassiveListeners;
|
||||
import com.willfp.ecobosses.bosses.listeners.SpawnListeners;
|
||||
import com.willfp.ecobosses.bosses.util.BossUtils;
|
||||
import com.willfp.ecobosses.commands.CommandEcobosses;
|
||||
import com.willfp.ecobosses.integrations.levelledmobs.LevelledMobsListener;
|
||||
import com.willfp.ecobosses.util.DiscoverRecipeListener;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class EcoBossesPlugin extends EcoPlugin {
|
||||
/**
|
||||
* Instance of the plugin.
|
||||
*/
|
||||
@Getter
|
||||
private static EcoBossesPlugin instance;
|
||||
|
||||
/**
|
||||
* Internal constructor called by bukkit on plugin load.
|
||||
*/
|
||||
public EcoBossesPlugin() {
|
||||
super(525, 10635, "com.willfp.ecobosses.proxy", "&9");
|
||||
instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMinimumEcoVersion() {
|
||||
return "6.9.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleDisable() {
|
||||
BossUtils.killAllBosses();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleReload() {
|
||||
this.getScheduler().runTimer(new AutoSpawnTimer(), 5, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PluginCommand> loadPluginCommands() {
|
||||
return List.of(
|
||||
new CommandEcobosses(this)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<IntegrationLoader> loadIntegrationLoaders() {
|
||||
return Arrays.asList(
|
||||
new IntegrationLoader("LevelledMobs", () -> this.getEventManager().registerListener(new LevelledMobsListener()))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Listener> loadListeners() {
|
||||
return Arrays.asList(
|
||||
new AttackListeners(this),
|
||||
new DeathListeners(this),
|
||||
new SpawnListeners(this),
|
||||
new DiscoverRecipeListener(this),
|
||||
new PassiveListeners(this)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.entities.CustomEntity;
|
||||
import com.willfp.eco.core.entities.Entities;
|
||||
import com.willfp.eco.core.entities.TestableEntity;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderEntry;
|
||||
import com.willfp.eco.core.items.CustomItem;
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.items.builder.ItemBuilder;
|
||||
import com.willfp.eco.core.items.builder.ItemStackBuilder;
|
||||
import com.willfp.eco.core.recipe.Recipes;
|
||||
import com.willfp.eco.core.requirement.Requirement;
|
||||
import com.willfp.eco.core.requirement.Requirements;
|
||||
import com.willfp.eco.core.tuples.Pair;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import com.willfp.ecobosses.bosses.effects.Effect;
|
||||
import com.willfp.ecobosses.bosses.effects.Effects;
|
||||
import com.willfp.ecobosses.bosses.util.BossUtils;
|
||||
import com.willfp.ecobosses.bosses.util.obj.ArgumentedEffectName;
|
||||
import com.willfp.ecobosses.bosses.util.obj.BossbarProperties;
|
||||
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 lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EcoBoss extends PluginDependent<EcoPlugin> {
|
||||
/**
|
||||
* The name of the boss.
|
||||
*/
|
||||
@Getter
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* The config of the set.
|
||||
*/
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
private final Config config;
|
||||
|
||||
/**
|
||||
* The display name of the boss.
|
||||
*/
|
||||
@Getter
|
||||
private final String displayName;
|
||||
|
||||
/**
|
||||
* The base entity spawner.
|
||||
*/
|
||||
private final TestableEntity bossType;
|
||||
|
||||
/**
|
||||
* If the boss bar is enabled.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean bossbarEnabled;
|
||||
|
||||
/**
|
||||
* The BossBar properties.
|
||||
*/
|
||||
@Getter
|
||||
private final BossbarProperties bossbarProperties;
|
||||
|
||||
/**
|
||||
* If spawn totem is enabled.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean spawnTotemEnabled;
|
||||
|
||||
/**
|
||||
* The spawn totem.
|
||||
*/
|
||||
@Getter
|
||||
private final SpawnTotem spawnTotem;
|
||||
|
||||
/**
|
||||
* Disabled world names for spawn totem.
|
||||
*/
|
||||
@Getter
|
||||
private final List<String> spawnTotemDisabledWorldNames;
|
||||
|
||||
/**
|
||||
* The max health.
|
||||
*/
|
||||
@Getter
|
||||
private final int maxHealth;
|
||||
|
||||
/**
|
||||
* The attack damage.
|
||||
*/
|
||||
@Getter
|
||||
private final int attackDamage;
|
||||
|
||||
/**
|
||||
* Age state.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean baby;
|
||||
|
||||
/**
|
||||
* The follow range.
|
||||
*/
|
||||
@Getter
|
||||
private final double followRange;
|
||||
|
||||
/**
|
||||
* The movement speed multiplier.
|
||||
*/
|
||||
@Getter
|
||||
private final double movementSpeedMultiplier;
|
||||
|
||||
/**
|
||||
* The immunity options.
|
||||
*/
|
||||
@Getter
|
||||
private final ImmunityOptions immunityOptions;
|
||||
|
||||
/**
|
||||
* The drops.
|
||||
*/
|
||||
private final List<String> drops;
|
||||
|
||||
/**
|
||||
* The exp to drop.
|
||||
*/
|
||||
@Getter
|
||||
private final ExperienceOptions experienceOptions;
|
||||
|
||||
/**
|
||||
* If attacks should be called on injury.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean attackOnInjure;
|
||||
|
||||
/**
|
||||
* Sounds played on injure.
|
||||
*/
|
||||
@Getter
|
||||
private final List<OptionedSound> injureSounds;
|
||||
|
||||
/**
|
||||
* Spawn sounds.
|
||||
*/
|
||||
@Getter
|
||||
private final List<OptionedSound> spawnSounds;
|
||||
|
||||
/**
|
||||
* Death sounds.
|
||||
*/
|
||||
@Getter
|
||||
private final List<OptionedSound> deathSounds;
|
||||
|
||||
/**
|
||||
* Summon sounds.
|
||||
*/
|
||||
@Getter
|
||||
private final List<OptionedSound> summonSounds;
|
||||
|
||||
/**
|
||||
* Despawn sounds.
|
||||
*/
|
||||
@Getter
|
||||
private final List<OptionedSound> despawnSounds;
|
||||
|
||||
/**
|
||||
* Spawn messages.
|
||||
*/
|
||||
@Getter
|
||||
private final List<String> spawnMessages;
|
||||
|
||||
/**
|
||||
* Death messages.
|
||||
*/
|
||||
@Getter
|
||||
private final List<String> deathMessages;
|
||||
|
||||
/**
|
||||
* Despawn messages.
|
||||
*/
|
||||
@Getter
|
||||
private final List<String> despawnMessages;
|
||||
|
||||
/**
|
||||
* Nearby players radius.
|
||||
*/
|
||||
@Getter
|
||||
private final double nearbyRadius;
|
||||
|
||||
/**
|
||||
* Nearby players commands.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<String, Double> nearbyPlayersCommands;
|
||||
|
||||
/**
|
||||
* Top damager commands.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<Integer, List<Pair<Double, String>>> topDamagerCommands;
|
||||
|
||||
/**
|
||||
* Incoming damage multipliers.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<EntityDamageEvent.DamageCause, Double> incomingMultipliers;
|
||||
|
||||
/**
|
||||
* Boss glowing effect.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean isGlowing;
|
||||
|
||||
/**
|
||||
* The currently living bosses of this type.
|
||||
*/
|
||||
private final Map<LivingEntity, com.willfp.ecobosses.bosses.LivingEcoBoss> livingBosses;
|
||||
|
||||
/**
|
||||
* The effect names and arguments.
|
||||
*/
|
||||
private final List<ArgumentedEffectName> effectNames;
|
||||
|
||||
/**
|
||||
* The target distance.
|
||||
*/
|
||||
@Getter
|
||||
private final double targetDistance;
|
||||
|
||||
/**
|
||||
* The targeting mode.
|
||||
*/
|
||||
@Getter
|
||||
private final TargetMode targetMode;
|
||||
|
||||
/**
|
||||
* If the boss shouldn't get into boats and minecarts.
|
||||
*/
|
||||
@Getter
|
||||
private final boolean disableBoats;
|
||||
|
||||
/**
|
||||
* The time between auto spawns.
|
||||
*/
|
||||
@Getter
|
||||
private final int autoSpawnInterval;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int timeUntilSpawn;
|
||||
|
||||
/**
|
||||
* The time to live.
|
||||
*/
|
||||
@Getter
|
||||
private final int timeToLive;
|
||||
|
||||
/**
|
||||
* Locations that the boss can auto spawn at.
|
||||
*/
|
||||
@Getter
|
||||
private final List<Location> autoSpawnLocations;
|
||||
|
||||
/**
|
||||
* The boss spawn egg.
|
||||
*/
|
||||
@Getter
|
||||
private final ItemStack spawnEgg;
|
||||
|
||||
/**
|
||||
* All the requirements needed in order to spawn the boss.
|
||||
*/
|
||||
private final Map<Requirement, List<String>> requirements = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Cached players to see if they meet requirements.
|
||||
*/
|
||||
private final Map<UUID, Boolean> cachedRequirements = new HashMap<>();
|
||||
|
||||
/**
|
||||
* The equipment for the boss.
|
||||
*/
|
||||
@Getter
|
||||
private final Map<EquipmentSlot, EquipmentPiece> equipment = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new Boss.
|
||||
*
|
||||
* @param id The name of the set.
|
||||
* @param config The set's config.
|
||||
* @param plugin Instance of EcoBosses.
|
||||
*/
|
||||
public EcoBoss(@NotNull final String id,
|
||||
@NotNull final Config config,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
this.config = config;
|
||||
this.id = id;
|
||||
this.livingBosses = new HashMap<>();
|
||||
this.isGlowing = this.getConfig().getBool("glowing");
|
||||
this.baby = this.getConfig().getBool("baby");
|
||||
|
||||
this.displayName = this.getConfig().getFormattedString("name");
|
||||
|
||||
// Boss Type
|
||||
this.bossType = Entities.lookup(this.getConfig().getString("base-mob"));
|
||||
|
||||
// Boss Bar
|
||||
this.bossbarEnabled = this.getConfig().getBool("bossbar.enabled");
|
||||
String barStyle = this.getConfig().getString("bossbar.style").toUpperCase();
|
||||
if (barStyle.equalsIgnoreCase("solid")) {
|
||||
barStyle = "PROGRESS";
|
||||
}
|
||||
this.bossbarProperties = new BossbarProperties(
|
||||
BossBar.Color.valueOf(this.getConfig().getString("bossbar.color").toUpperCase()),
|
||||
BossBar.Overlay.valueOf(barStyle)
|
||||
);
|
||||
|
||||
// Attributes
|
||||
this.attackDamage = this.getConfig().getInt("attack-damage");
|
||||
this.maxHealth = this.getConfig().getInt("max-health");
|
||||
this.followRange = this.getConfig().getInt("follow-range");
|
||||
this.movementSpeedMultiplier = this.getConfig().getInt("movement-speed");
|
||||
this.timeToLive = this.getConfig().getInt("time-to-live", -1);
|
||||
|
||||
// Equipment
|
||||
ItemStack helmet = Items.lookup(this.getConfig().getString("gear.helmet.item")).getItem();
|
||||
ItemStack chestplate = Items.lookup(this.getConfig().getString("gear.chestplate.item")).getItem();
|
||||
ItemStack leggings = Items.lookup(this.getConfig().getString("gear.leggings.item")).getItem();
|
||||
ItemStack boots = Items.lookup(this.getConfig().getString("gear.boots.item")).getItem();
|
||||
ItemStack hand = Items.lookup(this.getConfig().getString("gear.hand.item")).getItem();
|
||||
|
||||
if (helmet.getType() != Material.AIR) {
|
||||
this.equipment.put(
|
||||
EquipmentSlot.HEAD,
|
||||
new EquipmentPiece(
|
||||
helmet,
|
||||
this.getConfig().getDouble("gear.helmet.chance")
|
||||
)
|
||||
);
|
||||
}
|
||||
if (chestplate.getType() != Material.AIR) {
|
||||
this.equipment.put(
|
||||
EquipmentSlot.CHEST,
|
||||
new EquipmentPiece(
|
||||
chestplate,
|
||||
this.getConfig().getDouble("gear.chestplate.chance")
|
||||
)
|
||||
);
|
||||
}
|
||||
if (leggings.getType() != Material.AIR) {
|
||||
this.equipment.put(
|
||||
EquipmentSlot.LEGS,
|
||||
new EquipmentPiece(
|
||||
leggings,
|
||||
this.getConfig().getDouble("gear.leggings.chance")
|
||||
)
|
||||
);
|
||||
}
|
||||
if (boots.getType() != Material.AIR) {
|
||||
this.equipment.put(
|
||||
EquipmentSlot.FEET,
|
||||
new EquipmentPiece(
|
||||
boots,
|
||||
this.getConfig().getDouble("gear.boots.chance")
|
||||
)
|
||||
);
|
||||
}
|
||||
if (hand.getType() != Material.AIR) {
|
||||
this.equipment.put(
|
||||
EquipmentSlot.HAND,
|
||||
new EquipmentPiece(
|
||||
hand,
|
||||
this.getConfig().getDouble("gear.hand.chance")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Spawn Totem
|
||||
this.spawnTotemEnabled = this.getConfig().getBool("spawn-totem.enabled");
|
||||
this.spawnTotem = new SpawnTotem(
|
||||
Material.getMaterial(this.getConfig().getString("spawn-totem.bottom").toUpperCase()),
|
||||
Material.getMaterial(this.getConfig().getString("spawn-totem.middle").toUpperCase()),
|
||||
Material.getMaterial(this.getConfig().getString("spawn-totem.top").toUpperCase())
|
||||
);
|
||||
this.spawnTotemDisabledWorldNames = this.getConfig().getStrings("spawn-totem.world-blacklist").stream().map(String::toLowerCase).collect(Collectors.toList());
|
||||
|
||||
// Rewards
|
||||
this.drops = new ArrayList<>();
|
||||
drops.addAll(this.getConfig().getStrings("rewards.drops"));
|
||||
|
||||
this.experienceOptions = new ExperienceOptions(
|
||||
this.getConfig().getInt("rewards.xp.minimum"),
|
||||
this.getConfig().getInt("rewards.xp.maximum")
|
||||
);
|
||||
|
||||
// Immunities
|
||||
this.immunityOptions = new ImmunityOptions(
|
||||
this.getConfig().getBool("defence.immunities.fire"),
|
||||
this.getConfig().getBool("defence.immunities.suffocation"),
|
||||
this.getConfig().getBool("defence.immunities.drowning"),
|
||||
this.getConfig().getBool("defence.immunities.projectiles"),
|
||||
this.getConfig().getBool("defence.immunities.explosion")
|
||||
);
|
||||
|
||||
// Multipliers
|
||||
this.incomingMultipliers = new HashMap<>();
|
||||
double melee = this.getConfig().getDouble("defence.incoming-multipliers.melee");
|
||||
this.incomingMultipliers.put(EntityDamageEvent.DamageCause.ENTITY_ATTACK, melee);
|
||||
this.incomingMultipliers.put(EntityDamageEvent.DamageCause.ENTITY_SWEEP_ATTACK, melee);
|
||||
|
||||
double projectile = this.getConfig().getDouble("defence.incoming-multipliers.projectile");
|
||||
this.incomingMultipliers.put(EntityDamageEvent.DamageCause.PROJECTILE, projectile);
|
||||
|
||||
// Attack on injure
|
||||
this.attackOnInjure = this.getConfig().getBool("attacks.on-injure");
|
||||
|
||||
// Sounds
|
||||
this.injureSounds = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("sounds.injure")) {
|
||||
String[] split = string.split(":");
|
||||
this.injureSounds.add(new OptionedSound(
|
||||
Sound.valueOf(split[0].toUpperCase()),
|
||||
Float.parseFloat(split[1]) / 16,
|
||||
Float.parseFloat(split[2])
|
||||
));
|
||||
}
|
||||
|
||||
this.deathSounds = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("sounds.death")) {
|
||||
String[] split = string.split(":");
|
||||
this.deathSounds.add(new OptionedSound(
|
||||
Sound.valueOf(split[0].toUpperCase()),
|
||||
Float.parseFloat(split[1]) / 16,
|
||||
Float.parseFloat(split[2])
|
||||
));
|
||||
}
|
||||
|
||||
this.summonSounds = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("sounds.summon")) {
|
||||
String[] split = string.split(":");
|
||||
this.summonSounds.add(new OptionedSound(
|
||||
Sound.valueOf(split[0].toUpperCase()),
|
||||
Float.parseFloat(split[1]) / 16,
|
||||
Float.parseFloat(split[2])
|
||||
));
|
||||
}
|
||||
|
||||
this.spawnSounds = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("sounds.spawn")) {
|
||||
String[] split = string.split(":");
|
||||
this.spawnSounds.add(new OptionedSound(
|
||||
Sound.valueOf(split[0].toUpperCase()),
|
||||
Float.parseFloat(split[1]) / 16,
|
||||
Float.parseFloat(split[2])
|
||||
));
|
||||
}
|
||||
|
||||
this.despawnSounds = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("sounds.despawn")) {
|
||||
String[] split = string.split(":");
|
||||
this.despawnSounds.add(new OptionedSound(
|
||||
Sound.valueOf(split[0].toUpperCase()),
|
||||
Float.parseFloat(split[1]) / 16,
|
||||
Float.parseFloat(split[2])
|
||||
));
|
||||
}
|
||||
|
||||
// Messages
|
||||
this.spawnMessages = new ArrayList<>();
|
||||
for (String string : this.getConfig().getFormattedStrings("broadcast.spawn")) {
|
||||
this.spawnMessages.add(StringUtils.format(string));
|
||||
}
|
||||
this.deathMessages = new ArrayList<>();
|
||||
for (String string : this.getConfig().getFormattedStrings("broadcast.death")) {
|
||||
this.deathMessages.add(StringUtils.format(string));
|
||||
}
|
||||
this.despawnMessages = new ArrayList<>();
|
||||
for (String string : this.getConfig().getFormattedStrings("broadcast.despawn")) {
|
||||
this.despawnMessages.add(StringUtils.format(string));
|
||||
}
|
||||
|
||||
// Top Damager Commands
|
||||
this.topDamagerCommands = new HashMap<>();
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
this.topDamagerCommands.put(i, new ArrayList<>());
|
||||
for (String string : this.getConfig().getStrings("rewards.top-damager-commands." + i)) {
|
||||
double chance = 100;
|
||||
if (string.contains("::")) {
|
||||
String[] split = string.split("::");
|
||||
chance = Double.parseDouble(split[0]);
|
||||
string = split[1];
|
||||
}
|
||||
List<Pair<Double, String>> commands = this.topDamagerCommands.get(i) == null ? new ArrayList<>() : this.topDamagerCommands.get(i);
|
||||
commands.add(new Pair<>(chance, string));
|
||||
this.topDamagerCommands.put(i, commands);
|
||||
}
|
||||
}
|
||||
|
||||
// Nearby Rewards
|
||||
this.nearbyRadius = this.getConfig().getDouble("rewards.nearby-player-commands.radius");
|
||||
this.nearbyPlayersCommands = new HashMap<>();
|
||||
for (String string : this.getConfig().getStrings("rewards.nearby-player-commands.commands")) {
|
||||
double chance = 100;
|
||||
if (string.contains("::")) {
|
||||
String[] split = string.split("::");
|
||||
chance = Double.parseDouble(split[0]);
|
||||
string = split[1];
|
||||
}
|
||||
this.nearbyPlayersCommands.put(string, chance);
|
||||
}
|
||||
|
||||
// Effects
|
||||
this.effectNames = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("effects")) {
|
||||
String effectName = string.split(":")[0];
|
||||
List<String> args = new ArrayList<>(Arrays.asList(string.replace(effectName + ":", "").split(":")));
|
||||
this.effectNames.add(new ArgumentedEffectName(effectName, args));
|
||||
}
|
||||
|
||||
for (ArgumentedEffectName effectName : new ArrayList<>(this.effectNames)) {
|
||||
if (Effects.getEffect(effectName.name(), effectName.args()) == null) {
|
||||
this.effectNames.remove(effectName);
|
||||
Bukkit.getLogger().warning("Invalid effect " + effectName.name() + " specified in " + this.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Targeting
|
||||
this.targetDistance = this.getConfig().getDouble("attacks.target.range");
|
||||
this.targetMode = TargetMode.getByName(this.getConfig().getString("attacks.target.mode"));
|
||||
|
||||
// Boat + Minecarts
|
||||
this.disableBoats = this.getConfig().getBool("defence.no-boats");
|
||||
|
||||
// Auto Spawn
|
||||
this.autoSpawnInterval = this.getConfig().getInt("auto-spawn-interval");
|
||||
this.timeUntilSpawn = this.autoSpawnInterval;
|
||||
this.autoSpawnLocations = new ArrayList<>();
|
||||
for (String string : this.getConfig().getStrings("auto-spawn-locations")) {
|
||||
String[] split = string.split(":");
|
||||
World world = Bukkit.getWorld(split[0]);
|
||||
double x = Double.parseDouble(split[1]);
|
||||
double y = Double.parseDouble(split[2]);
|
||||
double z = Double.parseDouble(split[3]);
|
||||
autoSpawnLocations.add(new Location(world, x, y, z));
|
||||
}
|
||||
|
||||
new PlaceholderEntry(
|
||||
"timeuntilspawn_" + this.id,
|
||||
(player) -> new BigDecimal(this.timeUntilSpawn / 20).setScale(1, RoundingMode.HALF_UP).toString(),
|
||||
false
|
||||
).register();
|
||||
|
||||
for (String req : config.getStrings("spawn-requirements")) {
|
||||
List<String> split = Arrays.asList(req.split(":"));
|
||||
if (split.size() < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Requirement requirement = Requirements.getByID(split.get(0).toLowerCase());
|
||||
|
||||
this.requirements.put(requirement, split.subList(1, split.size()));
|
||||
}
|
||||
|
||||
this.clearCachedRequirements();
|
||||
|
||||
// Spawn egg
|
||||
if (this.getConfig().getBool("spawn-egg.enabled")) {
|
||||
ItemBuilder builder = new ItemStackBuilder(Items.lookup(this.getConfig().getString("spawn-egg.material")).getItem())
|
||||
.setDisplayName(this.getConfig().getString("spawn-egg.name"))
|
||||
.addLoreLines(this.getConfig().getStrings("spawn-egg.lore"))
|
||||
.writeMetaKey(this.getPlugin().getNamespacedKeyFactory().create("spawn_egg"), PersistentDataType.STRING, this.getId());
|
||||
|
||||
if (this.getConfig().getBool("spawn-egg.glow")) {
|
||||
builder.addEnchantment(Enchantment.DURABILITY, 1)
|
||||
.addItemFlag(ItemFlag.HIDE_ENCHANTS);
|
||||
}
|
||||
|
||||
this.spawnEgg = builder.build();
|
||||
|
||||
new CustomItem(
|
||||
this.getPlugin().getNamespacedKeyFactory().create(this.getId() + "_spawn_egg"),
|
||||
test -> {
|
||||
ItemMeta meta = test.getItemMeta();
|
||||
if (meta == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
if (!container.has(this.getPlugin().getNamespacedKeyFactory().create("spawn_egg"), PersistentDataType.STRING)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String spawnEggID = container.get(this.getPlugin().getNamespacedKeyFactory().create("spawn_egg"), PersistentDataType.STRING);
|
||||
if (spawnEggID == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return spawnEggID.equalsIgnoreCase(this.getId());
|
||||
},
|
||||
this.getSpawnEgg()
|
||||
).register();
|
||||
|
||||
if (this.getConfig().getBool("spawn-egg.craftable")) {
|
||||
Recipes.createAndRegisterRecipe(
|
||||
this.getPlugin(),
|
||||
"spawn_egg_" + this.getId(),
|
||||
this.getSpawnEgg(),
|
||||
this.getConfig().getStrings("spawn-egg.recipe")
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.spawnEgg = null;
|
||||
}
|
||||
|
||||
if (this.getConfig().getBool("enabled")) {
|
||||
EcoBosses.addBoss(this);
|
||||
|
||||
new CustomEntity(
|
||||
this.getPlugin().getNamespacedKeyFactory().create(this.id),
|
||||
test -> {
|
||||
if (!(test instanceof LivingEntity living)) {
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(this, BossUtils.getBoss(living));
|
||||
},
|
||||
this::spawn
|
||||
).register();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear requirements cache.
|
||||
*/
|
||||
public void clearCachedRequirements() {
|
||||
this.cachedRequirements.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the player meet the requirements to use this enchantment.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If the requirements are met.
|
||||
*/
|
||||
public boolean areRequirementsMet(@NotNull final Player player) {
|
||||
if (cachedRequirements.containsKey(player.getUniqueId())) {
|
||||
return cachedRequirements.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
for (Map.Entry<Requirement, List<String>> entry : requirements.entrySet()) {
|
||||
if (!entry.getKey().doesPlayerMeet(player, entry.getValue())) {
|
||||
cachedRequirements.put(player.getUniqueId(), false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cachedRequirements.put(player.getUniqueId(), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
public List<ItemStack> generateDrops() {
|
||||
List<ItemStack> drops = new ArrayList<>();
|
||||
|
||||
for (String dropName : this.drops) {
|
||||
double chance = 100;
|
||||
if (dropName.contains("::")) {
|
||||
String[] split = dropName.split("::");
|
||||
chance = Double.parseDouble(split[0]);
|
||||
dropName = split[1];
|
||||
}
|
||||
|
||||
ItemStack itemStack = Items.lookup(dropName).getItem();
|
||||
if (itemStack.getType() == Material.AIR) {
|
||||
Bukkit.getLogger().warning(this.getId() + " has an invalid drop configured! (" + dropName + ")");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NumberUtils.randFloat(0, 100) < chance) {
|
||||
drops.add(itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
return drops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create effect tickers for Living Boss.
|
||||
*
|
||||
* @return The effects.
|
||||
*/
|
||||
public List<Effect> createEffects() {
|
||||
List<Effect> effects = new ArrayList<>();
|
||||
for (ArgumentedEffectName effectName : this.effectNames) {
|
||||
effects.add(Effects.getEffect(effectName.name(), effectName.args()));
|
||||
}
|
||||
|
||||
return effects;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawn the boss.
|
||||
*
|
||||
* @param location The location.
|
||||
*/
|
||||
public LivingEntity spawn(@NotNull final Location location) {
|
||||
location.getChunk().load();
|
||||
|
||||
LivingEntity entity = (LivingEntity) bossType.spawn(location);
|
||||
this.livingBosses.put(entity, new com.willfp.ecobosses.bosses.LivingEcoBoss(
|
||||
this.getPlugin(),
|
||||
entity,
|
||||
this
|
||||
)
|
||||
);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link com.willfp.ecobosses.bosses.LivingEcoBoss} from an entity.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @return The living boss, or null if not a boss.
|
||||
*/
|
||||
public com.willfp.ecobosses.bosses.LivingEcoBoss getLivingBoss(@NotNull final LivingEntity entity) {
|
||||
return this.livingBosses.get(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove living boss.
|
||||
*
|
||||
* @param entity The entity.
|
||||
*/
|
||||
public void removeLivingBoss(@Nullable final LivingEntity entity) {
|
||||
this.livingBosses.remove(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all living bosses.
|
||||
*
|
||||
* @return The living bosses.
|
||||
*/
|
||||
public Map<LivingEntity, LivingEcoBoss> getLivingBosses() {
|
||||
return ImmutableMap.copyOf(this.livingBosses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof com.willfp.ecobosses.bosses.EcoBoss boss)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getId().equals(boss.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "EcoBoss{"
|
||||
+ this.getId()
|
||||
+ "}";
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.willfp.eco.core.config.updating.ConfigUpdater;
|
||||
import com.willfp.ecobosses.EcoBossesPlugin;
|
||||
import com.willfp.ecobosses.config.BaseBossConfig;
|
||||
import com.willfp.ecobosses.config.CustomConfig;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class EcoBosses {
|
||||
/**
|
||||
* Registered armor sets.
|
||||
*/
|
||||
private static final BiMap<String, com.willfp.ecobosses.bosses.EcoBoss> BY_NAME = HashBiMap.create();
|
||||
|
||||
/**
|
||||
* Sets that exist by default.
|
||||
*/
|
||||
private static final List<String> DEFAULT_BOSSES = Arrays.asList(
|
||||
"dark_guardian",
|
||||
"tarantula",
|
||||
"steel_golem",
|
||||
"alpha_wolf"
|
||||
);
|
||||
|
||||
/**
|
||||
* Get all registered {@link com.willfp.ecobosses.bosses.EcoBoss}es.
|
||||
*
|
||||
* @return A list of all {@link com.willfp.ecobosses.bosses.EcoBoss}es.
|
||||
*/
|
||||
public static List<com.willfp.ecobosses.bosses.EcoBoss> values() {
|
||||
return ImmutableList.copyOf(BY_NAME.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get {@link com.willfp.ecobosses.bosses.EcoBoss} matching name.
|
||||
*
|
||||
* @param name The name to search for.
|
||||
* @return The matching {@link com.willfp.ecobosses.bosses.EcoBoss}, or null if not found.
|
||||
*/
|
||||
public static com.willfp.ecobosses.bosses.EcoBoss getByName(@NotNull final String name) {
|
||||
return BY_NAME.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all {@link com.willfp.ecobosses.bosses.EcoBoss}s.
|
||||
*/
|
||||
@ConfigUpdater
|
||||
public static void update() {
|
||||
for (com.willfp.ecobosses.bosses.EcoBoss boss : values()) {
|
||||
removeBoss(boss);
|
||||
}
|
||||
|
||||
for (String defaultSetName : DEFAULT_BOSSES) {
|
||||
new com.willfp.ecobosses.bosses.EcoBoss(defaultSetName, new BaseBossConfig(defaultSetName), EcoBossesPlugin.getInstance());
|
||||
}
|
||||
|
||||
try {
|
||||
Files.walk(Paths.get(new File(EcoBossesPlugin.getInstance().getDataFolder(), "bosses/").toURI()))
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach(path -> {
|
||||
String name = path.getFileName().toString().replace(".yml", "");
|
||||
new com.willfp.ecobosses.bosses.EcoBoss(
|
||||
name,
|
||||
new CustomConfig(name, YamlConfiguration.loadConfiguration(path.toFile())),
|
||||
EcoBossesPlugin.getInstance()
|
||||
);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new {@link com.willfp.ecobosses.bosses.EcoBoss} to EcoBosses.
|
||||
*
|
||||
* @param set The {@link com.willfp.ecobosses.bosses.EcoBoss} to add.
|
||||
*/
|
||||
public static void addBoss(@NotNull final com.willfp.ecobosses.bosses.EcoBoss set) {
|
||||
BY_NAME.remove(set.getId());
|
||||
BY_NAME.put(set.getId(), set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove {@link com.willfp.ecobosses.bosses.EcoBoss} from EcoBosses.
|
||||
*
|
||||
* @param set The {@link com.willfp.ecobosses.bosses.EcoBoss} to remove.
|
||||
*/
|
||||
public static void removeBoss(@NotNull final EcoBoss set) {
|
||||
BY_NAME.remove(set.getId());
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.scheduling.RunnableTask;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import com.willfp.ecobosses.bosses.effects.Effect;
|
||||
import com.willfp.ecobosses.bosses.tick.tickers.BossBarTicker;
|
||||
import com.willfp.ecobosses.bosses.tick.tickers.DeathTimeTicker;
|
||||
import com.willfp.ecobosses.bosses.tick.tickers.NamePlaceholderTicker;
|
||||
import com.willfp.ecobosses.bosses.tick.tickers.TargetTicker;
|
||||
import com.willfp.ecobosses.bosses.util.obj.EquipmentPiece;
|
||||
import com.willfp.ecobosses.bosses.util.obj.OptionedSound;
|
||||
import com.willfp.ecobosses.tick.BossTicker;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class LivingEcoBoss extends PluginDependent<EcoPlugin> {
|
||||
/**
|
||||
* The entity.
|
||||
*/
|
||||
@Getter
|
||||
private LivingEntity entity;
|
||||
|
||||
/**
|
||||
* The boss.
|
||||
*/
|
||||
private final com.willfp.ecobosses.bosses.EcoBoss boss;
|
||||
|
||||
/**
|
||||
* The boss tickers.
|
||||
*/
|
||||
private final List<BossTicker> tickers;
|
||||
|
||||
/**
|
||||
* The effects.
|
||||
*/
|
||||
private final List<Effect> effects;
|
||||
|
||||
/**
|
||||
* Create new living EcoBoss.
|
||||
*
|
||||
* @param plugin Instance of EcoBosses.
|
||||
* @param entity The entity.
|
||||
* @param boss The boss.
|
||||
*/
|
||||
public LivingEcoBoss(@NotNull final EcoPlugin plugin,
|
||||
@NotNull final LivingEntity entity,
|
||||
@NotNull final EcoBoss boss) {
|
||||
super(plugin);
|
||||
this.entity = entity;
|
||||
this.boss = boss;
|
||||
|
||||
this.onSpawn();
|
||||
|
||||
// Tickers
|
||||
this.tickers = new ArrayList<>();
|
||||
this.tickers.add(new NamePlaceholderTicker());
|
||||
this.tickers.add(new DeathTimeTicker());
|
||||
this.tickers.add(new TargetTicker(boss.getTargetMode(), boss.getTargetDistance()));
|
||||
if (boss.isBossbarEnabled()) {
|
||||
this.tickers.add(
|
||||
new BossBarTicker(
|
||||
BossBar.bossBar(
|
||||
StringUtils.toComponent(entity.getCustomName()),
|
||||
1,
|
||||
boss.getBossbarProperties().color(),
|
||||
boss.getBossbarProperties().style()
|
||||
),
|
||||
this.getPlugin().getConfigYml().getInt("bossbar-radius")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Effects
|
||||
this.effects = new ArrayList<>();
|
||||
this.effects.addAll(boss.createEffects());
|
||||
|
||||
AtomicLong currentTick = new AtomicLong(0);
|
||||
this.getPlugin().getRunnableFactory().create(runnable -> this.tick(currentTick.getAndAdd(1), runnable)).runTaskTimer(0, 1);
|
||||
}
|
||||
|
||||
private void onSpawn() {
|
||||
entity.getPersistentDataContainer().set(this.getPlugin().getNamespacedKeyFactory().create("boss"), PersistentDataType.STRING, boss.getId());
|
||||
entity.setPersistent(true);
|
||||
entity.setRemoveWhenFarAway(false);
|
||||
|
||||
if (boss.isGlowing()) entity.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, Integer.MAX_VALUE, 1, false, false, false));
|
||||
|
||||
if (entity instanceof Ageable ageable) {
|
||||
if (boss.isBaby()) ageable.setBaby();
|
||||
else ageable.setAdult();
|
||||
}
|
||||
|
||||
if (boss.getTimeToLive() > 0) {
|
||||
entity.setMetadata("death-time", this.getPlugin().getMetadataValueFactory().create(System.currentTimeMillis() + (boss.getTimeToLive() * 1000L)));
|
||||
}
|
||||
|
||||
entity.setCustomName(boss.getDisplayName());
|
||||
entity.setCustomNameVisible(true);
|
||||
|
||||
EntityEquipment equipment = entity.getEquipment();
|
||||
if (equipment != null) {
|
||||
EquipmentPiece head = boss.getEquipment().get(EquipmentSlot.HEAD);
|
||||
EquipmentPiece chest = boss.getEquipment().get(EquipmentSlot.CHEST);
|
||||
EquipmentPiece legs = boss.getEquipment().get(EquipmentSlot.LEGS);
|
||||
EquipmentPiece boots = boss.getEquipment().get(EquipmentSlot.FEET);
|
||||
EquipmentPiece hand = boss.getEquipment().get(EquipmentSlot.HAND);
|
||||
if (head != null) {
|
||||
equipment.setHelmet(head.itemStack(), true);
|
||||
equipment.setHelmetDropChance((float) head.chance());
|
||||
}
|
||||
if (chest != null) {
|
||||
equipment.setChestplate(chest.itemStack(), true);
|
||||
equipment.setChestplateDropChance((float) chest.chance());
|
||||
}
|
||||
if (legs != null) {
|
||||
equipment.setLeggings(legs.itemStack(), true);
|
||||
equipment.setLeggingsDropChance((float) legs.chance());
|
||||
}
|
||||
if (boots != null) {
|
||||
equipment.setBoots(boots.itemStack(), true);
|
||||
equipment.setBootsDropChance((float) boots.chance());
|
||||
}
|
||||
if (hand != null) {
|
||||
equipment.setItemInMainHand(hand.itemStack(), true);
|
||||
equipment.setItemInMainHandDropChance((float) hand.chance());
|
||||
}
|
||||
}
|
||||
|
||||
AttributeInstance movementSpeed = entity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED);
|
||||
assert movementSpeed != null;
|
||||
movementSpeed.addModifier(new AttributeModifier(entity.getUniqueId(), "ecobosses-movement-multiplier", boss.getMovementSpeedMultiplier() - 1, AttributeModifier.Operation.MULTIPLY_SCALAR_1));
|
||||
|
||||
AttributeInstance maxHealth = entity.getAttribute(Attribute.GENERIC_MAX_HEALTH);
|
||||
if (maxHealth != null) {
|
||||
maxHealth.getModifiers().clear();
|
||||
maxHealth.setBaseValue(boss.getMaxHealth());
|
||||
entity.setHealth(maxHealth.getValue());
|
||||
}
|
||||
|
||||
AttributeInstance followRange = entity.getAttribute(Attribute.GENERIC_FOLLOW_RANGE);
|
||||
if (followRange != null) {
|
||||
followRange.getModifiers().clear();
|
||||
followRange.setBaseValue(boss.getFollowRange());
|
||||
}
|
||||
|
||||
AttributeInstance attackDamage = entity.getAttribute(Attribute.GENERIC_ATTACK_DAMAGE);
|
||||
if (attackDamage != null) {
|
||||
attackDamage.getModifiers().clear();
|
||||
attackDamage.setBaseValue(boss.getAttackDamage());
|
||||
}
|
||||
|
||||
for (OptionedSound sound : boss.getSpawnSounds()) {
|
||||
entity.getWorld().playSound(entity.getLocation(), sound.sound(), sound.volume(), sound.pitch());
|
||||
}
|
||||
|
||||
for (String spawnMessage : boss.getSpawnMessages()) {
|
||||
Bukkit.broadcastMessage(spawnMessage
|
||||
.replace("%x%", StringUtils.internalToString(entity.getLocation().getBlockX()))
|
||||
.replace("%y%", StringUtils.internalToString(entity.getLocation().getBlockY()))
|
||||
.replace("%z%", StringUtils.internalToString(entity.getLocation().getBlockZ()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void tick(final long tick,
|
||||
@NotNull final RunnableTask runnable) {
|
||||
if (entity == null || entity.isDead()) {
|
||||
for (BossTicker ticker : tickers) {
|
||||
ticker.onDeath(boss, entity, tick);
|
||||
}
|
||||
for (Effect effect : effects) {
|
||||
effect.onDeath(boss, entity, tick);
|
||||
}
|
||||
boss.removeLivingBoss(entity);
|
||||
runnable.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
for (BossTicker ticker : tickers) {
|
||||
ticker.tick(boss, entity, tick);
|
||||
}
|
||||
for (Effect effect : effects) {
|
||||
effect.tick(boss, entity, tick);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an attack to the player.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
public void handleAttack(@NotNull final Player player) {
|
||||
for (OptionedSound sound : boss.getInjureSounds()) {
|
||||
player.getWorld().playSound(entity.getLocation(), sound.sound(), sound.volume(), sound.pitch());
|
||||
}
|
||||
|
||||
for (Effect effect : effects) {
|
||||
effect.onAttack(boss, entity, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.listeners;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import com.willfp.ecobosses.bosses.LivingEcoBoss;
|
||||
import com.willfp.ecobosses.bosses.util.BossUtils;
|
||||
import com.willfp.ecobosses.bosses.util.obj.DamagerProperty;
|
||||
import com.willfp.ecobosses.bosses.util.obj.ImmunityOptions;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class AttackListeners extends PluginDependent<EcoPlugin> implements Listener {
|
||||
/**
|
||||
* Create new attack listeners.
|
||||
*
|
||||
* @param plugin Instance of EcoBosses.
|
||||
*/
|
||||
public AttackListeners(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player attacks a boss.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onAttackBoss(@NotNull final EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof LivingEntity entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = BossUtils.getPlayerFromEntity(event.getDamager());
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LivingEcoBoss livingEcoBoss = boss.getLivingBoss(entity);
|
||||
|
||||
if (livingEcoBoss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (boss.isAttackOnInjure()) {
|
||||
livingEcoBoss.handleAttack(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track top damage players.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void topDamageTracker(@NotNull final EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof LivingEntity entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = BossUtils.getPlayerFromEntity(event.getDamager());
|
||||
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<DamagerProperty> topDamagers = BossUtils.getTopDamagers(entity);
|
||||
|
||||
double playerDamage;
|
||||
|
||||
Optional<DamagerProperty> damager = topDamagers.stream().filter(damagerProperty -> damagerProperty.playerUUID().equals(player.getUniqueId())).findFirst();
|
||||
playerDamage = damager.map(DamagerProperty::damage).orElse(0.0);
|
||||
|
||||
playerDamage += event.getFinalDamage();
|
||||
topDamagers.removeIf(damagerProperty -> damagerProperty.playerUUID().equals(player.getUniqueId()));
|
||||
topDamagers.add(new DamagerProperty(player.getUniqueId(), playerDamage));
|
||||
|
||||
entity.removeMetadata("ecobosses-top-damagers", this.getPlugin());
|
||||
entity.setMetadata("ecobosses-top-damagers", this.getPlugin().getMetadataValueFactory().create(topDamagers));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a boss attacks a player.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onAttackPlayer(@NotNull final EntityDamageByEntityEvent event) {
|
||||
if (!(event.getEntity() instanceof Player player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getDamager() instanceof LivingEntity entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LivingEcoBoss livingEcoBoss = boss.getLivingBoss(entity);
|
||||
|
||||
if (livingEcoBoss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
livingEcoBoss.handleAttack(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a boss is damaged.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH)
|
||||
public void defenceListener(@NotNull final EntityDamageEvent event) {
|
||||
if (!(event.getEntity() instanceof LivingEntity entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmunityOptions immunities = boss.getImmunityOptions();
|
||||
|
||||
if (immunities.immuneToFire()
|
||||
&& (event.getCause() == EntityDamageEvent.DamageCause.FIRE
|
||||
|| event.getCause() == EntityDamageEvent.DamageCause.FIRE_TICK
|
||||
|| event.getCause() == EntityDamageEvent.DamageCause.LAVA
|
||||
|| event.getCause() == EntityDamageEvent.DamageCause.HOT_FLOOR)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (immunities.immuneToSuffocation()&& event.getCause() == EntityDamageEvent.DamageCause.SUFFOCATION) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (immunities.immuneToDrowning() && event.getCause() == EntityDamageEvent.DamageCause.DROWNING) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (immunities.immuneToExplosions() && (event.getCause() == EntityDamageEvent.DamageCause.ENTITY_EXPLOSION || event.getCause() == EntityDamageEvent.DamageCause.BLOCK_EXPLOSION)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
if (immunities.immuneToProjectiles() && (event.getCause() == EntityDamageEvent.DamageCause.PROJECTILE)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
for (Map.Entry<EntityDamageEvent.DamageCause, Double> entry : boss.getIncomingMultipliers().entrySet()) {
|
||||
if (event.getCause() == entry.getKey()) {
|
||||
event.setDamage(event.getDamage() * entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.listeners;
|
||||
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import com.willfp.ecobosses.bosses.EcoBosses;
|
||||
import com.willfp.ecobosses.events.EcoBossSpawnTimerEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class AutoSpawnTimer implements Runnable {
|
||||
private int tick = 0;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
tick++;
|
||||
|
||||
for (EcoBoss boss : EcoBosses.values()) {
|
||||
if (boss.getAutoSpawnInterval() < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (boss.getAutoSpawnLocations().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<World> worlds = new HashSet<>();
|
||||
|
||||
for (Entity entity : boss.getLivingBosses().keySet()) {
|
||||
if (entity == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
worlds.add(entity.getWorld());
|
||||
}
|
||||
|
||||
List<Location> locations = new ArrayList<>(boss.getAutoSpawnLocations());
|
||||
locations.removeIf(location -> worlds.contains(location.getWorld()));
|
||||
|
||||
if (locations.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boss.setTimeUntilSpawn(boss.getTimeUntilSpawn()-1);
|
||||
|
||||
if (tick % boss.getAutoSpawnInterval() == 0) {
|
||||
Location location = locations.get(NumberUtils.randInt(0, locations.size() - 1));
|
||||
EcoBossSpawnTimerEvent event = new EcoBossSpawnTimerEvent(boss, location);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
boss.spawn(location);
|
||||
boss.setTimeUntilSpawn(boss.getAutoSpawnInterval());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.listeners;
|
||||
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.events.EntityDeathByEntityEvent;
|
||||
import com.willfp.eco.core.tuples.Pair;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import com.willfp.ecobosses.bosses.util.BossUtils;
|
||||
import com.willfp.ecobosses.bosses.util.obj.DamagerProperty;
|
||||
import com.willfp.ecobosses.bosses.util.obj.OptionedSound;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.SlimeSplitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DeathListeners extends PluginDependent<EcoPlugin> implements Listener {
|
||||
/**
|
||||
* Create new death listeners.
|
||||
*
|
||||
* @param plugin Instance of EcoBosses.
|
||||
*/
|
||||
public DeathListeners(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a boss dies.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler
|
||||
public void onBossDeath(@NotNull final EntityDeathByEntityEvent event) {
|
||||
LivingEntity entity = event.getVictim();
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (OptionedSound sound : boss.getDeathSounds()) {
|
||||
entity.getWorld().playSound(entity.getLocation(), sound.sound(), sound.volume(), sound.pitch());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle drops and experience.
|
||||
*
|
||||
* @param event The event.
|
||||
*/
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onOtherDeath(@NotNull final EntityDeathEvent event) {
|
||||
LivingEntity entity = event.getEntity();
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<DamagerProperty> topDamagers = BossUtils.getTopDamagers(entity);
|
||||
|
||||
DamagerProperty top = null;
|
||||
DamagerProperty second = null;
|
||||
DamagerProperty third = null;
|
||||
|
||||
if (topDamagers.size() >= 1) {
|
||||
top = topDamagers.get(0);
|
||||
}
|
||||
if (topDamagers.size() >= 2) {
|
||||
second = topDamagers.get(1);
|
||||
}
|
||||
if (topDamagers.size() >= 3) {
|
||||
third = topDamagers.get(2);
|
||||
}
|
||||
|
||||
String na = this.getPlugin().getLangYml().getString("na");
|
||||
|
||||
String topDamager = top == null ? na : Bukkit.getPlayer(top.playerUUID()) != null ? Bukkit.getPlayer(top.playerUUID()).getDisplayName() : na;
|
||||
String topDamage = top == null ? na : StringUtils.internalToString(top.damage());
|
||||
|
||||
String secondDamager = second == null ? na : Bukkit.getPlayer(second.playerUUID()) != null ? Bukkit.getPlayer(second.playerUUID()).getDisplayName() : na;
|
||||
String secondDamage = second == null ? na : StringUtils.internalToString(second.damage());
|
||||
|
||||
String thirdDamager = third == null ? na : Bukkit.getPlayer(third.playerUUID()) != null ? Bukkit.getPlayer(third.playerUUID()).getDisplayName() : na;
|
||||
String thirdDamage = third == null ? na : StringUtils.internalToString(third.damage());
|
||||
|
||||
for (String spawnMessage : boss.getDeathMessages()) {
|
||||
Bukkit.broadcastMessage(spawnMessage
|
||||
.replace("%top%", topDamager)
|
||||
.replace("%top_damage%", topDamage)
|
||||
.replace("%second%", secondDamager)
|
||||
.replace("%second_damage%", secondDamage)
|
||||
.replace("%third%", thirdDamager)
|
||||
.replace("%third_damage%", thirdDamage)
|
||||
);
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 3; i++) {
|
||||
List<Pair<Double, String>> topDamagerCommands = boss.getTopDamagerCommands().get(i);
|
||||
for (Pair<Double, String> pair : topDamagerCommands) {
|
||||
if (top != null && i == 1) {
|
||||
if (NumberUtils.randFloat(0, 100) < pair.getFirst()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), pair.getSecond().replace("%player%", Bukkit.getOfflinePlayer(top.playerUUID()).getName()));
|
||||
}
|
||||
}
|
||||
if (second != null && i == 2) {
|
||||
if (NumberUtils.randFloat(0, 100) < pair.getFirst()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), pair.getSecond().replace("%player%", Bukkit.getOfflinePlayer(second.playerUUID()).getName()));
|
||||
}
|
||||
}
|
||||
if (third != null && i == 3) {
|
||||
if (NumberUtils.randFloat(0, 100) < pair.getFirst()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), pair.getSecond().replace("%player%", Bukkit.getOfflinePlayer(third.playerUUID()).getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<ItemStack> drops = boss.generateDrops();
|
||||
|
||||
for (Entity nearby : entity.getNearbyEntities(boss.getNearbyRadius(), boss.getNearbyRadius(), boss.getNearbyRadius())) {
|
||||
if (nearby instanceof Player) {
|
||||
String playerName = nearby.getName();
|
||||
for (Map.Entry<String, Double> entry : boss.getNearbyPlayersCommands().entrySet()) {
|
||||
if (NumberUtils.randFloat(0, 100) < entry.getValue()) {
|
||||
Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), entry.getKey().replace("%player%", playerName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event.getDrops().addAll(drops);
|
||||
event.setDroppedExp(boss.getExperienceOptions().generateXp());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void preventSplit(@NotNull final SlimeSplitEvent event) {
|
||||
LivingEntity entity = event.getEntity();
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.listeners;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import com.willfp.ecobosses.bosses.util.BossUtils;
|
||||
import org.bukkit.entity.Boat;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spigotmc.event.entity.EntityMountEvent;
|
||||
|
||||
public class PassiveListeners extends PluginDependent<EcoPlugin> implements Listener {
|
||||
/**
|
||||
* Create new attack listeners.
|
||||
*
|
||||
* @param plugin Instance of EcoBosses.
|
||||
*/
|
||||
public PassiveListeners(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player attacks a boss.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onMount(@NotNull final EntityMountEvent event) {
|
||||
if (!(event.getEntity() instanceof LivingEntity entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getMount() instanceof Boat || event.getMount() instanceof Minecart)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = BossUtils.getBoss(entity);
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (boss.isDisableBoats()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPickup(@NotNull final EntityPickupItemEvent event) {
|
||||
EcoBoss boss = BossUtils.getBoss(event.getEntity());
|
||||
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.listeners;
|
||||
|
||||
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.events.EcoBossSpawnEggEvent;
|
||||
import com.willfp.ecobosses.events.EcoBossSpawnTotemEvent;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SpawnListeners extends PluginDependent<EcoPlugin> implements Listener {
|
||||
/**
|
||||
* Create new spawn listeners and link them to a plugin.
|
||||
*
|
||||
* @param plugin The plugin to link to.
|
||||
*/
|
||||
public SpawnListeners(@NotNull final EcoPlugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on block place.
|
||||
*
|
||||
* @param event The event to listen for.
|
||||
*/
|
||||
@EventHandler
|
||||
public void spawnTotem(@NotNull final BlockPlaceEvent event) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Block block1;
|
||||
Block block2;
|
||||
Block block3;
|
||||
|
||||
if (i == 0) {
|
||||
block3 = event.getBlock();
|
||||
block2 = event.getBlock().getRelative(0, -1, 0);
|
||||
block1 = event.getBlock().getRelative(0, -2, 0);
|
||||
} else if (i == 1) {
|
||||
block1 = event.getBlock();
|
||||
block2 = event.getBlock().getRelative(0, 1, 0);
|
||||
block3 = event.getBlock().getRelative(0, 2, 0);
|
||||
} else {
|
||||
block2 = event.getBlock();
|
||||
block1 = event.getBlock().getRelative(0, -1, 0);
|
||||
block3 = event.getBlock().getRelative(0, 1, 0);
|
||||
}
|
||||
|
||||
SpawnTotem placedTotem = new SpawnTotem(block1.getType(), block2.getType(), block3.getType());
|
||||
|
||||
for (EcoBoss boss : EcoBosses.values()) {
|
||||
if (boss.isSpawnTotemEnabled()) {
|
||||
if (!boss.getSpawnTotemDisabledWorldNames().contains(event.getBlock().getWorld().getName().toLowerCase())) {
|
||||
if (boss.getSpawnTotem().equals(placedTotem)) {
|
||||
|
||||
if (!boss.areRequirementsMet(event.getPlayer())) {
|
||||
event.getPlayer().sendMessage(this.getPlugin().getLangYml().getMessage("requirements-not-met"));
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBossSpawnTotemEvent eggEvent = new EcoBossSpawnTotemEvent(boss, event.getPlayer(), event.getBlock().getLocation(), placedTotem);
|
||||
|
||||
this.getPlugin().getServer().getPluginManager().callEvent(eggEvent);
|
||||
|
||||
if (!eggEvent.isCancelled()) {
|
||||
block1.setType(Material.AIR);
|
||||
block2.setType(Material.AIR);
|
||||
block3.setType(Material.AIR);
|
||||
boss.spawn(event.getBlock().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void spawnEgg(@NotNull final PlayerInteractEvent event) {
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack item = event.getItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
if (!container.has(this.getPlugin().getNamespacedKeyFactory().create("spawn_egg"), PersistentDataType.STRING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String id = container.get(this.getPlugin().getNamespacedKeyFactory().create("spawn_egg"), PersistentDataType.STRING);
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBoss boss = EcoBosses.getByName(id);
|
||||
if (boss == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
event.setUseItemInHand(Event.Result.DENY);
|
||||
|
||||
if (!boss.areRequirementsMet(event.getPlayer())) {
|
||||
event.getPlayer().sendMessage(this.getPlugin().getLangYml().getMessage("requirements-not-met"));
|
||||
return;
|
||||
}
|
||||
|
||||
EcoBossSpawnEggEvent eggEvent = new EcoBossSpawnEggEvent(boss, event.getPlayer(), event.getClickedBlock().getLocation(), item);
|
||||
|
||||
this.getPlugin().getServer().getPluginManager().callEvent(eggEvent);
|
||||
|
||||
if (eggEvent.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getHand() == EquipmentSlot.HAND) {
|
||||
ItemStack hand = event.getPlayer().getInventory().getItemInMainHand();
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
} else {
|
||||
ItemStack hand = event.getPlayer().getInventory().getItemInOffHand();
|
||||
hand.setAmount(hand.getAmount() - 1);
|
||||
}
|
||||
|
||||
Block block = event.getClickedBlock();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boss.spawn(block.getLocation().add(0, 1.5, 0));
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util;
|
||||
|
||||
import com.willfp.ecobosses.EcoBossesPlugin;
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import com.willfp.ecobosses.bosses.EcoBosses;
|
||||
import com.willfp.ecobosses.bosses.util.obj.DamagerProperty;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.boss.KeyedBossBar;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BossUtils {
|
||||
/**
|
||||
* Instance of EcoBosses.
|
||||
*/
|
||||
private static final EcoBossesPlugin PLUGIN = EcoBossesPlugin.getInstance();
|
||||
|
||||
/**
|
||||
* Get {@link EcoBoss} from an entity.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @return The boss, or null if not a boss.
|
||||
*/
|
||||
@Nullable
|
||||
public EcoBoss getBoss(@NotNull final LivingEntity entity) {
|
||||
if (!entity.getPersistentDataContainer().has(PLUGIN.getNamespacedKeyFactory().create("boss"), PersistentDataType.STRING)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String bossName = entity.getPersistentDataContainer().get(PLUGIN.getNamespacedKeyFactory().create("boss"), PersistentDataType.STRING);
|
||||
|
||||
if (bossName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return EcoBosses.getByName(bossName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get top damagers for a boss.
|
||||
*
|
||||
* @param entity The boss entity.
|
||||
* @return A list of the top damagers, sorted.
|
||||
*/
|
||||
public List<DamagerProperty> getTopDamagers(@NotNull final LivingEntity entity) {
|
||||
if (getBoss(entity) == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<DamagerProperty> topDamagers;
|
||||
if (entity.hasMetadata("ecobosses-top-damagers")) {
|
||||
topDamagers = (List<DamagerProperty>) entity.getMetadata("ecobosses-top-damagers").get(0).value();
|
||||
} else {
|
||||
topDamagers = new ArrayList<>();
|
||||
}
|
||||
assert topDamagers != null;
|
||||
|
||||
topDamagers.sort(Comparator.comparingDouble(DamagerProperty::damage));
|
||||
Collections.reverse(topDamagers);
|
||||
|
||||
return topDamagers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill all bosses.
|
||||
*
|
||||
* @return The amount of bosses killed.
|
||||
*/
|
||||
public int killAllBosses() {
|
||||
return killAllBosses(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Kill all bosses.
|
||||
*
|
||||
* @param force If all entities should be checked for being bosses.
|
||||
* @return The amount of bosses killed.
|
||||
*/
|
||||
public int killAllBosses(final boolean force) {
|
||||
int amount = 0;
|
||||
for (EcoBoss boss : EcoBosses.values()) {
|
||||
for (LivingEntity entity : boss.getLivingBosses().keySet()) {
|
||||
assert entity != null;
|
||||
entity.damage(10000000);
|
||||
amount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (force) {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
for (Entity entity : world.getEntities()) {
|
||||
if (!(entity instanceof LivingEntity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BossUtils.getBoss((LivingEntity) entity) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<KeyedBossBar> bars = new ArrayList<>();
|
||||
Bukkit.getBossBars().forEachRemaining(bars::add);
|
||||
for (KeyedBossBar bar : bars) {
|
||||
if (bar.getKey().toString().startsWith("ecobosses:boss")) {
|
||||
BossBar bossBar = Bukkit.getBossBar(bar.getKey());
|
||||
assert bossBar != null;
|
||||
bossBar.removeAll();
|
||||
bossBar.setVisible(false);
|
||||
Bukkit.removeBossBar(bar.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get player from entity if player or projectile.
|
||||
*
|
||||
* @param entity The entity.
|
||||
* @return The player, or null if not a player.
|
||||
*/
|
||||
@Nullable
|
||||
public Player getPlayerFromEntity(@NotNull final Entity entity) {
|
||||
Player player = null;
|
||||
|
||||
if (entity instanceof Player) {
|
||||
player = (Player) entity;
|
||||
} else if (entity instanceof Projectile) {
|
||||
if (((Projectile) entity).getShooter() instanceof Player) {
|
||||
player = (Player) ((Projectile) entity).getShooter();
|
||||
}
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
|
||||
public record BossbarProperties(BossBar.Color color, BossBar.Overlay style) {
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record DamagerProperty(UUID playerUUID, double damage) {
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record EquipmentPiece(@NotNull ItemStack itemStack,
|
||||
double chance) {
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
|
||||
public record ExperienceOptions(int minimum, int maximum) {
|
||||
/**
|
||||
* Generate an exp amount.
|
||||
*
|
||||
* @return The amount.
|
||||
*/
|
||||
public int generateXp() {
|
||||
return NumberUtils.randInt(minimum, maximum);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
public record ImmunityOptions(boolean immuneToFire,
|
||||
boolean immuneToSuffocation,
|
||||
boolean immuneToDrowning,
|
||||
boolean immuneToProjectiles,
|
||||
boolean immuneToExplosions) {
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.willfp.ecobosses.bosses.util.obj;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
|
||||
public record OptionedSound(Sound sound,
|
||||
float volume,
|
||||
float pitch) {
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package com.willfp.ecobosses.events;
|
||||
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EcoBossSpawnEggEvent extends EcoBossSpawnEvent {
|
||||
/**
|
||||
* The egg item.
|
||||
*/
|
||||
@NotNull
|
||||
private final ItemStack egg;
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param boss - The boss to be spawned.
|
||||
* @param player - The player that spawned this boss (can be null)
|
||||
* @param location - The location that boss will spawn at.
|
||||
* @param egg - ItemStack that represents the egg.
|
||||
*/
|
||||
public EcoBossSpawnEggEvent(@NotNull EcoBoss boss, @Nullable Player player, @NotNull Location location, @NotNull ItemStack egg) {
|
||||
super(boss, player, location);
|
||||
this.egg = egg;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final ItemStack getEgg() {
|
||||
return this.egg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handlers.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handler list.
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
package com.willfp.ecobosses.events;
|
||||
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* This class represents all boss spawn events fired by EcoBosses.
|
||||
*/
|
||||
public class EcoBossSpawnEvent extends Event implements Cancellable {
|
||||
/**
|
||||
* Event cancellation state.
|
||||
*/
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* The boss to be spawned.
|
||||
*/
|
||||
private final EcoBoss boss;
|
||||
|
||||
/**
|
||||
* Location that boss will be spawned at.
|
||||
*/
|
||||
private final Location location;
|
||||
|
||||
/**
|
||||
* Player that spawned this boss.
|
||||
* (Will be null if EcoBossSpawnTimerEvent is fired)
|
||||
*/
|
||||
@Nullable
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
*
|
||||
* Default constructor
|
||||
*
|
||||
* @param boss - The boss to be spawned.
|
||||
* @param player - The player that spawned this boss (can be null)
|
||||
* @param location - The location that boss will spawn at.
|
||||
*/
|
||||
public EcoBossSpawnEvent(@NotNull final EcoBoss boss, @Nullable final Player player, @NotNull final Location location) {
|
||||
this.cancelled = false;
|
||||
this.boss = boss;
|
||||
this.location = location;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the EcoBoss.
|
||||
*
|
||||
* @return - EcoBoss to be spawned.
|
||||
*/
|
||||
@NotNull
|
||||
public EcoBoss getBoss() {
|
||||
return this.boss;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the location.
|
||||
*
|
||||
* @return - Location.
|
||||
*/
|
||||
@NotNull
|
||||
public Location getLocation() {
|
||||
return this.location;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the player if present.
|
||||
*
|
||||
* @return - The player.
|
||||
*/
|
||||
@Nullable
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Check if this event has any player presented.
|
||||
*
|
||||
* @return - If any player is presented in this event.
|
||||
*/
|
||||
public boolean hasPlayer() {
|
||||
return this.player != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handlers.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get if event is cancelled.
|
||||
*
|
||||
* @return Event cancellation state.
|
||||
*/
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Set event cancellation state.
|
||||
*
|
||||
* @param b - The state to set.
|
||||
*/
|
||||
@Override
|
||||
public void setCancelled(boolean b) {
|
||||
this.cancelled = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handler list.
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.willfp.ecobosses.events;
|
||||
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EcoBossSpawnTimerEvent extends EcoBossSpawnEvent {
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param boss - The boss to be spawned.
|
||||
* @param location - The location that boss will spawn at.
|
||||
*/
|
||||
public EcoBossSpawnTimerEvent(@NotNull EcoBoss boss, @NotNull Location location) {
|
||||
super(boss, null, location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handlers.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handler list.
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package com.willfp.ecobosses.events;
|
||||
|
||||
import com.willfp.ecobosses.bosses.EcoBoss;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class EcoBossSpawnTotemEvent extends EcoBossSpawnEvent {
|
||||
/**
|
||||
* The totem.
|
||||
*/
|
||||
@NotNull
|
||||
private final SpawnTotem totem;
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*/
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param boss - The boss to be spawned.
|
||||
* @param player - The player that spawned this boss (can be null)
|
||||
* @param location - The location that boss will spawn at.
|
||||
* @param totem - The totem.
|
||||
*/
|
||||
public EcoBossSpawnTotemEvent(@NotNull final EcoBoss boss, @Nullable final Player player, @NotNull final Location location, @NotNull final SpawnTotem totem) {
|
||||
super(boss, player, location);
|
||||
this.totem = totem;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SpawnTotem getTotem() {
|
||||
return this.totem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handlers.
|
||||
*/
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bukkit parity.
|
||||
*
|
||||
* @return The handler list.
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ 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.AutospawnHandler
|
||||
import com.willfp.ecobosses.spawn.SpawnEggHandler
|
||||
import com.willfp.ecobosses.spawn.SpawnTotemHandler
|
||||
import com.willfp.ecobosses.util.DiscoverRecipeListener
|
||||
@@ -31,6 +32,8 @@ class EcoBossesPlugin : LibReforgePlugin(525, 10635, "&9") {
|
||||
|
||||
override fun handleReloadAdditional() {
|
||||
logger.info(EcoBosses.values().size.toString() + " Bosses Loaded")
|
||||
|
||||
AutospawnHandler.startSpawning(this)
|
||||
}
|
||||
|
||||
override fun loadPluginCommands(): List<PluginCommand> {
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.willfp.ecobosses.util.SpawnTotem
|
||||
import com.willfp.ecobosses.util.XpReward
|
||||
import com.willfp.ecobosses.util.topDamagers
|
||||
import com.willfp.libreforge.Holder
|
||||
import com.willfp.libreforge.conditions.ConfiguredCondition
|
||||
import com.willfp.libreforge.conditions.Conditions
|
||||
import com.willfp.libreforge.effects.Effects
|
||||
import net.kyori.adventure.bossbar.BossBar
|
||||
import org.bukkit.Bukkit
|
||||
@@ -126,18 +126,36 @@ class EcoBoss(
|
||||
}
|
||||
|
||||
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
|
||||
Material.getMaterial(config.getString("spawn.totem.top")) ?: return@run null,
|
||||
Material.getMaterial(config.getString("spawn.totem.middle")) ?: return@run null,
|
||||
Material.getMaterial(config.getString("spawn.totem.bottom")) ?: return@run null
|
||||
)
|
||||
}
|
||||
|
||||
val disabledTotemWorlds: List<String> = config.getStrings("config.totem.notInWorlds")
|
||||
val disabledTotemWorlds: List<String> = config.getStrings("spawn.totem.notInWorlds")
|
||||
|
||||
val autoSpawnInterval = config.getInt("spawn.autospawn.interval")
|
||||
|
||||
val autoSpawnLocations: List<Location> = run {
|
||||
val locations = mutableListOf<Location>()
|
||||
|
||||
for (config in config.getSubsections("spawn.autospawn.locations")) {
|
||||
val world = Bukkit.getWorld(config.getString("world")) ?: continue
|
||||
val x = config.getDouble("x")
|
||||
val y = config.getDouble("y")
|
||||
val z = config.getDouble("z")
|
||||
locations.add(
|
||||
Location(
|
||||
world, x, y, z
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
locations
|
||||
}
|
||||
|
||||
val spawnConditions = config.getSubsections("spawn.conditions").mapNotNull {
|
||||
Conditions.compile(it, "$id Spawn Conditions")
|
||||
}
|
||||
|
||||
private val bossBarColor = BossBar.Color.valueOf(config.getString("bossBar.color").uppercase())
|
||||
@@ -233,7 +251,9 @@ class EcoBoss(
|
||||
|
||||
private val currentlyAlive = mutableMapOf<UUID, LivingEcoBoss>()
|
||||
|
||||
override val conditions = emptySet<ConfiguredCondition>()
|
||||
override val conditions = config.getSubsections("conditions").mapNotNull {
|
||||
Conditions.compile(it, "Boss ID $id")
|
||||
}.toSet()
|
||||
|
||||
override val effects = config.getSubsections("effects").mapNotNull {
|
||||
Effects.compile(it, "Boss ID $id")
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.willfp.ecobosses.spawn
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.ecobosses.bosses.Bosses
|
||||
|
||||
object AutospawnHandler {
|
||||
private var tick = 1
|
||||
|
||||
fun startSpawning(plugin: EcoPlugin) {
|
||||
plugin.scheduler.runTimer(1, 1) {
|
||||
for (boss in Bosses.values()) {
|
||||
if (boss.autoSpawnInterval < 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (tick % boss.autoSpawnInterval != 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
val location = boss.autoSpawnLocations.randomOrNull() ?: continue
|
||||
val world = location.world ?: continue
|
||||
|
||||
if (Bosses.getAllAlive().mapNotNull { it.entity }.map { it.world } == world) {
|
||||
continue
|
||||
}
|
||||
|
||||
boss.spawn(location)
|
||||
}
|
||||
|
||||
tick++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,12 @@ class SpawnEggHandler : Listener {
|
||||
|
||||
val location = event.clickedBlock?.location?.add(0.0, 1.5, 0.0) ?: return
|
||||
|
||||
val player = event.player
|
||||
|
||||
if (!boss.spawnConditions.all { it.condition.isConditionMet(player, it.config) }) {
|
||||
return
|
||||
}
|
||||
|
||||
val spawnEvent = BossSpawnEvent(boss, location, BossSpawnEvent.SpawnReason.EGG)
|
||||
|
||||
Bukkit.getPluginManager().callEvent(spawnEvent)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.willfp.ecobosses.spawn
|
||||
|
||||
import com.willfp.eco.util.containsIgnoreCase
|
||||
import com.willfp.ecobosses.bosses.EcoBosses
|
||||
import com.willfp.ecobosses.bosses.Bosses
|
||||
import com.willfp.ecobosses.events.BossSpawnEvent
|
||||
import com.willfp.ecobosses.util.SpawnTotem
|
||||
import org.bukkit.Material
|
||||
@@ -40,7 +40,7 @@ class SpawnTotemHandler : Listener {
|
||||
}
|
||||
|
||||
val placedTotem = SpawnTotem(block1.type, block2.type, block3.type)
|
||||
for (boss in EcoBosses.values()) {
|
||||
for (boss in Bosses.values()) {
|
||||
if (boss.totem == null || boss.disabledTotemWorlds.containsIgnoreCase(event.block.world.name)) {
|
||||
continue
|
||||
}
|
||||
@@ -49,6 +49,12 @@ class SpawnTotemHandler : Listener {
|
||||
continue
|
||||
}
|
||||
|
||||
val player = event.player
|
||||
|
||||
if (!boss.spawnConditions.all { it.condition.isConditionMet(player, it.config) }) {
|
||||
return
|
||||
}
|
||||
|
||||
val spawnEvent = BossSpawnEvent(boss, event.block.location, BossSpawnEvent.SpawnReason.TOTEM)
|
||||
|
||||
if (!spawnEvent.isCancelled) {
|
||||
|
||||
@@ -24,6 +24,8 @@ bosses:
|
||||
displayName: "&8Steel Golem &7| &c%health%♥ &7| &e%time%"
|
||||
influence: 40
|
||||
effects: [ ]
|
||||
conditions: [ ]
|
||||
lifespan: 120
|
||||
defence:
|
||||
preventMounts: true
|
||||
explosionImmune: true
|
||||
@@ -59,6 +61,7 @@ bosses:
|
||||
style: solid
|
||||
radius: 120
|
||||
spawn:
|
||||
conditions: [ ]
|
||||
autospawn:
|
||||
interval: -1
|
||||
locations:
|
||||
|
||||
Reference in New Issue
Block a user