displayData = new ArrayList<>();
displayData.add(header);
for (PrimarySkillType primarySkillType : skillGroup) {
diff --git a/src/main/java/com/gmail/nossr50/util/platform/PlatformBuilder.java b/src/main/java/com/gmail/nossr50/util/platform/PlatformBuilder.java
index a2930137e..733bf58a0 100644
--- a/src/main/java/com/gmail/nossr50/util/platform/PlatformBuilder.java
+++ b/src/main/java/com/gmail/nossr50/util/platform/PlatformBuilder.java
@@ -28,15 +28,10 @@ public class PlatformBuilder {
}
public @Nullable Platform build() {
- switch(serverSoftwareType) {
-
- case PAPER:
- case SPIGOT:
- case CRAFT_BUKKIT:
- return createBukkitPlatform();
- default:
- return null;
- }
+ return switch (serverSoftwareType) {
+ case PAPER, SPIGOT, CRAFT_BUKKIT -> createBukkitPlatform();
+ default -> null;
+ };
}
private BukkitPlatform createBukkitPlatform() {
diff --git a/src/main/java/com/gmail/nossr50/util/platform/PlatformManager.java b/src/main/java/com/gmail/nossr50/util/platform/PlatformManager.java
index 721df8091..a638dabfd 100644
--- a/src/main/java/com/gmail/nossr50/util/platform/PlatformManager.java
+++ b/src/main/java/com/gmail/nossr50/util/platform/PlatformManager.java
@@ -85,14 +85,11 @@ public class PlatformManager {
}
public String getServerSoftwareStr() {
- switch(getServerSoftware()) {
- case PAPER:
- return "Paper";
- case SPIGOT:
- return "Spigot";
- default:
- return "CraftBukkit";
- }
+ return switch (getServerSoftware()) {
+ case PAPER -> "Paper";
+ case SPIGOT -> "Spigot";
+ default -> "CraftBukkit";
+ };
}
public @Nullable CompatibilityManager getCompatibilityManager() {
diff --git a/src/main/java/com/gmail/nossr50/util/random/Probability.java b/src/main/java/com/gmail/nossr50/util/random/Probability.java
index 3b9225b97..6873371a2 100644
--- a/src/main/java/com/gmail/nossr50/util/random/Probability.java
+++ b/src/main/java/com/gmail/nossr50/util/random/Probability.java
@@ -94,4 +94,17 @@ public interface Probability {
double probabilityValue = getValue() * probabilityMultiplier;
return isSuccessfulRoll(probabilityValue);
}
+
+ /**
+ * Modify and then Simulate an outcome on a probability and return true or false for the result of that outcome.
+ *
+ * @param probabilityMultiplier probability will be multiplied by this before success is checked
+ * @param finalProbabilityMultiplier probability will be multiplied by this after the first multiplier,
+ * should be between 0 and 1
+ * @return true if the probability succeeded, false if it failed
+ */
+ default boolean evaluate(double probabilityMultiplier, double finalProbabilityMultiplier) {
+ double probabilityValue = getValue() * probabilityMultiplier;
+ return isSuccessfulRoll(probabilityValue * finalProbabilityMultiplier);
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java b/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java
index ca4a67de8..715673496 100644
--- a/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java
+++ b/src/main/java/com/gmail/nossr50/util/random/ProbabilityUtil.java
@@ -188,6 +188,45 @@ public class ProbabilityUtil {
}
}
+ /**
+ * This is one of several Skill RNG evaluation methods.
+ * This one specifically allows for a probability multiplier to be passed in.
+ * This probability multiplier is applied after any lucky modifiers, affecting the final result.
+ *
+ * This helper method is for specific {@link SubSkillType},
+ * which help mcMMO understand where the RNG values used in our calculations come from this {@link SubSkillType}
+ *
+ * 1) Determine where the RNG values come from for the passed {@link SubSkillType}
+ * NOTE: In the config file, there are values which are static and which are more dynamic,
+ * this is currently a bit hardcoded and will need to be updated manually
+ *
+ * 2) Determine whether to use Lucky multiplier and influence the outcome
+ *
+ * 3)
+ * Creates a {@link Probability} and pipes it to {@link ProbabilityUtil} which processes the result and returns it
+ *
+ * This also calls a {@link SubSkillEvent} which can be cancelled, if it is cancelled this will return false
+ * The outcome of the probability can also be modified by this event that is called
+ *
+ * @param subSkillType target subskill
+ * @param mmoPlayer target player
+ * can be null (null players are given odds equivalent to a player with no levels or luck)
+ * @return true if the Skill RNG succeeds, false if it fails
+ */
+ public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @Nullable McMMOPlayer mmoPlayer,
+ double probabilityMultiplier) {
+ final Probability probability = getSkillProbability(subSkillType, mmoPlayer);
+
+ //Luck
+ boolean isLucky = mmoPlayer != null && Permissions.lucky(mmoPlayer.getPlayer(), subSkillType.getParentSkill());
+
+ if (isLucky) {
+ return probability.evaluate(LUCKY_MODIFIER, probabilityMultiplier);
+ } else {
+ return probability.evaluate();
+ }
+ }
+
/**
* Returns the {@link Probability} for a specific {@link SubSkillType} for a specific {@link Player}.
* This does not take into account perks such as lucky for the player.
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 fb5834ad9..9dfb3abdb 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
@@ -13,6 +13,7 @@ import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
import com.gmail.nossr50.skills.archery.ArcheryManager;
import com.gmail.nossr50.skills.axes.AxesManager;
+import com.gmail.nossr50.skills.maces.MacesManager;
import com.gmail.nossr50.skills.swords.SwordsManager;
import com.gmail.nossr50.skills.taming.TamingManager;
import com.gmail.nossr50.skills.tridents.TridentsManager;
@@ -20,6 +21,7 @@ import com.gmail.nossr50.skills.unarmed.UnarmedManager;
import com.gmail.nossr50.util.*;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
+import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
@@ -58,7 +60,7 @@ public final class CombatUtils {
return;
}
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
@@ -72,10 +74,6 @@ public final class CombatUtils {
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.SWORDS);
}
- if (target.getHealth() - event.getFinalDamage() > 0) {
- swordsManager.processRupture(target);
- }
-
//Add Stab Damage
if (swordsManager.canUseStab()) {
boostedDamage += (swordsManager.getStabDamage() * mcMMOPlayer.getAttackStrength());
@@ -86,18 +84,27 @@ public final class CombatUtils {
}
if (canUseLimitBreak(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
- boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ boostedDamage += (getLimitBreakDamage
+ (player, target, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
}
event.setDamage(boostedDamage);
+
+ if (target.getHealth() - event.getFinalDamage() > 0) {
+ swordsManager.processRupture(target);
+ }
+
processCombatXP(mcMMOPlayer, target, PrimarySkillType.SWORDS);
printFinalDamageDebug(player, event, mcMMOPlayer);
}
- private static void printFinalDamageDebug(@NotNull Player player, @NotNull EntityDamageByEntityEvent event, @NotNull McMMOPlayer mcMMOPlayer, @Nullable String @Nullable ... extraInfoLines) {
+ private static void printFinalDamageDebug(@NotNull Player player, @NotNull EntityDamageByEntityEvent event,
+ @NotNull McMMOPlayer mcMMOPlayer,
+ @Nullable String @Nullable ...extraInfoLines) {
if (mcMMOPlayer.isDebugMode()) {
player.sendMessage("Final Damage value after mcMMO modifiers: "+ event.getFinalDamage());
+ player.sendMessage("Your current attack strength: "+ player.getAttackCooldown());
if (extraInfoLines != null) {
for(String str : extraInfoLines) {
if (str != null)
@@ -114,14 +121,14 @@ public final class CombatUtils {
double boostedDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
+ final TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
// if (tridentsManager.canActivateAbility()) {
// mcMMOPlayer.checkAbilityActivation(PrimarySkillType.TRIDENTS);
@@ -132,7 +139,8 @@ public final class CombatUtils {
}
if (canUseLimitBreak(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
- boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ boostedDamage += (getLimitBreakDamage(
+ player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
}
event.setDamage(boostedDamage);
@@ -148,21 +156,21 @@ public final class CombatUtils {
double boostedDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
+ final TridentsManager tridentsManager = mcMMOPlayer.getTridentsManager();
if (SkillUtils.canUseSubskill(player, SubSkillType.TRIDENTS_IMPALE)) {
- boostedDamage += (tridentsManager.impaleDamageBonus() * mcMMOPlayer.getAttackStrength());
+ boostedDamage += (tridentsManager.impaleDamageBonus());
}
if (canUseLimitBreak(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
- boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.TRIDENTS_TRIDENTS_LIMIT_BREAK));
}
event.setDamage(boostedDamage);
@@ -175,7 +183,7 @@ public final class CombatUtils {
@NotNull EntityDamageByEntityEvent event, @NotNull Arrow arrow) {
double initialDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
@@ -210,60 +218,73 @@ public final class CombatUtils {
delayArrowMetaCleanup(arrow);
}
- private static void processMacesCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
+ private static void processMacesCombat(@NotNull LivingEntity target,
+ @NotNull Player player,
+ @NotNull EntityDamageByEntityEvent event) {
if (event.getCause() == DamageCause.THORNS) {
return;
}
double boostedDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- // MacesManager macesManager = mcMMOPlayer.getMacesManager();
+ final MacesManager macesManager = mcMMOPlayer.getMacesManager();
+ // Apply Limit Break DMG
if (canUseLimitBreak(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK)) {
- boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ boostedDamage += (getLimitBreakDamage(
+ player, target, SubSkillType.MACES_MACES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
}
- event.setDamage(boostedDamage);
- processCombatXP(mcMMOPlayer, target, PrimarySkillType.MACES);
+ // Apply Crush DMG
+ boostedDamage += (macesManager.getCrushDamage() * mcMMOPlayer.getAttackStrength());
+ event.setDamage(boostedDamage);
+
+ // Apply Cripple
+ if (target.getHealth() - event.getFinalDamage() > 0) {
+ macesManager.processCripple(target);
+ }
+
+ processCombatXP(mcMMOPlayer, target, PrimarySkillType.MACES);
printFinalDamageDebug(player, event, mcMMOPlayer);
}
- private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
+ private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player,
+ @NotNull EntityDamageByEntityEvent event) {
if (event.getCause() == DamageCause.THORNS) {
return;
}
double boostedDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- AxesManager axesManager = mcMMOPlayer.getAxesManager();
+ final AxesManager axesManager = mcMMOPlayer.getAxesManager();
if (axesManager.canActivateAbility()) {
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.AXES);
}
if (axesManager.canUseAxeMastery()) {
- boostedDamage+=axesManager.axeMastery();
+ boostedDamage += axesManager.axeMastery() * mcMMOPlayer.getAttackStrength();
}
if (axesManager.canImpact(target)) {
axesManager.impactCheck(target);
} else if (axesManager.canGreaterImpact(target)) {
- boostedDamage+=axesManager.greaterImpact(target);
+ boostedDamage += axesManager.greaterImpact(target) * mcMMOPlayer.getAttackStrength();
}
if (axesManager.canUseSkullSplitter(target)) {
@@ -291,14 +312,14 @@ public final class CombatUtils {
double boostedDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
+ final UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
if (unarmedManager.canActivateAbility()) {
mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
@@ -317,7 +338,8 @@ public final class CombatUtils {
}
if (canUseLimitBreak(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) {
- boostedDamage+=(getLimitBreakDamage(player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
+ boostedDamage+=(getLimitBreakDamage(
+ player, target, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
}
event.setDamage(boostedDamage);
@@ -331,14 +353,14 @@ public final class CombatUtils {
double boostedDamage = initialDamage;
if (master != null && master.isOnline() && master.isValid()) {
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(master);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(master);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
return;
}
- TamingManager tamingManager = mcMMOPlayer.getTamingManager();
+ final TamingManager tamingManager = mcMMOPlayer.getTamingManager();
if (tamingManager.canUseFastFoodService()) {
tamingManager.fastFoodService(wolf, event.getDamage());
@@ -364,7 +386,7 @@ public final class CombatUtils {
@NotNull EntityDamageByEntityEvent event, @NotNull Arrow arrow) {
double initialDamage = event.getDamage();
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
//Make sure the profiles been loaded
if (mcMMOPlayer == null) {
@@ -372,7 +394,7 @@ public final class CombatUtils {
return;
}
- ArcheryManager archeryManager = mcMMOPlayer.getArcheryManager();
+ final ArcheryManager archeryManager = mcMMOPlayer.getArcheryManager();
double boostedDamage = event.getDamage();
@@ -416,7 +438,9 @@ public final class CombatUtils {
*
* @param event The event to run the combat checks on.
*/
- public static void processCombatAttack(@NotNull EntityDamageByEntityEvent event, @NotNull Entity painSourceRoot, @NotNull LivingEntity target) {
+ public static void processCombatAttack(@NotNull EntityDamageByEntityEvent event,
+ @NotNull Entity painSourceRoot,
+ @NotNull LivingEntity target) {
Entity painSource = event.getDamager();
EntityType entityType = painSource.getType();
@@ -435,8 +459,8 @@ public final class CombatUtils {
return;
}
- McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
- AcrobaticsManager acrobaticsManager = mcMMOPlayer.getAcrobaticsManager();
+ final McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+ final AcrobaticsManager acrobaticsManager = mcMMOPlayer.getAcrobaticsManager();
if (acrobaticsManager.canDodge(target)) {
event.setDamage(acrobaticsManager.dodgeCheck(painSourceRoot, event.getDamage()));
@@ -447,7 +471,7 @@ public final class CombatUtils {
return;
}
- SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
+ final SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
if (swordsManager.canUseCounterAttack(painSource)) {
swordsManager.counterAttackChecks((LivingEntity) painSource, event.getDamage());
@@ -456,7 +480,6 @@ public final class CombatUtils {
}
if (painSourceRoot instanceof Player player && entityType == EntityType.PLAYER) {
-
if (!UserManager.hasPlayerDataKey(player)) {
return;
}
@@ -811,7 +834,7 @@ public final class CombatUtils {
NotificationManager.sendPlayerInformation((Player)entity, NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.SS.Struck");
}
- McMMOPlayer mmoAttacker = UserManager.getPlayer(attacker);
+ final McMMOPlayer mmoAttacker = UserManager.getPlayer(attacker);
if (mmoAttacker != null) {
mmoAttacker.getSwordsManager().processRupture(livingEntity);
diff --git a/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java b/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
index c0e17bbe8..a205dfdea 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
@@ -1,13 +1,14 @@
package com.gmail.nossr50.util.skills;
+import com.gmail.nossr50.datatypes.interactions.NotificationType;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.player.NotificationManager;
+import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
import org.apache.commons.lang3.RandomUtils;
-import org.bukkit.Effect;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.World;
+import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.LivingEntity;
@@ -29,7 +30,26 @@ public final class ParticleEffectUtils {
return;
}
- livingEntity.getWorld().playEffect(getParticleLocation(livingEntity), Effect.STEP_SOUND, Material.REDSTONE_WIRE);
+ livingEntity.getWorld().playEffect(getParticleLocation(livingEntity),
+ Effect.STEP_SOUND, Material.REDSTONE_WIRE);
+ }
+
+ public static void playCrippleEffect(@NotNull LivingEntity livingEntity) {
+ if (!mcMMO.p.getGeneralConfig().getCrippleEffectEnabled()) {
+ return;
+ }
+
+ SoundManager.sendCategorizedSound(livingEntity.getLocation(), SoundType.CRIPPLE, SoundCategory.PLAYERS, 0.2F);
+ livingEntity.getWorld().playEffect(getParticleLocation(livingEntity), Effect.ANVIL_BREAK, null, 20);
+
+ if (livingEntity instanceof Player player) {
+ final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
+ boolean useChatNotification = mmoPlayer == null || mmoPlayer.useChatNotifications();
+ if (useChatNotification) {
+ NotificationManager.sendPlayerInformation(
+ player, NotificationType.SUBSKILL_MESSAGE, "Maces.SubSkill.Cripple.Proc");
+ }
+ }
}
private static @NotNull Location getParticleLocation(@NotNull LivingEntity livingEntity) {
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
index 151c7e649..8afb05594 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
@@ -23,8 +23,8 @@ import java.util.*;
public class SkillTools {
private final mcMMO pluginRef;
-
- //TODO: Figure out which ones we don't need, this was copy pasted from a diff branch
+ // TODO: Java has immutable types now, switch to those
+ // TODO: Figure out which ones we don't need, this was copy pasted from a diff branch
public final @NotNull ImmutableList LOCALIZED_SKILL_NAMES;
public final @NotNull ImmutableList FORMATTED_SUBSKILL_NAMES;
public final @NotNull ImmutableSet EXACT_SUBSKILL_NAMES;
@@ -156,14 +156,28 @@ public class SkillTools {
* Build categorized skill lists
*/
- COMBAT_SKILLS = ImmutableList.of(
- PrimarySkillType.ARCHERY,
- PrimarySkillType.AXES,
- PrimarySkillType.CROSSBOWS,
- PrimarySkillType.SWORDS,
- PrimarySkillType.TAMING,
- PrimarySkillType.TRIDENTS,
- PrimarySkillType.UNARMED);
+ // We are in a game version with Maces
+ if (mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
+ COMBAT_SKILLS = ImmutableList.of(
+ PrimarySkillType.ARCHERY,
+ PrimarySkillType.AXES,
+ PrimarySkillType.CROSSBOWS,
+ PrimarySkillType.MACES,
+ PrimarySkillType.SWORDS,
+ PrimarySkillType.TAMING,
+ PrimarySkillType.TRIDENTS,
+ PrimarySkillType.UNARMED);
+ } else {
+ // No Maces in this version
+ COMBAT_SKILLS = ImmutableList.of(
+ PrimarySkillType.ARCHERY,
+ PrimarySkillType.AXES,
+ PrimarySkillType.CROSSBOWS,
+ PrimarySkillType.SWORDS,
+ PrimarySkillType.TAMING,
+ PrimarySkillType.TRIDENTS,
+ PrimarySkillType.UNARMED);
+ }
GATHERING_SKILLS = ImmutableList.of(
PrimarySkillType.EXCAVATION,
PrimarySkillType.FISHING,
diff --git a/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java b/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java
index c809444fa..c89bf86e7 100644
--- a/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java
+++ b/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java
@@ -9,21 +9,54 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
public class SoundManager {
+ public static Sound CRIPPLE_SOUND;
+ static {
+ try {
+ CRIPPLE_SOUND = Sound.valueOf("ITEM_MACE_SMASH_GROUND");
+ } catch (IllegalArgumentException e) {
+ CRIPPLE_SOUND = Sound.BLOCK_ANVIL_PLACE;
+ }
+ }
+
/**
* Sends a sound to the player
* @param soundType the type of sound
*/
public static void sendSound(Player player, Location location, SoundType soundType) {
if (SoundConfig.getInstance().getIsEnabled(soundType))
- player.playSound(location, getSound(soundType), SoundCategory.MASTER, getVolume(soundType), getPitch(soundType));
+ player.playSound(location, getSound(soundType),
+ SoundCategory.MASTER, getVolume(soundType), getPitch(soundType));
}
- public static void sendCategorizedSound(Player player, Location location, SoundType soundType, SoundCategory soundCategory) {
+ public static void sendCategorizedSound(Location location, SoundType soundType, SoundCategory soundCategory) {
+ if (SoundConfig.getInstance().getIsEnabled(soundType)) {
+ final World world = location.getWorld();
+ if (world != null) {
+ world.playSound(location, getSound(soundType), soundCategory,
+ getVolume(soundType), getPitch(soundType));
+ }
+ }
+ }
+
+ public static void sendCategorizedSound(Location location, SoundType soundType, SoundCategory soundCategory,
+ float pitchModifier) {
+ if (SoundConfig.getInstance().getIsEnabled(soundType)) {
+ final World world = location.getWorld();
+ if (world != null) {
+ float totalPitch = Math.min(2.0F, (getPitch(soundType) + pitchModifier));
+ world.playSound(location, getSound(soundType), soundCategory, getVolume(soundType), totalPitch);
+ }
+ }
+ }
+
+ public static void sendCategorizedSound(Player player, Location location,
+ SoundType soundType, SoundCategory soundCategory) {
if (SoundConfig.getInstance().getIsEnabled(soundType))
player.playSound(location, getSound(soundType), soundCategory, getVolume(soundType), getPitch(soundType));
}
- public static void sendCategorizedSound(Player player, Location location, SoundType soundType, SoundCategory soundCategory, float pitchModifier) {
+ public static void sendCategorizedSound(Player player, Location location,
+ SoundType soundType, SoundCategory soundCategory, float pitchModifier) {
float totalPitch = Math.min(2.0F, (getPitch(soundType) + pitchModifier));
if (SoundConfig.getInstance().getIsEnabled(soundType))
@@ -74,6 +107,7 @@ public class SoundManager {
case DEFLECT_ARROWS, BLEED -> Sound.ENTITY_ENDER_EYE_DEATH;
case GLASS -> Sound.BLOCK_GLASS_BREAK;
case ITEM_CONSUMED -> Sound.ITEM_BOTTLE_EMPTY;
+ case CRIPPLE -> CRIPPLE_SOUND;
};
}
diff --git a/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java b/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java
index 5b4a083f3..21c1a0d93 100644
--- a/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java
+++ b/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java
@@ -16,6 +16,7 @@ public enum SoundType {
BLEED,
GLASS,
ITEM_CONSUMED,
+ CRIPPLE,
TIRED;
public boolean usesCustomPitch() {
diff --git a/src/main/resources/advanced.yml b/src/main/resources/advanced.yml
index 7d56c4e37..bbbf2ea44 100644
--- a/src/main/resources/advanced.yml
+++ b/src/main/resources/advanced.yml
@@ -633,4 +633,11 @@ Skills:
ChanceMax: 100.0
MaxBonusLevel:
Standard: 100
- RetroMode: 1000
\ No newline at end of file
+ RetroMode: 1000
+ Maces:
+ Cripple:
+ Chance_To_Apply_On_Hit:
+ Rank_1: 10
+ Rank_2: 15
+ Rank_3: 20
+ Rank_4: 33
\ No newline at end of file
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index fede55679..fdb93cc40 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -694,6 +694,7 @@ Particles:
Flux: true
Greater_Impact: true
Call_of_the_Wild: true
+ Cripple: true
# These settings determine if fireworks should get launched when a player levels-up,
# this will happen by default for every 100 levels.
diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties
index f2fcc7a26..af1fd69c9 100644
--- a/src/main/resources/locale/locale_en_US.properties
+++ b/src/main/resources/locale/locale_en_US.properties
@@ -458,12 +458,22 @@ Tridents.SubSkill.TridentAbility.Name=WIP
Tridents.Listener=Tridents:
#MACES
+Commands.McTop.MacesNotSupported=[[GREEN]]Maces are not supported in this version of Minecraft.
Maces.SkillName=MACES
Maces.Ability.Lower=&7You lower your mace.
Maces.Ability.Ready=&3You &6ready&3 your Mace.
Maces.SubSkill.MacesLimitBreak.Name=Maces Limit Break
Maces.SubSkill.MacesLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether it will boost damage in PVE.
Maces.SubSkill.MacesLimitBreak.Stat=Limit Break Max DMG
+Maces.SubSkill.Crush.Name=Crush
+Maces.SubSkill.Crush.Description=Adds bonus damage to your attacks.
+Maces.SubSkill.Crush.Stat=Crush Damage
+Maces.SubSkill.Cripple.Proc=**CRIPPLED**
+Maces.SubSkill.Cripple.Activated=CRIPPLED TARGET!
+Maces.SubSkill.Cripple.Name=Cripple
+Maces.SubSkill.Cripple.Description=Adds a chance to cripple your target.
+Maces.SubSkill.Cripple.Stat=Cripple Chance
+Maces.SubSkill.Cripple.Stat.Extra=[[DARK_AQUA]]Cripple Duration: &e{0}s&a vs Players, &e{1}s&a vs Mobs.
Maces.Listener=Maces:
#SWORDS
@@ -899,6 +909,7 @@ Commands.XPGain.Crossbows=Attacking Monsters
Commands.XPGain.Excavation=Digging and finding treasures
Commands.XPGain.Fishing=Fishing (Go figure!)
Commands.XPGain.Herbalism=Harvesting Herbs
+Commands.XPGain.Maces=Attacking Monsters
Commands.XPGain.Mining=Mining Stone & Ore
Commands.XPGain.Repair=Repairing
Commands.XPGain.Swords=Attacking Monsters
@@ -1038,11 +1049,11 @@ Guides.Woodcutting.Section.1=&3How does Tree Feller work?\n&eTree Feller is an a
Guides.Woodcutting.Section.2=&3How does Leaf Blower work?\n&eLeaf Blower is a passive ability that will cause leaf\n&eblocks to break instantly when hit with an axe. By default,\nðis ability unlocks at level 100.
Guides.Woodcutting.Section.3=&3How do Double Drops work?\n&eThis passive ability gives you a chance to obtain an extra\n&eblock for every log you chop.
# Crossbows
-Guides.Crossbows.Section.0=&3About Crossbows:\n&eCrossbows is all about shooting with your crossbow.\n\n&3XP GAIN:\n&eXP is gained whenever you shoot mobs with a crossbow.
+Guides.Crossbows.Section.0=&3About Crossbows:\n&eCrossbows is all about shooting with your crossbow.\n\n&3XP GAIN:\n&eXP is gained whenever you shoot mobs with a crossbow.\nThis is a WIP skill and more information will be added soon.
Guides.Crossbows.Section.1=&3How does Trickshot work?\n&eTrickshot is an passive ability, you shoot your bolts at a shallow angle with a crossbow to attempt a Trickshot. This will cause the arrow to ricochet off of blocks and potentially hit a target. The number of potential bounces from a ricochet depend on the rank of Trickshot.
# Tridents
-Guides.Tridents.Section.0=&3About Tridents:\n&eTridents skill involves impaling foes with your trident.\n\n&3XP GAIN:\n&eXP is gained whenever you hit mobs with a trident.
-
+Guides.Tridents.Section.0=&3About Tridents:\n&eTridents skill involves impaling foes with your trident.\n\n&3XP GAIN:\n&eXP is gained whenever you hit mobs with a trident.\nThis is a WIP skill and more information will be added soon.
+Guides.Maces.Section.0=&3About Maces:\n&eMaces is all about smashing your foes with a mace.\n\n&3XP GAIN:\n&eXP is gained whenever you hit mobs with a mace.\nThis is a WIP skill and more information will be added soon.
#INSPECT
Inspect.Offline= &cYou do not have permission to inspect offline players!
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 52500d4cb..864ba3bb6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -248,6 +248,7 @@ permissions:
mcmmo.ability.excavation.all: true
mcmmo.ability.fishing.all: true
mcmmo.ability.herbalism.all: true
+ mcmmo.ability.maces.all: true
mcmmo.ability.mining.all: true
mcmmo.ability.repair.all: true
mcmmo.ability.salvage.all: true
@@ -479,6 +480,23 @@ permissions:
description: Allows access to the Hylian Luck ability
mcmmo.ability.herbalism.shroomthumb:
description: Allows access to the Shroom Thumb ability
+ mcmmo.ability.maces.*:
+ default: false
+ description: Allows access to all Maces abilities
+ children:
+ mcmmo.ability.mining.all: true
+ mcmmo.ability.maces.all:
+ description: Allows access to all Maces abilities
+ children:
+ mcmmo.ability.maces.crush: true
+ mcmmo.ability.maces.cripple: true
+ mcmmo.ability.maces.maceslimitbreak: true
+ mcmmo.ability.maces.maceslimitbreak:
+ description: Allows access to Maces Limit Break subskill
+ mcmmo.ability.maces.crush:
+ description: Allows access to the Crush ability
+ mcmmo.ability.maces.cripple:
+ description: Allows access to the Cripple ability
mcmmo.ability.mining.*:
default: false
description: Allows access to all Mining abilities
@@ -870,6 +888,7 @@ permissions:
mcmmo.commands.mcscoreboard: true
mcmmo.commands.mcstats: true
mcmmo.commands.mctop.all: true
+ mcmmo.commands.maces: true
mcmmo.commands.mining: true
mcmmo.commands.party.all: true
mcmmo.commands.ptp.all: true
@@ -1047,6 +1066,7 @@ permissions:
mcmmo.commands.mctop.excavation: true
mcmmo.commands.mctop.fishing: true
mcmmo.commands.mctop.herbalism: true
+ mcmmo.commands.mctop.maces: true
mcmmo.commands.mctop.mining: true
mcmmo.commands.mctop.repair: true
mcmmo.commands.mctop.salvage: true
@@ -1074,6 +1094,8 @@ permissions:
description: Allows access to the mctop command for fishing
mcmmo.commands.mctop.herbalism:
description: Allows access to the mctop command for herbalism
+ mcmmo.commands.mctop.maces:
+ description: Allows access to the mctop command for maces
mcmmo.commands.mctop.mining:
description: Allows access to the mctop command for mining
mcmmo.commands.mctop.repair:
@@ -1234,6 +1256,9 @@ permissions:
mcmmo.commands.skillreset.taming: true
mcmmo.commands.skillreset.unarmed: true
mcmmo.commands.skillreset.woodcutting: true
+ mcmmo.commands.skillreset.crossbows: true
+ mcmmo.commands.skillreset.tridents: true
+ mcmmo.commands.skillreset.maces: true
mcmmo.commands.skillreset:
description: Allows access to the skillreset command
mcmmo.commands.skillreset.acrobatics:
@@ -1252,6 +1277,12 @@ permissions:
description: Allows access to the skillreset command for herbalism
mcmmo.commands.skillreset.mining:
description: Allows access to the skillreset command for mining
+ mcmmo.commands.skillreset.crossbows:
+ description: Allows access to the skillreset command for crossbows
+ mcmmo.commands.skillreset.tridents:
+ description: Allows access to the skillreset command for tridents
+ mcmmo.commands.skillreset.maces:
+ description: Allows access to the skillreset command for maces
mcmmo.commands.skillreset.others.*:
default: false
description: Implies access to all mcmmo.commands.skillreset.others permissions
@@ -1276,6 +1307,9 @@ permissions:
mcmmo.commands.skillreset.others.taming: true
mcmmo.commands.skillreset.others.unarmed: true
mcmmo.commands.skillreset.others.woodcutting: true
+ mcmmo.commands.skillreset.others.crossbows: true
+ mcmmo.commands.skillreset.others.tridents: true
+ mcmmo.commands.skillreset.others.maces: true
mcmmo.commands.skillreset.others:
description: Allows access to the skillreset command for other players
mcmmo.commands.skillreset.others.acrobatics:
@@ -1308,6 +1342,12 @@ permissions:
description: Allows access to the skillreset command for unarmed for other players
mcmmo.commands.skillreset.others.woodcutting:
description: Allows access to the skillreset command for woodcutting for other players
+ mcmmo.commands.skillreset.others.crossbows:
+ description: Allows access to the skillreset command for crossbows for other players
+ mcmmo.commands.skillreset.others.tridents:
+ description: Allows access to the skillreset command for tridents for other players
+ mcmmo.commands.skillreset.others.maces:
+ description: Allows access to the skillreset command for maces for other players
mcmmo.commands.skillreset.repair:
description: Allows access to the skillreset command for repair
mcmmo.commands.skillreset.salvage:
@@ -1332,23 +1372,6 @@ permissions:
description: Allows access to the taming command
mcmmo.commands.unarmed:
description: Allows access to the unarmed command
-# mcmmo.commands.vampirism.*:
-# default: false
-# description: Implies access to all mcmmo.commands.vampirism permissions
-# children:
-# mcmmo.commands.vampirism.all: true
-# mcmmo.commands.vampirism.all:
-# description: Implies access to all mcmmo.commands.vampirism permissions
-# children:
-# mcmmo.commands.vampirism: true
-# mcmmo.commands.vampirism.modify: true
-# mcmmo.commands.vampirism.toggle: true
-# mcmmo.commands.vampirism:
-# description: Allows access to the vampirism command
-# mcmmo.commands.vampirism.modify:
-# description: Allows access to the vampirism command to modify the vampirism rate
-# mcmmo.commands.vampirism.toggle:
-# description: Allows access to the vampirism command to toggle vampirism on/off
mcmmo.commands.woodcutting:
description: Allows access to the woodcutting command
mcmmo.commands.xprate.*:
@@ -1482,6 +1505,7 @@ permissions:
mcmmo.perks.lucky.excavation: true
mcmmo.perks.lucky.fishing: true
mcmmo.perks.lucky.herbalism: true
+ mcmmo.perks.lucky.maces: true
mcmmo.perks.lucky.mining: true
mcmmo.perks.lucky.repair: true
mcmmo.perks.lucky.salvage: true
@@ -1490,6 +1514,8 @@ permissions:
mcmmo.perks.lucky.taming: true
mcmmo.perks.lucky.unarmed: true
mcmmo.perks.lucky.woodcutting: true
+ mcmmo.perks.lucky.crossbows: true
+ mcmmo.perks.lucky.tridents: true
mcmmo.perks.lucky.acrobatics:
default: false
description: Gives Acrobatics abilities & skills a 33.3% better chance to activate.
@@ -1514,6 +1540,9 @@ permissions:
mcmmo.perks.lucky.herbalism:
default: false
description: Gives Herbalism abilities & skills a 33.3% better chance to activate.
+ mcmmo.perks.lucky.maces:
+ default: false
+ description: Gives Mining abilities & skills a 33.3% better chance to activate.
mcmmo.perks.lucky.mining:
default: false
description: Gives Mining abilities & skills a 33.3% better chance to activate.
@@ -1580,6 +1609,7 @@ permissions:
mcmmo.perks.xp.150percentboost.excavation: true
mcmmo.perks.xp.150percentboost.fishing: true
mcmmo.perks.xp.150percentboost.herbalism: true
+ mcmmo.perks.xp.150percentboost.maces: true
mcmmo.perks.xp.150percentboost.mining: true
mcmmo.perks.xp.150percentboost.repair: true
mcmmo.perks.xp.150percentboost.smelting: true
@@ -1612,6 +1642,9 @@ permissions:
mcmmo.perks.xp.150percentboost.herbalism:
default: false
description: Multiplies incoming Herbalism XP by 2.5
+ mcmmo.perks.xp.150percentboost.maces:
+ default: false
+ description: Multiplies incoming Maces XP by 2.5
mcmmo.perks.xp.150percentboost.mining:
default: false
description: Multiplies incoming Mining XP by 2.5
@@ -1658,6 +1691,7 @@ permissions:
mcmmo.perks.xp.50percentboost.excavation: true
mcmmo.perks.xp.50percentboost.fishing: true
mcmmo.perks.xp.50percentboost.herbalism: true
+ mcmmo.perks.xp.50percentboost.maces: true
mcmmo.perks.xp.50percentboost.mining: true
mcmmo.perks.xp.50percentboost.repair: true
mcmmo.perks.xp.50percentboost.smelting: true
@@ -1690,6 +1724,9 @@ permissions:
mcmmo.perks.xp.50percentboost.herbalism:
default: false
description: Multiplies incoming Herbalism XP by 1.5
+ mcmmo.perks.xp.50percentboost.maces:
+ default: false
+ description: Multiplies incoming Maces XP by 1.5
mcmmo.perks.xp.50percentboost.mining:
default: false
description: Multiplies incoming Mining XP by 1.5
@@ -1736,6 +1773,7 @@ permissions:
mcmmo.perks.xp.25percentboost.excavation: true
mcmmo.perks.xp.25percentboost.fishing: true
mcmmo.perks.xp.25percentboost.herbalism: true
+ mcmmo.perks.xp.25percentboost.maces: true
mcmmo.perks.xp.25percentboost.mining: true
mcmmo.perks.xp.25percentboost.repair: true
mcmmo.perks.xp.25percentboost.smelting: true
@@ -1768,6 +1806,9 @@ permissions:
mcmmo.perks.xp.25percentboost.herbalism:
default: false
description: Multiplies incoming Herbalism XP by 1.25
+ mcmmo.perks.xp.25percentboost.maces:
+ default: false
+ description: Multiplies incoming Maces XP by 1.25
mcmmo.perks.xp.25percentboost.mining:
default: false
description: Multiplies incoming Mining XP by 1.25
@@ -1814,6 +1855,7 @@ permissions:
mcmmo.perks.xp.10percentboost.excavation: true
mcmmo.perks.xp.10percentboost.fishing: true
mcmmo.perks.xp.10percentboost.herbalism: true
+ mcmmo.perks.xp.10percentboost.maces: true
mcmmo.perks.xp.10percentboost.mining: true
mcmmo.perks.xp.10percentboost.repair: true
mcmmo.perks.xp.10percentboost.smelting: true
@@ -1846,6 +1888,9 @@ permissions:
mcmmo.perks.xp.10percentboost.herbalism:
default: false
description: Multiplies incoming Herbalism XP by 1.1
+ mcmmo.perks.xp.10percentboost.maces:
+ default: false
+ description: Multiplies incoming Maces XP by 1.1
mcmmo.perks.xp.10percentboost.mining:
default: false
description: Multiplies incoming Mining XP by 1.1
@@ -1892,6 +1937,7 @@ permissions:
mcmmo.perks.xp.customboost.excavation: true
mcmmo.perks.xp.customboost.fishing: true
mcmmo.perks.xp.customboost.herbalism: true
+ mcmmo.perks.xp.customboost.maces: true
mcmmo.perks.xp.customboost.mining: true
mcmmo.perks.xp.customboost.repair: true
mcmmo.perks.xp.customboost.smelting: true
@@ -1924,6 +1970,9 @@ permissions:
mcmmo.perks.xp.customboost.herbalism:
default: false
description: Multiplies incoming Herbalism XP by the boost amount defined in the experience config
+ mcmmo.perks.xp.customboost.maces:
+ default: false
+ description: Multiplies incoming Maces XP by the boost amount defined in the experience config
mcmmo.perks.xp.customboost.mining:
default: false
description: Multiplies incoming Mining XP by the boost amount defined in the experience config
@@ -1970,6 +2019,7 @@ permissions:
mcmmo.perks.xp.double.excavation: true
mcmmo.perks.xp.double.fishing: true
mcmmo.perks.xp.double.herbalism: true
+ mcmmo.perks.xp.double.maces: true
mcmmo.perks.xp.double.mining: true
mcmmo.perks.xp.double.repair: true
mcmmo.perks.xp.double.smelting: true
@@ -2002,6 +2052,9 @@ permissions:
mcmmo.perks.xp.double.herbalism:
default: false
description: Doubles incoming Herbalism XP
+ mcmmo.perks.xp.double.maces:
+ default: false
+ description: Doubles incoming Maces XP
mcmmo.perks.xp.double.mining:
default: false
description: Doubles incoming Mining XP
@@ -2048,6 +2101,7 @@ permissions:
mcmmo.perks.xp.quadruple.excavation: true
mcmmo.perks.xp.quadruple.fishing: true
mcmmo.perks.xp.quadruple.herbalism: true
+ mcmmo.perks.xp.quadruple.maces: true
mcmmo.perks.xp.quadruple.mining: true
mcmmo.perks.xp.quadruple.repair: true
mcmmo.perks.xp.quadruple.smelting: true
@@ -2080,6 +2134,9 @@ permissions:
mcmmo.perks.xp.quadruple.herbalism:
default: false
description: Quadruples incoming Herbalism XP
+ mcmmo.perks.xp.quadruple.maces:
+ default: false
+ description: Quadruples incoming Maces XP
mcmmo.perks.xp.quadruple.mining:
default: false
description: Quadruples incoming Mining XP
@@ -2127,6 +2184,7 @@ permissions:
mcmmo.perks.xp.triple.fishing: true
mcmmo.perks.xp.triple.herbalism: true
mcmmo.perks.xp.triple.mining: true
+ mcmmo.perks.xp.triple.maces: true
mcmmo.perks.xp.triple.repair: true
mcmmo.perks.xp.triple.smelting: true
mcmmo.perks.xp.triple.swords: true
@@ -2158,6 +2216,9 @@ permissions:
mcmmo.perks.xp.triple.herbalism:
default: false
description: Triples incoming Herbalism XP
+ mcmmo.perks.xp.triple.maces:
+ default: false
+ description: Triples incoming Maces XP
mcmmo.perks.xp.triple.mining:
default: false
description: Triples incoming Mining XP
@@ -2203,6 +2264,7 @@ permissions:
mcmmo.skills.excavation: true
mcmmo.skills.fishing: true
mcmmo.skills.herbalism: true
+ mcmmo.skill.maces: true
mcmmo.skills.mining: true
mcmmo.skills.repair: true
mcmmo.skills.salvage: true
@@ -2283,6 +2345,11 @@ permissions:
children:
mcmmo.ability.taming.all: true
mcmmo.commands.taming: true
+ mcmmo.skills.maces:
+ description: Allows access to the Maces skill
+ children:
+ mcmmo.ability.maces.all: true
+ mcmmo.commands.maces: true
mcmmo.skills.tridents:
description: Allows access to the Tridents skill
children:
diff --git a/src/main/resources/repair.vanilla.yml b/src/main/resources/repair.vanilla.yml
index 72ba687bd..52165805f 100644
--- a/src/main/resources/repair.vanilla.yml
+++ b/src/main/resources/repair.vanilla.yml
@@ -284,4 +284,12 @@ Repairables:
ItemMaterialCategory: OTHER
RepairMaterial: PRISMARINE_CRYSTALS
MinimumQuantity: 16
+ MaximumDurability: 250
+ MACE:
+ MinimumLevel: 0
+ XpMultiplier: 3
+ ItemType: TOOL
+ ItemMaterialCategory: OTHER
+ RepairMaterial: BREEZE_ROD
+ MinimumQuantity: 4
MaximumDurability: 250
\ No newline at end of file
diff --git a/src/main/resources/skillranks.yml b/src/main/resources/skillranks.yml
index e6cea3643..66e2cb06e 100644
--- a/src/main/resources/skillranks.yml
+++ b/src/main/resources/skillranks.yml
@@ -444,28 +444,51 @@ Salvage:
Rank_7: 850
Rank_8: 1000
Maces:
- Standard:
- Rank_1: 10
- Rank_2: 20
- Rank_3: 30
- Rank_4: 40
- Rank_5: 50
- Rank_6: 60
- Rank_7: 70
- Rank_8: 80
- Rank_9: 90
- Rank_10: 100
- RetroMode:
- Rank_1: 100
- Rank_2: 200
- Rank_3: 300
- Rank_4: 400
- Rank_5: 500
- Rank_6: 600
- Rank_7: 700
- Rank_8: 800
- Rank_9: 900
- Rank_10: 1000
+ MacesLimitBreak:
+ Standard:
+ Rank_1: 10
+ Rank_2: 20
+ Rank_3: 30
+ Rank_4: 40
+ Rank_5: 50
+ Rank_6: 60
+ Rank_7: 70
+ Rank_8: 80
+ Rank_9: 90
+ Rank_10: 100
+ RetroMode:
+ Rank_1: 100
+ Rank_2: 200
+ Rank_3: 300
+ Rank_4: 400
+ Rank_5: 500
+ Rank_6: 600
+ Rank_7: 700
+ Rank_8: 800
+ Rank_9: 900
+ Rank_10: 1000
+ Cripple:
+ Standard:
+ Rank_1: 5
+ Rank_2: 20
+ Rank_3: 40
+ Rank_4: 80
+ RetroMode:
+ Rank_1: 50
+ Rank_2: 200
+ Rank_3: 400
+ Rank_4: 800
+ Crush:
+ Standard:
+ Rank_1: 10
+ Rank_2: 25
+ Rank_3: 75
+ Rank_4: 90
+ RetroMode:
+ Rank_1: 100
+ Rank_2: 250
+ Rank_3: 750
+ Rank_4: 900
Mining:
MotherLode:
Standard:
diff --git a/src/main/resources/sounds.yml b/src/main/resources/sounds.yml
index 8f88c574f..b6d4fcba4 100644
--- a/src/main/resources/sounds.yml
+++ b/src/main/resources/sounds.yml
@@ -67,4 +67,8 @@ Sounds:
BLEED:
Enable: true
Volume: 2.0
- Pitch: 2.0
\ No newline at end of file
+ Pitch: 2.0
+ CRIPPLE:
+ Enable: true
+ Volume: 1.0
+ Pitch: 0.5
\ No newline at end of file
diff --git a/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java b/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
index 984c5f123..3baa1a98d 100644
--- a/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
+++ b/src/test/java/com/gmail/nossr50/MMOTestEnvironment.java
@@ -13,6 +13,8 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.util.*;
import com.gmail.nossr50.util.blockmeta.ChunkManager;
+import com.gmail.nossr50.util.compat.CompatibilityManager;
+import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillTools;
@@ -67,8 +69,16 @@ public abstract class MMOTestEnvironment {
protected ChunkManager chunkManager;
protected MaterialMapStore materialMapStore;
+ protected CompatibilityManager compatibilityManager;
+
protected void mockBaseEnvironment(Logger logger) throws InvalidSkillException {
+ compatibilityManager = mock(CompatibilityManager.class);
+ final MinecraftGameVersion minecraftGameVersion = mock(MinecraftGameVersion.class);
+ when(compatibilityManager.getMinecraftGameVersion()).thenReturn(minecraftGameVersion);
+ // TODO: We should change minecraftGameVersion to be a passed in parameter instead of always returning true
+ when(minecraftGameVersion.isAtLeast(anyInt(), anyInt(), anyInt())).thenReturn(true);
mockedMcMMO = mockStatic(mcMMO.class);
+ when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
mcMMO.p = mock(mcMMO.class);
when(mcMMO.p.getLogger()).thenReturn(logger);
diff --git a/src/test/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingTest.java b/src/test/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingTest.java
index 01c7c1549..06eecb43b 100644
--- a/src/test/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingTest.java
+++ b/src/test/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingTest.java
@@ -17,9 +17,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;