mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-25 02:04:44 +02:00

committed by
GitHub

parent
02c732bdf2
commit
971e5da0ad
@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class McrankCommand implements TabExecutor {
|
||||
public class McRankCommand implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
switch (args.length) {
|
@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MctopCommand implements TabExecutor {
|
||||
public class McTopCommand implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
PrimarySkillType skill = null;
|
||||
@ -44,6 +44,12 @@ public class MctopCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the command is for Maces but the MC version is not correct
|
||||
if (skill == PrimarySkillType.MACES
|
||||
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
display(1, skill, sender, command);
|
||||
return true;
|
||||
|
||||
@ -58,6 +64,12 @@ public class MctopCommand implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if the command is for Maces but the MC version is not correct
|
||||
if (skill == PrimarySkillType.MACES
|
||||
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
display(Math.abs(Integer.parseInt(args[1])), skill, sender, command);
|
||||
return true;
|
||||
|
@ -1,52 +1,81 @@
|
||||
//package com.gmail.nossr50.commands.skills;
|
||||
//
|
||||
//import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
//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.text.TextComponentFactory;
|
||||
//import net.kyori.adventure.text.Component;
|
||||
//import org.bukkit.ChatColor;
|
||||
//import org.bukkit.entity.Player;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//
|
||||
//import static com.gmail.nossr50.datatypes.skills.SubSkillType.MACES_MACES_LIMIT_BREAK;
|
||||
//
|
||||
//public class MacesCommand extends SkillCommand {
|
||||
//
|
||||
// public MacesCommand() {
|
||||
// super(PrimarySkillType.MACES);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void dataCalculations(Player player, float skillValue) {}
|
||||
//
|
||||
// @Override
|
||||
// protected void permissionsCheck(Player player) {}
|
||||
//
|
||||
// @Override
|
||||
// protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
|
||||
// List<String> messages = new ArrayList<>();
|
||||
//
|
||||
// if (SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
|
||||
// messages.add(getStatMessage(MACES_MACES_LIMIT_BREAK,
|
||||
// String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, MACES_MACES_LIMIT_BREAK, 1000))));
|
||||
// }
|
||||
//
|
||||
// messages.add(ChatColor.GRAY + "The Maces skill is a work in progress and is still being developed," +
|
||||
// " feedback would be appreciated in the mcMMO discord server.");
|
||||
// return messages;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected List<Component> getTextComponents(Player player) {
|
||||
// List<Component> textComponents = new ArrayList<>();
|
||||
//
|
||||
// TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.MACES);
|
||||
//
|
||||
// return textComponents;
|
||||
// }
|
||||
//}
|
||||
package com.gmail.nossr50.commands.skills;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.maces.MacesManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
import com.gmail.nossr50.util.text.TextComponentFactory;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.gmail.nossr50.datatypes.skills.SubSkillType.MACES_CRIPPLE;
|
||||
import static com.gmail.nossr50.datatypes.skills.SubSkillType.MACES_MACES_LIMIT_BREAK;
|
||||
|
||||
public class MacesCommand extends SkillCommand {
|
||||
|
||||
public MacesCommand() {
|
||||
super(PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
String crippleChanceToApply, crippleChanceToApplyLucky, crippleLengthAgainstPlayers, crippleLengthAgainstMobs;
|
||||
|
||||
@Override
|
||||
protected void dataCalculations(Player player, float skillValue) {
|
||||
if (SkillUtils.canUseSubskill(player, MACES_CRIPPLE)) {
|
||||
int crippleRank = RankUtils.getRank(player, MACES_CRIPPLE);
|
||||
crippleLengthAgainstPlayers = String.valueOf(MacesManager.getCrippleTickDuration(true) / 20.0D);
|
||||
crippleLengthAgainstMobs = String.valueOf(MacesManager.getCrippleTickDuration(false) / 20.0D);
|
||||
|
||||
crippleChanceToApply = String.valueOf(mcMMO.p.getAdvancedConfig().getCrippleChanceToApplyOnHit(crippleRank) + "%");
|
||||
crippleChanceToApplyLucky = String.valueOf(mcMMO.p.getAdvancedConfig().getCrippleChanceToApplyOnHit(crippleRank) * 1.33);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void permissionsCheck(Player player) {}
|
||||
|
||||
@Override
|
||||
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
|
||||
final List<String> messages = new ArrayList<>();
|
||||
|
||||
if (SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
|
||||
messages.add(getStatMessage(MACES_MACES_LIMIT_BREAK,
|
||||
String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player,
|
||||
MACES_MACES_LIMIT_BREAK, 1000))));
|
||||
}
|
||||
|
||||
if (SkillUtils.canUseSubskill(player, MACES_CRIPPLE)) {
|
||||
messages.add(getStatMessage(MACES_CRIPPLE, crippleChanceToApply)
|
||||
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", crippleChanceToApplyLucky) : ""));
|
||||
messages.add(getStatMessage(true, true, MACES_CRIPPLE,
|
||||
crippleLengthAgainstPlayers,
|
||||
crippleLengthAgainstMobs));
|
||||
}
|
||||
|
||||
if (SkillUtils.canUseSubskill(player, SubSkillType.MACES_CRUSH)) {
|
||||
messages.add(getStatMessage(SubSkillType.MACES_CRUSH,
|
||||
String.valueOf(mmoPlayer.getMacesManager().getCrushDamage())));
|
||||
}
|
||||
|
||||
messages.add(ChatColor.GRAY + "The Maces skill is a work in progress and is still being developed," +
|
||||
" feedback would be appreciated in the mcMMO discord server.");
|
||||
return messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Component> getTextComponents(Player player) {
|
||||
List<Component> textComponents = new ArrayList<>();
|
||||
|
||||
TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.MACES);
|
||||
|
||||
return textComponents;
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AdvancedConfig extends BukkitConfig {
|
||||
int[] defaultCrippleValues = new int[]{10, 15, 20, 25};
|
||||
|
||||
public AdvancedConfig(File dataFolder) {
|
||||
super("advanced.yml", dataFolder);
|
||||
@ -937,4 +938,10 @@ public class AdvancedConfig extends BukkitConfig {
|
||||
public boolean isKnockOnWoodXPOrbEnabled() {
|
||||
return config.getBoolean("Skills.Woodcutting.TreeFeller.Knock_On_Wood.Add_XP_Orbs_To_Drops", true);
|
||||
}
|
||||
|
||||
/* MACES */
|
||||
public double getCrippleChanceToApplyOnHit(int rank) {
|
||||
String root = "Skills.Maces.Cripple.Chance_To_Apply_On_Hit.Rank_";
|
||||
return config.getDouble(root + rank, defaultCrippleValues[rank-1]);
|
||||
}
|
||||
}
|
||||
|
@ -547,6 +547,10 @@ public class GeneralConfig extends BukkitConfig {
|
||||
return config.getBoolean("Particles.Bleed", true);
|
||||
}
|
||||
|
||||
public boolean getCrippleEffectEnabled() {
|
||||
return config.getBoolean("Particles.Cripple", true);
|
||||
}
|
||||
|
||||
public boolean getDodgeEffectEnabled() {
|
||||
return config.getBoolean("Particles.Dodge", true);
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ public class SoundConfig extends BukkitConfig {
|
||||
|
||||
public float getVolume(SoundType soundType) {
|
||||
String key = "Sounds." + soundType.toString() + ".Volume";
|
||||
return (float) config.getDouble(key);
|
||||
return (float) config.getDouble(key, 1.0);
|
||||
}
|
||||
|
||||
public float getPitch(SoundType soundType) {
|
||||
String key = "Sounds." + soundType.toString() + ".Pitch";
|
||||
return (float) config.getDouble(key);
|
||||
return (float) config.getDouble(key, 1.0);
|
||||
}
|
||||
|
||||
public boolean getIsEnabled(SoundType soundType) {
|
||||
|
@ -112,7 +112,6 @@ public class McMMOPlayer implements Identified {
|
||||
private int respawnATS;
|
||||
private int teleportATS;
|
||||
private long databaseATS;
|
||||
private double attackStrength; //captured during arm swing events
|
||||
//private int chimeraWingLastUse;
|
||||
private Location teleportCommence;
|
||||
|
||||
@ -151,7 +150,6 @@ public class McMMOPlayer implements Identified {
|
||||
experienceBarManager = new ExperienceBarManager(this);
|
||||
|
||||
debugMode = false; //Debug mode helps solve support issues, players can toggle it on or off
|
||||
attackStrength = 1.0D;
|
||||
|
||||
this.playerAuthor = new PlayerAuthor(player);
|
||||
|
||||
@ -227,7 +225,9 @@ public class McMMOPlayer implements Identified {
|
||||
skillManagers.put(primarySkillType, new WoodcuttingManager(this));
|
||||
break;
|
||||
case MACES:
|
||||
skillManagers.put(primarySkillType, new MacesManager(this));
|
||||
if (mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
|
||||
skillManagers.put(primarySkillType, new MacesManager(this));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new InvalidSkillException("The skill named has no manager! Contact the devs!");
|
||||
@ -239,7 +239,7 @@ public class McMMOPlayer implements Identified {
|
||||
}
|
||||
|
||||
public double getAttackStrength() {
|
||||
return attackStrength;
|
||||
return player.getAttackCooldown();
|
||||
}
|
||||
|
||||
public @NotNull PrimarySkillType getLastSkillShownScoreboard() {
|
||||
|
@ -59,6 +59,8 @@ public enum SubSkillType {
|
||||
|
||||
/* Maces */
|
||||
MACES_MACES_LIMIT_BREAK(10),
|
||||
MACES_CRUSH(4),
|
||||
MACES_CRIPPLE(4),
|
||||
|
||||
/* Mining */
|
||||
MINING_BIGGER_BOMBS(1),
|
||||
|
@ -162,6 +162,9 @@ public class mcMMO extends JavaPlugin {
|
||||
//Filter out any debug messages (if debug/verbose logging is not enabled)
|
||||
getLogger().setFilter(new LogFilter(this));
|
||||
|
||||
//Platform Manager
|
||||
platformManager = new PlatformManager();
|
||||
|
||||
//Folia lib plugin instance
|
||||
foliaLib = new FoliaLib(this);
|
||||
InvalidTickDelayNotifier.disableNotifications = true;
|
||||
@ -178,9 +181,6 @@ public class mcMMO extends JavaPlugin {
|
||||
//Store this value so other plugins can check it
|
||||
isRetroModeEnabled = generalConfig.getIsRetroMode();
|
||||
|
||||
//Platform Manager
|
||||
platformManager = new PlatformManager();
|
||||
|
||||
MetadataConstants.MCMMO_METADATA_VALUE = new FixedMetadataValue(this, true);
|
||||
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
|
@ -310,6 +310,7 @@ public final class PartyManager {
|
||||
* @param party The party to remove
|
||||
* @deprecated Use {@link #disbandParty(McMMOPlayer, Party)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void disbandParty(@NotNull Party party) {
|
||||
requireNonNull(party, "party cannot be null!");
|
||||
disbandParty(null, party);
|
||||
|
@ -32,7 +32,7 @@ public class McRankCommandAsyncTask extends CancellableRunnable {
|
||||
public void run() {
|
||||
Map<PrimarySkillType, Integer> skills = mcMMO.getDatabaseManager().readRank(playerName);
|
||||
|
||||
mcMMO.p.getFoliaLib().getImpl().runNextTick(new McrankCommandDisplayTask(skills, sender, playerName, useBoard, useChat));
|
||||
mcMMO.p.getFoliaLib().getImpl().runNextTick(new McRankCommandDisplayTask(skills, sender, playerName, useBoard, useChat));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,14 @@ import java.util.Map;
|
||||
/**
|
||||
* Display the results of McrankCommandAsyncTask to the sender.
|
||||
*/
|
||||
public class McrankCommandDisplayTask extends CancellableRunnable {
|
||||
public class McRankCommandDisplayTask extends CancellableRunnable {
|
||||
private final Map<PrimarySkillType, Integer> skills;
|
||||
private final CommandSender sender;
|
||||
private final String playerName;
|
||||
private final boolean useBoard, useChat;
|
||||
|
||||
McrankCommandDisplayTask(Map<PrimarySkillType, Integer> skills, CommandSender sender, String playerName, boolean useBoard, boolean useChat) {
|
||||
McRankCommandDisplayTask(Map<PrimarySkillType, Integer> skills, CommandSender sender, String playerName,
|
||||
boolean useBoard, boolean useChat) {
|
||||
this.skills = skills;
|
||||
this.sender = sender;
|
||||
this.playerName = playerName;
|
||||
@ -42,17 +43,17 @@ public class McrankCommandDisplayTask extends CancellableRunnable {
|
||||
}
|
||||
|
||||
private void displayChat() {
|
||||
// Player player = mcMMO.p.getServer().getPlayerExact(playerName);
|
||||
Integer rank;
|
||||
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
|
||||
|
||||
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
|
||||
// if (!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, skill)) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// Check if the command is for Maces but the MC version is not correct
|
||||
if (skill == PrimarySkillType.MACES
|
||||
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
|
||||
continue;
|
||||
}
|
||||
rank = skills.get(skill);
|
||||
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", mcMMO.p.getSkillTools().getLocalizedSkillName(skill), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
|
||||
}
|
@ -22,6 +22,9 @@ import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.gmail.nossr50.util.random.ProbabilityUtil.isSkillRNGSuccessful;
|
||||
import static com.gmail.nossr50.util.skills.SkillUtils.handleArmorDurabilityChange;
|
||||
|
||||
public class AxesManager extends SkillManager {
|
||||
public AxesManager(McMMOPlayer mcMMOPlayer) {
|
||||
super(mcMMOPlayer, PrimarySkillType.AXES);
|
||||
@ -84,7 +87,7 @@ public class AxesManager extends SkillManager {
|
||||
* @param damage The amount of damage initially dealt by the event
|
||||
*/
|
||||
public double criticalHit(LivingEntity target, double damage) {
|
||||
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_CRITICAL_STRIKES, mmoPlayer)) {
|
||||
if (!isSkillRNGSuccessful(SubSkillType.AXES_CRITICAL_STRIKES, mmoPlayer, mmoPlayer.getAttackStrength())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -123,8 +126,8 @@ public class AxesManager extends SkillManager {
|
||||
|
||||
for (ItemStack armor : equipment.getArmorContents()) {
|
||||
if (armor != null && ItemUtils.isArmor(armor)) {
|
||||
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_ARMOR_IMPACT, mmoPlayer)) {
|
||||
SkillUtils.handleArmorDurabilityChange(armor, durabilityDamage, 1);
|
||||
if (isSkillRNGSuccessful(SubSkillType.AXES_ARMOR_IMPACT, mmoPlayer, mmoPlayer.getAttackStrength())) {
|
||||
handleArmorDurabilityChange(armor, durabilityDamage, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,15 +143,15 @@ public class AxesManager extends SkillManager {
|
||||
* @param target The {@link LivingEntity} being affected by the ability
|
||||
*/
|
||||
public double greaterImpact(@NotNull LivingEntity target) {
|
||||
//static chance (3rd param)
|
||||
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_GREATER_IMPACT, mmoPlayer)) {
|
||||
if (!isSkillRNGSuccessful(SubSkillType.AXES_GREATER_IMPACT, mmoPlayer, mmoPlayer.getAttackStrength())) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Player player = getPlayer();
|
||||
|
||||
ParticleEffectUtils.playGreaterImpactEffect(target);
|
||||
target.setVelocity(player.getLocation().getDirection().normalize().multiply(Axes.greaterImpactKnockbackMultiplier));
|
||||
target.setVelocity(
|
||||
player.getLocation().getDirection().normalize().multiply(Axes.greaterImpactKnockbackMultiplier));
|
||||
|
||||
if (mmoPlayer.useChatNotifications()) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Axes.Combat.GI.Proc");
|
||||
@ -170,6 +173,6 @@ public class AxesManager extends SkillManager {
|
||||
* @param damage The amount of damage initially dealt by the event
|
||||
*/
|
||||
public void skullSplitterCheck(@NotNull LivingEntity target, double damage) {
|
||||
CombatUtils.applyAbilityAoE(getPlayer(), target, damage / Axes.skullSplitterModifier, skill);
|
||||
CombatUtils.applyAbilityAoE(getPlayer(), target, (damage / Axes.skullSplitterModifier) * mmoPlayer.getAttackStrength(), skill);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,114 @@
|
||||
package com.gmail.nossr50.skills.maces;
|
||||
|
||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.random.ProbabilityUtil;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class MacesManager extends SkillManager {
|
||||
private static @Nullable PotionEffectType slowEffectType;
|
||||
|
||||
public MacesManager(McMMOPlayer mmoPlayer) {
|
||||
super(mmoPlayer, PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
private static @Nullable PotionEffectType mockSpigotMatch(@NotNull String input) {
|
||||
// Replicates match() behaviour for older versions lacking this API
|
||||
final String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_");
|
||||
final NamespacedKey namespacedKey = NamespacedKey.fromString(filtered);
|
||||
return (namespacedKey != null) ? Registry.EFFECT.get(namespacedKey) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Crush damage bonus.
|
||||
*
|
||||
* @return the Crush damage bonus.
|
||||
*/
|
||||
public double getCrushDamage() {
|
||||
if (!Permissions.canUseSubSkill(mmoPlayer.getPlayer(), SubSkillType.MACES_CRUSH))
|
||||
return 0;
|
||||
|
||||
int rank = RankUtils.getRank(getPlayer(), SubSkillType.MACES_CRUSH);
|
||||
|
||||
if (rank > 0) {
|
||||
return (0.5D + (rank * 1.D));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Cripple attack.
|
||||
*
|
||||
* @param target The defending entity
|
||||
*/
|
||||
public void processCripple(@NotNull LivingEntity target) {
|
||||
// Lazy initialized to avoid some backwards compatibility issues
|
||||
if (slowEffectType == null) {
|
||||
if (mockSpigotMatch("slowness") == null) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Slowness PotionEffectType, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Slowness PotionEffectType!");
|
||||
} else {
|
||||
slowEffectType = mockSpigotMatch("slowness");
|
||||
}
|
||||
}
|
||||
|
||||
boolean isPlayerTarget = target instanceof Player;
|
||||
// Don't apply Cripple if the target is already Slowed
|
||||
if (slowEffectType == null || target.getPotionEffect(slowEffectType) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Permissions.canUseSubSkill(mmoPlayer.getPlayer(), SubSkillType.MACES_CRIPPLE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int crippleRank = RankUtils.getRank(getPlayer(), SubSkillType.MACES_CRIPPLE);
|
||||
double crippleOdds = (mcMMO.p.getAdvancedConfig().getCrippleChanceToApplyOnHit(crippleRank)
|
||||
* mmoPlayer.getAttackStrength());
|
||||
|
||||
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.MACES, mmoPlayer, crippleOdds)) {
|
||||
if (mmoPlayer.useChatNotifications()) {
|
||||
NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(),
|
||||
NotificationType.SUBSKILL_MESSAGE, "Maces.SubSkill.Cripple.Activated");
|
||||
}
|
||||
|
||||
// Cripple is success, Cripple the target
|
||||
target.addPotionEffect(slowEffectType.createEffect(
|
||||
getCrippleTickDuration(isPlayerTarget),
|
||||
getCrippleStrength(isPlayerTarget)));
|
||||
ParticleEffectUtils.playCrippleEffect(target);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCrippleTickDuration(boolean isPlayerTarget) {
|
||||
// TODO: Make configurable
|
||||
if (isPlayerTarget) {
|
||||
return 20;
|
||||
} else {
|
||||
return 30;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCrippleStrength(boolean isPlayerTarget) {
|
||||
// TODO: Make configurable
|
||||
return isPlayerTarget ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,8 @@ public class SwordsManager extends SkillManager {
|
||||
return; //Don't apply bleed
|
||||
}
|
||||
|
||||
double ruptureOdds = mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(getRuptureRank());
|
||||
double ruptureOdds = mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(getRuptureRank())
|
||||
* mmoPlayer.getAttackStrength();
|
||||
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SWORDS, mmoPlayer, ruptureOdds)) {
|
||||
|
||||
if (target instanceof Player defender) {
|
||||
|
@ -22,6 +22,8 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.gmail.nossr50.util.random.ProbabilityUtil.isSkillRNGSuccessful;
|
||||
|
||||
public class UnarmedManager extends SkillManager {
|
||||
|
||||
public UnarmedManager(McMMOPlayer mcMMOPlayer) {
|
||||
@ -98,7 +100,8 @@ public class UnarmedManager extends SkillManager {
|
||||
* @param defender The defending player
|
||||
*/
|
||||
public void disarmCheck(@NotNull Player defender) {
|
||||
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_DISARM, mmoPlayer) && !hasIronGrip(defender)) {
|
||||
if (isSkillRNGSuccessful(SubSkillType.UNARMED_DISARM, mmoPlayer, mmoPlayer.getAttackStrength())
|
||||
&& !hasIronGrip(defender)) {
|
||||
if (EventUtils.callDisarmEvent(defender).isCancelled()) {
|
||||
return;
|
||||
}
|
||||
@ -121,7 +124,7 @@ public class UnarmedManager extends SkillManager {
|
||||
* Check for arrow deflection.
|
||||
*/
|
||||
public boolean deflectCheck() {
|
||||
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_ARROW_DEFLECT, mmoPlayer)) {
|
||||
if (isSkillRNGSuccessful(SubSkillType.UNARMED_ARROW_DEFLECT, mmoPlayer)) {
|
||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.ArrowDeflect");
|
||||
return true;
|
||||
}
|
||||
@ -178,7 +181,7 @@ public class UnarmedManager extends SkillManager {
|
||||
private boolean hasIronGrip(@NotNull Player defender) {
|
||||
if (!Misc.isNPCEntityExcludingVillagers(defender)
|
||||
&& Permissions.isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP)
|
||||
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_IRON_GRIP, UserManager.getPlayer(defender))) {
|
||||
&& isSkillRNGSuccessful(SubSkillType.UNARMED_IRON_GRIP, UserManager.getPlayer(defender))) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Defender");
|
||||
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Attacker");
|
||||
|
||||
|
@ -32,95 +32,47 @@ public final class CommandRegistrationManager {
|
||||
private static final String permissionsMessage = LocaleLoader.getString("mcMMO.NoPermission");
|
||||
|
||||
private static void registerSkillCommands() {
|
||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
||||
if (skill == PrimarySkillType.MACES)
|
||||
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
|
||||
if (primarySkillType == PrimarySkillType.MACES
|
||||
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 21, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
|
||||
final String commandName = primarySkillType.toString().toLowerCase(Locale.ENGLISH);
|
||||
final String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
PluginCommand command;
|
||||
final PluginCommand command = mcMMO.p.getCommand(commandName);
|
||||
if (command == null) {
|
||||
mcMMO.p.getLogger().severe("Command not found: " + commandName);
|
||||
continue;
|
||||
}
|
||||
|
||||
command = mcMMO.p.getCommand(commandName);
|
||||
command.setDescription(LocaleLoader.getString("Commands.Description.Skill", StringUtils.getCapitalized(localizedName)));
|
||||
command.setPermission("mcmmo.commands." + commandName);
|
||||
command.setPermissionMessage(permissionsMessage);
|
||||
command.setUsage(LocaleLoader.getString("Commands.Usage.0", commandName));
|
||||
command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.2", commandName, "?", "[" + LocaleLoader.getString("Commands.Usage.Page") + "]"));
|
||||
|
||||
switch (skill) {
|
||||
case ACROBATICS:
|
||||
command.setExecutor(new AcrobaticsCommand());
|
||||
break;
|
||||
|
||||
case ALCHEMY:
|
||||
command.setExecutor(new AlchemyCommand());
|
||||
break;
|
||||
|
||||
case ARCHERY:
|
||||
command.setExecutor(new ArcheryCommand());
|
||||
break;
|
||||
|
||||
case AXES:
|
||||
command.setExecutor(new AxesCommand());
|
||||
break;
|
||||
case CROSSBOWS:
|
||||
command.setExecutor(new CrossbowsCommand());
|
||||
break;
|
||||
|
||||
case EXCAVATION:
|
||||
command.setExecutor(new ExcavationCommand());
|
||||
break;
|
||||
|
||||
case FISHING:
|
||||
command.setExecutor(new FishingCommand());
|
||||
break;
|
||||
|
||||
case HERBALISM:
|
||||
command.setExecutor(new HerbalismCommand());
|
||||
break;
|
||||
|
||||
case MACES:
|
||||
// command.setExecutor(new MacesCommand());
|
||||
break;
|
||||
|
||||
case MINING:
|
||||
command.setExecutor(new MiningCommand());
|
||||
break;
|
||||
|
||||
case REPAIR:
|
||||
command.setExecutor(new RepairCommand());
|
||||
break;
|
||||
|
||||
case SALVAGE:
|
||||
command.setExecutor(new SalvageCommand());
|
||||
break;
|
||||
|
||||
case SMELTING:
|
||||
command.setExecutor(new SmeltingCommand());
|
||||
break;
|
||||
|
||||
case SWORDS:
|
||||
command.setExecutor(new SwordsCommand());
|
||||
break;
|
||||
|
||||
case TAMING:
|
||||
command.setExecutor(new TamingCommand());
|
||||
break;
|
||||
case TRIDENTS:
|
||||
command.setExecutor(new TridentsCommand());
|
||||
break;
|
||||
|
||||
case UNARMED:
|
||||
command.setExecutor(new UnarmedCommand());
|
||||
break;
|
||||
|
||||
case WOODCUTTING:
|
||||
command.setExecutor(new WoodcuttingCommand());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + skill);
|
||||
switch (primarySkillType) {
|
||||
case ACROBATICS -> command.setExecutor(new AcrobaticsCommand());
|
||||
case ALCHEMY -> command.setExecutor(new AlchemyCommand());
|
||||
case ARCHERY -> command.setExecutor(new ArcheryCommand());
|
||||
case AXES -> command.setExecutor(new AxesCommand());
|
||||
case CROSSBOWS -> command.setExecutor(new CrossbowsCommand());
|
||||
case EXCAVATION -> command.setExecutor(new ExcavationCommand());
|
||||
case FISHING -> command.setExecutor(new FishingCommand());
|
||||
case HERBALISM -> command.setExecutor(new HerbalismCommand());
|
||||
case MACES -> command.setExecutor(new MacesCommand());
|
||||
case MINING -> command.setExecutor(new MiningCommand());
|
||||
case REPAIR -> command.setExecutor(new RepairCommand());
|
||||
case SALVAGE -> command.setExecutor(new SalvageCommand());
|
||||
case SMELTING -> command.setExecutor(new SmeltingCommand());
|
||||
case SWORDS -> command.setExecutor(new SwordsCommand());
|
||||
case TAMING -> command.setExecutor(new TamingCommand());
|
||||
case TRIDENTS -> command.setExecutor(new TridentsCommand());
|
||||
case UNARMED -> command.setExecutor(new UnarmedCommand());
|
||||
case WOODCUTTING -> command.setExecutor(new WoodcuttingCommand());
|
||||
default -> throw new IllegalStateException("Unexpected value: " + primarySkillType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,7 +215,7 @@ public final class CommandRegistrationManager {
|
||||
command.setPermission("mcmmo.commands.mcrank;mcmmo.commands.mcrank.others;mcmmo.commands.mcrank.others.far;mcmmo.commands.mcrank.others.offline");
|
||||
command.setPermissionMessage(permissionsMessage);
|
||||
command.setUsage(LocaleLoader.getString("Commands.Usage.1", "mcrank", "[" + LocaleLoader.getString("Commands.Usage.Player") + "]"));
|
||||
command.setExecutor(new McrankCommand());
|
||||
command.setExecutor(new McRankCommand());
|
||||
}
|
||||
|
||||
private static void registerMcstatsCommand() {
|
||||
@ -281,7 +233,7 @@ public final class CommandRegistrationManager {
|
||||
command.setPermission("mcmmo.commands.mctop"); // Only need the main one, not the individual skill ones
|
||||
command.setPermissionMessage(permissionsMessage);
|
||||
command.setUsage(LocaleLoader.getString("Commands.Usage.2", "mctop", "[" + LocaleLoader.getString("Commands.Usage.Skill") + "]", "[" + LocaleLoader.getString("Commands.Usage.Page") + "]"));
|
||||
command.setExecutor(new MctopCommand());
|
||||
command.setExecutor(new McTopCommand());
|
||||
}
|
||||
|
||||
private static void registerMcpurgeCommand() {
|
||||
|
@ -216,13 +216,14 @@ public final class CommandUtils {
|
||||
return LocaleLoader.getString("Skills.Stats", LocaleLoader.getString(StringUtils.getCapitalized(skill.toString()) + ".Listener") + " ", profile.getSkillLevel(skill), profile.getSkillXpLevel(skill), profile.getXpToLevel(skill));
|
||||
}
|
||||
|
||||
private static void printGroupedSkillData(Player inspectTarget, CommandSender display, String header, List<PrimarySkillType> skillGroup) {
|
||||
private static void printGroupedSkillData(Player inspectTarget, CommandSender display,
|
||||
String header, List<PrimarySkillType> skillGroup) {
|
||||
if (UserManager.getPlayer(inspectTarget) == null)
|
||||
return;
|
||||
|
||||
PlayerProfile profile = UserManager.getPlayer(inspectTarget).getProfile();
|
||||
final PlayerProfile profile = UserManager.getPlayer(inspectTarget).getProfile();
|
||||
|
||||
List<String> displayData = new ArrayList<>();
|
||||
final List<String> displayData = new ArrayList<>();
|
||||
displayData.add(header);
|
||||
|
||||
for (PrimarySkillType primarySkillType : skillGroup) {
|
||||
|
@ -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() {
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
* <p>
|
||||
* 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}
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* 2) Determine whether to use Lucky multiplier and influence the outcome
|
||||
* <p>
|
||||
* 3)
|
||||
* Creates a {@link Probability} and pipes it to {@link ProbabilityUtil} which processes the result and returns it
|
||||
* <p>
|
||||
* 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.
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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<String> LOCALIZED_SKILL_NAMES;
|
||||
public final @NotNull ImmutableList<String> FORMATTED_SUBSKILL_NAMES;
|
||||
public final @NotNull ImmutableSet<String> 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,
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ public enum SoundType {
|
||||
BLEED,
|
||||
GLASS,
|
||||
ITEM_CONSUMED,
|
||||
CRIPPLE,
|
||||
TIRED;
|
||||
|
||||
public boolean usesCustomPitch() {
|
||||
|
Reference in New Issue
Block a user