diff --git a/.classpath b/.classpath index cee3862..b08699a 100644 --- a/.classpath +++ b/.classpath @@ -6,7 +6,7 @@ - + diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index e67e3c1..9a4b24c 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/plugin.yml b/src/plugin.yml index 2880779..e96135b 100644 --- a/src/plugin.yml +++ b/src/plugin.yml @@ -1,6 +1,6 @@ name: TwosideKeeper main: sig.plugin.TwosideKeeper.TwosideKeeper -version: 3.12.1a +version: 3.12.1b loadbefore: [aPlugin] commands: money: diff --git a/src/sig/plugin/TwosideKeeper/Boss/Arena.java b/src/sig/plugin/TwosideKeeper/Boss/Arena.java index c0d69e7..fb85eeb 100644 --- a/src/sig/plugin/TwosideKeeper/Boss/Arena.java +++ b/src/sig/plugin/TwosideKeeper/Boss/Arena.java @@ -23,8 +23,9 @@ import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.MaterialData; /** * Holds data about an arena. + * @param */ -public class Arena { +public class Arena { HashMap oldblocklist = new HashMap(); List wallmats = new ArrayList(); List floormats = new ArrayList(); @@ -34,6 +35,7 @@ public class Arena { List arenaplayers = new ArrayList(); Box box; World world; + E test; public Arena(World world, int x, int y, int z, int w, int h, int d,Material arena_mat) { this.world = world; diff --git a/src/sig/plugin/TwosideKeeper/CustomDamage.java b/src/sig/plugin/TwosideKeeper/CustomDamage.java index 951eb0d..b306cc1 100644 --- a/src/sig/plugin/TwosideKeeper/CustomDamage.java +++ b/src/sig/plugin/TwosideKeeper/CustomDamage.java @@ -1054,9 +1054,31 @@ public class CustomDamage { GenericFunctions.removeNoDamageTick(target, damager); } } + updateAggroValues(getDamagerEntity(damager),target,damage,reason); return damage; } + private static void updateAggroValues(LivingEntity damager, LivingEntity target, double damage, String reason) { + if (getDamagerEntity(damager)!=null && EntityUtils.isValidEntity(getDamagerEntity(damager))) { + if (target!=null && EntityUtils.isValidEntity(target) && !(target instanceof Player)) { + LivingEntity damaging_ent = getDamagerEntity(damager); + double mult = 1.0; + if (damaging_ent instanceof Player) { + if (PlayerMode.getPlayerMode((Player)damaging_ent)==PlayerMode.BARBARIAN) { + mult += 4-((damaging_ent.getHealth()/damaging_ent.getMaxHealth())*4d); + } + } + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(target); + les.increaseAggro(getDamagerEntity(damager), (int)(damage*mult)); + //TwosideKeeper.log(les.displayAggroTable(),0); + if (les.GetTarget()!=null && + les.GetTarget() == getDamagerEntity(damager)) { + les.lastHit = TwosideKeeper.getServerTickTime(); + } + } + } + } + private static void createBloodPool(Arrow proj, LivingEntity target) { TemporaryBlock.createTemporaryBlockCircle(target.getLocation(), 1, Material.WOOL, (byte)14, 20*30, "BLOODPOOL"); new EffectPool(target.getLocation(),1,20*30,Color.fromRGB(255, 0, 0)); @@ -1415,10 +1437,12 @@ public class CustomDamage { for (Player pl : partymembers) { if (!pl.equals(p) && ItemSet.HasSetBonusBasedOnSetBonusCount(pl, ItemSet.DONNER, 4)) { //Aggro to them instead. + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); if (!m.hasPotionEffect(PotionEffectType.GLOWING)) { setMonsterTarget(m,pl); setAggroGlowTickTime(m,100); } + les.increaseAggro(pl, 500*ItemSet.getHighestTierInSet(pl, ItemSet.DONNER)); break; } } @@ -1879,6 +1903,9 @@ public class CustomDamage { } else { pd.regenpool += lifestealamt; } + if (p.getMaxHealth()==p.getHealth()) { + pd.damagepool -= Math.max(pd.damagepool-lifestealamt, 0); + } } else { pd.regenpool += lifestealamt; } @@ -1999,7 +2026,9 @@ public class CustomDamage { //This is allowed, get the level on the weapon. setMonsterTarget(m,p); //TwosideKeeper.log("Aggro tick time: "+(int)(GenericFunctions.getAbilityValue(ArtifactAbility.PROVOKE, weapon)*20), 0); - setAggroGlowTickTime(m,(int)(GenericFunctions.getAbilityValue(ArtifactAbility.PROVOKE, weapon, p)*20)); + //setAggroGlowTickTime(m,(int)(GenericFunctions.getAbilityValue(ArtifactAbility.PROVOKE, weapon, p)*20)); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggro(p, (int)GenericFunctions.getAbilityValue(ArtifactAbility.PROVOKE, weapon, p)); } } @@ -2016,8 +2045,10 @@ public class CustomDamage { } private static void applyDonnerSetAggro(Monster m, Player p) { - double aggrotime = ItemSet.GetTotalBaseAmount(p, ItemSet.DONNER)*20; - setAggroGlowTickTime(m,(int)aggrotime); + int aggroamt = ItemSet.GetTotalBaseAmount(p, ItemSet.DONNER); + //setAggroGlowTickTime(m,(int)aggrotime); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggro(p, aggroamt); } static void leaderRallyNearbyMonsters(Monster m, Player p) { @@ -2225,14 +2256,14 @@ public class CustomDamage { } public static void addMonsterToTargetList(LivingEntity m,Player p) { - if (m instanceof Monster && !m.hasPotionEffect(PotionEffectType.GLOWING)) {((Monster)m).setTarget(p);} + //if (m instanceof Monster && !m.hasPotionEffect(PotionEffectType.GLOWING)) {((Monster)m).setTarget(p);} if (TwosideKeeper.livingentitydata.containsKey(m.getUniqueId())) { LivingEntityStructure ms = (LivingEntityStructure)TwosideKeeper.livingentitydata.get(m.getUniqueId()); - ms.SetTarget(p); + //ms.SetTarget(p); } else { LivingEntityStructure ms = new LivingEntityStructure(m,p); TwosideKeeper.livingentitydata.put(m.getUniqueId(),ms); - ms.SetTarget(p); + //ms.SetTarget(p); } } @@ -2344,7 +2375,7 @@ public class CustomDamage { PVP session = PVP.getMatch(defender); session.joinMatch(attacker); } else - if (!PVP.isPvPing(defender) && (weapon==null || (weapon.getType()==Material.AIR && weapon.isSimilar(attacker.getEquipment().getItemInMainHand())))) { + if (TwosideKeeper.PVPISENABLED && !PVP.isPvPing(defender) && (weapon==null || (weapon.getType()==Material.AIR && weapon.isSimilar(attacker.getEquipment().getItemInMainHand())))) { PlayerStructure pd = PlayerStructure.GetPlayerStructure(attacker); PlayerStructure pd2 = PlayerStructure.GetPlayerStructure(defender); if (pd.lastStartedPlayerClicks+200<=TwosideKeeper.getServerTickTime() && @@ -2617,7 +2648,7 @@ public class CustomDamage { } dodgechance=addMultiplicativeValue(dodgechance,ItemSet.TotalBaseAmountBasedOnSetBonusCount(p,ItemSet.PANROS,3,3)/100d); - if (p.isBlocking()) { + if (p.isBlocking() || pd.lastblock+20*5<=TwosideKeeper.getServerTickTime()) { dodgechance=addMultiplicativeValue(dodgechance,ItemSet.GetMultiplicativeTotalBaseAmount(p, ItemSet.SONGSTEEL)); } dodgechance=addMultiplicativeValue(dodgechance,ItemSet.TotalBaseAmountBasedOnSetBonusCount(p,ItemSet.JAMDAK,2,2)/100d); diff --git a/src/sig/plugin/TwosideKeeper/EliteMonster.java b/src/sig/plugin/TwosideKeeper/EliteMonster.java index 7d3b045..61e0078 100644 --- a/src/sig/plugin/TwosideKeeper/EliteMonster.java +++ b/src/sig/plugin/TwosideKeeper/EliteMonster.java @@ -323,6 +323,8 @@ public class EliteMonster { Player p = targetlist.get((int)(Math.random() * targetlist.size())); GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS,20*1,7,p); m.setTarget(p); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggroWhileMultiplyingAllOthers(p, 0, 0.25); TwosideKeeper.log("Set new target to "+p.getName(), 2); return p; } else { diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java b/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java index b3d2492..5c6d85f 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java @@ -76,7 +76,7 @@ public enum ArtifactAbility { new PVPValue(0,0.05),100,40,UpgradePath.ARMOR,10), //Sword abilities - PROVOKE("Provoke","Your attacks provoke enemies for [VAL] seconds.",new double[]{0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1}, + PROVOKE("Provoke","Your attacks increase Aggression by [VAL].",new double[]{5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5}, new PVPValue(0,1.0),10000,10,UpgradePath.PROVOKE,1), COMBO("Belligerent","[VAL]% more damage for each successive strike on a mob. Resets after 2 seconds of no combat.",new double[]{0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1}, new PVPValue(50,0.1),10000,40,UpgradePath.SWORD,1), diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java index 24724fa..0d0ef20 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java @@ -3711,7 +3711,7 @@ public class GenericFunctions { boolean revived=false; boolean fromRoom=false; PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - DebugUtils.showStackTrace(); + //DebugUtils.showStackTrace(); if (p.getHealth()<=dmg || (PlayerMode.getPlayerMode(p)==PlayerMode.SLAYER && pd.slayermodehp<=dmg)) { //This means we would die from this attack. Attempt to revive the player. //Check all artifact armor for a perk. @@ -3892,9 +3892,13 @@ public class GenericFunctions { //List monsters = getNearbyMobs(p.getLocation(),8); List monsters = CustomDamage.trimNonMonsterEntities(p.getNearbyEntities(24, 24, 24)); for (Monster m : monsters) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.setAggro(m, 0); + if (les.GetTarget()==p) { + les.SetTarget(null); + } if (m.getTarget()!=null && - m.getTarget().equals(p) && - !m.hasPotionEffect(PotionEffectType.GLOWING)) { + m.getTarget().equals(p)) { m.setTarget(null); } } @@ -5473,6 +5477,8 @@ public class GenericFunctions { GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.SLOW, 20*15, poisonlv, ent); }*/ CustomDamage.ApplyDamage(totalpoisonlv*10, p, ent, null, "Siphon", CustomDamage.TRUEDMG|CustomDamage.IGNOREDODGE|CustomDamage.IGNORE_DAMAGE_TICK); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(ent); + les.setAggro(p, 0); } CustomDamage.setAbsorptionHearts(p, CustomDamage.getAbsorptionHearts(p)+totalpoisonstacks*4); TwosideKeeper.sendSuccessfulCastMessage(p); @@ -5642,6 +5648,7 @@ public class GenericFunctions { if (e instanceof LivingEntity && !(e instanceof Player)) { LivingEntity l = (LivingEntity)e; LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(l); + les.setAggro(p, 0); if (les.GetTarget()!=null && les.GetTarget().equals(p)) { l.setAI(false); diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java b/src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java index d627e6a..5b79e55 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/ItemSet.java @@ -43,7 +43,7 @@ public enum ItemSet { VIXEN(5,4, 3,3, 5,5, 0,0, 5, 3, 5, 0), COMET(10,10, 10,10, 2,1, 0,0, 10, 10, 2, 0), CUPID(10,5, 10,10, 2,1, 0,0, 10, 10, 2, 0), - DONNER(5,5, 10,10, 2,1, 0,0, 5, 10, 2, 0), + DONNER(100,100, 10,10, 2,1, 0,0, 5, 10, 2, 0), BLITZEN(10,10, 3,3, 5,5, 0,0, 10, 3, 5, 0), RUDOLPH(5,5, 10,10, 2,1, 0,0, 5, 10, 2, 0), OLIVE(3,2, 10,10, 2,1, 0,0, 3, 10, 2, 0), @@ -520,7 +520,7 @@ public enum ItemSet { case DONNER: lore.add(ChatColor.BLUE+"Holiday Gear"); lore.add(ChatColor.GOLD+""+ChatColor.BOLD+"T"+tier+" "+GenericFunctions.CapitalizeFirstLetters(set.name())+" Set"); - lore.add(ChatColor.YELLOW+"Attacking aggros enemies for "+ItemSet.GetBaseAmount(set, tier, 1, p)+" seconds"); + lore.add(ChatColor.YELLOW+"Attacking increases aggression by "+ItemSet.GetBaseAmount(set, tier, 1, p)); break; case OLIVE: lore.add(ChatColor.BLUE+"Holiday Gear"); @@ -637,7 +637,8 @@ public enum ItemSet { lore.add(ChatColor.GRAY+" Mock cooldown decreases from"); lore.add(ChatColor.GRAY+" 20 -> 10 seconds, making it stackable."); lore.add(ChatColor.GRAY+" All Lifesteal Stacks and Weapon Charges"); - lore.add(ChatColor.GRAY+" gained are doubled."); + lore.add(ChatColor.GRAY+" gained are doubled. Increases Aggression"); + lore.add(ChatColor.GRAY+" by an additional "+(tier*1000)+"."); lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+""); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Lifesteal"); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Health Regeneration"); @@ -749,8 +750,6 @@ public enum ItemSet { lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"Strength Cap Increases to 40. 2 Stacks per kill."); lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"Successful Assassinations apply damage"); lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"in an AoE Range."); - lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"Slayers can drop aggro by sneaking"); - lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"for Three seconds."); lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"While in Stealth Mode you gain 40%"); lore.add(ChatColor.GRAY+" "+ChatColor.WHITE+"Dodge Chance"); }break; @@ -828,7 +827,8 @@ public enum ItemSet { lore.add(ChatColor.DARK_AQUA+" 3 - "+ChatColor.WHITE+" +"+ItemSet.GetBaseAmount(set, tier, 3, p)+" Damage"); lore.add(ChatColor.DARK_AQUA+" 4 - "+ABILITY_LABEL+" Come At Me"+ABILITY_LABEL_END); lore.add(ChatColor.GRAY+" Monsters attacking your party members"); - lore.add(ChatColor.GRAY+" will automatically be provoked to you."); + lore.add(ChatColor.GRAY+" will increase aggression towards you by"); + lore.add(ChatColor.GRAY+" "+(tier*500)+"."); break; case OLIVE: lore.add(ChatColor.GOLD+""+ChatColor.ITALIC+"Set Bonus:"); @@ -924,7 +924,9 @@ public enum ItemSet { 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.WHITE+" +20 Damage"); + lore.add(ChatColor.WHITE+" When at Full Health, all overflow"); + lore.add(ChatColor.WHITE+" Lifesteal reduces your Damage Pool."); lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+""); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Lifesteal"); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Health Regeneration"); @@ -962,6 +964,7 @@ public enum ItemSet { lore.add(ChatColor.GRAY+" "); lore.add(ChatColor.WHITE+" +50% Armor Penetration"); lore.add(ChatColor.WHITE+" +20 Damage"); + lore.add(ChatColor.WHITE+" +"+(tier*100)+"% Threat Generation"); lore.add(ChatColor.DARK_AQUA+" 6 - "+ChatColor.WHITE+""); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Lifesteal"); lore.add(ChatColor.WHITE+" +"+(tier*10)+"% Health Regeneration"); diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java index b192996..e272492 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/BlockUtils.java @@ -84,4 +84,17 @@ public class BlockUtils { b.getType()==Material.WALL_SIGN || b.getType()==Material.SIGN_POST; } + + public static boolean isInteractable(Block b) { + return b.getType().name().contains("DOOR") || + b.getType().name().contains("CHEST") || + b.getType().name().contains("FURNACE") || + b.getType().name().contains("MINECART") || + b.getType()==Material.BREWING_STAND || + b.getType()==Material.WORKBENCH || + b.getType()==Material.ENCHANTMENT_TABLE || + b.getType()==Material.LEVER || + b.getType().name().contains("BUTTON") || + b.getType().name().contains("BOAT"); + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java index f4d0324..0a107db 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java @@ -210,4 +210,8 @@ public class EntityUtils { //-X: -180/180 degrees (West) return faces[(int)((dir+22.5)/45)%faces.length]; } + + public static boolean isValidEntity(Entity e) { + return e!=null && e.isValid() && !e.isDead(); + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java index a5a93f2..019e142 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java @@ -6,6 +6,8 @@ import java.util.Map; import org.bukkit.ChatColor; +import sig.plugin.TwosideKeeper.TwosideKeeper; + public class TextUtils { public static ChatColor RandomColor() { @@ -116,4 +118,38 @@ public class TextUtils { } return true; } + + + /** + * Uses Underline formatting to create a bar beneath a given set of text with X% of the width filled. + */ + @Deprecated + public static String createUnderlineBar(String finaltext, double pct) { + //TODO Does not work. + int barlength = finaltext.length(); + int filledbar = (int)(pct * barlength); + finaltext = ChatColor.UNDERLINE+finaltext; + TwosideKeeper.log("Text: "+finaltext, 0); + finaltext = finaltext.substring(0, filledbar-1) + ChatColor.RESET + finaltext.substring(filledbar-1, finaltext.length()-1); + return finaltext; + } + + /** + * Use boxes to create an aggro bar. + */ + public static String createAggroBar(double pct) { + StringBuilder sb = new StringBuilder(ChatColor.DARK_RED+""+ChatColor.ITALIC+""+ChatColor.UNDERLINE+""); + for (int i=0;i<5;i++) { + if (pct>=(0.1*(i+1))+0.5) { + sb.append("█"); + } else + if(pct>=0.1*(i+1)) { + sb.append("▄"); + } else + { + sb.append(" "); + } + } + return sb.toString()+ChatColor.RESET; + } } diff --git a/src/sig/plugin/TwosideKeeper/LivingEntityStructure.java b/src/sig/plugin/TwosideKeeper/LivingEntityStructure.java index 34172cf..fab33ae 100644 --- a/src/sig/plugin/TwosideKeeper/LivingEntityStructure.java +++ b/src/sig/plugin/TwosideKeeper/LivingEntityStructure.java @@ -1,20 +1,26 @@ package sig.plugin.TwosideKeeper; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.attribute.Attribute; +import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; import org.inventivetalent.glow.GlowAPI; import sig.plugin.TwosideKeeper.HelperStructures.Channel; import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; import sig.plugin.TwosideKeeper.HelperStructures.Utils.DebugUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils; import sig.plugin.TwosideKeeper.Monster.Knight; public class LivingEntityStructure { @@ -42,9 +48,11 @@ public class LivingEntityStructure { public long lastInfectionTick=0; public long lastCrippleTick=0; public long lastBurnTick=0; + public long lastHit=0; public float MoveSpeedMultBeforeCripple=1f; public Channel currentChannel=null; public boolean isImportantGlowEnemy=true; + public HashMap aggro_table = new HashMap(); final static String MODIFIED_NAME_CODE = ChatColor.RESET+""+ChatColor.RESET+""+ChatColor.RESET; final static String MODIFIED_NAME_DELIMITER = ChatColor.RESET+";"+ChatColor.RESET; @@ -344,4 +352,148 @@ public class LivingEntityStructure { LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(l); return les.prefix; } + + public static int getAggroRating(LivingEntity l, Entity targetEntity) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(l); + if (les.aggro_table.containsKey(targetEntity.getUniqueId())) { + return les.aggro_table.get(targetEntity.getUniqueId()); + } else { + return 0; + } + } + + public int getAggroRating(Entity targetEntity) { + return getAggroRating(m, targetEntity); + } + + /** + * May return null if there is no currently aggro'd target. + */ + public static LivingEntity getAggroTarget(LivingEntity l) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(l); + int highest_aggroRating = 0; + UUID bestAggroTarget = null; + for (UUID ent : les.aggro_table.keySet()) { + if (les.aggro_table.get(ent)>highest_aggroRating) { + highest_aggroRating = les.aggro_table.get(ent); + bestAggroTarget = ent; + } + } + for (Entity e : l.getWorld().getEntities()) { + if (e instanceof LivingEntity) { + if (e.getUniqueId().equals(bestAggroTarget) && EntityUtils.isValidEntity(e)) { + return (LivingEntity)e; + } + } + } + les.aggro_table.remove(bestAggroTarget); + return null; + } + + + /** + * May return null if there is no currently aggro'd target. + */ + public LivingEntity getAggroTarget() { + return getAggroTarget(m); + } + + public void setAggro(LivingEntity target, int aggroValue) { + if (isValidTarget(target)) { + UUID key = target.getUniqueId(); + aggro_table.put(key, Math.max(aggroValue, 0)); + } + } + + public void increaseAggro(LivingEntity target, int amt) { + setAggro(target,getAggroRating(target)+amt); + } + public void decreaseAggro(LivingEntity target, int amt) { + increaseAggro(target,-amt); + } + /** + * Increases aggro of selected Target, multiplies all other aggro by multiplier. + */ + public void increaseAggroWhileMultiplyingAllOthers(LivingEntity target, int amt, double multiplier) { + if (isValidTarget(target)) { + for (UUID id : aggro_table.keySet()) { + if (id!=target.getUniqueId()) { + //setAggro(target,-(int)(getAggroRating(target)*multiplier)); + if (aggro_table.containsKey(id)) { + aggro_table.put(id, (int)(aggro_table.get(id)*multiplier)); + } + } else { + increaseAggro(target,amt); + } + } + } + } + + public void increaseAggroWhileMultiplyingAllOthers(List targets, int amt, double multiplier) { + List uuid_list = new ArrayList(); + for (LivingEntity ent : targets) { + uuid_list.add(ent.getUniqueId()); + } + if (isValidTarget(target)) { + for (UUID id : aggro_table.keySet()) { + if (!uuid_list.contains(id)) { + //setAggro(target,-(int)(getAggroRating(target)*multiplier)); + if (aggro_table.containsKey(id)) { + aggro_table.put(id, (int)(aggro_table.get(id)*multiplier)); + } + } else { + increaseAggro(target,amt); + } + } + } + } + + private boolean isValidTarget(LivingEntity target) { + return target!=null && EntityUtils.isValidEntity(target) && target!=m; + } + + public double getAggroPercentage(LivingEntity target) { + int highestAggro = 0; + if (!aggro_table.containsKey(target.getUniqueId())) { + return 0.0; + } else { + for (UUID id : aggro_table.keySet()) { + if (aggro_table.get(id)>highestAggro) { + highestAggro = aggro_table.get(id); + } + } + //TwosideKeeper.log("Aggro is "+aggro_table.get(target.getUniqueId())+" / "+highestAggro, 0); + return ((double)aggro_table.get(target.getUniqueId()))/highestAggro; + } + } + + public String displayAggroTable() { + StringBuilder sb = new StringBuilder("Aggro Table for Entity "+GenericFunctions.GetEntityDisplayName(m)+": \n"); + for (UUID id : aggro_table.keySet()) { + int aggroRating = aggro_table.get(id); + sb.append(" "+id+" : "+aggroRating+"\n"); + } + return sb.toString(); + } + public void UpdateAggroTarget() { + LivingEntity target = getAggroTarget(); + if (target!=null) { + if (m instanceof Monster) { + Monster mm = (Monster)m; + mm.setTarget(target); + EntityTargetEvent ev = new EntityTargetEvent(m,target,TargetReason.CUSTOM); + Bukkit.getPluginManager().callEvent(ev); + } + SetTarget(target); + if (lastHit+40<=TwosideKeeper.getServerTickTime()) { + decreaseAggro(target,getAggroRating(target)/2); + //TwosideKeeper.log("Decreased aggro due to no attacking to "+getAggroRating(target), 0); + } + } + + if (target!=null && !EntityUtils.isValidEntity(target)) { + aggro_table.remove(target.getUniqueId()); + } + + } } diff --git a/src/sig/plugin/TwosideKeeper/Monster/Knight.java b/src/sig/plugin/TwosideKeeper/Monster/Knight.java index e75858c..ca919e3 100644 --- a/src/sig/plugin/TwosideKeeper/Monster/Knight.java +++ b/src/sig/plugin/TwosideKeeper/Monster/Knight.java @@ -767,9 +767,13 @@ public class Knight extends GenericBoss{ for (Player p : participantlist) { if (Math.random()<=1d/participantlist.size() && !p.isDead() && p.isValid()) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggroWhileMultiplyingAllOthers(p, 0, 0.25); return p; } } + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggroWhileMultiplyingAllOthers(participantlist.get(0), 0, 0.25); return participantlist.get(0); } else { return null; diff --git a/src/sig/plugin/TwosideKeeper/Monster/SniperSkeleton.java b/src/sig/plugin/TwosideKeeper/Monster/SniperSkeleton.java index 90d25c3..17ba5aa 100644 --- a/src/sig/plugin/TwosideKeeper/Monster/SniperSkeleton.java +++ b/src/sig/plugin/TwosideKeeper/Monster/SniperSkeleton.java @@ -624,9 +624,13 @@ public class SniperSkeleton extends GenericBoss{ for (Player p : participantlist) { if (Math.random()<=1d/participantlist.size() && !p.isDead() && p.isValid()) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggroWhileMultiplyingAllOthers(p, 0, 0.25); return p; } } + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + les.increaseAggroWhileMultiplyingAllOthers(participantlist.get(0), 0, 0.25); return participantlist.get(0); } else { return null; diff --git a/src/sig/plugin/TwosideKeeper/PlayerStructure.java b/src/sig/plugin/TwosideKeeper/PlayerStructure.java index 0d645ff..e3327e2 100644 --- a/src/sig/plugin/TwosideKeeper/PlayerStructure.java +++ b/src/sig/plugin/TwosideKeeper/PlayerStructure.java @@ -354,6 +354,7 @@ public class PlayerStructure { this.equiparmor=true; this.customtitle = new AdvancedTitle(p); this.lastLocationChange = TwosideKeeper.getServerTickTime(); + this.lastblock = TwosideKeeper.getServerTickTime(); //Set defaults first, in case this is a new user. loadConfig(); //p.getInventory().addItem(new ItemStack(Material.PORTAL)); diff --git a/src/sig/plugin/TwosideKeeper/Rooms/DPSChallengeRoom.java b/src/sig/plugin/TwosideKeeper/Rooms/DPSChallengeRoom.java index e252ed9..22fb80d 100644 --- a/src/sig/plugin/TwosideKeeper/Rooms/DPSChallengeRoom.java +++ b/src/sig/plugin/TwosideKeeper/Rooms/DPSChallengeRoom.java @@ -258,6 +258,9 @@ public class DPSChallengeRoom extends Room{ private void StartChallenge() { startTime = TwosideKeeper.getServerTickTime(); + if (p!=null && p.isValid()) { + GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.LEVITATION, p); + } } diff --git a/src/sig/plugin/TwosideKeeper/Rooms/ParkourChallengeRoom.java b/src/sig/plugin/TwosideKeeper/Rooms/ParkourChallengeRoom.java index eec4750..722ab44 100644 --- a/src/sig/plugin/TwosideKeeper/Rooms/ParkourChallengeRoom.java +++ b/src/sig/plugin/TwosideKeeper/Rooms/ParkourChallengeRoom.java @@ -231,6 +231,9 @@ public class ParkourChallengeRoom extends Room{ private void StartChallenge() { startTime = TwosideKeeper.getServerTickTime(); lastLavaTime = TwosideKeeper.getServerTickTime()+200; + if (p!=null && p.isValid()) { + GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.LEVITATION, p); + } Block chest = instance.getBlockAt(ROOM_WIDTH/2, 1, ROOM_LENGTH/2); chest.setType(Material.CHEST); Chest c = (Chest)(chest.getState()); diff --git a/src/sig/plugin/TwosideKeeper/Rooms/TankChallengeRoom.java b/src/sig/plugin/TwosideKeeper/Rooms/TankChallengeRoom.java index b4c19eb..8fcd652 100644 --- a/src/sig/plugin/TwosideKeeper/Rooms/TankChallengeRoom.java +++ b/src/sig/plugin/TwosideKeeper/Rooms/TankChallengeRoom.java @@ -242,6 +242,9 @@ public class TankChallengeRoom extends Room { private void StartChallenge() { startTime = TwosideKeeper.getServerTickTime(); + if (p!=null && p.isValid()) { + GenericFunctions.logAndRemovePotionEffectFromEntity(PotionEffectType.LEVITATION, p); + } } diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index 3798d77..0220d61 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -113,6 +113,7 @@ import org.bukkit.event.entity.EntityPortalEvent; import org.bukkit.event.entity.EntityPortalExitEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityShootBowEvent; +import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent.TargetReason; import org.bukkit.event.entity.EntityTargetLivingEntityEvent; import org.bukkit.event.entity.EntityTeleportEvent; @@ -278,6 +279,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.Utils.MessageUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.MovementUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.PlayerUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.TextUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.TimeUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.ColoredParticle; import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.InstanceFilter; @@ -301,7 +303,7 @@ import sig.plugin.TwosideKeeper.Rooms.ParkourChallengeRoom; import sig.plugin.TwosideKeeper.Rooms.TankChallengeRoom; -public class TwosideKeeper extends JavaPlugin implements Listener { +public class TwosideKeeper extends JavaPlugin implements Listener { public final static int CUSTOM_DAMAGE_IDENTIFIER = 500000; @@ -603,6 +605,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public final static boolean ELITEGUARDIANS_ACTIVATED=false; public final static boolean MINIBOSSES_ACTIVATED=true; public final static boolean NEWARTIFACTABILITIES_ACTIVATED=false; + public final static boolean PVPISENABLED=false; public static final Set LIVING_ENTITY_TYPES = ImmutableSet.of( EntityType.BAT,EntityType.BLAZE,EntityType.CAVE_SPIDER,EntityType.CHICKEN, @@ -3150,6 +3153,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } private void setTier(ItemStack piece, int tier) { TwosideKeeperAPI.setItemTier(piece, tier); + piece.addUnsafeEnchantment(Enchantment.DURABILITY, 99); } private void CreateDarkReveriePool(Player p, int tier) { AreaEffectCloud aec = (AreaEffectCloud)p.getWorld().spawnEntity(p.getLocation(), EntityType.AREA_EFFECT_CLOUD); @@ -3976,6 +3980,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ItemStack[] tempitems = null; Player p = ev.getPlayer(); int marker = 0; + boolean firstItem=true; byte[] messagebytes = ev.getMessage().getBytes(); TextComponent finalmsg = new TextComponent("<"+p.getName()+"> "); TextComponent finalmsgDiscord = new TextComponent(""); @@ -4034,7 +4039,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (tempitems!=null) { for (int j=0;j1)?ChatColor.YELLOW+" x"+tempitems[j].getAmount():"")+ChatColor.RESET+ChatColor.GREEN+"]"); tc.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT,new ComponentBuilder(item_text_output).create())); if (j>0) { finalmsg.addExtra("\n"); @@ -4043,7 +4048,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { finalmsg.addExtra(tc); finalmsgDiscord.addExtra("**"); finalmsgDiscord.addExtra(tc); - finalmsgDiscord.addExtra("**"); + finalmsgDiscord.addExtra("** "); if (tempitems[j]!=null && tempitems[j].getType()!=Material.AIR) { targetitem.add(tempitems[j]); } @@ -4394,6 +4399,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { LinkPlayerToOtherPlayer(p,pl); } } + aggroMonsters(p,pd,1000,16); } private void LinkPlayerToOtherPlayer(Player p, Player pl) { @@ -4761,37 +4767,20 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } //Shield related stuff in here. - if (ev.getAction()==Action.RIGHT_CLICK_AIR || - ev.getAction()==Action.RIGHT_CLICK_BLOCK) { + //TwosideKeeper.log(ev.useInteractedBlock().toString(), 0); + if ((ev.getAction()==Action.RIGHT_CLICK_AIR || + ev.getAction()==Action.RIGHT_CLICK_BLOCK) && (ev.getClickedBlock()==null || !BlockUtils.isInteractable(ev.getClickedBlock()))) { + aggroMonsters(p, pd, 1000, 16); //See if this player is blocking. If so, give them absorption. //Player p = ev.getPlayer(); - Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + /*Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { @Override public void run() { if (p.isBlocking()) { //Give absorption hearts. - if (PlayerMode.isDefender(p)) { - GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.ABSORPTION,200,1,p); - List entities = p.getNearbyEntities(16, 16, 16); - for (int i=0;iTwosideKeeper.getServerTickTime()) && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { + if (((isHoldingDailyToken(p) || pd.lastdpsDailyChallenge+1152000<=TwosideKeeper.getServerTickTime()) && pd.lastuseddailysign+100>TwosideKeeper.getServerTickTime() && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { new DPSChallengeRoom(p,new DPSRoom(32,32)); if (isHoldingDailyToken(p)) { consumeToken(p); @@ -5264,7 +5253,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } else if (s.getLine(1).equalsIgnoreCase(ChatColor.DARK_GREEN+"TANK CHALLENGE")) { - if (((isHoldingDailyToken(p) || pd.lastuseddailysign+100>TwosideKeeper.getServerTickTime()) && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { + if (((isHoldingDailyToken(p) || pd.lasttankDailyChallenge+1152000<=TwosideKeeper.getServerTickTime()) && pd.lastuseddailysign+100>TwosideKeeper.getServerTickTime() && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { new TankChallengeRoom(p,new DPSRoom(32,32)); if (isHoldingDailyToken(p)) { consumeToken(p); @@ -5285,7 +5274,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } else if (s.getLine(1).equalsIgnoreCase(ChatColor.DARK_PURPLE+"PARKOUR CHALLENGE")) { - if (((isHoldingDailyToken(p) || pd.lastuseddailysign+100>TwosideKeeper.getServerTickTime()) && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { + if (((isHoldingDailyToken(p) || pd.lastparkourDailyChallenge+1152000<=TwosideKeeper.getServerTickTime()) && pd.lastuseddailysign+100>TwosideKeeper.getServerTickTime() && pd.nameoflastdailysign.equalsIgnoreCase(s.getLine(1)))) { if (isHoldingDailyToken(p)) { consumeToken(p); } else { @@ -5471,6 +5460,33 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } } + private void aggroMonsters(final Player p, PlayerStructure pd, int tauntAmt, int range) { + if (PlayerMode.isDefender(p)) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.ABSORPTION,200,1,p); + List entities = p.getNearbyEntities(range, range, range); + for (int i=0;i=getServerTickTime()) { + Monster m = (Monster)(entities.get(i)); + m.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING,100,5,true,true,Color.NAVY)); + m.setTarget(p); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(m); + //les.increaseAggro(p, 1000); + les.increaseAggroWhileMultiplyingAllOthers(p, tauntAmt, 0.5); + les.lastHit = TwosideKeeper.getServerTickTime(); + } + } + } + } else { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.ABSORPTION,200,0,p); + } + DecimalFormat df = new DecimalFormat("0.0"); + if (pd.lastblock+20*5<=getServerTickTime()) { + p.sendMessage(ChatColor.GRAY+"Damage Reduction: "+ChatColor.DARK_AQUA+df.format(((1-CustomDamage.CalculateDamageReduction(1,p,null))*100))+"% "+ChatColor.GRAY+"Block Chance: "+ChatColor.DARK_AQUA+df.format(((CustomDamage.CalculateDodgeChance(p))*100))+"% "); + pd.lastblock=getServerTickTime(); + + } + } private void consumeToken(Player p) { if (isHoldingDailyToken(p)) { ItemStack tokens = p.getEquipment().getItemInMainHand().clone(); @@ -6384,6 +6400,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } } + aggroMonsters(p,pd,2000+((hasFullSet)?(ItemSet.getHighestTierInSet(p, ItemSet.DAWNTRACKER)*1000):0),12); SoundUtils.playLocalSound(p, Sound.ENTITY_VILLAGER_AMBIENT, 1.0f, 0.3f); aPlugin.API.displayEndRodParticle(p.getLocation(), 0, 0f, 0f, 5, 20); if (hasFullSet) { @@ -7752,6 +7769,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public void dodgeEvent(PlayerDodgeEvent ev) { Player p = ev.getPlayer(); PlayerMode pm = PlayerMode.getPlayerMode(p); + LivingEntity damager = CustomDamage.getDamagerEntity(ev.getDamager()); + if (damager != null && + ev.getPlayer() != null) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(damager); + les.increaseAggro(ev.getPlayer(), (int)(5*ev.getRawDamage())); + les.increaseAggro(ev.getPlayer(), les.getAggroRating(ev.getPlayer())*2); + les.lastHit = TwosideKeeper.getServerTickTime(); + } if (!pm.isRanger(p)) { if (p.isBlocking() || pm.isDefender(p)) { //Only reduce durability of the shield. @@ -8190,14 +8215,37 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ChatColor finalcolor = GetHeartColor(color1); ChatColor finalcolor2 = GetHeartColor(color2); String finalheartdisplay=finalcolor2+((finalcolor2==ChatColor.MAGIC)?remainingheartdisplay.replace((char)0x2665, 'A'):remainingheartdisplay)+finalcolor+((finalcolor==ChatColor.MAGIC)?heartdisplay.substring(0, heartdisplay.length()-remainingheartdisplay.length()).replace((char)0x2665, 'A'):heartdisplay.substring(0, heartdisplay.length()-remainingheartdisplay.length())); + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(target); if (target.getHealth()>2000) { finalheartdisplay=GetHeartColor(GetFactorialAmt(target.getHealth()))+FinalHealthDisplay(target.getHealth())+" / "+FinalHealthDisplay(target.getMaxHealth()); //p.sendTitle(message1, finalMonsterName+" "+finalheartdisplay+" "+ChatColor.RESET); - pd.customtitle.modifySmallCenterTitle(finalMonsterName+ChatColor.RESET+" "+finalheartdisplay+" "+ChatColor.RESET, 100); + //String finaltext = " "; + String finaltext = finalMonsterName+ChatColor.RESET+" "+finalheartdisplay+" "+ChatColor.RESET; + if (!(target instanceof Player)) { + if (les.aggro_table.size()>1) { + finaltext = TextUtils.createAggroBar(les.getAggroPercentage(p)) +" "+ finaltext; + } + } + pd.customtitle.modifySmallCenterTitle(finaltext, 100); } else { - pd.customtitle.modifySmallCenterTitle(finalMonsterName+ChatColor.RESET+" "+finalheartdisplay+" "+ChatColor.RESET+ChatColor.DARK_GRAY+"x"+(int)(target.getHealth()/20+1), 100); + //String finaltext = " "; + //String finaltext = TextUtils.createUnderlineBar(,1); + String finaltext = finalMonsterName+ChatColor.RESET+" "+finalheartdisplay+" "+ChatColor.RESET+ChatColor.DARK_GRAY+"x"+(int)(target.getHealth()/20+1); + if (!(target instanceof Player)) { + if (les.aggro_table.size()>1) { + finaltext = TextUtils.createAggroBar(les.getAggroPercentage(p)) + " "+ finaltext; + } + } + pd.customtitle.modifySmallCenterTitle(finaltext, 100); //p.sendTitle(message1, finalMonsterName+" "+finalheartdisplay+" "+ChatColor.RESET+ChatColor.DARK_GRAY+"x"+(int)(target.getHealth()/20+1)); } + } else + //Only display the aggro bar, because they have the healthbar display disabled. + if (Bukkit.getPlayer(pd.name)!=null && target!=null) { + if (!(target instanceof Player)) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure(target); + pd.customtitle.modifySmallCenterTitle(TextUtils.createAggroBar(les.getAggroPercentage(p)), 100); + } } //pd.customtitle.updateTitle(p, true); } @@ -8438,13 +8486,52 @@ public class TwosideKeeper extends JavaPlugin implements Listener { log("A new artifact base was generated.",1); } } + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) + public void entityTargetEvent(EntityTargetEvent ev) { + if (ev.getReason()==TargetReason.CUSTOM && ev.getEntity() instanceof LivingEntity && ev.getTarget() instanceof LivingEntity) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure((LivingEntity)ev.getEntity()); + les.SetTarget((LivingEntity)ev.getTarget()); + //TwosideKeeper.log("Aggro target set to "+GenericFunctions.GetEntityDisplayName(ev.getTarget()), 0); + ev.setCancelled(true); + return; + } + if ((ev.getEntity() instanceof LivingEntity)) { + LivingEntityStructure les = LivingEntityStructure.GetLivingEntityStructure((LivingEntity)ev.getEntity()); + if (ev.getReason()==TargetReason.FORGOT_TARGET && les.GetTarget()!=null && les.GetTarget().getUniqueId().equals(ev.getTarget())) { + TwosideKeeper.log("Trying to forget current target...Cancelled.", 0); + ev.setCancelled(true); + return; + } + } + if (ev.getEntity() instanceof LivingEntity && + ev.getReason()==TargetReason.TARGET_ATTACKED_NEARBY_ENTITY) { + if (pigmanAggroCount