diff --git a/Changelog.txt b/Changelog.txt index 5360ea9c1..90cb04df4 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,3 +1,9 @@ +Version 2.2.049 + Combat abilities work with spear in off-hand again (see notes) + + NOTES: + As a semi-permanent work around, mcMMO keeps track of when players swing their weapon, if they have swung it recently enough combat skills will work even if you have a spear in your off-hand. + Prior to this patch, mcMMO disabled combat abilities when spear was in off-hand to prevent the off-hand spear charge from applying combat abilities from other skills, as mcMMO was unable to determine which item (mainhand vs offhand) caused the damage from the event information alone. Version 2.2.048 Fixed error when loading Spears skill manager on older Minecraft versions Fixed error when using /spears command on an older Minecraft version diff --git a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java index be6ed57ac..595f47811 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java +++ b/src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java @@ -81,6 +81,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.VisibleForTesting; public class McMMOPlayer implements Identified { + private static final long NO_SWING = 0L; private final @NotNull Identity identity; //Hacky fix for now, redesign later @@ -97,6 +98,7 @@ public class McMMOPlayer implements Identified { private Party invite; private Party allianceInvite; private int itemShareModifier; + private long lastSwingTimestamp = NO_SWING; private PartyTeleportRecord ptpRecord; @@ -1278,4 +1280,12 @@ public class McMMOPlayer implements Identified { public void setChatMode(@NotNull ChatChannel chatChannel) { this.chatChannel = chatChannel; } + + public long getLastSwingTimestamp() { + return lastSwingTimestamp; + } + + public void setLastSwingTimestamp(long lastSwingTimestamp) { + this.lastSwingTimestamp = lastSwingTimestamp; + } } diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index bf24749f4..dd67906d5 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -63,6 +63,8 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.PlayerAnimationEvent; +import org.bukkit.event.player.PlayerAnimationType; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerDropItemEvent; @@ -909,7 +911,6 @@ public class PlayerListener implements Listener { HerbalismManager herbalismManager = mmoPlayer.getHerbalismManager(); - // FakePlayerAnimationEvent fakeSwing = new FakePlayerAnimationEvent(event.getPlayer(), PlayerAnimationType.ARM_SWING); //PlayerAnimationEvent compat if (!event.isCancelled() || event.useInteractedBlock() != Event.Result.DENY) { //TODO: Is this code to set false from bone meal even needed? I'll have to double check later. if (heldItem.getType() == Material.BONE_MEAL) { @@ -1122,4 +1123,23 @@ public class PlayerListener implements Listener { SkillUtils.removeAbilityBuff(event.getMainHandItem()); SkillUtils.removeAbilityBuff(event.getOffHandItem()); } + + @EventHandler(ignoreCancelled = false, priority = EventPriority.MONITOR) + public void onPlayerAnimation(PlayerAnimationEvent event) { + if (event.getAnimationType() != PlayerAnimationType.ARM_SWING) { + return; + } + + final Player player = event.getPlayer(); + + if (!UserManager.hasPlayerDataKey(player)) { + return; + } + + final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); + + if (mmoPlayer != null) { + mmoPlayer.setLastSwingTimestamp(System.currentTimeMillis()); + } + } } diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java index cd05099f3..895378a8d 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -125,11 +125,6 @@ public final class CombatUtils { return; } - // TODO: Temporary hack to avoid unintended spear interactions - if (isSpear(player.getInventory().getItemInOffHand())) { - return; - } - final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); //Make sure the profiles been loaded @@ -137,6 +132,11 @@ public final class CombatUtils { return; } + // Hack to avoid other combat abilities applying to off-hand spear attacks + if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) { + return; + } + SwordsManager swordsManager = mmoPlayer.getSwordsManager(); double boostedDamage = event.getDamage(); @@ -194,11 +194,6 @@ public final class CombatUtils { return; } - // TODO: Temporary hack to avoid unintended spear interactions - if (isSpear(player.getInventory().getItemInOffHand())) { - return; - } - double boostedDamage = event.getDamage(); final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); @@ -208,6 +203,11 @@ public final class CombatUtils { return; } + // Hack to avoid other combat abilities applying to off-hand spear attacks + if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) { + return; + } + final TridentsManager tridentsManager = mmoPlayer.getTridentsManager(); // if (tridentsManager.canActivateAbility()) { @@ -312,11 +312,6 @@ public final class CombatUtils { return; } - // TODO: Temporary hack to avoid unintended spear interactions - if (isSpear(player.getInventory().getItemInOffHand())) { - return; - } - double boostedDamage = event.getDamage(); final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); @@ -326,6 +321,11 @@ public final class CombatUtils { return; } + // Hack to avoid other combat abilities applying to off-hand spear attacks + if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) { + return; + } + final MacesManager macesManager = mmoPlayer.getMacesManager(); // Apply Limit Break DMG @@ -395,11 +395,6 @@ public final class CombatUtils { return; } - // TODO: Temporary hack to avoid unintended spear interactions - if (isSpear(player.getInventory().getItemInOffHand())) { - return; - } - double boostedDamage = event.getDamage(); final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); @@ -409,6 +404,11 @@ public final class CombatUtils { return; } + // Hack to avoid other combat abilities applying to off-hand spear attacks + if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) { + return; + } + final AxesManager axesManager = mmoPlayer.getAxesManager(); if (axesManager.canActivateAbility()) { @@ -454,11 +454,6 @@ public final class CombatUtils { double boostedDamage = event.getDamage(); - // TODO: Temporary hack to avoid unintended spear interactions - if (isSpear(player.getInventory().getItemInOffHand())) { - return; - } - final McMMOPlayer mmoPlayer = UserManager.getPlayer(player); //Make sure the profiles been loaded @@ -466,6 +461,11 @@ public final class CombatUtils { return; } + // Hack to avoid other combat abilities applying to off-hand spear attacks + if (isSpear(player.getInventory().getItemInOffHand()) && isNotSwinging(mmoPlayer)) { + return; + } + final UnarmedManager unarmedManager = mmoPlayer.getUnarmedManager(); if (unarmedManager.canActivateAbility()) { @@ -949,8 +949,6 @@ public final class CombatUtils { continue; } - //EventUtils.callFakeArmSwingEvent(attacker); - switch (type) { case SWORDS: if (entity instanceof Player) { @@ -1227,4 +1225,10 @@ public final class CombatUtils { mcMMO.p.getFoliaLib().getScheduler() .runLater(() -> ProjectileUtils.cleanupProjectileMetadata(arrow), 20 * 120); } + + public static boolean isNotSwinging(McMMOPlayer mmoPlayer) { + // If player has swung in the last second, it's extremely unlikely the damage originates + // from an off-hand spear charge attack + return mmoPlayer.getLastSwingTimestamp() + 500L < System.currentTimeMillis(); + } }