Players who used unarmed combat are still considered using unarmed while not holding weapons for a brief time period

This commit is contained in:
nossr50 2022-07-23 16:13:49 -07:00
parent 9cf856221d
commit 993b418fbc
5 changed files with 73 additions and 39 deletions

View File

@ -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.

View File

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

View File

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

View File

@ -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;
}
/**

View File

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