Fixed possible NPE in our events, and BrewingStands now remember who last interacted with them, this allows for hoppers to be used with Alchemy Fixes #5004 Fixes #4958 Fixes #4641

This commit is contained in:
nossr50 2024-05-12 14:09:00 -07:00
parent 17052861d1
commit 3ba6b93135
80 changed files with 1137 additions and 797 deletions

View File

@ -1,3 +1,42 @@
Version 2.2.010
Fixed rare NPE in mcMMO events when player data was unable to be retrieved
Fixed a NPE that could happen when damaging armor with Axes
Fixed a bug where Alchemy brewing would be cancelled if the player died
(API) Added getMcMMOPlayer() to McMMOPlayerSkillEvent
(API) Added new ctor McMMOPlayerSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType)
(API) Deprecated ctor McMMOPlayerSkillEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Added ctor McMMOPlayerAbilityEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Deprecated ctor McMMOPlayerAbilityEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Deprecated ctor McMMOPlayerAbilityActivateEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Added ctor McMMOPlayerAbilityActivateEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Deprecated ctor McMMOPlayerCatalysisEvent(org.bukkit.entity.Player, double)
(API) Added ctor McMMOPlayerCatalysisEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, double)
(API) Deprecated util method EventUtils.callPlayerAbilityActivateEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Added util method EventUtils.callPlayerAbilityActivateEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Deprecated ctor McMMOPlayerFishingEvent(org.bukkit.entity.Player)
(API) Added ctor McMMOPlayerFishingEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer)
(API) Deprecated ctor McMMOPlayerFishingTreasureEvent.McMMOPlayerFishingTreasureEvent(org.bukkit.entity.Player, org.bukkit.inventory.ItemStack, int)
(API) Added ctor McMMOPlayerFishingTreasureEvent.McMMOPlayerFishingTreasureEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, org.bukkit.inventory.ItemStack, int)
(API) Deprecated ctor McMMOPlayerMagicHunterEvent(org.bukkit.entity.Player, org.bukkit.inventory.ItemStack, int, java.util.Map<org.bukkit.enchantments.Enchantment,java.lang.Integer>)
(API) Added ctor McMMOPlayerMagicHunterEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, org.bukkit.inventory.ItemStack, int, java.util.Map<org.bukkit.enchantments.Enchantment,java.lang.Integer>)
(API) Deprecated ctor McMMOPlayerAbilityDeactivateEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Added ctor McMMOPlayerAbilityDeactivateEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
(API) Deprecated util method EventUtils.callAbilityDeactivateEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.SuperAbilityType)
(API) Added util method EventUtils.callAbilityDeactivateEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.SuperAbilityType)
(API) Deprecated util EventUtils.callSubSkillEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.SubSkillType)
(API) Added util EventUtils.callSubSkillEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.SubSkillType)
(API) Deprecated ctor SubSkillEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.SubSkillType)
(API) Added ctor SubSkillEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.SubSkillType)
(API) Deprecated ctor SubSkillEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.SubSkillType, double)
(API) Added ctor SubSkillEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.SubSkillType, double)
(API) Deprecated ctor SubSkillEvent(org.bukkit.entity.Player, com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill)
(API) Added ctor SubSkillEvent(com.gmail.nossr50.datatypes.player.McMMOPlayer, com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill)
(API) Deprecated ctor AlchemyBrewCheckTask(org.bukkit.entity.Player, org.bukkit.block.BrewingStand)
(API) Added ctor AlchemyBrewCheckTask(org.bukkit.block.BrewingStand)
NOTES:
This is not an exhaustive list of API changes in this update, but most of them should be documented here.
Version 2.2.009
Fixed a bug that prevented mcMMO from loading on MC versions older than 1.20.6
Dramatically increased the base XP for Alchemy again (see notes)

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.2.009</version>
<version>2.2.010-SNAPSHOT</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm>

View File

@ -29,7 +29,7 @@ public class AcrobaticsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// ACROBATICS_DODGE
if (canDodge) {
String[] dodgeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_DODGE);
final String[] dodgeStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ACROBATICS_DODGE);
dodgeChance = dodgeStrings[0];
dodgeChanceLucky = dodgeStrings[1];
}
@ -56,7 +56,7 @@ public class AcrobaticsCommand extends SkillCommand {
if(abstractSubSkill != null)
{
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_ROLL);
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ACROBATICS_ROLL);
messages.add(getStatMessage(SubSkillType.ACROBATICS_ROLL, rollStrings[0])
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", rollStrings[1]) : ""));

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.alchemy.AlchemyManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
@ -30,14 +29,7 @@ public class AlchemyCommand extends SkillCommand {
}
protected String[] calculateAbilityDisplayValues(Player player) {
//TODO: Needed?
if(UserManager.getPlayer(player) == null)
{
player.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return new String[] {"DATA NOT LOADED", "DATA NOT LOADED"};
}
AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
AlchemyManager alchemyManager = mmoPlayer.getAlchemyManager();
String[] displayValues = new String[2];
boolean isLucky = Permissions.lucky(player, PrimarySkillType.ALCHEMY);
@ -59,7 +51,7 @@ public class AlchemyCommand extends SkillCommand {
// ALCHEMY_CONCOCTIONS
if (canConcoctions) {
AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager();
AlchemyManager alchemyManager = mmoPlayer.getAlchemyManager();
tier = alchemyManager.getTier();
ingredientCount = alchemyManager.getIngredients().size();
ingredientList = alchemyManager.getIngredientList();

View File

@ -33,14 +33,14 @@ public class ArcheryCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// ARCHERY_ARROW_RETRIEVAL
if (canRetrieve) {
String[] retrieveStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
String[] retrieveStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
retrieveChance = retrieveStrings[0];
retrieveChanceLucky = retrieveStrings[1];
}
// ARCHERY_DAZE
if (canDaze) {
String[] dazeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_DAZE);
String[] dazeStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ARCHERY_DAZE);
dazeChance = dazeStrings[0];
dazeChanceLucky = dazeStrings[1];
}

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.axes.Axes;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
@ -38,7 +37,7 @@ public class AxesCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// ARMOR IMPACT
if (canImpact) {
impactDamage = UserManager.getPlayer(player).getAxesManager().getImpactDurabilityDamage();
impactDamage = mmoPlayer.getAxesManager().getImpactDurabilityDamage();
}
// AXE MASTERY
@ -48,7 +47,7 @@ public class AxesCommand extends SkillCommand {
// CRITICAL HIT
if (canCritical) {
String[] criticalHitStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.AXES_CRITICAL_STRIKES);
String[] criticalHitStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.AXES_CRITICAL_STRIKES);
critChance = criticalHitStrings[0];
critChanceLucky = criticalHitStrings[1];
}

View File

@ -1,9 +1,7 @@
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.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@ -42,7 +40,6 @@ public class CrossbowsCommand extends SkillCommand {
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return messages;
}

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.excavation.ExcavationManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
@ -45,7 +44,7 @@ public class ExcavationCommand extends SkillCommand {
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
ExcavationManager excavationManager = UserManager.getPlayer(player).getExcavationManager();
ExcavationManager excavationManager = mmoPlayer.getExcavationManager();
if (canGigaDrill) {
messages.add(getStatMessage(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, gigaDrillBreakerLength)

View File

@ -8,7 +8,6 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.Probability;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
@ -50,7 +49,7 @@ public class FishingCommand extends SkillCommand {
@Override
protected void dataCalculations(Player player, float skillValue) {
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager();
FishingManager fishingManager = mmoPlayer.getFishingManager();
// TREASURE HUNTER
if (canTreasureHunt) {

View File

@ -49,13 +49,13 @@ public class HerbalismCommand extends SkillCommand {
// DOUBLE DROPS
if (canDoubleDrop) {
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_DOUBLE_DROPS);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.HERBALISM_DOUBLE_DROPS);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}
if (canTripleDrop) {
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_VERDANT_BOUNTY);
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.HERBALISM_VERDANT_BOUNTY);
tripleDropChance = tripleDropStrings[0];
tripleDropChanceLucky = tripleDropStrings[1];
}
@ -76,21 +76,21 @@ public class HerbalismCommand extends SkillCommand {
if (canGreenThumbBlocks || canGreenThumbPlants) {
greenThumbStage = RankUtils.getRank(player, SubSkillType.HERBALISM_GREEN_THUMB);
String[] greenThumbStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_GREEN_THUMB);
String[] greenThumbStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.HERBALISM_GREEN_THUMB);
greenThumbChance = greenThumbStrings[0];
greenThumbChanceLucky = greenThumbStrings[1];
}
// HYLIAN LUCK
if (hasHylianLuck) {
String[] hylianLuckStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_HYLIAN_LUCK);
String[] hylianLuckStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.HERBALISM_HYLIAN_LUCK);
hylianLuckChance = hylianLuckStrings[0];
hylianLuckChanceLucky = hylianLuckStrings[1];
}
// SHROOM THUMB
if (canShroomThumb) {
String[] shroomThumbStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.HERBALISM_SHROOM_THUMB);
String[] shroomThumbStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.HERBALISM_SHROOM_THUMB);
shroomThumbChance = shroomThumbStrings[0];
shroomThumbChanceLucky = shroomThumbStrings[1];
}

View File

@ -30,10 +30,6 @@
// @Override
// protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
// List<String> messages = new ArrayList<>();
// McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
// if (mmoPlayer == null) {
// return messages;
// }
//
// if(SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
// messages.add(getStatMessage(MACES_MACES_LIMIT_BREAK,

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@ -45,7 +44,7 @@ public class MiningCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// BLAST MINING
if (canBlast || canDemoExpert || canBiggerBombs) {
MiningManager miningManager = UserManager.getPlayer(player).getMiningManager();
MiningManager miningManager = mmoPlayer.getMiningManager();
blastMiningRank = miningManager.getBlastMiningTier();
bonusTNTDrops = miningManager.getDropMultiplier();
@ -57,14 +56,14 @@ public class MiningCommand extends SkillCommand {
// Mastery TRIPLE DROPS
if (canTripleDrop) {
String[] masteryTripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_MOTHER_LODE);
String[] masteryTripleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.MINING_MOTHER_LODE);
tripleDropChance = masteryTripleDropStrings[0];
tripleDropChanceLucky = masteryTripleDropStrings[1];
}
// DOUBLE DROPS
if (canDoubleDrop) {
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_DOUBLE_DROPS);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.MINING_DOUBLE_DROPS);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}

View File

@ -10,7 +10,6 @@ import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.repair.RepairManager;
import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@ -68,7 +67,7 @@ public class RepairCommand extends SkillCommand {
// SUPER REPAIR
if (canSuperRepair) {
String[] superRepairStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.REPAIR_SUPER_REPAIR);
String[] superRepairStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.REPAIR_SUPER_REPAIR);
superRepairChance = superRepairStrings[0];
superRepairChanceLucky = superRepairStrings[1];
}
@ -94,7 +93,7 @@ public class RepairCommand extends SkillCommand {
List<String> messages = new ArrayList<>();
if (canArcaneForge) {
RepairManager repairManager = UserManager.getPlayer(player).getRepairManager();
RepairManager repairManager = mmoPlayer.getRepairManager();
messages.add(getStatMessage(false, true,
SubSkillType.REPAIR_ARCANE_FORGING,

View File

@ -6,7 +6,6 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.skills.salvage.SalvageManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component;
@ -38,7 +37,7 @@ public class SalvageCommand extends SkillCommand {
@Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
SalvageManager salvageManager = UserManager.getPlayer(player).getSalvageManager();
SalvageManager salvageManager = mmoPlayer.getSalvageManager();
if (canScrapCollector) {
messages.add(getStatMessage(false, true,

View File

@ -34,6 +34,7 @@ public abstract class SkillCommand implements TabExecutor {
protected DecimalFormat percent = new DecimalFormat("##0.00%");
protected DecimalFormat decimal = new DecimalFormat("##0.00");
protected McMMOPlayer mmoPlayer;
private final CommandExecutor skillGuideCommand;
@ -53,9 +54,9 @@ public abstract class SkillCommand implements TabExecutor {
}
Player player = (Player) sender;
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
mmoPlayer = UserManager.getPlayer(player);
if (mcMMOPlayer == null) {
if (mmoPlayer == null) {
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true;
}
@ -63,7 +64,7 @@ public abstract class SkillCommand implements TabExecutor {
if (args.length == 0) {
boolean isLucky = Permissions.lucky(player, skill);
boolean hasEndurance = PerksUtils.handleActivationPerks(player, 0, 0) != 0;
float skillValue = mcMMOPlayer.getSkillLevel(skill);
float skillValue = mmoPlayer.getSkillLevel(skill);
//Send the players a few blank lines to make finding the top of the skill command easier
if (mcMMO.p.getAdvancedConfig().doesSkillCommandSendBlankLines())
@ -75,7 +76,7 @@ public abstract class SkillCommand implements TabExecutor {
dataCalculations(player, skillValue);
sendSkillCommandHeader(mcMMO.p.getSkillTools().getLocalizedSkillName(skill),
player, mcMMOPlayer, (int) skillValue);
player, mmoPlayer, (int) skillValue);
//Make JSON text components
List<Component> subskillTextComponents = getTextComponents(player);

View File

@ -4,7 +4,6 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory;
@ -34,7 +33,7 @@ public class SmeltingCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// FUEL EFFICIENCY
if (canFuelEfficiency) {
burnTimeModifier = String.valueOf(UserManager.getPlayer(player).getSmeltingManager().getFuelEfficiencyMultiplier());
burnTimeModifier = String.valueOf(mmoPlayer.getSmeltingManager().getFuelEfficiencyMultiplier());
}
// FLUX MINING
@ -46,7 +45,7 @@ public class SmeltingCommand extends SkillCommand {
// SECOND SMELT
if (canSecondSmelt) {
String[] secondSmeltStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.SMELTING_SECOND_SMELT);
String[] secondSmeltStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.SMELTING_SECOND_SMELT);
str_secondSmeltChance = secondSmeltStrings[0];
str_secondSmeltChanceLucky = secondSmeltStrings[1];
}
@ -81,7 +80,7 @@ public class SmeltingCommand extends SkillCommand {
if (canUnderstandTheArt) {
messages.add(getStatMessage(false, true, SubSkillType.SMELTING_UNDERSTANDING_THE_ART,
String.valueOf(UserManager.getPlayer(player).getSmeltingManager().getVanillaXpMultiplier())));
String.valueOf(mmoPlayer.getSmeltingManager().getVanillaXpMultiplier())));
}
return messages;

View File

@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
@ -39,7 +38,7 @@ public class SwordsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// SWORDS_COUNTER_ATTACK
if (canCounter) {
String[] counterStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.SWORDS_COUNTER_ATTACK);
String[] counterStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.SWORDS_COUNTER_ATTACK);
counterChance = counterStrings[0];
counterChanceLucky = counterStrings[1];
}
@ -105,7 +104,7 @@ public class SwordsCommand extends SkillCommand {
if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_STAB))
{
messages.add(getStatMessage(SubSkillType.SWORDS_STAB,
String.valueOf(UserManager.getPlayer(player).getSwordsManager().getStabDamage())));
String.valueOf(mmoPlayer.getSwordsManager().getStabDamage())));
}
if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {

View File

@ -35,7 +35,7 @@ public class TamingCommand extends SkillCommand {
@Override
protected void dataCalculations(Player player, float skillValue) {
if (canGore) {
String[] goreStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.TAMING_GORE);
String[] goreStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.TAMING_GORE);
goreChance = goreStrings[0];
goreChanceLucky = goreStrings[1];
}

View File

@ -1,8 +1,6 @@
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;
@ -32,10 +30,6 @@ public class TridentsCommand extends SkillCommand {
@Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return messages;
}
if(SkillUtils.canUseSubskill(player, TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
messages.add(getStatMessage(TRIDENTS_TRIDENTS_LIMIT_BREAK,

View File

@ -4,7 +4,6 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils;
@ -40,7 +39,7 @@ public class UnarmedCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) {
// UNARMED_ARROW_DEFLECT
if (canDeflect) {
String[] deflectStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_ARROW_DEFLECT);
String[] deflectStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_ARROW_DEFLECT);
deflectChance = deflectStrings[0];
deflectChanceLucky = deflectStrings[1];
}
@ -54,19 +53,19 @@ public class UnarmedCommand extends SkillCommand {
// UNARMED_DISARM
if (canDisarm) {
String[] disarmStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_DISARM);
String[] disarmStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_DISARM);
disarmChance = disarmStrings[0];
disarmChanceLucky = disarmStrings[1];
}
// IRON ARM
if (canIronArm) {
ironArmBonus = UserManager.getPlayer(player).getUnarmedManager().getSteelArmStyleDamage();
ironArmBonus = mmoPlayer.getUnarmedManager().getSteelArmStyleDamage();
}
// IRON GRIP
if (canIronGrip) {
String[] ironGripStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_IRON_GRIP);
String[] ironGripStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_IRON_GRIP);
ironGripChance = ironGripStrings[0];
ironGripChanceLucky = ironGripStrings[1];
}

View File

@ -41,7 +41,7 @@ public class WoodcuttingCommand extends SkillCommand {
//Clean Cuts
if(canTripleDrop) {
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.WOODCUTTING_CLEAN_CUTS);
String[] tripleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.WOODCUTTING_CLEAN_CUTS);
tripleDropChance = tripleDropStrings[0];
tripleDropChanceLucky = tripleDropStrings[1];
}
@ -55,7 +55,7 @@ public class WoodcuttingCommand extends SkillCommand {
}
private void setDoubleDropClassicChanceStrings(Player player) {
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.WOODCUTTING_HARVEST_LUMBER);
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.WOODCUTTING_HARVEST_LUMBER);
doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1];
}

View File

@ -14,15 +14,16 @@ import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.codehaus.plexus.util.StringUtils;
import org.jetbrains.annotations.VisibleForTesting;
import java.io.File;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.gmail.nossr50.util.ItemUtils.setItemName;
import static com.gmail.nossr50.util.PotionUtil.*;
import static com.gmail.nossr50.util.text.StringUtils.convertKeyToName;
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
public class PotionConfig extends LegacyConfigLoader {

View File

@ -72,6 +72,9 @@ import java.util.EnumMap;
import java.util.Map;
import java.util.UUID;
import static com.gmail.nossr50.util.EventUtils.callPlayerAbilityActivateEvent;
import static java.util.Objects.requireNonNull;
public class McMMOPlayer implements Identified {
private final @NotNull Identity identity;
@ -120,6 +123,8 @@ public class McMMOPlayer implements Identified {
private PrimarySkillType lastSkillShownScoreboard = PrimarySkillType.values()[0];
public McMMOPlayer(Player player, PlayerProfile profile) {
requireNonNull(player, "player cannot be null");
requireNonNull(profile, "profile cannot be null");
this.playerName = player.getName();
UUID uuid = player.getUniqueId();
identity = Identity.identity(uuid);
@ -747,11 +752,11 @@ public class McMMOPlayer implements Identified {
* Players & Profiles
*/
public Player getPlayer() {
public @NotNull Player getPlayer() {
return player;
}
public PlayerProfile getProfile() {
public @NotNull PlayerProfile getProfile() {
return profile;
}
@ -925,7 +930,7 @@ public class McMMOPlayer implements Identified {
return;
}
if (EventUtils.callPlayerAbilityActivateEvent(player, primarySkillType).isCancelled()) {
if (callPlayerAbilityActivateEvent(this, primarySkillType).isCancelled()) {
return;
}

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.skills.subskills;
import com.gmail.nossr50.config.CoreSkillsConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank;
@ -48,13 +49,13 @@ public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, S
/**
* Prints detailed info about this subskill to the player
*
* @param player the target player
* @param mmoPlayer the target player
*/
@Override
public void printInfo(Player player) {
public void printInfo(McMMOPlayer mmoPlayer) {
/* DEFAULT SETTINGS PRINT THE BARE MINIMUM */
//TextComponentFactory.sendPlayerUrlHeader(player);
final Player player = mmoPlayer.getPlayer();
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", getConfigKeyName()));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader"));

View File

@ -4,7 +4,6 @@ import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@ -13,7 +12,6 @@ import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.Probability;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.PerksUtils;
@ -67,25 +65,25 @@ public class Roll extends AcrobaticsSubSkill {
return false;
if (entityDamageEvent.getCause() == EntityDamageEvent.DamageCause.FALL) {//Grab the player
McMMOPlayer mcMMOPlayer = EventUtils.getMcMMOPlayer(entityDamageEvent.getEntity());
McMMOPlayer mmoPlayer = EventUtils.getMcMMOPlayer(entityDamageEvent.getEntity());
if (mcMMOPlayer == null)
if (mmoPlayer == null)
return false;
/*
* Check for success
*/
Player player = (Player) ((EntityDamageEvent) event).getEntity();
if (canRoll(player)) {
entityDamageEvent.setDamage(rollCheck(player, mcMMOPlayer, entityDamageEvent.getFinalDamage()));
if (canRoll(mmoPlayer)) {
entityDamageEvent.setDamage(rollCheck(mmoPlayer, entityDamageEvent.getFinalDamage()));
if (entityDamageEvent.getFinalDamage() == 0) {
entityDamageEvent.setCancelled(true);
return true;
}
} else if(mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.ACROBATICS)) {
} else if(mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(mmoPlayer.getPlayer(), PrimarySkillType.ACROBATICS)) {
//Give XP Anyways
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, ((EntityDamageEvent) event).getFinalDamage(), false), XPGainReason.PVE);
SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, ((EntityDamageEvent) event).getFinalDamage(), false), XPGainReason.PVE);
}
}
@ -117,25 +115,24 @@ public class Roll extends AcrobaticsSubSkill {
* Adds detailed stats specific to this skill
*
* @param componentBuilder target component builder
* @param player target player
* @param mmoPlayer target player
*/
@Override
public void addStats(TextComponent.Builder componentBuilder, Player player) {
public void addStats(TextComponent.Builder componentBuilder, McMMOPlayer mmoPlayer) {
String rollChance, rollChanceLucky, gracefulRollChance, gracefulRollChanceLucky;
/* Values related to the player */
PlayerProfile playerProfile = UserManager.getPlayer(player).getProfile();
float skillValue = playerProfile.getSkillLevel(getPrimarySkill());
boolean isLucky = Permissions.lucky(player, getPrimarySkill());
float skillValue = mmoPlayer.getSkillLevel(getPrimarySkill());
boolean isLucky = Permissions.lucky(mmoPlayer.getPlayer(), getPrimarySkill());
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_ROLL);
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ACROBATICS_ROLL);
rollChance = rollStrings[0];
rollChanceLucky = rollStrings[1];
/*
* Graceful is double the odds of a normal roll
*/
Probability probability = getRollProbability(player);
Probability probability = getRollProbability(mmoPlayer);
Probability gracefulProbability = Probability.ofValue(probability.getValue() * 2);
String[] gracefulRollStrings = ProbabilityUtil.getRNGDisplayValues(gracefulProbability);
gracefulRollChance = gracefulRollStrings[0];
@ -169,8 +166,8 @@ public class Roll extends AcrobaticsSubSkill {
}
@NotNull
private Probability getRollProbability(Player player) {
return ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player);
private Probability getRollProbability(McMMOPlayer mmoPlayer) {
return ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, mmoPlayer);
}
@Override
@ -188,8 +185,9 @@ public class Roll extends AcrobaticsSubSkill {
return true;
}
private boolean canRoll(Player player) {
return RankUtils.hasUnlockedSubskill(player, SubSkillType.ACROBATICS_ROLL) && Permissions.isSubSkillEnabled(player, SubSkillType.ACROBATICS_ROLL);
private boolean canRoll(McMMOPlayer mmoPlayer) {
return RankUtils.hasUnlockedSubskill(mmoPlayer.getPlayer(), SubSkillType.ACROBATICS_ROLL)
&& Permissions.isSubSkillEnabled(mmoPlayer.getPlayer(), SubSkillType.ACROBATICS_ROLL);
}
/**
@ -199,43 +197,42 @@ public class Roll extends AcrobaticsSubSkill {
* @return the modified event damage if the ability was successful, the original event damage otherwise
*/
@VisibleForTesting
public double rollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage) {
public double rollCheck(McMMOPlayer mmoPlayer, double damage) {
int skillLevel = mmoPlayer.getSkillLevel(getPrimarySkill());
int skillLevel = mcMMOPlayer.getSkillLevel(getPrimarySkill());
if (player.isSneaking()) {
return gracefulRollCheck(player, mcMMOPlayer, damage, skillLevel);
if (mmoPlayer.getPlayer().isSneaking()) {
return gracefulRollCheck(mmoPlayer, damage, skillLevel);
}
double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold());
if (!isFatal(player, modifiedDamage)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_ROLL, player)) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text");
SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS);
//player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
if (!isFatal(mmoPlayer, modifiedDamage)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_ROLL, mmoPlayer)) {
NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text");
SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS);
//mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
//if (!SkillUtils.cooldownExpired((long) mcMMOmmoPlayer.getPlayer().getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, true), XPGainReason.PVE);
//}
addFallLocation(player);
addFallLocation(mmoPlayer);
return modifiedDamage;
}
else if (!isFatal(player, damage)) {
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
else if (!isFatal(mmoPlayer, damage)) {
//if (!SkillUtils.cooldownExpired((long) mmoPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, false), XPGainReason.PVE);
//}
}
addFallLocation(player);
addFallLocation(mmoPlayer);
return damage;
}
private int getActivationChance(McMMOPlayer mcMMOPlayer) {
return PerksUtils.handleLuckyPerks(mcMMOPlayer.getPlayer(), getPrimarySkill());
private int getActivationChance(McMMOPlayer mmoPlayer) {
return PerksUtils.handleLuckyPerks(mmoPlayer, getPrimarySkill());
}
/**
@ -244,36 +241,36 @@ public class Roll extends AcrobaticsSubSkill {
* @param damage The amount of damage initially dealt by the event
* @return the modified event damage if the ability was successful, the original event damage otherwise
*/
private double gracefulRollCheck(Player player, McMMOPlayer mcMMOPlayer, double damage, int skillLevel) {
private double gracefulRollCheck(McMMOPlayer mmoPlayer, double damage, int skillLevel) {
double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2);
Probability gracefulProbability = getGracefulProbability(player);
final Probability gracefulProbability = getGracefulProbability(mmoPlayer);
if (!isFatal(player, modifiedDamage)
if (!isFatal(mmoPlayer, modifiedDamage)
//TODO: Graceful isn't sending out an event
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.ACROBATICS, player, gracefulProbability))
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.ACROBATICS, mmoPlayer, gracefulProbability))
{
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc");
SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F);
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE);
NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc");
SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F);
if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, true), XPGainReason.PVE);
addFallLocation(player);
addFallLocation(mmoPlayer);
return modifiedDamage;
}
else if (!isFatal(player, damage)) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE);
else if (!isFatal(mmoPlayer, damage)) {
if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, false), XPGainReason.PVE);
addFallLocation(player);
addFallLocation(mmoPlayer);
}
return damage;
}
@NotNull
public static Probability getGracefulProbability(Player player) {
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player).getValue() * 2;
public static Probability getGracefulProbability(McMMOPlayer mmoPlayer) {
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, mmoPlayer).getValue() * 2;
return Probability.ofValue(gracefulOdds);
}
@ -283,24 +280,22 @@ public class Roll extends AcrobaticsSubSkill {
*
* @return true if exploits are detected, false otherwise
*/
private boolean isExploiting(Player player) {
private boolean isExploiting(McMMOPlayer mmoPlayer) {
if (!ExperienceConfig.getInstance().isAcrobaticsExploitingPrevented()) {
return false;
}
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
if (ItemUtils.hasItemInEitherHand(player, Material.ENDER_PEARL) || player.isInsideVehicle()) {
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Ender Pearl or Inside Vehicle");
if (ItemUtils.hasItemInEitherHand(mmoPlayer.getPlayer(), Material.ENDER_PEARL) || mmoPlayer.getPlayer().isInsideVehicle()) {
if(mmoPlayer.isDebugMode()) {
mmoPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Ender Pearl or Inside Vehicle");
}
return true;
}
if(UserManager.getPlayer(player).getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(player)))
if(mmoPlayer.getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(mmoPlayer)))
{
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Fallen in location before");
if(mmoPlayer.isDebugMode()) {
mmoPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Fallen in location before");
}
return true;
@ -309,11 +304,11 @@ public class Roll extends AcrobaticsSubSkill {
return false; //NOT EXPLOITING
}
private float calculateRollXP(Player player, double damage, boolean isRoll) {
private float calculateRollXP(McMMOPlayer mmoPlayer, double damage, boolean isRoll) {
//Clamp Damage to account for insane DRs
damage = Math.min(20, damage);
ItemStack boots = player.getInventory().getBoots();
ItemStack boots = mmoPlayer.getPlayer().getInventory().getBoots();
float xp = (float) (damage * (isRoll ? ExperienceConfig.getInstance().getRollXPModifier() : ExperienceConfig.getInstance().getFallXPModifier()));
if (boots != null && boots.containsEnchantment(mcMMO.p.getEnchantmentMapper().getFeatherFalling())) {
@ -327,8 +322,8 @@ public class Roll extends AcrobaticsSubSkill {
return Math.max(damage - damageThreshold, 0.0);
}
private boolean isFatal(Player player, double damage) {
return player.getHealth() - damage <= 0;
private boolean isFatal(McMMOPlayer mmoPlayer, double damage) {
return mmoPlayer.getPlayer().getHealth() - damage <= 0;
}
/**
@ -344,103 +339,51 @@ public class Roll extends AcrobaticsSubSkill {
/**
* Prints detailed info about this subskill to the player
*
* @param player the target player
* @param mmoPlayer the target player
*/
@Override
public void printInfo(Player player) {
public void printInfo(McMMOPlayer mmoPlayer) {
//Header
super.printInfo(player);
super.printInfo(mmoPlayer);
//Start the description string.
//player.sendMessage(getDescription());
//Player stats
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Stats",
LocaleLoader.getString("Acrobatics.SubSkill.Roll.Stats", getStats(player))));
mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.MmoInfo.Stats",
LocaleLoader.getString("Acrobatics.SubSkill.Roll.Stats", getStats(mmoPlayer))));
//Mechanics
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mechanics"));
player.sendMessage(getMechanics());
mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mechanics"));
mmoPlayer.getPlayer().sendMessage(getMechanics());
}
/**
* Returns a collection of strings about how a skill works
* Used in the MMO Info command
*
* @return
*/
@Override
public String getMechanics() {
//Vars passed to locale
//0 = chance to roll at half max level
//1 = chance to roll with grace at half max level
//2 = level where maximum bonus is reached
//3 = additive chance to succeed per level
//4 = damage threshold when rolling
//5 = damage threshold when rolling with grace
//6 = half of level where maximum bonus is reached
/*
Roll:
# ChanceMax: Maximum chance of rolling when on <MaxBonusLevel> or higher
# MaxBonusLevel: On this level or higher, the roll chance will not go higher than <ChanceMax>
# DamageThreshold: The max damage a player can negate with a roll
ChanceMax: 100.0
MaxBonusLevel: 100
DamageThreshold: 7.0
*/
return "Under Construction: This will work in a future update.";
//
// double rollChanceHalfMax, graceChanceHalfMax, damageThreshold, chancePerLevel;
//
// //Chance to roll at half max skill
// RandomChanceSkill rollHalfMaxSkill = new RandomChanceSkill(null, subSkillType);
// int halfMaxSkillValue = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL)/2;
// rollHalfMaxSkill.setSkillLevel(halfMaxSkillValue);
//
// //Chance to graceful roll at full skill
// RandomChanceSkill rollGraceHalfMaxSkill = new RandomChanceSkill(null, subSkillType);
// rollGraceHalfMaxSkill.setSkillLevel(halfMaxSkillValue * 2); //Double the effective odds
//
// //Chance to roll per level
// RandomChanceSkill rollOneSkillLevel = new RandomChanceSkill(null, subSkillType);
// rollGraceHalfMaxSkill.setSkillLevel(1); //Level 1 skill
//
// //Chance Stat Calculations
// rollChanceHalfMax = RandomChanceUtil.getRandomChanceExecutionChance(rollHalfMaxSkill);
// graceChanceHalfMax = RandomChanceUtil.getRandomChanceExecutionChance(rollGraceHalfMaxSkill);
// damageThreshold = mcMMO.p.getAdvancedConfig().getRollDamageThreshold();
//
// chancePerLevel = RandomChanceUtil.getRandomChanceExecutionChance(rollOneSkillLevel);
//
// double maxLevel = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL);
//
// return LocaleLoader.getString("Acrobatics.SubSkill.Roll.Mechanics", rollChanceHalfMax, graceChanceHalfMax, maxLevel, chancePerLevel, damageThreshold, damageThreshold * 2,halfMaxSkillValue);
}
/**
* Get an array of various stats for a player
*
* @param player target player
* @param mmoPlayer target player
* @return stat array for target player for this skill
*/
@Override
public Double[] getStats(Player player)
public Double[] getStats(McMMOPlayer mmoPlayer)
{
double playerChanceRoll = ProbabilityUtil.getSubSkillProbability(subSkillType, player).getValue();
double playerChanceRoll = ProbabilityUtil.getSubSkillProbability(subSkillType, mmoPlayer).getValue();
double playerChanceGrace = playerChanceRoll * 2;
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(subSkillType, player).getValue() * 2;
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(subSkillType, mmoPlayer).getValue() * 2;
return new Double[]{ playerChanceRoll, playerChanceGrace };
}
public void addFallLocation(@NotNull Player player)
{
UserManager.getPlayer(player).getAcrobaticsManager().addLocationToFallMap(getBlockLocation(player));
public void addFallLocation(@NotNull McMMOPlayer mmoPlayer) {
mmoPlayer.getAcrobaticsManager().addLocationToFallMap(getBlockLocation(mmoPlayer));
}
public @NotNull Location getBlockLocation(@NotNull Player player)
{
return player.getLocation().getBlock().getLocation();
public @NotNull Location getBlockLocation(@NotNull McMMOPlayer mmoPlayer) {
return mmoPlayer.getPlayer().getLocation().getBlock().getLocation();
}
}

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.datatypes.skills.subskills.interfaces;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.interfaces.Skill;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player;
@ -19,10 +20,10 @@ public interface SubSkill extends Skill {
/**
* Get an array of various stats for a player
* @param player target player
* @param mmoPlayer target player
* @return stat array for target player for this skill
*/
Double[] getStats(Player player);
Double[] getStats(McMMOPlayer mmoPlayer);
/**
* Checks if a player has permission to use this skill
@ -59,9 +60,9 @@ public interface SubSkill extends Skill {
/**
* Adds detailed stats specific to this skill
* @param componentBuilder target component builder
* @param player owner of this skill
* @param mmoPlayer owner of this skill
*/
void addStats(TextComponent.Builder componentBuilder, Player player);
void addStats(TextComponent.Builder componentBuilder, McMMOPlayer mmoPlayer);
/**
* Whether this subskill is enabled
@ -71,7 +72,7 @@ public interface SubSkill extends Skill {
/**
* Prints detailed info about this subskill to the player
* @param player the target player
* @param mmoPlayer the target player
*/
void printInfo(Player player);
void printInfo(McMMOPlayer mmoPlayer);
}

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.events.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
@ -7,19 +8,35 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
/**
* Generic event for mcMMO skill handling.
*/
public abstract class McMMOPlayerSkillEvent extends PlayerEvent {
protected @NotNull PrimarySkillType skill;
protected int skillLevel;
protected McMMOPlayer mmoPlayer;
@Deprecated(forRemoval = true, since = "2.2.010")
protected McMMOPlayerSkillEvent(@NotNull Player player, @NotNull PrimarySkillType skill) {
super(player);
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
requireNonNull(mmoPlayer, "Player not found in UserManager," +
"contact the dev and tell them to use the constructor for" +
" McMMOPlayerSkillEvent(McMMOPlayer, PrimarySkillType) instead");
this.skill = skill;
this.skillLevel = UserManager.getPlayer(player).getSkillLevel(skill);
}
protected McMMOPlayerSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType) {
super(mmoPlayer.getPlayer());
requireNonNull(mmoPlayer, "mmoPlayer cannot be null");
requireNonNull(primarySkillType, "primarySkillType cannot be null");
this.skill = primarySkillType;
this.skillLevel = mmoPlayer.getSkillLevel(primarySkillType);
}
/**
* @return The skill involved in this event
*/
@ -37,6 +54,15 @@ public abstract class McMMOPlayerSkillEvent extends PlayerEvent {
/** Rest of file is required boilerplate for custom events **/
private static final HandlerList handlers = new HandlerList();
/**
* Returns the {@link McMMOPlayer} associated with this event.
*
* @return The {@link McMMOPlayer} associated with this event.
*/
public @NotNull McMMOPlayer getMcMMOPlayer() {
return mmoPlayer;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlers;

View File

@ -1,14 +1,24 @@
package com.gmail.nossr50.events.skills.abilities;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import java.util.Objects;
public class McMMOPlayerAbilityActivateEvent extends McMMOPlayerAbilityEvent implements Cancellable {
private boolean cancelled;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerAbilityActivateEvent(Player player, PrimarySkillType skill) {
super(player, skill);
super(Objects.requireNonNull(UserManager.getPlayer(player)), skill);
cancelled = false;
}
public McMMOPlayerAbilityActivateEvent(McMMOPlayer mmoPlayer, PrimarySkillType skill) {
super(mmoPlayer, skill);
cancelled = false;
}

View File

@ -1,10 +1,20 @@
package com.gmail.nossr50.events.skills.abilities;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
public class McMMOPlayerAbilityDeactivateEvent extends McMMOPlayerAbilityEvent {
public McMMOPlayerAbilityDeactivateEvent(Player player, PrimarySkillType skill) {
super(player, skill);
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerAbilityDeactivateEvent(@NotNull Player player, @NotNull PrimarySkillType skill) {
this(requireNonNull(UserManager.getPlayer(player)), skill);
}
public McMMOPlayerAbilityDeactivateEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull PrimarySkillType skill) {
super(mmoPlayer, skill);
}
}

View File

@ -1,16 +1,38 @@
package com.gmail.nossr50.events.skills.abilities;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import java.util.Objects;
public class McMMOPlayerAbilityEvent extends McMMOPlayerSkillEvent {
private final SuperAbilityType ability;
/**
* Create a new McMMOPlayerAbilityEvent.
*
* @param player The player involved in this event
* @param skill The skill involved in this event
* @deprecated Use {@link #McMMOPlayerAbilityEvent(McMMOPlayer, PrimarySkillType)} instead
*/
@Deprecated(forRemoval = true, since = "2.2.010")
protected McMMOPlayerAbilityEvent(Player player, PrimarySkillType skill) {
super(player, skill);
super(Objects.requireNonNull(UserManager.getPlayer(player)), skill);
ability = mcMMO.p.getSkillTools().getSuperAbility(skill);
}
/**
* Create a new McMMOPlayerAbilityEvent.
* @param mmoPlayer The McMMOPlayer involved in this event
* @param skill The skill involved in this event
*/
protected McMMOPlayerAbilityEvent(McMMOPlayer mmoPlayer, PrimarySkillType skill) {
super(mmoPlayer, skill);
ability = mcMMO.p.getSkillTools().getSuperAbility(skill);
}

View File

@ -1,24 +1,36 @@
package com.gmail.nossr50.events.skills.alchemy;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
public class McMMOPlayerBrewEvent extends McMMOPlayerSkillEvent implements Cancellable {
private final BlockState brewingStand;
private boolean cancelled;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerBrewEvent(Player player, BlockState brewingStand) {
super(player, PrimarySkillType.ALCHEMY);
super(requireNonNull(UserManager.getPlayer(player)), PrimarySkillType.ALCHEMY);
this.brewingStand = brewingStand;
cancelled = false;
}
public McMMOPlayerBrewEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull BlockState brewingStand) {
super(mmoPlayer, PrimarySkillType.ALCHEMY);
this.brewingStand = requireNonNull(brewingStand);
cancelled = false;
}
public boolean isCancelled() {
return cancelled;
}

View File

@ -1,17 +1,28 @@
package com.gmail.nossr50.events.skills.alchemy;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import static java.util.Objects.requireNonNull;
public class McMMOPlayerCatalysisEvent extends McMMOPlayerSkillEvent implements Cancellable {
private double speed;
private boolean cancelled;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerCatalysisEvent(Player player, double speed) {
super(player, PrimarySkillType.ALCHEMY);
super(requireNonNull(UserManager.getPlayer(player)), PrimarySkillType.ALCHEMY);
this.speed = speed;
cancelled = false;
}
public McMMOPlayerCatalysisEvent(McMMOPlayer mmoPlayer, double speed) {
super(mmoPlayer, PrimarySkillType.ALCHEMY);
this.speed = speed;
cancelled = false;
}

View File

@ -1,15 +1,23 @@
package com.gmail.nossr50.events.skills.fishing;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
public class McMMOPlayerFishingEvent extends McMMOPlayerSkillEvent implements Cancellable {
private boolean cancelled;
@Deprecated(forRemoval = true, since = "2.2.010")
protected McMMOPlayerFishingEvent(Player player) {
super(player, PrimarySkillType.FISHING);
super(UserManager.getPlayer(player), PrimarySkillType.FISHING);
cancelled = false;
}
protected McMMOPlayerFishingEvent(McMMOPlayer mmoPlayer) {
super(mmoPlayer, PrimarySkillType.FISHING);
cancelled = false;
}

View File

@ -1,23 +1,34 @@
package com.gmail.nossr50.events.skills.fishing;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static java.util.Objects.requireNonNull;
public class McMMOPlayerFishingTreasureEvent extends McMMOPlayerFishingEvent {
private ItemStack treasure;
private int xp;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerFishingTreasureEvent(Player player, ItemStack treasure, int xp) {
super(player);
this(requireNonNull(UserManager.getPlayer(player)), treasure, xp);
}
public McMMOPlayerFishingTreasureEvent(@NotNull McMMOPlayer mmoPlayer, @Nullable ItemStack treasure, int xp) {
super(mmoPlayer);
this.treasure = treasure;
this.xp = xp;
}
public ItemStack getTreasure() {
public @Nullable ItemStack getTreasure() {
return treasure;
}
public void setTreasure(ItemStack item) {
public void setTreasure(@Nullable ItemStack item) {
this.treasure = item;
}

View File

@ -1,20 +1,32 @@
package com.gmail.nossr50.events.skills.fishing;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
public class McMMOPlayerMagicHunterEvent extends McMMOPlayerFishingTreasureEvent {
private final Map<Enchantment, Integer> enchants;
import static java.util.Objects.requireNonNull;
public McMMOPlayerMagicHunterEvent(Player player, ItemStack treasure, int xp, Map<Enchantment, Integer> enchants) {
super(player, treasure, xp);
this.enchants = enchants;
public class McMMOPlayerMagicHunterEvent extends McMMOPlayerFishingTreasureEvent {
private final Map<Enchantment, Integer> enchants = new HashMap<>();
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerMagicHunterEvent(@NotNull Player player, @NotNull ItemStack treasure, int xp, @NotNull Map<Enchantment, Integer> enchants) {
this(requireNonNull(UserManager.getPlayer(player)), treasure, xp, enchants);
}
public Map<Enchantment, Integer> getEnchantments() {
public McMMOPlayerMagicHunterEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull ItemStack treasure, int xp, @NotNull Map<Enchantment, Integer> enchants) {
super(mmoPlayer, treasure, xp);
requireNonNull(enchants, "enchants cannot be null");
this.enchants.putAll(enchants);
}
public @NotNull Map<Enchantment, Integer> getEnchantments() {
return enchants;
}
}

View File

@ -1,11 +1,16 @@
package com.gmail.nossr50.events.skills.secondaryabilities;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable {
private SubSkillType subSkillType;
@ -16,9 +21,20 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* Only skills using the old system will fire this event
* @param player target player
* @param subSkillType target subskill
* @deprecated Use {@link #SubSkillEvent(McMMOPlayer, SubSkillType)} instead
*/
public SubSkillEvent(Player player, SubSkillType subSkillType) {
super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
@Deprecated(forRemoval = true, since = "2.2.010")
public SubSkillEvent(@NotNull Player player, @NotNull SubSkillType subSkillType) {
this(requireNonNull(UserManager.getPlayer(player)), subSkillType);
}
/**
* Only skills using the old system will fire this event
* @param mmoPlayer target player
* @param subSkillType target subskill
*/
public SubSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull SubSkillType subSkillType) {
super(mmoPlayer, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType;
}
@ -28,15 +44,30 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* @param subSkillType target subskill
* @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0
*/
public SubSkillEvent(Player player, SubSkillType subSkillType, double resultModifier) {
@Deprecated(forRemoval = true, since = "2.2.010")
public SubSkillEvent(@NotNull Player player, @NotNull SubSkillType subSkillType, double resultModifier) {
this(requireNonNull(UserManager.getPlayer(player)), subSkillType, resultModifier);
}
/**
* Only skills using the old system will fire this event
* @param player target player
* @param subSkillType target subskill
* @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0
*/
public SubSkillEvent(@NotNull McMMOPlayer player, @NotNull SubSkillType subSkillType, double resultModifier) {
super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType;
this.subSkillType = requireNonNull(subSkillType, "subSkillType cannot be null");
this.resultModifier = resultModifier;
}
public SubSkillEvent(Player player, AbstractSubSkill abstractSubSkill)
{
super(player, abstractSubSkill.getPrimarySkill());
@Deprecated(forRemoval = true, since = "2.2.010")
public SubSkillEvent(@NotNull Player player, @NotNull AbstractSubSkill abstractSubSkill) {
this(requireNonNull(UserManager.getPlayer(player)), abstractSubSkill);
}
public SubSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull AbstractSubSkill abstractSubSkill) {
super(mmoPlayer, abstractSubSkill.getPrimarySkill());
}
public double getResultModifier() {

View File

@ -708,19 +708,16 @@ public class BlockListener implements Listener {
player.sendMessage("[mcMMO DEBUG] World Guard xp flag is not permitted for this player in this region");
}
if(blockState instanceof Furnace furnace)
{
if(mcMMO.getSmeltingTracker().isFurnaceOwned(furnace))
{
player.sendMessage("[mcMMO DEBUG] This furnace has a registered owner");
OfflinePlayer furnacePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
if(furnacePlayer != null)
{
player.sendMessage("[mcMMO DEBUG] This furnace is owned by player "+furnacePlayer.getName());
if(blockState instanceof Furnace || blockState instanceof BrewingStand) {
if(ContainerMetadataUtils.isContainerOwned(blockState)) {
player.sendMessage("[mcMMO DEBUG] This container has a registered owner");
final OfflinePlayer furnacePlayer = ContainerMetadataUtils.getContainerOwner(blockState);
if(furnacePlayer != null) {
player.sendMessage("[mcMMO DEBUG] This container is owned by player "+furnacePlayer.getName());
}
}
else
player.sendMessage("[mcMMO DEBUG] This furnace does not have a registered owner");
player.sendMessage("[mcMMO DEBUG] This container does not have a registered owner");
}
if(ExperienceConfig.getInstance().isExperienceBarsEnabled())

View File

@ -8,7 +8,6 @@ import com.gmail.nossr50.datatypes.skills.subskills.interfaces.InteractType;
import com.gmail.nossr50.events.fake.FakeEntityTameEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.metadata.MobMetaFlagType;
import com.gmail.nossr50.metadata.MobMetadataService;
import com.gmail.nossr50.runnables.TravelingBlockMetaCleanup;
import com.gmail.nossr50.skills.archery.Archery;
import com.gmail.nossr50.skills.crossbows.Crossbows;
@ -47,9 +46,10 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource;
import org.jetbrains.annotations.NotNull;
import static com.gmail.nossr50.util.MobMetadataUtils.*;
public class EntityListener implements Listener {
private final mcMMO pluginRef;
private final @NotNull MobMetadataService mobMetadataService;
/**
* We can use this {@link NamespacedKey} for {@link Enchantment} comparisons to
@ -59,7 +59,6 @@ public class EntityListener implements Listener {
public EntityListener(final mcMMO pluginRef) {
this.pluginRef = pluginRef;
mobMetadataService = mcMMO.getMetadataService().getMobMetadataService();
}
@EventHandler(priority = EventPriority.MONITOR)
@ -67,10 +66,10 @@ public class EntityListener implements Listener {
if(event.getEntity() instanceof LivingEntity livingEntity) {
//Transfer metadata keys from mob-spawned mobs to new mobs
if(mobMetadataService.hasMobFlags(livingEntity)) {
if(hasMobFlags(livingEntity)) {
for(Entity entity : event.getTransformedEntities()) {
if(entity instanceof LivingEntity transformedEntity) {
mobMetadataService.addMobFlags(livingEntity, transformedEntity);
addMobFlags(livingEntity, transformedEntity);
}
}
}
@ -93,8 +92,8 @@ public class EntityListener implements Listener {
{
if(event.getEntity() instanceof Enderman enderman) {
if(!mobMetadataService.hasMobFlag(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman)) {
mobMetadataService.flagMetadata(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman);
if(!hasMobFlag(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman)) {
flagMetadata(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman);
}
}
}
@ -168,7 +167,7 @@ public class EntityListener implements Listener {
return;
}
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_ARROW_RETRIEVAL, player)) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_ARROW_RETRIEVAL, UserManager.getPlayer(player))) {
arrow.setMetadata(MetadataConstants.METADATA_KEY_TRACKED_ARROW, MetadataConstants.MCMMO_METADATA_VALUE);
}
}
@ -730,11 +729,11 @@ public class EntityListener implements Listener {
}
private void trackSpawnedAndPassengers(LivingEntity livingEntity, MobMetaFlagType mobMetaFlagType) {
mobMetadataService.flagMetadata(mobMetaFlagType, livingEntity);
flagMetadata(mobMetaFlagType, livingEntity);
for(Entity passenger : livingEntity.getPassengers()) {
if(passenger != null) {
mobMetadataService.flagMetadata(mobMetaFlagType, livingEntity);
flagMetadata(mobMetaFlagType, livingEntity);
}
}
}
@ -742,7 +741,7 @@ public class EntityListener implements Listener {
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityBreed(EntityBreedEvent event) {
if(ExperienceConfig.getInstance().isCOTWBreedingPrevented()) {
if(mobMetadataService.hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, event.getFather()) || mobMetadataService.hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, event.getMother())) {
if(hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, event.getFather()) || hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, event.getMother())) {
event.setCancelled(true);
Animals mom = (Animals) event.getMother();
Animals father = (Animals) event.getFather();
@ -1005,12 +1004,12 @@ public class EntityListener implements Listener {
if (!UserManager.hasPlayerDataKey(player)
|| (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(livingEntity))
|| mobMetadataService.hasMobFlag(MobMetaFlagType.EGG_MOB, livingEntity)
|| mobMetadataService.hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, livingEntity)) {
|| hasMobFlag(MobMetaFlagType.EGG_MOB, livingEntity)
|| hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, livingEntity)) {
return;
}
mobMetadataService.flagMetadata(MobMetaFlagType.PLAYER_TAMED_MOB, livingEntity);
flagMetadata(MobMetaFlagType.PLAYER_TAMED_MOB, livingEntity);
//Profile not loaded
if(UserManager.getPlayer(player) == null)

View File

@ -5,11 +5,11 @@ 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.events.fake.FakeBrewEvent;
import com.gmail.nossr50.events.fake.FakeEvent;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
import com.gmail.nossr50.skills.alchemy.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.ContainerMetadataUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.Permissions;
@ -29,7 +29,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BrewingStartEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.inventory.*;
@ -55,7 +54,7 @@ public class InventoryListener implements Listener {
}
Furnace furnace = (Furnace) furnaceState;
OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(furnace);
Player player;
if(offlinePlayer != null && offlinePlayer.isOnline() && offlinePlayer instanceof Player) {
@ -101,7 +100,7 @@ public class InventoryListener implements Listener {
}
if(blockState instanceof Furnace furnace) {
OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace);
OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(furnace);
if(offlinePlayer != null) {
@ -167,16 +166,16 @@ public class InventoryListener implements Listener {
Inventory inventory = event.getInventory();
Player player = ((Player) event.getWhoClicked()).getPlayer();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(event.getInventory() instanceof FurnaceInventory)
{
Furnace furnace = mcMMO.getSmeltingTracker().getFurnaceFromInventory(event.getInventory());
if (furnace != null)
{
if(event.getInventory() instanceof FurnaceInventory furnaceInventory) {
//Switch owners
mcMMO.getSmeltingTracker().processFurnaceOwnership(furnace, player);
ContainerMetadataUtils.processContainerOwnership(furnaceInventory.getHolder(), player);
}
if(event.getInventory() instanceof BrewerInventory brewerInventory) {
// switch owners
ContainerMetadataUtils.processContainerOwnership(brewerInventory.getHolder(), player);
}
if (!(inventory instanceof BrewerInventory)) {
@ -191,10 +190,11 @@ public class InventoryListener implements Listener {
HumanEntity whoClicked = event.getWhoClicked();
if (!UserManager.hasPlayerDataKey(event.getWhoClicked()) || !Permissions.isSubSkillEnabled(whoClicked, SubSkillType.ALCHEMY_CONCOCTIONS)) {
if (mmoPlayer == null || !Permissions.isSubSkillEnabled(whoClicked, SubSkillType.ALCHEMY_CONCOCTIONS)) {
return;
}
// TODO: Investigate why this WG check is all the way down here?
/* WORLD GUARD MAIN FLAG CHECK */
if(WorldGuardUtils.isWorldGuardLoaded())
{
@ -202,11 +202,16 @@ public class InventoryListener implements Listener {
return;
}
ItemStack clicked = event.getCurrentItem();
ItemStack cursor = event.getCursor();
final ItemStack clicked = event.getCurrentItem();
final ItemStack cursor = event.getCursor();
if ((clicked != null && (clicked.getType() == Material.POTION || clicked.getType() == Material.SPLASH_POTION || clicked.getType() == Material.LINGERING_POTION)) || (cursor != null && (cursor.getType() == Material.POTION || cursor.getType() == Material.SPLASH_POTION || cursor.getType() == Material.LINGERING_POTION))) {
AlchemyPotionBrewer.scheduleCheck(player, stand);
if ((clicked != null && (clicked.getType() == Material.POTION
|| clicked.getType() == Material.SPLASH_POTION
|| clicked.getType() == Material.LINGERING_POTION))
|| (cursor != null && (cursor.getType() == Material.POTION
|| cursor.getType() == Material.SPLASH_POTION
|| cursor.getType() == Material.LINGERING_POTION))) {
AlchemyPotionBrewer.scheduleCheck(stand);
return;
}
@ -216,11 +221,11 @@ public class InventoryListener implements Listener {
if (click.isShiftClick()) {
switch (slot) {
case FUEL:
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
return;
case CONTAINER:
case QUICKBAR:
if (!AlchemyPotionBrewer.isValidIngredient(player, clicked)) {
if (!AlchemyPotionBrewer.isValidIngredientByPlayer(player, clicked)) {
return;
}
@ -230,7 +235,7 @@ public class InventoryListener implements Listener {
event.setCancelled(true);
AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
return;
default:
}
@ -240,14 +245,14 @@ public class InventoryListener implements Listener {
if (AlchemyPotionBrewer.isEmpty(cursor)) {
if (emptyClicked && click == ClickType.NUMBER_KEY) {
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
return;
}
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
}
else if (emptyClicked) {
if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
if (AlchemyPotionBrewer.isValidIngredientByPlayer(player, cursor)) {
int amount = cursor.getAmount();
if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) {
@ -256,7 +261,7 @@ public class InventoryListener implements Listener {
event.setCursor(null);
AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
}
else if (click == ClickType.RIGHT) {
event.setCancelled(true);
@ -271,7 +276,7 @@ public class InventoryListener implements Listener {
event.setCursor(rest);
AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand);
AlchemyPotionBrewer.scheduleCheck(stand);
}
}
}
@ -324,9 +329,9 @@ public class InventoryListener implements Listener {
return;
}
if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) {
if (AlchemyPotionBrewer.isValidIngredientByPlayer(player, cursor)) {
// Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
AlchemyPotionBrewer.scheduleCheck(player, (BrewingStand) holder);
AlchemyPotionBrewer.scheduleCheck((BrewingStand) holder);
return;
}
@ -371,17 +376,15 @@ public class InventoryListener implements Listener {
if(WorldBlacklist.isWorldBlacklisted(event.getSource().getLocation().getWorld()))
return;
Inventory inventory = event.getDestination();
final Inventory inventory = event.getDestination();
if (!(inventory instanceof BrewerInventory)) {
return;
}
InventoryHolder holder = inventory.getHolder();
final InventoryHolder holder = inventory.getHolder();
if (!(holder instanceof BrewingStand)) {
return;
}
if (holder instanceof BrewingStand brewingStand) {
ItemStack item = event.getItem();
@ -394,9 +397,20 @@ public class InventoryListener implements Listener {
event.setCancelled(true);
return;
}
int ingredientLevel = 1;
if (mcMMO.p.getGeneralConfig().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(brewingStand);
if (offlinePlayer != null && offlinePlayer.isOnline()) {
McMMOPlayer mmoPlayer = UserManager.getPlayer(offlinePlayer.getPlayer());
if (mmoPlayer != null) {
ingredientLevel = mmoPlayer.getAlchemyManager().getTier();
}
}
if (mcMMO.p.getGeneralConfig().getEnabledForHoppers()
&& AlchemyPotionBrewer.isValidIngredientByLevel(ingredientLevel, item)) {
AlchemyPotionBrewer.scheduleCheck(brewingStand);
}
}
}

View File

@ -19,7 +19,6 @@ import com.gmail.nossr50.database.DatabaseManagerFactory;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll;
import com.gmail.nossr50.listeners.*;
import com.gmail.nossr50.metadata.MetadataService;
import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.placeholders.PapiExpansion;
import com.gmail.nossr50.runnables.SaveTimerTask;
@ -50,7 +49,6 @@ import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.util.skills.SmeltingTracker;
import com.gmail.nossr50.util.upgrade.UpgradeManager;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.tcoded.folialib.FoliaLib;
@ -80,7 +78,6 @@ import java.util.List;
public class mcMMO extends JavaPlugin {
/* Managers & Services */
private static PlatformManager platformManager;
private static MetadataService metadataService;
private static ChunkManager placeStore;
private static RepairableManager repairableManager;
private static SalvageableManager salvageableManager;
@ -90,12 +87,10 @@ public class mcMMO extends JavaPlugin {
private static UpgradeManager upgradeManager;
private static MaterialMapStore materialMapStore;
private static PlayerLevelUtils playerLevelUtils;
private static SmeltingTracker smeltingTracker;
private static TransientMetadataTools transientMetadataTools;
private static ChatManager chatManager;
private static CommandManager commandManager; //ACF
private static TransientEntityTracker transientEntityTracker;
// private static ProtocolLibManager protocolLibManager;
private SkillTools skillTools;
@ -186,9 +181,6 @@ public class mcMMO extends JavaPlugin {
//Platform Manager
platformManager = new PlatformManager();
//metadata service
metadataService = new MetadataService(this);
MetadataConstants.MCMMO_METADATA_VALUE = new FixedMetadataValue(this, true);
PluginManager pluginManager = getServer().getPluginManager();
@ -319,9 +311,6 @@ public class mcMMO extends JavaPlugin {
//Init the blacklist
worldBlacklist = new WorldBlacklist(this);
//Init smelting tracker
smeltingTracker = new SmeltingTracker();
//Set up Adventure's audiences
audiences = BukkitAudiences.create(this);
@ -482,10 +471,6 @@ public class mcMMO extends JavaPlugin {
return platformManager.getCompatibilityManager();
}
public static MetadataService getMetadataService() {
return metadataService;
}
@Deprecated
public static void setDatabaseManager(DatabaseManager databaseManager) {
mcMMO.databaseManager = databaseManager;
@ -741,10 +726,6 @@ public class mcMMO extends JavaPlugin {
return platformManager;
}
public static SmeltingTracker getSmeltingTracker() {
return smeltingTracker;
}
public static BukkitAudiences getAudiences() {
return audiences;
}

View File

@ -1,49 +0,0 @@
package com.gmail.nossr50.metadata;
import com.gmail.nossr50.mcMMO;
import org.bukkit.block.Furnace;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import static com.gmail.nossr50.metadata.MetadataService.NSK_FURNACE_UUID_LEAST_SIG;
import static com.gmail.nossr50.metadata.MetadataService.NSK_FURNACE_UUID_MOST_SIG;
public class BlockMetadataService {
private final @NotNull mcMMO pluginRef;
public BlockMetadataService(@NotNull mcMMO pluginRef) {
this.pluginRef = pluginRef;
}
public @Nullable UUID getFurnaceOwner(@NotNull Furnace furnace) {
//Get container from entity
PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
//Too lazy to make a custom data type for this stuff
Long mostSigBits = dataContainer.get(NSK_FURNACE_UUID_MOST_SIG, PersistentDataType.LONG);
Long leastSigBits = dataContainer.get(NSK_FURNACE_UUID_LEAST_SIG, PersistentDataType.LONG);
if (mostSigBits != null && leastSigBits != null) {
return new UUID(mostSigBits, leastSigBits);
} else {
return null;
}
}
public void setFurnaceOwner(@NotNull Furnace furnace, @NotNull UUID uuid) {
PersistentDataContainer dataContainer = ((PersistentDataHolder) furnace).getPersistentDataContainer();
dataContainer.set(NSK_FURNACE_UUID_MOST_SIG, PersistentDataType.LONG, uuid.getMostSignificantBits());
dataContainer.set(NSK_FURNACE_UUID_LEAST_SIG, PersistentDataType.LONG, uuid.getLeastSignificantBits());
furnace.update();
}
}

View File

@ -1,71 +0,0 @@
package com.gmail.nossr50.metadata;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.MetadataConstants;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
public class MetadataService {
private final @NotNull mcMMO pluginRef;
protected static final @NotNull NamespacedKey NSK_SUPER_ABILITY_BOOSTED_ITEM;
protected static final @NotNull NamespacedKey NSK_MOB_SPAWNER_MOB;
protected static final @NotNull NamespacedKey NSK_EGG_MOB;
protected static final @NotNull NamespacedKey NSK_NETHER_GATE_MOB;
protected static final @NotNull NamespacedKey NSK_COTW_SUMMONED_MOB;
protected static final @NotNull NamespacedKey NSK_PLAYER_BRED_MOB;
protected static final @NotNull NamespacedKey NSK_PLAYER_TAMED_MOB;
protected static final @NotNull NamespacedKey NSK_VILLAGER_TRADE_ORIGIN_ITEM;
protected static final @NotNull NamespacedKey NSK_EXPLOITED_ENDERMEN;
protected static final @NotNull NamespacedKey NSK_FURNACE_UUID_MOST_SIG;
protected static final @NotNull NamespacedKey NSK_FURNACE_UUID_LEAST_SIG;
static {
NSK_SUPER_ABILITY_BOOSTED_ITEM = getNamespacedKey(MetadataConstants.METADATA_KEY_SUPER_ABILITY_BOOSTED_ITEM);
NSK_MOB_SPAWNER_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_MOB_SPAWNER_MOB);
NSK_EGG_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_EGG_MOB);
NSK_NETHER_GATE_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_NETHER_PORTAL_MOB);
NSK_COTW_SUMMONED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_COTW_SUMMONED_MOB);
NSK_PLAYER_BRED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_PLAYER_BRED_MOB);
NSK_PLAYER_TAMED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_PLAYER_TAMED_MOB);
NSK_VILLAGER_TRADE_ORIGIN_ITEM = getNamespacedKey(MetadataConstants.METADATA_KEY_VILLAGER_TRADE_ORIGIN_ITEM);
NSK_EXPLOITED_ENDERMEN = getNamespacedKey(MetadataConstants.METADATA_KEY_EXPLOITED_ENDERMEN);
NSK_FURNACE_UUID_MOST_SIG = getNamespacedKey(MetadataConstants.METADATA_KEY_FURNACE_UUID_MOST_SIG);
NSK_FURNACE_UUID_LEAST_SIG = getNamespacedKey(MetadataConstants.METADATA_KEY_FURNACE_UUID_LEAST_SIG);
}
private final @NotNull ItemMetadataService itemMetadataService;
private final @NotNull MobMetadataService mobMetadataService;
private final @NotNull BlockMetadataService blockMetadataService;
public MetadataService(@NotNull mcMMO pluginRef) {
this.pluginRef = pluginRef;
blockMetadataService = new BlockMetadataService(pluginRef);
mobMetadataService = new MobMetadataService(pluginRef);
itemMetadataService = new ItemMetadataService(pluginRef);
}
/**
* Helper method to simplify generating namespaced keys
*
* @param key the {@link String} value of the key
*
* @return the generated {@link NamespacedKey}
*/
public static @NotNull NamespacedKey getNamespacedKey(@NotNull String key) {
return new NamespacedKey(mcMMO.p, key);
}
public @NotNull ItemMetadataService getItemMetadataService() {
return itemMetadataService;
}
public @NotNull MobMetadataService getMobMetadataService() {
return mobMetadataService;
}
public @NotNull BlockMetadataService getBlockMetadataService() {
return blockMetadataService;
}
}

View File

@ -1,32 +1,51 @@
package com.gmail.nossr50.runnables.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.skills.alchemy.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.CancellableRunnable;
import org.bukkit.Bukkit;
import com.gmail.nossr50.util.ContainerMetadataUtils;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import static com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer.isValidBrew;
import static com.gmail.nossr50.util.EventUtils.getMcMMOPlayer;
public class AlchemyBrewCheckTask extends CancellableRunnable {
private final Player player;
private final BrewingStand brewingStand;
private final ItemStack[] oldInventory;
public AlchemyBrewCheckTask(Player player, BrewingStand brewingStand) {
this.player = player;
@Deprecated(forRemoval = true, since = "2.2.010")
public AlchemyBrewCheckTask(@Nullable Player ignored, BrewingStand brewingStand) {
this(brewingStand);
}
public AlchemyBrewCheckTask(@NotNull BrewingStand brewingStand) {
this.brewingStand = brewingStand;
this.oldInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
}
@Override
public void run() {
Location location = brewingStand.getLocation();
ItemStack[] newInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
boolean validBrew = brewingStand.getFuelLevel() > 0 && AlchemyPotionBrewer.isValidBrew(player, newInventory);
OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(brewingStand);
int ingredientLevel = 1;
if (offlinePlayer != null && offlinePlayer.isOnline()) {
final McMMOPlayer mmoPlayer = UserManager.getPlayer(offlinePlayer.getPlayer());
if (mmoPlayer != null) {
ingredientLevel = mmoPlayer.getAlchemyManager().getTier();
}
}
final Location location = brewingStand.getLocation();
final ItemStack[] newInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
boolean validBrew = brewingStand.getFuelLevel() > 0 && isValidBrew(ingredientLevel, newInventory);
if (Alchemy.brewingStandMap.containsKey(location)) {
if (oldInventory[Alchemy.INGREDIENT_SLOT] == null
@ -36,7 +55,7 @@ public class AlchemyBrewCheckTask extends CancellableRunnable {
Alchemy.brewingStandMap.get(location).cancelBrew();
}
} else if (validBrew) {
Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand, player));
Alchemy.brewingStandMap.put(location, new AlchemyBrewTask(brewingStand));
}
}
}

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.runnables.skills;
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.events.skills.alchemy.McMMOPlayerBrewEvent;
@ -8,44 +9,56 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.alchemy.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.CancellableRunnable;
import com.gmail.nossr50.util.ContainerMetadataUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class AlchemyBrewTask extends CancellableRunnable {
private static final double DEFAULT_BREW_SPEED = 1.0;
private static final int DEFAULT_BREW_TICKS = 400;
private final BlockState brewingStand;
private final Location location;
private final OfflinePlayer offlinePlayer;
private McMMOPlayer mmoPlayer;
private double brewSpeed;
private double brewTimer;
private final Player player;
private int fuel;
private boolean firstRun = true;
private int ingredientLevel = 1;
@Deprecated(forRemoval = true, since = "2.2.010")
public AlchemyBrewTask(@NotNull BlockState brewingStand, Player ignored) {
this(brewingStand);
}
public AlchemyBrewTask(@NotNull BlockState brewingStand) {
offlinePlayer = ContainerMetadataUtils.getContainerOwner(brewingStand);
McMMOPlayer mmoPlayer = null;
if (offlinePlayer != null && offlinePlayer.isOnline()) {
mmoPlayer = UserManager.getPlayer(offlinePlayer.getPlayer());
}
public AlchemyBrewTask(BlockState brewingStand, Player player) {
this.brewingStand = brewingStand;
this.location = brewingStand.getLocation();
this.player = player;
brewSpeed = DEFAULT_BREW_SPEED;
brewTimer = DEFAULT_BREW_TICKS;
if (player != null
&& !Misc.isNPCEntityExcludingVillagers(player)
&& Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS)
&& UserManager.getPlayer(player) != null) {
if (mmoPlayer != null
&& !Misc.isNPCEntityExcludingVillagers(mmoPlayer.getPlayer())
&& Permissions.isSubSkillEnabled(mmoPlayer.getPlayer(), SubSkillType.ALCHEMY_CATALYSIS)) {
ingredientLevel = mmoPlayer.getAlchemyManager().getTier();
double catalysis = UserManager.getPlayer(player).getAlchemyManager().calculateBrewSpeed(Permissions.lucky(player, PrimarySkillType.ALCHEMY));
double catalysis = mmoPlayer.getAlchemyManager().calculateBrewSpeed(Permissions.lucky(mmoPlayer.getPlayer(),
PrimarySkillType.ALCHEMY));
McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(player, catalysis);
McMMOPlayerCatalysisEvent event = new McMMOPlayerCatalysisEvent(mmoPlayer, catalysis);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
@ -53,8 +66,8 @@ public class AlchemyBrewTask extends CancellableRunnable {
}
}
if (Alchemy.brewingStandMap.containsKey(location)) {
Alchemy.brewingStandMap.get(location).cancel();
if (Alchemy.brewingStandMap.containsKey(brewingStand.getLocation())) {
Alchemy.brewingStandMap.get(brewingStand.getLocation()).cancel();
}
fuel = ((BrewingStand) brewingStand).getFuelLevel();
@ -62,16 +75,16 @@ public class AlchemyBrewTask extends CancellableRunnable {
if (((BrewingStand) brewingStand).getBrewingTime() == -1) // Only decrement on our end if it isn't a vanilla ingredient.
fuel--;
Alchemy.brewingStandMap.put(location, this);
mcMMO.p.getFoliaLib().getImpl().runAtLocationTimer(location, this, 1, 1);
Alchemy.brewingStandMap.put(brewingStand.getLocation(), this);
mcMMO.p.getFoliaLib().getImpl().runAtLocationTimer(brewingStand.getLocation(), this, 1, 1);
}
@Override
public void run() {
// Check if preconditions for brewing are not met
if (shouldCancelBrewing()) {
if (Alchemy.brewingStandMap.containsKey(location)) {
Alchemy.brewingStandMap.remove(location);
if (Alchemy.brewingStandMap.containsKey(brewingStand.getLocation())) {
Alchemy.brewingStandMap.remove(brewingStand.getLocation());
}
this.cancel();
return;
@ -93,10 +106,7 @@ public class AlchemyBrewTask extends CancellableRunnable {
}
private boolean shouldCancelBrewing() {
if (player == null) {
return true;
}
if (!player.isValid()) {
if (offlinePlayer == null) {
return true;
}
if (brewingStand == null) {
@ -105,10 +115,24 @@ public class AlchemyBrewTask extends CancellableRunnable {
if (brewingStand.getType() != Material.BREWING_STAND) {
return true;
}
if (!AlchemyPotionBrewer.isValidIngredient(player, ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT])) {
return true;
return !AlchemyPotionBrewer.isValidIngredientByLevel(
getIngredientLevelUpdated(), ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT]);
}
private int getIngredientLevelUpdated() {
if (mmoPlayer != null) {
ingredientLevel = mmoPlayer.getAlchemyManager().getTier();
return ingredientLevel;
} else if (offlinePlayer.isOnline() && mmoPlayer == null) {
final McMMOPlayer fetchedMMOPlayer = UserManager.getPlayer(offlinePlayer.getPlayer());
if (fetchedMMOPlayer != null) {
this.mmoPlayer = fetchedMMOPlayer;
ingredientLevel = mmoPlayer.getAlchemyManager().getTier();
}
return ingredientLevel;
} else {
return ingredientLevel;
}
return false;
}
private void initializeBrewing() {
@ -128,27 +152,27 @@ public class AlchemyBrewTask extends CancellableRunnable {
private void finish() {
McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand);
final McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(mmoPlayer, brewingStand);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
AlchemyPotionBrewer.finishBrewing(brewingStand, player, false);
AlchemyPotionBrewer.finishBrewing(brewingStand, mmoPlayer.getPlayer(), false);
}
Alchemy.brewingStandMap.remove(location);
Alchemy.brewingStandMap.remove(brewingStand.getLocation());
}
public void finishImmediately() {
this.cancel();
AlchemyPotionBrewer.finishBrewing(brewingStand, player, true);
Alchemy.brewingStandMap.remove(location);
AlchemyPotionBrewer.finishBrewing(brewingStand, mmoPlayer.getPlayer(), true);
Alchemy.brewingStandMap.remove(brewingStand.getLocation());
}
public void cancelBrew() {
this.cancel();
((BrewingStand) brewingStand).setBrewingTime(-1);
Alchemy.brewingStandMap.remove(location);
Alchemy.brewingStandMap.remove(brewingStand.getLocation());
}
}

View File

@ -14,6 +14,7 @@ import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.RankUtils;
@ -94,7 +95,7 @@ public class AcrobaticsManager extends SkillManager {
Player player = getPlayer();
if (!isFatal(modifiedDamage)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_DODGE, player)) {
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_DODGE, UserManager.getPlayer(player))) {
ParticleEffectUtils.playDodgeEffect(player);
if (mmoPlayer.useChatNotifications()) {

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.alchemy;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
@ -9,7 +10,6 @@ import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
import com.gmail.nossr50.runnables.skills.AlchemyBrewCheckTask;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand;
@ -20,14 +20,39 @@ import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
// TODO: Update to use McMMOPlayer
public final class AlchemyPotionBrewer {
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isValidBrew(Player player, ItemStack[] contents) {
if (!isValidIngredient(player, contents[Alchemy.INGREDIENT_SLOT])) {
if (!isValidIngredientByPlayer(player, contents[Alchemy.INGREDIENT_SLOT])) {
return false;
}
for (int i = 0; i < 3; i++) {
if (contents[i] == null || contents[i].getType() != Material.POTION
&& contents[i].getType() != Material.SPLASH_POTION
&& contents[i].getType() != Material.LINGERING_POTION) {
continue;
}
final AlchemyPotion potion = mcMMO.p.getPotionConfig().getPotion(contents[i]);
if (getChildPotion(potion, contents[Alchemy.INGREDIENT_SLOT]) != null) {
return true;
}
}
return false;
}
public static boolean isValidBrew(int ingredientLevel, ItemStack[] contents) {
if (!isValidIngredientByLevel(ingredientLevel, contents[Alchemy.INGREDIENT_SLOT])) {
return false;
}
@ -65,7 +90,7 @@ public final class AlchemyPotionBrewer {
ItemStack ingredient = inventory.getIngredient().clone();
if (!isEmpty(ingredient) && isValidIngredient(player, ingredient)) {
if (!isEmpty(ingredient) && isValidIngredientByPlayer(player, ingredient)) {
if (ingredient.getAmount() <= 1) {
inventory.setIngredient(null);
}
@ -79,15 +104,15 @@ public final class AlchemyPotionBrewer {
private static boolean hasIngredient(BrewerInventory inventory, Player player) {
ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone();
return !isEmpty(ingredient) && isValidIngredient(player, ingredient);
return !isEmpty(ingredient) && isValidIngredientByPlayer(player, ingredient);
}
public static boolean isValidIngredient(Player player, ItemStack item) {
public static boolean isValidIngredientByPlayer(Player player, ItemStack item) {
if (isEmpty(item)) {
return false;
}
for (ItemStack ingredient : getValidIngredients(player)) {
for (ItemStack ingredient : getValidIngredients(UserManager.getPlayer(player))) {
if (item.isSimilar(ingredient)) {
return true;
}
@ -96,12 +121,28 @@ public final class AlchemyPotionBrewer {
return false;
}
private static List<ItemStack> getValidIngredients(Player player) {
if(player == null || UserManager.getPlayer(player) == null) {
public static boolean isValidIngredientByLevel(int ingredientLevel, ItemStack item) {
if (isEmpty(item)) {
return false;
}
// TODO: Update this when we fix loading from hoppers
for (ItemStack ingredient : mcMMO.p.getPotionConfig().getIngredients(ingredientLevel)) {
if (item.isSimilar(ingredient)) {
return true;
}
}
return false;
}
private static List<ItemStack> getValidIngredients(@Nullable McMMOPlayer mmoPlayer) {
if(mmoPlayer == null) {
return mcMMO.p.getPotionConfig().getIngredients(1);
}
return mcMMO.p.getPotionConfig().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
return mcMMO.p.getPotionConfig().getIngredients(!Permissions.isSubSkillEnabled(mmoPlayer, SubSkillType.ALCHEMY_CONCOCTIONS)
? 1 : mmoPlayer.getAlchemyManager().getTier());
}
public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
@ -280,8 +321,9 @@ public final class AlchemyPotionBrewer {
return false;
}
public static void scheduleCheck(Player player, BrewingStand brewingStand) {
mcMMO.p.getFoliaLib().getImpl().runAtEntity(player, new AlchemyBrewCheckTask(player, brewingStand));
public static void scheduleCheck(@NotNull BrewingStand brewingStand) {
mcMMO.p.getFoliaLib().getImpl().runAtLocation(
brewingStand.getLocation(), new AlchemyBrewCheckTask(brewingStand));
}
public static void scheduleUpdate(Inventory inventory) {

View File

@ -89,7 +89,7 @@ public class ArcheryManager extends SkillManager {
* @param defender The {@link Player} being affected by the ability
*/
public double daze(Player defender) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_DAZE, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_DAZE, mmoPlayer)) {
return 0;
}
@ -116,7 +116,7 @@ public class ArcheryManager extends SkillManager {
* @param oldDamage The raw damage value of this arrow before we modify it
*/
public double skillShot(double oldDamage) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.ARCHERY_SKILL_SHOT, getPlayer())) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.ARCHERY_SKILL_SHOT, mmoPlayer)) {
return Archery.getSkillShotBonusDamage(getPlayer(), oldDamage);
} else {
return oldDamage;

View File

@ -18,6 +18,7 @@ import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
@ -69,7 +70,7 @@ public class AxesManager extends SkillManager {
* Handle the effects of the Axe Mastery ability
*/
public double axeMastery() {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.AXES_AXE_MASTERY, getPlayer())) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.AXES_AXE_MASTERY, mmoPlayer)) {
return Axes.getAxeMasteryBonusDamage(getPlayer());
}
@ -83,7 +84,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, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_CRITICAL_STRIKES, mmoPlayer)) {
return 0;
}
@ -115,10 +116,15 @@ public class AxesManager extends SkillManager {
*/
public void impactCheck(@NotNull LivingEntity target) {
double durabilityDamage = getImpactDurabilityDamage();
final EntityEquipment equipment = target.getEquipment();
for (ItemStack armor : target.getEquipment().getArmorContents()) {
if (equipment == null) {
return;
}
for (ItemStack armor : equipment.getArmorContents()) {
if (armor != null && ItemUtils.isArmor(armor)) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_ARMOR_IMPACT, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_ARMOR_IMPACT, mmoPlayer)) {
SkillUtils.handleArmorDurabilityChange(armor, durabilityDamage, 1);
}
}
@ -136,7 +142,7 @@ public class AxesManager extends SkillManager {
*/
public double greaterImpact(@NotNull LivingEntity target) {
//static chance (3rd param)
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_GREATER_IMPACT, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.AXES_GREATER_IMPACT, mmoPlayer)) {
return 0;
}

View File

@ -100,7 +100,7 @@ public class CrossbowsManager extends SkillManager {
}
public double poweredShot(double oldDamage) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.CROSSBOWS_POWERED_SHOT, getPlayer())) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.CROSSBOWS_POWERED_SHOT, mmoPlayer)) {
return getPoweredShotBonusDamage(getPlayer(), oldDamage);
} else {
return oldDamage;

View File

@ -46,7 +46,8 @@ public class ExcavationManager extends SkillManager {
for (ExcavationTreasure treasure : treasures) {
if (skillLevel >= treasure.getDropLevel()
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.EXCAVATION, getPlayer(), treasure.getDropProbability())) {
&& ProbabilityUtil.isStaticSkillRNGSuccessful(
PrimarySkillType.EXCAVATION, mmoPlayer, treasure.getDropProbability())) {
processExcavationBonusesOnBlock(blockState, treasure, location);
}
}
@ -65,7 +66,8 @@ public class ExcavationManager extends SkillManager {
@VisibleForTesting
public void processExcavationBonusesOnBlock(BlockState blockState, ExcavationTreasure treasure, Location location) {
//Spawn Vanilla XP orbs if a dice roll succeeds
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.EXCAVATION, getPlayer(), getArchaelogyExperienceOrbChance())) {
if(ProbabilityUtil.isStaticSkillRNGSuccessful(
PrimarySkillType.EXCAVATION, mmoPlayer, getArchaelogyExperienceOrbChance())) {
Misc.spawnExperienceOrb(location, getExperienceOrbsReward());
}

View File

@ -412,13 +412,13 @@ public class FishingManager extends SkillManager {
enchants.putAll(treasureDrop.getItemMeta().getEnchants());
}
event = EventUtils.callFishingTreasureEvent(player, treasureDrop, treasure.getXp(), enchants);
event = EventUtils.callFishingTreasureEvent(mmoPlayer, treasureDrop, treasure.getXp(), enchants);
} else {
if (isMagicHunterEnabled() && ItemUtils.isEnchantable(treasureDrop)) {
enchants = processMagicHunter(treasureDrop);
}
event = EventUtils.callFishingTreasureEvent(player, treasureDrop, treasure.getXp(), enchants);
event = EventUtils.callFishingTreasureEvent(mmoPlayer, treasureDrop, treasure.getXp(), enchants);
}
if (!event.isCancelled()) {
@ -480,7 +480,7 @@ public class FishingManager extends SkillManager {
* @param target The {@link LivingEntity} affected by the ability
*/
public void shakeCheck(@NotNull LivingEntity target) {
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.FISHING, getPlayer(), getShakeChance())) {
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.FISHING, mmoPlayer, getShakeChance())) {
List<ShakeTreasure> possibleDrops = Fishing.findPossibleDrops(target);
if (possibleDrops == null || possibleDrops.isEmpty()) {

View File

@ -33,7 +33,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
@ -44,6 +43,7 @@ import java.util.*;
import static com.gmail.nossr50.util.ItemUtils.hasItemIncludingOffHand;
import static com.gmail.nossr50.util.ItemUtils.removeItemIncludingOffHand;
import static java.util.Objects.requireNonNull;
public class HerbalismManager extends SkillManager {
public HerbalismManager(McMMOPlayer mcMMOPlayer) {
@ -637,12 +637,13 @@ public class HerbalismManager extends SkillManager {
/**
* Check for success on herbalism double drops
*
* @param blockState target block state
* @return true if double drop succeeds
* @return true if the double drop succeeds
*/
private boolean checkDoubleDrop(BlockState blockState)
{
return BlockUtils.checkDoubleDrops(getPlayer(), blockState, skill, SubSkillType.HERBALISM_DOUBLE_DROPS);
private boolean checkDoubleDrop(@NotNull BlockState blockState) {
requireNonNull(blockState, "BlockState cannot be null");
return BlockUtils.checkDoubleDrops(mmoPlayer, blockState, SubSkillType.HERBALISM_DOUBLE_DROPS);
}
/**
@ -652,7 +653,7 @@ public class HerbalismManager extends SkillManager {
* @return true if the ability was successful, false otherwise
*/
public boolean processGreenThumbBlocks(BlockState blockState) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, mmoPlayer)) {
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.GTh.Fail");
return false;
}
@ -667,7 +668,7 @@ public class HerbalismManager extends SkillManager {
* @return true if the ability was successful, false otherwise
*/
public boolean processHylianLuck(BlockState blockState) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_HYLIAN_LUCK, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_HYLIAN_LUCK, mmoPlayer)) {
return false;
}
@ -676,7 +677,6 @@ public class HerbalismManager extends SkillManager {
return false;
List<HylianTreasure> treasures = TreasureConfig.getInstance().hylianMap.get(friendly);
Player player = getPlayer();
if (treasures.isEmpty()) {
return false;
@ -686,13 +686,13 @@ public class HerbalismManager extends SkillManager {
for (HylianTreasure treasure : treasures) {
if (skillLevel >= treasure.getDropLevel()
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.HERBALISM, player, treasure.getDropChance())) {
if (!EventUtils.simulateBlockBreak(blockState.getBlock(), player)) {
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.HERBALISM, mmoPlayer, treasure.getDropChance())) {
if (!EventUtils.simulateBlockBreak(blockState.getBlock(), mmoPlayer.getPlayer())) {
return false;
}
blockState.setType(Material.AIR);
Misc.spawnItem(getPlayer(), location, treasure.getDrop(), ItemSpawnReason.HYLIAN_LUCK_TREASURE);
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Herbalism.HylianLuck");
NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Herbalism.HylianLuck");
return true;
}
}
@ -706,25 +706,24 @@ public class HerbalismManager extends SkillManager {
* @return true if the ability was successful, false otherwise
*/
public boolean processShroomThumb(BlockState blockState) {
Player player = getPlayer();
PlayerInventory playerInventory = player.getInventory();
PlayerInventory playerInventory = getPlayer().getInventory();
if (!playerInventory.contains(Material.BROWN_MUSHROOM, 1)) {
NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Skills.NeedMore", StringUtils.getPrettyItemString(Material.BROWN_MUSHROOM));
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.REQUIREMENTS_NOT_MET, "Skills.NeedMore", StringUtils.getPrettyItemString(Material.BROWN_MUSHROOM));
return false;
}
if (!playerInventory.contains(Material.RED_MUSHROOM, 1)) {
NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Skills.NeedMore", StringUtils.getPrettyItemString(Material.RED_MUSHROOM));
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.REQUIREMENTS_NOT_MET, "Skills.NeedMore", StringUtils.getPrettyItemString(Material.RED_MUSHROOM));
return false;
}
playerInventory.removeItem(new ItemStack(Material.BROWN_MUSHROOM));
playerInventory.removeItem(new ItemStack(Material.RED_MUSHROOM));
player.updateInventory();
getPlayer().updateInventory();
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_SHROOM_THUMB, player)) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.ShroomThumb.Fail");
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_SHROOM_THUMB, mmoPlayer)) {
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.ShroomThumb.Fail");
return false;
}
@ -789,7 +788,7 @@ public class HerbalismManager extends SkillManager {
return false;
}
if (!greenTerra && !ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, player)) {
if (!greenTerra && !ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, mmoPlayer)) {
return false;
}

View File

@ -2,9 +2,7 @@ package com.gmail.nossr50.skills.maces;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
public class MacesManager extends SkillManager {
public MacesManager(McMMOPlayer mmoPlayer) {

View File

@ -115,7 +115,7 @@ public class MiningManager extends SkillManager {
private boolean processTripleDrops(@NotNull BlockState blockState) {
//TODO: Make this readable
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.MINING_MOTHER_LODE, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.MINING_MOTHER_LODE, mmoPlayer)) {
BlockUtils.markDropsAsBonus(blockState, 2);
return true;
} else {
@ -125,7 +125,7 @@ public class MiningManager extends SkillManager {
private void processDoubleDrops(@NotNull BlockState blockState) {
//TODO: Make this readable
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.MINING_DOUBLE_DROPS, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.MINING_DOUBLE_DROPS, mmoPlayer)) {
boolean useTriple = mmoPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER) && mcMMO.p.getAdvancedConfig().getAllowMiningTripleDrops();
BlockUtils.markDropsAsBonus(blockState, useTriple);
}

View File

@ -329,7 +329,7 @@ public class RepairManager extends SkillManager {
if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.REPAIR_SUPER_REPAIR))
return false;
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.REPAIR_SUPER_REPAIR, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.REPAIR_SUPER_REPAIR, mmoPlayer)) {
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Repair.Skills.FeltEasy");
return true;
}
@ -380,10 +380,10 @@ public class RepairManager extends SkillManager {
Enchantment enchantment = enchant.getKey();
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.REPAIR, getPlayer(), getKeepEnchantChance())) {
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.REPAIR, mmoPlayer, getKeepEnchantChance())) {
if (ArcaneForging.arcaneForgingDowngrades && enchantLevel > 1
&& (!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.REPAIR, getPlayer(), 100 - getDowngradeEnchantChance()))) {
&& (!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.REPAIR, mmoPlayer, 100 - getDowngradeEnchantChance()))) {
item.addUnsafeEnchantment(enchantment, enchantLevel - 1);
downgraded = true;
}

View File

@ -125,7 +125,7 @@ public class SalvageManager extends SkillManager {
for(int x = 0; x < potentialSalvageYield-1; x++) {
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SALVAGE, player, chanceOfSuccess)) {
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SALVAGE, mmoPlayer, chanceOfSuccess)) {
chanceOfSuccess-=3;
chanceOfSuccess = Math.max(chanceOfSuccess, 90);
@ -232,12 +232,14 @@ public class SalvageManager extends SkillManager {
if (!Salvage.arcaneSalvageEnchantLoss
|| Permissions.hasSalvageEnchantBypassPerk(player)
|| ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SALVAGE, player, getExtractFullEnchantChance())) {
|| ProbabilityUtil.isStaticSkillRNGSuccessful(
PrimarySkillType.SALVAGE, mmoPlayer, getExtractFullEnchantChance())) {
enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel, true);
}
else if (enchantLevel > 1
&& Salvage.arcaneSalvageDowngrades
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SALVAGE, player, getExtractPartialEnchantChance())) {
&& ProbabilityUtil.isStaticSkillRNGSuccessful(
PrimarySkillType.SALVAGE, mmoPlayer, getExtractPartialEnchantChance())) {
enchantMeta.addStoredEnchant(enchant.getKey(), enchantLevel - 1, true);
downgraded = true;
} else {

View File

@ -24,7 +24,7 @@ public class SmeltingManager extends SkillManager {
public boolean isSecondSmeltSuccessful() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_SECOND_SMELT)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.SMELTING_SECOND_SMELT, getPlayer());
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.SMELTING_SECOND_SMELT, mmoPlayer);
}
/**

View File

@ -76,7 +76,7 @@ public class SwordsManager extends SkillManager {
}
double ruptureOdds = mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(getRuptureRank());
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SWORDS, this.getPlayer(), ruptureOdds)) {
if (ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.SWORDS, mmoPlayer, ruptureOdds)) {
if (target instanceof Player defender) {
@ -142,7 +142,7 @@ public class SwordsManager extends SkillManager {
*/
public void counterAttackChecks(@NotNull LivingEntity attacker, double damage) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.SWORDS_COUNTER_ATTACK, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.SWORDS_COUNTER_ATTACK, mmoPlayer)) {
CombatUtils.dealDamage(attacker, damage / Swords.counterAttackModifier, getPlayer());
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Countered");

View File

@ -31,6 +31,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import static com.gmail.nossr50.util.MobMetadataUtils.flagMetadata;
public class TamingManager extends SkillManager {
//TODO: Temporary static cache, will be changed in 2.2
private static HashMap<Material, CallOfTheWildType> summoningItems;
@ -143,7 +145,7 @@ public class TamingManager extends SkillManager {
* @param damage The damage being absorbed by the wolf
*/
public void fastFoodService(@NotNull Wolf wolf, double damage) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.TAMING_FAST_FOOD_SERVICE, getPlayer())) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.TAMING_FAST_FOOD_SERVICE, mmoPlayer)) {
return;
}
@ -262,7 +264,7 @@ public class TamingManager extends SkillManager {
if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_PUMMEL))
return;
if(!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.TAMING, getPlayer(), mcMMO.p.getAdvancedConfig().getPummelChance()))
if(!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.TAMING, mmoPlayer, mcMMO.p.getAdvancedConfig().getPummelChance()))
return;
ParticleEffectUtils.playGreaterImpactEffect(target);
@ -459,7 +461,7 @@ public class TamingManager extends SkillManager {
private void applyMetaDataToCOTWEntity(LivingEntity summonedEntity) {
//This helps identify the entity as being summoned by COTW
mcMMO.getMetadataService().getMobMetadataService().flagMetadata(MobMetaFlagType.COTW_SUMMONED_MOB, summonedEntity);
flagMetadata(MobMetaFlagType.COTW_SUMMONED_MOB, summonedEntity);
}
/**

View File

@ -3,9 +3,7 @@ package com.gmail.nossr50.skills.tridents;
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.datatypes.skills.ToolType;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.RankUtils;
public class TridentsManager extends SkillManager {

View File

@ -67,7 +67,7 @@ public class UnarmedManager extends SkillManager {
}
public boolean blockCrackerCheck(@NotNull BlockState blockState) {
if (!ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_BLOCK_CRACKER, getPlayer())) {
if (!ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_BLOCK_CRACKER, mmoPlayer)) {
return false;
}
@ -98,7 +98,7 @@ public class UnarmedManager extends SkillManager {
* @param defender The defending player
*/
public void disarmCheck(@NotNull Player defender) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_DISARM, getPlayer()) && !hasIronGrip(defender)) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_DISARM, mmoPlayer) && !hasIronGrip(defender)) {
if (EventUtils.callDisarmEvent(defender).isCancelled()) {
return;
}
@ -121,7 +121,7 @@ public class UnarmedManager extends SkillManager {
* Check for arrow deflection.
*/
public boolean deflectCheck() {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_ARROW_DEFLECT, getPlayer())) {
if (ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.UNARMED_ARROW_DEFLECT, mmoPlayer)) {
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.ArrowDeflect");
return true;
}
@ -144,7 +144,7 @@ public class UnarmedManager extends SkillManager {
* Handle the effects of the Iron Arm ability
*/
public double calculateSteelArmStyleDamage() {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_STEEL_ARM_STYLE, getPlayer())) {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_STEEL_ARM_STYLE, mmoPlayer)) {
return getSteelArmStyleDamage();
}
@ -178,7 +178,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, defender)) {
&& ProbabilityUtil.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");

View File

@ -72,14 +72,14 @@ public class WoodcuttingManager extends SkillManager {
private boolean checkHarvestLumberActivation(Material material) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.WOODCUTTING_HARVEST_LUMBER, getPlayer())
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.WOODCUTTING_HARVEST_LUMBER, mmoPlayer)
&& mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
}
private boolean checkCleanCutsActivation(Material material) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.WOODCUTTING_CLEAN_CUTS, getPlayer())
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.WOODCUTTING_CLEAN_CUTS, mmoPlayer)
&& mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
}
@ -336,7 +336,7 @@ public class WoodcuttingManager extends SkillManager {
if(RankUtils.hasUnlockedSubskill(player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
if(RankUtils.hasReachedRank(2, player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
if(mcMMO.p.getAdvancedConfig().isKnockOnWoodXPOrbEnabled()) {
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.WOODCUTTING, player, 10)) {
if(ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.WOODCUTTING, mmoPlayer, 10)) {
int randOrbCount = Math.max(1, Misc.getRandom().nextInt(100));
Misc.spawnExperienceOrb(blockState.getLocation(), randOrbCount);
}

View File

@ -2,11 +2,13 @@ package com.gmail.nossr50.util;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.meta.BonusDropMeta;
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.repair.Repair;
import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil;
import org.bukkit.Material;
import org.bukkit.World;
@ -16,9 +18,12 @@ import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import static java.util.Objects.requireNonNull;
public final class BlockUtils {
public static final String SHORT_GRASS = "SHORT_GRASS";
@ -94,10 +99,28 @@ public final class BlockUtils {
*
* @param blockState the blockstate
* @return true if the player succeeded in the check
* @deprecated Use {@link #checkDoubleDrops(McMMOPlayer, BlockState, SubSkillType)} instead
*/
public static boolean checkDoubleDrops(Player player, BlockState blockState, PrimarySkillType skillType, SubSkillType subSkillType) {
if (mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(skillType, blockState.getType()) && Permissions.isSubSkillEnabled(player, subSkillType)) {
return ProbabilityUtil.isSkillRNGSuccessful(subSkillType, player);
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean checkDoubleDrops(Player player, BlockState blockState, PrimarySkillType ignored, SubSkillType subSkillType) {
return checkDoubleDrops(UserManager.getPlayer(player), blockState, subSkillType);
}
/**
* Checks if a player successfully passed the double drop check
*
* @param mmoPlayer the player involved in the check
* @param blockState the blockstate of the block
* @param subSkillType the subskill involved
* @return true if the player succeeded in the check
*/
public static boolean checkDoubleDrops(@Nullable McMMOPlayer mmoPlayer, @NotNull BlockState blockState,
@NotNull SubSkillType subSkillType) {
requireNonNull(blockState, "blockState cannot be null");
requireNonNull(subSkillType, "subSkillType cannot be null");
if (mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(subSkillType.getParentSkill(), blockState.getType())
&& Permissions.isSubSkillEnabled(mmoPlayer, subSkillType)) {
return ProbabilityUtil.isSkillRNGSuccessful(subSkillType, mmoPlayer);
}
return false;

View File

@ -0,0 +1,116 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataHolder;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import static com.gmail.nossr50.util.MetadataService.NSK_CONTAINER_UUID_LEAST_SIG;
import static com.gmail.nossr50.util.MetadataService.NSK_CONTAINER_UUID_MOST_SIG;
import static java.util.Objects.requireNonNull;
public class ContainerMetadataUtils {
public static void changeContainerOwnership(@NotNull BlockState blockState, @NotNull Player player) {
requireNonNull(blockState, "blockState cannot be null");
requireNonNull(player, "Player cannot be null");
final McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
/*
Debug output
*/
printOwnershipGainDebug(blockState, mmoPlayer);
printOwnershipLossDebug(blockState);
setOwner(blockState, player.getUniqueId());
}
public static void printOwnershipGainDebug(@NotNull BlockState blockState, @Nullable McMMOPlayer mmoPlayer) {
if(mmoPlayer != null && mmoPlayer.isDebugMode()) {
mmoPlayer.getPlayer().sendMessage("Container ownership " +
ChatColor.GREEN +"gained " + ChatColor.RESET +
"at location: " + blockState.getLocation().toString());
}
}
public static void printOwnershipLossDebug(BlockState blockState) {
OfflinePlayer containerOwner = getContainerOwner(blockState);
if(containerOwner != null && containerOwner.isOnline()) {
final McMMOPlayer mmoContainerOwner = UserManager.getPlayer(containerOwner.getPlayer());
if(mmoContainerOwner != null) {
if(mmoContainerOwner.isDebugMode()) {
mmoContainerOwner.getPlayer().sendMessage("Container ownership " +
ChatColor.RED + "lost " + ChatColor.RESET +
"at location: " + blockState.getLocation().toString());
}
}
}
}
public static @Nullable OfflinePlayer getContainerOwner(BlockState container) {
if (container instanceof PersistentDataHolder persistentDataHolder) {
final UUID uuid = getOwner(persistentDataHolder);
if(uuid != null) {
return Bukkit.getOfflinePlayer(uuid);
}
}
return null;
}
public static boolean isContainerOwned(BlockState blockState) {
return getContainerOwner(blockState) != null;
}
public static void processContainerOwnership(BlockState blockState, Player player) {
if(!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SMELTING))
return;
if(getContainerOwner(blockState) != null) {
if(getContainerOwner(blockState).getUniqueId().equals(player.getUniqueId()))
return;
}
changeContainerOwnership(blockState, player);
}
public static @Nullable UUID getOwner(@NotNull PersistentDataHolder persistentDataHolder) {
//Get container from entity
final PersistentDataContainer dataContainer = persistentDataHolder.getPersistentDataContainer();
//Too lazy to make a custom data type for this stuff
final Long mostSigBits = dataContainer.get(NSK_CONTAINER_UUID_MOST_SIG, PersistentDataType.LONG);
final Long leastSigBits = dataContainer.get(NSK_CONTAINER_UUID_LEAST_SIG, PersistentDataType.LONG);
if (mostSigBits != null && leastSigBits != null) {
return new UUID(mostSigBits, leastSigBits);
} else {
return null;
}
}
public static void setOwner(@NotNull BlockState blockState, @NotNull UUID uuid) {
PersistentDataContainer dataContainer = ((PersistentDataHolder) blockState).getPersistentDataContainer();
dataContainer.set(NSK_CONTAINER_UUID_MOST_SIG, PersistentDataType.LONG, uuid.getMostSignificantBits());
dataContainer.set(NSK_CONTAINER_UUID_LEAST_SIG, PersistentDataType.LONG, uuid.getLeastSignificantBits());
blockState.update();
}
}

View File

@ -10,7 +10,6 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelChangeEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelDownEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
@ -59,6 +58,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import static java.util.Objects.requireNonNull;
/**
* This class is meant to help make event related code less boilerplate
*/
@ -163,8 +164,17 @@ public final class EventUtils {
* Others
*/
public static @NotNull McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(@NotNull Player player, @NotNull PrimarySkillType skill) {
McMMOPlayerAbilityActivateEvent event = new McMMOPlayerAbilityActivateEvent(player, skill);
@Deprecated(forRemoval = true, since = "2.2.010")
public static @NotNull McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(@NotNull Player player,
@NotNull PrimarySkillType skill) {
return callPlayerAbilityActivateEvent(requireNonNull(UserManager.getPlayer(player)), skill);
}
public static @NotNull McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(@NotNull McMMOPlayer mmoPlayer,
@NotNull PrimarySkillType skill) {
requireNonNull(mmoPlayer, "mmoPlayer cannot be null");
requireNonNull(skill, "skill cannot be null");
McMMOPlayerAbilityActivateEvent event = new McMMOPlayerAbilityActivateEvent(mmoPlayer, skill);
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;
@ -183,8 +193,21 @@ public final class EventUtils {
* @param subSkillType target subskill
* @return the event after it has been fired
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static @NotNull SubSkillEvent callSubSkillEvent(@NotNull Player player, @NotNull SubSkillType subSkillType) {
SubSkillEvent event = new SubSkillEvent(player, subSkillType);
return callSubSkillEvent(requireNonNull(UserManager.getPlayer(player)), subSkillType);
}
/**
* Calls a new SubSkillEvent for this SubSkill and then returns it
* @param mmoPlayer target mmoPlayer
* @param subSkillType target subskill
* @return the event after it has been fired
*/
public static @NotNull SubSkillEvent callSubSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull SubSkillType subSkillType) {
requireNonNull(mmoPlayer, "mmoPlayer cannot be null");
requireNonNull(subSkillType, "subSkillType cannot be null");
final SubSkillEvent event = new SubSkillEvent(mmoPlayer, subSkillType);
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;
@ -204,26 +227,6 @@ public final class EventUtils {
return event;
}
/**
* Calls a new SubSkillEvent for this SubSkill and then returns it
* @param player target player
* @param abstractSubSkill target subskill
* @return the event after it has been fired
*/
public static SubSkillEvent callSubSkillEvent(Player player, AbstractSubSkill abstractSubSkill) {
SubSkillEvent event = new SubSkillEvent(player, abstractSubSkill);
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;
}
// public static Event callFakeArmSwingEvent(@NotNull Player player) {
// PlayerAnimationEvent event = new FakePlayerAnimationEvent(player, PlayerAnimationType.ARM_SWING);
// mcMMO.p.getServer().getPluginManager().callEvent(event);
//
// return event;
// }
public static boolean tryLevelChangeEvent(Player player, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
@ -497,15 +500,25 @@ public final class EventUtils {
return !isCancelled;
}
@Deprecated(forRemoval = true, since = "2.2.010")
public static McMMOPlayerAbilityDeactivateEvent callAbilityDeactivateEvent(Player player, SuperAbilityType ability) {
McMMOPlayerAbilityDeactivateEvent event = new McMMOPlayerAbilityDeactivateEvent(player, mcMMO.p.getSkillTools().getPrimarySkillBySuperAbility(ability));
return callAbilityDeactivateEvent(requireNonNull(UserManager.getPlayer(player)), ability);
}
public static McMMOPlayerAbilityDeactivateEvent callAbilityDeactivateEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull SuperAbilityType ability) {
final McMMOPlayerAbilityDeactivateEvent event = new McMMOPlayerAbilityDeactivateEvent(mmoPlayer, mcMMO.p.getSkillTools().getPrimarySkillBySuperAbility(ability));
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;
}
@Deprecated(forRemoval = true, since = "2.2.010")
public static McMMOPlayerFishingTreasureEvent callFishingTreasureEvent(Player player, ItemStack treasureDrop, int treasureXp, Map<Enchantment, Integer> enchants) {
McMMOPlayerFishingTreasureEvent event = enchants.isEmpty() ? new McMMOPlayerFishingTreasureEvent(player, treasureDrop, treasureXp) : new McMMOPlayerMagicHunterEvent(player, treasureDrop, treasureXp, enchants);
return callFishingTreasureEvent(requireNonNull(UserManager.getPlayer(player)), treasureDrop, treasureXp, enchants);
}
public static McMMOPlayerFishingTreasureEvent callFishingTreasureEvent(McMMOPlayer mmoPlayer, ItemStack treasureDrop, int treasureXp, Map<Enchantment, Integer> enchants) {
final McMMOPlayerFishingTreasureEvent event = enchants.isEmpty() ? new McMMOPlayerFishingTreasureEvent(mmoPlayer, treasureDrop, treasureXp) : new McMMOPlayerMagicHunterEvent(mmoPlayer, treasureDrop, treasureXp, enchants);
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;

View File

@ -1,4 +1,4 @@
package com.gmail.nossr50.metadata;
package com.gmail.nossr50.util;
import com.gmail.nossr50.mcMMO;
import org.bukkit.inventory.ItemStack;
@ -9,18 +9,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
import static com.gmail.nossr50.metadata.MetadataService.NSK_SUPER_ABILITY_BOOSTED_ITEM;
import static com.gmail.nossr50.util.MetadataService.NSK_SUPER_ABILITY_BOOSTED_ITEM;
public class ItemMetadataService {
public final class ItemMetadataUtils {
public final @NotNull String LEGACY_ABILITY_TOOL_LORE = "mcMMO Ability Tool";
public final @NotNull mcMMO pluginRef;
public static final @NotNull String LEGACY_ABILITY_TOOL_LORE = "mcMMO Ability Tool";
public ItemMetadataService(@NotNull mcMMO pluginRef) {
this.pluginRef = pluginRef;
private ItemMetadataUtils() {
// private ctor
}
public void setSuperAbilityBoostedItem(@NotNull ItemStack itemStack, int originalDigSpeed) {
public static void setSuperAbilityBoostedItem(@NotNull ItemStack itemStack, int originalDigSpeed) {
if (itemStack.getItemMeta() == null) {
mcMMO.p.getLogger().severe("Can not assign persistent data to an item with null item metadata");
return;
@ -34,7 +33,7 @@ public class ItemMetadataService {
itemStack.setItemMeta(itemMeta);
}
public boolean isSuperAbilityBoosted(@NotNull ItemStack itemStack) {
public static boolean isSuperAbilityBoosted(@NotNull ItemStack itemStack) {
if (itemStack.getItemMeta() == null)
return false;
@ -48,7 +47,7 @@ public class ItemMetadataService {
return boostValue != null;
}
public int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemStack itemStack) {
public static int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemStack itemStack) {
//Get container from entity
ItemMeta itemMeta = itemStack.getItemMeta();
@ -67,7 +66,7 @@ public class ItemMetadataService {
}
}
public void removeBonusDigSpeedOnSuperAbilityTool(@NotNull ItemStack itemStack) {
public static void removeBonusDigSpeedOnSuperAbilityTool(@NotNull ItemStack itemStack) {
int originalSpeed = getSuperAbilityToolOriginalDigSpeed(itemStack);
ItemMeta itemMeta = itemStack.getItemMeta();
@ -89,7 +88,7 @@ public class ItemMetadataService {
}
}
public boolean isLegacyAbilityTool(@NotNull ItemStack itemStack) {
public static boolean isLegacyAbilityTool(@NotNull ItemStack itemStack) {
ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null)
@ -102,8 +101,4 @@ public class ItemMetadataService {
return lore.contains(LEGACY_ABILITY_TOOL_LORE);
}
public @NotNull String getLegacyAbilityToolLore() {
return LEGACY_ABILITY_TOOL_LORE;
}
}

View File

@ -34,8 +34,9 @@ public class MetadataConstants {
public static final @NotNull String METADATA_KEY_DISARMED_ITEM = "mcMMO: Disarmed Item";
public static final @NotNull String METADATA_KEY_PLAYER_DATA = "mcMMO: Player Data";
public static final @NotNull String METADATA_KEY_DATABASE_COMMAND = "mcMMO: Processing Database Command";
public static final @NotNull String METADATA_KEY_FURNACE_UUID_MOST_SIG = "furnace_uuid_most_sig";
public static final @NotNull String METADATA_KEY_FURNACE_UUID_LEAST_SIG = "furnace_uuid_least_sig";
// the value of these two keys have "furnace" to keep supporting legacy data
public static final @NotNull String METADATA_KEY_CONTAINER_UUID_MOST_SIG = "furnace_uuid_most_sig";
public static final @NotNull String METADATA_KEY_CONTAINER_UUID_LEAST_SIG = "furnace_uuid_least_sig";
public static final @NotNull String METADATA_KEY_SUPER_ABILITY_BOOSTED_ITEM = "super_ability_boosted";
public static final @NotNull String METADATA_KEY_MOB_SPAWNER_MOB = "mcmmo_mob_spawner_mob";
public static final @NotNull String METADATA_KEY_EGG_MOB = "mcmmo_egg_mob";

View File

@ -0,0 +1,48 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.mcMMO;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.NotNull;
public final class MetadataService {
static final @NotNull NamespacedKey NSK_SUPER_ABILITY_BOOSTED_ITEM;
static final @NotNull NamespacedKey NSK_MOB_SPAWNER_MOB;
static final @NotNull NamespacedKey NSK_EGG_MOB;
static final @NotNull NamespacedKey NSK_NETHER_GATE_MOB;
static final @NotNull NamespacedKey NSK_COTW_SUMMONED_MOB;
static final @NotNull NamespacedKey NSK_PLAYER_BRED_MOB;
static final @NotNull NamespacedKey NSK_PLAYER_TAMED_MOB;
static final @NotNull NamespacedKey NSK_VILLAGER_TRADE_ORIGIN_ITEM;
static final @NotNull NamespacedKey NSK_EXPLOITED_ENDERMEN;
static final @NotNull NamespacedKey NSK_CONTAINER_UUID_MOST_SIG;
static final @NotNull NamespacedKey NSK_CONTAINER_UUID_LEAST_SIG;
private MetadataService() {
// private ctor
}
static {
NSK_SUPER_ABILITY_BOOSTED_ITEM = getNamespacedKey(MetadataConstants.METADATA_KEY_SUPER_ABILITY_BOOSTED_ITEM);
NSK_MOB_SPAWNER_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_MOB_SPAWNER_MOB);
NSK_EGG_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_EGG_MOB);
NSK_NETHER_GATE_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_NETHER_PORTAL_MOB);
NSK_COTW_SUMMONED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_COTW_SUMMONED_MOB);
NSK_PLAYER_BRED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_PLAYER_BRED_MOB);
NSK_PLAYER_TAMED_MOB = getNamespacedKey(MetadataConstants.METADATA_KEY_PLAYER_TAMED_MOB);
NSK_VILLAGER_TRADE_ORIGIN_ITEM = getNamespacedKey(MetadataConstants.METADATA_KEY_VILLAGER_TRADE_ORIGIN_ITEM);
NSK_EXPLOITED_ENDERMEN = getNamespacedKey(MetadataConstants.METADATA_KEY_EXPLOITED_ENDERMEN);
NSK_CONTAINER_UUID_MOST_SIG = getNamespacedKey(MetadataConstants.METADATA_KEY_CONTAINER_UUID_MOST_SIG);
NSK_CONTAINER_UUID_LEAST_SIG = getNamespacedKey(MetadataConstants.METADATA_KEY_CONTAINER_UUID_LEAST_SIG);
}
/**
* Helper method to simplify generating namespaced keys
*
* @param key the {@link String} value of the key
*
* @return the generated {@link NamespacedKey}
*/
public static @NotNull NamespacedKey getNamespacedKey(@NotNull String key) {
return new NamespacedKey(mcMMO.p, key);
}
}

View File

@ -1,9 +1,8 @@
package com.gmail.nossr50.metadata;
package com.gmail.nossr50.util;
import com.gmail.nossr50.api.exceptions.IncompleteNamespacedKeyRegister;
import com.gmail.nossr50.config.PersistentDataConfig;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.metadata.MobMetaFlagType;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
@ -15,17 +14,19 @@ import java.util.EnumMap;
import java.util.HashSet;
import java.util.WeakHashMap;
import static com.gmail.nossr50.metadata.MetadataService.*;
import static com.gmail.nossr50.util.MetadataService.*;
//TODO: Use SpawnReason where appropriate instead of MobMetaFlagType
public class MobMetadataService {
private final @NotNull WeakHashMap<Entity, HashSet<MobMetaFlagType>> mobRegistry; //transient data
private final @NotNull EnumMap<MobMetaFlagType, NamespacedKey> mobFlagKeyMap; //used for persistent data
private final @NotNull mcMMO pluginRef;
private boolean isUsingPersistentData = false;
public final class MobMetadataUtils {
private static final @NotNull WeakHashMap<Entity, HashSet<MobMetaFlagType>> mobRegistry; //transient data
private static final @NotNull EnumMap<MobMetaFlagType, NamespacedKey> mobFlagKeyMap; //used for persistent data
private static boolean isUsingPersistentData = false;
public MobMetadataService(@NotNull mcMMO pluginRef) {
this.pluginRef = pluginRef;
private MobMetadataUtils() {
// private ctor
}
static {
mobFlagKeyMap = new EnumMap<>(MobMetaFlagType.class);
mobRegistry = new WeakHashMap<>();
initMobFlagKeyMap();
@ -40,7 +41,7 @@ public class MobMetadataService {
* Registers the namespaced keys required by the API (CB/Spigot)
* Used primarily for persistent data
*/
private void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister {
private static void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister {
for (MobMetaFlagType mobMetaFlagType : MobMetaFlagType.values()) {
switch (mobMetaFlagType) {
case MOB_SPAWNER_MOB -> mobFlagKeyMap.put(mobMetaFlagType, NSK_MOB_SPAWNER_MOB);
@ -63,7 +64,7 @@ public class MobMetadataService {
*
* @return true if the mob has metadata values for target {@link MobMetaFlagType}
*/
public boolean hasMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
public static boolean hasMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
if (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
return livingEntity.getPersistentDataContainer().has(mobFlagKeyMap.get(flag), PersistentDataType.BYTE);
} else {
@ -82,7 +83,7 @@ public class MobMetadataService {
*
* @return true if the mob has any mcMMO mob related metadata values
*/
public boolean hasMobFlags(@NotNull LivingEntity livingEntity) {
public static boolean hasMobFlags(@NotNull LivingEntity livingEntity) {
if (isUsingPersistentData) {
for (MobMetaFlagType metaFlagType : MobMetaFlagType.values()) {
if (hasMobFlag(metaFlagType, livingEntity))
@ -102,7 +103,7 @@ public class MobMetadataService {
* @param sourceEntity entity to copy from
* @param targetEntity entity to copy to
*/
public void addMobFlags(@NotNull LivingEntity sourceEntity, @NotNull LivingEntity targetEntity) {
public static void addMobFlags(@NotNull LivingEntity sourceEntity, @NotNull LivingEntity targetEntity) {
if (!hasMobFlags(sourceEntity))
return;
@ -125,7 +126,7 @@ public class MobMetadataService {
* @param flag the desired flag to assign
* @param livingEntity the target living entity
*/
public void flagMetadata(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
public static void flagMetadata(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
if (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
if (!hasMobFlag(flag, livingEntity)) {
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
@ -144,7 +145,7 @@ public class MobMetadataService {
* @param flag desired flag to remove
* @param livingEntity the target living entity
*/
public void removeMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
public static void removeMobFlag(@NotNull MobMetaFlagType flag, @NotNull LivingEntity livingEntity) {
if (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
if (hasMobFlag(flag, livingEntity)) {
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
@ -165,7 +166,7 @@ public class MobMetadataService {
*
* @param livingEntity target entity
*/
public void removeMobFlags(@NotNull LivingEntity livingEntity) {
public static void removeMobFlags(@NotNull LivingEntity livingEntity) {
if (isUsingPersistentData) {
for (MobMetaFlagType flag : MobMetaFlagType.values()) {
removeMobFlag(flag, livingEntity);

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.commands.party.PartySubcommandType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@ -17,6 +18,7 @@ import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
@ -171,10 +173,19 @@ public final class Permissions {
}
public static boolean vanillaXpBoost(Permissible permissible, PrimarySkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase(Locale.ENGLISH) + ".vanillaxpboost"); }
public static boolean isSubSkillEnabled(Permissible permissible, SubSkillType subSkillType) {
public static boolean isSubSkillEnabled(@Nullable Permissible permissible, @NotNull SubSkillType subSkillType) {
if (permissible == null)
return false;
return permissible.hasPermission(subSkillType.getPermissionNodeAddress());
}
public static boolean isSubSkillEnabled(@Nullable McMMOPlayer permissible, @NotNull SubSkillType subSkillType) {
if (permissible == null)
return false;
return isSubSkillEnabled(permissible.getPlayer(), subSkillType);
}
/* ACROBATICS */
public static boolean dodge(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.dodge"); }
public static boolean gracefulRoll(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.gracefulroll"); }

View File

@ -18,6 +18,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.gmail.nossr50.util.MobMetadataUtils.removeMobFlags;
public class TransientEntityTracker {
//These two are updated in step with each other
private final @NotNull HashMap<UUID, HashMap<CallOfTheWildType, HashSet<TrackedTamingEntity>>> perPlayerTransientEntityMap;
@ -273,7 +275,7 @@ public class TransientEntityTracker {
}
//Remove our metadata
mcMMO.getMetadataService().getMobMetadataService().removeMobFlags(livingEntity);
removeMobFlags(livingEntity);
//Clean from trackers
unregisterEntity(livingEntity);

View File

@ -4,6 +4,8 @@ import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull;
import static com.gmail.nossr50.util.MobMetadataUtils.removeMobFlags;
public class TransientMetadataTools {
private final mcMMO pluginRef;
@ -30,7 +32,7 @@ public class TransientMetadataTools {
}
//Cleanup mob metadata
mcMMO.getMetadataService().getMobMetadataService().removeMobFlags(entity);
removeMobFlags(entity);
//TODO: This loop has some redundancy, this whole method needs to be rewritten
for(String key : MetadataConstants.MOB_METADATA_KEYS) {

View File

@ -11,26 +11,37 @@ import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import java.text.DecimalFormat;
import static java.util.Objects.requireNonNull;
public class ProbabilityUtil {
public static final @NotNull DecimalFormat percent = new DecimalFormat("##0.00%");
public static final double LUCKY_MODIFIER = 1.333D;
/**
* Return a chance of success in "percentage" format, show to the player in UI elements
* Return a chance of success in "percentage" format, shown to the player in UI elements
*
* @param player target player
* @param subSkillType target subskill
* @param isLucky whether to apply luck modifiers
*
* @return "percentage" representation of success
* @deprecated use {@link #chanceOfSuccessPercentage(McMMOPlayer, SubSkillType, boolean)} instead
*/
public static double chanceOfSuccessPercentage(@NotNull Player player,
@Deprecated(forRemoval = true, since = "2.2.010")
public static double chanceOfSuccessPercentage(@Nullable Player player,
@NotNull SubSkillType subSkillType,
boolean isLucky) {
Probability probability = getSubSkillProbability(subSkillType, player);
return chanceOfSuccessPercentage(requireNonNull(UserManager.getPlayer(player)), subSkillType, isLucky);
}
public static double chanceOfSuccessPercentage(@Nullable McMMOPlayer mmoPlayer,
@NotNull SubSkillType subSkillType,
boolean isLucky) {
Probability probability = getSubSkillProbability(subSkillType, mmoPlayer);
//Probability values are on a 0-1 scale and need to be "transformed" into a 1-100 scale
double percentageValue = probability.getValue(); //Doesn't need to be scaled
@ -42,6 +53,13 @@ public class ProbabilityUtil {
return percentageValue;
}
/**
* Return a chance of success as a double representing a "percentage".
*
* @param probability the probability of success
* @param isLucky whether to apply luck modifiers
* @return a double as a "percentage" representation of success
*/
public static double chanceOfSuccessPercentage(@NotNull Probability probability, boolean isLucky) {
//Probability values are on a 0-1 scale and need to be "transformed" into a 1-100 scale
double percentageValue = probability.getValue();
@ -54,6 +72,7 @@ public class ProbabilityUtil {
return percentageValue;
}
@VisibleForTesting
static Probability getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance {
return switch (subSkillType) {
case AXES_ARMOR_IMPACT -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getImpactChance());
@ -74,19 +93,20 @@ public class ProbabilityUtil {
return skillProbabilityType;
}
static @NotNull Probability ofSubSkill(@Nullable Player player,
@NotNull SubSkillType subSkillType) {
@Deprecated(forRemoval = true, since = "2.2.010")
private static @NotNull Probability ofSubSkill(@Nullable Player player, @NotNull SubSkillType subSkillType) {
// no null check needed here
return ofSubSkill(UserManager.getPlayer(player), subSkillType);
}
private static @NotNull Probability ofSubSkill(@Nullable McMMOPlayer mmoPlayer, @NotNull SubSkillType subSkillType) {
switch (getProbabilityType(subSkillType)) {
case DYNAMIC_CONFIGURABLE:
double probabilityCeiling;
double skillLevel;
double maxBonusLevel; // If a skill level is equal to the cap, it has the full probability
if (player != null) {
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return Probability.ofPercent(0);
}
if (mmoPlayer != null) {
skillLevel = mmoPlayer.getSkillLevel(subSkillType.getParentSkill());
} else {
skillLevel = 0;
@ -101,10 +121,10 @@ public class ProbabilityUtil {
try {
return getStaticRandomChance(subSkillType);
} catch (InvalidStaticChance invalidStaticChance) {
invalidStaticChance.printStackTrace();
throw new RuntimeException(invalidStaticChance);
}
default:
throw new RuntimeException("No case in switch statement for Skill Probability Type!");
throw new IllegalStateException("No case in switch statement for Skill Probability Type!");
}
}
@ -123,14 +143,43 @@ public class ProbabilityUtil {
* The outcome of the probability can also be modified by this event that is called
*
* @param subSkillType target subskill
* @param player target player, can be null (null players are given odds equivalent to a player with no levels or luck)
* @param player 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
* @deprecated use {@link #isSkillRNGSuccessful(SubSkillType, McMMOPlayer)} instead
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @Nullable Player player) {
return isSkillRNGSuccessful(subSkillType, UserManager.getPlayer(player));
}
/**
* This is one of several Skill RNG check methods
* 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, @NotNull Player player) {
final Probability probability = getSkillProbability(subSkillType, player);
public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @Nullable McMMOPlayer mmoPlayer) {
final Probability probability = getSkillProbability(subSkillType, mmoPlayer);
//Luck
boolean isLucky = Permissions.lucky(player, subSkillType.getParentSkill());
boolean isLucky = mmoPlayer != null && Permissions.lucky(mmoPlayer.getPlayer(), subSkillType.getParentSkill());
if(isLucky) {
return probability.evaluate(LUCKY_MODIFIER);
@ -143,17 +192,37 @@ public class ProbabilityUtil {
* 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.
* This is affected by other plugins who can listen to the {@link SubSkillEvent} and cancel it or mutate it.
* Null players will be treated as zero skill players.
*
* @param subSkillType the target subskill
* @param player the target player
* can be null (null players have the worst odds)
* @return the probability for this skill
* @deprecated use {@link #getSkillProbability(SubSkillType, McMMOPlayer)} instead
*/
@Deprecated(forRemoval = true)
public static Probability getSkillProbability(@NotNull SubSkillType subSkillType, @Nullable Player player) {
return getSkillProbability(subSkillType, UserManager.getPlayer(player));
}
/**
* 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.
* This is affected by other plugins who can listen to the {@link SubSkillEvent} and cancel it or mutate it.
* Null players will be treated as zero skill players.
*
* @param subSkillType the target subskill
* @param mmoPlayer the target player
* can be null (null players have the worst odds)
* @return the probability for this skill
*/
public static Probability getSkillProbability(@NotNull SubSkillType subSkillType, @NotNull Player player) {
public static Probability getSkillProbability(@NotNull SubSkillType subSkillType, @Nullable McMMOPlayer mmoPlayer) {
// Process probability
Probability probability = getSubSkillProbability(subSkillType, player);
Probability probability = getSubSkillProbability(subSkillType, mmoPlayer);
// Send out event
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(player, subSkillType);
if (mmoPlayer != null) {
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(mmoPlayer, subSkillType);
if(subSkillEvent.isCancelled()) {
return Probability.ALWAYS_FAILS;
@ -165,6 +234,7 @@ public class ProbabilityUtil {
// Mutate probability
if(resultModifier != 1.0D)
probability = Probability.ofPercent(probability.getValue() * resultModifier);
}
return probability;
}
@ -177,12 +247,11 @@ public class ProbabilityUtil {
* @param player the target player can be null (null players have the worst odds)
* @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
* @return true if the RNG succeeds, false if it fails
* @deprecated use {@link #isStaticSkillRNGSuccessful(PrimarySkillType, McMMOPlayer, double)} instead
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType, @Nullable Player player, double probabilityPercentage) {
//Grab a probability converted from a "percentage" value
Probability probability = Probability.ofPercent(probabilityPercentage);
return isStaticSkillRNGSuccessful(primarySkillType, player, probability);
return isStaticSkillRNGSuccessful(primarySkillType, player, Probability.ofPercent(probabilityPercentage));
}
/**
@ -190,12 +259,49 @@ public class ProbabilityUtil {
* This helper method is specific to static value RNG, which can be influenced by a player's Luck
*
* @param primarySkillType the related primary skill
* @param player the target player, can be null (null players have the worst odds)
* @param probability the probability of this player succeeding
* @param mmoPlayer the target player can be null (null players have the worst odds)
* @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
* @return true if the RNG succeeds, false if it fails
*/
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType, @Nullable Player player, @NotNull Probability probability) {
boolean isLucky = player != null && Permissions.lucky(player, primarySkillType);
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType,
@Nullable McMMOPlayer mmoPlayer, double probabilityPercentage) {
//Grab a probability converted from a "percentage" value
final Probability probability = Probability.ofPercent(probabilityPercentage);
return isStaticSkillRNGSuccessful(primarySkillType, mmoPlayer, probability);
}
/**
* This is one of several Skill RNG check methods
* This helper method is specific to static value RNG, which can be influenced by a player's Luck
*
* @param primarySkillType the related primary skill
* @param player the target player
* can be null (null players have the worst odds)
* @param probability the probability of this player succeeding
* @return true if the RNG succeeds, false if it fails
* @deprecated use {@link #isStaticSkillRNGSuccessful(PrimarySkillType, McMMOPlayer, Probability)} instead, this
* method is redundant and will be removed.
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType,
@Nullable Player player, @NotNull Probability probability) {
return isStaticSkillRNGSuccessful(primarySkillType, UserManager.getPlayer(player), probability);
}
/**
* This is one of several Skill RNG check methods
* This helper method is specific to static value RNG, which can be influenced by a mmoPlayer's Luck
*
* @param primarySkillType the related primary skill
* @param mmoPlayer the target mmoPlayer
* can be null (null players have the worst odds)
* @param probability the probability of this mmoPlayer succeeding
* @return true if the RNG succeeds, false if it fails
*/
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType,
@Nullable McMMOPlayer mmoPlayer, @NotNull Probability probability) {
boolean isLucky = mmoPlayer != null && Permissions.lucky(mmoPlayer.getPlayer(), primarySkillType);
if(isLucky) {
return probability.evaluate(LUCKY_MODIFIER);
@ -209,25 +315,57 @@ public class ProbabilityUtil {
* @param subSkillType target subskill
* @param player target player
* @return true if the skill succeeds (wasn't cancelled by any other plugin)
* @deprecated use {@link #isNonRNGSkillActivationSuccessful(SubSkillType, McMMOPlayer)} instead
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isNonRNGSkillActivationSuccessful(@NotNull SubSkillType subSkillType, @NotNull Player player) {
return !EventUtils.callSubSkillEvent(player, subSkillType).isCancelled();
return isNonRNGSkillActivationSuccessful(subSkillType, requireNonNull(UserManager.getPlayer(player)));
}
/**
* Grab the {@link Probability} for a specific {@link SubSkillType} for a specific {@link Player}
*
* Skills activate without RNG, this allows other plugins to prevent that activation
* @param subSkillType target subskill
* @param player target player
* @return the Probability of this skill succeeding
* @param mmoPlayer target player
* @return true if the skill succeeds (wasn't cancelled by any other plugin)
*/
public static @NotNull Probability getSubSkillProbability(@NotNull SubSkillType subSkillType, @Nullable Player player) {
public static boolean isNonRNGSkillActivationSuccessful(@NotNull SubSkillType subSkillType,
@NotNull McMMOPlayer mmoPlayer) {
return !EventUtils.callSubSkillEvent(mmoPlayer, subSkillType).isCancelled();
}
/**
* Retrieves the {@link Probability} of success for a specified {@link SubSkillType} for a given {@link Player}.
*
* @param subSkillType The targeted subskill.
* @param player The player in question.
* If null, the method treats it as a player with no levels or luck and calculates the probability
* accordingly.
* @return The probability that the specified skill will succeed.
* @deprecated use {@link #getSubSkillProbability(SubSkillType, McMMOPlayer)} instead
*/
@Deprecated(forRemoval = true, since = "2.2.010")
public static @NotNull Probability getSubSkillProbability(@NotNull SubSkillType subSkillType,
@Nullable Player player) {
return ProbabilityUtil.ofSubSkill(player, subSkillType);
}
public static @NotNull String[] getRNGDisplayValues(@NotNull Player player, @NotNull SubSkillType subSkill) {
double firstValue = chanceOfSuccessPercentage(player, subSkill, false);
double secondValue = chanceOfSuccessPercentage(player, subSkill, true);
/**
* Retrieves the {@link Probability} of success for a specified {@link SubSkillType} for a given {@link Player}.
*
* @param subSkillType The targeted subskill.
* @param mmoPlayer The player in question.
* If null, the method treats it as a player with no levels or luck and calculates the probability
* accordingly.
* @return The probability that the specified skill will succeed.
*/
public static @NotNull Probability getSubSkillProbability(@NotNull SubSkillType subSkillType,
@Nullable McMMOPlayer mmoPlayer) {
return ProbabilityUtil.ofSubSkill(mmoPlayer, subSkillType);
}
public static @NotNull String[] getRNGDisplayValues(@Nullable McMMOPlayer mmoPlayer, @NotNull SubSkillType subSkill) {
double firstValue = chanceOfSuccessPercentage(mmoPlayer, subSkill, false);
double secondValue = chanceOfSuccessPercentage(mmoPlayer, subSkill, true);
return new String[]{percent.format(firstValue), percent.format(secondValue)};
}

View File

@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.metadata.MobMetaFlagType;
import com.gmail.nossr50.metadata.MobMetadataService;
import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
import com.gmail.nossr50.skills.archery.ArcheryManager;
@ -37,14 +36,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.gmail.nossr50.util.MobMetadataUtils.hasMobFlag;
public final class CombatUtils {
private CombatUtils() {}
private static @NotNull MobMetadataService getMobMetadataService() {
return mcMMO.getMetadataService().getMobMetadataService();
}
public static boolean isDamageLikelyFromNormalCombat(@NotNull DamageCause damageCause) {
return switch (damageCause) {
case ENTITY_ATTACK, ENTITY_SWEEP_ATTACK, PROJECTILE -> true;
@ -926,17 +923,17 @@ public final class CombatUtils {
}
}
if(getMobMetadataService().hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, target)) {
if(hasMobFlag(MobMetaFlagType.COTW_SUMMONED_MOB, target)) {
baseXP = 0;
} else if(getMobMetadataService().hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, target) || target.hasMetadata("ES")) {
} else if(hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, target) || target.hasMetadata("ES")) {
baseXP *= ExperienceConfig.getInstance().getSpawnedMobXpMultiplier();
} else if(getMobMetadataService().hasMobFlag(MobMetaFlagType.NETHER_PORTAL_MOB, target)) {
} else if(hasMobFlag(MobMetaFlagType.NETHER_PORTAL_MOB, target)) {
baseXP *= ExperienceConfig.getInstance().getNetherPortalXpMultiplier();
} else if(getMobMetadataService().hasMobFlag(MobMetaFlagType.EGG_MOB, target)) {
} else if(hasMobFlag(MobMetaFlagType.EGG_MOB, target)) {
baseXP *= ExperienceConfig.getInstance().getEggXpMultiplier();
} else if (getMobMetadataService().hasMobFlag(MobMetaFlagType.PLAYER_BRED_MOB, target)) {
} else if (hasMobFlag(MobMetaFlagType.PLAYER_BRED_MOB, target)) {
baseXP *= ExperienceConfig.getInstance().getBredMobXpMultiplier();
} else if(getMobMetadataService().hasMobFlag(MobMetaFlagType.PLAYER_TAMED_MOB, target)) {
} else if(hasMobFlag(MobMetaFlagType.PLAYER_TAMED_MOB, target)) {
baseXP *= ExperienceConfig.getInstance().getTamedMobXpMultiplier();
}

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.util.skills;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.skills.SkillActivationPerkEvent;
import com.gmail.nossr50.util.Permissions;
@ -106,4 +107,19 @@ public final class PerksUtils {
return NORMAL_SKILL_ACTIVATION_CHANCE;
}
/**
* Calculate activation chance for a skill.
*
* @param mmoPlayer Player to check the activation chance for
* @param skill PrimarySkillType to check the activation chance of
* @return the activation chance with "lucky perk" accounted for
*/
public static int handleLuckyPerks(McMMOPlayer mmoPlayer, PrimarySkillType skill) {
if (Permissions.lucky(mmoPlayer.getPlayer(), skill)) {
return LUCKY_SKILL_ACTIVATION_CHANCE;
}
return NORMAL_SKILL_ACTIVATION_CHANCE;
}
}

View File

@ -10,7 +10,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.metadata.ItemMetadataService;
import com.gmail.nossr50.util.ItemMetadataUtils;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
import static com.gmail.nossr50.util.ItemMetadataUtils.*;
import static com.gmail.nossr50.util.PotionEffectMapper.getHaste;
public final class SkillUtils {
@ -152,7 +153,7 @@ public final class SkillUtils {
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency()));
//1.13.2+ will have persistent metadata for this item
mcMMO.getMetadataService().getItemMetadataService().setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
ItemMetadataUtils.setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
} else {
int duration = 0;
int amplifier = 0;
@ -209,9 +210,7 @@ public final class SkillUtils {
//1.13.2+ will have persistent metadata for this itemStack
ItemMetadataService itemMetadataService = mcMMO.getMetadataService().getItemMetadataService();
if(itemMetadataService.isLegacyAbilityTool(itemStack)) {
if(isLegacyAbilityTool(itemStack)) {
ItemMeta itemMeta = itemStack.getItemMeta();
if(itemMeta != null) {
@ -223,8 +222,8 @@ public final class SkillUtils {
}
}
if(itemMetadataService.isSuperAbilityBoosted(itemStack)) {
itemMetadataService.removeBonusDigSpeedOnSuperAbilityTool(itemStack);
if(isSuperAbilityBoosted(itemStack)) {
removeBonusDigSpeedOnSuperAbilityTool(itemStack);
}
}

View File

@ -1,102 +0,0 @@
package com.gmail.nossr50.util.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.Furnace;
import org.bukkit.entity.Player;
import org.bukkit.inventory.FurnaceInventory;
import org.bukkit.inventory.Inventory;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public class SmeltingTracker {
// private final HashMap<Furnace, OfflinePlayer> furnaceOwners;
private void changeFurnaceOwnership(Furnace furnace, Player player) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
/*
Debug output
*/
printOwnershipGainDebug(furnace, mcMMOPlayer);
printOwnershipLossDebug(furnace);
setFurnaceOwner(furnace, player);
}
private void setFurnaceOwner(Furnace furnace, Player player) {
mcMMO.getMetadataService().getBlockMetadataService().setFurnaceOwner(furnace, player.getUniqueId());
}
private void printOwnershipGainDebug(Furnace furnace, McMMOPlayer mcMMOPlayer) {
if(mcMMOPlayer != null) {
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Furnace ownership " +
ChatColor.GREEN +"gained " + ChatColor.RESET +
"at location: " + furnace.getLocation().toString());
}
}
}
private void printOwnershipLossDebug(Furnace furnace) {
OfflinePlayer furnaceOwner = getFurnaceOwner(furnace);
if(furnaceOwner != null && furnaceOwner.isOnline()) {
McMMOPlayer furnaceOwnerProfile = UserManager.getPlayer(furnaceOwner.getPlayer());
if(furnaceOwnerProfile != null) {
if(furnaceOwnerProfile.isDebugMode()) {
furnaceOwnerProfile.getPlayer().sendMessage("Furnace ownership " +
ChatColor.RED + "lost " + ChatColor.RESET +
"at location: " + furnace.getLocation().toString());
}
}
}
}
public @Nullable OfflinePlayer getFurnaceOwner(Furnace furnace) {
UUID uuid = mcMMO.getMetadataService().getBlockMetadataService().getFurnaceOwner(furnace);
if(uuid != null) {
return Bukkit.getOfflinePlayer(uuid);
} else {
return null;
}
}
@Nullable
public Furnace getFurnaceFromInventory(Inventory inventory) {
if (!(inventory instanceof FurnaceInventory)) {
return null;
}
return (Furnace) inventory.getHolder();
}
public boolean isFurnaceOwned(Furnace furnace) {
return getFurnaceOwner(furnace) != null;
}
public void processFurnaceOwnership(Furnace furnace, Player player) {
if(!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SMELTING))
return;
//Don't swap ownership if its the same player
if(getFurnaceOwner(furnace) != null) {
if(getFurnaceOwner(furnace).getUniqueId().equals(player.getUniqueId()))
return;
}
changeFurnaceOwnership(furnace, player);
}
}

View File

@ -10,6 +10,7 @@ import com.gmail.nossr50.listeners.InteractionManager;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
@ -345,7 +346,8 @@ public class TextComponentFactory {
componentBuilder.append(Component.newline());
//Finally, add details to the tooltip
abstractSubSkill.addStats(componentBuilder, player);
// TODO: pass in McMMOPlayer instead
abstractSubSkill.addStats(componentBuilder, UserManager.getPlayer(player));
}
return componentBuilder.build();

View File

@ -21,7 +21,6 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.PluginManager;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

View File

@ -62,7 +62,8 @@ class ProbabilityUtilTest extends MMOTestEnvironment {
when(advancedConfig.getMaximumProbability(UNARMED_ARROW_DEFLECT)).thenReturn(20D);
when(advancedConfig.getMaxBonusLevel(UNARMED_ARROW_DEFLECT)).thenReturn(0);
final Probability probability = ProbabilityUtil.getSkillProbability(UNARMED_ARROW_DEFLECT, player);
@SuppressWarnings("all")
final Probability probability = ProbabilityUtil.getSkillProbability(UNARMED_ARROW_DEFLECT, mmoPlayer);
assertEquals(0.2D, probability.getValue());
assertProbabilityExpectations(20, probability);
}