3.0.0-SNAPSHOT-U30

+ Fully implemented Boss listeners for damage handling
+ Switched around the bosses.json layout a bit to handle multiple mobs per boss easier
+ Updated mechanics to handle all bosses in a activebossholder
This commit is contained in:
AMinecraftDev 2018-10-21 15:09:51 +08:00
parent 5397f90843
commit 234f814f94
28 changed files with 660 additions and 180 deletions

View File

@ -1,35 +1,37 @@
{
"SkeletonKing": {
"editing": true,
"mainStats": [
{
"position": 1,
"entityType": "SKELETON",
"health": 500,
"displayName": "&6&lSkeleton King Boss"
}
],
"spawnItem": "SKSpawnItem",
"equipment": {
"helmet": "SKHelmet",
"chestplate": "SKChestplate",
"leggings": "SKLeggings",
"boots": "SKBoots"
},
"hands": {
"mainHand": "SKMainHand",
"offHand": "SKOffHand"
},
"potions": [
"entityStats": [
{
"type": "resistance",
"level": 3,
"duration": -1
},
{
"type": "speed",
"level": 1,
"duration": 500
"mainStats": {
"position": 1,
"entityType": "SKELETON",
"health": 500,
"displayName": "&6&lSkeleton King Boss"
},
"equipment": {
"helmet": "SKHelmet",
"chestplate": "SKChestplate",
"leggings": "SKLeggings",
"boots": "SKBoots"
},
"hands": {
"mainHand": "SKMainHand",
"offHand": "SKOffHand"
},
"potions": [
{
"type": "resistance",
"level": 3,
"duration": -1
},
{
"type": "speed",
"level": 1,
"duration": 500
}
]
}
],
"skills": {
@ -52,7 +54,9 @@
},
"onDeath": {
"message": "SKOnDeath",
"radius": -1
"positionMessage": "SKPosition",
"radius": -1,
"onlyShow": 3
},
"taunts": {
"delay": 60,

View File

@ -15,12 +15,13 @@
"&e{boss}&f has been killed,",
"&fbelow are the top damagers:",
"&7",
"&6&l#1 &e{pos1}&f - &e{pos1%}% &f(&e{pos1dmg} dmg&f)",
"&6&l#2 &e{pos2}&f - &e{pos2%}% &f(&e{pos2dmg} dmg&f)",
"&6&l#3 &e{pos3}&f - &e{pos3%}% &f(&e{pos3dmg} dmg&f)",
"{positions}",
"&7",
"&8&m-----*--------------------*-----"
],
"SKPosition": [
"&6&l#{pos} &e{name}&f - &e{percent}% &f(&e{dmg} dmg&f)"
],
"SKTaunt1": [
"&6&lSkeleton King &f» &7My pocket knife is sharper then that sword! &o*cackle*"
],

View File

@ -105,22 +105,27 @@ public class BossAPI {
if (entityFinder == null) return null;
List<MainStatsElement> mainStatsElements = new ArrayList<>(Arrays.asList(new MainStatsElement()));
EquipmentElement equipmentElement = new EquipmentElement();
HandsElement handsElement = new HandsElement();
List<PotionEffectHolder> potionEffectHolders = new ArrayList<>();
List<EntityStatsElement> entityStatsElements = new ArrayList<>();
EntityStatsElement entityStatsElement = new EntityStatsElement();
MainStatsElement mainStatsElement = new MainStatsElement();
mainStatsElement.setHealth(50D);
mainStatsElement.setDisplayName(name);
mainStatsElement.setEntityType(entityFinder.getFancyName());
entityStatsElement.setMainStats(mainStatsElement);
entityStatsElement.setEquipment(new EquipmentElement());
entityStatsElement.setHands(new HandsElement());
entityStatsElement.setPotions(new ArrayList<>());
entityStatsElements.add(entityStatsElement);
SkillsElement skillsElement = new SkillsElement();
DropsElement dropsElement = new DropsElement();
MessagesElement messagesElement = new MessagesElement();
CommandsElement commandsElement = new CommandsElement();
BossEntity bossEntity = new BossEntity(true, null, mainStatsElements, equipmentElement, handsElement, potionEffectHolders, skillsElement, dropsElement, messagesElement, commandsElement);
MainStatsElement mainStatsElement = mainStatsElements.get(0);
mainStatsElement.setEntityType(entityFinder.getFancyName());
mainStatsElement.setDisplayName(name);
mainStatsElement.setHealth(50D);
BossEntity bossEntity = new BossEntity(true, null, entityStatsElements, skillsElement, dropsElement, messagesElement, commandsElement);
boolean result = PLUGIN.getBossEntityContainer().saveData(name, bossEntity);
if (!result) {

View File

@ -15,26 +15,19 @@ import java.util.List;
*/
public class BossEntity {
@Expose @Getter private final List<PotionEffectHolder> potions;
@Expose @Getter private final List<MainStatsElement> mainStats;
@Expose @Getter private final EquipmentElement equipment;
@Expose @Getter private final List<EntityStatsElement> entityStats;
@Expose @Getter private final MessagesElement messages;
@Expose @Getter private final CommandsElement commands;
@Expose @Getter private final SkillsElement skills;
@Expose @Getter private final HandsElement hands;
@Expose @Getter private final DropsElement drops;
@Expose @Getter @Setter private String spawnItem;
@Expose @Getter @Setter private boolean editing;
public BossEntity(boolean editing, String spawnItem, List<MainStatsElement> mainStats, EquipmentElement equipment, HandsElement hands, List<PotionEffectHolder> potions,
SkillsElement skills, DropsElement drops, MessagesElement messages, CommandsElement commands) {
public BossEntity(boolean editing, String spawnItem, List<EntityStatsElement> entityStats, SkillsElement skills, DropsElement drops, MessagesElement messages, CommandsElement commands) {
this.editing = editing;
this.mainStats = mainStats;
this.spawnItem = spawnItem;
this.equipment = equipment;
this.hands = hands;
this.potions = potions;
this.entityStats = entityStats;
this.skills = skills;
this.drops = drops;
this.messages = messages;

View File

@ -0,0 +1,22 @@
package net.aminecraftdev.custombosses.entity.elements;
import com.google.gson.annotations.Expose;
import lombok.Getter;
import lombok.Setter;
import net.aminecraftdev.custombosses.utils.potion.holder.PotionEffectHolder;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 21-Oct-18
*/
public class EntityStatsElement {
@Expose @Getter @Setter private MainStatsElement mainStats;
@Expose @Getter @Setter private EquipmentElement equipment;
@Expose @Getter @Setter private HandsElement hands;
@Expose @Getter @Setter private List<PotionEffectHolder> potions;
}

View File

@ -11,7 +11,8 @@ import lombok.Setter;
*/
public class MessagesElement {
@Expose @Getter @Setter private SubMessageElement onSpawn, onDeath;
@Expose @Getter @Setter private OnSpawnMessageElement onSpawn;
@Expose @Getter @Setter private OnDeathMessageElement onDeath;
@Expose @Getter @Setter private TauntElement taunts;
}

View File

@ -0,0 +1,16 @@
package net.aminecraftdev.custombosses.entity.elements;
import com.google.gson.annotations.Expose;
import lombok.Getter;
import lombok.Setter;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 21-Oct-18
*/
public class OnDeathMessageElement {
@Expose @Getter @Setter private String message, positionMessage;
@Expose @Getter @Setter private Integer radius, onlyShow;
}

View File

@ -7,10 +7,11 @@ import lombok.Setter;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 20-Oct-18
* @since 21-Oct-18
*/
public class SubMessageElement {
public class OnSpawnMessageElement {
@Expose @Getter @Setter private String message;
@Expose @Getter @Setter private Integer radius;
}

View File

@ -0,0 +1,31 @@
package net.aminecraftdev.custombosses.events;
import lombok.Getter;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 21-Oct-18
*/
public class BossDeathEvent extends Event {
private static final HandlerList handlers = new HandlerList();
@Getter private ActiveBossHolder activeBossHolder;
public BossDeathEvent(ActiveBossHolder activeBossHolder) {
this.activeBossHolder = activeBossHolder;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,34 @@
package net.aminecraftdev.custombosses.events;
import lombok.Getter;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import org.bukkit.Location;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 21-Oct-18
*/
public class PreBossDeathEvent extends Event {
private static final HandlerList handlers = new HandlerList();
@Getter private ActiveBossHolder activeBossHolder;
@Getter private Location location;
public PreBossDeathEvent(ActiveBossHolder activeBossHolder, Location location) {
this.activeBossHolder = activeBossHolder;
this.location = location;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,142 @@
package net.aminecraftdev.custombosses.listeners.after;
import net.aminecraftdev.custombosses.CustomBosses;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.events.BossDeathEvent;
import net.aminecraftdev.custombosses.events.PreBossDeathEvent;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.managers.BossEntityManager;
import net.aminecraftdev.custombosses.utils.NumberUtils;
import net.aminecraftdev.custombosses.utils.ServerUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 20-Oct-18
*/
public class BossDeathListener implements Listener {
private BossEntityManager bossEntityManager;
public BossDeathListener(CustomBosses plugin) {
this.bossEntityManager = plugin.getBossEntityManager();
}
@EventHandler
public void onDeath(EntityDeathEvent event) {
LivingEntity livingEntity = event.getEntity();
EntityDamageEvent entityDamageEvent = livingEntity.getLastDamageCause();
ActiveBossHolder activeBossHolder = this.bossEntityManager.getActiveBossHolder(livingEntity);
Location location = livingEntity.getLocation();
if(activeBossHolder == null) return;
EntityDamageEvent.DamageCause damageCause = entityDamageEvent.getCause();
if(damageCause == EntityDamageEvent.DamageCause.VOID || damageCause == EntityDamageEvent.DamageCause.LAVA
|| activeBossHolder.getMapOfDamagingUsers().isEmpty()) {
this.bossEntityManager.removeActiveBossHolder(activeBossHolder);
return;
}
if(this.bossEntityManager.isAllEntitiesDead(activeBossHolder)) {
PreBossDeathEvent preBossDeathEvent = new PreBossDeathEvent(activeBossHolder, location);
ServerUtils.get().callEvent(preBossDeathEvent);
}
}
@EventHandler
public void onPreBossDeath(PreBossDeathEvent event) {
ActiveBossHolder activeBossHolder = event.getActiveBossHolder();
BossEntity bossEntity = activeBossHolder.getBossEntity();
Location location = event.getLocation();
List<String> commands = this.bossEntityManager.getOnDeathCommands(bossEntity);
List<String> messages = this.bossEntityManager.getOnDeathMessage(bossEntity);
int messageRadius = this.bossEntityManager.getOnDeathMessageRadius(bossEntity);
int onlyShow = this.bossEntityManager.getOnDeathShowAmount(bossEntity);
if(commands != null) {
commands.forEach(command -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command));
}
ServerUtils.get().runTaskAsync(() -> {
List<String> positionsMessage = this.bossEntityManager.getOnDeathPositionMessage(bossEntity);
if(messages != null) {
if(positionsMessage != null) {
Map<UUID, Double> mapOfDamage = this.bossEntityManager.getSortedMapOfDamage(activeBossHolder);
List<String> finalPositionsMessage = new ArrayList<>();
int current = 1;
for(Map.Entry<UUID, Double> entry : mapOfDamage.entrySet()) {
if(current > onlyShow) break;
List<String> clonedPositionsMessage = new ArrayList<>(positionsMessage);
double percentage = this.bossEntityManager.getPercentage(activeBossHolder, entry.getKey());
int position = current;
clonedPositionsMessage.replaceAll(s -> s
.replace("{pos}", ""+position)
.replace("{name}", Bukkit.getOfflinePlayer(entry.getKey()).getName())
.replace("{dmg}", NumberUtils.get().formatDouble(entry.getValue()))
.replace("{percent}", NumberUtils.get().formatDouble(percentage))
.replace('&', '§'));
finalPositionsMessage.addAll(clonedPositionsMessage);
current++;
}
positionsMessage = finalPositionsMessage;
}
if(activeBossHolder.getName() != null) messages.replaceAll(s -> s.replace("{boss}", activeBossHolder.getName()));
messages.replaceAll(s -> s.replace('&', '§'));
List<String> finalMessage = new ArrayList<>();
for(String s : messages) {
if(s.contains("{positions}") && positionsMessage != null) {
finalMessage.addAll(positionsMessage);
} else {
finalMessage.add(s);
}
}
if(messageRadius == -1) {
finalMessage.forEach(Bukkit::broadcastMessage);
} else {
Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
if(onlinePlayer.getWorld().getName().equals(location.getWorld().getName())) {
if(onlinePlayer.getLocation().distanceSquared(location) <= messageRadius) {
finalMessage.forEach(s -> onlinePlayer.sendMessage(s));
}
}
});
}
}
});
//TODO: Handle DropTable
BossDeathEvent bossDeathEvent = new BossDeathEvent(activeBossHolder);
ServerUtils.get().callEvent(bossDeathEvent);
}
}

View File

@ -136,7 +136,7 @@ public class BossSpawnListener implements Listener {
Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
if(onlinePlayer.getWorld().getName().equals(location.getWorld().getName())) {
if(onlinePlayer.getLocation().distanceSquared(location) <= messagesRadius) {
messages.forEach(player::sendMessage);
messages.forEach(s -> onlinePlayer.sendMessage(s));
}
}
});
@ -144,6 +144,7 @@ public class BossSpawnListener implements Listener {
}
//TODO: Create AutoTarget for TargetHandler
//TODO: Handle Taunts
BossSpawnEvent bossSpawnEvent = new BossSpawnEvent(activeBossHolder);

View File

@ -14,10 +14,8 @@ import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author Charles Cullen
@ -28,15 +26,11 @@ public class BossEntityManager {
private static final List<ActiveBossHolder> ACTIVE_BOSS_HOLDERS = new ArrayList<>();
private BossMessagesFileManager bossMessagesFileManager;
private BossCommandFileManager bossCommandFileManager;
private BossItemFileManager bossItemFileManager;
private BossMechanicManager bossMechanicManager;
private BossesFileManager bossesFileManager;
public BossEntityManager(CustomBosses customBosses) {
this.bossMessagesFileManager = customBosses.getBossMessagesFileManager();
this.bossCommandFileManager = customBosses.getBossCommandFileManager();
this.bossMechanicManager = customBosses.getBossMechanicManager();
this.bossItemFileManager = customBosses.getItemStackManager();
this.bossesFileManager = customBosses.getBossesFileManager();
@ -92,6 +86,58 @@ public class BossEntityManager {
return commands;
}
public List<String> getOnDeathMessage(BossEntity bossEntity) {
String id = bossEntity.getMessages().getOnDeath().getMessage();
List<String> messages = BossAPI.getStoredMessages(id);
if(messages == null) {
Debug.FAILED_TO_LOAD_MESSAGES.debug(id);
return null;
}
return messages;
}
public int getOnDeathMessageRadius(BossEntity bossEntity) {
Integer radius = bossEntity.getMessages().getOnDeath().getRadius();
if(radius == null) radius = -1;
return radius;
}
public int getOnDeathShowAmount(BossEntity bossEntity) {
Integer onlyShow = bossEntity.getMessages().getOnDeath().getOnlyShow();
if(onlyShow == null) onlyShow = 3;
return onlyShow;
}
public List<String> getOnDeathPositionMessage(BossEntity bossEntity) {
String id = bossEntity.getMessages().getOnDeath().getPositionMessage();
List<String> messages = BossAPI.getStoredMessages(id);
if(messages == null) {
Debug.FAILED_TO_LOAD_MESSAGES.debug(id);
return null;
}
return messages;
}
public List<String> getOnDeathCommands(BossEntity bossEntity) {
String id = bossEntity.getCommands().getOnDeath();
List<String> commands = BossAPI.getStoredCommands(id);
if(commands == null) {
Debug.FAILED_TO_LOAD_COMMANDS.debug(id);
return null;
}
return commands;
}
public Map<BossEntity, ItemStack> getMapOfEntitiesAndSpawnItems() {
Map<String, BossEntity> currentEntities = new HashMap<>(this.bossesFileManager.getBossEntities());
Map<BossEntity, ItemStack> newMap = new HashMap<>();
@ -125,4 +171,44 @@ public class BossEntityManager {
return null;
}
public void removeActiveBossHolder(ActiveBossHolder activeBossHolder) {
for(Map.Entry<Integer, LivingEntity> entry : activeBossHolder.getLivingEntityMap().entrySet()) {
if(!entry.getValue().isDead()) entry.getValue().remove();
}
ACTIVE_BOSS_HOLDERS.remove(activeBossHolder);
}
public boolean isAllEntitiesDead(ActiveBossHolder activeBossHolder) {
for(Map.Entry<Integer, LivingEntity> entry : activeBossHolder.getLivingEntityMap().entrySet()) {
if(!entry.getValue().isDead()) return false;
}
return true;
}
public Map<UUID, Double> getSortedMapOfDamage(ActiveBossHolder activeBossHolder) {
Map<UUID, Double> unsortedMap = activeBossHolder.getMapOfDamagingUsers();
Map<UUID, Double> sortedMap;
sortedMap = unsortedMap.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));
return sortedMap;
}
public double getPercentage(ActiveBossHolder activeBossHolder, UUID uuid) {
Map<UUID, Double> damagingUsers = activeBossHolder.getMapOfDamagingUsers();
double totalDamage = 0.0;
for(Double damage : damagingUsers.values()) {
if(damage != null) totalDamage += damage;
}
double playerDamage = damagingUsers.get(uuid);
double onePercent = totalDamage / 100;
return playerDamage / onePercent;
}
}

View File

@ -1,6 +1,7 @@
package net.aminecraftdev.custombosses.managers;
import net.aminecraftdev.custombosses.CustomBosses;
import net.aminecraftdev.custombosses.listeners.after.BossDeathListener;
import net.aminecraftdev.custombosses.listeners.during.BossDamageListener;
import net.aminecraftdev.custombosses.listeners.pre.BossSpawnListener;
import net.aminecraftdev.custombosses.utils.Debug;
@ -32,7 +33,7 @@ public class BossListenerManager implements ILoadable {
serverUtils.registerListener(new BossSpawnListener(this.plugin));
serverUtils.registerListener(new BossDamageListener(this.plugin));
serverUtils.registerListener(new BossDeathListener(this.plugin));
this.hasBeenLoaded = true;
}

View File

@ -7,6 +7,7 @@ import net.aminecraftdev.custombosses.mechanics.*;
import net.aminecraftdev.custombosses.utils.Debug;
import net.aminecraftdev.custombosses.utils.ILoadable;
import net.aminecraftdev.custombosses.utils.IMechanic;
import net.aminecraftdev.custombosses.utils.ServerUtils;
import net.aminecraftdev.custombosses.utils.mechanics.IOptionalMechanic;
import net.aminecraftdev.custombosses.utils.mechanics.IPrimaryMechanic;
@ -66,6 +67,8 @@ public class BossMechanicManager implements ILoadable {
if(mechanic == null) continue;
ServerUtils.get().logDebug("Applying " + mechanic.getClass().getSimpleName());
if(didMechanicApplicationFail(mechanic, bossEntity, activeBossHolder)) return false;
}

View File

@ -1,18 +1,15 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.api.BossAPI;
import net.aminecraftdev.custombosses.container.BossEntityContainer;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.utils.Debug;
import net.aminecraftdev.custombosses.utils.EntityFinder;
import net.aminecraftdev.custombosses.utils.IMechanic;
import net.aminecraftdev.custombosses.utils.mechanics.IPrimaryMechanic;
import org.bukkit.entity.LivingEntity;
import java.util.Map;
/**
* @author Charles Cullen
* @version 1.0.0
@ -22,7 +19,13 @@ public class EntityTypeMechanic implements IPrimaryMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
for(MainStatsElement mainStatsElement : bossEntity.getMainStats()) {
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
System.out.println(entityStatsElement);
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
System.out.println(mainStatsElement);
String bossEntityType = mainStatsElement.getEntityType();
String input = bossEntityType.split(":")[0];
EntityFinder entityFinder = EntityFinder.get(input);

View File

@ -1,7 +1,9 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.EquipmentElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.managers.files.BossItemFileManager;
import net.aminecraftdev.custombosses.utils.IMechanic;
@ -26,53 +28,59 @@ public class EquipmentMechanic implements IOptionalMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
EquipmentElement equipmentElement = bossEntity.getEquipment();
EntityEquipment entityEquipment = livingEntity.getEquipment();
String helmet = equipmentElement.getHelmet();
String chestplate = equipmentElement.getChestplate();
String leggings = equipmentElement.getLeggings();
String boots = equipmentElement.getBoots();
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
if(helmet != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(helmet);
if(livingEntity == null) return false;
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
EquipmentElement equipmentElement = entityStatsElement.getEquipment();
EntityEquipment entityEquipment = livingEntity.getEquipment();
String helmet = equipmentElement.getHelmet();
String chestplate = equipmentElement.getChestplate();
String leggings = equipmentElement.getLeggings();
String boots = equipmentElement.getBoots();
entityEquipment.setHelmet(itemStack);
if(helmet != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(helmet);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setHelmet(itemStack);
}
}
}
if(chestplate != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(chestplate);
if(chestplate != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(chestplate);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setChestplate(itemStack);
entityEquipment.setChestplate(itemStack);
}
}
}
if(leggings != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(leggings);
if(leggings != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(leggings);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setLeggings(itemStack);
entityEquipment.setLeggings(itemStack);
}
}
}
if(boots != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(boots);
if(boots != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(boots);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setBoots(itemStack);
entityEquipment.setBoots(itemStack);
}
}
}

View File

@ -1,9 +1,12 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.utils.Debug;
import net.aminecraftdev.custombosses.utils.IMechanic;
import net.aminecraftdev.custombosses.utils.ServerUtils;
import net.aminecraftdev.custombosses.utils.file.reader.SpigotYmlReader;
import net.aminecraftdev.custombosses.utils.mechanics.IPrimaryMechanic;
import org.bukkit.entity.LivingEntity;
@ -17,20 +20,27 @@ public class HealthMechanic implements IPrimaryMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(bossEntity.getMainStats().isEmpty() || bossEntity.getMainStats().get(0) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
double maxHealthSetting = (double) SpigotYmlReader.get().getObject("settings.attribute.maxHealth.max");
double maxHealth = bossEntity.getMainStats().get(0).getHealth();
if(maxHealth > maxHealthSetting) {
Debug.MAX_HEALTH.debug(maxHealthSetting);
return false;
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
double maxHealth = mainStatsElement.getHealth();
if(livingEntity == null) return false;
if(maxHealth > maxHealthSetting) {
Debug.MAX_HEALTH.debug(maxHealthSetting);
return false;
}
livingEntity.setMaxHealth(maxHealth);
livingEntity.setHealth(maxHealth);
}
livingEntity.setMaxHealth(maxHealth);
livingEntity.setHealth(maxHealth);
return true;
}
}

View File

@ -1,7 +1,10 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.utils.Debug;
import net.aminecraftdev.custombosses.utils.IMechanic;
import net.aminecraftdev.custombosses.utils.StringUtils;
import net.aminecraftdev.custombosses.utils.mechanics.IOptionalMechanic;
@ -18,16 +21,19 @@ public class NameMechanic implements IOptionalMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(bossEntity.getMainStats().isEmpty() || bossEntity.getMainStats().get(0) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
String customName = mainStatsElement.getDisplayName();
String customName = bossEntity.getMainStats().get(0).getDisplayName();
if(livingEntity == null) return false;
if(customName != null) {
livingEntity.setCustomName(StringUtils.get().translateColor(customName));
livingEntity.setCustomNameVisible(true);
if(customName != null) {
livingEntity.setCustomName(StringUtils.get().translateColor(customName));
livingEntity.setCustomNameVisible(true);
}
}
return true;

View File

@ -1,8 +1,11 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.utils.IMechanic;
import net.aminecraftdev.custombosses.utils.StringUtils;
import net.aminecraftdev.custombosses.utils.mechanics.IOptionalMechanic;
import net.aminecraftdev.custombosses.utils.potion.PotionEffectConverter;
import net.aminecraftdev.custombosses.utils.potion.holder.PotionEffectHolder;
@ -25,13 +28,18 @@ public class PotionMechanic implements IOptionalMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
List<PotionEffectHolder> potionElements = bossEntity.getPotions();
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
List<PotionEffectHolder> potionElements = entityStatsElement.getPotions();
if(potionElements != null && !potionElements.isEmpty()) {
potionElements.forEach(potionElement -> livingEntity.addPotionEffect(this.potionEffectConverter.from(potionElement)));
if(livingEntity == null) return false;
if(potionElements != null && !potionElements.isEmpty()) {
potionElements.forEach(potionElement -> livingEntity.addPotionEffect(this.potionEffectConverter.from(potionElement)));
}
}
return true;

View File

@ -1,6 +1,8 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.utils.Debug;
import net.aminecraftdev.custombosses.utils.IMechanic;
@ -26,23 +28,29 @@ public class SettingsMechanic implements IPrimaryMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
EntityEquipment entityEquipment = livingEntity.getEquipment();
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
livingEntity.setRemoveWhenFarAway(false);
livingEntity.setCanPickupItems(false);
entityEquipment.setHelmetDropChance(0.0F);
entityEquipment.setChestplateDropChance(0.0F);
entityEquipment.setLeggingsDropChance(0.0F);
entityEquipment.setBootsDropChance(0.0F);
if(livingEntity == null) return false;
if(this.versionHandler.canUseOffHand()) {
entityEquipment.setItemInMainHandDropChance(0.0F);
entityEquipment.setItemInOffHandDropChance(0.0F);
} else {
entityEquipment.setItemInHandDropChance(0.0F);
EntityEquipment entityEquipment = livingEntity.getEquipment();
livingEntity.setRemoveWhenFarAway(false);
livingEntity.setCanPickupItems(false);
entityEquipment.setHelmetDropChance(0.0F);
entityEquipment.setChestplateDropChance(0.0F);
entityEquipment.setLeggingsDropChance(0.0F);
entityEquipment.setBootsDropChance(0.0F);
if(this.versionHandler.canUseOffHand()) {
entityEquipment.setItemInMainHandDropChance(0.0F);
entityEquipment.setItemInOffHandDropChance(0.0F);
} else {
entityEquipment.setItemInHandDropChance(0.0F);
}
}
return true;

View File

@ -1,7 +1,10 @@
package net.aminecraftdev.custombosses.mechanics;
import net.aminecraftdev.custombosses.entity.BossEntity;
import net.aminecraftdev.custombosses.entity.elements.EntityStatsElement;
import net.aminecraftdev.custombosses.entity.elements.EquipmentElement;
import net.aminecraftdev.custombosses.entity.elements.HandsElement;
import net.aminecraftdev.custombosses.entity.elements.MainStatsElement;
import net.aminecraftdev.custombosses.holder.ActiveBossHolder;
import net.aminecraftdev.custombosses.managers.files.BossItemFileManager;
import net.aminecraftdev.custombosses.utils.IMechanic;
@ -29,38 +32,44 @@ public class WeaponMechanic implements IOptionalMechanic {
@Override
public boolean applyMechanic(BossEntity bossEntity, ActiveBossHolder activeBossHolder) {
if(activeBossHolder.getLivingEntityMap().getOrDefault(0, null) == null) return false;
if(activeBossHolder.getLivingEntityMap().getOrDefault(1, null) == null) return false;
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(0, null);
EntityEquipment entityEquipment = livingEntity.getEquipment();
HandsElement handsElement = bossEntity.getHands();
String mainHand = handsElement.getMainHand();
String offHand = handsElement.getOffHand();
for(EntityStatsElement entityStatsElement : bossEntity.getEntityStats()) {
MainStatsElement mainStatsElement = entityStatsElement.getMainStats();
LivingEntity livingEntity = activeBossHolder.getLivingEntityMap().getOrDefault(mainStatsElement.getPosition(), null);
if(mainHand != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(mainHand);
if(livingEntity == null) return false;
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
EntityEquipment entityEquipment = livingEntity.getEquipment();
HandsElement handsElement = entityStatsElement.getHands();
String mainHand = handsElement.getMainHand();
String offHand = handsElement.getOffHand();
if(this.versionHandler.canUseOffHand()) {
entityEquipment.setItemInMainHand(itemStack);
} else {
entityEquipment.setItemInHand(itemStack);
if(mainHand != null) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(mainHand);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
if(this.versionHandler.canUseOffHand()) {
entityEquipment.setItemInMainHand(itemStack);
} else {
entityEquipment.setItemInHand(itemStack);
}
}
}
if(offHand != null && this.versionHandler.canUseOffHand()) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(offHand);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setItemInOffHand(itemStack);
}
}
}
if(offHand != null && this.versionHandler.canUseOffHand()) {
ItemStackHolder itemStackHolder = this.itemStackManager.getItemStackHolder(offHand);
if(itemStackHolder != null) {
ItemStack itemStack = this.itemStackManager.getItemStackConverter().from(itemStackHolder);
entityEquipment.setItemInOffHand(itemStack);
}
}
return false;
return true;
}
}

View File

@ -1,5 +1,6 @@
package net.aminecraftdev.custombosses.utils;
import lombok.Getter;
import org.bukkit.enchantments.Enchantment;
import java.util.ArrayList;
@ -44,9 +45,9 @@ public enum EnchantFinder {
mending("Mending", Enchantment.MENDING, "mending"),
curse_of_vanishing("Curse of Vanishing", Enchantment.VANISHING_CURSE, "vanishing", "vanishing curse", "vanishing_curse", "curseofvanishing", "vanishingcurse", "curse of vanishing", "curse_of_vanishing");
private Enchantment enchantment;
private String fancyName;
private List<String> names = new ArrayList<>();
@Getter private List<String> names = new ArrayList<>();
@Getter private Enchantment enchantment;
@Getter private String fancyName;
EnchantFinder(String fancyName, Enchantment enchantment, String... names) {
this.fancyName = fancyName;
@ -56,18 +57,6 @@ public enum EnchantFinder {
this.names.add(fancyName);
}
public Enchantment getEnchantment() {
return enchantment;
}
public List<String> getNames() {
return names;
}
public String getFancyName() {
return fancyName;
}
public static EnchantFinder getByName(String name) {
for(EnchantFinder enchantFinder : values()) {
List<String> names = enchantFinder.getNames();

View File

@ -1,5 +1,7 @@
package net.aminecraftdev.custombosses.utils;
import java.text.DecimalFormat;
/**
* @author Charles Cullen
* @version 1.0.0
@ -41,6 +43,12 @@ public class NumberUtils {
return Double.valueOf(input);
}
public String formatDouble(double d) {
DecimalFormat decimalFormat = new DecimalFormat("###,###,###,###,###.##");
return decimalFormat.format(d);
}
public static NumberUtils get() {
return INSTANCE;
}

View File

@ -0,0 +1,79 @@
package net.aminecraftdev.custombosses.utils;
import lombok.Getter;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Charles Cullen
* @version 1.0.0
* @since 21-Oct-18
*/
public enum PotionEffectFinder {
Absorption("Absorption", PotionEffectType.ABSORPTION),
Blindness("Blind", PotionEffectType.BLINDNESS, "blindness", "cantsee"),
ConduitPower("ConduitPower", PotionEffectType.CONDUIT_POWER, "conduit", "conduit_power"),
Confusion("Confusion", PotionEffectType.CONFUSION, "nausea"),
Resistance("Resistance", PotionEffectType.DAMAGE_RESISTANCE, "damage_resistance", "res", "damageresistance"),
DolphinsGrace("DolphinsGrace", PotionEffectType.DOLPHINS_GRACE, "grace", "dolphins_grace"),
Haste("Haste", PotionEffectType.FAST_DIGGING, "fast_digging", "haste"),
Fire_Resistance("FireResistance", PotionEffectType.FIRE_RESISTANCE, "fire_resistance", "fire_resist", "fire_res", "fireresist", "fireres"),
Glowing("Glowing", PotionEffectType.GLOWING),
Harm("Harm", PotionEffectType.HARM, "damage"),
Heal("Heal", PotionEffectType.HEAL),
HealthBoost("HealthBoost", PotionEffectType.HEALTH_BOOST, "healthboost", "health_boost"),
Hunger("Hunger", PotionEffectType.HUNGER, "starve", "starving"),
Strength("Strength", PotionEffectType.INCREASE_DAMAGE, "increase_damage", "increasedamage"),
Invisibility("Invisibility", PotionEffectType.INVISIBILITY),
Jump("Jump", PotionEffectType.JUMP),
Levitation("Levitation", PotionEffectType.LEVITATION),
Luck("Luck", PotionEffectType.LUCK),
NightVision("NightVision", PotionEffectType.NIGHT_VISION, "seeinthedarkness", "nv", "night_vision"),
Posion("Posion", PotionEffectType.POISON, "witched"),
Regen("regen", PotionEffectType.REGENERATION, "regeneration"),
Saturation("Saturation", PotionEffectType.SATURATION, "saturated"),
Slow("Slow", PotionEffectType.SLOW, "tank"),
MiningFatigue("MiningFatigue", PotionEffectType.SLOW_DIGGING, "slow_digging"),
SlowFalling("SlowFalling", PotionEffectType.SLOW_FALLING, "slow_falling"),
Speed("Speed", PotionEffectType.SPEED, "fast", "fastboots"),
Unluck("Unlucky", PotionEffectType.UNLUCK, "unluck", "notlucky"),
WaterBreathing("WaterBreathing", PotionEffectType.WATER_BREATHING, "breathunderwater", "water_breathing", "fish"),
Weakness("Weakness", PotionEffectType.WEAKNESS),
Wither("Wither", PotionEffectType.WITHER, "blackhearts");
@Getter private List<String> names = new ArrayList<>();
@Getter private PotionEffectType potionEffectType;
@Getter private String fancyName;
PotionEffectFinder(String fancyName, PotionEffectType potionEffectType, String... names) {
this.fancyName = fancyName;
this.potionEffectType = potionEffectType;
this.names.addAll(Arrays.asList(names));
this.names.add(fancyName);
}
public static PotionEffectFinder getByName(String name) {
for(PotionEffectFinder potionEffectFinder : values()) {
List<String> names = potionEffectFinder.getNames();
for(String s : names) {
if(s.equalsIgnoreCase(name)) return potionEffectFinder;
}
}
return null;
}
public static PotionEffectFinder getByEffect(PotionEffectType potionEffectType) {
for(PotionEffectFinder potionEffectFinder : values()) {
if(potionEffectType.equals(potionEffectFinder.getPotionEffectType())) return potionEffectFinder;
}
return null;
}
}

View File

@ -33,8 +33,10 @@ public class PotionEffectConverter implements IConverter<PotionEffectHolder, Pot
String potionEffectType = potionHolder.getType();
Integer duration = potionHolder.getDuration();
Integer level = potionHolder.getLevel();
PotionEffectType potionEffectTypeConverted = this.potionEffectTypeConverter.from(potionEffectType);
if(potionEffectType != null && duration != null && level != null) return new PotionEffect(this.potionEffectTypeConverter.from(potionEffectType), level-1, (duration*20));
if(potionEffectTypeConverted == null) return null;
if(potionEffectType != null && duration != null && level != null) return new PotionEffect(potionEffectTypeConverted, level-1, (duration*20));
return null;
}

View File

@ -1,6 +1,7 @@
package net.aminecraftdev.custombosses.utils.potion.converters;
import net.aminecraftdev.custombosses.utils.IConverter;
import net.aminecraftdev.custombosses.utils.PotionEffectFinder;
import org.bukkit.potion.PotionEffectType;
/**
@ -12,11 +13,19 @@ public class PotionEffectTypeConverter implements IConverter<String, PotionEffec
@Override
public String to(PotionEffectType potionEffectType) {
return potionEffectType.getName().toUpperCase();
PotionEffectFinder potionEffectFinder = PotionEffectFinder.getByEffect(potionEffectType);
if(potionEffectFinder == null) return null;
return potionEffectFinder.getFancyName();
}
@Override
public PotionEffectType from(String s) {
return PotionEffectType.getByName(s);
PotionEffectFinder potionEffectFinder = PotionEffectFinder.getByName(s);
if(potionEffectFinder == null) return null;
return potionEffectFinder.getPotionEffectType();
}
}

View File

@ -19,7 +19,7 @@
</modules>
<properties>
<plugin.version>3.0.0-SNAPSHOT-U29</plugin.version>
<plugin.version>3.0.0-SNAPSHOT-U30</plugin.version>
<plugin.name>CustomBosses</plugin.name>
<plugin.main>net.aminecraftdev.custombosses.CustomBosses</plugin.main>
<plugin.author>AMinecraftDev</plugin.author>