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 Version 2.2.009
Fixed a bug that prevented mcMMO from loading on MC versions older than 1.20.6 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) Dramatically increased the base XP for Alchemy again (see notes)

View File

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

View File

@ -29,7 +29,7 @@ public class AcrobaticsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// ACROBATICS_DODGE // ACROBATICS_DODGE
if (canDodge) { if (canDodge) {
String[] dodgeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_DODGE); final String[] dodgeStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ACROBATICS_DODGE);
dodgeChance = dodgeStrings[0]; dodgeChance = dodgeStrings[0];
dodgeChanceLucky = dodgeStrings[1]; dodgeChanceLucky = dodgeStrings[1];
} }
@ -56,7 +56,7 @@ public class AcrobaticsCommand extends SkillCommand {
if(abstractSubSkill != null) 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]) messages.add(getStatMessage(SubSkillType.ACROBATICS_ROLL, rollStrings[0])
+ (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", rollStrings[1]) : "")); + (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.locale.LocaleLoader;
import com.gmail.nossr50.skills.alchemy.AlchemyManager; import com.gmail.nossr50.skills.alchemy.AlchemyManager;
import com.gmail.nossr50.util.Permissions; 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.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -30,14 +29,7 @@ public class AlchemyCommand extends SkillCommand {
} }
protected String[] calculateAbilityDisplayValues(Player player) { protected String[] calculateAbilityDisplayValues(Player player) {
//TODO: Needed? AlchemyManager alchemyManager = mmoPlayer.getAlchemyManager();
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();
String[] displayValues = new String[2]; String[] displayValues = new String[2];
boolean isLucky = Permissions.lucky(player, PrimarySkillType.ALCHEMY); boolean isLucky = Permissions.lucky(player, PrimarySkillType.ALCHEMY);
@ -59,7 +51,7 @@ public class AlchemyCommand extends SkillCommand {
// ALCHEMY_CONCOCTIONS // ALCHEMY_CONCOCTIONS
if (canConcoctions) { if (canConcoctions) {
AlchemyManager alchemyManager = UserManager.getPlayer(player).getAlchemyManager(); AlchemyManager alchemyManager = mmoPlayer.getAlchemyManager();
tier = alchemyManager.getTier(); tier = alchemyManager.getTier();
ingredientCount = alchemyManager.getIngredients().size(); ingredientCount = alchemyManager.getIngredients().size();
ingredientList = alchemyManager.getIngredientList(); ingredientList = alchemyManager.getIngredientList();

View File

@ -33,14 +33,14 @@ public class ArcheryCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// ARCHERY_ARROW_RETRIEVAL // ARCHERY_ARROW_RETRIEVAL
if (canRetrieve) { if (canRetrieve) {
String[] retrieveStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_ARROW_RETRIEVAL); String[] retrieveStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ARCHERY_ARROW_RETRIEVAL);
retrieveChance = retrieveStrings[0]; retrieveChance = retrieveStrings[0];
retrieveChanceLucky = retrieveStrings[1]; retrieveChanceLucky = retrieveStrings[1];
} }
// ARCHERY_DAZE // ARCHERY_DAZE
if (canDaze) { if (canDaze) {
String[] dazeStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ARCHERY_DAZE); String[] dazeStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ARCHERY_DAZE);
dazeChance = dazeStrings[0]; dazeChance = dazeStrings[0];
dazeChanceLucky = dazeStrings[1]; 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.locale.LocaleLoader;
import com.gmail.nossr50.skills.axes.Axes; import com.gmail.nossr50.skills.axes.Axes;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
@ -38,7 +37,7 @@ public class AxesCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// ARMOR IMPACT // ARMOR IMPACT
if (canImpact) { if (canImpact) {
impactDamage = UserManager.getPlayer(player).getAxesManager().getImpactDurabilityDamage(); impactDamage = mmoPlayer.getAxesManager().getImpactDurabilityDamage();
} }
// AXE MASTERY // AXE MASTERY
@ -48,7 +47,7 @@ public class AxesCommand extends SkillCommand {
// CRITICAL HIT // CRITICAL HIT
if (canCritical) { if (canCritical) {
String[] criticalHitStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.AXES_CRITICAL_STRIKES); String[] criticalHitStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.AXES_CRITICAL_STRIKES);
critChance = criticalHitStrings[0]; critChance = criticalHitStrings[0];
critChanceLucky = criticalHitStrings[1]; critChanceLucky = criticalHitStrings[1];
} }

View File

@ -1,9 +1,7 @@
package com.gmail.nossr50.commands.skills; package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.Permissions; 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.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; 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) { protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) { if (mmoPlayer == null) {
return messages; 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.locale.LocaleLoader;
import com.gmail.nossr50.skills.excavation.ExcavationManager; import com.gmail.nossr50.skills.excavation.ExcavationManager;
import com.gmail.nossr50.util.Permissions; 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.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component; 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) { protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
ExcavationManager excavationManager = UserManager.getPlayer(player).getExcavationManager(); ExcavationManager excavationManager = mmoPlayer.getExcavationManager();
if (canGigaDrill) { if (canGigaDrill) {
messages.add(getStatMessage(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, gigaDrillBreakerLength) 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.mcMMO;
import com.gmail.nossr50.skills.fishing.FishingManager; import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.util.Permissions; 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.Probability;
import com.gmail.nossr50.util.random.ProbabilityUtil; import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
@ -50,7 +49,7 @@ public class FishingCommand extends SkillCommand {
@Override @Override
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
FishingManager fishingManager = UserManager.getPlayer(player).getFishingManager(); FishingManager fishingManager = mmoPlayer.getFishingManager();
// TREASURE HUNTER // TREASURE HUNTER
if (canTreasureHunt) { if (canTreasureHunt) {

View File

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

View File

@ -30,10 +30,6 @@
// @Override // @Override
// protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) { // protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
// List<String> messages = new ArrayList<>(); // List<String> messages = new ArrayList<>();
// McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
// if (mmoPlayer == null) {
// return messages;
// }
// //
// if(SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) { // if(SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
// messages.add(getStatMessage(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.locale.LocaleLoader;
import com.gmail.nossr50.skills.mining.MiningManager; import com.gmail.nossr50.skills.mining.MiningManager;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
@ -45,7 +44,7 @@ public class MiningCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// BLAST MINING // BLAST MINING
if (canBlast || canDemoExpert || canBiggerBombs) { if (canBlast || canDemoExpert || canBiggerBombs) {
MiningManager miningManager = UserManager.getPlayer(player).getMiningManager(); MiningManager miningManager = mmoPlayer.getMiningManager();
blastMiningRank = miningManager.getBlastMiningTier(); blastMiningRank = miningManager.getBlastMiningTier();
bonusTNTDrops = miningManager.getDropMultiplier(); bonusTNTDrops = miningManager.getDropMultiplier();
@ -57,14 +56,14 @@ public class MiningCommand extends SkillCommand {
// Mastery TRIPLE DROPS // Mastery TRIPLE DROPS
if (canTripleDrop) { if (canTripleDrop) {
String[] masteryTripleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_MOTHER_LODE); String[] masteryTripleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.MINING_MOTHER_LODE);
tripleDropChance = masteryTripleDropStrings[0]; tripleDropChance = masteryTripleDropStrings[0];
tripleDropChanceLucky = masteryTripleDropStrings[1]; tripleDropChanceLucky = masteryTripleDropStrings[1];
} }
// DOUBLE DROPS // DOUBLE DROPS
if (canDoubleDrop) { if (canDoubleDrop) {
String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.MINING_DOUBLE_DROPS); String[] doubleDropStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.MINING_DOUBLE_DROPS);
doubleDropChance = doubleDropStrings[0]; doubleDropChance = doubleDropStrings[0];
doubleDropChanceLucky = doubleDropStrings[1]; 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.RepairManager;
import com.gmail.nossr50.skills.repair.repairables.Repairable; import com.gmail.nossr50.skills.repair.repairables.Repairable;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
@ -68,7 +67,7 @@ public class RepairCommand extends SkillCommand {
// SUPER REPAIR // SUPER REPAIR
if (canSuperRepair) { if (canSuperRepair) {
String[] superRepairStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.REPAIR_SUPER_REPAIR); String[] superRepairStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.REPAIR_SUPER_REPAIR);
superRepairChance = superRepairStrings[0]; superRepairChance = superRepairStrings[0];
superRepairChanceLucky = superRepairStrings[1]; superRepairChanceLucky = superRepairStrings[1];
} }
@ -94,7 +93,7 @@ public class RepairCommand extends SkillCommand {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
if (canArcaneForge) { if (canArcaneForge) {
RepairManager repairManager = UserManager.getPlayer(player).getRepairManager(); RepairManager repairManager = mmoPlayer.getRepairManager();
messages.add(getStatMessage(false, true, messages.add(getStatMessage(false, true,
SubSkillType.REPAIR_ARCANE_FORGING, 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.Salvage;
import com.gmail.nossr50.skills.salvage.SalvageManager; import com.gmail.nossr50.skills.salvage.SalvageManager;
import com.gmail.nossr50.util.Permissions; 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.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -38,7 +37,7 @@ public class SalvageCommand extends SkillCommand {
@Override @Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) { protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
SalvageManager salvageManager = UserManager.getPlayer(player).getSalvageManager(); SalvageManager salvageManager = mmoPlayer.getSalvageManager();
if (canScrapCollector) { if (canScrapCollector) {
messages.add(getStatMessage(false, true, 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 percent = new DecimalFormat("##0.00%");
protected DecimalFormat decimal = new DecimalFormat("##0.00"); protected DecimalFormat decimal = new DecimalFormat("##0.00");
protected McMMOPlayer mmoPlayer;
private final CommandExecutor skillGuideCommand; private final CommandExecutor skillGuideCommand;
@ -53,9 +54,9 @@ public abstract class SkillCommand implements TabExecutor {
} }
Player player = (Player) sender; 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")); sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
return true; return true;
} }
@ -63,7 +64,7 @@ public abstract class SkillCommand implements TabExecutor {
if (args.length == 0) { if (args.length == 0) {
boolean isLucky = Permissions.lucky(player, skill); boolean isLucky = Permissions.lucky(player, skill);
boolean hasEndurance = PerksUtils.handleActivationPerks(player, 0, 0) != 0; 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 //Send the players a few blank lines to make finding the top of the skill command easier
if (mcMMO.p.getAdvancedConfig().doesSkillCommandSendBlankLines()) if (mcMMO.p.getAdvancedConfig().doesSkillCommandSendBlankLines())
@ -75,7 +76,7 @@ public abstract class SkillCommand implements TabExecutor {
dataCalculations(player, skillValue); dataCalculations(player, skillValue);
sendSkillCommandHeader(mcMMO.p.getSkillTools().getLocalizedSkillName(skill), sendSkillCommandHeader(mcMMO.p.getSkillTools().getLocalizedSkillName(skill),
player, mcMMOPlayer, (int) skillValue); player, mmoPlayer, (int) skillValue);
//Make JSON text components //Make JSON text components
List<Component> subskillTextComponents = getTextComponents(player); 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.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
@ -34,7 +33,7 @@ public class SmeltingCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// FUEL EFFICIENCY // FUEL EFFICIENCY
if (canFuelEfficiency) { if (canFuelEfficiency) {
burnTimeModifier = String.valueOf(UserManager.getPlayer(player).getSmeltingManager().getFuelEfficiencyMultiplier()); burnTimeModifier = String.valueOf(mmoPlayer.getSmeltingManager().getFuelEfficiencyMultiplier());
} }
// FLUX MINING // FLUX MINING
@ -46,7 +45,7 @@ public class SmeltingCommand extends SkillCommand {
// SECOND SMELT // SECOND SMELT
if (canSecondSmelt) { 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_secondSmeltChance = secondSmeltStrings[0];
str_secondSmeltChanceLucky = secondSmeltStrings[1]; str_secondSmeltChanceLucky = secondSmeltStrings[1];
} }
@ -81,7 +80,7 @@ public class SmeltingCommand extends SkillCommand {
if (canUnderstandTheArt) { if (canUnderstandTheArt) {
messages.add(getStatMessage(false, true, SubSkillType.SMELTING_UNDERSTANDING_THE_ART, messages.add(getStatMessage(false, true, SubSkillType.SMELTING_UNDERSTANDING_THE_ART,
String.valueOf(UserManager.getPlayer(player).getSmeltingManager().getVanillaXpMultiplier()))); String.valueOf(mmoPlayer.getSmeltingManager().getVanillaXpMultiplier())));
} }
return messages; 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.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
@ -39,7 +38,7 @@ public class SwordsCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// SWORDS_COUNTER_ATTACK // SWORDS_COUNTER_ATTACK
if (canCounter) { if (canCounter) {
String[] counterStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.SWORDS_COUNTER_ATTACK); String[] counterStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.SWORDS_COUNTER_ATTACK);
counterChance = counterStrings[0]; counterChance = counterStrings[0];
counterChanceLucky = counterStrings[1]; counterChanceLucky = counterStrings[1];
} }
@ -105,7 +104,7 @@ public class SwordsCommand extends SkillCommand {
if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_STAB)) if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_STAB))
{ {
messages.add(getStatMessage(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)) { if(SkillUtils.canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {

View File

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

View File

@ -1,8 +1,6 @@
package com.gmail.nossr50.commands.skills; package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; 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.CombatUtils;
import com.gmail.nossr50.util.skills.SkillUtils; import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.text.TextComponentFactory; import com.gmail.nossr50.util.text.TextComponentFactory;
@ -32,10 +30,6 @@ public class TridentsCommand extends SkillCommand {
@Override @Override
protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) { protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>(); List<String> messages = new ArrayList<>();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return messages;
}
if(SkillUtils.canUseSubskill(player, TRIDENTS_TRIDENTS_LIMIT_BREAK)) { if(SkillUtils.canUseSubskill(player, TRIDENTS_TRIDENTS_LIMIT_BREAK)) {
messages.add(getStatMessage(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.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.util.Permissions; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.CombatUtils; import com.gmail.nossr50.util.skills.CombatUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
@ -40,7 +39,7 @@ public class UnarmedCommand extends SkillCommand {
protected void dataCalculations(Player player, float skillValue) { protected void dataCalculations(Player player, float skillValue) {
// UNARMED_ARROW_DEFLECT // UNARMED_ARROW_DEFLECT
if (canDeflect) { if (canDeflect) {
String[] deflectStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_ARROW_DEFLECT); String[] deflectStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_ARROW_DEFLECT);
deflectChance = deflectStrings[0]; deflectChance = deflectStrings[0];
deflectChanceLucky = deflectStrings[1]; deflectChanceLucky = deflectStrings[1];
} }
@ -54,19 +53,19 @@ public class UnarmedCommand extends SkillCommand {
// UNARMED_DISARM // UNARMED_DISARM
if (canDisarm) { if (canDisarm) {
String[] disarmStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_DISARM); String[] disarmStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_DISARM);
disarmChance = disarmStrings[0]; disarmChance = disarmStrings[0];
disarmChanceLucky = disarmStrings[1]; disarmChanceLucky = disarmStrings[1];
} }
// IRON ARM // IRON ARM
if (canIronArm) { if (canIronArm) {
ironArmBonus = UserManager.getPlayer(player).getUnarmedManager().getSteelArmStyleDamage(); ironArmBonus = mmoPlayer.getUnarmedManager().getSteelArmStyleDamage();
} }
// IRON GRIP // IRON GRIP
if (canIronGrip) { if (canIronGrip) {
String[] ironGripStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.UNARMED_IRON_GRIP); String[] ironGripStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.UNARMED_IRON_GRIP);
ironGripChance = ironGripStrings[0]; ironGripChance = ironGripStrings[0];
ironGripChanceLucky = ironGripStrings[1]; ironGripChanceLucky = ironGripStrings[1];
} }

View File

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

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.skills.subskills; package com.gmail.nossr50.datatypes.skills.subskills;
import com.gmail.nossr50.config.CoreSkillsConfig; 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.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction; import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction;
import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank; 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 * Prints detailed info about this subskill to the player
* *
* @param player the target player * @param mmoPlayer the target player
*/ */
@Override @Override
public void printInfo(Player player) { public void printInfo(McMMOPlayer mmoPlayer) {
/* DEFAULT SETTINGS PRINT THE BARE MINIMUM */ /* 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.Header"));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", getConfigKeyName())); player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.SubSkillHeader", getConfigKeyName()));
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.DetailsHeader")); 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.experience.XPGainReason;
import com.gmail.nossr50.datatypes.interactions.NotificationType; import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer; 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader; 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.ItemUtils;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.NotificationManager; 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.Probability;
import com.gmail.nossr50.util.random.ProbabilityUtil; import com.gmail.nossr50.util.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.PerksUtils; import com.gmail.nossr50.util.skills.PerksUtils;
@ -67,25 +65,25 @@ public class Roll extends AcrobaticsSubSkill {
return false; return false;
if (entityDamageEvent.getCause() == EntityDamageEvent.DamageCause.FALL) {//Grab the player 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; return false;
/* /*
* Check for success * Check for success
*/ */
Player player = (Player) ((EntityDamageEvent) event).getEntity();
if (canRoll(player)) { if (canRoll(mmoPlayer)) {
entityDamageEvent.setDamage(rollCheck(player, mcMMOPlayer, entityDamageEvent.getFinalDamage())); entityDamageEvent.setDamage(rollCheck(mmoPlayer, entityDamageEvent.getFinalDamage()));
if (entityDamageEvent.getFinalDamage() == 0) { if (entityDamageEvent.getFinalDamage() == 0) {
entityDamageEvent.setCancelled(true); entityDamageEvent.setCancelled(true);
return 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 //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 * Adds detailed stats specific to this skill
* *
* @param componentBuilder target component builder * @param componentBuilder target component builder
* @param player target player * @param mmoPlayer target player
*/ */
@Override @Override
public void addStats(TextComponent.Builder componentBuilder, Player player) { public void addStats(TextComponent.Builder componentBuilder, McMMOPlayer mmoPlayer) {
String rollChance, rollChanceLucky, gracefulRollChance, gracefulRollChanceLucky; String rollChance, rollChanceLucky, gracefulRollChance, gracefulRollChanceLucky;
/* Values related to the player */ /* Values related to the player */
PlayerProfile playerProfile = UserManager.getPlayer(player).getProfile(); float skillValue = mmoPlayer.getSkillLevel(getPrimarySkill());
float skillValue = playerProfile.getSkillLevel(getPrimarySkill()); boolean isLucky = Permissions.lucky(mmoPlayer.getPlayer(), getPrimarySkill());
boolean isLucky = Permissions.lucky(player, getPrimarySkill());
String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(player, SubSkillType.ACROBATICS_ROLL); String[] rollStrings = ProbabilityUtil.getRNGDisplayValues(mmoPlayer, SubSkillType.ACROBATICS_ROLL);
rollChance = rollStrings[0]; rollChance = rollStrings[0];
rollChanceLucky = rollStrings[1]; rollChanceLucky = rollStrings[1];
/* /*
* Graceful is double the odds of a normal roll * Graceful is double the odds of a normal roll
*/ */
Probability probability = getRollProbability(player); Probability probability = getRollProbability(mmoPlayer);
Probability gracefulProbability = Probability.ofValue(probability.getValue() * 2); Probability gracefulProbability = Probability.ofValue(probability.getValue() * 2);
String[] gracefulRollStrings = ProbabilityUtil.getRNGDisplayValues(gracefulProbability); String[] gracefulRollStrings = ProbabilityUtil.getRNGDisplayValues(gracefulProbability);
gracefulRollChance = gracefulRollStrings[0]; gracefulRollChance = gracefulRollStrings[0];
@ -169,8 +166,8 @@ public class Roll extends AcrobaticsSubSkill {
} }
@NotNull @NotNull
private Probability getRollProbability(Player player) { private Probability getRollProbability(McMMOPlayer mmoPlayer) {
return ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player); return ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, mmoPlayer);
} }
@Override @Override
@ -188,8 +185,9 @@ public class Roll extends AcrobaticsSubSkill {
return true; return true;
} }
private boolean canRoll(Player player) { private boolean canRoll(McMMOPlayer mmoPlayer) {
return RankUtils.hasUnlockedSubskill(player, SubSkillType.ACROBATICS_ROLL) && Permissions.isSubSkillEnabled(player, SubSkillType.ACROBATICS_ROLL); 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 * @return the modified event damage if the ability was successful, the original event damage otherwise
*/ */
@VisibleForTesting @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 (mmoPlayer.getPlayer().isSneaking()) {
return gracefulRollCheck(mmoPlayer, damage, skillLevel);
if (player.isSneaking()) {
return gracefulRollCheck(player, mcMMOPlayer, damage, skillLevel);
} }
double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold()); double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold());
if (!isFatal(player, modifiedDamage) if (!isFatal(mmoPlayer, modifiedDamage)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_ROLL, player)) { && ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_ROLL, mmoPlayer)) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text"); NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Roll.Text");
SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS); SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS);
//player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text")); //mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Acrobatics.Roll.Text"));
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { //if (!SkillUtils.cooldownExpired((long) mcMMOmmoPlayer.getPlayer().getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, true), XPGainReason.PVE);
//} //}
addFallLocation(player); addFallLocation(mmoPlayer);
return modifiedDamage; return modifiedDamage;
} }
else if (!isFatal(player, damage)) { else if (!isFatal(mmoPlayer, damage)) {
//if (!SkillUtils.cooldownExpired((long) mcMMOPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) { //if (!SkillUtils.cooldownExpired((long) mmoPlayer.getTeleportATS(), Config.getInstance().getXPAfterTeleportCooldown())) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE); SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, false), XPGainReason.PVE);
//} //}
} }
addFallLocation(player); addFallLocation(mmoPlayer);
return damage; return damage;
} }
private int getActivationChance(McMMOPlayer mcMMOPlayer) { private int getActivationChance(McMMOPlayer mmoPlayer) {
return PerksUtils.handleLuckyPerks(mcMMOPlayer.getPlayer(), getPrimarySkill()); 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 * @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 * @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); 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 //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"); NotificationManager.sendPlayerInformation(mmoPlayer.getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Acrobatics.Ability.Proc");
SoundManager.sendCategorizedSound(player, player.getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F); SoundManager.sendCategorizedSound(mmoPlayer.getPlayer(), mmoPlayer.getPlayer().getLocation(), SoundType.ROLL_ACTIVATED, SoundCategory.PLAYERS,0.5F);
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, true), XPGainReason.PVE); SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, true), XPGainReason.PVE);
addFallLocation(player); addFallLocation(mmoPlayer);
return modifiedDamage; return modifiedDamage;
} }
else if (!isFatal(player, damage)) { else if (!isFatal(mmoPlayer, damage)) {
if(!isExploiting(player) && mcMMOPlayer.getAcrobaticsManager().canGainRollXP()) if(!isExploiting(mmoPlayer) && mmoPlayer.getAcrobaticsManager().canGainRollXP())
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, damage, false), XPGainReason.PVE); SkillUtils.applyXpGain(mmoPlayer, getPrimarySkill(), calculateRollXP(mmoPlayer, damage, false), XPGainReason.PVE);
addFallLocation(player); addFallLocation(mmoPlayer);
} }
return damage; return damage;
} }
@NotNull @NotNull
public static Probability getGracefulProbability(Player player) { public static Probability getGracefulProbability(McMMOPlayer mmoPlayer) {
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, player).getValue() * 2; double gracefulOdds = ProbabilityUtil.getSubSkillProbability(SubSkillType.ACROBATICS_ROLL, mmoPlayer).getValue() * 2;
return Probability.ofValue(gracefulOdds); return Probability.ofValue(gracefulOdds);
} }
@ -283,24 +280,22 @@ public class Roll extends AcrobaticsSubSkill {
* *
* @return true if exploits are detected, false otherwise * @return true if exploits are detected, false otherwise
*/ */
private boolean isExploiting(Player player) { private boolean isExploiting(McMMOPlayer mmoPlayer) {
if (!ExperienceConfig.getInstance().isAcrobaticsExploitingPrevented()) { if (!ExperienceConfig.getInstance().isAcrobaticsExploitingPrevented()) {
return false; return false;
} }
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); if (ItemUtils.hasItemInEitherHand(mmoPlayer.getPlayer(), Material.ENDER_PEARL) || mmoPlayer.getPlayer().isInsideVehicle()) {
if(mmoPlayer.isDebugMode()) {
if (ItemUtils.hasItemInEitherHand(player, Material.ENDER_PEARL) || player.isInsideVehicle()) { mmoPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Ender Pearl or Inside Vehicle");
if(mcMMOPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Ender Pearl or Inside Vehicle");
} }
return true; return true;
} }
if(UserManager.getPlayer(player).getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(player))) if(mmoPlayer.getAcrobaticsManager().hasFallenInLocationBefore(getBlockLocation(mmoPlayer)))
{ {
if(mcMMOPlayer.isDebugMode()) { if(mmoPlayer.isDebugMode()) {
mcMMOPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Fallen in location before"); mmoPlayer.getPlayer().sendMessage("Acrobatics XP Prevented: Fallen in location before");
} }
return true; return true;
@ -309,11 +304,11 @@ public class Roll extends AcrobaticsSubSkill {
return false; //NOT EXPLOITING 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 //Clamp Damage to account for insane DRs
damage = Math.min(20, damage); 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())); float xp = (float) (damage * (isRoll ? ExperienceConfig.getInstance().getRollXPModifier() : ExperienceConfig.getInstance().getFallXPModifier()));
if (boots != null && boots.containsEnchantment(mcMMO.p.getEnchantmentMapper().getFeatherFalling())) { 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); return Math.max(damage - damageThreshold, 0.0);
} }
private boolean isFatal(Player player, double damage) { private boolean isFatal(McMMOPlayer mmoPlayer, double damage) {
return player.getHealth() - damage <= 0; return mmoPlayer.getPlayer().getHealth() - damage <= 0;
} }
/** /**
@ -344,103 +339,51 @@ public class Roll extends AcrobaticsSubSkill {
/** /**
* Prints detailed info about this subskill to the player * Prints detailed info about this subskill to the player
* *
* @param player the target player * @param mmoPlayer the target player
*/ */
@Override @Override
public void printInfo(Player player) { public void printInfo(McMMOPlayer mmoPlayer) {
//Header //Header
super.printInfo(player); super.printInfo(mmoPlayer);
//Start the description string. //Start the description string.
//player.sendMessage(getDescription()); //player.sendMessage(getDescription());
//Player stats //Player stats
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Stats", mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.MmoInfo.Stats",
LocaleLoader.getString("Acrobatics.SubSkill.Roll.Stats", getStats(player)))); LocaleLoader.getString("Acrobatics.SubSkill.Roll.Stats", getStats(mmoPlayer))));
//Mechanics //Mechanics
player.sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mechanics")); mmoPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.MmoInfo.Mechanics"));
player.sendMessage(getMechanics()); mmoPlayer.getPlayer().sendMessage(getMechanics());
} }
/**
* Returns a collection of strings about how a skill works
* Used in the MMO Info command
*
* @return
*/
@Override @Override
public String getMechanics() { 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."; 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 * 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 * @return stat array for target player for this skill
*/ */
@Override @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 playerChanceGrace = playerChanceRoll * 2;
double gracefulOdds = ProbabilityUtil.getSubSkillProbability(subSkillType, player).getValue() * 2; double gracefulOdds = ProbabilityUtil.getSubSkillProbability(subSkillType, mmoPlayer).getValue() * 2;
return new Double[]{ playerChanceRoll, playerChanceGrace }; return new Double[]{ playerChanceRoll, playerChanceGrace };
} }
public void addFallLocation(@NotNull Player player) public void addFallLocation(@NotNull McMMOPlayer mmoPlayer) {
{ mmoPlayer.getAcrobaticsManager().addLocationToFallMap(getBlockLocation(mmoPlayer));
UserManager.getPlayer(player).getAcrobaticsManager().addLocationToFallMap(getBlockLocation(player));
} }
public @NotNull Location getBlockLocation(@NotNull Player player) public @NotNull Location getBlockLocation(@NotNull McMMOPlayer mmoPlayer) {
{ return mmoPlayer.getPlayer().getLocation().getBlock().getLocation();
return player.getLocation().getBlock().getLocation();
} }
} }

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.datatypes.skills.subskills.interfaces; package com.gmail.nossr50.datatypes.skills.subskills.interfaces;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.interfaces.Skill; import com.gmail.nossr50.datatypes.skills.interfaces.Skill;
import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TextComponent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -19,10 +20,10 @@ public interface SubSkill extends Skill {
/** /**
* Get an array of various stats for a player * 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 * @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 * 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 * Adds detailed stats specific to this skill
* @param componentBuilder target component builder * @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 * Whether this subskill is enabled
@ -71,7 +72,7 @@ public interface SubSkill extends Skill {
/** /**
* Prints detailed info about this subskill to the player * 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; package com.gmail.nossr50.events.skills;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -7,19 +8,35 @@ import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
/** /**
* Generic event for mcMMO skill handling. * Generic event for mcMMO skill handling.
*/ */
public abstract class McMMOPlayerSkillEvent extends PlayerEvent { public abstract class McMMOPlayerSkillEvent extends PlayerEvent {
protected @NotNull PrimarySkillType skill; protected @NotNull PrimarySkillType skill;
protected int skillLevel; protected int skillLevel;
protected McMMOPlayer mmoPlayer;
@Deprecated(forRemoval = true, since = "2.2.010")
protected McMMOPlayerSkillEvent(@NotNull Player player, @NotNull PrimarySkillType skill) { protected McMMOPlayerSkillEvent(@NotNull Player player, @NotNull PrimarySkillType skill) {
super(player); 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.skill = skill;
this.skillLevel = UserManager.getPlayer(player).getSkillLevel(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 * @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 **/ /** Rest of file is required boilerplate for custom events **/
private static final HandlerList handlers = new HandlerList(); 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 @Override
public @NotNull HandlerList getHandlers() { public @NotNull HandlerList getHandlers() {
return handlers; return handlers;

View File

@ -1,14 +1,24 @@
package com.gmail.nossr50.events.skills.abilities; 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.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import java.util.Objects;
public class McMMOPlayerAbilityActivateEvent extends McMMOPlayerAbilityEvent implements Cancellable { public class McMMOPlayerAbilityActivateEvent extends McMMOPlayerAbilityEvent implements Cancellable {
private boolean cancelled; private boolean cancelled;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerAbilityActivateEvent(Player player, PrimarySkillType skill) { 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; cancelled = false;
} }

View File

@ -1,10 +1,20 @@
package com.gmail.nossr50.events.skills.abilities; 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.PrimarySkillType;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
public class McMMOPlayerAbilityDeactivateEvent extends McMMOPlayerAbilityEvent { public class McMMOPlayerAbilityDeactivateEvent extends McMMOPlayerAbilityEvent {
public McMMOPlayerAbilityDeactivateEvent(Player player, PrimarySkillType skill) { @Deprecated(forRemoval = true, since = "2.2.010")
super(player, skill); 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; 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType; import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent; import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Objects;
public class McMMOPlayerAbilityEvent extends McMMOPlayerSkillEvent { public class McMMOPlayerAbilityEvent extends McMMOPlayerSkillEvent {
private final SuperAbilityType ability; 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) { 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); ability = mcMMO.p.getSkillTools().getSuperAbility(skill);
} }

View File

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

View File

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

View File

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

View File

@ -1,23 +1,34 @@
package com.gmail.nossr50.events.skills.fishing; 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.entity.Player;
import org.bukkit.inventory.ItemStack; 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 { public class McMMOPlayerFishingTreasureEvent extends McMMOPlayerFishingEvent {
private ItemStack treasure; private ItemStack treasure;
private int xp; private int xp;
@Deprecated(forRemoval = true, since = "2.2.010")
public McMMOPlayerFishingTreasureEvent(Player player, ItemStack treasure, int xp) { 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.treasure = treasure;
this.xp = xp; this.xp = xp;
} }
public ItemStack getTreasure() { public @Nullable ItemStack getTreasure() {
return treasure; return treasure;
} }
public void setTreasure(ItemStack item) { public void setTreasure(@Nullable ItemStack item) {
this.treasure = item; this.treasure = item;
} }

View File

@ -1,20 +1,32 @@
package com.gmail.nossr50.events.skills.fishing; 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.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class McMMOPlayerMagicHunterEvent extends McMMOPlayerFishingTreasureEvent { import static java.util.Objects.requireNonNull;
private final Map<Enchantment, Integer> enchants;
public McMMOPlayerMagicHunterEvent(Player player, ItemStack treasure, int xp, Map<Enchantment, Integer> enchants) { public class McMMOPlayerMagicHunterEvent extends McMMOPlayerFishingTreasureEvent {
super(player, treasure, xp); private final Map<Enchantment, Integer> enchants = new HashMap<>();
this.enchants = enchants;
@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; return enchants;
} }
} }

View File

@ -1,11 +1,16 @@
package com.gmail.nossr50.events.skills.secondaryabilities; 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.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill; import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent; import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.jetbrains.annotations.NotNull;
import static java.util.Objects.requireNonNull;
public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable { public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable {
private SubSkillType subSkillType; private SubSkillType subSkillType;
@ -16,9 +21,20 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* Only skills using the old system will fire this event * Only skills using the old system will fire this event
* @param player target player * @param player target player
* @param subSkillType target subskill * @param subSkillType target subskill
* @deprecated Use {@link #SubSkillEvent(McMMOPlayer, SubSkillType)} instead
*/ */
public SubSkillEvent(Player player, SubSkillType subSkillType) { @Deprecated(forRemoval = true, since = "2.2.010")
super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType)); 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; this.subSkillType = subSkillType;
} }
@ -28,15 +44,30 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
* @param subSkillType target subskill * @param subSkillType target subskill
* @param resultModifier a value multiplied against the final result of the dice roll, typically between 0-1.0 * @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)); super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType; this.subSkillType = requireNonNull(subSkillType, "subSkillType cannot be null");
this.resultModifier = resultModifier; this.resultModifier = resultModifier;
} }
public SubSkillEvent(Player player, AbstractSubSkill abstractSubSkill) @Deprecated(forRemoval = true, since = "2.2.010")
{ public SubSkillEvent(@NotNull Player player, @NotNull AbstractSubSkill abstractSubSkill) {
super(player, abstractSubSkill.getPrimarySkill()); this(requireNonNull(UserManager.getPlayer(player)), abstractSubSkill);
}
public SubSkillEvent(@NotNull McMMOPlayer mmoPlayer, @NotNull AbstractSubSkill abstractSubSkill) {
super(mmoPlayer, abstractSubSkill.getPrimarySkill());
} }
public double getResultModifier() { 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"); player.sendMessage("[mcMMO DEBUG] World Guard xp flag is not permitted for this player in this region");
} }
if(blockState instanceof Furnace furnace) if(blockState instanceof Furnace || blockState instanceof BrewingStand) {
{ if(ContainerMetadataUtils.isContainerOwned(blockState)) {
if(mcMMO.getSmeltingTracker().isFurnaceOwned(furnace)) player.sendMessage("[mcMMO DEBUG] This container has a registered owner");
{ final OfflinePlayer furnacePlayer = ContainerMetadataUtils.getContainerOwner(blockState);
player.sendMessage("[mcMMO DEBUG] This furnace has a registered owner"); if(furnacePlayer != null) {
OfflinePlayer furnacePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace); player.sendMessage("[mcMMO DEBUG] This container is owned by player "+furnacePlayer.getName());
if(furnacePlayer != null)
{
player.sendMessage("[mcMMO DEBUG] This furnace is owned by player "+furnacePlayer.getName());
} }
} }
else 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()) 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.events.fake.FakeEntityTameEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.metadata.MobMetaFlagType; import com.gmail.nossr50.metadata.MobMetaFlagType;
import com.gmail.nossr50.metadata.MobMetadataService;
import com.gmail.nossr50.runnables.TravelingBlockMetaCleanup; import com.gmail.nossr50.runnables.TravelingBlockMetaCleanup;
import com.gmail.nossr50.skills.archery.Archery; import com.gmail.nossr50.skills.archery.Archery;
import com.gmail.nossr50.skills.crossbows.Crossbows; import com.gmail.nossr50.skills.crossbows.Crossbows;
@ -47,9 +46,10 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static com.gmail.nossr50.util.MobMetadataUtils.*;
public class EntityListener implements Listener { public class EntityListener implements Listener {
private final mcMMO pluginRef; private final mcMMO pluginRef;
private final @NotNull MobMetadataService mobMetadataService;
/** /**
* We can use this {@link NamespacedKey} for {@link Enchantment} comparisons to * 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) { public EntityListener(final mcMMO pluginRef) {
this.pluginRef = pluginRef; this.pluginRef = pluginRef;
mobMetadataService = mcMMO.getMetadataService().getMobMetadataService();
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
@ -67,10 +66,10 @@ public class EntityListener implements Listener {
if(event.getEntity() instanceof LivingEntity livingEntity) { if(event.getEntity() instanceof LivingEntity livingEntity) {
//Transfer metadata keys from mob-spawned mobs to new mobs //Transfer metadata keys from mob-spawned mobs to new mobs
if(mobMetadataService.hasMobFlags(livingEntity)) { if(hasMobFlags(livingEntity)) {
for(Entity entity : event.getTransformedEntities()) { for(Entity entity : event.getTransformedEntities()) {
if(entity instanceof LivingEntity transformedEntity) { 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(event.getEntity() instanceof Enderman enderman) {
if(!mobMetadataService.hasMobFlag(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman)) { if(!hasMobFlag(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman)) {
mobMetadataService.flagMetadata(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman); flagMetadata(MobMetaFlagType.EXPLOITED_ENDERMEN, enderman);
} }
} }
} }
@ -168,7 +167,7 @@ public class EntityListener implements Listener {
return; 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); 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) { private void trackSpawnedAndPassengers(LivingEntity livingEntity, MobMetaFlagType mobMetaFlagType) {
mobMetadataService.flagMetadata(mobMetaFlagType, livingEntity); flagMetadata(mobMetaFlagType, livingEntity);
for(Entity passenger : livingEntity.getPassengers()) { for(Entity passenger : livingEntity.getPassengers()) {
if(passenger != null) { 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) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onEntityBreed(EntityBreedEvent event) { public void onEntityBreed(EntityBreedEvent event) {
if(ExperienceConfig.getInstance().isCOTWBreedingPrevented()) { 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); event.setCancelled(true);
Animals mom = (Animals) event.getMother(); Animals mom = (Animals) event.getMother();
Animals father = (Animals) event.getFather(); Animals father = (Animals) event.getFather();
@ -1005,12 +1004,12 @@ public class EntityListener implements Listener {
if (!UserManager.hasPlayerDataKey(player) if (!UserManager.hasPlayerDataKey(player)
|| (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(livingEntity)) || (ExperienceConfig.getInstance().isNPCInteractionPrevented() && Misc.isNPCEntityExcludingVillagers(livingEntity))
|| mobMetadataService.hasMobFlag(MobMetaFlagType.EGG_MOB, livingEntity) || hasMobFlag(MobMetaFlagType.EGG_MOB, livingEntity)
|| mobMetadataService.hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, livingEntity)) { || hasMobFlag(MobMetaFlagType.MOB_SPAWNER_MOB, livingEntity)) {
return; return;
} }
mobMetadataService.flagMetadata(MobMetaFlagType.PLAYER_TAMED_MOB, livingEntity); flagMetadata(MobMetaFlagType.PLAYER_TAMED_MOB, livingEntity);
//Profile not loaded //Profile not loaded
if(UserManager.getPlayer(player) == null) 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.events.fake.FakeBrewEvent; import com.gmail.nossr50.events.fake.FakeBrewEvent;
import com.gmail.nossr50.events.fake.FakeEvent;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask; import com.gmail.nossr50.runnables.player.PlayerUpdateInventoryTask;
import com.gmail.nossr50.skills.alchemy.Alchemy; import com.gmail.nossr50.skills.alchemy.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.ContainerMetadataUtils;
import com.gmail.nossr50.util.ItemUtils; import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.MetadataConstants; import com.gmail.nossr50.util.MetadataConstants;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
@ -29,7 +29,6 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BrewingStartEvent;
import org.bukkit.event.inventory.*; import org.bukkit.event.inventory.*;
import org.bukkit.inventory.*; import org.bukkit.inventory.*;
@ -55,7 +54,7 @@ public class InventoryListener implements Listener {
} }
Furnace furnace = (Furnace) furnaceState; Furnace furnace = (Furnace) furnaceState;
OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace); OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(furnace);
Player player; Player player;
if(offlinePlayer != null && offlinePlayer.isOnline() && offlinePlayer instanceof Player) { if(offlinePlayer != null && offlinePlayer.isOnline() && offlinePlayer instanceof Player) {
@ -101,7 +100,7 @@ public class InventoryListener implements Listener {
} }
if(blockState instanceof Furnace furnace) { if(blockState instanceof Furnace furnace) {
OfflinePlayer offlinePlayer = mcMMO.getSmeltingTracker().getFurnaceOwner(furnace); OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(furnace);
if(offlinePlayer != null) { if(offlinePlayer != null) {
@ -167,16 +166,16 @@ public class InventoryListener implements Listener {
Inventory inventory = event.getInventory(); Inventory inventory = event.getInventory();
Player player = ((Player) event.getWhoClicked()).getPlayer(); Player player = ((Player) event.getWhoClicked()).getPlayer();
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if(event.getInventory() instanceof FurnaceInventory) if(event.getInventory() instanceof FurnaceInventory furnaceInventory) {
{
Furnace furnace = mcMMO.getSmeltingTracker().getFurnaceFromInventory(event.getInventory());
if (furnace != null)
{
//Switch owners //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)) { if (!(inventory instanceof BrewerInventory)) {
@ -191,10 +190,11 @@ public class InventoryListener implements Listener {
HumanEntity whoClicked = event.getWhoClicked(); 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; return;
} }
// TODO: Investigate why this WG check is all the way down here?
/* WORLD GUARD MAIN FLAG CHECK */ /* WORLD GUARD MAIN FLAG CHECK */
if(WorldGuardUtils.isWorldGuardLoaded()) if(WorldGuardUtils.isWorldGuardLoaded())
{ {
@ -202,11 +202,16 @@ public class InventoryListener implements Listener {
return; return;
} }
ItemStack clicked = event.getCurrentItem(); final ItemStack clicked = event.getCurrentItem();
ItemStack cursor = event.getCursor(); 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))) { if ((clicked != null && (clicked.getType() == Material.POTION
AlchemyPotionBrewer.scheduleCheck(player, stand); || 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; return;
} }
@ -216,11 +221,11 @@ public class InventoryListener implements Listener {
if (click.isShiftClick()) { if (click.isShiftClick()) {
switch (slot) { switch (slot) {
case FUEL: case FUEL:
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
return; return;
case CONTAINER: case CONTAINER:
case QUICKBAR: case QUICKBAR:
if (!AlchemyPotionBrewer.isValidIngredient(player, clicked)) { if (!AlchemyPotionBrewer.isValidIngredientByPlayer(player, clicked)) {
return; return;
} }
@ -230,7 +235,7 @@ public class InventoryListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
AlchemyPotionBrewer.scheduleUpdate(inventory); AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
return; return;
default: default:
} }
@ -240,14 +245,14 @@ public class InventoryListener implements Listener {
if (AlchemyPotionBrewer.isEmpty(cursor)) { if (AlchemyPotionBrewer.isEmpty(cursor)) {
if (emptyClicked && click == ClickType.NUMBER_KEY) { if (emptyClicked && click == ClickType.NUMBER_KEY) {
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
return; return;
} }
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
} }
else if (emptyClicked) { else if (emptyClicked) {
if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) { if (AlchemyPotionBrewer.isValidIngredientByPlayer(player, cursor)) {
int amount = cursor.getAmount(); int amount = cursor.getAmount();
if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) { if (click == ClickType.LEFT || (click == ClickType.RIGHT && amount == 1)) {
@ -256,7 +261,7 @@ public class InventoryListener implements Listener {
event.setCursor(null); event.setCursor(null);
AlchemyPotionBrewer.scheduleUpdate(inventory); AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
} }
else if (click == ClickType.RIGHT) { else if (click == ClickType.RIGHT) {
event.setCancelled(true); event.setCancelled(true);
@ -271,7 +276,7 @@ public class InventoryListener implements Listener {
event.setCursor(rest); event.setCursor(rest);
AlchemyPotionBrewer.scheduleUpdate(inventory); AlchemyPotionBrewer.scheduleUpdate(inventory);
AlchemyPotionBrewer.scheduleCheck(player, stand); AlchemyPotionBrewer.scheduleCheck(stand);
} }
} }
} }
@ -324,9 +329,9 @@ public class InventoryListener implements Listener {
return; return;
} }
if (AlchemyPotionBrewer.isValidIngredient(player, cursor)) { if (AlchemyPotionBrewer.isValidIngredientByPlayer(player, cursor)) {
// Not handled: dragging custom ingredients over ingredient slot (does not trigger any event) // Not handled: dragging custom ingredients over ingredient slot (does not trigger any event)
AlchemyPotionBrewer.scheduleCheck(player, (BrewingStand) holder); AlchemyPotionBrewer.scheduleCheck((BrewingStand) holder);
return; return;
} }
@ -371,17 +376,15 @@ public class InventoryListener implements Listener {
if(WorldBlacklist.isWorldBlacklisted(event.getSource().getLocation().getWorld())) if(WorldBlacklist.isWorldBlacklisted(event.getSource().getLocation().getWorld()))
return; return;
Inventory inventory = event.getDestination(); final Inventory inventory = event.getDestination();
if (!(inventory instanceof BrewerInventory)) { if (!(inventory instanceof BrewerInventory)) {
return; return;
} }
InventoryHolder holder = inventory.getHolder(); final InventoryHolder holder = inventory.getHolder();
if (!(holder instanceof BrewingStand)) { if (holder instanceof BrewingStand brewingStand) {
return;
}
ItemStack item = event.getItem(); ItemStack item = event.getItem();
@ -394,9 +397,20 @@ public class InventoryListener implements Listener {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
int ingredientLevel = 1;
if (mcMMO.p.getGeneralConfig().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) { OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(brewingStand);
AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder); 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll; import com.gmail.nossr50.datatypes.skills.subskills.acrobatics.Roll;
import com.gmail.nossr50.listeners.*; import com.gmail.nossr50.listeners.*;
import com.gmail.nossr50.metadata.MetadataService;
import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.party.PartyManager;
import com.gmail.nossr50.placeholders.PapiExpansion; import com.gmail.nossr50.placeholders.PapiExpansion;
import com.gmail.nossr50.runnables.SaveTimerTask; 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.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillTools; 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.util.upgrade.UpgradeManager;
import com.gmail.nossr50.worldguard.WorldGuardManager; import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.tcoded.folialib.FoliaLib; import com.tcoded.folialib.FoliaLib;
@ -80,7 +78,6 @@ import java.util.List;
public class mcMMO extends JavaPlugin { public class mcMMO extends JavaPlugin {
/* Managers & Services */ /* Managers & Services */
private static PlatformManager platformManager; private static PlatformManager platformManager;
private static MetadataService metadataService;
private static ChunkManager placeStore; private static ChunkManager placeStore;
private static RepairableManager repairableManager; private static RepairableManager repairableManager;
private static SalvageableManager salvageableManager; private static SalvageableManager salvageableManager;
@ -90,12 +87,10 @@ public class mcMMO extends JavaPlugin {
private static UpgradeManager upgradeManager; private static UpgradeManager upgradeManager;
private static MaterialMapStore materialMapStore; private static MaterialMapStore materialMapStore;
private static PlayerLevelUtils playerLevelUtils; private static PlayerLevelUtils playerLevelUtils;
private static SmeltingTracker smeltingTracker;
private static TransientMetadataTools transientMetadataTools; private static TransientMetadataTools transientMetadataTools;
private static ChatManager chatManager; private static ChatManager chatManager;
private static CommandManager commandManager; //ACF private static CommandManager commandManager; //ACF
private static TransientEntityTracker transientEntityTracker; private static TransientEntityTracker transientEntityTracker;
// private static ProtocolLibManager protocolLibManager;
private SkillTools skillTools; private SkillTools skillTools;
@ -186,9 +181,6 @@ public class mcMMO extends JavaPlugin {
//Platform Manager //Platform Manager
platformManager = new PlatformManager(); platformManager = new PlatformManager();
//metadata service
metadataService = new MetadataService(this);
MetadataConstants.MCMMO_METADATA_VALUE = new FixedMetadataValue(this, true); MetadataConstants.MCMMO_METADATA_VALUE = new FixedMetadataValue(this, true);
PluginManager pluginManager = getServer().getPluginManager(); PluginManager pluginManager = getServer().getPluginManager();
@ -319,9 +311,6 @@ public class mcMMO extends JavaPlugin {
//Init the blacklist //Init the blacklist
worldBlacklist = new WorldBlacklist(this); worldBlacklist = new WorldBlacklist(this);
//Init smelting tracker
smeltingTracker = new SmeltingTracker();
//Set up Adventure's audiences //Set up Adventure's audiences
audiences = BukkitAudiences.create(this); audiences = BukkitAudiences.create(this);
@ -482,10 +471,6 @@ public class mcMMO extends JavaPlugin {
return platformManager.getCompatibilityManager(); return platformManager.getCompatibilityManager();
} }
public static MetadataService getMetadataService() {
return metadataService;
}
@Deprecated @Deprecated
public static void setDatabaseManager(DatabaseManager databaseManager) { public static void setDatabaseManager(DatabaseManager databaseManager) {
mcMMO.databaseManager = databaseManager; mcMMO.databaseManager = databaseManager;
@ -741,10 +726,6 @@ public class mcMMO extends JavaPlugin {
return platformManager; return platformManager;
} }
public static SmeltingTracker getSmeltingTracker() {
return smeltingTracker;
}
public static BukkitAudiences getAudiences() { public static BukkitAudiences getAudiences() {
return audiences; 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; 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.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.CancellableRunnable; 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.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BrewingStand; import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays; 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 { public class AlchemyBrewCheckTask extends CancellableRunnable {
private final Player player;
private final BrewingStand brewingStand; private final BrewingStand brewingStand;
private final ItemStack[] oldInventory; private final ItemStack[] oldInventory;
public AlchemyBrewCheckTask(Player player, BrewingStand brewingStand) { @Deprecated(forRemoval = true, since = "2.2.010")
this.player = player; public AlchemyBrewCheckTask(@Nullable Player ignored, BrewingStand brewingStand) {
this(brewingStand);
}
public AlchemyBrewCheckTask(@NotNull BrewingStand brewingStand) {
this.brewingStand = brewingStand; this.brewingStand = brewingStand;
this.oldInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4); this.oldInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4);
} }
@Override @Override
public void run() { public void run() {
Location location = brewingStand.getLocation(); OfflinePlayer offlinePlayer = ContainerMetadataUtils.getContainerOwner(brewingStand);
ItemStack[] newInventory = Arrays.copyOfRange(brewingStand.getInventory().getContents(), 0, 4); int ingredientLevel = 1;
boolean validBrew = brewingStand.getFuelLevel() > 0 && AlchemyPotionBrewer.isValidBrew(player, newInventory); 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 (Alchemy.brewingStandMap.containsKey(location)) {
if (oldInventory[Alchemy.INGREDIENT_SLOT] == null if (oldInventory[Alchemy.INGREDIENT_SLOT] == null
@ -36,7 +55,7 @@ public class AlchemyBrewCheckTask extends CancellableRunnable {
Alchemy.brewingStandMap.get(location).cancelBrew(); Alchemy.brewingStandMap.get(location).cancelBrew();
} }
} else if (validBrew) { } 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; 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.events.skills.alchemy.McMMOPlayerBrewEvent; 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.Alchemy;
import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer; import com.gmail.nossr50.skills.alchemy.AlchemyPotionBrewer;
import com.gmail.nossr50.util.CancellableRunnable; import com.gmail.nossr50.util.CancellableRunnable;
import com.gmail.nossr50.util.ContainerMetadataUtils;
import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand; import org.bukkit.block.BrewingStand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public class AlchemyBrewTask extends CancellableRunnable { public class AlchemyBrewTask extends CancellableRunnable {
private static final double DEFAULT_BREW_SPEED = 1.0; private static final double DEFAULT_BREW_SPEED = 1.0;
private static final int DEFAULT_BREW_TICKS = 400; private static final int DEFAULT_BREW_TICKS = 400;
private final BlockState brewingStand; private final BlockState brewingStand;
private final Location location; private final OfflinePlayer offlinePlayer;
private McMMOPlayer mmoPlayer;
private double brewSpeed; private double brewSpeed;
private double brewTimer; private double brewTimer;
private final Player player;
private int fuel; private int fuel;
private boolean firstRun = true; 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.brewingStand = brewingStand;
this.location = brewingStand.getLocation();
this.player = player;
brewSpeed = DEFAULT_BREW_SPEED; brewSpeed = DEFAULT_BREW_SPEED;
brewTimer = DEFAULT_BREW_TICKS; brewTimer = DEFAULT_BREW_TICKS;
if (player != null if (mmoPlayer != null
&& !Misc.isNPCEntityExcludingVillagers(player) && !Misc.isNPCEntityExcludingVillagers(mmoPlayer.getPlayer())
&& Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CATALYSIS) && Permissions.isSubSkillEnabled(mmoPlayer.getPlayer(), SubSkillType.ALCHEMY_CATALYSIS)) {
&& UserManager.getPlayer(player) != null) { 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); mcMMO.p.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
@ -53,8 +66,8 @@ public class AlchemyBrewTask extends CancellableRunnable {
} }
} }
if (Alchemy.brewingStandMap.containsKey(location)) { if (Alchemy.brewingStandMap.containsKey(brewingStand.getLocation())) {
Alchemy.brewingStandMap.get(location).cancel(); Alchemy.brewingStandMap.get(brewingStand.getLocation()).cancel();
} }
fuel = ((BrewingStand) brewingStand).getFuelLevel(); 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. if (((BrewingStand) brewingStand).getBrewingTime() == -1) // Only decrement on our end if it isn't a vanilla ingredient.
fuel--; fuel--;
Alchemy.brewingStandMap.put(location, this); Alchemy.brewingStandMap.put(brewingStand.getLocation(), this);
mcMMO.p.getFoliaLib().getImpl().runAtLocationTimer(location, this, 1, 1); mcMMO.p.getFoliaLib().getImpl().runAtLocationTimer(brewingStand.getLocation(), this, 1, 1);
} }
@Override @Override
public void run() { public void run() {
// Check if preconditions for brewing are not met // Check if preconditions for brewing are not met
if (shouldCancelBrewing()) { if (shouldCancelBrewing()) {
if (Alchemy.brewingStandMap.containsKey(location)) { if (Alchemy.brewingStandMap.containsKey(brewingStand.getLocation())) {
Alchemy.brewingStandMap.remove(location); Alchemy.brewingStandMap.remove(brewingStand.getLocation());
} }
this.cancel(); this.cancel();
return; return;
@ -93,10 +106,7 @@ public class AlchemyBrewTask extends CancellableRunnable {
} }
private boolean shouldCancelBrewing() { private boolean shouldCancelBrewing() {
if (player == null) { if (offlinePlayer == null) {
return true;
}
if (!player.isValid()) {
return true; return true;
} }
if (brewingStand == null) { if (brewingStand == null) {
@ -105,10 +115,24 @@ public class AlchemyBrewTask extends CancellableRunnable {
if (brewingStand.getType() != Material.BREWING_STAND) { if (brewingStand.getType() != Material.BREWING_STAND) {
return true; return true;
} }
if (!AlchemyPotionBrewer.isValidIngredient(player, ((BrewingStand) brewingStand).getInventory().getContents()[Alchemy.INGREDIENT_SLOT])) { return !AlchemyPotionBrewer.isValidIngredientByLevel(
return true; 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() { private void initializeBrewing() {
@ -128,27 +152,27 @@ public class AlchemyBrewTask extends CancellableRunnable {
private void finish() { private void finish() {
McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(player, brewingStand); final McMMOPlayerBrewEvent event = new McMMOPlayerBrewEvent(mmoPlayer, brewingStand);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) { 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() { public void finishImmediately() {
this.cancel(); this.cancel();
AlchemyPotionBrewer.finishBrewing(brewingStand, player, true); AlchemyPotionBrewer.finishBrewing(brewingStand, mmoPlayer.getPlayer(), true);
Alchemy.brewingStandMap.remove(location); Alchemy.brewingStandMap.remove(brewingStand.getLocation());
} }
public void cancelBrew() { public void cancelBrew() {
this.cancel(); this.cancel();
((BrewingStand) brewingStand).setBrewingTime(-1); ((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.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.NotificationManager; 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.random.ProbabilityUtil;
import com.gmail.nossr50.util.skills.ParticleEffectUtils; import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
@ -94,7 +95,7 @@ public class AcrobaticsManager extends SkillManager {
Player player = getPlayer(); Player player = getPlayer();
if (!isFatal(modifiedDamage) if (!isFatal(modifiedDamage)
&& ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_DODGE, player)) { && ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ACROBATICS_DODGE, UserManager.getPlayer(player))) {
ParticleEffectUtils.playDodgeEffect(player); ParticleEffectUtils.playDodgeEffect(player);
if (mmoPlayer.useChatNotifications()) { if (mmoPlayer.useChatNotifications()) {

View File

@ -1,5 +1,6 @@
package com.gmail.nossr50.skills.alchemy; 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.SubSkillType;
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion; import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage; 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.runnables.skills.AlchemyBrewCheckTask;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.BrewingStand; import org.bukkit.block.BrewingStand;
@ -20,14 +20,39 @@ import org.bukkit.inventory.BrewerInventory;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
// TODO: Update to use McMMOPlayer
public final class AlchemyPotionBrewer { public final class AlchemyPotionBrewer {
@Deprecated(forRemoval = true, since = "2.2.010")
public static boolean isValidBrew(Player player, ItemStack[] contents) { 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; return false;
} }
@ -65,7 +90,7 @@ public final class AlchemyPotionBrewer {
ItemStack ingredient = inventory.getIngredient().clone(); ItemStack ingredient = inventory.getIngredient().clone();
if (!isEmpty(ingredient) && isValidIngredient(player, ingredient)) { if (!isEmpty(ingredient) && isValidIngredientByPlayer(player, ingredient)) {
if (ingredient.getAmount() <= 1) { if (ingredient.getAmount() <= 1) {
inventory.setIngredient(null); inventory.setIngredient(null);
} }
@ -79,15 +104,15 @@ public final class AlchemyPotionBrewer {
private static boolean hasIngredient(BrewerInventory inventory, Player player) { private static boolean hasIngredient(BrewerInventory inventory, Player player) {
ItemStack ingredient = inventory.getIngredient() == null ? null : inventory.getIngredient().clone(); 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)) { if (isEmpty(item)) {
return false; return false;
} }
for (ItemStack ingredient : getValidIngredients(player)) { for (ItemStack ingredient : getValidIngredients(UserManager.getPlayer(player))) {
if (item.isSimilar(ingredient)) { if (item.isSimilar(ingredient)) {
return true; return true;
} }
@ -96,12 +121,28 @@ public final class AlchemyPotionBrewer {
return false; return false;
} }
private static List<ItemStack> getValidIngredients(Player player) { public static boolean isValidIngredientByLevel(int ingredientLevel, ItemStack item) {
if(player == null || UserManager.getPlayer(player) == null) { 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(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) { public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
@ -280,8 +321,9 @@ public final class AlchemyPotionBrewer {
return false; return false;
} }
public static void scheduleCheck(Player player, BrewingStand brewingStand) { public static void scheduleCheck(@NotNull BrewingStand brewingStand) {
mcMMO.p.getFoliaLib().getImpl().runAtEntity(player, new AlchemyBrewCheckTask(player, brewingStand)); mcMMO.p.getFoliaLib().getImpl().runAtLocation(
brewingStand.getLocation(), new AlchemyBrewCheckTask(brewingStand));
} }
public static void scheduleUpdate(Inventory inventory) { 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 * @param defender The {@link Player} being affected by the ability
*/ */
public double daze(Player defender) { public double daze(Player defender) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_DAZE, getPlayer())) { if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.ARCHERY_DAZE, mmoPlayer)) {
return 0; return 0;
} }
@ -116,7 +116,7 @@ public class ArcheryManager extends SkillManager {
* @param oldDamage The raw damage value of this arrow before we modify it * @param oldDamage The raw damage value of this arrow before we modify it
*/ */
public double skillShot(double oldDamage) { 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); return Archery.getSkillShotBonusDamage(getPlayer(), oldDamage);
} else { } else {
return oldDamage; return oldDamage;

View File

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

View File

@ -100,7 +100,7 @@ public class CrossbowsManager extends SkillManager {
} }
public double poweredShot(double oldDamage) { 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); return getPoweredShotBonusDamage(getPlayer(), oldDamage);
} else { } else {
return oldDamage; return oldDamage;

View File

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

View File

@ -412,13 +412,13 @@ public class FishingManager extends SkillManager {
enchants.putAll(treasureDrop.getItemMeta().getEnchants()); enchants.putAll(treasureDrop.getItemMeta().getEnchants());
} }
event = EventUtils.callFishingTreasureEvent(player, treasureDrop, treasure.getXp(), enchants); event = EventUtils.callFishingTreasureEvent(mmoPlayer, treasureDrop, treasure.getXp(), enchants);
} else { } else {
if (isMagicHunterEnabled() && ItemUtils.isEnchantable(treasureDrop)) { if (isMagicHunterEnabled() && ItemUtils.isEnchantable(treasureDrop)) {
enchants = processMagicHunter(treasureDrop); enchants = processMagicHunter(treasureDrop);
} }
event = EventUtils.callFishingTreasureEvent(player, treasureDrop, treasure.getXp(), enchants); event = EventUtils.callFishingTreasureEvent(mmoPlayer, treasureDrop, treasure.getXp(), enchants);
} }
if (!event.isCancelled()) { if (!event.isCancelled()) {
@ -480,7 +480,7 @@ public class FishingManager extends SkillManager {
* @param target The {@link LivingEntity} affected by the ability * @param target The {@link LivingEntity} affected by the ability
*/ */
public void shakeCheck(@NotNull LivingEntity target) { 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); List<ShakeTreasure> possibleDrops = Fishing.findPossibleDrops(target);
if (possibleDrops == null || possibleDrops.isEmpty()) { 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.BlockState;
import org.bukkit.block.data.Ageable; import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack; 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.hasItemIncludingOffHand;
import static com.gmail.nossr50.util.ItemUtils.removeItemIncludingOffHand; import static com.gmail.nossr50.util.ItemUtils.removeItemIncludingOffHand;
import static java.util.Objects.requireNonNull;
public class HerbalismManager extends SkillManager { public class HerbalismManager extends SkillManager {
public HerbalismManager(McMMOPlayer mcMMOPlayer) { public HerbalismManager(McMMOPlayer mcMMOPlayer) {
@ -637,12 +637,13 @@ public class HerbalismManager extends SkillManager {
/** /**
* Check for success on herbalism double drops * Check for success on herbalism double drops
*
* @param blockState target block state * @param blockState target block state
* @return true if double drop succeeds * @return true if the double drop succeeds
*/ */
private boolean checkDoubleDrop(BlockState blockState) private boolean checkDoubleDrop(@NotNull BlockState blockState) {
{ requireNonNull(blockState, "BlockState cannot be null");
return BlockUtils.checkDoubleDrops(getPlayer(), blockState, skill, SubSkillType.HERBALISM_DOUBLE_DROPS); 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 * @return true if the ability was successful, false otherwise
*/ */
public boolean processGreenThumbBlocks(BlockState blockState) { 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"); NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.GTh.Fail");
return false; return false;
} }
@ -667,7 +668,7 @@ public class HerbalismManager extends SkillManager {
* @return true if the ability was successful, false otherwise * @return true if the ability was successful, false otherwise
*/ */
public boolean processHylianLuck(BlockState blockState) { public boolean processHylianLuck(BlockState blockState) {
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_HYLIAN_LUCK, getPlayer())) { if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_HYLIAN_LUCK, mmoPlayer)) {
return false; return false;
} }
@ -676,7 +677,6 @@ public class HerbalismManager extends SkillManager {
return false; return false;
List<HylianTreasure> treasures = TreasureConfig.getInstance().hylianMap.get(friendly); List<HylianTreasure> treasures = TreasureConfig.getInstance().hylianMap.get(friendly);
Player player = getPlayer();
if (treasures.isEmpty()) { if (treasures.isEmpty()) {
return false; return false;
@ -686,13 +686,13 @@ public class HerbalismManager extends SkillManager {
for (HylianTreasure treasure : treasures) { for (HylianTreasure treasure : treasures) {
if (skillLevel >= treasure.getDropLevel() if (skillLevel >= treasure.getDropLevel()
&& ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.HERBALISM, player, treasure.getDropChance())) { && ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.HERBALISM, mmoPlayer, treasure.getDropChance())) {
if (!EventUtils.simulateBlockBreak(blockState.getBlock(), player)) { if (!EventUtils.simulateBlockBreak(blockState.getBlock(), mmoPlayer.getPlayer())) {
return false; return false;
} }
blockState.setType(Material.AIR); blockState.setType(Material.AIR);
Misc.spawnItem(getPlayer(), location, treasure.getDrop(), ItemSpawnReason.HYLIAN_LUCK_TREASURE); 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; return true;
} }
} }
@ -706,25 +706,24 @@ public class HerbalismManager extends SkillManager {
* @return true if the ability was successful, false otherwise * @return true if the ability was successful, false otherwise
*/ */
public boolean processShroomThumb(BlockState blockState) { public boolean processShroomThumb(BlockState blockState) {
Player player = getPlayer(); PlayerInventory playerInventory = getPlayer().getInventory();
PlayerInventory playerInventory = player.getInventory();
if (!playerInventory.contains(Material.BROWN_MUSHROOM, 1)) { 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; return false;
} }
if (!playerInventory.contains(Material.RED_MUSHROOM, 1)) { 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; return false;
} }
playerInventory.removeItem(new ItemStack(Material.BROWN_MUSHROOM)); playerInventory.removeItem(new ItemStack(Material.BROWN_MUSHROOM));
playerInventory.removeItem(new ItemStack(Material.RED_MUSHROOM)); playerInventory.removeItem(new ItemStack(Material.RED_MUSHROOM));
player.updateInventory(); getPlayer().updateInventory();
if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_SHROOM_THUMB, player)) { if (!ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_SHROOM_THUMB, mmoPlayer)) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.ShroomThumb.Fail"); NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE_FAILED, "Herbalism.Ability.ShroomThumb.Fail");
return false; return false;
} }
@ -789,7 +788,7 @@ public class HerbalismManager extends SkillManager {
return false; return false;
} }
if (!greenTerra && !ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, player)) { if (!greenTerra && !ProbabilityUtil.isSkillRNGSuccessful(SubSkillType.HERBALISM_GREEN_THUMB, mmoPlayer)) {
return false; 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.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
public class MacesManager extends SkillManager { public class MacesManager extends SkillManager {
public MacesManager(McMMOPlayer mmoPlayer) { public MacesManager(McMMOPlayer mmoPlayer) {

View File

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

View File

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

View File

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

View File

@ -24,7 +24,7 @@ public class SmeltingManager extends SkillManager {
public boolean isSecondSmeltSuccessful() { public boolean isSecondSmeltSuccessful() {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SMELTING_SECOND_SMELT) 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()); 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) { if (target instanceof Player defender) {
@ -142,7 +142,7 @@ public class SwordsManager extends SkillManager {
*/ */
public void counterAttackChecks(@NotNull LivingEntity attacker, double damage) { 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()); CombatUtils.dealDamage(attacker, damage / Swords.counterAttackModifier, getPlayer());
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Swords.Combat.Countered"); 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 java.util.HashMap;
import static com.gmail.nossr50.util.MobMetadataUtils.flagMetadata;
public class TamingManager extends SkillManager { public class TamingManager extends SkillManager {
//TODO: Temporary static cache, will be changed in 2.2 //TODO: Temporary static cache, will be changed in 2.2
private static HashMap<Material, CallOfTheWildType> summoningItems; private static HashMap<Material, CallOfTheWildType> summoningItems;
@ -143,7 +145,7 @@ public class TamingManager extends SkillManager {
* @param damage The damage being absorbed by the wolf * @param damage The damage being absorbed by the wolf
*/ */
public void fastFoodService(@NotNull Wolf wolf, double damage) { 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; return;
} }
@ -262,7 +264,7 @@ public class TamingManager extends SkillManager {
if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_PUMMEL)) if(!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_PUMMEL))
return; return;
if(!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.TAMING, getPlayer(), mcMMO.p.getAdvancedConfig().getPummelChance())) if(!ProbabilityUtil.isStaticSkillRNGSuccessful(PrimarySkillType.TAMING, mmoPlayer, mcMMO.p.getAdvancedConfig().getPummelChance()))
return; return;
ParticleEffectUtils.playGreaterImpactEffect(target); ParticleEffectUtils.playGreaterImpactEffect(target);
@ -459,7 +461,7 @@ public class TamingManager extends SkillManager {
private void applyMetaDataToCOTWEntity(LivingEntity summonedEntity) { private void applyMetaDataToCOTWEntity(LivingEntity summonedEntity) {
//This helps identify the entity as being summoned by COTW //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.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.skills.SkillManager; import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
public class TridentsManager extends SkillManager { public class TridentsManager extends SkillManager {

View File

@ -67,7 +67,7 @@ public class UnarmedManager extends SkillManager {
} }
public boolean blockCrackerCheck(@NotNull BlockState blockState) { public boolean blockCrackerCheck(@NotNull BlockState blockState) {
if (!ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_BLOCK_CRACKER, getPlayer())) { if (!ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_BLOCK_CRACKER, mmoPlayer)) {
return false; return false;
} }
@ -98,7 +98,7 @@ public class UnarmedManager extends SkillManager {
* @param defender The defending player * @param defender The defending player
*/ */
public void disarmCheck(@NotNull Player defender) { 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()) { if (EventUtils.callDisarmEvent(defender).isCancelled()) {
return; return;
} }
@ -121,7 +121,7 @@ public class UnarmedManager extends SkillManager {
* Check for arrow deflection. * Check for arrow deflection.
*/ */
public boolean deflectCheck() { 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"); NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Combat.ArrowDeflect");
return true; return true;
} }
@ -144,7 +144,7 @@ public class UnarmedManager extends SkillManager {
* Handle the effects of the Iron Arm ability * Handle the effects of the Iron Arm ability
*/ */
public double calculateSteelArmStyleDamage() { public double calculateSteelArmStyleDamage() {
if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_STEEL_ARM_STYLE, getPlayer())) { if (ProbabilityUtil.isNonRNGSkillActivationSuccessful(SubSkillType.UNARMED_STEEL_ARM_STYLE, mmoPlayer)) {
return getSteelArmStyleDamage(); return getSteelArmStyleDamage();
} }
@ -178,7 +178,7 @@ public class UnarmedManager extends SkillManager {
private boolean hasIronGrip(@NotNull Player defender) { private boolean hasIronGrip(@NotNull Player defender) {
if (!Misc.isNPCEntityExcludingVillagers(defender) if (!Misc.isNPCEntityExcludingVillagers(defender)
&& Permissions.isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP) && 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(defender, NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Defender");
NotificationManager.sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Attacker"); 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) { private boolean checkHarvestLumberActivation(Material material) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER) return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, 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); && mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
} }
private boolean checkCleanCutsActivation(Material material) { private boolean checkCleanCutsActivation(Material material) {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER) return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, 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); && 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.hasUnlockedSubskill(player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
if(RankUtils.hasReachedRank(2, player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) { if(RankUtils.hasReachedRank(2, player, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
if(mcMMO.p.getAdvancedConfig().isKnockOnWoodXPOrbEnabled()) { 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)); int randOrbCount = Math.max(1, Misc.getRandom().nextInt(100));
Misc.spawnExperienceOrb(blockState.getLocation(), randOrbCount); 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.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.meta.BonusDropMeta; 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.Repair; import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.salvage.Salvage; import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.random.ProbabilityUtil; import com.gmail.nossr50.util.random.ProbabilityUtil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -16,9 +18,12 @@ import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet; import java.util.HashSet;
import static java.util.Objects.requireNonNull;
public final class BlockUtils { public final class BlockUtils {
public static final String SHORT_GRASS = "SHORT_GRASS"; public static final String SHORT_GRASS = "SHORT_GRASS";
@ -94,10 +99,28 @@ public final class BlockUtils {
* *
* @param blockState the blockstate * @param blockState the blockstate
* @return true if the player succeeded in the check * @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) { @Deprecated(forRemoval = true, since = "2.2.010")
if (mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(skillType, blockState.getType()) && Permissions.isSubSkillEnabled(player, subSkillType)) { public static boolean checkDoubleDrops(Player player, BlockState blockState, PrimarySkillType ignored, SubSkillType subSkillType) {
return ProbabilityUtil.isSkillRNGSuccessful(subSkillType, player); 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; 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.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType; import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType; 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.McMMOPlayerLevelChangeEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelDownEvent; import com.gmail.nossr50.events.experience.McMMOPlayerLevelDownEvent;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent; import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
@ -59,6 +58,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import static java.util.Objects.requireNonNull;
/** /**
* This class is meant to help make event related code less boilerplate * This class is meant to help make event related code less boilerplate
*/ */
@ -163,8 +164,17 @@ public final class EventUtils {
* Others * Others
*/ */
public static @NotNull McMMOPlayerAbilityActivateEvent callPlayerAbilityActivateEvent(@NotNull Player player, @NotNull PrimarySkillType skill) { @Deprecated(forRemoval = true, since = "2.2.010")
McMMOPlayerAbilityActivateEvent event = new McMMOPlayerAbilityActivateEvent(player, skill); 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); mcMMO.p.getServer().getPluginManager().callEvent(event);
return event; return event;
@ -183,8 +193,21 @@ public final class EventUtils {
* @param subSkillType target subskill * @param subSkillType target subskill
* @return the event after it has been fired * @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) { 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); mcMMO.p.getServer().getPluginManager().callEvent(event);
return event; return event;
@ -204,26 +227,6 @@ public final class EventUtils {
return event; 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) { 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); McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event); mcMMO.p.getServer().getPluginManager().callEvent(event);
@ -497,15 +500,25 @@ public final class EventUtils {
return !isCancelled; return !isCancelled;
} }
@Deprecated(forRemoval = true, since = "2.2.010")
public static McMMOPlayerAbilityDeactivateEvent callAbilityDeactivateEvent(Player player, SuperAbilityType ability) { 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); mcMMO.p.getServer().getPluginManager().callEvent(event);
return event; return event;
} }
@Deprecated(forRemoval = true, since = "2.2.010")
public static McMMOPlayerFishingTreasureEvent callFishingTreasureEvent(Player player, ItemStack treasureDrop, int treasureXp, Map<Enchantment, Integer> enchants) { 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); mcMMO.p.getServer().getPluginManager().callEvent(event);
return 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 com.gmail.nossr50.mcMMO;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -9,18 +9,17 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; 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 static final @NotNull String LEGACY_ABILITY_TOOL_LORE = "mcMMO Ability Tool";
public final @NotNull mcMMO pluginRef;
public ItemMetadataService(@NotNull mcMMO pluginRef) { private ItemMetadataUtils() {
this.pluginRef = pluginRef; // private ctor
} }
public void setSuperAbilityBoostedItem(@NotNull ItemStack itemStack, int originalDigSpeed) { public static void setSuperAbilityBoostedItem(@NotNull ItemStack itemStack, int originalDigSpeed) {
if (itemStack.getItemMeta() == null) { if (itemStack.getItemMeta() == null) {
mcMMO.p.getLogger().severe("Can not assign persistent data to an item with null item metadata"); mcMMO.p.getLogger().severe("Can not assign persistent data to an item with null item metadata");
return; return;
@ -34,7 +33,7 @@ public class ItemMetadataService {
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
} }
public boolean isSuperAbilityBoosted(@NotNull ItemStack itemStack) { public static boolean isSuperAbilityBoosted(@NotNull ItemStack itemStack) {
if (itemStack.getItemMeta() == null) if (itemStack.getItemMeta() == null)
return false; return false;
@ -48,7 +47,7 @@ public class ItemMetadataService {
return boostValue != null; return boostValue != null;
} }
public int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemStack itemStack) { public static int getSuperAbilityToolOriginalDigSpeed(@NotNull ItemStack itemStack) {
//Get container from entity //Get container from entity
ItemMeta itemMeta = itemStack.getItemMeta(); 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); int originalSpeed = getSuperAbilityToolOriginalDigSpeed(itemStack);
ItemMeta itemMeta = itemStack.getItemMeta(); 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(); ItemMeta itemMeta = itemStack.getItemMeta();
if (itemMeta == null) if (itemMeta == null)
@ -102,8 +101,4 @@ public class ItemMetadataService {
return lore.contains(LEGACY_ABILITY_TOOL_LORE); 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_DISARMED_ITEM = "mcMMO: Disarmed Item";
public static final @NotNull String METADATA_KEY_PLAYER_DATA = "mcMMO: Player Data"; 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_DATABASE_COMMAND = "mcMMO: Processing Database Command";
public static final @NotNull String METADATA_KEY_FURNACE_UUID_MOST_SIG = "furnace_uuid_most_sig"; // the value of these two keys have "furnace" to keep supporting legacy data
public static final @NotNull String METADATA_KEY_FURNACE_UUID_LEAST_SIG = "furnace_uuid_least_sig"; 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_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_MOB_SPAWNER_MOB = "mcmmo_mob_spawner_mob";
public static final @NotNull String METADATA_KEY_EGG_MOB = "mcmmo_egg_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.api.exceptions.IncompleteNamespacedKeyRegister;
import com.gmail.nossr50.config.PersistentDataConfig; import com.gmail.nossr50.config.PersistentDataConfig;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.metadata.MobMetaFlagType;
import com.gmail.nossr50.util.MetadataConstants;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
@ -15,17 +14,19 @@ import java.util.EnumMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.WeakHashMap; 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 //TODO: Use SpawnReason where appropriate instead of MobMetaFlagType
public class MobMetadataService { public final class MobMetadataUtils {
private final @NotNull WeakHashMap<Entity, HashSet<MobMetaFlagType>> mobRegistry; //transient data private static final @NotNull WeakHashMap<Entity, HashSet<MobMetaFlagType>> mobRegistry; //transient data
private final @NotNull EnumMap<MobMetaFlagType, NamespacedKey> mobFlagKeyMap; //used for persistent data private static final @NotNull EnumMap<MobMetaFlagType, NamespacedKey> mobFlagKeyMap; //used for persistent data
private final @NotNull mcMMO pluginRef; private static boolean isUsingPersistentData = false;
private boolean isUsingPersistentData = false;
public MobMetadataService(@NotNull mcMMO pluginRef) { private MobMetadataUtils() {
this.pluginRef = pluginRef; // private ctor
}
static {
mobFlagKeyMap = new EnumMap<>(MobMetaFlagType.class); mobFlagKeyMap = new EnumMap<>(MobMetaFlagType.class);
mobRegistry = new WeakHashMap<>(); mobRegistry = new WeakHashMap<>();
initMobFlagKeyMap(); initMobFlagKeyMap();
@ -40,7 +41,7 @@ public class MobMetadataService {
* Registers the namespaced keys required by the API (CB/Spigot) * Registers the namespaced keys required by the API (CB/Spigot)
* Used primarily for persistent data * Used primarily for persistent data
*/ */
private void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister { private static void initMobFlagKeyMap() throws IncompleteNamespacedKeyRegister {
for (MobMetaFlagType mobMetaFlagType : MobMetaFlagType.values()) { for (MobMetaFlagType mobMetaFlagType : MobMetaFlagType.values()) {
switch (mobMetaFlagType) { switch (mobMetaFlagType) {
case MOB_SPAWNER_MOB -> mobFlagKeyMap.put(mobMetaFlagType, NSK_MOB_SPAWNER_MOB); 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} * @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)) { if (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
return livingEntity.getPersistentDataContainer().has(mobFlagKeyMap.get(flag), PersistentDataType.BYTE); return livingEntity.getPersistentDataContainer().has(mobFlagKeyMap.get(flag), PersistentDataType.BYTE);
} else { } else {
@ -82,7 +83,7 @@ public class MobMetadataService {
* *
* @return true if the mob has any mcMMO mob related metadata values * @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) { if (isUsingPersistentData) {
for (MobMetaFlagType metaFlagType : MobMetaFlagType.values()) { for (MobMetaFlagType metaFlagType : MobMetaFlagType.values()) {
if (hasMobFlag(metaFlagType, livingEntity)) if (hasMobFlag(metaFlagType, livingEntity))
@ -102,7 +103,7 @@ public class MobMetadataService {
* @param sourceEntity entity to copy from * @param sourceEntity entity to copy from
* @param targetEntity entity to copy to * @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)) if (!hasMobFlags(sourceEntity))
return; return;
@ -125,7 +126,7 @@ public class MobMetadataService {
* @param flag the desired flag to assign * @param flag the desired flag to assign
* @param livingEntity the target living entity * @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 (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
if (!hasMobFlag(flag, livingEntity)) { if (!hasMobFlag(flag, livingEntity)) {
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer(); PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
@ -144,7 +145,7 @@ public class MobMetadataService {
* @param flag desired flag to remove * @param flag desired flag to remove
* @param livingEntity the target living entity * @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 (PersistentDataConfig.getInstance().isMobPersistent(flag)) {
if (hasMobFlag(flag, livingEntity)) { if (hasMobFlag(flag, livingEntity)) {
PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer(); PersistentDataContainer persistentDataContainer = livingEntity.getPersistentDataContainer();
@ -165,7 +166,7 @@ public class MobMetadataService {
* *
* @param livingEntity target entity * @param livingEntity target entity
*/ */
public void removeMobFlags(@NotNull LivingEntity livingEntity) { public static void removeMobFlags(@NotNull LivingEntity livingEntity) {
if (isUsingPersistentData) { if (isUsingPersistentData) {
for (MobMetaFlagType flag : MobMetaFlagType.values()) { for (MobMetaFlagType flag : MobMetaFlagType.values()) {
removeMobFlag(flag, livingEntity); removeMobFlag(flag, livingEntity);

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.util; package com.gmail.nossr50.util;
import com.gmail.nossr50.commands.party.PartySubcommandType; 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.ItemType;
import com.gmail.nossr50.datatypes.skills.MaterialType; import com.gmail.nossr50.datatypes.skills.MaterialType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@ -17,6 +18,7 @@ import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault; import org.bukkit.permissions.PermissionDefault;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale; 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 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()); 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 */ /* ACROBATICS */
public static boolean dodge(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.dodge"); } 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"); } 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 java.util.*;
import static com.gmail.nossr50.util.MobMetadataUtils.removeMobFlags;
public class TransientEntityTracker { public class TransientEntityTracker {
//These two are updated in step with each other //These two are updated in step with each other
private final @NotNull HashMap<UUID, HashMap<CallOfTheWildType, HashSet<TrackedTamingEntity>>> perPlayerTransientEntityMap; private final @NotNull HashMap<UUID, HashMap<CallOfTheWildType, HashSet<TrackedTamingEntity>>> perPlayerTransientEntityMap;
@ -273,7 +275,7 @@ public class TransientEntityTracker {
} }
//Remove our metadata //Remove our metadata
mcMMO.getMetadataService().getMobMetadataService().removeMobFlags(livingEntity); removeMobFlags(livingEntity);
//Clean from trackers //Clean from trackers
unregisterEntity(livingEntity); unregisterEntity(livingEntity);

View File

@ -4,6 +4,8 @@ import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import static com.gmail.nossr50.util.MobMetadataUtils.removeMobFlags;
public class TransientMetadataTools { public class TransientMetadataTools {
private final mcMMO pluginRef; private final mcMMO pluginRef;
@ -30,7 +32,7 @@ public class TransientMetadataTools {
} }
//Cleanup mob metadata //Cleanup mob metadata
mcMMO.getMetadataService().getMobMetadataService().removeMobFlags(entity); removeMobFlags(entity);
//TODO: This loop has some redundancy, this whole method needs to be rewritten //TODO: This loop has some redundancy, this whole method needs to be rewritten
for(String key : MetadataConstants.MOB_METADATA_KEYS) { 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.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import static java.util.Objects.requireNonNull;
public class ProbabilityUtil { public class ProbabilityUtil {
public static final @NotNull DecimalFormat percent = new DecimalFormat("##0.00%"); public static final @NotNull DecimalFormat percent = new DecimalFormat("##0.00%");
public static final double LUCKY_MODIFIER = 1.333D; 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 player target player
* @param subSkillType target subskill * @param subSkillType target subskill
* @param isLucky whether to apply luck modifiers * @param isLucky whether to apply luck modifiers
* *
* @return "percentage" representation of success * @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, @NotNull SubSkillType subSkillType,
boolean isLucky) { 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 //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 double percentageValue = probability.getValue(); //Doesn't need to be scaled
@ -42,6 +53,13 @@ public class ProbabilityUtil {
return percentageValue; 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) { 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 //Probability values are on a 0-1 scale and need to be "transformed" into a 1-100 scale
double percentageValue = probability.getValue(); double percentageValue = probability.getValue();
@ -54,6 +72,7 @@ public class ProbabilityUtil {
return percentageValue; return percentageValue;
} }
@VisibleForTesting
static Probability getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance { static Probability getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance {
return switch (subSkillType) { return switch (subSkillType) {
case AXES_ARMOR_IMPACT -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getImpactChance()); case AXES_ARMOR_IMPACT -> Probability.ofPercent(mcMMO.p.getAdvancedConfig().getImpactChance());
@ -74,19 +93,20 @@ public class ProbabilityUtil {
return skillProbabilityType; return skillProbabilityType;
} }
static @NotNull Probability ofSubSkill(@Nullable Player player, @Deprecated(forRemoval = true, since = "2.2.010")
@NotNull SubSkillType subSkillType) { 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)) { switch (getProbabilityType(subSkillType)) {
case DYNAMIC_CONFIGURABLE: case DYNAMIC_CONFIGURABLE:
double probabilityCeiling; double probabilityCeiling;
double skillLevel; double skillLevel;
double maxBonusLevel; // If a skill level is equal to the cap, it has the full probability double maxBonusLevel; // If a skill level is equal to the cap, it has the full probability
if (player != null) { if (mmoPlayer != null) {
McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
if (mmoPlayer == null) {
return Probability.ofPercent(0);
}
skillLevel = mmoPlayer.getSkillLevel(subSkillType.getParentSkill()); skillLevel = mmoPlayer.getSkillLevel(subSkillType.getParentSkill());
} else { } else {
skillLevel = 0; skillLevel = 0;
@ -101,10 +121,10 @@ public class ProbabilityUtil {
try { try {
return getStaticRandomChance(subSkillType); return getStaticRandomChance(subSkillType);
} catch (InvalidStaticChance invalidStaticChance) { } catch (InvalidStaticChance invalidStaticChance) {
invalidStaticChance.printStackTrace(); throw new RuntimeException(invalidStaticChance);
} }
default: 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 * The outcome of the probability can also be modified by this event that is called
* *
* @param subSkillType target subskill * @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 * @return true if the Skill RNG succeeds, false if it fails
*/ */
public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @NotNull Player player) { public static boolean isSkillRNGSuccessful(@NotNull SubSkillType subSkillType, @Nullable McMMOPlayer mmoPlayer) {
final Probability probability = getSkillProbability(subSkillType, player); final Probability probability = getSkillProbability(subSkillType, mmoPlayer);
//Luck //Luck
boolean isLucky = Permissions.lucky(player, subSkillType.getParentSkill()); boolean isLucky = mmoPlayer != null && Permissions.lucky(mmoPlayer.getPlayer(), subSkillType.getParentSkill());
if(isLucky) { if(isLucky) {
return probability.evaluate(LUCKY_MODIFIER); return probability.evaluate(LUCKY_MODIFIER);
@ -143,28 +192,49 @@ public class ProbabilityUtil {
* Returns the {@link Probability} for a specific {@link SubSkillType} for a specific {@link 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 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. * 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 subSkillType the target subskill
* @param player the target player * @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 * @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 // Process probability
Probability probability = getSubSkillProbability(subSkillType, player); Probability probability = getSubSkillProbability(subSkillType, mmoPlayer);
//Send out event // Send out event
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(player, subSkillType); if (mmoPlayer != null) {
SubSkillEvent subSkillEvent = EventUtils.callSubSkillEvent(mmoPlayer, subSkillType);
if(subSkillEvent.isCancelled()) { if(subSkillEvent.isCancelled()) {
return Probability.ALWAYS_FAILS; return Probability.ALWAYS_FAILS;
} }
//Result modifier // Result modifier
double resultModifier = subSkillEvent.getResultModifier(); double resultModifier = subSkillEvent.getResultModifier();
//Mutate probability // Mutate probability
if(resultModifier != 1.0D) if(resultModifier != 1.0D)
probability = Probability.ofPercent(probability.getValue() * resultModifier); probability = Probability.ofPercent(probability.getValue() * resultModifier);
}
return probability; return probability;
} }
@ -177,12 +247,11 @@ public class ProbabilityUtil {
* @param player the target player can be null (null players have the worst odds) * @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) * @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
* @return true if the RNG succeeds, false if it fails * @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) { public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType, @Nullable Player player, double probabilityPercentage) {
//Grab a probability converted from a "percentage" value return isStaticSkillRNGSuccessful(primarySkillType, player, Probability.ofPercent(probabilityPercentage));
Probability probability = Probability.ofPercent(probabilityPercentage);
return isStaticSkillRNGSuccessful(primarySkillType, player, probability);
} }
/** /**
@ -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 * 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 primarySkillType the related primary skill
* @param player the target player, can be null (null players have the worst odds) * @param mmoPlayer the target player can be null (null players have the worst odds)
* @param probability the probability of this player succeeding * @param probabilityPercentage the probability of this player succeeding in "percentage" format (0-100 inclusive)
* @return true if the RNG succeeds, false if it fails * @return true if the RNG succeeds, false if it fails
*/ */
public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType, @Nullable Player player, @NotNull Probability probability) { public static boolean isStaticSkillRNGSuccessful(@NotNull PrimarySkillType primarySkillType,
boolean isLucky = player != null && Permissions.lucky(player, 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) { if(isLucky) {
return probability.evaluate(LUCKY_MODIFIER); return probability.evaluate(LUCKY_MODIFIER);
@ -209,25 +315,57 @@ public class ProbabilityUtil {
* @param subSkillType target subskill * @param subSkillType target subskill
* @param player target player * @param player target player
* @return true if the skill succeeds (wasn't cancelled by any other plugin) * @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) { 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 subSkillType target subskill
* @param player target player * @param mmoPlayer target player
* @return the Probability of this skill succeeding * @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); return ProbabilityUtil.ofSubSkill(player, subSkillType);
} }
public static @NotNull String[] getRNGDisplayValues(@NotNull Player player, @NotNull SubSkillType subSkill) { /**
double firstValue = chanceOfSuccessPercentage(player, subSkill, false); * Retrieves the {@link Probability} of success for a specified {@link SubSkillType} for a given {@link Player}.
double secondValue = chanceOfSuccessPercentage(player, subSkill, true); *
* @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)}; 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.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.metadata.MobMetaFlagType; import com.gmail.nossr50.metadata.MobMetaFlagType;
import com.gmail.nossr50.metadata.MobMetadataService;
import com.gmail.nossr50.runnables.skills.AwardCombatXpTask; import com.gmail.nossr50.runnables.skills.AwardCombatXpTask;
import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager; import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
import com.gmail.nossr50.skills.archery.ArcheryManager; import com.gmail.nossr50.skills.archery.ArcheryManager;
@ -37,14 +36,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import static com.gmail.nossr50.util.MobMetadataUtils.hasMobFlag;
public final class CombatUtils { public final class CombatUtils {
private CombatUtils() {} private CombatUtils() {}
private static @NotNull MobMetadataService getMobMetadataService() {
return mcMMO.getMetadataService().getMobMetadataService();
}
public static boolean isDamageLikelyFromNormalCombat(@NotNull DamageCause damageCause) { public static boolean isDamageLikelyFromNormalCombat(@NotNull DamageCause damageCause) {
return switch (damageCause) { return switch (damageCause) {
case ENTITY_ATTACK, ENTITY_SWEEP_ATTACK, PROJECTILE -> true; 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; 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(); 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(); baseXP *= ExperienceConfig.getInstance().getNetherPortalXpMultiplier();
} else if(getMobMetadataService().hasMobFlag(MobMetaFlagType.EGG_MOB, target)) { } else if(hasMobFlag(MobMetaFlagType.EGG_MOB, target)) {
baseXP *= ExperienceConfig.getInstance().getEggXpMultiplier(); 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(); 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(); baseXP *= ExperienceConfig.getInstance().getTamedMobXpMultiplier();
} }

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.util.skills; package com.gmail.nossr50.util.skills;
import com.gmail.nossr50.config.experience.ExperienceConfig; 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.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.skills.SkillActivationPerkEvent; import com.gmail.nossr50.events.skills.SkillActivationPerkEvent;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
@ -106,4 +107,19 @@ public final class PerksUtils {
return NORMAL_SKILL_ACTIVATION_CHANCE; 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.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; 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.ItemUtils;
import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions; import com.gmail.nossr50.util.Permissions;
@ -32,6 +32,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Iterator; import java.util.Iterator;
import static com.gmail.nossr50.util.ItemMetadataUtils.*;
import static com.gmail.nossr50.util.PotionEffectMapper.getHaste; import static com.gmail.nossr50.util.PotionEffectMapper.getHaste;
public final class SkillUtils { public final class SkillUtils {
@ -152,7 +153,7 @@ public final class SkillUtils {
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency())); ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency()));
//1.13.2+ will have persistent metadata for this item //1.13.2+ will have persistent metadata for this item
mcMMO.getMetadataService().getItemMetadataService().setSuperAbilityBoostedItem(heldItem, originalDigSpeed); ItemMetadataUtils.setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
} else { } else {
int duration = 0; int duration = 0;
int amplifier = 0; int amplifier = 0;
@ -209,9 +210,7 @@ public final class SkillUtils {
//1.13.2+ will have persistent metadata for this itemStack //1.13.2+ will have persistent metadata for this itemStack
ItemMetadataService itemMetadataService = mcMMO.getMetadataService().getItemMetadataService(); if(isLegacyAbilityTool(itemStack)) {
if(itemMetadataService.isLegacyAbilityTool(itemStack)) {
ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta itemMeta = itemStack.getItemMeta();
if(itemMeta != null) { if(itemMeta != null) {
@ -223,8 +222,8 @@ public final class SkillUtils {
} }
} }
if(itemMetadataService.isSuperAbilityBoosted(itemStack)) { if(isSuperAbilityBoosted(itemStack)) {
itemMetadataService.removeBonusDigSpeedOnSuperAbilityTool(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.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions; 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.skills.RankUtils;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -345,7 +346,8 @@ public class TextComponentFactory {
componentBuilder.append(Component.newline()); componentBuilder.append(Component.newline());
//Finally, add details to the tooltip //Finally, add details to the tooltip
abstractSubSkill.addStats(componentBuilder, player); // TODO: pass in McMMOPlayer instead
abstractSubSkill.addStats(componentBuilder, UserManager.getPlayer(player));
} }
return componentBuilder.build(); return componentBuilder.build();

View File

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

View File

@ -62,7 +62,8 @@ class ProbabilityUtilTest extends MMOTestEnvironment {
when(advancedConfig.getMaximumProbability(UNARMED_ARROW_DEFLECT)).thenReturn(20D); when(advancedConfig.getMaximumProbability(UNARMED_ARROW_DEFLECT)).thenReturn(20D);
when(advancedConfig.getMaxBonusLevel(UNARMED_ARROW_DEFLECT)).thenReturn(0); 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()); assertEquals(0.2D, probability.getValue());
assertProbabilityExpectations(20, probability); assertProbabilityExpectations(20, probability);
} }