diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index fd77afa..d451572 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/CustomDamage.java b/src/sig/plugin/TwosideKeeper/CustomDamage.java index eb5a142..0d0b090 100644 --- a/src/sig/plugin/TwosideKeeper/CustomDamage.java +++ b/src/sig/plugin/TwosideKeeper/CustomDamage.java @@ -54,6 +54,7 @@ public class CustomDamage { public static final int CRITICALSTRIKE = 1; public static final int IGNOREDODGE = 2; public static final int TRUEDMG = 4; + public static final int SPECIALATTACK = 8; //Used internally to specifically define a special attack. //////////////////THE FLAGS BELOW ARE SYSTEM FLAGS!! DO NOT USE THEM! public static final int IS_CRIT = 1; //System Flag. Used for telling a player structure their last hit was a crit. @@ -94,7 +95,11 @@ public class CustomDamage { * @return Whether or not this attack actually was applied. Returns false if it was dodged, nodamageticks, etc. */ static public boolean ApplyDamage(double damage, Entity damager, LivingEntity target, ItemStack weapon, String reason, int flags) { - if (!InvulnerableCheck(damager,target) || (isFlagSet(flags,IGNOREDODGE))) { + if (damage!=0.0 && weapon==null) { + //Custom damage right here. + flags = setFlag(flags,SPECIALATTACK); + } + if (!InvulnerableCheck(damager,target,flags)) { double dmg = 0.0; if (isFlagSet(flags,TRUEDMG)) { if (reason!=null) { @@ -153,27 +158,44 @@ public class CustomDamage { } } } - dmg += addToPlayerLogger(damager,target,"Execute",(((GenericFunctions.getAbilityValue(ArtifactAbility.EXECUTION, weapon)*5.0)*(1-(target.getHealth()/target.getMaxHealth()))))); - dmg += addMultiplierToPlayerLogger(damager,target,"Striker Mult",dmg * calculateStrikerMultiplier(shooter,target)); - double preemptivedmg = addMultiplierToPlayerLogger(damager,target,"Preemptive Strike Mult",dmg * calculatePreemptiveStrikeMultiplier(target,shooter)); - if (preemptivedmg!=0.0) {preemptive=true;} - dmg += preemptivedmg; - dmg += addMultiplierToPlayerLogger(damager,target,"STRENGTH Mult",dmg * calculateStrengthEffectMultiplier(shooter,target)); - dmg += addMultiplierToPlayerLogger(damager,target,"WEAKNESS Mult",dmg * calculateWeaknessEffectMultiplier(shooter,target)); - dmg += addMultiplierToPlayerLogger(damager,target,"POISON Mult",dmg * calculatePoisonEffectMultiplier(target)); - double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,flags)); - if (critdmg!=0.0) {crit=true;} - dmg += critdmg; + } else { + if (damage!=0.0) { + dmg = damage; + TwosideKeeper.log("Setting damage to "+dmg+" for "+reason+".", 5); + } else + if (shooter instanceof LivingEntity) { + dmg = calculateMobBaseDamage(shooter,target)*calculateMonsterDifficultyMultiplier(shooter); + } } + dmg += addToPlayerLogger(damager,target,"Execute",(((GenericFunctions.getAbilityValue(ArtifactAbility.EXECUTION, weapon)*5.0)*(1-(target.getHealth()/target.getMaxHealth()))))); + dmg += addMultiplierToPlayerLogger(damager,target,"Striker Mult",dmg * calculateStrikerMultiplier(shooter,target)); + double preemptivedmg = addMultiplierToPlayerLogger(damager,target,"Preemptive Strike Mult",dmg * calculatePreemptiveStrikeMultiplier(target,shooter)); + if (preemptivedmg!=0.0) {preemptive=true;} + dmg += preemptivedmg; + dmg += addMultiplierToPlayerLogger(damager,target,"STRENGTH Mult",dmg * calculateStrengthEffectMultiplier(shooter,target)); + dmg += addMultiplierToPlayerLogger(damager,target,"WEAKNESS Mult",dmg * calculateWeaknessEffectMultiplier(shooter,target)); + dmg += addMultiplierToPlayerLogger(damager,target,"POISON Mult",dmg * calculatePoisonEffectMultiplier(target)); + double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,flags)); + if (critdmg!=0.0) {crit=true;} + dmg += critdmg; double armorpendmg = addToPlayerLogger(damager,target,"Armor Pen",calculateArmorPen(damager,dmg,weapon)); addToLoggerActual(damager,dmg); + addToPlayerRawDamage(dmg,target); dmg = CalculateDamageReduction(dmg-armorpendmg,target,damager); - TwosideKeeper.log("Damage: "+dmg+", Armor Pen Damage: "+armorpendmg, 2); + TwosideKeeper.log("Damage: "+dmg+", Armor Pen Damage: "+armorpendmg, 3); setupDamagePropertiesForPlayer(damager,((crit)?IS_CRIT:0)|((headshot)?IS_HEADSHOT:0)|((preemptive)?IS_PREEMPTIVE:0)); dmg = hardCapDamage(dmg+armorpendmg); return dmg; } + private static void addToPlayerRawDamage(double damage, LivingEntity target) { + if (target instanceof Player) { + Player p = (Player)target; + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.lastrawdamage=damage; + } + } + /** * Returns how much damage comes from the WEAPON, and no other sources. * @param damager Optional. @@ -226,17 +248,24 @@ public class CustomDamage { target.setNoDamageTicks(0); target.setMaximumNoDamageTicks(0); damage = subtractAbsorptionHearts(damage,target); - applyOnHitEffects(damage,damager,target,weapon,reason,flags); + damage = applyOnHitEffects(damage,damager,target,weapon,reason,flags); if (getDamagerEntity(damager) instanceof Player) { //Player dealing damage to living entities does a custom damage modifier. TwosideKeeper.log("Dealing "+damage+" damage.", 5); TwosideKeeper.log("Sending out "+(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER)+" damage.",5); target.damage(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER,getDamagerEntity(damager)); } else - if (!(getDamagerEntity(damager) instanceof LivingEntity)) { + if (!(getDamagerEntity(damager) instanceof LivingEntity) || (damage!=0 && isFlagSet(flags,SPECIALATTACK))) { //TwosideKeeper.log("Sending out "+damage+" damage.",2); subtractHealth(damage,target); aPlugin.API.sendEntityHurtAnimation(target); } + + if (target instanceof Player) { //Update player health whenever hit. + Player p = (Player)target; + TwosideKeeper.setPlayerMaxHealth(p); + p.getScoreboard().getTeam(p.getName().toLowerCase()).setSuffix(TwosideKeeper.createHealthbar(((p.getHealth())/p.getMaxHealth())*100,p)); + p.getScoreboard().getTeam(p.getName().toLowerCase()).setPrefix(GenericFunctions.PlayerModePrefix(p)); + } } /** @@ -248,7 +277,7 @@ public class CustomDamage { * @param reason * @param flags */ - static void applyOnHitEffects(double damage, Entity damager, LivingEntity target, ItemStack weapon, + static double applyOnHitEffects(double damage, Entity damager, LivingEntity target, ItemStack weapon, String reason, int flags) { if (target instanceof Player) { Player p = (Player)target; @@ -263,7 +292,7 @@ public class CustomDamage { } if (p.isBlocking() && ItemSet.hasFullSet(p, ItemSet.SONGSTEEL)) { PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - pd.vendetta_amt+=(damage-CalculateDamageReduction(damage,target,damager))*0.3; + pd.vendetta_amt+=((1-CalculateDamageReduction(1,target,damager))*pd.lastrawdamage)*0.3; aPlugin.API.sendActionBarMessage(p, ChatColor.YELLOW+"Vendetta: "+ChatColor.GREEN+Math.round(pd.vendetta_amt)+" dmg stored"); } } @@ -283,8 +312,13 @@ public class CustomDamage { md.SetTarget(target); } increaseStrikerSpeed(p); - increaseArtifactArmorXP(p,(int)damage); - + healDefenderSaturation(p); + reduceDefenderKnockback(p); + if (GenericFunctions.AttemptRevive(p, damage, reason)) { + damage=0; + } + if (damage10) { + dmgamountcopy/=2; + heartcount++; + } + return heartcount; + } + + private static void subtractWeaponDurability(Player p,ItemStack weapon) { + aPlugin.API.damageItem(p, weapon, 1); + } + + static void triggerEliteEvent(Player p, Entity damager) { + for (int i=0;i0) { + for (int i=0;i10)?10:resistlevel; protectionlevel=(protectionlevel>100)?100:protectionlevel; - //partylevel=(partylevel>9)?9:partylevel; + partylevel=(partylevel>9)?9:partylevel; double finaldmg=(basedmg-(basedmg*(dmgreduction/100.0d))) *(1d-((resistlevel*10d)/100d)) *(1d-((protectionlevel)/100d)) *(1d-((projectileprotectionlevel)/100d)) *(1d-((explosionprotectionlevel)/100d)) *(1d-rangerdmgdiv) - //*((10-partylevel)*0.1) + *(1d-((partylevel*10d)/100d)) *setbonus *((target instanceof Player && ((Player)target).isBlocking())?(GenericFunctions.isDefender((Player)target))?0.30:0.50:1) *((target instanceof Player)?((GenericFunctions.isDefender((Player)target))?0.9:(target.getEquipment().getItemInOffHand()!=null && target.getEquipment().getItemInOffHand().getType()==Material.SHIELD)?0.95:1):1); @@ -826,30 +953,38 @@ public class CustomDamage { * @param p */ public static void addIframe(int ticks, Player p) { - PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - if (pd.iframetimeTwosideKeeper.getServerTickTime(); + if (p!=null) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + return pd.iframetime>TwosideKeeper.getServerTickTime(); + } else { + return false; + } } public static void removeIframe(Player p) { - PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - pd.iframetime=0; - p.removePotionEffect(PotionEffectType.GLOWING); - int level = GenericFunctions.getPotionEffectLevel(PotionEffectType.NIGHT_VISION, p); - if (level==64) { - p.removePotionEffect(PotionEffectType.NIGHT_VISION); + if (p!=null) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.iframetime=0; + p.removePotionEffect(PotionEffectType.GLOWING); + int level = GenericFunctions.getPotionEffectLevel(PotionEffectType.NIGHT_VISION, p); + if (level==64) { + p.removePotionEffect(PotionEffectType.NIGHT_VISION); + } } } @@ -996,7 +1131,7 @@ public class CustomDamage { static double calculateStrengthEffectMultiplier(LivingEntity damager, LivingEntity target) { double mult = 0.0; - if (damager.hasPotionEffect(PotionEffectType.INCREASE_DAMAGE)) { + if (damager!=null && damager.hasPotionEffect(PotionEffectType.INCREASE_DAMAGE)) { mult += (GenericFunctions.getPotionEffectLevel(PotionEffectType.INCREASE_DAMAGE, damager)+1)*0.1; } return mult; @@ -1004,7 +1139,7 @@ public class CustomDamage { static double calculateWeaknessEffectMultiplier(LivingEntity damager, LivingEntity target) { double mult = 0.0; - if (damager.hasPotionEffect(PotionEffectType.WEAKNESS)) { + if (damager!=null && damager.hasPotionEffect(PotionEffectType.WEAKNESS)) { int weaknesslv = GenericFunctions.getPotionEffectLevel(PotionEffectType.WEAKNESS, damager)+1; if (weaknesslv>10) { mult -= 1.0; @@ -1336,11 +1471,14 @@ public class CustomDamage { } private static void subtractHealth(double damage, LivingEntity target) { - if (target.getHealth()0) { + if (target.getHealth()0) { willpower+=mobcount; last_willpower_increase=TwosideKeeper.getServerTickTime(); - if (!first_willpower_notification) { + if (!first_willpower_notification && willpower>20) { for (int i=0;i81) { + if (!leaping && targetlist.size()==0 && m.getLocation().getWorld().equals(myspawn.getWorld()) && m.getLocation().distanceSquared(myspawn)>81) { while (myspawn.getBlock().getRelative(0, -1, 0).getType()==Material.AIR && myspawn.getY()>1) { myspawn = myspawn.add(0,-1,0); } @@ -273,6 +273,9 @@ public class EliteMonster { dpslist.clear(); willpower=0; } + if (!m.getLocation().getWorld().equals(myspawn.getWorld())) { + myspawn = m.getLocation(); //Then this is my new spawn... + } } private void dontDrown() { @@ -371,12 +374,12 @@ public class EliteMonster { } if (!storingenergy) { if (storingenergy_hit>0) { - storingenergy_hit/=1.02f; + storingenergy_hit/=1.04f; if (storingenergy_hit<10) { storingenergy_hit=0; } } - if (l.getLocation().distanceSquared(m.getLocation())>4096) { + if (l.getLocation().distanceSquared(m.getLocation())>4096 && !leaping) { //Lose the target. targetlist.remove(l); if (targetlist.size()>0) { @@ -479,13 +482,13 @@ public class EliteMonster { Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { public void run() { last_storingenergy_health=m.getHealth(); - }},5*1); + }},20*1); Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { public void run() { Player target = ChooseRandomTarget(); if (target!=null) { if (last_storingenergy_health-m.getHealth()>0) { - storingenergy_hit=(last_storingenergy_health-m.getHealth())*1000d; + storingenergy_hit=(last_storingenergy_health-m.getHealth())*500d; for (int i=0;i nearbyplayers = GenericFunctions.getNearbyPlayers(target_leap_loc, radius); for (int i=0;i0) { + nearbyplayers.get(i).setVelocity(new Vector(0,2,0)); + } } - GenericFunctions.DealDamageToNearbyPlayers(target_leap_loc, 5, radius, true, 2, m, "Leap",false); + //GenericFunctions.DealDamageToNearbyPlayers(target_leap_loc, 5*200, radius, true, 2, m, "Leap",false); //GenericFunctions.getNear } - },(int)(((20*4)*(CustomDamage.getPercentHealthRemaining(m)/100d))+10)); + },(int)(((20*3)*(CustomDamage.getPercentHealthRemaining(m)/100d))+30)); } private Player ChooseRandomTarget() { @@ -657,13 +669,15 @@ public class EliteMonster { if (!targetlist.contains(ent) && (ent instanceof Player)) { targetlist.add((Player)ent); } - if (ent.hasPotionEffect(PotionEffectType.POISON)) { - int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent); - ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,poisonlv+1),true); - ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,poisonlv+1)); - } else { - ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,0)); - ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,0)); + if (Math.random()<=0.33) { + if (ent.hasPotionEffect(PotionEffectType.POISON)) { + int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent); + ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,poisonlv+1),true); + ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,poisonlv+1)); + } else { + ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,0)); + ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,0)); + } } if (ent instanceof Player) { Player p = (Player)ent; @@ -671,9 +685,11 @@ public class EliteMonster { p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_DOOR_WOOD, 1.0f, 1.0f); p.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION,20*4,0)); TwosideKeeper.log("Got hit for "+storingenergy_hit+" damage!", 2); - CustomDamage.ApplyDamage(storingenergy_hit, m, p, null, "Stored Energy"); - //TwosideKeeperAPI.DealDamageToEntity(.CalculateDamageReduction(storingenergy_hit,p,m),p,m); - storingenergy_hit=0; + GenericFunctions.removeNoDamageTick(p, m); + if (CustomDamage.ApplyDamage(storingenergy_hit, m, p, null, "Stored Energy")) { + //TwosideKeeperAPI.DealDamageToEntity(.CalculateDamageReduction(storingenergy_hit,p,m),p,m); + storingenergy_hit=0; + } } } } @@ -725,7 +741,7 @@ public class EliteMonster { if (finalstr.length()!=0) { finalstr.append("\n"); } - finalstr.append(sorted_pl.get(i)+": "+sorted_dmg.get(i)+" dmg ("+df.format((sorted_dmg.get(i)/totaldmg)*100)+"%)"); + finalstr.append(sorted_pl.get(i)+": "+df.format(sorted_dmg.get(i))+" dmg ("+df.format((sorted_dmg.get(i)/totaldmg)*100)+"%)"); } return finalstr.toString(); } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java b/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java index 257ac36..d66aa00 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/ArtifactAbility.java @@ -35,8 +35,8 @@ public enum ArtifactAbility { new double[]{1.0,0.975,0.95,0.925,0.9,0.875,0.85,0.8,0.75,0.7,0.65,0.6,0.55,0.5,0.4},100,1,UpgradePath.BASIC), EXECUTION("Execute","Deals [VAL] extra damage for every 20% of target's missing health.",new double[]{0.1,0.125,0.15,0.175,0.2,0.225,0.25,0.275,0.3,0.35,0.4,0.5,0.7,0.9,1.25}, new double[]{1.0,0.975,0.95,0.925,0.9,0.875,0.85,0.825,0.8,0.75,0.7,0.65,0.6,0.55,0.5},100,1,UpgradePath.BASIC), - LIFESTEAL("Lifesteal","Heals [VAL]% of the damage dealt to targets back to your health pool.",new double[]{0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.4,1.6,1.8,2.0,2.2}, - new double[]{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},100,1,UpgradePath.WEAPON), + LIFESTEAL("Lifesteal","Heals [VAL]% of the damage dealt to targets back to your health pool.",new double[]{0.8,1.2,1.6,2.0,2.4,2.8,3.2,3.6,4.0,4.4,4.8,5.6,6.4,7.2,8.0,8.8}, + new double[]{1.0,1.0,0.9,0.9,0.8,0.8,0.75,0.75,0.7,0.7,0.6,0.6,0.5,0.5,0.4},100,1,UpgradePath.WEAPON), CRITICAL("Critical","[VAL]% chance to deal critical strikes.",new double[]{1.0,1.25,1.5,1.75,2.0,2.25,2.50,2.75,3.0,3.25,3.50,3.75,4.00,4.25,4.50}, new double[]{1.0,0.975,0.95,0.925,0.9,0.875,0.85,0.825,0.8,0.75,0.7,0.65,0.6,0.55,0.5},100,1,UpgradePath.WEAPON), CRIT_DMG("Crit Damage","Critical Strikes deal [200VAL]% damage.",new double[]{0.5,1.0,2.0,4.0,6.0,10.0,15.0,19.0,22.0,26.0,30.0,35.0,40.0,45.0,60.0}, diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java index 072abaf..3f50ace 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java @@ -2828,10 +2828,9 @@ public class GenericFunctions { p.setVelocity(p.getLocation().getDirection().multiply(1.4f)); } - p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,dodgeduration,0)); + CustomDamage.addIframe(dodgeduration, p); p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,dodgeduration,2)); - p.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING,dodgeduration,0)); - TwosideKeeper.log("Added "+dodgeduration+" glowing ticks to "+p.getName()+" for dodging.",3); + //TwosideKeeper.log("Added "+dodgeduration+" glowing ticks to "+p.getName()+" for dodging.",3); } } } @@ -2944,29 +2943,24 @@ public class GenericFunctions { return false; } - public static void removeNoDamageTick(LivingEntity entity, LivingEntity damager) { - if (entity instanceof Player) { - Player p = (Player)entity; + public static void removeNoDamageTick(LivingEntity entity, Entity damager) { + damager = CustomDamage.getDamagerEntity(damager); + if (damager instanceof Player) { + Player p = (Player)damager; PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - if (damager!=null) { - if (damager instanceof Projectile) { - damager = CustomDamage.getDamagerEntity(damager); - } - pd.hitlist.put(damager.getUniqueId(), TwosideKeeper.getServerTickTime()-10); + if (entity!=null) { + pd.hitlist.remove(entity.getUniqueId()); } else { - pd.hitlist.put(p.getUniqueId(), TwosideKeeper.getServerTickTime()-10); + pd.hitlist.remove(p.getUniqueId()); } } - if (entity instanceof Monster) { - Monster m = (Monster)entity; + if (damager instanceof Monster) { + Monster m = (Monster)damager; MonsterStructure md = MonsterStructure.getMonsterStructure(m); - if (damager!=null) { - if (damager instanceof Projectile) { - damager = CustomDamage.getDamagerEntity(damager); - } - md.hitlist.put(damager.getUniqueId(), TwosideKeeper.getServerTickTime()-10); + if (entity!=null) { + md.hitlist.remove(entity.getUniqueId()); } else { - md.hitlist.put(m.getUniqueId(), TwosideKeeper.getServerTickTime()-10); + md.hitlist.remove(m.getUniqueId()); } } } @@ -3037,31 +3031,35 @@ public class GenericFunctions { } return false; } - + public static boolean isSoftBlock(Block b) { - if (b.getType()==Material.SAND || - b.getType()==Material.DIRT || - b.getType()==Material.GRASS || - b.getType()==Material.GRAVEL || - b.getType()==Material.CLAY || - b.getType()==Material.HARD_CLAY || - b.getType()==Material.STAINED_CLAY || - b.getType()==Material.ENDER_STONE || - b.getType()==Material.SOIL || - b.getType()==Material.SNOW || - b.getType()==Material.SOUL_SAND || - b.getType()==Material.STONE || - b.getType()==Material.COBBLESTONE || - b.getType()==Material.NETHERRACK || - b.getType()==Material.WOOL || - b.getType()==Material.WOOD || - b.getType()==Material.COAL_ORE || - b.getType()==Material.DIAMOND_ORE || - b.getType()==Material.GOLD_ORE || - b.getType()==Material.IRON_ORE || - b.getType()==Material.REDSTONE_ORE || - b.getType()==Material.LAPIS_ORE || - b.getType()==Material.EMERALD_ORE) { + return isSoftBlock(b.getType()); + } + + public static boolean isSoftBlock(Material b) { + if (b==Material.SAND || + b==Material.DIRT || + b==Material.GRASS || + b==Material.GRAVEL || + b==Material.CLAY || + b==Material.HARD_CLAY || + b==Material.STAINED_CLAY || + b==Material.ENDER_STONE || + b==Material.SOIL || + b==Material.SNOW || + b==Material.SOUL_SAND || + b==Material.STONE || + b==Material.COBBLESTONE || + b==Material.NETHERRACK || + b==Material.WOOL || + b==Material.WOOD || + b==Material.COAL_ORE || + b==Material.DIAMOND_ORE || + b==Material.GOLD_ORE || + b==Material.IRON_ORE || + b==Material.REDSTONE_ORE || + b==Material.LAPIS_ORE || + b==Material.EMERALD_ORE) { return true; } else { return false; @@ -3197,16 +3195,19 @@ public class GenericFunctions { return orb; } - public static boolean AttemptRevive(Player p, double dmg) { + public static boolean AttemptRevive(Player p, double dmg, String reason) { boolean revived=false; if (p.getHealth()<=dmg) { //This means we would die from this attack. Attempt to revive the player. //Check all artifact armor for a perk. + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.lastdamagetaken=dmg; + pd.lasthitdesc=reason; ItemStack[] equips = p.getEquipment().getArmorContents(); for (int i=0;i itemcubelist = new ArrayList(); public int lasthitproperties=0; + public String lasthitdesc=""; + public double lastdamagetaken=0; + public double lastrawdamage=0; public long iframetime = 0; diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index 20c1cd0..5bc13b6 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -199,6 +199,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.ItemSet; import sig.plugin.TwosideKeeper.HelperStructures.MalleableBaseQuest; import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.MonsterType; +import sig.plugin.TwosideKeeper.HelperStructures.Pronouns; import sig.plugin.TwosideKeeper.HelperStructures.QuestStatus; import sig.plugin.TwosideKeeper.HelperStructures.ServerType; import sig.plugin.TwosideKeeper.HelperStructures.SessionState; @@ -1103,13 +1104,13 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (SERVER_TYPE==ServerType.TEST || SERVER_TYPE==ServerType.QUIET || p.isOp()) { /*PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); pd.swordcombo=20;*/ - float f = ((org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity)p).getHandle().getAbsorptionHearts(); + /*float f = ((org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity)p).getHandle().getAbsorptionHearts(); log("Absorption Hearts: "+f,2); if (args.length>0) { ((org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity)p).getHandle().setAbsorptionHearts(Float.valueOf(args[0])); - } - /*Monster m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE); - m.setHealth(m.getMaxHealth()/16d);*/ + }*/ + Monster m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE); + m.setHealth(m.getMaxHealth()/16d); //TwosideKeeperAPI.spawnAdjustedMonster(MonsterType.GIANT, p.getLocation()); //TwosideKeeper.log("This is from set "+ItemSet.GetSet(p.getEquipment().getItemInMainHand())+" T"+ItemSet.GetTier(p.getEquipment().getItemInMainHand()),2); /*Skeleton s = (Skeleton)p.getWorld().spawnEntity(p.getLocation(), EntityType.SKELETON); @@ -1429,6 +1430,12 @@ public class TwosideKeeper extends JavaPlugin implements Listener { log("[TASK] New Player Data has been added. Size of array: "+playerdata.size(),4); GenericFunctions.updateSetItemsInInventory(ev.getPlayer().getInventory()); + ev.getPlayer().setCollidable(true); + + ev.getPlayer().removePotionEffect(PotionEffectType.LEVITATION); + ev.getPlayer().removePotionEffect(PotionEffectType.JUMP); + ev.getPlayer().setVelocity(new Vector(0,0,0)); + CustomDamage.removeIframe(ev.getPlayer()); //Update player max health. Check equipment too. setPlayerMaxHealth(ev.getPlayer()); @@ -2868,7 +2875,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } - @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) + @EventHandler(priority=EventPriority.LOWEST,ignoreCancelled = true) public void onPlayerDeath(PlayerDeathEvent ev) { //Modify the death message. This is a fix for getting rid of the healthbar from the player name. final Player p = ev.getEntity(); @@ -2884,21 +2891,27 @@ public class TwosideKeeper extends JavaPlugin implements Listener { newDeathMsg+=" "+parsed_msg[i]; } } + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + if (pd.lasthitdesc!=null) { + newDeathMsg = getFancyDeathMessage(p); + } newDeathMsg=p.getName()+" "+newDeathMsg; ev.setDeathMessage(newDeathMsg); log("Death Message: "+ev.getDeathMessage(),5); + DecimalFormat df = new DecimalFormat("0.00"); if (p!=null) { p.sendMessage(ChatColor.GRAY+"Due to death, you lost "+DEATHPENALTY+"% of your holding money. "); givePlayerMoney(p,-Math.round(getPlayerMoney(p)/2)); - DecimalFormat df = new DecimalFormat("0.00"); p.sendMessage(" Now Holding: "+ChatColor.GREEN+"$"+df.format(getPlayerMoney(p))); } + p.sendMessage("You took "+ChatColor.RED+df.format(pd.lastdamagetaken)+" damage"+ChatColor.WHITE+" from the last attack "+((pd.lasthitdesc!=null)?"("+pd.lasthitdesc+")":""+"!")); + ev.setKeepInventory(true); log("Y position is "+p.getLocation().getY(), 4); DeathManager.addNewDeathStructure(ev.getDrops(), (p.getLocation().getY()<0)?p.getLocation().add(0,-p.getLocation().getY()+256,0) //This means they fell into the void. Might as well put it way higher. :p.getLocation(), p); - PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd = PlayerStructure.GetPlayerStructure(p); pd.hasDied=true; pd.vendetta_amt=0.0; p.getInventory().clear(); @@ -2909,7 +2922,78 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } - @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) + private String getFancyDeathMessage(Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + switch (pd.lasthitdesc) { + case "LAVA": { + if (Math.random()<=0.2) { + return "tried to swim in... Oh who am I kidding, you were just being dumb."; + } else { + return Pronouns.ChoosePronoun(6); + } + } + case "FALL": { + return Pronouns.ChoosePronoun(2)+" and died."; + } + case "FIRE_TICK": + case "FIRE": { + if (Math.random()<0.5) { + return "could not handle the "+Pronouns.ChoosePronoun(3)+" flames."; + } else { + return "was "+Pronouns.ChoosePronoun(4)+" by the flames."; + } + } + case "DROWNING": { + return Pronouns.ChoosePronoun(9); + } + case "CONTACT": { + return "could not resist "+Pronouns.ChoosePronoun(1)+" cacti."; + } + case "FALLING_BLOCK": { + return "got "+Pronouns.ChoosePronoun(10)+" by a falling block."; + } + case "LIGHTNING": { + return Pronouns.ChoosePronoun(11); + } + case "FLY_INTO_WALL": { + return "was flying too fast. SPLAT!"; + } + case "Explosion": + case "BLOCK_EXPLOSION": + case "MELTING":{ + return Pronouns.ChoosePronoun(5); + } + case "Leap": { + return Pronouns.ChoosePronoun(7); + } + case "Stored Energy": { + return Pronouns.ChoosePronoun(8); + } + case "POISON": { + return Pronouns.ChoosePronoun(12)+" Poison."; + } + case "WITHER": { + return Pronouns.ChoosePronoun(13); + } + case "STARVATION":{ + return Pronouns.ChoosePronoun(14); + } + case "SUFFOCATION":{ + return Pronouns.ChoosePronoun(16); + } + case "VOID": { + return Pronouns.ChoosePronoun(0)+" into the void."; + } + case "DRAGON_BREATH": { + return Pronouns.ChoosePronoun(0)+" to the breath of the Ender Dragon."; + } + default:{ + return "has died by "+pd.lasthitdesc; + } + } + } + + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onSignChange(SignChangeEvent ev) { Player p = ev.getPlayer(); Block b = ev.getBlock(); @@ -3253,7 +3337,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } p.playSound(p.getLocation(), Sound.BLOCK_CHEST_CLOSE, 1.0f, 1.0f); itemCube_saveConfig(id,itemcube_contents); - ItemCubeWindow.popItemCubeWindow(p); + if (!pd.opened_another_cube) { + ItemCubeWindow.removeAllItemCubeWindows(p); + } pd.isViewingItemCube=false; } if (ev.getInventory().getLocation()!=null) { @@ -3476,7 +3562,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { //log("Cursor: "+ev.getCursor().toString(),2); ItemStack item = ev.getCursor(); if (item.getType()==Material.AIR) { - ItemCubeWindow.removeAllItemCubeWindows((Player)ev.getWhoClicked()); + //ItemCubeWindow.removeAllItemCubeWindows((Player)ev.getWhoClicked()); + ItemCubeWindow.popItemCubeWindow((Player)ev.getWhoClicked()); ev.getWhoClicked().closeInventory(); } } @@ -3984,6 +4071,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (ev.getCause()!=DamageCause.ENTITY_ATTACK && ev.getCause()!=DamageCause.PROJECTILE && ev.getCause()!=DamageCause.ENTITY_EXPLOSION && + ev.getCause()!=DamageCause.THORNS && ev.getCause()!=DamageCause.MAGIC) { //We handle the event inside of here. DealDamage(ev.getDamage(DamageModifier.BASE)); @@ -3996,7 +4084,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (ev.getCause()!=DamageCause.CUSTOM) { //This is not handled damage, so apply it. double dmgdealt = ev.getDamage(DamageModifier.BASE); CustomDamage.setupTrueDamage(ev); - CustomDamage.ApplyDamage(dmgdealt, null, (LivingEntity)ev.getEntity(), null, null, CustomDamage.TRUEDMG); + CustomDamage.ApplyDamage(dmgdealt, null, (LivingEntity)ev.getEntity(), null, ev.getCause().name(), CustomDamage.TRUEDMG); ev.setCancelled(true); } else { @@ -4009,9 +4097,38 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } + private double getMaxThornsLevelOnEquipment(Entity damager) { + int maxthornslevel = 0; + LivingEntity shooter = CustomDamage.getDamagerEntity(damager); + if (shooter instanceof LivingEntity) { + ItemStack[] equipment = GenericFunctions.getEquipment(shooter); + for (int i=0;imaxthornslevel) { + maxthornslevel=equipment[i].getEnchantmentLevel(Enchantment.THORNS); + } + } + return maxthornslevel; + } + log("[ERROR] Thorns level could not be found even though getMaxThornsLevelOnEquipment() was called!",0); + return 0.01; //This should not happen unless something seriously is bugged with thorns. + } + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void entityHitEvent(EntityDamageByEntityEvent ev) { if (ev.getEntity() instanceof LivingEntity) { + if (ev.getCause()==DamageCause.THORNS) { //Custom thorns damage formula. + double dmgdealt=0; + dmgdealt=getMaxThornsLevelOnEquipment(ev.getDamager()); + if (ev.getEntity() instanceof Player) { + if (GenericFunctions.isRanger((Player)ev.getEntity())) { + dmgdealt=0.25; + } + } + ev.getEntity().getWorld().playSound(ev.getEntity().getLocation(), Sound.ENCHANT_THORNS_HIT, 1.0f, 1.0f); + CustomDamage.setupTrueDamage(ev); + CustomDamage.ApplyDamage(dmgdealt, ev.getDamager(), (LivingEntity)ev.getEntity(), null, ev.getCause().name(), CustomDamage.TRUEDMG); + ev.setCancelled(true); + } else if (ev.getDamage(DamageModifier.BASE)>=CUSTOM_DAMAGE_IDENTIFIER) { log("BASE damage: "+ev.getDamage(DamageModifier.BASE)+"-"+CUSTOM_DAMAGE_IDENTIFIER,5); double dmgdealt = ev.getDamage(DamageModifier.BASE)-CUSTOM_DAMAGE_IDENTIFIER; @@ -4035,18 +4152,32 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } if (CustomDamage.getDamagerEntity(ev.getDamager()) instanceof Player) { - CustomDamage.ApplyDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), weapon, null); - if (ev.getDamager() instanceof Projectile) { - Projectile proj = (Projectile)ev.getDamager(); - proj.remove(); + Player p = (Player)CustomDamage.getDamagerEntity(ev.getDamager()); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + if (GenericFunctions.isDefender(p) && ItemSet.GetSetCount(ItemSet.SONGSTEEL, p)>=5 && pd.vendetta_amt>0.0) { //Deal Vendetta damage instead. + p.playSound(p.getLocation(), Sound.BLOCK_GLASS_BREAK, 1.0f, 0.5f); + double dmg = pd.vendetta_amt; + CustomDamage.ApplyDamage(pd.vendetta_amt, ev.getDamager(), (LivingEntity)ev.getEntity(), null, "Vendetta"); + pd.vendetta_amt=0.0; + aPlugin.API.sendActionBarMessage(p, ChatColor.YELLOW+"Vendetta: "+ChatColor.GREEN+Math.round(pd.vendetta_amt)+" dmg stored"); + } else { + CustomDamage.ApplyDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), weapon, null); + if (ev.getDamager() instanceof Projectile) { + Projectile proj = (Projectile)ev.getDamager(); + proj.remove(); + } + ev.setCancelled(true); } - ev.setCancelled(true); //Handle this manually if it's a player. } else { + if (ev.getEntity() instanceof Player) { //Check for custom trigger events for elites first. + Player p = (Player)ev.getEntity(); + CustomDamage.triggerEliteEvent(p,ev.getDamager()); + } if (!CustomDamage.InvulnerableCheck(ev.getDamager(), (LivingEntity)ev.getEntity())) { double dmgdealt = CustomDamage.CalculateDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), null, null, CustomDamage.NONE); dmgdealt = CustomDamage.subtractAbsorptionHearts(dmgdealt, (LivingEntity)ev.getEntity()); - CustomDamage.applyOnHitEffects(dmgdealt,ev.getDamager(),(LivingEntity)ev.getEntity(),weapon,null,CustomDamage.NONE); + dmgdealt = CustomDamage.applyOnHitEffects(dmgdealt,ev.getDamager(),(LivingEntity)ev.getEntity(),weapon,null,CustomDamage.NONE); if (ev.getDamager()!=null) { TwosideKeeper.logHealth((LivingEntity)ev.getEntity(),((LivingEntity)ev.getEntity()).getHealth(),dmgdealt,ev.getDamager()); } @@ -4122,8 +4253,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { log("Preparing to explode.",5); Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { public void run() { - c.getLocation().getWorld().createExplosion(c.getLocation().getX(),c.getLocation().getY(),c.getLocation().getZ(),4.0f,false,false); GenericFunctions.DealExplosionDamageToEntities(c.getLocation(), 16, 4); + aPlugin.API.sendSoundlessExplosion(c.getLocation(), 4.0f); + c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f); }} ,10); } else @@ -4132,9 +4264,10 @@ public class TwosideKeeper extends JavaPlugin implements Listener { c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f); Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { public void run() { - c.getLocation().getWorld().createExplosion(c.getLocation().getX(),c.getLocation().getY(),c.getLocation().getZ(),6.0f,false,false); - GenericFunctions.RandomlyCreateFire(c.getLocation(),3); GenericFunctions.DealExplosionDamageToEntities(c.getLocation(), 32, 3); + aPlugin.API.sendSoundlessExplosion(c.getLocation(), 6.0f); + c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f); + GenericFunctions.RandomlyCreateFire(c.getLocation(),3); }} ,10); } else @@ -4143,9 +4276,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener { c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f); Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { public void run() { - c.getLocation().getWorld().createExplosion(c.getLocation().getX(),c.getLocation().getY(),c.getLocation().getZ(),8.0f,false,false); - GenericFunctions.RandomlyCreateFire(c.getLocation(),4); GenericFunctions.DealExplosionDamageToEntities(c.getLocation(), 64, 4); + aPlugin.API.sendSoundlessExplosion(c.getLocation(), 8.0f); + c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f); + //c.getLocation().getWorld().createExplosion(c.getLocation().getX(),c.getLocation().getY(),c.getLocation().getZ(),8.0f,false,false); + GenericFunctions.RandomlyCreateFire(c.getLocation(),4); }} ,30); } @@ -4200,7 +4335,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ev.setCancelled(true); } } - m.setTarget(ev.getTarget()); ev.setCancelled(true); } else { log("This monster is "+MonsterController.getMonsterDifficulty(m).name(),5); @@ -4231,6 +4365,15 @@ public class TwosideKeeper extends JavaPlugin implements Listener { Monster m = (Monster)ev.getEntity(); GlowAPI.setGlowing(m, GlowAPI.Color.DARK_RED, Bukkit.getOnlinePlayers()); } + + if(!ev.isCancelled()) { + if ((ev.getEntity() instanceof Monster)) { + Monster m = (Monster)ev.getEntity(); + if (m.hasPotionEffect(PotionEffectType.GLOWING)) { + ev.setCancelled(true); + } + } + } } @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) @@ -4402,15 +4545,19 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:"); - Bukkit.getServer().broadcastMessage(em.generateDPSReport()); - aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+em.generateDPSReport()+"\n```"); Bukkit.getServer().broadcastMessage(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" have successfully slain "+m.getCustomName()+ChatColor.WHITE+"!"); aPlugin.API.discordSendRaw(ChatColor.GREEN+participants_list.toString()+ChatColor.WHITE+" have successfully slain **"+m.getCustomName()+ChatColor.WHITE+"**!"); m.getWorld().spawnEntity(m.getLocation(), EntityType.LIGHTNING); m.getWorld().setStorm(true); m.getWorld().setWeatherDuration(20*60*15); em.removeAllHealthbars(); - elitemonsters.remove(em); + + Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + public void run() { + Bukkit.getServer().broadcastMessage(em.generateDPSReport()); + aPlugin.API.discordSendRaw(ChatColor.YELLOW+"DPS Breakdown:"+"\n```\n"+em.generateDPSReport()+"\n```"); + elitemonsters.remove(em); + }},1); GenericFunctions.generateNewElite(); } @@ -4545,8 +4692,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (DeathManager.getDeathStructure(p)!=null) { DeathManager.continueAction(p); } - p.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION,1,0),true); - p.removePotionEffect(PotionEffectType.ABSORPTION); + p.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,255)); + CustomDamage.setAbsorptionHearts(p, 0.0f); GenericFunctions.addIFrame(p, Integer.MAX_VALUE); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); pd.lastdeath=getServerTickTime(); @@ -4558,7 +4705,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener { pd.hasDied=false; //log("Block started on is "+ev.getRespawnLocation().getBlock(),2); //p.teleport(GenericFunctions.FindRandomFreeLocation(p.getLocation().add(0,1,0))); - ev.setRespawnLocation(GenericFunctions.FindRandomFreeLocation(ev.getRespawnLocation())); + Location newloc = ev.getRespawnLocation(); + newloc.setY(newloc.getWorld().getHighestBlockYAt(ev.getRespawnLocation())); + ev.setRespawnLocation(newloc.add(0,10,0)); } @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) @@ -6537,7 +6686,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { receiver.sendMessage("Habitat Quality: "+habitat_data.getHabitationLevel(p.getLocation())); receiver.sendMessage(ChatColor.GRAY+""+ChatColor.ITALIC+"Base Damage: "+ChatColor.RESET+""+ChatColor.DARK_PURPLE+df.format(store2)); receiver.sendMessage(ChatColor.GRAY+""+ChatColor.ITALIC+"Damage Reduction: "+ChatColor.RESET+""+ChatColor.DARK_AQUA+df.format((1.0-store1)*100)+"%"); - receiver.sendMessage(ChatColor.GRAY+""+ChatColor.ITALIC+"Life Steal: "+ChatColor.RESET+""+ChatColor.DARK_AQUA+df.format(CustomDamage.calculateLifeStealAmount(p)*100)+"%"); + receiver.sendMessage(ChatColor.GRAY+""+ChatColor.ITALIC+"Life Steal: "+ChatColor.RESET+""+ChatColor.DARK_AQUA+df.format(CustomDamage.calculateLifeStealAmount(p,p.getEquipment().getItemInMainHand())*100)+"%"); receiver.sendMessage(ChatColor.GRAY+""+ChatColor.ITALIC+"Critical Strike Chance: "+ChatColor.RESET+""+ChatColor.DARK_AQUA+df.format((CustomDamage.calculateCriticalStrikeChance(p.getEquipment().getItemInMainHand(), p))*100)+"%"); if (GenericFunctions.isDefender(p)) { double dodgechance=0.0; @@ -6617,7 +6766,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { if (CustomDamage.isFlagSet(flags, CustomDamage.IS_HEADSHOT)) { col = ChatColor.DARK_RED; } - updateTitle(shooter,col+""+pd.damagedealt); + DecimalFormat df = new DecimalFormat("0.00"); + updateTitle(shooter,col+""+df.format(pd.damagedealt)); } } diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeperAPI.java b/src/sig/plugin/TwosideKeeper/TwosideKeeperAPI.java index 32a4914..871b8f7 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeperAPI.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeperAPI.java @@ -181,6 +181,17 @@ public final class TwosideKeeperAPI { return CustomDamage.ApplyDamage(damage, damager, target, weapon, reason, flags); } + /** + * Returns the string of the last damage reason the player took. All attacks in the game except + * for basic attacks from monsters and projectiles (which makes this return null) have a reason. + * @param p + * @return Returns the string containing the reason, or null otherwise. + * Be sure to check for null! This CAN and probably WILL return null. + */ + public static String getLastDamageReason(Player p) { + return CustomDamage.getLastDamageReason(p); + } + /** * Determines if the target is invulnerable.