diff --git a/Changelog.txt b/Changelog.txt index 63b05feea..fb636f699 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -13,6 +13,7 @@ Version 1.3.09 + Added API for plugins to add custom tools directly via Spout - repair / abilities do not work ATM + Added offline party members to the list displayed by /party + Added possibility to kick offline members from parties + = Fixed bug with Acrobatics not saving you from deadly falls = Fixed /mcremove being applied only after a reload = Fixed Archery PVE disablement not working properly = Fixed possible NPE when a projectile is shot by a dispenser or doesn't have any shooter diff --git a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java index 776a4777b..c76ec8469 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java @@ -50,7 +50,6 @@ public class PlayerProfile { /* Timestamps */ private int xpGainATS = 0; private int recentlyHurt = 0; - private int respawnATS; /* mySQL STUFF */ private int lastlogin = 0; @@ -588,18 +587,6 @@ public class PlayerProfile { partyChatMode = !partyChatMode; } - /* - * Exploit Prevention - */ - - public long getRespawnATS() { - return respawnATS; - } - - public void setRespawnATS(long newvalue) { - respawnATS = (int) (newvalue / 1000); - } - /* * Tools */ diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index 247bca84c..9a13ebfdb 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -32,10 +32,10 @@ import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent; import com.gmail.nossr50.events.fake.FakeEntityDamageEvent; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.runnables.BleedTimer; +import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager; import com.gmail.nossr50.skills.combat.Archery; import com.gmail.nossr50.skills.combat.Taming; import com.gmail.nossr50.skills.gathering.BlastMining; -import com.gmail.nossr50.skills.misc.Acrobatics; import com.gmail.nossr50.util.Combat; import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Permissions; @@ -128,8 +128,9 @@ public class EntityListener implements Listener { } if (!Misc.isInvincible(player, event)) { - if (cause == DamageCause.FALL && Permissions.getInstance().acrobatics(player) && !player.isInsideVehicle() && !player.getItemInHand().getType().equals(Material.ENDER_PEARL)) { - Acrobatics.acrobaticsCheck(player, event); + if (cause == DamageCause.FALL && !player.isInsideVehicle() && !player.getItemInHand().getType().equals(Material.ENDER_PEARL)) { + AcrobaticsManager acroManager = new AcrobaticsManager(player); + acroManager.rollCheck(event); } else if (cause == DamageCause.BLOCK_EXPLOSION && Permissions.getInstance().demolitionsExpertise(player)) { BlastMining.demolitionsExpertise(player, event); diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java new file mode 100644 index 000000000..9b30f2a6c --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java @@ -0,0 +1,9 @@ +package com.gmail.nossr50.skills.acrobatics; + +public class Acrobatics { + public static final int DODGE_MAX_BONUS_LEVEL = 800; + public static final int DODGE_XP_MODIFIER = 120; + public static final int FALL_XP_MODIFIER = 120; + public static final int ROLL_MAX_BONUS_LEVEL = 1000; + public static final int ROLL_XP_MODIFIER = 80; +} diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java new file mode 100644 index 000000000..4d715ea18 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java @@ -0,0 +1,84 @@ +package com.gmail.nossr50.skills.acrobatics; + +import java.util.Random; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; + +import com.gmail.nossr50.datatypes.PlayerProfile; +import com.gmail.nossr50.datatypes.SkillType; +import com.gmail.nossr50.util.Users; + +public class AcrobaticsManager { + private Random random = new Random(); + + private Player player; + private PlayerProfile profile; + private int skillLevel; + private AcrobaticsPermissionsHandler permHandler; + + public AcrobaticsManager (Player player) { + this.player = player; + this.profile = Users.getProfile(player); + this.skillLevel = profile.getSkillLevel(SkillType.ACROBATICS); + this.permHandler = new AcrobaticsPermissionsHandler(player); + } + + /** + * Check for fall damage reduction. + * + * @param event The event to check + */ + public void rollCheck(EntityDamageEvent event) { + if (!permHandler.hasRollPermissions()) { + return; + } + + RollEventHandler eventHandler = new RollEventHandler(this, event); + + if (random.nextInt(1000) <= eventHandler.getSkillModifier() && !eventHandler.isFatal(eventHandler.getModifiedDamage())) { + eventHandler.modifyEventDamage(); + eventHandler.sendAbilityMessage(); + eventHandler.processRollXPGain(); + } + else if (!eventHandler.isFatal(event.getDamage())){ + eventHandler.processFallXPGain(); + } + } + + /** + * Check for dodge damage reduction. + * + * @param event The event to check + */ + public void dodgeCheck(EntityDamageByEntityEvent event) { + if (!permHandler.canDodge()) { + return; + } + + DodgeEventHandler eventHandler = new DodgeEventHandler(this, event); + + if (random.nextInt(4000) <= eventHandler.getSkillModifier()) { + eventHandler.modifyEventDamage(); + eventHandler.sendAbilityMessage(); + eventHandler.processXP(); + } + } + + protected Player getPlayer() { + return player; + } + + protected PlayerProfile getProfile() { + return profile; + } + + protected int getSkillLevel() { + return skillLevel; + } + + protected AcrobaticsPermissionsHandler getPermissionsHandler() { + return permHandler; + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsPermissionsHandler.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsPermissionsHandler.java new file mode 100644 index 000000000..c0009821b --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsPermissionsHandler.java @@ -0,0 +1,41 @@ +package com.gmail.nossr50.skills.acrobatics; + +import org.bukkit.entity.Player; + +import com.gmail.nossr50.util.Permissions; + +public class AcrobaticsPermissionsHandler { + private Permissions permInstance = Permissions.getInstance(); + + private boolean canDodge; + private boolean canGracefulRoll; + private boolean canRoll; + private boolean canGainXP; + + protected AcrobaticsPermissionsHandler (Player player) { + this.canDodge = permInstance.dodge(player); + this.canGracefulRoll = permInstance.gracefulRoll(player); + this.canRoll = permInstance.roll(player); + this.canGainXP = permInstance.acrobatics(player); + } + + protected boolean canDodge() { + return canDodge; + } + + protected boolean canGracefulRoll() { + return canGracefulRoll; + } + + protected boolean canRoll() { + return canRoll; + } + + protected boolean canGainXP() { + return canGainXP; + } + + protected boolean hasRollPermissions() { + return (canRoll || canGracefulRoll); + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/DodgeEventHandler.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/DodgeEventHandler.java new file mode 100644 index 000000000..0320e18a3 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/DodgeEventHandler.java @@ -0,0 +1,61 @@ +package com.gmail.nossr50.skills.acrobatics; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import com.gmail.nossr50.datatypes.SkillType; +import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.Skills; + +public class DodgeEventHandler { + private AcrobaticsManager manager; + private Player player; + + private EntityDamageByEntityEvent event; + private int damage; + + private int skillModifier; + private int modifiedDamage; + + protected DodgeEventHandler(AcrobaticsManager manager, EntityDamageByEntityEvent event) { + this.manager = manager; + this.player = manager.getPlayer(); + this.event = event; + this.damage = event.getDamage(); + this.skillModifier = calculateSkillModifier(); + this.modifiedDamage = calculateModifiedDamage(damage); + } + + private int calculateSkillModifier() { + return Misc.skillCheck(manager.getSkillLevel(), Acrobatics.DODGE_MAX_BONUS_LEVEL); + } + + private int calculateModifiedDamage(int initialDamage) { + int modifiedDamage = initialDamage / 2; + + if (modifiedDamage <= 0) { + modifiedDamage = 1; + } + + return modifiedDamage; + } + + protected void modifyEventDamage() { + event.setDamage(modifiedDamage); + } + + protected void sendAbilityMessage() { + player.sendMessage(LocaleLoader.getString("Acrobatics.Combat.Proc")); + } + + protected void processXP() { + if (manager.getPermissionsHandler().canGainXP()) { + Skills.xpProcessing(player, manager.getProfile(), SkillType.ACROBATICS, damage * Acrobatics.DODGE_XP_MODIFIER); + } + } + + protected int getSkillModifier() { + return skillModifier; + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/RollEventHandler.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/RollEventHandler.java new file mode 100644 index 000000000..d190a97a5 --- /dev/null +++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/RollEventHandler.java @@ -0,0 +1,127 @@ +package com.gmail.nossr50.skills.acrobatics; + +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; + +import com.gmail.nossr50.datatypes.SkillType; +import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.util.Skills; + +public class RollEventHandler { + private AcrobaticsManager manager; + private Player player; + private AcrobaticsPermissionsHandler permHandler; + + private EntityDamageEvent event; + private int damage; + + private boolean isGraceful; + private int skillModifier; + private int damageThreshold; + private int modifiedDamage; + + protected RollEventHandler(AcrobaticsManager manager, EntityDamageEvent event) { + this.manager = manager; + this.player = manager.getPlayer(); + this.permHandler = manager.getPermissionsHandler(); + this.event = event; + this.damage = event.getDamage(); + this.isGraceful = isGracefulRoll(); + this.skillModifier = calculateSkillModifier(); + this.damageThreshold = calculateDamageThreshold(); + this.modifiedDamage = calculateModifiedDamage(damage); + } + + private boolean isGracefulRoll() { + if (permHandler.canGracefulRoll()) { + return player.isSneaking(); + } + else { + return false; + } + } + + private int calculateSkillModifier() { + int skillModifer = manager.getSkillLevel(); + + if (isGraceful) { + skillModifer = skillModifer * 2; + } + + skillModifer = Misc.skillCheck(skillModifer, Acrobatics.ROLL_MAX_BONUS_LEVEL); + return skillModifer; + } + + private int calculateDamageThreshold() { + int damageThreshold = 7; + + if (isGraceful) { + damageThreshold = damageThreshold * 2; + } + + return damageThreshold; + } + + private int calculateModifiedDamage(int initialDamage) { + int modifiedDamage = initialDamage - damageThreshold; + + if (modifiedDamage < 0) { + modifiedDamage = 0; + } + + return modifiedDamage; + } + + protected void modifyEventDamage() { + event.setDamage(modifiedDamage); + + if (event.getDamage() == 0) { + event.setCancelled(true); + } + } + + protected void sendAbilityMessage() { + if (isGraceful) { + player.sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc")); + } + else { + player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text")); + } + } + + protected void processFallXPGain() { + processXPGain(damage * Acrobatics.FALL_XP_MODIFIER); + } + + protected void processRollXPGain() { + processXPGain(damage * Acrobatics.ROLL_XP_MODIFIER); + } + + private void processXPGain(int xpGain) { + if (permHandler.canGainXP()) { + Skills.xpProcessing(player, manager.getProfile(), SkillType.ACROBATICS, xpGain); + } + } + + protected boolean isFatal(int damage) { + if (player.getHealth() - damage < 1) { + return true; + } + else { + return false; + } + } + + protected boolean isGraceful() { + return isGraceful; + } + + protected int getSkillModifier() { + return skillModifier; + } + + protected int getModifiedDamage() { + return modifiedDamage; + } +} diff --git a/src/main/java/com/gmail/nossr50/skills/misc/Acrobatics.java b/src/main/java/com/gmail/nossr50/skills/misc/Acrobatics.java deleted file mode 100644 index 9fb5c3764..000000000 --- a/src/main/java/com/gmail/nossr50/skills/misc/Acrobatics.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.gmail.nossr50.skills.misc; - -import java.util.Random; - -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; - -import com.gmail.nossr50.datatypes.PlayerProfile; -import com.gmail.nossr50.datatypes.SkillType; -import com.gmail.nossr50.locale.LocaleLoader; -import com.gmail.nossr50.party.PartyManager; -import com.gmail.nossr50.util.Misc; -import com.gmail.nossr50.util.Permissions; -import com.gmail.nossr50.util.Skills; -import com.gmail.nossr50.util.Users; - -public class Acrobatics { - private static Random random = new Random(); - - /** - * Check for fall damage reduction. - * - * @param player The player whose fall damage to modify - * @param event The event to check - */ - public static void acrobaticsCheck(Player player, EntityDamageEvent event) { - final int ROLL_XP_MODIFIER = 80; - final int FALL_XP_MODIFIER = 120; - final int MAX_BONUS_LEVEL = 1000; - - PlayerProfile PP = Users.getProfile(player); - int acrovar = PP.getSkillLevel(SkillType.ACROBATICS); - boolean gracefulRoll = player.isSneaking(); - int damage = event.getDamage(); - int health = player.getHealth(); - - if (!Permissions.getInstance().gracefulRoll(player)) { - gracefulRoll = false; - } - - if (gracefulRoll) { - acrovar = acrovar * 2; - } - - if ((acrovar > MAX_BONUS_LEVEL || random.nextInt(1000) <= acrovar) && Permissions.getInstance().roll(player)) { - int threshold = 7; - - if (gracefulRoll) { - threshold = threshold * 2; - } - - int newDamage = damage - threshold; - - if (newDamage < 0) { - newDamage = 0; - } - - /* Check for death */ - if (health - damage >= 1) { - Skills.xpProcessing(player, PP, SkillType.ACROBATICS, damage * ROLL_XP_MODIFIER); - - event.setDamage(newDamage); - - if (event.getDamage() <= 0) { - event.setCancelled(true); - } - - if (gracefulRoll) { - player.sendMessage(LocaleLoader.getString("Acrobatics.Ability.Proc")); - } - else { - player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text")); - } - } - } - else if (health - damage >= 1) { - Skills.xpProcessing(player, PP, SkillType.ACROBATICS, event.getDamage() * FALL_XP_MODIFIER); - } - } - - /** - * Check for dodge damage reduction. - * - * @param event The event to check - */ - public static void dodgeChecks(EntityDamageByEntityEvent event) { - final int DODGE_MODIFIER = 120; - final int MAX_BONUS_LEVEL = 800; - - Player defender = (Player) event.getEntity(); - PlayerProfile PPd = Users.getProfile(defender); - int damage = event.getDamage(); - - /* PARTY CHECK */ - if (event.getDamager() instanceof Player) { - Player attacker = (Player) event.getDamager(); - - if (PartyManager.getInstance().inSameParty(defender, attacker)) { - return; - } - } - - if (Permissions.getInstance().acrobatics(defender)) { - int skillLevel = PPd.getSkillLevel(SkillType.ACROBATICS); - int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL); - - if (random.nextInt(4000) <= skillCheck && Permissions.getInstance().dodge(defender)) { - defender.sendMessage(LocaleLoader.getString("Acrobatics.Combat.Proc")); - - if (System.currentTimeMillis() >= (5000 + PPd.getRespawnATS()) && defender.getHealth() >= 1) { - Skills.xpProcessing(defender, PPd, SkillType.ACROBATICS, damage * DODGE_MODIFIER); - } - - int newDamage = damage / 2; - - if (newDamage <= 0) { - event.setDamage(1); - } - else { - event.setDamage(newDamage); - } - } - } - } -} diff --git a/src/main/java/com/gmail/nossr50/util/Combat.java b/src/main/java/com/gmail/nossr50/util/Combat.java index 16c766552..3b6c57d96 100644 --- a/src/main/java/com/gmail/nossr50/util/Combat.java +++ b/src/main/java/com/gmail/nossr50/util/Combat.java @@ -29,12 +29,12 @@ import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.runnables.BleedTimer; import com.gmail.nossr50.runnables.GainXp; +import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager; import com.gmail.nossr50.skills.combat.Archery; import com.gmail.nossr50.skills.combat.Axes; import com.gmail.nossr50.skills.combat.Swords; import com.gmail.nossr50.skills.combat.Taming; import com.gmail.nossr50.skills.combat.Unarmed; -import com.gmail.nossr50.skills.misc.Acrobatics; public class Combat { private static Config configInstance = Config.getInstance(); @@ -205,6 +205,8 @@ public class Combat { } if (target instanceof Player) { + AcrobaticsManager acroManager = new AcrobaticsManager((Player) target); + if (configInstance.getSwordsPVP() && damager instanceof Player) { Swords.counterAttackChecks(damager, (Player) target, event.getDamage()); } @@ -214,11 +216,11 @@ public class Combat { } if (configInstance.getAcrobaticsPVP() && damager instanceof Player) { - Acrobatics.dodgeChecks(event); + acroManager.dodgeCheck(event); } if (configInstance.getAcrobaticsPVE() && !(damager instanceof Player)) { - Acrobatics.dodgeChecks(event); + acroManager.dodgeCheck(event); } } } @@ -459,9 +461,8 @@ public class Combat { } Player defender = (Player) target; - PlayerProfile PPd = Users.getProfile(defender); - if (System.currentTimeMillis() >= (PPd.getRespawnATS() * 1000) + 5000 && ((PPd.getLastLogin() + 5) * 1000) < System.currentTimeMillis() && defender.getHealth() >= 1) { + if (defender.getHealth() >= 1) { baseXP = 20 * configInstance.getPlayerVersusPlayerXP(); } }