Organized common attributes of Bosses into a GenericBoss class.
Completed Personal Loot system for defeating bosses. Implemented all loot for new minibosses.
This commit is contained in:
parent
f404d2fd73
commit
05582519fc
Binary file not shown.
@ -18,6 +18,7 @@ import org.bukkit.potion.PotionEffect;
|
||||
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
|
||||
|
||||
@Deprecated
|
||||
public class BossMonster {
|
||||
private String name;
|
||||
private double maxhp;
|
||||
|
@ -2980,7 +2980,17 @@ public class CustomDamage {
|
||||
dmg += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)shooter, ItemSet.OLIVE, 3, 3);
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.PANROS, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.DAWNTRACKER, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.LUCI, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.WINDRY, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.SHARD, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.TOXIN, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.PROTECTOR, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.SUSTENANCE, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.LEGION, 5) ||
|
||||
ItemSet.HasSetBonusBasedOnSetBonusCount((Player)shooter, ItemSet.PRIDE, 5) ||
|
||||
(ItemSet.meetsSlayerSwordConditions(ItemSet.LORASYS, 9, 1, (Player)shooter)) ||
|
||||
(ItemSet.meetsSlayerSwordConditions(ItemSet.ASSASSIN, 9, 1, (Player)shooter)) ||
|
||||
(ItemSet.meetsSlayerSwordConditions(ItemSet.STEALTH, 9, 1, (Player)shooter)) ||
|
||||
GenericFunctions.HasFullRangerSet((Player)shooter)) {
|
||||
dmg += 15;
|
||||
}
|
||||
@ -3448,8 +3458,38 @@ public class CustomDamage {
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.DAWNTRACKER, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.WINDRY, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.LUCI, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.SHARD, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.TOXIN, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.PROTECTOR, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.SUSTENANCE, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.LEGION, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.HasSetBonusBasedOnSetBonusCount(p, ItemSet.PRIDE, 5)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.meetsSlayerSwordConditions(ItemSet.LORASYS, 9, 1, p)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.meetsSlayerSwordConditions(ItemSet.ASSASSIN, 9, 1, p)) {
|
||||
finaldmg += dmg*0.5;
|
||||
} else
|
||||
if (ItemSet.meetsSlayerSwordConditions(ItemSet.STEALTH, 9, 1, p)) {
|
||||
finaldmg += dmg*0.5;
|
||||
}
|
||||
finaldmg += dmg*aPlugin.API.getPlayerBonuses(p).getBonusArmorPenetration();
|
||||
if (Buff.hasBuff(p, "WINDCHARGE") &&
|
||||
|
@ -99,4 +99,14 @@ public class CustomMonster {
|
||||
|
||||
public void bloodPoolSpawnedEvent(LivingEntity target) {
|
||||
}
|
||||
|
||||
public void AnnounceDPSBreakdown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 0.0 means cannot be moved, 1.0 means normal knockback.
|
||||
*/
|
||||
public double getKnockbackMult() {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
99
src/sig/plugin/TwosideKeeper/GlobalLoot.java
Normal file
99
src/sig/plugin/TwosideKeeper/GlobalLoot.java
Normal file
@ -0,0 +1,99 @@
|
||||
package sig.plugin.TwosideKeeper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
|
||||
|
||||
public class GlobalLoot {
|
||||
Item item;
|
||||
String lootname;
|
||||
UUID item_uuid;
|
||||
HashMap<UUID,Inventory> drop_inventories = new HashMap<UUID,Inventory>();
|
||||
HashMap<UUID,Long> last_opened_loot = new HashMap<UUID,Long>();
|
||||
|
||||
GlobalLoot(Location spawnLoc, String lootName) {
|
||||
item = (Item)spawnLoc.getWorld().dropItemNaturally(spawnLoc, new ItemStack(Material.CHEST));
|
||||
item_uuid = item.getUniqueId();
|
||||
item.setCustomName(lootName);
|
||||
item.setCustomNameVisible(true);
|
||||
item.setPickupDelay(Integer.MAX_VALUE);
|
||||
item.setInvulnerable(true);
|
||||
this.lootname = lootName;
|
||||
}
|
||||
|
||||
public void runInventoryCloseEvent(InventoryCloseEvent ev) {
|
||||
Player p = (Player)ev.getPlayer();
|
||||
if (drop_inventories.containsKey(p.getUniqueId()) &&
|
||||
ev.getInventory().getTitle()!=null &&
|
||||
ev.getInventory().getTitle().equalsIgnoreCase(lootname)) {
|
||||
last_opened_loot.put(p.getUniqueId(), TwosideKeeper.getServerTickTime());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean runTick() {
|
||||
if ((item!=null && item.isValid())) {
|
||||
List<Player> players = GenericFunctions.getNearbyPlayers(item.getLocation(), 1);
|
||||
for (Player p : players) {
|
||||
if (p.getOpenInventory().getType()==InventoryType.CRAFTING &&
|
||||
drop_inventories.containsKey(p.getUniqueId())) {
|
||||
if (!last_opened_loot.containsKey(p.getUniqueId()) ||
|
||||
last_opened_loot.get(p.getUniqueId())+100<=TwosideKeeper.getServerTickTime()) {
|
||||
last_opened_loot.put(p.getUniqueId(), TwosideKeeper.getServerTickTime());
|
||||
p.openInventory(drop_inventories.get(p.getUniqueId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public UUID getItemUniqueID() {
|
||||
return item_uuid;
|
||||
}
|
||||
|
||||
public void addNewDropInventory(Player p, ItemStack...lootitems) {
|
||||
if (drop_inventories.containsKey(p.getUniqueId())) {
|
||||
Inventory inv = drop_inventories.get(p.getUniqueId());
|
||||
inv.addItem(lootitems);
|
||||
} else {
|
||||
Inventory newinv = Bukkit.createInventory(p, ((((lootitems.length-1)/9)+1)*9),this.lootname);
|
||||
newinv.addItem(lootitems);
|
||||
drop_inventories.put(p.getUniqueId(), newinv);
|
||||
}
|
||||
}
|
||||
|
||||
public void openDropInventory(Player p) {
|
||||
if (drop_inventories.containsKey(p.getUniqueId())) {
|
||||
p.openInventory(drop_inventories.get(p.getUniqueId()));
|
||||
} else {
|
||||
TwosideKeeper.log("WARNING! Drop Inventory for Player with UUID <"+p.getUniqueId()+"> does not have an associated inventory with Global Loot <"+item.getUniqueId()+">. THIS SHOULD NOT BE HAPPENING!!", 1);
|
||||
p.sendMessage(ChatColor.RED+"Something terrible has happened! "+ChatColor.RESET+"Please let the server administrator know about this.");
|
||||
}
|
||||
}
|
||||
|
||||
public static GlobalLoot spawnGlobalLoot(Location loc, String lootName) {
|
||||
GlobalLoot loot = new GlobalLoot(loc,lootName);
|
||||
TwosideKeeper.globalloot.put(loot.getItem().getUniqueId(), loot);
|
||||
return loot;
|
||||
}
|
||||
}
|
@ -15,5 +15,5 @@ public enum ArtifactItem {
|
||||
DIVINE_CORE,
|
||||
DIVINE_BASE,
|
||||
MALLEABLE_BASE,
|
||||
ARTIFACT_RECIPE
|
||||
ARTIFACT_RECIPE;
|
||||
}
|
||||
|
@ -2615,7 +2615,9 @@ public class GenericFunctions {
|
||||
return ItemSet.hasFullSet(p, ItemSet.ALIKAHN) ||
|
||||
ItemSet.hasFullSet(p, ItemSet.DARNYS) ||
|
||||
ItemSet.hasFullSet(p, ItemSet.JAMDAK) ||
|
||||
ItemSet.hasFullSet(p, ItemSet.LORASAADI);
|
||||
ItemSet.hasFullSet(p, ItemSet.LORASAADI) ||
|
||||
ItemSet.hasFullSet(p, ItemSet.TOXIN) ||
|
||||
ItemSet.hasFullSet(p, ItemSet.SHARD);
|
||||
/*int rangerarmort1 = 0; //Count the number of each tier of sets. //LEGACY CODE.
|
||||
int rangerarmort2 = 0;
|
||||
int rangerarmort3 = 0;
|
||||
|
@ -154,6 +154,48 @@ public class CustomItem {
|
||||
return item_VacuumCube.clone();
|
||||
}
|
||||
|
||||
public static ItemStack IronMaterialKit() {
|
||||
ItemStack kit = new ItemStack(Material.IRON_BLOCK);
|
||||
ItemUtils.setDisplayName(kit, ChatColor.translateAlternateColorCodes('§', "§7§lIron Material Kit"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Converts an item's base material"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7to §rIron§7 and hardens it."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§eIncreases Breaks Remaining."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Right-click an item on a pedestal to use."));
|
||||
kit.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||
ItemUtils.addFlag(kit, ItemFlag.HIDE_ENCHANTS);
|
||||
return kit.clone();
|
||||
}
|
||||
|
||||
public static ItemStack DiamondMaterialKit() {
|
||||
ItemStack kit = new ItemStack(Material.DIAMOND_BLOCK);
|
||||
ItemUtils.setDisplayName(kit, ChatColor.translateAlternateColorCodes('§', "§b§lDiamond Material Kit"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Converts an item's base material"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7to §bDiamond§7."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§aApplies Unbreaking and Mending."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Right-click an item on a pedestal to use."));
|
||||
kit.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||
ItemUtils.addFlag(kit, ItemFlag.HIDE_ENCHANTS);
|
||||
return kit.clone();
|
||||
}
|
||||
|
||||
public static ItemStack GoldMaterialKit() {
|
||||
ItemStack kit = new ItemStack(Material.GOLD_BLOCK);
|
||||
ItemUtils.setDisplayName(kit, ChatColor.translateAlternateColorCodes('§', "§e§lGold Material Kit"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Converts an item's base material"));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7to §eGold§7."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§cMay degrade the item."));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', ""));
|
||||
ItemUtils.addLore(kit, ChatColor.translateAlternateColorCodes('§', "§7Right-click an item on a pedestal to use."));
|
||||
kit.addUnsafeEnchantment(Enchantment.DURABILITY, 1);
|
||||
ItemUtils.addFlag(kit, ItemFlag.HIDE_ENCHANTS);
|
||||
return kit.clone();
|
||||
}
|
||||
|
||||
private static ShapelessRecipe VacuumCubeRecipe() {
|
||||
ItemStack item_VacuumCube = VacuumCube();
|
||||
|
||||
|
@ -821,6 +821,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" with Wind Slash and gain "+(tier)+" Absorption Health.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.GRAY+" (5 second cooldown)");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
case ASSASSIN:
|
||||
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Increases in power based on "+ChatColor.BOLD+"Total Tier Amount");
|
||||
@ -829,6 +832,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.WHITE+" Assassinate enables you to jump to target blocks.");
|
||||
lore.add(ChatColor.WHITE+" Cooldown of Assassinate decreases by 70% when");
|
||||
lore.add(ChatColor.WHITE+" jumping to blocks.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
if (tier>=2) {
|
||||
lore.add(ChatColor.DARK_AQUA+" T18 - ");
|
||||
lore.add(ChatColor.WHITE+" Decreases cooldown of Assassinate by 50% when");
|
||||
@ -857,6 +863,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" going below 1 for "+(tier+6)+" seconds.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.GRAY+" (120s Cooldown)");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+"");
|
||||
lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Lifesteal");
|
||||
lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Health Regeneration");
|
||||
@ -877,6 +886,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" Dodge performed.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.GRAY+" (120s Cooldown)");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
case PRIDE:
|
||||
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
|
||||
@ -888,6 +900,9 @@ public enum ItemSet {
|
||||
lore.add(" "+ChatColor.WHITE+" Poison "+ItemSet.GetBaseAmount(set, tier, 4)+" to everything it hits for 15 seconds.");
|
||||
lore.add(ChatColor.DARK_AQUA+" 5 - "+ChatColor.WHITE+" "+ABILITY_LABEL+"Sweep Up"+ABILITY_LABEL_END+" (Shift+Right-Click) heals");
|
||||
lore.add(" "+ChatColor.WHITE+" half the health it deals as HP directly.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+"");
|
||||
lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Lifesteal");
|
||||
lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Health Regeneration");
|
||||
@ -907,6 +922,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" seconds on all party members.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.GRAY+" (150 second cooldown)");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
case SHARD:
|
||||
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
|
||||
@ -918,6 +936,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" into shrapnel, dealing damage to all nearby targets");
|
||||
lore.add(ChatColor.GRAY+" and dealing ticks of additional fire damage for 10");
|
||||
lore.add(ChatColor.GRAY+" seconds. Shrapnel stacks infinitely on a target.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
case STEALTH:
|
||||
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Increases in power based on "+ChatColor.BOLD+"Total Tier Amount");
|
||||
@ -925,6 +946,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.DARK_AQUA+" T9 - ");
|
||||
lore.add(ChatColor.WHITE+" Stealth does not cause durability to decrease.");
|
||||
lore.add(ChatColor.WHITE+" Stealth does not get removed when getting hit.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
if (tier>=2) {
|
||||
lore.add(ChatColor.DARK_AQUA+" T18 - ");
|
||||
lore.add(ChatColor.WHITE+" Going from Visible to Stealth will remove");
|
||||
@ -953,6 +977,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.DARK_AQUA+" 5 - "+ABILITY_LABEL+" Share the Life"+ABILITY_LABEL_END);
|
||||
lore.add(ChatColor.GRAY+" Increases the Regeneration Pool for other party");
|
||||
lore.add(ChatColor.GRAY+" members by "+(tier)+" whenever you get hit.");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
case TOXIN:
|
||||
lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:");
|
||||
@ -970,6 +997,9 @@ public enum ItemSet {
|
||||
lore.add(ChatColor.GRAY+" is created around it, applying stacking Burn to all");
|
||||
lore.add(ChatColor.GRAY+" enemy targets in the fire pool. (Burn deals more damage");
|
||||
lore.add(ChatColor.GRAY+" as the number of stacks increase.)");
|
||||
lore.add(ChatColor.GRAY+" ");
|
||||
lore.add(ChatColor.WHITE+" +50% Armor Penetration");
|
||||
lore.add(ChatColor.WHITE+" +20 Damage");
|
||||
break;
|
||||
}
|
||||
return lore;
|
||||
|
@ -561,7 +561,9 @@ public class Loot {
|
||||
boolean allowed=true; //Setting this to false will not convert it to a set piece.
|
||||
prefix = (hardened)?(ChatColor.LIGHT_PURPLE+""+ChatColor.BOLD+"Hardened Mega "):(ChatColor.AQUA+""+ChatColor.BOLD+"Mega ");
|
||||
switch (set) {
|
||||
case PANROS:{
|
||||
case PANROS:
|
||||
case WINDRY:
|
||||
case LUCI:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
|
||||
} else
|
||||
@ -570,9 +572,11 @@ public class Loot {
|
||||
allowed = false;
|
||||
}
|
||||
tierbonus = (custom)?tierbonus:modifyTierBonus(item,tierbonus);
|
||||
set_name = prefix+"Panros Striker "+GenericFunctions.UserFriendlyMaterialName(item.getType()); //Striker set.
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Striker "+GenericFunctions.UserFriendlyMaterialName(item.getType()); //Striker set.
|
||||
}break;
|
||||
case SONGSTEEL:{
|
||||
case SONGSTEEL:
|
||||
case PROTECTOR:
|
||||
case SUSTENANCE:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.SHIELD);
|
||||
tierbonus/=(custom)?1:2;
|
||||
@ -582,9 +586,11 @@ public class Loot {
|
||||
allowed = false;
|
||||
}
|
||||
tierbonus = (custom)?tierbonus:modifyTierBonus(item,tierbonus);
|
||||
set_name = prefix+"Songsteel Defender "+GenericFunctions.UserFriendlyMaterialName(item.getType()); //Defender set.
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Defender "+GenericFunctions.UserFriendlyMaterialName(item.getType()); //Defender set.
|
||||
}break;
|
||||
case DAWNTRACKER:{
|
||||
case DAWNTRACKER:
|
||||
case LEGION:
|
||||
case PRIDE:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.valueOf(item.getType().toString().replace("SWORD","")+"AXE"));
|
||||
} else
|
||||
@ -593,50 +599,39 @@ public class Loot {
|
||||
allowed = false;
|
||||
}
|
||||
tierbonus = (custom)?tierbonus:modifyTierBonus(item,tierbonus);
|
||||
set_name = prefix+"Dawntracker Barbarian "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Barbarian "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case LORASYS:{
|
||||
case LORASYS:
|
||||
case ASSASSIN:
|
||||
case STEALTH:{
|
||||
if (!item.getType().toString().contains("SWORD")) {
|
||||
allowed = false;
|
||||
}
|
||||
tierbonus = (custom)?tierbonus:modifyTierBonus(item,tierbonus);
|
||||
set_name = prefix+"Lorasys Slayer "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case JAMDAK:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.BOW);
|
||||
} else
|
||||
if (!item.getType().name().contains("LEATHER") && !item.getType().name().contains("BOW")) {
|
||||
allowed = false;
|
||||
}
|
||||
set_name = prefix+"Jamdak Ranger "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case DARNYS:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.BOW);
|
||||
} else
|
||||
if (!item.getType().toString().contains("LEATHER") && !item.getType().name().contains("BOW")) {
|
||||
allowed = false;
|
||||
}
|
||||
set_name = prefix+"Darnys Ranger "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case ALIKAHN:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.BOW);
|
||||
} else
|
||||
if (!item.getType().toString().contains("LEATHER") && !item.getType().name().contains("BOW")) {
|
||||
allowed = false;
|
||||
}
|
||||
set_name = prefix+"Alikahn Ranger "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Slayer "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case JAMDAK:
|
||||
case SHARD:
|
||||
case TOXIN:
|
||||
case DARNYS:
|
||||
case ALIKAHN:
|
||||
case LORASAADI:{
|
||||
if (item.getType().toString().contains("SWORD")) {
|
||||
item.setType(Material.BOW);
|
||||
} else
|
||||
if (!item.getType().toString().contains("LEATHER") && !item.getType().name().contains("BOW")) {
|
||||
if (item.getType().toString().contains("_HELMET") ||
|
||||
item.getType().toString().contains("_LEGGINGS") ||
|
||||
item.getType().toString().contains("_CHESTPLATE") ||
|
||||
item.getType().toString().contains("_BOOTS")) {
|
||||
String itemstr = item.getType().toString();
|
||||
String[] split = itemstr.split("_");
|
||||
String newstr = "LEATHER_"+split[1];
|
||||
item.setType(Material.valueOf(newstr));
|
||||
} else
|
||||
if (!item.getType().name().contains("LEATHER") && !item.getType().name().contains("BOW")) {
|
||||
allowed = false;
|
||||
}
|
||||
set_name = prefix+"Lorasaadi Ranger "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Ranger "+GenericFunctions.UserFriendlyMaterialName(item.getType());
|
||||
}break;
|
||||
case GLADOMAIN:{
|
||||
//item.setType(Material.SKULL_ITEM); else
|
||||
@ -648,7 +643,7 @@ public class Loot {
|
||||
ItemMeta m = item.getItemMeta();
|
||||
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
item.setItemMeta(m);
|
||||
set_name = prefix+"Gladomain Slayer Amulet";
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Slayer Amulet";
|
||||
}break;
|
||||
case MOONSHADOW:{
|
||||
if (!item.getType().toString().contains("SKULL_ITEM")) {
|
||||
@ -660,7 +655,7 @@ public class Loot {
|
||||
ItemMeta m = item.getItemMeta();
|
||||
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
item.setItemMeta(m);
|
||||
set_name = prefix+"Moonshadow Slayer Trinket";
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Slayer Trinket";
|
||||
}break;
|
||||
case WOLFSBANE:{
|
||||
if (!item.getType().toString().contains("SKULL_ITEM")) {
|
||||
@ -672,7 +667,7 @@ public class Loot {
|
||||
ItemMeta m = item.getItemMeta();
|
||||
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
item.setItemMeta(m);
|
||||
set_name = prefix+"Wolfsbane Slayer Ornament";
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Slayer Ornament";
|
||||
}break;
|
||||
case ALUSTINE:{
|
||||
if (!item.getType().toString().contains("SKULL_ITEM")) {
|
||||
@ -684,7 +679,7 @@ public class Loot {
|
||||
ItemMeta m = item.getItemMeta();
|
||||
m.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
item.setItemMeta(m);
|
||||
set_name = prefix+"Alustine Slayer Charm";
|
||||
set_name = prefix+GenericFunctions.CapitalizeFirstLetters(set.name())+" Slayer Charm";
|
||||
}break;
|
||||
case BLITZEN:
|
||||
case COMET:
|
||||
|
@ -97,8 +97,8 @@ public enum PlayerMode {
|
||||
+ ChatColor.WHITE+"->Whenever a Slayer critically strikes, it suppresses a target for 0.75 seconds. Suppression prevents movement, attacking, teleporting, and exploding. Suppressed targets glow Black.\n"
|
||||
+ ChatColor.GRAY+"->Slayers thrive in 1vs1 situations. If a target is completely alone, they will glow white to the Slayer. Isolated targets take 50% more damage from the Slayer. Slayer's Dodge Chance increases by 40% against isolated targets.\n"
|
||||
+ ChatColor.WHITE+"->Slayers can use the Assassination ability. Press the Drop key while looking at an enemy to perform an assassination: You jump directly behind the enemy, gaining 0.5 seconds of invulnerability. If the next hit after Assassination is performed kills the target, you gain a speed and strength buff. These buffs cap at Speed V and Strength X respectively and last 10 seconds. Assassination cooldown is reset whenever a target is instantly killed in this manner, and you get immediately put back into stealth, preventing further detection from other monsters.\n"),
|
||||
SUMMONER(ChatColor.DARK_PURPLE,"SM","Summoner",
|
||||
ChatColor.DARK_PURPLE+""+ChatColor.BOLD+"Summoner mode Perks: "+ChatColor.RESET+"\n"),
|
||||
/*SUMMONER(ChatColor.DARK_PURPLE,"SM","Summoner",
|
||||
ChatColor.DARK_PURPLE+""+ChatColor.BOLD+"Summoner mode Perks: "+ChatColor.RESET+"\n"),*/
|
||||
NORMAL(ChatColor.WHITE,"A","Adventurer",
|
||||
ChatColor.WHITE+""+ChatColor.BOLD+"Adventurer mode Perks: "+ChatColor.RESET+"\n"
|
||||
+ ChatColor.WHITE+"->Players are identified as 'Adventurers' by default.\n"
|
||||
|
353
src/sig/plugin/TwosideKeeper/Monster/GenericBoss.java
Normal file
353
src/sig/plugin/TwosideKeeper/Monster/GenericBoss.java
Normal file
@ -0,0 +1,353 @@
|
||||
package sig.plugin.TwosideKeeper.Monster;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BossBar;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import sig.plugin.TwosideKeeper.ChargeZombie;
|
||||
import sig.plugin.TwosideKeeper.CustomMonster;
|
||||
import sig.plugin.TwosideKeeper.LivingEntityStructure;
|
||||
import sig.plugin.TwosideKeeper.TwosideKeeper;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Channel;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils;
|
||||
|
||||
public class GenericBoss extends CustomMonster{
|
||||
|
||||
protected List<Player> participantlist = new ArrayList<Player>();
|
||||
protected HashMap<String,Double> dpslist = new HashMap<String,Double>();
|
||||
protected HashMap<String,HashMap<String,Integer>> modelist = new HashMap<String,HashMap<String,Integer>>();
|
||||
BossBar healthbar;
|
||||
protected String arrow = "->";
|
||||
int scroll=0;
|
||||
boolean startedfight=false;
|
||||
private Location lastLoc = null;
|
||||
private long stuckTimer=0;
|
||||
long lasthit;
|
||||
|
||||
public GenericBoss(LivingEntity m) {
|
||||
super(m);
|
||||
}
|
||||
|
||||
public List<Player> getParticipants() {
|
||||
return participantlist;
|
||||
}
|
||||
|
||||
public void runTick() {
|
||||
updateHealthbarForNearbyPlayers();
|
||||
updateTargetIfLost();
|
||||
regenerateHealthAndResetBossIfIdle();
|
||||
keepHealthbarUpdated();
|
||||
unstuckIfStuck();
|
||||
increaseBarTextScroll();
|
||||
}
|
||||
|
||||
protected void increaseBarTextScroll() {
|
||||
scroll++;
|
||||
switch (scroll%22) {
|
||||
case 11:{
|
||||
arrow=" -";
|
||||
}break;
|
||||
case 12:{
|
||||
arrow=" ";
|
||||
}break;
|
||||
case 13:{
|
||||
arrow="> ";
|
||||
}break;
|
||||
case 14:{
|
||||
arrow="->";
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
private void unstuckIfStuck() {
|
||||
if (!startedfight) {
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else
|
||||
if (startedfight) {
|
||||
lastLoc = m.getLocation().clone();
|
||||
if (lastLoc!=null && lastLoc.distance(m.getLocation())<=0.4) {
|
||||
stuckTimer++;
|
||||
//TwosideKeeper.log("Stuck. "+stuckTimer, 0);
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else {
|
||||
stuckTimer=0;
|
||||
}
|
||||
if (!Channel.isChanneling(m) && stuckTimer>5) {
|
||||
//Teleport randomly.
|
||||
double numb = Math.random();
|
||||
if (numb<=0.33) {
|
||||
Location newloc = m.getLocation().add(Math.random()*10-5,0,0);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
} else
|
||||
if (numb<=0.5) {
|
||||
Location newloc = m.getLocation().add(0,0,Math.random()*10-5);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
}
|
||||
stuckTimer=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void keepHealthbarUpdated() {
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
Monster me = (Monster)m;
|
||||
String healthbarfooter = ((me.getTarget()!=null && (me.getTarget() instanceof Player))?(ChatColor.DARK_AQUA+" "+arrow+" "+ChatColor.YELLOW+((Player)me.getTarget()).getName()):"");
|
||||
if (Channel.isChanneling(m)) {
|
||||
healthbar.setTitle(LivingEntityStructure.getChannelingBar(m)+healthbarfooter);
|
||||
} else {
|
||||
healthbar.setTitle(GenericFunctions.getDisplayName(m)+healthbarfooter);
|
||||
}
|
||||
}
|
||||
|
||||
private void regenerateHealthAndResetBossIfIdle() {
|
||||
if (lasthit+20*15<=TwosideKeeper.getServerTickTime()) {
|
||||
GenericFunctions.HealEntity(m, m.getMaxHealth()*0.01);
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.GREEN);
|
||||
}
|
||||
} else {
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
startedfight=false;
|
||||
m.setAI(false);
|
||||
m.setHealth(m.getMaxHealth());
|
||||
announceFailedTakedown();
|
||||
}
|
||||
}
|
||||
|
||||
public void announceFailedTakedown() {
|
||||
if (dpslist.size()>0 && !m.isDead()) {
|
||||
Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed...");
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(GenericFunctions.getDisplayName(m)+" Takedown Failed...\n\n"+ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```");
|
||||
dpslist.clear();
|
||||
healthbar.setColor(BarColor.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTargetIfLost() {
|
||||
Monster mm = (Monster)m;
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m);
|
||||
if (mm.getTarget()==null || !mm.getTarget().isValid() ||
|
||||
les.GetTarget()==null || !mm.getTarget().isValid() ||
|
||||
((mm.getTarget().getLocation().distanceSquared(mm.getLocation())>2500 ||
|
||||
les.GetTarget().getLocation().distanceSquared(mm.getLocation())>2500
|
||||
))) {
|
||||
//See if there's another participant in the list. Choose randomly.
|
||||
while (participantlist.size()>0) {
|
||||
Player p = participantlist.get((int)(Math.random()*participantlist.size()));
|
||||
if (p!=null && p.isValid() && !p.isDead() &&
|
||||
(p.getLocation().distanceSquared(mm.getLocation())<=2500)) {
|
||||
mm.setTarget(p);
|
||||
les.SetTarget(p);
|
||||
break;
|
||||
} else {
|
||||
participantlist.remove(p);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
//This fight has failed.
|
||||
announceFailedTakedown();
|
||||
startedfight=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHealthbarForNearbyPlayers() {
|
||||
for (Player p : healthbar.getPlayers()) {
|
||||
if (p.getWorld().equals(m.getWorld()) && p.getLocation().distanceSquared(m.getLocation())>2500) {
|
||||
healthbar.removePlayer(p);
|
||||
}
|
||||
}
|
||||
for (Entity e : m.getNearbyEntities(50, 50, 50)) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player)e;
|
||||
healthbar.addPlayer(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String generateDPSReport() {
|
||||
//Sorts a list of players by DPS contribution.
|
||||
List<Double> sorted_dmg = new ArrayList<Double>();
|
||||
List<String> sorted_pl = new ArrayList<String>();
|
||||
double totaldmg = 0;
|
||||
for (String pl : dpslist.keySet()) {
|
||||
double dmg = dpslist.get(pl);
|
||||
int slot = 0;
|
||||
totaldmg+=dmg;
|
||||
for (int i=0;i<sorted_dmg.size();i++) {
|
||||
if (dmg>sorted_dmg.get(i)) {
|
||||
break;
|
||||
} else {
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
sorted_pl.add(slot,pl);
|
||||
sorted_dmg.add(slot,dmg);
|
||||
}
|
||||
StringBuilder finalstr = new StringBuilder();
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
for (int i=0;i<sorted_pl.size();i++) {
|
||||
if (finalstr.length()!=0) {
|
||||
finalstr.append("\n");
|
||||
}
|
||||
finalstr.append(sorted_pl.get(i)+": "+df.format(sorted_dmg.get(i))+" dmg ("+df.format((sorted_dmg.get(i)/totaldmg)*100)+"%)");
|
||||
}
|
||||
return finalstr.toString();
|
||||
}
|
||||
|
||||
public void AnnounceDPSBreakdown() {
|
||||
List<Player> participants = getParticipants();
|
||||
StringBuilder participants_list = new StringBuilder();
|
||||
for (int i=0;i<participants.size();i++) {
|
||||
Player pl = participants.get(i);
|
||||
if (pl!=null && pl.isOnline()) {
|
||||
/*ExperienceOrb exp = GenericFunctions.spawnXP(pl.getLocation(), ev.getDroppedExp()*300);
|
||||
exp.setInvulnerable(true);
|
||||
if (m instanceof Zombie) {
|
||||
Zombie z = (Zombie)m;
|
||||
if (z.isBaby()) {
|
||||
GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
}
|
||||
}*/
|
||||
//GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
//log("Dropping "+aPlugin.API.getChestItem(Chests.ELITE).toString(),2);
|
||||
if (participants_list.length()<1) {
|
||||
participants_list.append(pl.getName());
|
||||
} else {
|
||||
if (i==participants.size()-1) {
|
||||
if (participants.size()==2) {
|
||||
participants_list.append(" and "+pl.getName());
|
||||
} else {
|
||||
participants_list.append(", and "+pl.getName());
|
||||
}
|
||||
} else {
|
||||
participants_list.append(", "+pl.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*Item it = m.getWorld().dropItemNaturally(m.getLocation(), aPlugin.API.getChestItem(Chests.ELITE));
|
||||
it.setInvulnerable(true);
|
||||
it.setPickupDelay(0);*/
|
||||
}
|
||||
}
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"!");
|
||||
aPlugin.API.discordSendRaw(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+"**"+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"**!");
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
|
||||
public void run() {
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```");
|
||||
cleanup();
|
||||
}},1);
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
healthbar.removeAll();
|
||||
}
|
||||
|
||||
protected void announceMessageToParticipants(String msg) {
|
||||
for (Player p : participantlist) {
|
||||
p.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void onHitEvent(LivingEntity damager, double damage) {
|
||||
addTarget(damager,damage);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, ()->{
|
||||
m.setVelocity(m.getVelocity().multiply(getKnockbackMult()));
|
||||
}, 1);
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
lasthit=TwosideKeeper.getServerTickTime();
|
||||
if (!startedfight) {
|
||||
startedfight=true;
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
m.setAI(true);
|
||||
}
|
||||
|
||||
private void addTarget(LivingEntity damager, double dmg) {
|
||||
if (damager instanceof Player) {
|
||||
Player p = (Player)damager;
|
||||
addParticipant(p);
|
||||
if (!dpslist.containsKey(p.getName())) {
|
||||
dpslist.put(p.getName(), dmg);
|
||||
} else {
|
||||
dpslist.put(p.getName(), dpslist.get(p.getName())+dmg);
|
||||
}
|
||||
if (!modelist.containsKey(p.getName())) {
|
||||
HashMap<String,Integer> modestruct = new HashMap<String,Integer>();
|
||||
modestruct.put(PlayerMode.getPlayerMode(p).name(), 1);
|
||||
modelist.put(p.getName(), modestruct);
|
||||
} else {
|
||||
HashMap<String,Integer> modestruct = modelist.get(p.getName());
|
||||
if (modestruct.containsKey(PlayerMode.getPlayerMode(p).name())) {
|
||||
Integer amt = modestruct.get(PlayerMode.getPlayerMode(p).name());
|
||||
modestruct.put(PlayerMode.getPlayerMode(p).name(), ++amt);
|
||||
} else {
|
||||
modestruct.put(PlayerMode.getPlayerMode(p).name(), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerMode getMostUsedPlayerMode(Player p) {
|
||||
int highestamt = 0;
|
||||
PlayerMode highestmode = null;
|
||||
if (modelist.containsKey(p.getName())) {
|
||||
HashMap<String,Integer> modestruct = modelist.get(p.getName());
|
||||
for (String s : modestruct.keySet()) {
|
||||
PlayerMode pm = PlayerMode.valueOf(s);
|
||||
int amt = modestruct.get(s);
|
||||
if (highestamt<amt) {
|
||||
highestamt=amt;
|
||||
highestmode=pm;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (highestmode!=null) {
|
||||
return highestmode;
|
||||
} else {
|
||||
return PlayerMode.NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
public void addParticipant(Player p) {
|
||||
if (!participantlist.contains(p)) {
|
||||
participantlist.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupBonusLoot() {
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -30,6 +30,10 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.entity.Skeleton.SkeletonType;
|
||||
import org.inventivetalent.glow.GlowAPI.Color;
|
||||
|
||||
import aPlugin.DropRandomEnchantedBook;
|
||||
import aPlugin.DropRandomFood;
|
||||
|
||||
import org.bukkit.entity.Spider;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -39,23 +43,32 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import sig.plugin.TwosideKeeper.Artifact;
|
||||
import sig.plugin.TwosideKeeper.Buff;
|
||||
import sig.plugin.TwosideKeeper.ChargeZombie;
|
||||
import sig.plugin.TwosideKeeper.CustomDamage;
|
||||
import sig.plugin.TwosideKeeper.CustomMonster;
|
||||
import sig.plugin.TwosideKeeper.GlobalLoot;
|
||||
import sig.plugin.TwosideKeeper.LivingEntityStructure;
|
||||
import sig.plugin.TwosideKeeper.MonsterController;
|
||||
import sig.plugin.TwosideKeeper.PlayerStructure;
|
||||
import sig.plugin.TwosideKeeper.TwosideKeeper;
|
||||
import sig.plugin.TwosideKeeper.TwosideKeeperAPI;
|
||||
import sig.plugin.TwosideKeeper.Events.EntityChannelCastEvent;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactItem;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactItemType;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Channel;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.CustomItem;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Spell;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Effects.DarkSlash;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Effects.HighlightCircle;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Effects.TemporaryBlock;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.BlockUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.DebugUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.MovementUtils;
|
||||
@ -64,20 +77,11 @@ import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.ColoredParticle;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.MixedDamage;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.ParticleEffect;
|
||||
|
||||
public class Knight extends CustomMonster{
|
||||
public class Knight extends GenericBoss{
|
||||
|
||||
DarkSpider spider_pet;
|
||||
protected String arrow = "->";
|
||||
protected List<Player> participantlist = new ArrayList<Player>();
|
||||
protected HashMap<String,Double> dpslist = new HashMap<String,Double>();
|
||||
BossBar healthbar;
|
||||
BossBar shieldbar;
|
||||
long lasthit;
|
||||
boolean startedfight=false;
|
||||
boolean isFlying=false;
|
||||
private long stuckTimer=0;
|
||||
int scroll=0;
|
||||
private Location lastLoc = null;
|
||||
Location lastlandedloc = null;
|
||||
final static double[] SHIELD_AMT = new double[]{1800,4700,16000};
|
||||
Location targetloc = null;
|
||||
@ -93,7 +97,7 @@ public class Knight extends CustomMonster{
|
||||
final static int[] GRANDSLAM_COOLDOWN = new int[]{900,700,600};
|
||||
MixedDamage[] GRANDSLAM_DAMAGE = new MixedDamage[]{MixedDamage.v(450),MixedDamage.v(700),MixedDamage.v(700, 0.55)};
|
||||
final Spell DARKREVERIE = new Spell("Dark Reverie",new int[]{60,40,40},new int[]{600,600,600});
|
||||
final Spell PHASEII = new Spell("Phase II",new int[]{200,200,200},new int[]{0,0,0});
|
||||
final Spell PHASEII = new Spell("Phase II",new int[]{80,80,80},new int[]{0,0,0});
|
||||
final Spell LIGHTNINGBOLT = new Spell("Lightning Bolt",new int[]{80,60,40},new int[]{400,300,200},new MixedDamage[]{MixedDamage.v(100,0.02),MixedDamage.v(250,0.05),MixedDamage.v(400, 0.1)});
|
||||
final Spell DARKLIGHT = new Spell("The Dark Light",new int[]{60,60,60},new int[]{500,500,500},new MixedDamage[]{MixedDamage.v(200,0.05),MixedDamage.v(300,0.10),MixedDamage.v(400, 0.15)});
|
||||
final Spell MINDFIELD = new Spell("Mind Field",new int[]{120,80,80},new int[]{1200,1000,800},new MixedDamage[]{MixedDamage.v(0,0.04),MixedDamage.v(0,0.07),MixedDamage.v(0, 0.15)});
|
||||
@ -137,16 +141,11 @@ public class Knight extends CustomMonster{
|
||||
}
|
||||
|
||||
public void runTick() {
|
||||
updateHealthbarForNearbyPlayers();
|
||||
super.runTick();
|
||||
relinkToSpider();
|
||||
displayDarkSwordParticles();
|
||||
updateTargetIfLost();
|
||||
regenerateHealthAndResetBossIfIdle();
|
||||
keepHealthbarUpdated();
|
||||
keepSpiderPetNearby();
|
||||
unstuckIfStuck();
|
||||
preventTargetFromBeingTheSameAsSpider();
|
||||
increaseBarTextScroll();
|
||||
performSpells();
|
||||
performSilverfishNotification();
|
||||
removeDebuffs();
|
||||
@ -449,12 +448,6 @@ public class Knight extends CustomMonster{
|
||||
return currentloc.getBlockY();
|
||||
}
|
||||
|
||||
private void announceMessageToParticipants(String msg) {
|
||||
for (Player p : participantlist) {
|
||||
p.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeAllBuffsFromPlayers() {
|
||||
for (Player p : participantlist) {
|
||||
for (PotionEffect pe : p.getActivePotionEffects()) {
|
||||
@ -784,43 +777,6 @@ public class Knight extends CustomMonster{
|
||||
spider_pet.GetMonster().isValid();
|
||||
}
|
||||
|
||||
private void unstuckIfStuck() {
|
||||
if (!startedfight) {
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else
|
||||
if (startedfight) {
|
||||
lastLoc = m.getLocation().clone();
|
||||
if (lastLoc!=null && lastLoc.distance(m.getLocation())<=0.4) {
|
||||
stuckTimer++;
|
||||
//TwosideKeeper.log("Stuck. "+stuckTimer, 0);
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else {
|
||||
stuckTimer=0;
|
||||
}
|
||||
if (!Channel.isChanneling(m) && stuckTimer>5) {
|
||||
//Teleport randomly.
|
||||
double numb = Math.random();
|
||||
if (numb<=0.33) {
|
||||
Location newloc = m.getLocation().add(Math.random()*10-5,0,0);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
} else
|
||||
if (numb<=0.5) {
|
||||
Location newloc = m.getLocation().add(0,0,Math.random()*10-5);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
}
|
||||
stuckTimer=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void keepSpiderPetNearby() {
|
||||
if (isValidSpiderPet()) {
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(spider_pet.GetMonster());
|
||||
@ -831,81 +787,12 @@ public class Knight extends CustomMonster{
|
||||
}
|
||||
}
|
||||
|
||||
private void keepHealthbarUpdated() {
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
Monster me = (Monster)m;
|
||||
String healthbarfooter = ((me.getTarget()!=null && (me.getTarget() instanceof Player))?(ChatColor.DARK_AQUA+" "+arrow+" "+ChatColor.YELLOW+((Player)me.getTarget()).getName()):"");
|
||||
if (Channel.isChanneling(m)) {
|
||||
healthbar.setTitle(LivingEntityStructure.getChannelingBar(m)+healthbarfooter);
|
||||
} else {
|
||||
healthbar.setTitle(GenericFunctions.getDisplayName(m)+healthbarfooter);
|
||||
}
|
||||
if (isValidSpiderPet()) {
|
||||
spider_pet.GetMonster().setHealth(spider_pet.GetMonster().getMaxHealth());
|
||||
}
|
||||
if (shieldbar!=null) {
|
||||
shieldbar.setProgress(Math.min(CustomDamage.getAbsorptionHearts(m)/SHIELD_AMT[getDifficultySlot()],1));
|
||||
}
|
||||
}
|
||||
|
||||
private void regenerateHealthAndResetBossIfIdle() {
|
||||
if (lasthit+20*15<=TwosideKeeper.getServerTickTime()) {
|
||||
GenericFunctions.HealEntity(m, m.getMaxHealth()*0.01);
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.GREEN);
|
||||
}
|
||||
} else {
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
startedfight=false;
|
||||
m.setAI(false);
|
||||
m.setHealth(m.getMaxHealth());
|
||||
announceFailedTakedown();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTargetIfLost() {
|
||||
Monster mm = (Monster)m;
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m);
|
||||
if (mm.getTarget()==null || !mm.getTarget().isValid() ||
|
||||
les.GetTarget()==null || !mm.getTarget().isValid() ||
|
||||
(!isFlying && (mm.getTarget().getLocation().distanceSquared(mm.getLocation())>2500 ||
|
||||
les.GetTarget().getLocation().distanceSquared(mm.getLocation())>2500
|
||||
))) {
|
||||
//See if there's another participant in the list. Choose randomly.
|
||||
while (participantlist.size()>0) {
|
||||
Player p = participantlist.get((int)(Math.random()*participantlist.size()));
|
||||
if (p!=null && p.isValid() && !p.isDead() &&
|
||||
(isFlying || p.getLocation().distanceSquared(mm.getLocation())<=2500)) {
|
||||
mm.setTarget(p);
|
||||
les.SetTarget(p);
|
||||
break;
|
||||
} else {
|
||||
participantlist.remove(p);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
//This fight has failed.
|
||||
announceFailedTakedown();
|
||||
startedfight=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void announceFailedTakedown() {
|
||||
super.announceFailedTakedown();
|
||||
if (dpslist.size()>0 && !m.isDead()) {
|
||||
phaseii=false;
|
||||
Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed...");
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(GenericFunctions.getDisplayName(m)+" Takedown Failed...\n\n"+ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```");
|
||||
dpslist.clear();
|
||||
PerformSpiderCleanup();
|
||||
PerformSilverfishAndEndermiteCleanup();
|
||||
healthbar.setColor(BarColor.WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -930,36 +817,6 @@ public class Knight extends CustomMonster{
|
||||
}
|
||||
}
|
||||
|
||||
public String generateDPSReport() {
|
||||
//Sorts a list of players by DPS contribution.
|
||||
List<Double> sorted_dmg = new ArrayList<Double>();
|
||||
List<String> sorted_pl = new ArrayList<String>();
|
||||
double totaldmg = 0;
|
||||
for (String pl : dpslist.keySet()) {
|
||||
double dmg = dpslist.get(pl);
|
||||
int slot = 0;
|
||||
totaldmg+=dmg;
|
||||
for (int i=0;i<sorted_dmg.size();i++) {
|
||||
if (dmg>sorted_dmg.get(i)) {
|
||||
break;
|
||||
} else {
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
sorted_pl.add(slot,pl);
|
||||
sorted_dmg.add(slot,dmg);
|
||||
}
|
||||
StringBuilder finalstr = new StringBuilder();
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
for (int i=0;i<sorted_pl.size();i++) {
|
||||
if (finalstr.length()!=0) {
|
||||
finalstr.append("\n");
|
||||
}
|
||||
finalstr.append(sorted_pl.get(i)+": "+df.format(sorted_dmg.get(i))+" dmg ("+df.format((sorted_dmg.get(i)/totaldmg)*100)+"%)");
|
||||
}
|
||||
return finalstr.toString();
|
||||
}
|
||||
|
||||
private void setupDarkSword() {
|
||||
ItemStack weap = new ItemStack(Material.STONE_SWORD);
|
||||
for (Enchantment ench : Enchantment.values()) {
|
||||
@ -976,37 +833,10 @@ public class Knight extends CustomMonster{
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
}
|
||||
|
||||
public void onHitEvent(LivingEntity damager, double damage) {
|
||||
addTarget(damager,damage);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, ()->{
|
||||
m.setVelocity(m.getVelocity().multiply(0.1));
|
||||
}, 1);
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
lasthit=TwosideKeeper.getServerTickTime();
|
||||
if (!startedfight) {
|
||||
startedfight=true;
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
m.setAI(true);
|
||||
public double getKnockbackMult() {
|
||||
return 0.1;
|
||||
}
|
||||
|
||||
private void addTarget(LivingEntity damager, double dmg) {
|
||||
if (damager instanceof Player) {
|
||||
Player p = (Player)damager;
|
||||
addParticipant(p);
|
||||
if (!dpslist.containsKey(p.getName())) {
|
||||
dpslist.put(p.getName(), dmg);
|
||||
} else {
|
||||
dpslist.put(p.getName(), dpslist.get(p.getName())+dmg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addParticipant(Player p) {
|
||||
if (!participantlist.contains(p)) {
|
||||
participantlist.add(p);
|
||||
}
|
||||
}
|
||||
private void displayDarkSwordParticles() {
|
||||
Location sparkleloc = m.getEyeLocation().add(0,-0.25,0);
|
||||
sparkleloc.setDirection(m.getLocation().getDirection().multiply(3));
|
||||
@ -1041,40 +871,6 @@ public class Knight extends CustomMonster{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateHealthbarForNearbyPlayers() {
|
||||
for (Player p : healthbar.getPlayers()) {
|
||||
if (p.getLocation().distanceSquared(m.getLocation())>2500) {
|
||||
healthbar.removePlayer(p);
|
||||
if (shieldbar!=null) {
|
||||
shieldbar.removePlayer(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Entity e : m.getNearbyEntities(50, 50, 50)) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player)e;
|
||||
healthbar.addPlayer(p);
|
||||
if (shieldbar!=null) {
|
||||
shieldbar.addPlayer(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shieldbar==null && CustomDamage.getAbsorptionHearts(m)>0) {
|
||||
shieldbar = Bukkit.getServer().createBossBar(GenericFunctions.getDisplayName(m)+"'s Shield", BarColor.WHITE, BarStyle.SEGMENTED_6, BarFlag.CREATE_FOG);
|
||||
GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.INVISIBILITY, DARKCLEANSE.getCastTimes()[getDifficultySlot()], 1, m, true);
|
||||
shieldbar.setProgress(Math.min(CustomDamage.getAbsorptionHearts(m)/SHIELD_AMT[getDifficultySlot()],1));
|
||||
for (Player p : healthbar.getPlayers()) {
|
||||
shieldbar.addPlayer(p);
|
||||
}
|
||||
}
|
||||
if (shieldbar!=null && m.hasPotionEffect(PotionEffectType.INVISIBILITY) &&
|
||||
CustomDamage.getAbsorptionHearts(m)<=0) {
|
||||
GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.INVISIBILITY, m);
|
||||
shieldbar.removeAll();
|
||||
shieldbar=null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupSpiderPet(LivingEntity m) {
|
||||
if (!TwosideKeeper.custommonsters.containsKey(m)) {
|
||||
TwosideKeeper.custommonsters.put(m.getUniqueId(),new DarkSpider((LivingEntity)m));
|
||||
@ -1130,7 +926,7 @@ public class Knight extends CustomMonster{
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
healthbar.removeAll();
|
||||
super.cleanup();
|
||||
if (shieldbar!=null) {
|
||||
shieldbar.removeAll();
|
||||
}
|
||||
@ -1157,32 +953,239 @@ public class Knight extends CustomMonster{
|
||||
endermites.clear();
|
||||
}
|
||||
|
||||
protected void increaseBarTextScroll() {
|
||||
scroll++;
|
||||
switch (scroll%22) {
|
||||
case 11:{
|
||||
arrow=" -";
|
||||
public void setupBonusLoot() {
|
||||
LivingEntityDifficulty diff = MonsterController.getLivingEntityDifficulty(m);
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m);
|
||||
GlobalLoot gl = GlobalLoot.spawnGlobalLoot(m.getLocation(), ChatColor.AQUA+""+ChatColor.BOLD+les.getDifficultyAndMonsterName()+ChatColor.AQUA+""+ChatColor.BOLD+" Miniboss Loot");
|
||||
double lootrate=1.0;
|
||||
for (Player p : participantlist) {
|
||||
PlayerMode mode = getMostUsedPlayerMode(p);
|
||||
switch (diff) {
|
||||
case T2_MINIBOSS:{
|
||||
lootrate+=0.5;
|
||||
}break;
|
||||
case 12:{
|
||||
arrow=" ";
|
||||
case T3_MINIBOSS:{
|
||||
lootrate+=1.0;
|
||||
}break;
|
||||
case 13:{
|
||||
arrow="> ";
|
||||
}
|
||||
double lootamt = lootrate;
|
||||
while (lootamt>0) {
|
||||
if ((lootamt-1)>=0 ||
|
||||
Math.random()<=lootamt) {
|
||||
gl.addNewDropInventory(p,GetSetPiece(diff,mode)); //Guaranteed Loot Piece.
|
||||
}
|
||||
lootamt--;
|
||||
}
|
||||
AttemptRoll(gl, 0.33*lootrate, p, GetSetPiece(diff,PlayerMode.values()[(int)(Math.random()*PlayerMode.values().length)]));
|
||||
AttemptRoll(gl, 0.33*lootrate, p, GetSetPiece(diff,PlayerMode.values()[(int)(Math.random()*PlayerMode.values().length)]));
|
||||
|
||||
AttemptRoll(gl, 0.75*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MYSTERIOUS_ESSENCE, (int)(Math.random()*3)+1));
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_CORE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
case 14:{
|
||||
arrow="->";
|
||||
case T2_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ANCIENT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
case T3_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.LOST_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
}
|
||||
//Artifact.createRecipe(5, ArtifactItemType.SHOVEL)
|
||||
AttemptRoll(gl, 0.08*lootrate, p, GetArtifactRecipe(diff));
|
||||
AttemptRoll(gl, 0.02*lootrate, p, GetMaterialKit(diff));
|
||||
AttemptRoll(gl, 0.5*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,100).getItemStack());
|
||||
AttemptRoll(gl, 0.33*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,500).getItemStack());
|
||||
AttemptRoll(gl, 0.1*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,1000).getItemStack());
|
||||
AttemptRoll(gl, 0.5*lootrate, p, new DropRandomEnchantedBook(0,2).getItemStack());
|
||||
AttemptRoll(gl, 0.33*lootrate, p, new DropRandomEnchantedBook(0,4).getItemStack());
|
||||
AttemptRoll(gl, 0.1*lootrate, p, new DropRandomEnchantedBook(0,6).getItemStack());
|
||||
AttemptRoll(gl, 0.15*lootrate, p, TwosideKeeper.HUNTERS_COMPASS.getItemStack());
|
||||
AttemptRoll(gl, 0.05*lootrate, p, getVial(diff));
|
||||
}
|
||||
}
|
||||
|
||||
public void onDeathEvent() {
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```");
|
||||
cleanup();
|
||||
private ItemStack getVial(LivingEntityDifficulty diff) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return TwosideKeeper.STRENGTHENING_VIAL.getItemStack();
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
return TwosideKeeper.LIFE_VIAL.getItemStack();
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
return TwosideKeeper.HARDENING_VIAL.getItemStack();
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating material kit. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Player> getParticipants() {
|
||||
return participantlist;
|
||||
private ItemStack GetMaterialKit(LivingEntityDifficulty diff) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return CustomItem.IronMaterialKit();
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
if (Math.random()<=0.5) {
|
||||
return CustomItem.DiamondMaterialKit();
|
||||
} else {
|
||||
return CustomItem.IronMaterialKit();
|
||||
}
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.33) {
|
||||
return CustomItem.IronMaterialKit();
|
||||
} else
|
||||
if (Math.random()<=0.5){
|
||||
return CustomItem.DiamondMaterialKit();
|
||||
} else {
|
||||
return CustomItem.GoldMaterialKit();
|
||||
}
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating material kit. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack GetArtifactRecipe(LivingEntityDifficulty diff) {
|
||||
ArtifactItemType type = ArtifactItemType.values()[(int)(Math.random()*ArtifactItemType.values().length)];
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return Artifact.createRecipe(4, type);
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
return Artifact.createRecipe(5, type);
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.1) {
|
||||
return Artifact.createRecipe(8, type);
|
||||
} else {
|
||||
return Artifact.createRecipe(7, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating artifact recipe. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void AttemptRoll(GlobalLoot loot, double chance, Player p,
|
||||
ItemStack item) {
|
||||
double lootamt = chance;
|
||||
if (Math.random()<=lootamt) {
|
||||
loot.addNewDropInventory(p,item); //Guaranteed Loot Piece.
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack GetSetPiece(LivingEntityDifficulty diff, PlayerMode mode) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_BOOTS, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, ItemSet.WOLFSBANE, (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
if (Math.random()<=0.05) {
|
||||
//Weapon roll.
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
if (Math.random()<=0.5) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_HELMET, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
} else {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.DIAMOND_BOOTS, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
} else {
|
||||
ItemSet[] baublesets = new ItemSet[]{ItemSet.WOLFSBANE,ItemSet.ALUSTINE};
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, baublesets[(int)(Math.random()*baublesets.length)], (Math.random()<=0.2)?true:false, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.10) {
|
||||
//Weapon roll.
|
||||
switch ((int)(Math.random()*4)) {
|
||||
case 0:
|
||||
case 3:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
case 1:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.DIAMOND_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
}
|
||||
case 2:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.GOLD_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
switch ((int)(Math.random()*4)) {
|
||||
case 0:
|
||||
case 3:{
|
||||
Material[] armor = new Material[]{Material.IRON_HELMET,Material.IRON_CHESTPLATE,Material.IRON_LEGGINGS,Material.IRON_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
case 1:{
|
||||
Material[] armor = new Material[]{Material.DIAMOND_HELMET,Material.DIAMOND_CHESTPLATE,Material.DIAMOND_LEGGINGS,Material.DIAMOND_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
}
|
||||
case 2:{
|
||||
Material[] armor = new Material[]{Material.GOLD_HELMET,Material.GOLD_CHESTPLATE,Material.GOLD_LEGGINGS,Material.GOLD_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
} else {
|
||||
ItemSet[] baublesets = new ItemSet[]{ItemSet.WOLFSBANE,ItemSet.ALUSTINE,ItemSet.MOONSHADOW,ItemSet.GLADOMAIN};
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, baublesets[(int)(Math.random()*baublesets.length)], true, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating set piece. Diff: "+diff+", Mode: "+mode, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemSet getModeSpecificSet(PlayerMode mode) {
|
||||
ItemSet[] allsets = new ItemSet[]{ItemSet.WINDRY,ItemSet.SHARD,ItemSet.PROTECTOR,ItemSet.LEGION,ItemSet.ASSASSIN,};
|
||||
switch (mode) {
|
||||
case BARBARIAN:
|
||||
return ItemSet.LEGION;
|
||||
case DEFENDER:
|
||||
return ItemSet.PROTECTOR;
|
||||
case NORMAL:
|
||||
return allsets[(int)(Math.random()*allsets.length)];
|
||||
case RANGER:
|
||||
return ItemSet.SHARD;
|
||||
case SLAYER:
|
||||
return ItemSet.ASSASSIN;
|
||||
case STRIKER:
|
||||
return ItemSet.WINDRY;
|
||||
default:
|
||||
TwosideKeeper.log("WARNING! Could not find loot entry for mode "+mode+". This should not be happening!!", 1);
|
||||
return allsets[(int)(Math.random()*allsets.length)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,37 +39,39 @@ import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.inventivetalent.glow.GlowAPI.Color;
|
||||
|
||||
import aPlugin.DropRandomEnchantedBook;
|
||||
import aPlugin.DropRandomFood;
|
||||
import sig.plugin.TwosideKeeper.Artifact;
|
||||
import sig.plugin.TwosideKeeper.Buff;
|
||||
import sig.plugin.TwosideKeeper.ChargeZombie;
|
||||
import sig.plugin.TwosideKeeper.CustomDamage;
|
||||
import sig.plugin.TwosideKeeper.CustomMonster;
|
||||
import sig.plugin.TwosideKeeper.GlobalLoot;
|
||||
import sig.plugin.TwosideKeeper.LivingEntityStructure;
|
||||
import sig.plugin.TwosideKeeper.MonsterController;
|
||||
import sig.plugin.TwosideKeeper.TwosideKeeper;
|
||||
import sig.plugin.TwosideKeeper.TwosideKeeperAPI;
|
||||
import sig.plugin.TwosideKeeper.Events.EntityChannelCastEvent;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactItem;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ArtifactItemType;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.BuffTemplate;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Channel;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.CustomItem;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Spell;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Effects.HighlightCircle;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.DebugUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.MovementUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.ColoredParticle;
|
||||
import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.MixedDamage;
|
||||
|
||||
public class SniperSkeleton extends CustomMonster{
|
||||
public class SniperSkeleton extends GenericBoss{
|
||||
|
||||
BossBar healthbar;
|
||||
protected String arrow = "->";
|
||||
int scroll=0;
|
||||
protected List<Player> participantlist = new ArrayList<Player>();
|
||||
protected HashMap<String,Double> dpslist = new HashMap<String,Double>();
|
||||
long lasthit;
|
||||
boolean startedfight=false;
|
||||
private long stuckTimer=0;
|
||||
private Location lastLoc = null;
|
||||
MixedDamage[] BASIC_ATTACK_DAMAGE = new MixedDamage[]{MixedDamage.v(30),MixedDamage.v(50),MixedDamage.v(130, 0.02)};
|
||||
final Spell PIERCING_ARROW = new Spell("Piercing Arrow",new int[]{40,20,20},new int[]{240,200,160},new MixedDamage[]{MixedDamage.v(100,0.02),MixedDamage.v(140,0.04),MixedDamage.v(200,0.08)});
|
||||
final Spell BURNING_PLUME = new Spell("Burning Plume",new int[]{50,40,30},new int[]{300,240,200},new MixedDamage[]{MixedDamage.v(200,0.06),MixedDamage.v(300,0.08),MixedDamage.v(500,0.15)});
|
||||
@ -133,12 +135,7 @@ public class SniperSkeleton extends CustomMonster{
|
||||
}
|
||||
|
||||
public void runTick() {
|
||||
updateHealthbarForNearbyPlayers();
|
||||
updateTargetIfLost();
|
||||
regenerateHealthAndResetBossIfIdle();
|
||||
keepHealthbarUpdated();
|
||||
unstuckIfStuck();
|
||||
increaseBarTextScroll();
|
||||
super.runTick();
|
||||
performSpells();
|
||||
updateAI();
|
||||
removeIfTooOld();
|
||||
@ -357,12 +354,6 @@ public class SniperSkeleton extends CustomMonster{
|
||||
bloodmites.add(bloodmite);
|
||||
}
|
||||
|
||||
private void announceMessageToParticipants(String msg) {
|
||||
for (Player p : participantlist) {
|
||||
p.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean attemptSpellCast(Spell spell) {
|
||||
if (cooldownIsAvailable(spell.getLastCastedTime(),spell)) {
|
||||
//Face target.
|
||||
@ -374,7 +365,7 @@ public class SniperSkeleton extends CustomMonster{
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
healthbar.removeAll();
|
||||
super.cleanup();
|
||||
for (LivingEntity ent : bloodmites) {
|
||||
if (ent!=null && ent.isValid()) {
|
||||
ent.remove();
|
||||
@ -457,6 +448,19 @@ public class SniperSkeleton extends CustomMonster{
|
||||
}
|
||||
}
|
||||
|
||||
public void announceFailedTakedown() {
|
||||
super.announceFailedTakedown();
|
||||
if (dpslist.size()>0 && !m.isDead()) {
|
||||
phaseii=false;
|
||||
|
||||
for (LivingEntity ent : bloodmites) {
|
||||
if (ent!=null && ent.isValid()) {
|
||||
ent.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runArrowRain() {
|
||||
new HighlightCircle(m.getLocation(),8,20,ARROW_RAIN.getCastTimes()[getDifficultySlot()]);
|
||||
for (int i=0;i<200;i++) {
|
||||
@ -601,119 +605,6 @@ public class SniperSkeleton extends CustomMonster{
|
||||
return Math.random()<=1/8d && !Buff.hasBuff(m, "SILENCE") && startedfight && !Channel.isChanneling(m) && !m.hasPotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
|
||||
private void unstuckIfStuck() {
|
||||
if (!startedfight) {
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else
|
||||
if (startedfight) {
|
||||
lastLoc = m.getLocation().clone();
|
||||
if (lastLoc!=null && lastLoc.distance(m.getLocation())<=0.4) {
|
||||
stuckTimer++;
|
||||
//TwosideKeeper.log("Stuck. "+stuckTimer, 0);
|
||||
ChargeZombie.BreakBlocksAroundArea((Monster)m, 1);
|
||||
} else {
|
||||
stuckTimer=0;
|
||||
}
|
||||
if (!Channel.isChanneling(m) && stuckTimer>5) {
|
||||
//Teleport randomly.
|
||||
double numb = Math.random();
|
||||
if (numb<=0.33) {
|
||||
Location newloc = m.getLocation().add(Math.random()*10-5,0,0);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
} else
|
||||
if (numb<=0.5) {
|
||||
Location newloc = m.getLocation().add(0,0,Math.random()*10-5);
|
||||
if (!newloc.getBlock().getType().isSolid() &&
|
||||
!newloc.getBlock().getRelative(0,1,0).getType().isSolid()) {
|
||||
SoundUtils.playGlobalSound(m.getLocation(), Sound.ENTITY_ENDERMEN_TELEPORT, 0.4f, 0.95f);
|
||||
m.teleport(newloc);
|
||||
}
|
||||
}
|
||||
stuckTimer=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void keepHealthbarUpdated() {
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
Monster me = (Monster)m;
|
||||
String healthbarfooter = ((me.getTarget()!=null && (me.getTarget() instanceof Player))?(ChatColor.DARK_AQUA+" "+arrow+" "+ChatColor.YELLOW+((Player)me.getTarget()).getName()):"");
|
||||
if (Channel.isChanneling(m)) {
|
||||
healthbar.setTitle(LivingEntityStructure.getChannelingBar(m)+healthbarfooter);
|
||||
} else {
|
||||
healthbar.setTitle(GenericFunctions.getDisplayName(m)+healthbarfooter);
|
||||
}
|
||||
}
|
||||
|
||||
private void regenerateHealthAndResetBossIfIdle() {
|
||||
if (lasthit+20*15<=TwosideKeeper.getServerTickTime()) {
|
||||
GenericFunctions.HealEntity(m, m.getMaxHealth()*0.01);
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.GREEN);
|
||||
}
|
||||
} else {
|
||||
if (startedfight) {
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
startedfight=false;
|
||||
m.setAI(false);
|
||||
m.setHealth(m.getMaxHealth());
|
||||
announceFailedTakedown();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTargetIfLost() {
|
||||
Monster mm = (Monster)m;
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m);
|
||||
if (mm.getTarget()==null || !mm.getTarget().isValid() ||
|
||||
les.GetTarget()==null || !mm.getTarget().isValid() ||
|
||||
((mm.getTarget().getLocation().distanceSquared(mm.getLocation())>2500 ||
|
||||
les.GetTarget().getLocation().distanceSquared(mm.getLocation())>2500
|
||||
))) {
|
||||
//See if there's another participant in the list. Choose randomly.
|
||||
while (participantlist.size()>0) {
|
||||
Player p = participantlist.get((int)(Math.random()*participantlist.size()));
|
||||
if (p!=null && p.isValid() && !p.isDead() &&
|
||||
(p.getLocation().distanceSquared(mm.getLocation())<=2500)) {
|
||||
mm.setTarget(p);
|
||||
les.SetTarget(p);
|
||||
break;
|
||||
} else {
|
||||
participantlist.remove(p);
|
||||
}
|
||||
}
|
||||
if (participantlist.size()==0 && startedfight) {
|
||||
//This fight has failed.
|
||||
announceFailedTakedown();
|
||||
startedfight=false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void announceFailedTakedown() {
|
||||
if (dpslist.size()>0 && !m.isDead()) {
|
||||
phaseii=false;
|
||||
Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed...");
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(GenericFunctions.getDisplayName(m)+" Takedown Failed...\n\n"+ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+generateDPSReport()+"\n```");
|
||||
dpslist.clear();
|
||||
healthbar.setColor(BarColor.WHITE);
|
||||
|
||||
for (LivingEntity ent : bloodmites) {
|
||||
if (ent!=null && ent.isValid()) {
|
||||
ent.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void announceSuccessfulTakedown() {
|
||||
if (dpslist.size()>0 && !m.isDead()) {
|
||||
phaseii=false;
|
||||
@ -732,80 +623,8 @@ public class SniperSkeleton extends CustomMonster{
|
||||
}
|
||||
}
|
||||
|
||||
public String generateDPSReport() {
|
||||
//Sorts a list of players by DPS contribution.
|
||||
List<Double> sorted_dmg = new ArrayList<Double>();
|
||||
List<String> sorted_pl = new ArrayList<String>();
|
||||
double totaldmg = 0;
|
||||
for (String pl : dpslist.keySet()) {
|
||||
double dmg = dpslist.get(pl);
|
||||
int slot = 0;
|
||||
totaldmg+=dmg;
|
||||
for (int i=0;i<sorted_dmg.size();i++) {
|
||||
if (dmg>sorted_dmg.get(i)) {
|
||||
break;
|
||||
} else {
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
sorted_pl.add(slot,pl);
|
||||
sorted_dmg.add(slot,dmg);
|
||||
}
|
||||
StringBuilder finalstr = new StringBuilder();
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
for (int i=0;i<sorted_pl.size();i++) {
|
||||
if (finalstr.length()!=0) {
|
||||
finalstr.append("\n");
|
||||
}
|
||||
finalstr.append(sorted_pl.get(i)+": "+df.format(sorted_dmg.get(i))+" dmg ("+df.format((sorted_dmg.get(i)/totaldmg)*100)+"%)");
|
||||
}
|
||||
return finalstr.toString();
|
||||
}
|
||||
|
||||
public void onHitEvent(LivingEntity damager, double damage) {
|
||||
addTarget(damager,damage);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, ()->{
|
||||
m.setVelocity(m.getVelocity().multiply(0.33));
|
||||
}, 1);
|
||||
healthbar.setProgress(m.getHealth()/m.getMaxHealth());
|
||||
lasthit=TwosideKeeper.getServerTickTime();
|
||||
if (!startedfight) {
|
||||
startedfight=true;
|
||||
healthbar.setColor(BarColor.BLUE);
|
||||
}
|
||||
m.setAI(true);
|
||||
}
|
||||
|
||||
private void addTarget(LivingEntity damager, double dmg) {
|
||||
if (damager instanceof Player) {
|
||||
Player p = (Player)damager;
|
||||
addParticipant(p);
|
||||
if (!dpslist.containsKey(p.getName())) {
|
||||
dpslist.put(p.getName(), dmg);
|
||||
} else {
|
||||
dpslist.put(p.getName(), dpslist.get(p.getName())+dmg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addParticipant(Player p) {
|
||||
if (!participantlist.contains(p)) {
|
||||
participantlist.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateHealthbarForNearbyPlayers() {
|
||||
for (Player p : healthbar.getPlayers()) {
|
||||
if (p.getWorld().equals(m.getWorld()) && p.getLocation().distanceSquared(m.getLocation())>2500) {
|
||||
healthbar.removePlayer(p);
|
||||
}
|
||||
}
|
||||
for (Entity e : m.getNearbyEntities(50, 50, 50)) {
|
||||
if (e instanceof Player) {
|
||||
Player p = (Player)e;
|
||||
healthbar.addPlayer(p);
|
||||
}
|
||||
}
|
||||
public double getKnockbackMult() {
|
||||
return 0.33;
|
||||
}
|
||||
|
||||
public static boolean randomlyConvertAsSniperSkeleton(LivingEntity m, boolean force) {
|
||||
@ -843,27 +662,247 @@ public class SniperSkeleton extends CustomMonster{
|
||||
);
|
||||
}
|
||||
|
||||
protected void increaseBarTextScroll() {
|
||||
scroll++;
|
||||
switch (scroll%22) {
|
||||
case 11:{
|
||||
arrow=" -";
|
||||
}break;
|
||||
case 12:{
|
||||
arrow=" ";
|
||||
}break;
|
||||
case 13:{
|
||||
arrow="> ";
|
||||
}break;
|
||||
case 14:{
|
||||
arrow="->";
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
enum ShotMode {
|
||||
NORMAL,
|
||||
POISON,
|
||||
BLEED
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setupBonusLoot() {
|
||||
LivingEntityDifficulty diff = MonsterController.getLivingEntityDifficulty(m);
|
||||
LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m);
|
||||
GlobalLoot gl = GlobalLoot.spawnGlobalLoot(m.getLocation(), ChatColor.AQUA+""+ChatColor.BOLD+les.getDifficultyAndMonsterName()+ChatColor.AQUA+""+ChatColor.BOLD+" Miniboss Loot");
|
||||
double lootrate=1.0;
|
||||
for (Player p : participantlist) {
|
||||
PlayerMode mode = getMostUsedPlayerMode(p);
|
||||
switch (diff) {
|
||||
case T2_MINIBOSS:{
|
||||
lootrate+=0.5;
|
||||
}break;
|
||||
case T3_MINIBOSS:{
|
||||
lootrate+=1.0;
|
||||
}break;
|
||||
}
|
||||
double lootamt = lootrate;
|
||||
while (lootamt>0) {
|
||||
if ((lootamt-1)>=0 ||
|
||||
Math.random()<=lootamt) {
|
||||
gl.addNewDropInventory(p,GetSetPiece(diff,mode)); //Guaranteed Loot Piece.
|
||||
}
|
||||
lootamt--;
|
||||
}
|
||||
AttemptRoll(gl, 0.33*lootrate, p, GetSetPiece(diff,PlayerMode.values()[(int)(Math.random()*PlayerMode.values().length)]));
|
||||
AttemptRoll(gl, 0.33*lootrate, p, GetSetPiece(diff,PlayerMode.values()[(int)(Math.random()*PlayerMode.values().length)]));
|
||||
|
||||
AttemptRoll(gl, 0.75*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MYSTERIOUS_ESSENCE, (int)(Math.random()*3)+1));
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_CORE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
case T2_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ANCIENT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
case T3_MINIBOSS:{
|
||||
AttemptRoll(gl, 0.5*lootrate, p, Artifact.createArtifactItem(ArtifactItem.LOST_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.25*lootrate, p, Artifact.createArtifactItem(ArtifactItem.ARTIFACT_ESSENCE, (int)(Math.random()*3)+1));
|
||||
AttemptRoll(gl, 0.125*lootrate, p, Artifact.createArtifactItem(ArtifactItem.MALLEABLE_BASE, 1));
|
||||
}break;
|
||||
}
|
||||
//Artifact.createRecipe(5, ArtifactItemType.SHOVEL)
|
||||
AttemptRoll(gl, 0.08*lootrate, p, GetArtifactRecipe(diff));
|
||||
AttemptRoll(gl, 0.02*lootrate, p, GetMaterialKit(diff));
|
||||
AttemptRoll(gl, 0.5*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,100).getItemStack());
|
||||
AttemptRoll(gl, 0.33*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,500).getItemStack());
|
||||
AttemptRoll(gl, 0.1*lootrate, p, new DropRandomFood((int)(Math.random()*10)+1,0,0.5,1000).getItemStack());
|
||||
AttemptRoll(gl, 0.5*lootrate, p, new DropRandomEnchantedBook(0,2).getItemStack());
|
||||
AttemptRoll(gl, 0.33*lootrate, p, new DropRandomEnchantedBook(0,4).getItemStack());
|
||||
AttemptRoll(gl, 0.1*lootrate, p, new DropRandomEnchantedBook(0,6).getItemStack());
|
||||
AttemptRoll(gl, 0.15*lootrate, p, TwosideKeeper.HUNTERS_COMPASS.getItemStack());
|
||||
AttemptRoll(gl, 0.05*lootrate, p, getVial(diff));
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getVial(LivingEntityDifficulty diff) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return TwosideKeeper.STRENGTHENING_VIAL.getItemStack();
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
return TwosideKeeper.LIFE_VIAL.getItemStack();
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
return TwosideKeeper.HARDENING_VIAL.getItemStack();
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating material kit. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack GetMaterialKit(LivingEntityDifficulty diff) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return CustomItem.IronMaterialKit();
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
if (Math.random()<=0.5) {
|
||||
return CustomItem.DiamondMaterialKit();
|
||||
} else {
|
||||
return CustomItem.IronMaterialKit();
|
||||
}
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.33) {
|
||||
return CustomItem.IronMaterialKit();
|
||||
} else
|
||||
if (Math.random()<=0.5){
|
||||
return CustomItem.DiamondMaterialKit();
|
||||
} else {
|
||||
return CustomItem.GoldMaterialKit();
|
||||
}
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating material kit. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemStack GetArtifactRecipe(LivingEntityDifficulty diff) {
|
||||
ArtifactItemType type = ArtifactItemType.values()[(int)(Math.random()*ArtifactItemType.values().length)];
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
return Artifact.createRecipe(4, type);
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
return Artifact.createRecipe(5, type);
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.1) {
|
||||
return Artifact.createRecipe(8, type);
|
||||
} else {
|
||||
return Artifact.createRecipe(7, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating artifact recipe. Diff: "+diff, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
private void AttemptRoll(GlobalLoot loot, double chance, Player p,
|
||||
ItemStack item) {
|
||||
double lootamt = chance;
|
||||
if (Math.random()<=lootamt) {
|
||||
loot.addNewDropInventory(p,item); //Guaranteed Loot Piece.
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack GetSetPiece(LivingEntityDifficulty diff, PlayerMode mode) {
|
||||
switch (diff) {
|
||||
case T1_MINIBOSS:{
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_BOOTS, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, ItemSet.WOLFSBANE, (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
case T2_MINIBOSS:{
|
||||
if (Math.random()<=0.05) {
|
||||
//Weapon roll.
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
} else {
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
if (Math.random()<=0.5) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_HELMET, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
} else {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.DIAMOND_BOOTS, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
} else {
|
||||
ItemSet[] baublesets = new ItemSet[]{ItemSet.WOLFSBANE,ItemSet.ALUSTINE};
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, baublesets[(int)(Math.random()*baublesets.length)], (Math.random()<=0.2)?true:false, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case T3_MINIBOSS:{
|
||||
if (Math.random()<=0.10) {
|
||||
//Weapon roll.
|
||||
switch ((int)(Math.random()*4)) {
|
||||
case 0:
|
||||
case 3:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
case 1:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.DIAMOND_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
}
|
||||
case 2:{
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.GOLD_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (mode!=PlayerMode.SLAYER) {
|
||||
switch ((int)(Math.random()*4)) {
|
||||
case 0:
|
||||
case 3:{
|
||||
Material[] armor = new Material[]{Material.IRON_HELMET,Material.IRON_CHESTPLATE,Material.IRON_LEGGINGS,Material.IRON_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
}
|
||||
case 1:{
|
||||
Material[] armor = new Material[]{Material.DIAMOND_HELMET,Material.DIAMOND_CHESTPLATE,Material.DIAMOND_LEGGINGS,Material.DIAMOND_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 2);
|
||||
}
|
||||
case 2:{
|
||||
Material[] armor = new Material[]{Material.GOLD_HELMET,Material.GOLD_CHESTPLATE,Material.GOLD_LEGGINGS,Material.GOLD_BOOTS,};
|
||||
return TwosideKeeperAPI.generateSetPiece(armor[(int)(Math.random()*armor.length)], getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (Math.random()<=0.4) {
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.IRON_SWORD, getModeSpecificSet(mode), (Math.random()<=0.1)?true:false, 3);
|
||||
} else {
|
||||
ItemSet[] baublesets = new ItemSet[]{ItemSet.WOLFSBANE,ItemSet.ALUSTINE,ItemSet.MOONSHADOW,ItemSet.GLADOMAIN};
|
||||
return TwosideKeeperAPI.generateSetPiece(Material.SKULL_ITEM, baublesets[(int)(Math.random()*baublesets.length)], true, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
TwosideKeeper.log("WARNING! Something went terribly wrong while generating set piece. Diff: "+diff+", Mode: "+mode, 1);
|
||||
DebugUtils.showStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemSet getModeSpecificSet(PlayerMode mode) {
|
||||
ItemSet[] allsets = new ItemSet[]{ItemSet.LUCI,ItemSet.TOXIN,ItemSet.SUSTENANCE,ItemSet.PRIDE,ItemSet.STEALTH,};
|
||||
switch (mode) {
|
||||
case BARBARIAN:
|
||||
return ItemSet.PRIDE;
|
||||
case DEFENDER:
|
||||
return ItemSet.SUSTENANCE;
|
||||
case NORMAL:
|
||||
return allsets[(int)(Math.random()*allsets.length)];
|
||||
case RANGER:
|
||||
return ItemSet.TOXIN;
|
||||
case SLAYER:
|
||||
return ItemSet.STEALTH;
|
||||
case STRIKER:
|
||||
return ItemSet.LUCI;
|
||||
default:
|
||||
TwosideKeeper.log("WARNING! Could not find loot entry for mode "+mode+". This should not be happening!!", 1);
|
||||
return allsets[(int)(Math.random()*allsets.length)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -273,6 +273,7 @@ import sig.plugin.TwosideKeeper.Logging.BowModeLogger;
|
||||
import sig.plugin.TwosideKeeper.Logging.LootLogger;
|
||||
import sig.plugin.TwosideKeeper.Logging.MysteriousEssenceLogger;
|
||||
import sig.plugin.TwosideKeeper.Monster.Dummy;
|
||||
import sig.plugin.TwosideKeeper.Monster.GenericBoss;
|
||||
import sig.plugin.TwosideKeeper.Monster.HellfireGhast;
|
||||
import sig.plugin.TwosideKeeper.Monster.Knight;
|
||||
import sig.plugin.TwosideKeeper.Monster.MonsterTemplate;
|
||||
@ -481,6 +482,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
public static final int TIMINGS_DEBUG = 5;
|
||||
public static double worldShopDistanceSquared = 1000000;
|
||||
public static double worldShopPriceMult = 2.0; //How much higher the price increases for every increment of worlsShopDistanceSquared.
|
||||
public static Inventory testinv = null;
|
||||
|
||||
public static String lastActionBarMessage="";
|
||||
public static long last_snow_golem = 0;
|
||||
@ -532,6 +534,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
public List<Integer> colors_used = new ArrayList<Integer>();
|
||||
public static HashMap<UUID,ChargeZombie> chargezombies = new HashMap<UUID,ChargeZombie>();
|
||||
public static HashMap<UUID,CustomMonster> custommonsters = new HashMap<UUID,CustomMonster>();
|
||||
public static HashMap<UUID,GlobalLoot> globalloot = new HashMap<UUID,GlobalLoot>();
|
||||
public static List<EliteMonster> elitemonsters = new ArrayList<EliteMonster>();
|
||||
|
||||
public static RecyclingCenter TwosideRecyclingCenter;
|
||||
@ -1582,8 +1585,10 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
w.setHealth(10);
|
||||
}break;
|
||||
case "ELITE":{
|
||||
Guardian m = (Guardian)MonsterController.convertLivingEntity((LivingEntity)p.getWorld().spawnEntity(p.getLocation(),EntityType.GUARDIAN), LivingEntityDifficulty.ELITE);
|
||||
m.setElder(true);
|
||||
LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE);
|
||||
m.setHealth(1);
|
||||
//Guardian m = (Guardian)MonsterController.convertLivingEntity((LivingEntity)p.getWorld().spawnEntity(p.getLocation(),EntityType.GUARDIAN), LivingEntityDifficulty.ELITE);
|
||||
//m.setElder(true);
|
||||
}break;
|
||||
case "VACUUM":{
|
||||
ItemStack[] remaining = InventoryUtils.insertItemsInVacuumCube(p, new ItemStack(Material.ENDER_PEARL,16), new ItemStack(Material.IRON_PICKAXE,1), new ItemStack(Material.GOLDEN_APPLE,64));
|
||||
@ -2042,9 +2047,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
LivingEntityDifficulty.T1_MINIBOSS);
|
||||
SniperSkeleton.randomlyConvertAsSniperSkeleton(m,true);
|
||||
TwosideKeeper.custommonsters.put(m.getUniqueId(),new SniperSkeleton(m));
|
||||
Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{
|
||||
m.setHealth(m.getMaxHealth()*0.3);
|
||||
}, 20);
|
||||
}break;
|
||||
case "DAMAGETEST":{
|
||||
LivingEntity m = MonsterController.convertLivingEntity((Skeleton)p.getWorld().spawnEntity(p.getLocation(),EntityType.SKELETON),
|
||||
@ -2100,6 +2102,34 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
case "EFFECTPOOL":{
|
||||
new EffectPool(p.getLocation(),2,20*10,Color.fromRGB(255, 255, 0));
|
||||
}break;
|
||||
case "KIT":{
|
||||
ItemStack giveitem = null;
|
||||
switch (Integer.parseInt(args[1])) {
|
||||
case 0:{
|
||||
giveitem = CustomItem.IronMaterialKit();
|
||||
}break;
|
||||
case 1:{
|
||||
giveitem = CustomItem.DiamondMaterialKit();
|
||||
}break;
|
||||
case 2:{
|
||||
giveitem = CustomItem.GoldMaterialKit();
|
||||
}break;
|
||||
}
|
||||
GenericFunctions.giveItem(p, giveitem);
|
||||
}
|
||||
case "INV":{
|
||||
switch (Integer.parseInt(args[1])) {
|
||||
case 0:{
|
||||
GlobalLoot gl = GlobalLoot.spawnGlobalLoot(p.getLocation(), "Test Loot");
|
||||
gl.addNewDropInventory(p, new ItemStack[]{CustomItem.IronMaterialKit(),CustomItem.DiamondMaterialKit(),CustomItem.GoldMaterialKit()});
|
||||
}break;
|
||||
}
|
||||
}break;
|
||||
case "SHARD":{
|
||||
ItemStack shard = TwosideKeeper.UPGRADE_SHARD.getItemStack();
|
||||
TwosideKeeperAPI.setUpgradeShardTier(shard, Integer.parseInt(args[1]));
|
||||
GenericFunctions.giveItem(p, shard);
|
||||
}
|
||||
}
|
||||
}
|
||||
//LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE);
|
||||
@ -5482,6 +5512,10 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
public void onInventoryClose(InventoryCloseEvent ev) {
|
||||
if (ev.getPlayer() instanceof Player) {
|
||||
Player p = (Player)ev.getPlayer();
|
||||
for (UUID id : globalloot.keySet()) {
|
||||
GlobalLoot loot = globalloot.get(id);
|
||||
loot.runInventoryCloseEvent(ev);
|
||||
}
|
||||
//log("Location of inventory: "+ev.getInventory().getLocation().toString(),2);
|
||||
if (DeathManager.deathStructureExists(p) && ev.getInventory().getTitle().contains("Death Loot")) {
|
||||
Location deathloc = DeathManager.getDeathStructure(p).deathloc;
|
||||
@ -6485,6 +6519,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Entity> removalEntities = new ArrayList<Entity>();
|
||||
for (Entity e : ev.getChunk().getEntities()) {
|
||||
if (e instanceof LivingEntity) {
|
||||
LivingEntity l = (LivingEntity)e;
|
||||
@ -6493,6 +6528,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
l.setCustomName(les.getUnloadedName());
|
||||
}
|
||||
}
|
||||
if (e instanceof Item) {
|
||||
if (TwosideKeeper.globalloot.containsKey(e.getUniqueId())) {
|
||||
removalEntities.add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Entity e : removalEntities) {
|
||||
e.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@ -7843,52 +7886,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
|
||||
if (custommonsters.containsKey(m.getUniqueId())) {
|
||||
CustomMonster cm = custommonsters.get(m.getUniqueId());
|
||||
if (cm instanceof Knight) {
|
||||
Knight k = (Knight)cm;
|
||||
List<Player> participants = k.getParticipants();
|
||||
StringBuilder participants_list = new StringBuilder();
|
||||
for (int i=0;i<participants.size();i++) {
|
||||
Player pl = participants.get(i);
|
||||
if (pl!=null && pl.isOnline()) {
|
||||
/*ExperienceOrb exp = GenericFunctions.spawnXP(pl.getLocation(), ev.getDroppedExp()*300);
|
||||
exp.setInvulnerable(true);
|
||||
if (m instanceof Zombie) {
|
||||
Zombie z = (Zombie)m;
|
||||
if (z.isBaby()) {
|
||||
GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
}
|
||||
}*/
|
||||
//GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
//log("Dropping "+aPlugin.API.getChestItem(Chests.ELITE).toString(),2);
|
||||
if (participants_list.length()<1) {
|
||||
participants_list.append(pl.getName());
|
||||
} else {
|
||||
if (i==participants.size()-1) {
|
||||
if (participants.size()==2) {
|
||||
participants_list.append(" and "+pl.getName());
|
||||
} else {
|
||||
participants_list.append(", and "+pl.getName());
|
||||
}
|
||||
} else {
|
||||
participants_list.append(", "+pl.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*Item it = m.getWorld().dropItemNaturally(m.getLocation(), aPlugin.API.getChestItem(Chests.ELITE));
|
||||
it.setInvulnerable(true);
|
||||
it.setPickupDelay(0);*/
|
||||
}
|
||||
}
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"!");
|
||||
aPlugin.API.discordSendRaw(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+"**"+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"**!");
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
public void run() {
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(k.generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+k.generateDPSReport()+"\n```");
|
||||
k.cleanup();
|
||||
}},1);
|
||||
if (cm instanceof GenericBoss) {
|
||||
GenericBoss gb = (GenericBoss)cm;
|
||||
gb.AnnounceDPSBreakdown();
|
||||
//TwosideKeeper.log("Difficulty was "+diff, 0);
|
||||
gb.setupBonusLoot();
|
||||
}
|
||||
}
|
||||
|
||||
@ -7898,6 +7900,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
//For each target, drop additional loot and exp.
|
||||
List<Player> participants = em.getParticipantList();
|
||||
StringBuilder participants_list = new StringBuilder();
|
||||
GlobalLoot gl = GlobalLoot.spawnGlobalLoot(m.getLocation(), ChatColor.LIGHT_PURPLE+""+ChatColor.BOLD+"Elite Loot");
|
||||
for (int i=0;i<participants.size();i++) {
|
||||
Player pl = participants.get(i);
|
||||
if (pl!=null && pl.isOnline()) {
|
||||
@ -7906,10 +7909,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
if (m instanceof Zombie) {
|
||||
Zombie z = (Zombie)m;
|
||||
if (z.isBaby()) {
|
||||
GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
//GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
gl.addNewDropInventory(pl, aPlugin.API.getChestItem(Chests.ELITE));
|
||||
}
|
||||
}
|
||||
GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
gl.addNewDropInventory(pl, aPlugin.API.getChestItem(Chests.ELITE));
|
||||
log("Dropping "+aPlugin.API.getChestItem(Chests.ELITE).toString(),2);
|
||||
if (participants_list.length()<1) {
|
||||
participants_list.append(pl.getName());
|
||||
@ -7924,11 +7928,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
participants_list.append(", "+pl.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}/* else {
|
||||
Item it = m.getWorld().dropItemNaturally(m.getLocation(), aPlugin.API.getChestItem(Chests.ELITE));
|
||||
it.setInvulnerable(true);
|
||||
it.setPickupDelay(0);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"!");
|
||||
aPlugin.API.discordSendRaw(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+"**"+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"**!");
|
||||
@ -7945,15 +7949,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
em.Cleanup();
|
||||
elitemonsters.remove(em);
|
||||
}},1);
|
||||
if (TwosideKeeper.custommonsters.containsKey(m.getUniqueId())) {
|
||||
CustomMonster cm = TwosideKeeper.custommonsters.get(m.getUniqueId());
|
||||
if (cm instanceof Knight) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
public void run() {
|
||||
cm.onDeathEvent();
|
||||
}},1);
|
||||
}
|
||||
}
|
||||
GenericFunctions.generateNewElite(null,"");
|
||||
}
|
||||
|
||||
@ -8117,6 +8112,58 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
|
||||
log(" Drops "+"["+(drop.size()+originaldroplist.size())+"]: "+ChatColor.GOLD+ChatColor.stripColor(originaldroplist.toString())+ChatColor.WHITE+","+ChatColor.LIGHT_PURPLE+ChatColor.stripColor(drop.toString()),LOOT_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void AnnounceDPSBreakdown(LivingEntity m, CustomMonster cm) {
|
||||
if (cm instanceof Knight) {
|
||||
Knight k = (Knight)cm;
|
||||
|
||||
} else {
|
||||
SniperSkeleton ss = (SniperSkeleton)cm;
|
||||
List<Player> participants = ss.getParticipants();
|
||||
StringBuilder participants_list = new StringBuilder();
|
||||
for (int i=0;i<participants.size();i++) {
|
||||
Player pl = participants.get(i);
|
||||
if (pl!=null && pl.isOnline()) {
|
||||
/*ExperienceOrb exp = GenericFunctions.spawnXP(pl.getLocation(), ev.getDroppedExp()*300);
|
||||
exp.setInvulnerable(true);
|
||||
if (m instanceof Zombie) {
|
||||
Zombie z = (Zombie)m;
|
||||
if (z.isBaby()) {
|
||||
GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
}
|
||||
}*/
|
||||
//GenericFunctions.giveItem(pl,aPlugin.API.getChestItem(Chests.ELITE));
|
||||
//log("Dropping "+aPlugin.API.getChestItem(Chests.ELITE).toString(),2);
|
||||
if (participants_list.length()<1) {
|
||||
participants_list.append(pl.getName());
|
||||
} else {
|
||||
if (i==participants.size()-1) {
|
||||
if (participants.size()==2) {
|
||||
participants_list.append(" and "+pl.getName());
|
||||
} else {
|
||||
participants_list.append(", and "+pl.getName());
|
||||
}
|
||||
} else {
|
||||
participants_list.append(", "+pl.getName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*Item it = m.getWorld().dropItemNaturally(m.getLocation(), aPlugin.API.getChestItem(Chests.ELITE));
|
||||
it.setInvulnerable(true);
|
||||
it.setPickupDelay(0);*/
|
||||
}
|
||||
}
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"!");
|
||||
aPlugin.API.discordSendRaw(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" "+(participants_list.length()==1?"has single-handedly taken down the ":"have successfully slain ")+"**"+GenericFunctions.getDisplayName(m)+ChatColor.WHITE+"**!");
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
|
||||
public void run() {
|
||||
Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:");
|
||||
Bukkit.getServer().broadcastMessage(ss.generateDPSReport());
|
||||
aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+ss.generateDPSReport()+"\n```");
|
||||
ss.cleanup();
|
||||
}},1);
|
||||
}
|
||||
}
|
||||
public void PlaceWitherLootChestsWithDefinedLayout(LivingEntity m, double chance_to_place_reward_chest,
|
||||
Integer[] chest_positions) {
|
||||
|
@ -352,6 +352,9 @@ final class runServerHeartbeat implements Runnable {
|
||||
PerformHighlightCircleEffects();
|
||||
TwosideKeeper.HeartbeatLogger.AddEntry("Highlight Server Tick Effects", (int)(System.nanoTime()-time));time=System.nanoTime();
|
||||
|
||||
PerformGlobalLootManagement();
|
||||
TwosideKeeper.HeartbeatLogger.AddEntry("Global Loot Management", (int)(System.nanoTime()-time));time=System.nanoTime();
|
||||
|
||||
resetPigmanAggro();
|
||||
TwosideKeeper.HeartbeatLogger.AddEntry("Reset Pigman Aggro", (int)(System.nanoTime()-time));time=System.nanoTime();
|
||||
if ((int)(System.nanoTime()-totaltime)/1000000d>50) {
|
||||
@ -360,6 +363,15 @@ final class runServerHeartbeat implements Runnable {
|
||||
TwosideKeeper.HeartbeatLogger.AddEntry(ChatColor.LIGHT_PURPLE+"Total Server Heartbeat", (int)(System.nanoTime()-totaltime));totaltime=System.nanoTime();
|
||||
}
|
||||
|
||||
private void PerformGlobalLootManagement() {
|
||||
for (UUID id : TwosideKeeper.globalloot.keySet()) {
|
||||
GlobalLoot gl = TwosideKeeper.globalloot.get(id);
|
||||
if (!gl.runTick()) {
|
||||
TwosideKeeper.ScheduleRemoval(TwosideKeeper.globalloot, gl.getItemUniqueID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformHighlightCircleEffects() {
|
||||
for (HighlightCircle hc : TwosideKeeper.circles) {
|
||||
if (!hc.runTick()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user