->Rewritten invincibility application code so it no longer causes

players to be permanently invulnerable.
->Players now auto equip items bought back after death.
->Fixed a bug causing Bane of Arthropods and Smite damage to deal one
extra damage more than intended.
->Fixed a bug causing Weakness to show up in the Damage Logger when
Strength was applied.
->Absorption damage calculation is now part of the custom damage
calculation, thus resulting in accurate loss of absorption health when
taking damage.
->Item Cube navigation history resets when opening an item cube from the
lower half of your viewing inventory.
->Non-armored mobs are tankier. Zombie Leaders became much more tankier.
->Lifesteal on artifact items have been significantly reduced.
->'stats' now includes total number of hits and average final damage per
hit.
->Removed Striker's bonus damage based on missing HP. This is going to
be moved to Barbarians in the future.
->The game's damage calculation formula has been rewritten! Damage from
abilities, skills, and weapons should be consistent across the board.
Weapon base damage is now well defined and accurate (only includes
bonuses directly from weapons!) Optimizations have been made to the
game's damage calculation formula.
->Added addIframe(), removeIframe(), and isInIframe(),
getLastDamageReason() to API.
->Remove double cooldown packet sending.
->Fixed a bug causing errors when casting Eruption on Entities that were
not Monsters. Eruption is no longer used up in these cases.
->Made the nether portal respawn code much less likely to spawn you in a
very distant location from your actual bed. It will do a better job of
finding a location close to home.
->All attack bonuses are now applied properly to all abilities, as it
should be. Ex. You can now crit on line drives, deal extra damage on
poisoned mobs when using Eruption, etc. All custom abilities added
through the API should also be handled properly now.
->Death loot is handled slightly differently now, putting you in limbo
while you claim your items. This prevents the player from being
disrupted during this time.
->Fixed a bug where Defense bonuses were not being applied in parties.
->Fixed a bug with no damage ticks not being removed for all attacks
that utilized this behavior.
->Fixed a bug where an Elite Zombie would reset after Leaping when there
were no other valid targets to be found.
->Vendetta behavior modified. When a Full Block occurs dues to block
chance, Vendetta damage increases by 100% of the mitigation damage the
Defender would have taken.
->Defensive enchantments on shields now add to your total damage
reduction properly.
->Elite monster mechanics modified slightly to be a bit more forgiving.
->Item Cube history behavior modified. Clicking outside the window now
goes up a level while pressing escape now closes the inventory
completely. (like old inventory behavior)
This commit is contained in:
sigonasr2 2016-08-21 14:53:42 -05:00
parent 3a92432cb6
commit 6dd39028f7
12 changed files with 750 additions and 174 deletions

Binary file not shown.

View File

@ -54,6 +54,7 @@ public class CustomDamage {
public static final int CRITICALSTRIKE = 1; public static final int CRITICALSTRIKE = 1;
public static final int IGNOREDODGE = 2; public static final int IGNOREDODGE = 2;
public static final int TRUEDMG = 4; 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! //////////////////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. 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. * @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) { 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; double dmg = 0.0;
if (isFlagSet(flags,TRUEDMG)) { if (isFlagSet(flags,TRUEDMG)) {
if (reason!=null) { if (reason!=null) {
@ -153,6 +158,15 @@ public class CustomDamage {
} }
} }
} }
} 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 += 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)); dmg += addMultiplierToPlayerLogger(damager,target,"Striker Mult",dmg * calculateStrikerMultiplier(shooter,target));
double preemptivedmg = addMultiplierToPlayerLogger(damager,target,"Preemptive Strike Mult",dmg * calculatePreemptiveStrikeMultiplier(target,shooter)); double preemptivedmg = addMultiplierToPlayerLogger(damager,target,"Preemptive Strike Mult",dmg * calculatePreemptiveStrikeMultiplier(target,shooter));
@ -164,16 +178,24 @@ public class CustomDamage {
double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,flags)); double critdmg = addMultiplierToPlayerLogger(damager,target,"Critical Strike Mult",dmg * calculateCriticalStrikeMultiplier(weapon,shooter,target,flags));
if (critdmg!=0.0) {crit=true;} if (critdmg!=0.0) {crit=true;}
dmg += critdmg; dmg += critdmg;
}
double armorpendmg = addToPlayerLogger(damager,target,"Armor Pen",calculateArmorPen(damager,dmg,weapon)); double armorpendmg = addToPlayerLogger(damager,target,"Armor Pen",calculateArmorPen(damager,dmg,weapon));
addToLoggerActual(damager,dmg); addToLoggerActual(damager,dmg);
addToPlayerRawDamage(dmg,target);
dmg = CalculateDamageReduction(dmg-armorpendmg,target,damager); 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)); setupDamagePropertiesForPlayer(damager,((crit)?IS_CRIT:0)|((headshot)?IS_HEADSHOT:0)|((preemptive)?IS_PREEMPTIVE:0));
dmg = hardCapDamage(dmg+armorpendmg); dmg = hardCapDamage(dmg+armorpendmg);
return dmg; 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. * Returns how much damage comes from the WEAPON, and no other sources.
* @param damager Optional. * @param damager Optional.
@ -226,17 +248,24 @@ public class CustomDamage {
target.setNoDamageTicks(0); target.setNoDamageTicks(0);
target.setMaximumNoDamageTicks(0); target.setMaximumNoDamageTicks(0);
damage = subtractAbsorptionHearts(damage,target); 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. if (getDamagerEntity(damager) instanceof Player) { //Player dealing damage to living entities does a custom damage modifier.
TwosideKeeper.log("Dealing "+damage+" damage.", 5); TwosideKeeper.log("Dealing "+damage+" damage.", 5);
TwosideKeeper.log("Sending out "+(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER)+" damage.",5); TwosideKeeper.log("Sending out "+(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER)+" damage.",5);
target.damage(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER,getDamagerEntity(damager)); target.damage(damage+TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER,getDamagerEntity(damager));
} else } else
if (!(getDamagerEntity(damager) instanceof LivingEntity)) { if (!(getDamagerEntity(damager) instanceof LivingEntity) || (damage!=0 && isFlagSet(flags,SPECIALATTACK))) {
//TwosideKeeper.log("Sending out "+damage+" damage.",2); //TwosideKeeper.log("Sending out "+damage+" damage.",2);
subtractHealth(damage,target); subtractHealth(damage,target);
aPlugin.API.sendEntityHurtAnimation(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 reason
* @param flags * @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) { String reason, int flags) {
if (target instanceof Player) { if (target instanceof Player) {
Player p = (Player)target; Player p = (Player)target;
@ -263,7 +292,7 @@ public class CustomDamage {
} }
if (p.isBlocking() && ItemSet.hasFullSet(p, ItemSet.SONGSTEEL)) { if (p.isBlocking() && ItemSet.hasFullSet(p, ItemSet.SONGSTEEL)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); 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"); 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); md.SetTarget(target);
} }
increaseStrikerSpeed(p); increaseStrikerSpeed(p);
increaseArtifactArmorXP(p,(int)damage); healDefenderSaturation(p);
reduceDefenderKnockback(p);
if (GenericFunctions.AttemptRevive(p, damage, reason)) {
damage=0;
}
if (damage<p.getHealth()) {increaseArtifactArmorXP(p,(int)damage);}
aPlugin.API.showDamage(target, GetHeartAmount(damage));
} }
LivingEntity shooter = getDamagerEntity(damager); LivingEntity shooter = getDamagerEntity(damager);
if ((shooter instanceof Player) && target!=null) { if ((shooter instanceof Player) && target!=null) {
@ -360,11 +394,67 @@ public class CustomDamage {
increaseSwordComboCount(weapon, p); increaseSwordComboCount(weapon, p);
} }
healDefenderSaturation(p); performMegaKnockback(damager,target);
reduceDefenderKnockback(p);
removePermEnchantments(p,weapon); removePermEnchantments(p,weapon);
castEruption(p,target,weapon); castEruption(p,target,weapon);
addHealthFromLifesteal(p,damage,weapon);
triggerEliteHitEvent(p,target,damage);
subtractWeaponDurability(p,weapon);
aPlugin.API.showDamage(target, GetHeartAmount(damage));
} }
return damage;
}
private static int GetHeartAmount(double dmg) {
int heartcount = 1;
double dmgamountcopy = dmg;
while (dmgamountcopy>10) {
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;i<TwosideKeeper.elitemonsters.size();i++) {
if (TwosideKeeper.elitemonsters.get(i).m.equals(getDamagerEntity(damager))) {
TwosideKeeper.elitemonsters.get(i).hitEvent(p);
}
}
}
private static void triggerEliteHitEvent(Player p, LivingEntity target, double dmg) {
if (target instanceof Monster &&
TwosideKeeper.monsterdata.containsKey(target.getUniqueId())) {
MonsterStructure ms = MonsterStructure.getMonsterStructure((Monster)target);
if (ms.getElite()) {
boolean exists=false;
for (int i=0;i<TwosideKeeper.elitemonsters.size();i++) {
if (TwosideKeeper.elitemonsters.get(i).m.equals(target)) {
exists=true;
TwosideKeeper.elitemonsters.get(i).runHitEvent(p,dmg);
}
}
if (!exists) {
TwosideKeeper.elitemonsters.add(new EliteMonster((Monster)target));
}
}
}
}
private static void addHealthFromLifesteal(Player p, double damage, ItemStack weapon) {
double lifestealamt = damage*calculateLifeStealAmount(p,weapon);
if ((p.getMaxHealth()-p.getHealth())<lifestealamt) {
p.setHealth(p.getMaxHealth());
} else {
p.setHealth(p.getHealth()+lifestealamt);
}
DecimalFormat df = new DecimalFormat("0.00");
TwosideKeeper.log(p.getName()+" healed "+df.format(lifestealamt)+" dmg from Lifesteal.", 5);
} }
public static void castEruption(Player p, Entity target, ItemStack weapon) { public static void castEruption(Player p, Entity target, ItemStack weapon) {
@ -521,6 +611,7 @@ public class CustomDamage {
} }
public static void increaseArtifactArmorXP(Player p, int exp) { public static void increaseArtifactArmorXP(Player p, int exp) {
if (p.getHealth()>0) {
for (int i=0;i<p.getEquipment().getArmorContents().length;i++) { for (int i=0;i<p.getEquipment().getArmorContents().length;i++) {
if (GenericFunctions.isArtifactEquip(p.getEquipment().getArmorContents()[i]) && if (GenericFunctions.isArtifactEquip(p.getEquipment().getArmorContents()[i]) &&
GenericFunctions.isArtifactArmor(p.getEquipment().getArmorContents()[i])) { GenericFunctions.isArtifactArmor(p.getEquipment().getArmorContents()[i])) {
@ -528,6 +619,7 @@ public class CustomDamage {
} }
} }
} }
}
static List<LivingEntity> getAOEList(ItemStack weapon, LivingEntity target) { static List<LivingEntity> getAOEList(ItemStack weapon, LivingEntity target) {
List<LivingEntity> list = new ArrayList<LivingEntity>(); List<LivingEntity> list = new ArrayList<LivingEntity>();
@ -563,29 +655,56 @@ public class CustomDamage {
return livinglist; return livinglist;
} }
static public boolean InvulnerableCheck(Entity damager, LivingEntity target) {
return InvulnerableCheck(damager,target,NONE);
}
/** /**
* Determines if the target is invulnerable. * Determines if the target is invulnerable.
* @param damager * @param damager
* @param target * @param target
* @return Returns true if the target cannot be hit. False otherwise. * @return Returns true if the target cannot be hit. False otherwise.
*/ */
static public boolean InvulnerableCheck(Entity damager, LivingEntity target) { static public boolean InvulnerableCheck(Entity damager, LivingEntity target, int flags) {
if (GenericFunctions.enoughTicksHavePassed(target, damager)) { if (GenericFunctions.enoughTicksHavePassed(target, damager)) {
TwosideKeeper.log("Enough ticks have passed.", 5); TwosideKeeper.log("Enough ticks have passed.", 5);
if (!PassesDodgeCheck(target,damager)) { if (!PassesIframeCheck(target,damager) || isFlagSet(flags,IGNOREDODGE)) {
TwosideKeeper.log("Not in an iframe.", 5);
if (!PassesDodgeCheck(target,damager) || isFlagSet(flags,IGNOREDODGE)) {
GenericFunctions.updateNoDamageTickMap(target, damager); GenericFunctions.updateNoDamageTickMap(target, damager);
TwosideKeeper.log("Did not dodge attack.", 5); TwosideKeeper.log("Did not dodge attack.", 5);
if (!PassesIframeCheck(target,damager)) {
TwosideKeeper.log("Not in an iframe.", 5);
return false; return false;
}
} else { } else {
if (target instanceof Player) {
Player p = (Player)target;
p.playSound(p.getLocation(), Sound.ENTITY_PLAYER_ATTACK_SWEEP, 3.0f, 1.0f);
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.fulldodge=false;
}
calculateGracefulDodgeTicks(target);
GenericFunctions.updateNoDamageTickMap(target, damager); GenericFunctions.updateNoDamageTickMap(target, damager);
} }
} }
}
return true; return true;
} }
private static void calculateGracefulDodgeTicks(LivingEntity target) {
if (target instanceof Player) {
ItemStack[] equip = GenericFunctions.getEquipment(target);
double duration = 0.0;
for (int i=0;i<equip.length;i++) {
if (ArtifactAbility.containsEnchantment(ArtifactAbility.GRACEFULDODGE, equip[i])) {
duration += GenericFunctions.getAbilityValue(ArtifactAbility.GRACEFULDODGE, equip[i]);
}
}
//Convert from seconds to ticks.
int tick_duration = (int)(duration*20);
//Apply iframes.
addIframe(tick_duration,(Player)target);
}
}
private static boolean PassesIframeCheck(LivingEntity target, Entity damager) { private static boolean PassesIframeCheck(LivingEntity target, Entity damager) {
if ((target instanceof Player) && isInIframe((Player)target)) { if ((target instanceof Player) && isInIframe((Player)target)) {
return true; return true;
@ -595,6 +714,13 @@ public class CustomDamage {
private static boolean PassesDodgeCheck(LivingEntity target, Entity damager) { private static boolean PassesDodgeCheck(LivingEntity target, Entity damager) {
if ((target instanceof Player) && Math.random()<CalculateDodgeChance((Player)target)) { if ((target instanceof Player) && Math.random()<CalculateDodgeChance((Player)target)) {
Player p = (Player)target;
double rawdmg = CalculateDamage(0,damager,target,null,null,TRUEDMG)*(1d/CalculateDamageReduction(1,target,damager));
if (p.isBlocking() && ItemSet.hasFullSet(p, ItemSet.SONGSTEEL)) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.vendetta_amt+=((1-CalculateDamageReduction(1,target,damager))*rawdmg);
aPlugin.API.sendActionBarMessage(p, ChatColor.YELLOW+"Vendetta: "+ChatColor.GREEN+Math.round(pd.vendetta_amt)+" dmg stored");
}
return true; return true;
} }
return false; return false;
@ -675,7 +801,7 @@ public class CustomDamage {
double rangerdmgdiv = 0; double rangerdmgdiv = 0;
if (target instanceof LivingEntity) { if (target instanceof LivingEntity) {
ItemStack[] armor = target.getEquipment().getArmorContents(); ItemStack[] armor = GenericFunctions.getEquipment(target);
if (target instanceof Player) { if (target instanceof Player) {
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.ALIKAHN, 2, 2)/100d; rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.ALIKAHN, 2, 2)/100d;
rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.JAMDAK, 2, 2)/100d; rangerdmgdiv += ItemSet.TotalBaseAmountBasedOnSetBonusCount((Player)target, ItemSet.JAMDAK, 2, 2)/100d;
@ -786,6 +912,7 @@ public class CustomDamage {
dmgreduction /= ArtifactAbility.containsEnchantment(ArtifactAbility.GREED, p.getEquipment().getItemInMainHand())?2:1; dmgreduction /= ArtifactAbility.containsEnchantment(ArtifactAbility.GREED, p.getEquipment().getItemInMainHand())?2:1;
}*/ }*/
setbonus = ((100-ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.SONGSTEEL, 4, 4))/100d); setbonus = ((100-ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.SONGSTEEL, 4, 4))/100d);
} }
//Blocking: -((p.isBlocking())?ev.getDamage()*0.33:0) //33% damage will be reduced if we are blocking. //Blocking: -((p.isBlocking())?ev.getDamage()*0.33:0) //33% damage will be reduced if we are blocking.
@ -795,14 +922,14 @@ public class CustomDamage {
resistlevel=(resistlevel>10)?10:resistlevel; resistlevel=(resistlevel>10)?10:resistlevel;
protectionlevel=(protectionlevel>100)?100:protectionlevel; protectionlevel=(protectionlevel>100)?100:protectionlevel;
//partylevel=(partylevel>9)?9:partylevel; partylevel=(partylevel>9)?9:partylevel;
double finaldmg=(basedmg-(basedmg*(dmgreduction/100.0d))) double finaldmg=(basedmg-(basedmg*(dmgreduction/100.0d)))
*(1d-((resistlevel*10d)/100d)) *(1d-((resistlevel*10d)/100d))
*(1d-((protectionlevel)/100d)) *(1d-((protectionlevel)/100d))
*(1d-((projectileprotectionlevel)/100d)) *(1d-((projectileprotectionlevel)/100d))
*(1d-((explosionprotectionlevel)/100d)) *(1d-((explosionprotectionlevel)/100d))
*(1d-rangerdmgdiv) *(1d-rangerdmgdiv)
//*((10-partylevel)*0.1) *(1d-((partylevel*10d)/100d))
*setbonus *setbonus
*((target instanceof Player && ((Player)target).isBlocking())?(GenericFunctions.isDefender((Player)target))?0.30:0.50:1) *((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); *((target instanceof Player)?((GenericFunctions.isDefender((Player)target))?0.9:(target.getEquipment().getItemInOffHand()!=null && target.getEquipment().getItemInOffHand().getType()==Material.SHIELD)?0.95:1):1);
@ -826,6 +953,7 @@ public class CustomDamage {
* @param p * @param p
*/ */
public static void addIframe(int ticks, Player p) { public static void addIframe(int ticks, Player p) {
if (p!=null) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.iframetime<TwosideKeeper.getServerTickTime()+ticks) { if (pd.iframetime<TwosideKeeper.getServerTickTime()+ticks) {
pd.iframetime=TwosideKeeper.getServerTickTime()+ticks; pd.iframetime=TwosideKeeper.getServerTickTime()+ticks;
@ -837,13 +965,19 @@ public class CustomDamage {
p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,ticks,64)); p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,ticks,64));
} }
} }
}
public static boolean isInIframe(Player p) { public static boolean isInIframe(Player p) {
if (p!=null) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
return pd.iframetime>TwosideKeeper.getServerTickTime(); return pd.iframetime>TwosideKeeper.getServerTickTime();
} else {
return false;
}
} }
public static void removeIframe(Player p) { public static void removeIframe(Player p) {
if (p!=null) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.iframetime=0; pd.iframetime=0;
p.removePotionEffect(PotionEffectType.GLOWING); p.removePotionEffect(PotionEffectType.GLOWING);
@ -852,6 +986,7 @@ public class CustomDamage {
p.removePotionEffect(PotionEffectType.NIGHT_VISION); p.removePotionEffect(PotionEffectType.NIGHT_VISION);
} }
} }
}
/** /**
* Returns the shooter of a projectile. * Returns the shooter of a projectile.
@ -996,7 +1131,7 @@ public class CustomDamage {
static double calculateStrengthEffectMultiplier(LivingEntity damager, LivingEntity target) { static double calculateStrengthEffectMultiplier(LivingEntity damager, LivingEntity target) {
double mult = 0.0; 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; mult += (GenericFunctions.getPotionEffectLevel(PotionEffectType.INCREASE_DAMAGE, damager)+1)*0.1;
} }
return mult; return mult;
@ -1004,7 +1139,7 @@ public class CustomDamage {
static double calculateWeaknessEffectMultiplier(LivingEntity damager, LivingEntity target) { static double calculateWeaknessEffectMultiplier(LivingEntity damager, LivingEntity target) {
double mult = 0.0; double mult = 0.0;
if (damager.hasPotionEffect(PotionEffectType.WEAKNESS)) { if (damager!=null && damager.hasPotionEffect(PotionEffectType.WEAKNESS)) {
int weaknesslv = GenericFunctions.getPotionEffectLevel(PotionEffectType.WEAKNESS, damager)+1; int weaknesslv = GenericFunctions.getPotionEffectLevel(PotionEffectType.WEAKNESS, damager)+1;
if (weaknesslv>10) { if (weaknesslv>10) {
mult -= 1.0; mult -= 1.0;
@ -1336,6 +1471,8 @@ public class CustomDamage {
} }
private static void subtractHealth(double damage, LivingEntity target) { private static void subtractHealth(double damage, LivingEntity target) {
if (target instanceof Player) {TwosideKeeper.log("Going to subtract "+damage+" damage", 5);}
if (target.getHealth()>0) {
if (target.getHealth()<damage) { if (target.getHealth()<damage) {
target.setHealth(0.00001); target.setHealth(0.00001);
target.damage(Integer.MAX_VALUE); target.damage(Integer.MAX_VALUE);
@ -1343,6 +1480,7 @@ public class CustomDamage {
target.setHealth(target.getHealth()-damage); target.setHealth(target.getHealth()-damage);
} }
} }
}
public static void setAbsorptionHearts(LivingEntity l, float new_absorption_val) { public static void setAbsorptionHearts(LivingEntity l, float new_absorption_val) {
if (l instanceof LivingEntity) { if (l instanceof LivingEntity) {
@ -1441,6 +1579,9 @@ public class CustomDamage {
case GHAST: case GHAST:
difficulty_damage=new double[]{10.0,20.0,30.0}; difficulty_damage=new double[]{10.0,20.0,30.0};
break; break;
case PRIMED_TNT:
difficulty_damage=new double[]{10.0,20.0,30.0};
break;
case GUARDIAN: case GUARDIAN:
difficulty_damage=new double[]{4.0,7.0,10.0}; difficulty_damage=new double[]{4.0,7.0,10.0};
break; break;
@ -1567,8 +1708,8 @@ public class CustomDamage {
} }
/*0.0-1.0*/ /*0.0-1.0*/
public static double calculateLifeStealAmount(Player p) { public static double calculateLifeStealAmount(Player p, ItemStack weapon) {
double lifestealpct = GenericFunctions.getAbilityValue(ArtifactAbility.LIFESTEAL, p.getEquipment().getItemInMainHand())/100; double lifestealpct = GenericFunctions.getAbilityValue(ArtifactAbility.LIFESTEAL, weapon)/100;
lifestealpct += ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.DAWNTRACKER, 3, 3)/100d; lifestealpct += ItemSet.TotalBaseAmountBasedOnSetBonusCount(p, ItemSet.DAWNTRACKER, 3, 3)/100d;
return lifestealpct; return lifestealpct;
} }
@ -1691,4 +1832,9 @@ public class CustomDamage {
} }
} }
} }
public static String getLastDamageReason(Player p) {
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
return pd.lasthitdesc;
}
} }

View File

@ -17,8 +17,10 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import sig.plugin.TwosideKeeper.HelperStructures.DeathStructure; import sig.plugin.TwosideKeeper.HelperStructures.DeathStructure;
import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions;
public class DeathManager { public class DeathManager {
static String Pick5Text = "Mercy (Pick 5 Lost Items)"; static String Pick5Text = "Mercy (Pick 5 Lost Items)";
@ -33,10 +35,21 @@ public class DeathManager {
} }
public static void removeDeathStructure(Player p) { public static void removeDeathStructure(Player p) {
ds.remove(getDeathStructure(p)); ds.remove(getDeathStructure(p));
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
@Override
public void run() {
p.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,15,-2),true);
p.addPotionEffect(new PotionEffect(PotionEffectType.JUMP,15,100),true);
p.setVelocity(new Vector(0,0,0));
CustomDamage.removeIframe(p); CustomDamage.removeIframe(p);
Location loc = p.getLocation();
loc.setY(p.getBedSpawnLocation().getY());
p.teleport(loc);
}},1);
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.deathloot.clear(); pd.deathloot.clear();
pd.hasDied=false; pd.hasDied=false;
p.setCollidable(true);
} }
public static boolean deathStructureExists(Player p) { public static boolean deathStructureExists(Player p) {
if (getDeathStructure(p)!=null) { if (getDeathStructure(p)!=null) {

View File

@ -156,7 +156,7 @@ public class EliteMonster {
if (mobcount>0) { if (mobcount>0) {
willpower+=mobcount; willpower+=mobcount;
last_willpower_increase=TwosideKeeper.getServerTickTime(); last_willpower_increase=TwosideKeeper.getServerTickTime();
if (!first_willpower_notification) { if (!first_willpower_notification && willpower>20) {
for (int i=0;i<targetlist.size();i++) { for (int i=0;i<targetlist.size();i++) {
targetlist.get(i).sendMessage(ChatColor.ITALIC+"The "+m.getCustomName()+ChatColor.RESET+ChatColor.ITALIC+" gains morale and the will to fight from its minions!"); targetlist.get(i).sendMessage(ChatColor.ITALIC+"The "+m.getCustomName()+ChatColor.RESET+ChatColor.ITALIC+" gains morale and the will to fight from its minions!");
} }
@ -256,7 +256,7 @@ public class EliteMonster {
} }
private void resetToSpawn() { private void resetToSpawn() {
if (targetlist.size()==0 && m.getLocation().distanceSquared(myspawn)>81) { 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) { while (myspawn.getBlock().getRelative(0, -1, 0).getType()==Material.AIR && myspawn.getY()>1) {
myspawn = myspawn.add(0,-1,0); myspawn = myspawn.add(0,-1,0);
} }
@ -273,6 +273,9 @@ public class EliteMonster {
dpslist.clear(); dpslist.clear();
willpower=0; willpower=0;
} }
if (!m.getLocation().getWorld().equals(myspawn.getWorld())) {
myspawn = m.getLocation(); //Then this is my new spawn...
}
} }
private void dontDrown() { private void dontDrown() {
@ -371,12 +374,12 @@ public class EliteMonster {
} }
if (!storingenergy) { if (!storingenergy) {
if (storingenergy_hit>0) { if (storingenergy_hit>0) {
storingenergy_hit/=1.02f; storingenergy_hit/=1.04f;
if (storingenergy_hit<10) { if (storingenergy_hit<10) {
storingenergy_hit=0; storingenergy_hit=0;
} }
} }
if (l.getLocation().distanceSquared(m.getLocation())>4096) { if (l.getLocation().distanceSquared(m.getLocation())>4096 && !leaping) {
//Lose the target. //Lose the target.
targetlist.remove(l); targetlist.remove(l);
if (targetlist.size()>0) { if (targetlist.size()>0) {
@ -479,13 +482,13 @@ public class EliteMonster {
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() { public void run() {
last_storingenergy_health=m.getHealth(); last_storingenergy_health=m.getHealth();
}},5*1); }},20*1);
Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(TwosideKeeper.plugin, new Runnable() {
public void run() { public void run() {
Player target = ChooseRandomTarget(); Player target = ChooseRandomTarget();
if (target!=null) { if (target!=null) {
if (last_storingenergy_health-m.getHealth()>0) { 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<targetlist.size();i++) { for (int i=0;i<targetlist.size();i++) {
targetlist.get(i).sendMessage(ChatColor.GOLD+"The "+m.getCustomName()+ChatColor.GOLD+"'s next hit is stronger!"); targetlist.get(i).sendMessage(ChatColor.GOLD+"The "+m.getCustomName()+ChatColor.GOLD+"'s next hit is stronger!");
targetlist.get(i).sendMessage(ChatColor.DARK_RED+""+ChatColor.ITALIC+" \"DIE "+target.getName()+ChatColor.DARK_RED+"! DIEE!\""); targetlist.get(i).sendMessage(ChatColor.DARK_RED+""+ChatColor.ITALIC+" \"DIE "+target.getName()+ChatColor.DARK_RED+"! DIEE!\"");
@ -499,7 +502,7 @@ public class EliteMonster {
storingenergy=false; storingenergy=false;
} }
} }
},5*20); },6*20);
} }
} }
if (CustomDamage.getPercentHealthRemaining(m)<=10) { if (CustomDamage.getPercentHealthRemaining(m)<=10) {
@ -572,7 +575,7 @@ public class EliteMonster {
private void performLeap() { private void performLeap() {
last_leap_time = TwosideKeeper.getServerTickTime(); last_leap_time = TwosideKeeper.getServerTickTime();
int radius = (int)(6*(CustomDamage.getPercentHealthMissing(m)/100d)); int radius = (int)(6*(CustomDamage.getPercentHealthMissing(m)/100d))+1;
//Choose a target randomly. //Choose a target randomly.
Player target = ChooseRandomTarget(); Player target = ChooseRandomTarget();
m.setTarget(target); m.setTarget(target);
@ -586,7 +589,7 @@ public class EliteMonster {
for (int x=-radius;x<radius+1;x++) { for (int x=-radius;x<radius+1;x++) {
for (int z=-radius;z<radius+1;z++) { for (int z=-radius;z<radius+1;z++) {
Block b = target.getLocation().add(x,-0.9,z).getBlock(); Block b = target.getLocation().add(x,-0.9,z).getBlock();
if (b.getType()!=Material.AIR && aPlugin.API.isDestroyable(b) && GenericFunctions.isSoftBlock(b)) { if (b.getType()!=Material.AIR && b.getType()!=Material.STAINED_GLASS) {
storedblocks.put(b, b.getType()); storedblocks.put(b, b.getType());
b.setType(Material.STAINED_GLASS); b.setType(Material.STAINED_GLASS);
b.setData((byte)4); b.setData((byte)4);
@ -604,23 +607,32 @@ public class EliteMonster {
private void restoreBlocks() { private void restoreBlocks() {
for (Block b : storedblocks.keySet()) { for (Block b : storedblocks.keySet()) {
if (b.getType()!=Material.AIR && aPlugin.API.isDestroyable(b) && GenericFunctions.isSoftBlock(b)) {
FallingBlock fb = (FallingBlock)b.getLocation().getWorld().spawnFallingBlock(b.getLocation(), storedblocks.get(b), b.getData()); FallingBlock fb = (FallingBlock)b.getLocation().getWorld().spawnFallingBlock(b.getLocation(), storedblocks.get(b), b.getData());
fb.setMetadata("FAKE", new FixedMetadataValue(TwosideKeeper.plugin,true)); fb.setMetadata("FAKE", new FixedMetadataValue(TwosideKeeper.plugin,true));
fb.setVelocity(new Vector(0,Math.random()*1.7,0)); fb.setVelocity(new Vector(0,Math.random()*1.7,0));
//b.setType(storedblocks.get(b)); //b.setType(storedblocks.get(b));
b.setType(Material.AIR); b.setType(Material.AIR);
} else {
b.setType(storedblocks.get(b));
}
aPlugin.API.sendSoundlessExplosion(target_leap_loc, 4); aPlugin.API.sendSoundlessExplosion(target_leap_loc, 4);
b.getLocation().getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.7f, 1.2f); b.getLocation().getWorld().playSound(b.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.7f, 1.2f);
} }
storedblocks.clear(); storedblocks.clear();
m.getLocation().getWorld().playSound(m.getLocation(), Sound.ENTITY_GENERIC_EXPLODE, 0.7f, 1.2f);
List<Player> nearbyplayers = GenericFunctions.getNearbyPlayers(target_leap_loc, radius); List<Player> nearbyplayers = GenericFunctions.getNearbyPlayers(target_leap_loc, radius);
for (int i=0;i<nearbyplayers.size();i++) { for (int i=0;i<nearbyplayers.size();i++) {
GenericFunctions.removeNoDamageTick(nearbyplayers.get(i), m); GenericFunctions.removeNoDamageTick(nearbyplayers.get(i), m);
boolean applied = CustomDamage.ApplyDamage(1000, m, nearbyplayers.get(i), null, "Leap", CustomDamage.NONE);
if (applied && nearbyplayers.get(i).getHealth()>0) {
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 //GenericFunctions.getNear
} }
},(int)(((20*4)*(CustomDamage.getPercentHealthRemaining(m)/100d))+10)); },(int)(((20*3)*(CustomDamage.getPercentHealthRemaining(m)/100d))+30));
} }
private Player ChooseRandomTarget() { private Player ChooseRandomTarget() {
@ -657,6 +669,7 @@ public class EliteMonster {
if (!targetlist.contains(ent) && (ent instanceof Player)) { if (!targetlist.contains(ent) && (ent instanceof Player)) {
targetlist.add((Player)ent); targetlist.add((Player)ent);
} }
if (Math.random()<=0.33) {
if (ent.hasPotionEffect(PotionEffectType.POISON)) { if (ent.hasPotionEffect(PotionEffectType.POISON)) {
int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent); int poisonlv = GenericFunctions.getPotionEffectLevel(PotionEffectType.POISON, ent);
ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,poisonlv+1),true); ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,poisonlv+1),true);
@ -665,18 +678,21 @@ public class EliteMonster {
ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,0)); ent.addPotionEffect(new PotionEffect(PotionEffectType.POISON,POISON_DURATION,0));
ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,0)); ent.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING,POISON_DURATION,0));
} }
}
if (ent instanceof Player) { if (ent instanceof Player) {
Player p = (Player)ent; Player p = (Player)ent;
if (storingenergy_hit>0) { if (storingenergy_hit>0) {
p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_DOOR_WOOD, 1.0f, 1.0f); p.playSound(p.getLocation(), Sound.ENTITY_ZOMBIE_BREAK_DOOR_WOOD, 1.0f, 1.0f);
p.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION,20*4,0)); p.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION,20*4,0));
TwosideKeeper.log("Got hit for "+storingenergy_hit+" damage!", 2); TwosideKeeper.log("Got hit for "+storingenergy_hit+" damage!", 2);
CustomDamage.ApplyDamage(storingenergy_hit, m, p, null, "Stored Energy"); GenericFunctions.removeNoDamageTick(p, m);
if (CustomDamage.ApplyDamage(storingenergy_hit, m, p, null, "Stored Energy")) {
//TwosideKeeperAPI.DealDamageToEntity(.CalculateDamageReduction(storingenergy_hit,p,m),p,m); //TwosideKeeperAPI.DealDamageToEntity(.CalculateDamageReduction(storingenergy_hit,p,m),p,m);
storingenergy_hit=0; storingenergy_hit=0;
} }
} }
} }
}
public Monster getMonster() { public Monster getMonster() {
return m; return m;
@ -725,7 +741,7 @@ public class EliteMonster {
if (finalstr.length()!=0) { if (finalstr.length()!=0) {
finalstr.append("\n"); 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(); return finalstr.toString();
} }

View File

@ -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), 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}, 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), 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}, 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,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), 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}, 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), 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}, 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},

View File

@ -2828,10 +2828,9 @@ public class GenericFunctions {
p.setVelocity(p.getLocation().getDirection().multiply(1.4f)); 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.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; return false;
} }
public static void removeNoDamageTick(LivingEntity entity, LivingEntity damager) { public static void removeNoDamageTick(LivingEntity entity, Entity damager) {
if (entity instanceof Player) { damager = CustomDamage.getDamagerEntity(damager);
Player p = (Player)entity; if (damager instanceof Player) {
Player p = (Player)damager;
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (damager!=null) { if (entity!=null) {
if (damager instanceof Projectile) { pd.hitlist.remove(entity.getUniqueId());
damager = CustomDamage.getDamagerEntity(damager);
}
pd.hitlist.put(damager.getUniqueId(), TwosideKeeper.getServerTickTime()-10);
} else { } else {
pd.hitlist.put(p.getUniqueId(), TwosideKeeper.getServerTickTime()-10); pd.hitlist.remove(p.getUniqueId());
} }
} }
if (entity instanceof Monster) { if (damager instanceof Monster) {
Monster m = (Monster)entity; Monster m = (Monster)damager;
MonsterStructure md = MonsterStructure.getMonsterStructure(m); MonsterStructure md = MonsterStructure.getMonsterStructure(m);
if (damager!=null) { if (entity!=null) {
if (damager instanceof Projectile) { md.hitlist.remove(entity.getUniqueId());
damager = CustomDamage.getDamagerEntity(damager);
}
md.hitlist.put(damager.getUniqueId(), TwosideKeeper.getServerTickTime()-10);
} else { } else {
md.hitlist.put(m.getUniqueId(), TwosideKeeper.getServerTickTime()-10); md.hitlist.remove(m.getUniqueId());
} }
} }
} }
@ -3039,29 +3033,33 @@ public class GenericFunctions {
} }
public static boolean isSoftBlock(Block b) { public static boolean isSoftBlock(Block b) {
if (b.getType()==Material.SAND || return isSoftBlock(b.getType());
b.getType()==Material.DIRT || }
b.getType()==Material.GRASS ||
b.getType()==Material.GRAVEL || public static boolean isSoftBlock(Material b) {
b.getType()==Material.CLAY || if (b==Material.SAND ||
b.getType()==Material.HARD_CLAY || b==Material.DIRT ||
b.getType()==Material.STAINED_CLAY || b==Material.GRASS ||
b.getType()==Material.ENDER_STONE || b==Material.GRAVEL ||
b.getType()==Material.SOIL || b==Material.CLAY ||
b.getType()==Material.SNOW || b==Material.HARD_CLAY ||
b.getType()==Material.SOUL_SAND || b==Material.STAINED_CLAY ||
b.getType()==Material.STONE || b==Material.ENDER_STONE ||
b.getType()==Material.COBBLESTONE || b==Material.SOIL ||
b.getType()==Material.NETHERRACK || b==Material.SNOW ||
b.getType()==Material.WOOL || b==Material.SOUL_SAND ||
b.getType()==Material.WOOD || b==Material.STONE ||
b.getType()==Material.COAL_ORE || b==Material.COBBLESTONE ||
b.getType()==Material.DIAMOND_ORE || b==Material.NETHERRACK ||
b.getType()==Material.GOLD_ORE || b==Material.WOOL ||
b.getType()==Material.IRON_ORE || b==Material.WOOD ||
b.getType()==Material.REDSTONE_ORE || b==Material.COAL_ORE ||
b.getType()==Material.LAPIS_ORE || b==Material.DIAMOND_ORE ||
b.getType()==Material.EMERALD_ORE) { b==Material.GOLD_ORE ||
b==Material.IRON_ORE ||
b==Material.REDSTONE_ORE ||
b==Material.LAPIS_ORE ||
b==Material.EMERALD_ORE) {
return true; return true;
} else { } else {
return false; return false;
@ -3197,16 +3195,19 @@ public class GenericFunctions {
return orb; return orb;
} }
public static boolean AttemptRevive(Player p, double dmg) { public static boolean AttemptRevive(Player p, double dmg, String reason) {
boolean revived=false; boolean revived=false;
if (p.getHealth()<=dmg) { if (p.getHealth()<=dmg) {
//This means we would die from this attack. Attempt to revive the player. //This means we would die from this attack. Attempt to revive the player.
//Check all artifact armor for a perk. //Check all artifact armor for a perk.
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.lastdamagetaken=dmg;
pd.lasthitdesc=reason;
ItemStack[] equips = p.getEquipment().getArmorContents(); ItemStack[] equips = p.getEquipment().getArmorContents();
for (int i=0;i<equips.length;i++) { for (int i=0;i<equips.length;i++) {
if (isArtifactEquip(equips[i]) && ArtifactAbility.containsEnchantment(ArtifactAbility.SURVIVOR, equips[i])) { if (isArtifactEquip(equips[i]) && ArtifactAbility.containsEnchantment(ArtifactAbility.SURVIVOR, equips[i])) {
//We can revive! //We can revive!
RevivePlayer(p, p.getMaxHealth()*(getAbilityValue(ArtifactAbility.SURVIVOR,equips[i])/100d)); RevivePlayer(p, Math.min(p.getMaxHealth()*(getAbilityValue(ArtifactAbility.SURVIVOR,equips[i])/100d),p.getMaxHealth()));
ArtifactAbility.removeEnchantment(ArtifactAbility.SURVIVOR, equips[i]); ArtifactAbility.removeEnchantment(ArtifactAbility.SURVIVOR, equips[i]);
revived=true; revived=true;
Bukkit.broadcastMessage(ChatColor.GOLD+p.getName()+ChatColor.WHITE+" almost died... But came back to life!"); Bukkit.broadcastMessage(ChatColor.GOLD+p.getName()+ChatColor.WHITE+" almost died... But came back to life!");
@ -3230,9 +3231,10 @@ public class GenericFunctions {
} }
} }
p.setFireTicks(0); p.setFireTicks(0);
p.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING,20,0)); CustomDamage.addIframe(40, p);
TwosideKeeper.log("Added "+20+" glowing ticks to "+p.getName()+" for reviving.",3); //p.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING,20,0));
p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,20,0)); //TwosideKeeper.log("Added "+20+" glowing ticks to "+p.getName()+" for reviving.",3);
//p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION,20,0));
} }
public static void DealExplosionDamageToEntities(Location l, double basedmg, double range) { public static void DealExplosionDamageToEntities(Location l, double basedmg, double range) {
@ -3253,7 +3255,8 @@ public class GenericFunctions {
damage_mult*=TwosideKeeper.EXPLOSION_DMG_MULT; damage_mult*=TwosideKeeper.EXPLOSION_DMG_MULT;
damage_mult*=CalculateBlastResistance((LivingEntity)nearbyentities.get(i)); damage_mult*=CalculateBlastResistance((LivingEntity)nearbyentities.get(i));
double dmg = basedmg * damage_mult; double dmg = basedmg * damage_mult;
CustomDamage.ApplyDamage(dmg, null, (LivingEntity)nearbyentities.get(i), null, null, CustomDamage.NONE); if (nearbyentities.get(i) instanceof Player) {TwosideKeeper.log("Damage is "+dmg, 5);}
CustomDamage.ApplyDamage(dmg, null, (LivingEntity)nearbyentities.get(i), null, "Explosion", CustomDamage.NONE);
//subtractHealth((LivingEntity)nearbyentities.get(i),null,NewCombat.CalculateDamageReduction(dmg, (LivingEntity)nearbyentities.get(i), null)); //subtractHealth((LivingEntity)nearbyentities.get(i),null,NewCombat.CalculateDamageReduction(dmg, (LivingEntity)nearbyentities.get(i), null));
} }
} }
@ -3576,6 +3579,6 @@ public class GenericFunctions {
testloc.getBlock().getType()==Material.ENDER_PORTAL) || testloc.getBlock().getType()==Material.ENDER_PORTAL) ||
testloc.getBlock().getRelative(0, 1, 0).getType()!=Material.AIR); testloc.getBlock().getRelative(0, 1, 0).getType()!=Material.AIR);
} }
return testloc.getBlock().getLocation().add(0.5, 1.5, 0.5); return testloc.getBlock().getLocation().add(0.5, 1.0, 0.5);
} }
} }

View File

@ -0,0 +1,224 @@
package sig.plugin.TwosideKeeper.HelperStructures;
import org.bukkit.ChatColor;
public class Pronouns {
public static String ChoosePronoun(int type) {
String[] pronouns = null;
switch (type) {
case 0:{
pronouns = new String[]{
"evaporated",
"vaporized",
"disappeared",
"melted",
"vanished",
"dematerialized",
"faded away",
};
}break;
case 1:{
pronouns = new String[]{
"getting poked by",
"getting jabbed by",
"hitting the",
"sitting on",
"hugging",
"the charming good looks of",
};
}break;
case 2:{
pronouns = new String[]{
"fell",
"stumbled",
"tumbled the wrong way",
"nose dived headfirst into the ground",
"plunged into the earth",
"tried to fly",
"thought they were Superman",
};
}break;
case 3:{
pronouns = new String[]{
"scorching heat of the",
"burn from the",
"heat of the",
"hot",
"burning",
"intense",
"last tick of",
ChatColor.YELLOW+"fire and",
};
}break;
case 4:{
pronouns = new String[]{
"scorched",
"burned",
"incinerated",
"destroyed",
"owned",
"melted",
"roasted",
"wrecked",
"boiled",
"rekt",
};
}break;
case 5:{
pronouns = new String[]{
"exploded.",
"decided there was a better life worth living.",
"exploded by the after shock.",
"was shredded by the secondary explsion.",
"exploded into pieces.",
"could not handle the after shock.",
"was feeling a little greedy, blindly walking into the demolition zone.",
"was feeling brave, but didn't seem all that tough after all!",
};
}break;
case 6:{
pronouns = new String[]{
"was roasted in a fiery oven.",
"was cooked by the vicious flames of lava.",
"tried to find the Underworld.",
"tried to swim in lava.",
"died to lava. Learn2P1ay skrub.",
"died in a pool of lava.",
"probably fell off a ledge into lava again.",
"fell into lava.",
"was playing with fire.",
"could not handle the intense heat.",
"turned to ashes.",
"instantly vaporized in a fiery hell.",
"tried out a fiery bath. It was too hot.",
"did not live to the fiery duress that is lava.",
};
}break;
case 7:{
pronouns = new String[]{
"got stomped on viciously.",
"got smooshed on by the Leap attack.",
"got squished on by the Leap attack.",
"did not survive the Leap attack.",
"got obliterated by the Leap attack.",
"got obliterated by the Leap attack.",
"got mashed into the ground from the Leap attack.",
"got smashed into the ground from the Leap attack..",
"did not see the clearly imprinted Yellow Glass on the ground, dying to the Leap attack.",
};
}break;
case 8:{
pronouns = new String[]{
"took on too much from the Stored Energy attack.",
"got steamrolled by the Stored Energy attack.",
"did not pay attention to the Stored Energy attack.",
"was put into the grave by the Stored Energy attack.",
"was killed by the Stored Energy attack.",
};
}break;
case 9:{
pronouns = new String[]{
"drowned.",
"ran out of air.",
"inhaled too much water.",
"could not find any oxygen.",
"could not reach the surface in time.",
"was not paying attention to their air meter.",
"could not breathe underwater.",
"is now swimming with the fishes.",
"took a last gasp of water before perishing in the sea.",
"could not make it to the surface.",
};
}break;
case 10:{
pronouns = new String[]{
"smashed",
"squished",
"smothered",
"flattened",
"destroyed",
"blasted",
"owned",
};
}break;
case 11:{
pronouns = new String[]{
"was electrocuted by Lightning.",
"was deleted by Lightning.",
"was blasted by Lightning.",
"received a painful electric shock from Lightning.",
"died to Lightning. Stop flying those kites in this weather!",
"was struck by Lightning. The Gods did not deem them worthy of living.",
"got struck by Lightning.",
"got killed by Lightning.",
};
}break;
case 12:{
pronouns = new String[]{
"was wracked by",
"was killed by the disasterous effects of",
"took too much",
"could not handle",
"died to",
"killed by vile ",
"killed by deadly ",
};
}break;
case 13:{
pronouns = new String[]{
"withered away.",
"withered away...Never to be seen again/",
"did not respect the Wither effect damage.",
"could not handle the Wither effect.",
"slowly withered into oblivion.",
"withered.",
"died to the Wither effect.",
"was under the effects of Wither for just too long.",
"could not shake off the last few ticks of the Wither effect in time.",
"almost lived through the Wither effect.",
"slowly withered away.",
};
}break;
case 14:{
pronouns = new String[]{
"starved.",
"died of starvation.",
"starved to death. They should have ate that last piece "+Pronouns.ChoosePronoun(15),
"thought they could live without eating that piece of "+Pronouns.ChoosePronoun(15),
};
}break;
case 15:{
pronouns = new String[]{
"beef",
"chicken",
"pork",
"rabbit",
"bread",
"beetroot",
"fish",
"cake",
"salmon",
"rotten flesh",
"potato",
"melon",
"pie",
};
}
case 16:{
pronouns = new String[]{
"thought living inside a block was a good idea.",
"suffocated.",
"died to a block.",
"got owned by a block.",
"somehow ended up trapped inside a wall.",
"somehow ended up trapped inside a block.",
"ended up suffocating.",
};
}
}
return pronouns[(int)(Math.random()*pronouns.length)];
}
}

View File

@ -4,6 +4,7 @@ import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result; import org.bukkit.event.Event.Result;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
@ -35,12 +36,16 @@ public class ItemCubeWindow {
inv_size=27; inv_size=27;
} }
Inventory temp = Bukkit.getServer().createInventory(p, inv_size, "Item Cube #"+itemcubeid); Inventory temp = Bukkit.getServer().createInventory(p, inv_size, "Item Cube #"+itemcubeid);
pd.opened_another_cube=true;
TwosideKeeper.openItemCubeInventory(temp); TwosideKeeper.openItemCubeInventory(temp);
pd.opened_another_cube=false;
InventoryView newinv = p.openInventory(temp); InventoryView newinv = p.openInventory(temp);
pd.isViewingItemCube=true; pd.isViewingItemCube=true;
p.playSound(p.getLocation(),Sound.BLOCK_CHEST_OPEN,1.0f,1.0f); p.playSound(p.getLocation(),Sound.BLOCK_CHEST_OPEN,1.0f,1.0f);
} else { } else {
pd.opened_another_cube=true;
p.openInventory(ItemCube.getViewingItemCubeInventory(itemcubeid, p)); p.openInventory(ItemCube.getViewingItemCubeInventory(itemcubeid, p));
pd.opened_another_cube=false;
pd.isViewingItemCube=true; pd.isViewingItemCube=true;
p.playSound(p.getLocation(), Sound.BLOCK_CHEST_OPEN, 1.0f, 1.0f); p.playSound(p.getLocation(), Sound.BLOCK_CHEST_OPEN, 1.0f, 1.0f);
} }

View File

@ -727,6 +727,7 @@ public class MonsterController {
if (!GenericFunctions.isArmoredMob(m)) { if (!GenericFunctions.isArmoredMob(m)) {
m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,1)); m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,1));
} }
m.getAttribute(Attribute.GENERIC_FOLLOW_RANGE).setBaseValue(32.0);
}break; }break;
case DEADLY: { case DEADLY: {
if (isAllowedToEquipItems(m)) { if (isAllowedToEquipItems(m)) {
@ -751,6 +752,7 @@ public class MonsterController {
if (!GenericFunctions.isArmoredMob(m)) { if (!GenericFunctions.isArmoredMob(m)) {
m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,3)); m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,3));
} }
m.getAttribute(Attribute.GENERIC_FOLLOW_RANGE).setBaseValue(48.0);
}break; }break;
case HELLFIRE:{ case HELLFIRE:{
//m.setCustomName(ChatColor.DARK_AQUA+"Dangerous Mob"); //m.setCustomName(ChatColor.DARK_AQUA+"Dangerous Mob");
@ -782,6 +784,7 @@ public class MonsterController {
if (!GenericFunctions.isArmoredMob(m)) { if (!GenericFunctions.isArmoredMob(m)) {
m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,5)); m.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE,Integer.MAX_VALUE,5));
} }
m.getAttribute(Attribute.GENERIC_FOLLOW_RANGE).setBaseValue(64.0);
}break; }break;
case ELITE:{ case ELITE:{
SetupCustomName(ChatColor.DARK_PURPLE+"Elite",m); SetupCustomName(ChatColor.DARK_PURPLE+"Elite",m);
@ -803,6 +806,7 @@ public class MonsterController {
m.setCustomNameVisible(true); m.setCustomNameVisible(true);
m.setRemoveWhenFarAway(false); m.setRemoveWhenFarAway(false);
MonsterStructure.getMonsterStructure(m).SetElite(true); MonsterStructure.getMonsterStructure(m).SetElite(true);
m.getAttribute(Attribute.GENERIC_FOLLOW_RANGE).setBaseValue(72.0);
}break; }break;
default: { default: {
if (isAllowedToEquipItems(m)) { if (isAllowedToEquipItems(m)) {
@ -825,6 +829,7 @@ public class MonsterController {
m.setMaxHealth(m.getMaxHealth()*1.0); m.setMaxHealth(m.getMaxHealth()*1.0);
m.setHealth(m.getMaxHealth()); m.setHealth(m.getMaxHealth());
} }
m.getAttribute(Attribute.GENERIC_FOLLOW_RANGE).setBaseValue(24.0);
}break; }break;
} }
removeZombieLeaderAttribute(m); removeZombieLeaderAttribute(m);

View File

@ -94,6 +94,9 @@ public class PlayerStructure {
public long lastblock = 0; public long lastblock = 0;
public List<Integer> itemcubelist = new ArrayList<Integer>(); public List<Integer> itemcubelist = new ArrayList<Integer>();
public int lasthitproperties=0; public int lasthitproperties=0;
public String lasthitdesc="";
public double lastdamagetaken=0;
public double lastrawdamage=0;
public long iframetime = 0; public long iframetime = 0;

View File

@ -199,6 +199,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.ItemSet;
import sig.plugin.TwosideKeeper.HelperStructures.MalleableBaseQuest; import sig.plugin.TwosideKeeper.HelperStructures.MalleableBaseQuest;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.MonsterDifficulty;
import sig.plugin.TwosideKeeper.HelperStructures.MonsterType; import sig.plugin.TwosideKeeper.HelperStructures.MonsterType;
import sig.plugin.TwosideKeeper.HelperStructures.Pronouns;
import sig.plugin.TwosideKeeper.HelperStructures.QuestStatus; import sig.plugin.TwosideKeeper.HelperStructures.QuestStatus;
import sig.plugin.TwosideKeeper.HelperStructures.ServerType; import sig.plugin.TwosideKeeper.HelperStructures.ServerType;
import sig.plugin.TwosideKeeper.HelperStructures.SessionState; 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()) { if (SERVER_TYPE==ServerType.TEST || SERVER_TYPE==ServerType.QUIET || p.isOp()) {
/*PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); /*PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.swordcombo=20;*/ 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); log("Absorption Hearts: "+f,2);
if (args.length>0) { if (args.length>0) {
((org.bukkit.craftbukkit.v1_9_R1.entity.CraftLivingEntity)p).getHandle().setAbsorptionHearts(Float.valueOf(args[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); Monster m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE);
m.setHealth(m.getMaxHealth()/16d);*/ m.setHealth(m.getMaxHealth()/16d);
//TwosideKeeperAPI.spawnAdjustedMonster(MonsterType.GIANT, p.getLocation()); //TwosideKeeperAPI.spawnAdjustedMonster(MonsterType.GIANT, p.getLocation());
//TwosideKeeper.log("This is from set "+ItemSet.GetSet(p.getEquipment().getItemInMainHand())+" T"+ItemSet.GetTier(p.getEquipment().getItemInMainHand()),2); //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); /*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); log("[TASK] New Player Data has been added. Size of array: "+playerdata.size(),4);
GenericFunctions.updateSetItemsInInventory(ev.getPlayer().getInventory()); 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. //Update player max health. Check equipment too.
setPlayerMaxHealth(ev.getPlayer()); 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) { public void onPlayerDeath(PlayerDeathEvent ev) {
//Modify the death message. This is a fix for getting rid of the healthbar from the player name. //Modify the death message. This is a fix for getting rid of the healthbar from the player name.
final Player p = ev.getEntity(); final Player p = ev.getEntity();
@ -2884,21 +2891,27 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
newDeathMsg+=" "+parsed_msg[i]; newDeathMsg+=" "+parsed_msg[i];
} }
} }
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
if (pd.lasthitdesc!=null) {
newDeathMsg = getFancyDeathMessage(p);
}
newDeathMsg=p.getName()+" "+newDeathMsg; newDeathMsg=p.getName()+" "+newDeathMsg;
ev.setDeathMessage(newDeathMsg); ev.setDeathMessage(newDeathMsg);
log("Death Message: "+ev.getDeathMessage(),5); log("Death Message: "+ev.getDeathMessage(),5);
DecimalFormat df = new DecimalFormat("0.00");
if (p!=null) { if (p!=null) {
p.sendMessage(ChatColor.GRAY+"Due to death, you lost "+DEATHPENALTY+"% of your holding money. "); p.sendMessage(ChatColor.GRAY+"Due to death, you lost "+DEATHPENALTY+"% of your holding money. ");
givePlayerMoney(p,-Math.round(getPlayerMoney(p)/2)); 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(" 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); ev.setKeepInventory(true);
log("Y position is "+p.getLocation().getY(), 4); 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. 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); :p.getLocation(), p);
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); pd = PlayerStructure.GetPlayerStructure(p);
pd.hasDied=true; pd.hasDied=true;
pd.vendetta_amt=0.0; pd.vendetta_amt=0.0;
p.getInventory().clear(); p.getInventory().clear();
@ -2909,6 +2922,77 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
} }
} }
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) @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
public void onSignChange(SignChangeEvent ev) { public void onSignChange(SignChangeEvent ev) {
Player p = ev.getPlayer(); Player p = ev.getPlayer();
@ -3253,7 +3337,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
} }
p.playSound(p.getLocation(), Sound.BLOCK_CHEST_CLOSE, 1.0f, 1.0f); p.playSound(p.getLocation(), Sound.BLOCK_CHEST_CLOSE, 1.0f, 1.0f);
itemCube_saveConfig(id,itemcube_contents); itemCube_saveConfig(id,itemcube_contents);
ItemCubeWindow.popItemCubeWindow(p); if (!pd.opened_another_cube) {
ItemCubeWindow.removeAllItemCubeWindows(p);
}
pd.isViewingItemCube=false; pd.isViewingItemCube=false;
} }
if (ev.getInventory().getLocation()!=null) { if (ev.getInventory().getLocation()!=null) {
@ -3476,7 +3562,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
//log("Cursor: "+ev.getCursor().toString(),2); //log("Cursor: "+ev.getCursor().toString(),2);
ItemStack item = ev.getCursor(); ItemStack item = ev.getCursor();
if (item.getType()==Material.AIR) { if (item.getType()==Material.AIR) {
ItemCubeWindow.removeAllItemCubeWindows((Player)ev.getWhoClicked()); //ItemCubeWindow.removeAllItemCubeWindows((Player)ev.getWhoClicked());
ItemCubeWindow.popItemCubeWindow((Player)ev.getWhoClicked());
ev.getWhoClicked().closeInventory(); ev.getWhoClicked().closeInventory();
} }
} }
@ -3984,6 +4071,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (ev.getCause()!=DamageCause.ENTITY_ATTACK && if (ev.getCause()!=DamageCause.ENTITY_ATTACK &&
ev.getCause()!=DamageCause.PROJECTILE && ev.getCause()!=DamageCause.PROJECTILE &&
ev.getCause()!=DamageCause.ENTITY_EXPLOSION && ev.getCause()!=DamageCause.ENTITY_EXPLOSION &&
ev.getCause()!=DamageCause.THORNS &&
ev.getCause()!=DamageCause.MAGIC) { ev.getCause()!=DamageCause.MAGIC) {
//We handle the event inside of here. DealDamage(ev.getDamage(DamageModifier.BASE)); //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. if (ev.getCause()!=DamageCause.CUSTOM) { //This is not handled damage, so apply it.
double dmgdealt = ev.getDamage(DamageModifier.BASE); double dmgdealt = ev.getDamage(DamageModifier.BASE);
CustomDamage.setupTrueDamage(ev); 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); ev.setCancelled(true);
} else } 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;i<equipment.length;i++) {
if (equipment[i]!=null && equipment[i].getEnchantmentLevel(Enchantment.THORNS)>maxthornslevel) {
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) @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true)
public void entityHitEvent(EntityDamageByEntityEvent ev) { public void entityHitEvent(EntityDamageByEntityEvent ev) {
if (ev.getEntity() instanceof LivingEntity) { 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) { if (ev.getDamage(DamageModifier.BASE)>=CUSTOM_DAMAGE_IDENTIFIER) {
log("BASE damage: "+ev.getDamage(DamageModifier.BASE)+"-"+CUSTOM_DAMAGE_IDENTIFIER,5); log("BASE damage: "+ev.getDamage(DamageModifier.BASE)+"-"+CUSTOM_DAMAGE_IDENTIFIER,5);
double dmgdealt = ev.getDamage(DamageModifier.BASE)-CUSTOM_DAMAGE_IDENTIFIER; 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) { if (CustomDamage.getDamagerEntity(ev.getDamager()) instanceof Player) {
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); CustomDamage.ApplyDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), weapon, null);
if (ev.getDamager() instanceof Projectile) { if (ev.getDamager() instanceof Projectile) {
Projectile proj = (Projectile)ev.getDamager(); Projectile proj = (Projectile)ev.getDamager();
proj.remove(); proj.remove();
} }
ev.setCancelled(true); ev.setCancelled(true);
}
//Handle this manually if it's a player. //Handle this manually if it's a player.
} else { } 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())) { if (!CustomDamage.InvulnerableCheck(ev.getDamager(), (LivingEntity)ev.getEntity())) {
double dmgdealt = CustomDamage.CalculateDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), null, null, CustomDamage.NONE); double dmgdealt = CustomDamage.CalculateDamage(0, ev.getDamager(), (LivingEntity)ev.getEntity(), null, null, CustomDamage.NONE);
dmgdealt = CustomDamage.subtractAbsorptionHearts(dmgdealt, (LivingEntity)ev.getEntity()); 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) { if (ev.getDamager()!=null) {
TwosideKeeper.logHealth((LivingEntity)ev.getEntity(),((LivingEntity)ev.getEntity()).getHealth(),dmgdealt,ev.getDamager()); 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); log("Preparing to explode.",5);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
public void run() { 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); 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); ,10);
} else } 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); c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
public void run() { 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); 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); ,10);
} else } 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); c.getLocation().getWorld().playSound(c.getLocation(), Sound.ENTITY_CREEPER_PRIMED, 1.0f, 1.0f);
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() {
public void run() { 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); 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); ,30);
} }
@ -4200,7 +4335,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
ev.setCancelled(true); ev.setCancelled(true);
} }
} }
m.setTarget(ev.getTarget());
ev.setCancelled(true); ev.setCancelled(true);
} else { } else {
log("This monster is "+MonsterController.getMonsterDifficulty(m).name(),5); 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(); Monster m = (Monster)ev.getEntity();
GlowAPI.setGlowing(m, GlowAPI.Color.DARK_RED, Bukkit.getOnlinePlayers()); 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) @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(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+"!"); 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+"**!"); 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().spawnEntity(m.getLocation(), EntityType.LIGHTNING);
m.getWorld().setStorm(true); m.getWorld().setStorm(true);
m.getWorld().setWeatherDuration(20*60*15); m.getWorld().setWeatherDuration(20*60*15);
em.removeAllHealthbars(); em.removeAllHealthbars();
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); elitemonsters.remove(em);
}},1);
GenericFunctions.generateNewElite(); GenericFunctions.generateNewElite();
} }
@ -4545,8 +4692,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (DeathManager.getDeathStructure(p)!=null) { if (DeathManager.getDeathStructure(p)!=null) {
DeathManager.continueAction(p); DeathManager.continueAction(p);
} }
p.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION,1,0),true); p.addPotionEffect(new PotionEffect(PotionEffectType.LEVITATION,Integer.MAX_VALUE,255));
p.removePotionEffect(PotionEffectType.ABSORPTION); CustomDamage.setAbsorptionHearts(p, 0.0f);
GenericFunctions.addIFrame(p, Integer.MAX_VALUE); GenericFunctions.addIFrame(p, Integer.MAX_VALUE);
PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); PlayerStructure pd = PlayerStructure.GetPlayerStructure(p);
pd.lastdeath=getServerTickTime(); pd.lastdeath=getServerTickTime();
@ -4558,7 +4705,9 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
pd.hasDied=false; pd.hasDied=false;
//log("Block started on is "+ev.getRespawnLocation().getBlock(),2); //log("Block started on is "+ev.getRespawnLocation().getBlock(),2);
//p.teleport(GenericFunctions.FindRandomFreeLocation(p.getLocation().add(0,1,0))); //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) @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("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+"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+"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)+"%"); 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)) { if (GenericFunctions.isDefender(p)) {
double dodgechance=0.0; double dodgechance=0.0;
@ -6617,7 +6766,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener {
if (CustomDamage.isFlagSet(flags, CustomDamage.IS_HEADSHOT)) { if (CustomDamage.isFlagSet(flags, CustomDamage.IS_HEADSHOT)) {
col = ChatColor.DARK_RED; col = ChatColor.DARK_RED;
} }
updateTitle(shooter,col+""+pd.damagedealt); DecimalFormat df = new DecimalFormat("0.00");
updateTitle(shooter,col+""+df.format(pd.damagedealt));
} }
} }

View File

@ -181,6 +181,17 @@ public final class TwosideKeeperAPI {
return CustomDamage.ApplyDamage(damage, damager, target, weapon, reason, flags); 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. * Determines if the target is invulnerable.