Browse Source

Reworking of Acrobatics, plus an Acrobatics bugfix.

GJ 13 năm trước cách đây
mục cha
commit
6ab1996440

+ 1 - 0
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

+ 0 - 13
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
      */

+ 4 - 3
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);

+ 9 - 0
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;
+}

+ 84 - 0
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;
+    }
+}

+ 41 - 0
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);
+    }
+}

+ 61 - 0
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;
+    }
+}

+ 127 - 0
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;
+    }
+}

+ 0 - 126
src/main/java/com/gmail/nossr50/skills/misc/Acrobatics.java

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

+ 6 - 5
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();
             }
         }