diff --git a/Changelog.txt b/Changelog.txt index 9cb1f2dfe..0ddc94644 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -1,4 +1,5 @@ Version 2.1.215 + Unarmed bonuses apply to players who hurt an entity with empty fists in the last 60 seconds, these bonuses do not get applied if you are using another mcMMO tool/weapon/trident/etc (see notes) Fixed Coal Blocks and potentially other fuel sources not showing burning animation to players (see notes) Level up broadcasts from level milestones will now be visible to the player who achieved them Fixed a bug where hovering over skill descriptions did not display anything (thanks Greymagic27) @@ -7,6 +8,8 @@ Version 2.1.215 Item in main hand is now used for Tree Feller drops (thanks destro174) NOTES: + The unarmed change is to lower the penalty for picking up items during a fight, as an alternative solution, you can turn on Skills.Unarmed.Items_As_Unarmed in config.yml to have players be considered to be using unarmed while holding items regardless of last unarmed combat (holding tools/weapons/tridents will disqualify you from this) + Players who damage another entity with empty hands are considered "recently unarmed" for the next 60 seconds, during this period if they attack with items in their hands (other weapons/tools/tridents excluded) they will be processed as if they are using unarmed combat, this also works with stuff like block breaker The burning animation bug is actually in Spigot, it takes an int for setBurnTime when it really should only take a short as the game is expecting a short value, I implemented a hacky workaround via Math.min There is a bug where you may lose your config comments, this will be complex to solve, for now you can check our GitHub for the configs with comments. diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java index 57c9572bb..e08eadf9d 100644 --- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java @@ -22,6 +22,7 @@ import com.gmail.nossr50.skills.salvage.Salvage; import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager; import com.gmail.nossr50.util.*; import com.gmail.nossr50.util.player.UserManager; +import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.util.sounds.SoundManager; import com.gmail.nossr50.util.sounds.SoundType; @@ -622,7 +623,7 @@ public class BlockListener implements Listener { blockState.update(true); } } - else if (mcMMOPlayer.getAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed())) { + else if (mcMMOPlayer.getAbilityMode(SuperAbilityType.BERSERK) && ItemUtils.isUnarmed(mcMMOPlayer.getPlayer().getInventory().getItemInMainHand()) || CombatUtils.isUsingUnarmedCombat(mcMMOPlayer)) { if (mcMMOPlayer.getUnarmedManager().canUseBlockCracker() && BlockUtils.affectedByBlockCracker(blockState)) { if (EventUtils.simulateBlockBreak(block, player, true) && mcMMOPlayer.getUnarmedManager().blockCrackerCheck(blockState)) { blockState.update(); diff --git a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java index 93dc5eef5..020ecf212 100644 --- a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java +++ b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java @@ -13,6 +13,7 @@ import com.gmail.nossr50.util.*; import com.gmail.nossr50.util.player.NotificationManager; import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.random.RandomChanceUtil; +import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.SkillActivationType; import org.bukkit.Material; @@ -24,6 +25,14 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; public class UnarmedManager extends SkillManager { + private long lastUsedUnarmed = 0L; + + /** + * Players are considered using Unarmed if they have damaged another entity with empty fists in the last 60 seconds + */ + public boolean usedUnarmedCombatRecently() { + return lastUsedUnarmed + 60000 > System.currentTimeMillis(); + } public UnarmedManager(McMMOPlayer mcMMOPlayer) { super(mcMMOPlayer, PrimarySkillType.UNARMED); @@ -57,7 +66,11 @@ public class UnarmedManager extends SkillManager { Player player = getPlayer(); - return ItemUtils.isUnarmed(player.getInventory().getItemInMainHand()) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_ARROW_DEFLECT); + McMMOPlayer mmoPlayer = UserManager.getPlayer(player); + if(mmoPlayer == null) + return false; + + return CombatUtils.isUsingUnarmedCombat(mmoPlayer) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.UNARMED_ARROW_DEFLECT); } public boolean canUseBlockCracker() { @@ -188,4 +201,8 @@ public class UnarmedManager extends SkillManager { return false; } + + public void updateLastUsedUnarmed() { + this.lastUsedUnarmed = System.currentTimeMillis(); + } } diff --git a/src/main/java/com/gmail/nossr50/util/ItemUtils.java b/src/main/java/com/gmail/nossr50/util/ItemUtils.java index 2e46341c2..cd0216678 100644 --- a/src/main/java/com/gmail/nossr50/util/ItemUtils.java +++ b/src/main/java/com/gmail/nossr50/util/ItemUtils.java @@ -2,6 +2,7 @@ package com.gmail.nossr50.util; import com.gmail.nossr50.config.experience.ExperienceConfig; import com.gmail.nossr50.config.party.ItemWeightConfig; +import com.gmail.nossr50.datatypes.player.McMMOPlayer; import com.gmail.nossr50.datatypes.treasure.EnchantmentWrapper; import com.gmail.nossr50.datatypes.treasure.FishingTreasureBook; import com.gmail.nossr50.locale.LocaleLoader; @@ -178,18 +179,12 @@ public final class ItemUtils { return mcMMO.getMaterialMapStore().isPickAxe(item.getType().getKey().getKey()); } - /** - * Checks if the item counts as unarmed. - * - * @param item Item to check - * @return true if the item counts as unarmed, false otherwise - */ - public static boolean isUnarmed(ItemStack item) { + public static boolean isUnarmed(@NotNull ItemStack itemInMainHand) { if (mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed()) { - return !isMinecraftTool(item); + return !isMinecraftTool(itemInMainHand); } - return item.getType() == Material.AIR; + return itemInMainHand.getType() == Material.AIR; } /** 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 bf4a3a4ee..4c4a25e3e 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java +++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java @@ -40,6 +40,8 @@ import org.jetbrains.annotations.Nullable; import java.util.List; +import static com.gmail.nossr50.util.ItemUtils.isMinecraftTool; + public final class CombatUtils { private CombatUtils() {} @@ -166,47 +168,45 @@ public final class CombatUtils { printFinalDamageDebug(player, event, mcMMOPlayer); } - private static void processUnarmedCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) { + private static void processUnarmedCombat(@NotNull LivingEntity target, @NotNull McMMOPlayer mmoPlayer, @NotNull EntityDamageByEntityEvent event) { if (event.getCause() == DamageCause.THORNS) { return; } double boostedDamage = event.getDamage(); - McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); + UnarmedManager unarmedManager = mmoPlayer.getUnarmedManager(); - //Make sure the profiles been loaded - if(mcMMOPlayer == null) { - return; - } + if(isUsingUnarmedCombat(mmoPlayer)) { + if (unarmedManager.canActivateAbility()) { + mmoPlayer.checkAbilityActivation(PrimarySkillType.UNARMED); + } - UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager(); + if (unarmedManager.canUseSteelArm()) { + boostedDamage+=(unarmedManager.calculateSteelArmStyleDamage() * mmoPlayer.getAttackStrength()); + } - if (unarmedManager.canActivateAbility()) { - mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED); - } + if (unarmedManager.canUseBerserk()) { + boostedDamage+=(unarmedManager.berserkDamage(boostedDamage) * mmoPlayer.getAttackStrength()); + } - if (unarmedManager.canUseSteelArm()) { - boostedDamage+=(unarmedManager.calculateSteelArmStyleDamage() * mcMMOPlayer.getAttackStrength()); - } + if (unarmedManager.canDisarm(target)) { + unarmedManager.disarmCheck((Player) target); + } - if (unarmedManager.canUseBerserk()) { - boostedDamage+=(unarmedManager.berserkDamage(boostedDamage) * mcMMOPlayer.getAttackStrength()); - } - - if (unarmedManager.canDisarm(target)) { - unarmedManager.disarmCheck((Player) target); - } - - if(canUseLimitBreak(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) - { - boostedDamage+=(getLimitBreakDamage(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength()); + if(canUseLimitBreak(mmoPlayer.getPlayer(), target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) + { + boostedDamage+=(getLimitBreakDamage(mmoPlayer.getPlayer(), target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK) * mmoPlayer.getAttackStrength()); + } } event.setDamage(boostedDamage); - processCombatXP(mcMMOPlayer, target, PrimarySkillType.UNARMED); + processCombatXP(mmoPlayer, target, PrimarySkillType.UNARMED); + printFinalDamageDebug(mmoPlayer.getPlayer(), event, mmoPlayer); - printFinalDamageDebug(player, event, mcMMOPlayer); + if (ItemUtils.isUnarmed(mmoPlayer.getPlayer().getInventory().getItemInMainHand())) { + mmoPlayer.getUnarmedManager().updateLastUsedUnarmed(); + } } private static void processTamingCombat(@NotNull LivingEntity target, @Nullable Player master, @NotNull Wolf wolf, @NotNull EntityDamageByEntityEvent event) { @@ -335,6 +335,7 @@ public final class CombatUtils { } if (painSourceRoot instanceof Player player && entityType == EntityType.PLAYER) { + McMMOPlayer mmoPlayer = UserManager.getPlayer(player); if (!UserManager.hasPlayerDataKey(player)) { return; @@ -377,13 +378,13 @@ public final class CombatUtils { processAxeCombat(target, player, event); } } - else if (ItemUtils.isUnarmed(heldItem)) { + else if (mmoPlayer != null && (mmoPlayer.getUnarmedManager().usedUnarmedCombatRecently() || ItemUtils.isUnarmed(heldItem))) { if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.UNARMED, target)) { return; } if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.UNARMED)) { - processUnarmedCombat(target, player, event); + processUnarmedCombat(target, mmoPlayer, event); } } } @@ -977,4 +978,21 @@ public final class CombatUtils { public static void delayArrowMetaCleanup(@NotNull Projectile entity) { Bukkit.getServer().getScheduler().runTaskLater(mcMMO.p, () -> cleanupArrowMetadata(entity), 20*60); } + + /** + * Check if a player is considered "unarmed" + * + * @param mmoPlayer target player + * @return true if the item counts as unarmed, false otherwise + */ + public static boolean isUsingUnarmedCombat(@NotNull McMMOPlayer mmoPlayer) { + ItemStack itemInMainHand = mmoPlayer.getPlayer().getInventory().getItemInMainHand(); + + // player has to have been unarmed recently or config allows items as unarmed + if (mmoPlayer.getUnarmedManager().usedUnarmedCombatRecently() || mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed()) { + return !isMinecraftTool(itemInMainHand); + } + + return itemInMainHand.getType() == Material.AIR; + } }