Organized common attributes of Bosses into a GenericBoss class.

Completed Personal Loot system for defeating bosses. Implemented all
loot for new minibosses.
patch_branch
sigonasr2 8 years ago
parent f404d2fd73
commit 05582519fc
  1. BIN
      TwosideKeeper.jar
  2. 1
      src/sig/plugin/TwosideKeeper/BossMonster.java
  3. 40
      src/sig/plugin/TwosideKeeper/CustomDamage.java
  4. 10
      src/sig/plugin/TwosideKeeper/CustomMonster.java
  5. 99
      src/sig/plugin/TwosideKeeper/GlobalLoot.java
  6. 2
      src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactItem.java
  7. 4
      src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java
  8. 42
      src/sig/plugin/TwosideKeeper/HelperStructures/CustomItem.java
  9. 30
      src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java
  10. 77
      src/sig/plugin/TwosideKeeper/HelperStructures/Loot.java
  11. 4
      src/sig/plugin/TwosideKeeper/HelperStructures/PlayerMode.java
  12. 353
      src/sig/plugin/TwosideKeeper/Monster/GenericBoss.java
  13. 499
      src/sig/plugin/TwosideKeeper/Monster/Knight.java
  14. 495
      src/sig/plugin/TwosideKeeper/Monster/SniperSkeleton.java
  15. 175
      src/sig/plugin/TwosideKeeper/TwosideKeeper.java
  16. 12
      src/sig/plugin/TwosideKeeper/runServerHeartbeat.java

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;
}
}

@ -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"

@ -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);
}
}
@ -929,36 +816,6 @@ public class Knight extends CustomMonster{
spider_pet.cleanup();
}
}
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);
@ -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);
}
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);
}
public double getKnockbackMult() {
return 0.1;
}
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=" -";
}break;
case 12:{
arrow=" ";
}break;
case 13:{
arrow="> ";
}break;
case 14:{
arrow="->";
}break;
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));
}
}
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;
}
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;
}
public List<Player> getParticipants() {
return participantlist;
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();
@ -456,6 +447,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()]);
@ -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) {
@ -842,28 +661,248 @@ public class SniperSkeleton extends CustomMonster{
MonsterController.getLivingEntityDifficulty(m)==LivingEntityDifficulty.T3_MINIBOSS
);
}
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,"");
}
@ -8118,6 +8113,58 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
}
}
}
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) {
for (int i=0;i<chest_positions.length/3;i++) {

@ -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…
Cancel
Save