getSkillAbilities() {
+ return new ArrayList<>(mcMMO.p.getSkillTools().getSubSkills(this));
+ }
+
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#getXpModifier(com.gmail.nossr50.datatypes.skills.PrimarySkillType)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
+ public double getXpModifier() {
+ return mcMMO.p.getSkillTools().getXpModifier(this);
+ }
+
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#matchSkill(java.lang.String)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
+ public static PrimarySkillType getSkill(String skillName) {
+ return mcMMO.p.getSkillTools().matchSkill(skillName);
+ }
+
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#isChildSkill(com.gmail.nossr50.datatypes.skills.PrimarySkillType)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
public boolean isChildSkill() {
- switch (this) {
- case SALVAGE:
- case SMELTING:
- return true;
-
- default:
- return false;
- }
+ return SkillTools.isChildSkill(this);
}
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#getPrimarySkillBySubSkill(com.gmail.nossr50.datatypes.skills.SubSkillType)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
public static PrimarySkillType bySecondaryAbility(SubSkillType subSkillType) {
- for (PrimarySkillType type : values()) {
- if (type.getSkillAbilities().contains(subSkillType)) {
- return type;
- }
- }
- return null;
+ return mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType);
}
- public static PrimarySkillType byAbility(SuperAbilityType ability) {
- for (PrimarySkillType type : values()) {
- if (type.getSuperAbilityType() == ability) {
- return type;
- }
- }
-
- return null;
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#getPrimarySkillBySuperAbility(com.gmail.nossr50.datatypes.skills.SuperAbilityType)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
+ public static PrimarySkillType byAbility(SuperAbilityType superAbilityType) {
+ return mcMMO.p.getSkillTools().getPrimarySkillBySuperAbility(superAbilityType);
}
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#getLocalizedSkillName(com.gmail.nossr50.datatypes.skills.PrimarySkillType)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
public String getName() {
- return StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(this.toString()) + ".SkillName"));
+ return mcMMO.p.getSkillTools().getLocalizedSkillName(this);
}
-// public String getName() {
-// return StringUtils.getCapitalized(StringUtils.getCapitalized(this.toString()));
-// }
-
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see Permissions#skillEnabled(org.bukkit.permissions.Permissible, com.gmail.nossr50.datatypes.skills.PrimarySkillType)
+ * @deprecated this is being removed in an upcoming update
+ */
+ @Deprecated
public boolean getPermissions(Player player) {
- return Permissions.skillEnabled(player, this);
+ return mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, this);
}
-/* public void celebrateLevelUp(Player player) {
- ParticleEffectUtils.fireworkParticleShower(player, skillColor);
- }*/
-
+ /**
+ * WARNING: Being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ * @return the max level of this skill
+ * @see SkillTools#canCombatSkillsTrigger(com.gmail.nossr50.datatypes.skills.PrimarySkillType, org.bukkit.entity.Entity)
+ * @deprecated this is being removed in an upcoming update, you should be using mcMMO.getSkillTools() instead
+ */
+ @Deprecated
public boolean shouldProcess(Entity target) {
- return (target instanceof Player || (target instanceof Tameable && ((Tameable) target).isTamed())) ? getPVPEnabled() : getPVEEnabled();
+ return mcMMO.p.getSkillTools().canCombatSkillsTrigger(this, target);
}
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java
index 480f8368b..f9fa5af3b 100644
--- a/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java
+++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java
@@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.skills;
import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.text.StringUtils;
import java.util.Locale;
@@ -145,7 +146,7 @@ public enum SubSkillType {
* If we add skills, those immutable lists need to be updated
* @return
*/
- public PrimarySkillType getParentSkill() { return PrimarySkillType.bySecondaryAbility(this); }
+ public PrimarySkillType getParentSkill() { return mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(this); }
/**
* Returns the root address for this skill in the advanced.yml file
diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java b/src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java
index 17755188b..7ce32a8f7 100644
--- a/src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java
+++ b/src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.datatypes.skills;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.BlockUtils;
@@ -137,11 +136,11 @@ public enum SuperAbilityType {
}
public int getCooldown() {
- return Config.getInstance().getCooldown(this);
+ return mcMMO.p.getSkillTools().getSuperAbilityCooldown(this);
}
public int getMaxLength() {
- return Config.getInstance().getMaxLength(this);
+ return mcMMO.p.getGeneralConfig().getMaxLength(this);
}
public String getAbilityOn() {
diff --git a/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java b/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java
index 4b5f77c1a..68479909d 100644
--- a/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java
+++ b/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -83,7 +82,7 @@ public class Roll extends AcrobaticsSubSkill {
entityDamageEvent.setCancelled(true);
return true;
}
- } else if(Permissions.skillEnabled(player, PrimarySkillType.ACROBATICS)) {
+ } else if(mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.ACROBATICS)) {
//Give XP Anyways
SkillUtils.applyXpGain(mcMMOPlayer, getPrimarySkill(), calculateRollXP(player, ((EntityDamageEvent) event).getFinalDamage(), false), XPGainReason.PVE);
}
@@ -199,7 +198,7 @@ public class Roll extends AcrobaticsSubSkill {
return gracefulRollCheck(player, mmoPlayer, damage, skillLevel);
}
- double modifiedDamage = calculateModifiedRollDamage(damage, AdvancedConfig.getInstance().getRollDamageThreshold());
+ double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold());
if (!isFatal(player, modifiedDamage)
&& RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.ACROBATICS_ROLL, player)) {
@@ -237,7 +236,7 @@ public class Roll extends AcrobaticsSubSkill {
* @return the modified event damage if the ability was successful, the original event damage otherwise
*/
private double gracefulRollCheck(Player player, OnlineMMOPlayer mmoPlayer, double damage, int skillLevel) {
- double modifiedDamage = calculateModifiedRollDamage(damage, AdvancedConfig.getInstance().getRollDamageThreshold() * 2);
+ double modifiedDamage = calculateModifiedRollDamage(damage, mcMMO.p.getAdvancedConfig().getRollDamageThreshold() * 2);
RandomChanceSkill rcs = new RandomChanceSkill(player, subSkillType);
rcs.setSkillLevel(rcs.getSkillLevel() * 2); //Double the effective odds
@@ -380,7 +379,7 @@ public class Roll extends AcrobaticsSubSkill {
//
// //Chance to roll at half max skill
// RandomChanceSkill rollHalfMaxSkill = new RandomChanceSkill(null, subSkillType);
-// int halfMaxSkillValue = AdvancedConfig.getInstance().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL)/2;
+// int halfMaxSkillValue = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL)/2;
// rollHalfMaxSkill.setSkillLevel(halfMaxSkillValue);
//
// //Chance to graceful roll at full skill
@@ -394,11 +393,11 @@ public class Roll extends AcrobaticsSubSkill {
// //Chance Stat Calculations
// rollChanceHalfMax = RandomChanceUtil.getRandomChanceExecutionChance(rollHalfMaxSkill);
// graceChanceHalfMax = RandomChanceUtil.getRandomChanceExecutionChance(rollGraceHalfMaxSkill);
-// damageThreshold = AdvancedConfig.getInstance().getRollDamageThreshold();
+// damageThreshold = mcMMO.p.getAdvancedConfig().getRollDamageThreshold();
//
// chancePerLevel = RandomChanceUtil.getRandomChanceExecutionChance(rollOneSkillLevel);
//
-// double maxLevel = AdvancedConfig.getInstance().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL);
+// double maxLevel = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL);
//
// return LocaleLoader.getString("Acrobatics.SubSkill.Roll.Mechanics", rollChanceHalfMax, graceChanceHalfMax, maxLevel, chancePerLevel, damageThreshold, damageThreshold * 2,halfMaxSkillValue);
}
@@ -435,4 +434,5 @@ public class Roll extends AcrobaticsSubSkill {
{
return player.getLocation().getBlock().getLocation();
}
+
}
diff --git a/src/main/java/com/gmail/nossr50/events/skills/abilities/McMMOPlayerAbilityEvent.java b/src/main/java/com/gmail/nossr50/events/skills/abilities/McMMOPlayerAbilityEvent.java
index 3c920464f..08d7dc2b2 100644
--- a/src/main/java/com/gmail/nossr50/events/skills/abilities/McMMOPlayerAbilityEvent.java
+++ b/src/main/java/com/gmail/nossr50/events/skills/abilities/McMMOPlayerAbilityEvent.java
@@ -3,6 +3,7 @@ package com.gmail.nossr50.events.skills.abilities;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.Player;
public class McMMOPlayerAbilityEvent extends McMMOPlayerSkillEvent {
@@ -10,7 +11,7 @@ public class McMMOPlayerAbilityEvent extends McMMOPlayerSkillEvent {
protected McMMOPlayerAbilityEvent(Player player, PrimarySkillType skill) {
super(player, skill);
- ability = skill.getSuperAbilityType();
+ ability = mcMMO.p.getSkillTools().getSuperAbility(skill);
}
public SuperAbilityType getAbility() {
diff --git a/src/main/java/com/gmail/nossr50/events/skills/secondaryabilities/SubSkillEvent.java b/src/main/java/com/gmail/nossr50/events/skills/secondaryabilities/SubSkillEvent.java
index ee4fbb873..7aefb003e 100644
--- a/src/main/java/com/gmail/nossr50/events/skills/secondaryabilities/SubSkillEvent.java
+++ b/src/main/java/com/gmail/nossr50/events/skills/secondaryabilities/SubSkillEvent.java
@@ -1,9 +1,9 @@
package com.gmail.nossr50.events.skills.secondaryabilities;
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.events.skills.McMMOPlayerSkillEvent;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
@@ -20,7 +20,7 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
*/
@Deprecated
public SubSkillEvent(Player player, SubSkillType subSkillType) {
- super(player, PrimarySkillType.bySecondaryAbility(subSkillType));
+ super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType;
}
@@ -33,7 +33,7 @@ public class SubSkillEvent extends McMMOPlayerSkillEvent implements Cancellable
*/
@Deprecated
public SubSkillEvent(Player player, SubSkillType subSkillType, double resultModifier) {
- super(player, PrimarySkillType.bySecondaryAbility(subSkillType));
+ super(player, mcMMO.p.getSkillTools().getPrimarySkillBySubSkill(subSkillType));
this.subSkillType = subSkillType;
this.resultModifier = resultModifier;
}
diff --git a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
index ec8302822..7fbd4043a 100644
--- a/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
@@ -1,7 +1,6 @@
package com.gmail.nossr50.listeners;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.config.experience.ExperienceConfig;
@@ -20,6 +19,8 @@ import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.salvage.Salvage;
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
import com.gmail.nossr50.util.*;
+import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
+import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
@@ -78,9 +79,9 @@ public class BlockListener implements Listener {
continue;
//TODO: Ignore this abomination its rewritten in 2.2
- if(!Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, is.getType())
- && !Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.HERBALISM, is.getType())
- && !Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, is.getType()))
+ if(!mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, is.getType())
+ && !mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.HERBALISM, is.getType())
+ && !mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, is.getType()))
continue;
//If we suspect TEs might be duped only reward block
@@ -122,10 +123,14 @@ public class BlockListener implements Listener {
BlockFace direction = event.getDirection();
Block movedBlock;
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
- for (Block b : event.getBlocks()) {
- movedBlock = b.getRelative(direction);
- mcMMO.getPlaceStore().setTrue(movedBlock);
+ for (Block block : event.getBlocks()) {
+ movedBlock = block.getRelative(direction);
+
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, movedBlock)) {
+ mcMMO.getPlaceStore().setTrue(movedBlock);
+ }
}
}
@@ -147,14 +152,18 @@ public class BlockListener implements Listener {
// Get opposite direction so we get correct block
BlockFace direction = event.getDirection();
Block movedBlock = event.getBlock().getRelative(direction);
- if (movedBlock.getY() >= Misc.getWorldMinCompat(movedBlock.getWorld())) // Very weird that the event is giving us these, they shouldn't exist
+
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
+
+ //Spigot makes bad things happen in its API
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, movedBlock)) {
mcMMO.getPlaceStore().setTrue(movedBlock);
+ }
for (Block block : event.getBlocks()) {
- movedBlock = block.getRelative(direction);
- if (movedBlock.getY() < Misc.getWorldMinCompat(movedBlock.getWorld())) // Very weird that the event is giving us these, they shouldn't exist
- continue;
- mcMMO.getPlaceStore().setTrue(movedBlock);
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+ mcMMO.getPlaceStore().setTrue(block.getRelative(direction));
+ }
}
}
@@ -171,11 +180,16 @@ public class BlockListener implements Listener {
if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
return;
+
BlockState blockState = event.getNewState();
- if(ExperienceConfig.getInstance().isSnowExploitPrevented() && BlockUtils.shouldBeWatched(blockState))
- {
- mcMMO.getPlaceStore().setTrue(blockState.getBlock());
+ if(ExperienceConfig.getInstance().isSnowExploitPrevented() && BlockUtils.shouldBeWatched(blockState)) {
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
+ Block block = blockState.getBlock();
+
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+ mcMMO.getPlaceStore().setTrue(block);
+ }
}
}
@@ -185,16 +199,20 @@ public class BlockListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockFormEvent(BlockFormEvent event)
{
+ World world = event.getBlock().getWorld();
+
/* WORLD BLACKLIST CHECK */
- if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
+ if(WorldBlacklist.isWorldBlacklisted(world))
return;
- BlockState newState = event.getNewState();
-
if(ExperienceConfig.getInstance().preventStoneLavaFarming()) {
- if(newState.getType() != Material.OBSIDIAN
- && ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.MINING, newState.getBlockData())) {
- mcMMO.getPlaceStore().setTrue(newState);
+ BlockState newState = event.getNewState();
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
+
+ if(newState.getType() != Material.OBSIDIAN && ExperienceConfig.getInstance().doesBlockGiveSkillXP(PrimarySkillType.MINING, newState.getBlockData())) {
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, newState.getBlock())) {
+ mcMMO.getPlaceStore().setTrue(newState);
+ }
}
}
}
@@ -207,16 +225,23 @@ public class BlockListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onBlockPlace(BlockPlaceEvent event) {
BlockState blockState = event.getBlock().getState();
+ Block block = blockState.getBlock();
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
// if (!Tag.LOGS.isTagged(event.getBlockReplacedState().getType()) || !Tag.LOGS.isTagged(event.getBlockPlaced().getType()))
- mcMMO.getPlaceStore().setTrue(blockState);
/* WORLD BLACKLIST CHECK */
- if(WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld())) {
+ if(WorldBlacklist.isWorldBlacklisted(block.getWorld())) {
return;
}
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
+
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+ mcMMO.getPlaceStore().setTrue(blockState);
+ }
+
+
Player player = event.getPlayer();
if (!UserManager.hasPlayerDataKey(player)) {
@@ -228,10 +253,10 @@ public class BlockListener implements Listener {
if(mmoPlayer == null)
return;
- if (blockState.getType() == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player)) {
+ if (blockState.getType() == Repair.anvilMaterial && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.REPAIR)) {
((McMMOPlayer) (mmoPlayer)).getRepairManager().placedAnvilCheck();
}
- else if (blockState.getType() == Salvage.anvilMaterial && PrimarySkillType.SALVAGE.getPermissions(player)) {
+ else if (blockState.getType() == Salvage.anvilMaterial && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SALVAGE)) {
((McMMOPlayer) (mmoPlayer)).getSalvageManager().placedAnvilCheck();
}
}
@@ -243,18 +268,21 @@ public class BlockListener implements Listener {
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onBlockMultiPlace(BlockMultiPlaceEvent event) {
- for (BlockState replacedBlockState : event.getReplacedBlockStates())
- {
+ for (BlockState replacedBlockState : event.getReplacedBlockStates()) {
BlockState blockState = replacedBlockState.getBlock().getState();
+ Block block = blockState.getBlock();
+
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
/* Check if the blocks placed should be monitored so they do not give out XP in the future */
- mcMMO.getPlaceStore().setTrue(blockState);
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+ mcMMO.getPlaceStore().setTrue(blockState);
+ }
}
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
- public void onBlockGrow(BlockGrowEvent event)
- {
+ public void onBlockGrow(BlockGrowEvent event) {
Block block = event.getBlock();
World world = block.getWorld();
@@ -263,10 +291,11 @@ public class BlockListener implements Listener {
return;
// Minecraft is dumb, the events still throw when a plant "grows" higher than the max block height. Even though no new block is created
- if (block.getY() >= world.getMaxHeight())
- return;
+ WorldCompatibilityLayer worldCompatibilityLayer = mcMMO.getCompatibilityManager().getWorldCompatibilityLayer();
- mcMMO.getPlaceStore().setFalse(block);
+ if(BlockUtils.isWithinWorldBounds(worldCompatibilityLayer, block)) {
+ mcMMO.getPlaceStore().setFalse(block);
+ }
}
/**
@@ -333,7 +362,7 @@ public class BlockListener implements Listener {
* We don't check the block store here because herbalism has too many unusual edge cases.
* Instead, we check it inside the drops handler.
*/
- if (PrimarySkillType.HERBALISM.getPermissions(player)) {
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.HERBALISM)) {
herbalismManager.processHerbalismBlockBreakEvent(event);
}
/*
@@ -344,13 +373,14 @@ public class BlockListener implements Listener {
}
/* MINING */
- else if (BlockUtils.affectedBySuperBreaker(blockState) && ItemUtils.isPickaxe(heldItem) && PrimarySkillType.MINING.getPermissions(player) && !mcMMO.getPlaceStore().isTrue(blockState)) {
+ else if (BlockUtils.affectedBySuperBreaker(blockState) && ItemUtils.isPickaxe(heldItem) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.MINING) && !mcMMO.getPlaceStore().isTrue(blockState)) {
MiningManager miningManager = ((McMMOPlayer) (mmoPlayer)).getMiningManager();
miningManager.miningBlockCheck(blockState);
}
/* WOOD CUTTING */
- else if (BlockUtils.hasWoodcuttingXP(blockState) && ItemUtils.isAxe(heldItem) && PrimarySkillType.WOODCUTTING.getPermissions(player) && !mcMMO.getPlaceStore().isTrue(blockState)) {
+ else if (BlockUtils.hasWoodcuttingXP(blockState) && ItemUtils.isAxe(heldItem)
+ && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.WOODCUTTING) && !mcMMO.getPlaceStore().isTrue(blockState)) {
WoodcuttingManager woodcuttingManager = ((McMMOPlayer) (mmoPlayer)).getWoodcuttingManager();
if (woodcuttingManager.canUseTreeFeller(heldItem)) {
woodcuttingManager.processTreeFeller(blockState);
@@ -365,7 +395,7 @@ public class BlockListener implements Listener {
}
/* EXCAVATION */
- else if (BlockUtils.affectedByGigaDrillBreaker(blockState) && ItemUtils.isShovel(heldItem) && PrimarySkillType.EXCAVATION.getPermissions(player) && !mcMMO.getPlaceStore().isTrue(blockState)) {
+ else if (BlockUtils.affectedByGigaDrillBreaker(blockState) && ItemUtils.isShovel(heldItem) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.EXCAVATION) && !mcMMO.getPlaceStore().isTrue(blockState)) {
ExcavationManager excavationManager = ((McMMOPlayer) (mmoPlayer)).getExcavationManager();
excavationManager.excavationBlockCheck(blockState);
@@ -523,7 +553,7 @@ public class BlockListener implements Listener {
*
* We don't need to check permissions here because they've already been checked for the ability to even activate.
*/
- if (mmoPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.hasWoodcuttingXP(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) {
+ if (mmoPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.hasWoodcuttingXP(blockState) && mcMMO.p.getGeneralConfig().getTreeFellerSoundsEnabled()) {
SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
}
}
@@ -578,7 +608,7 @@ public class BlockListener implements Listener {
blockState.update(true);
}
}
- else if (mmoPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || Config.getInstance().getUnarmedItemsAsUnarmed())) {
+ else if (mmoPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed())) {
if (((McMMOPlayer) (mmoPlayer)).getUnarmedManager().canUseBlockCracker() && BlockUtils.affectedByBlockCracker(blockState)) {
if (EventUtils.simulateBlockBreak(block, player, true) && ((McMMOPlayer) (mmoPlayer)).getUnarmedManager().blockCrackerCheck(blockState)) {
blockState.update();
diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
index dd6e8c251..cf88b32d7 100644
--- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.listeners;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.meta.ProjectileOriginMeta;
@@ -163,7 +161,7 @@ public class EntityListener implements Listener {
projectile.setMetadata(mcMMO.infiniteArrowKey, mcMMO.metadataValue);
}
- projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * AdvancedConfig.getInstance().getForceMultiplier(), 1.0)));
+ projectile.setMetadata(mcMMO.bowForceKey, new FixedMetadataValue(pluginRef, Math.min(event.getForce() * mcMMO.p.getAdvancedConfig().getForceMultiplier(), 1.0)));
projectile.setMetadata(mcMMO.arrowDistanceKey, new FixedMetadataValue(pluginRef, projectile.getLocation()));
//Cleanup metadata in 1 minute in case normal collection falls through
CombatUtils.delayArrowMetaCleanup((Projectile) projectile);
@@ -507,7 +505,7 @@ public class EntityListener implements Listener {
}
//Party Friendly Fire
- if(!Config.getInstance().getPartyFriendlyFire())
+ if(!mcMMO.p.getGeneralConfig().getPartyFriendlyFire())
if ((mcMMO.getPartyManager().inSameParty(defendingPlayer, attackingPlayer)
|| mcMMO.getPartyManager().areAllies(defendingPlayer, attackingPlayer))
&& !(Permissions.friendlyFire(attackingPlayer)
diff --git a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
index 3540dc14f..244c55df4 100644
--- a/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.listeners;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
@@ -381,17 +380,17 @@ public class InventoryListener implements Listener {
ItemStack item = event.getItem();
- if (Config.getInstance().getPreventHopperTransferIngredients() && item.getType() != Material.POTION && item.getType() != Material.SPLASH_POTION && item.getType() != Material.LINGERING_POTION) {
+ if (mcMMO.p.getGeneralConfig().getPreventHopperTransferIngredients() && item.getType() != Material.POTION && item.getType() != Material.SPLASH_POTION && item.getType() != Material.LINGERING_POTION) {
event.setCancelled(true);
return;
}
- if (Config.getInstance().getPreventHopperTransferBottles() && (item.getType() == Material.POTION || item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION)) {
+ if (mcMMO.p.getGeneralConfig().getPreventHopperTransferBottles() && (item.getType() == Material.POTION || item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION)) {
event.setCancelled(true);
return;
}
- if (Config.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
+ if (mcMMO.p.getGeneralConfig().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
}
}
diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
index 1a6b2237c..a9598e718 100644
--- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.listeners;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.WorldBlacklist;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.chat.ChatChannel;
@@ -13,6 +12,7 @@ import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.party.ShareHandler;
+import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
import com.gmail.nossr50.skills.fishing.FishingManager;
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
@@ -45,11 +45,13 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
+import org.bukkit.scheduler.BukkitRunnable;
import java.util.Locale;
@@ -74,11 +76,11 @@ public class PlayerListener implements Listener {
/* WORLD BLACKLIST CHECK */
if(WorldBlacklist.isWorldBlacklisted(event.getPlayer().getWorld())) {
//Remove scoreboards
- if(Config.getInstance().getScoreboardsEnabled()) {
+ if(mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
ScoreboardManager.teardownPlayer(event.getPlayer());
}
return;
- } else if(WorldBlacklist.isWorldBlacklisted(event.getFrom().getWorld()) && Config.getInstance().getScoreboardsEnabled()) {
+ } else if(WorldBlacklist.isWorldBlacklisted(event.getFrom().getWorld()) && mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
//This only fires if they are travelling to a non-blacklisted world from a blacklisted world
//Setup scoreboards
@@ -94,7 +96,7 @@ public class PlayerListener implements Listener {
return;
}
- if (!UserManager.hasPlayerDataKey(player) || Config.getInstance().getXPAfterTeleportCooldown() <= 0 || event.getFrom().equals(event.getTo())) {
+ if (!UserManager.hasPlayerDataKey(player) || mcMMO.p.getGeneralConfig().getXPAfterTeleportCooldown() <= 0 || event.getFrom().equals(event.getTo())) {
return;
}
@@ -107,36 +109,56 @@ public class PlayerListener implements Listener {
mmoPlayer.actualizeTeleportATS();
}
+
/**
- * Handle PlayerDeathEvents at the lowest priority.
+ * Handle {@link EntityDamageByEntityEvent} at the highest priority.
*
- * These events are used to modify the death message of a player when
- * needed to correct issues potentially caused by the custom naming used
- * for mob healthbars.
+ * This handler is used to clear the names of mobs with health bars to
+ * fix death messages showing mob health bars on death.
*
- * @param event The event to modify
+ * @param event the event to listen to
*/
- @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
- public void onPlayerDeathLowest(PlayerDeathEvent event) {
- /* WORLD BLACKLIST CHECK */
- if(WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
+ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
+ public void onEntityDamageByEntityHighest(EntityDamageByEntityEvent event) {
+ // we only care about players as this is for fixing player death messages
+ if (!(event.getEntity() instanceof Player))
+ return;
+ Player player = (Player) event.getEntity();
+
+ // get the attacker
+ LivingEntity attacker;
+ if (event.getDamager() instanceof LivingEntity)
+ attacker = (LivingEntity) event.getDamager();
+ // attempt to find creator of a projectile
+ else if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof LivingEntity)
+ attacker = (LivingEntity) ((Projectile) event.getDamager()).getShooter();
+ else
return;
- String deathMessage = event.getDeathMessage();
-
- /* WORLD GUARD MAIN FLAG CHECK */
- if(WorldGuardUtils.isWorldGuardLoaded())
- {
- if(!WorldGuardManager.getInstance().hasMainFlag(event.getEntity()))
- return;
- }
-
- if (deathMessage == null) {
+ if (attacker instanceof HumanEntity)
return;
- }
- Player player = event.getEntity();
- event.setDeathMessage(MobHealthbarUtils.fixDeathMessage(deathMessage, player));
+ // world blacklist check
+ if (WorldBlacklist.isWorldBlacklisted(event.getEntity().getWorld()))
+ return;
+ // world guard main flag check
+ if (WorldGuardUtils.isWorldGuardLoaded() && !WorldGuardManager.getInstance().hasMainFlag((Player) event.getEntity()))
+ return;
+
+ // we only want to handle player deaths
+ if ((player.getHealth() - event.getFinalDamage()) > 0)
+ return;
+
+ // temporarily clear the mob's name
+ new MobHealthDisplayUpdaterTask(attacker).run();
+
+ // set the name back
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ MobHealthbarUtils.handleMobHealthbars(attacker, 0, mcMMO.p);
+ }
+ }.runTaskLater(mcMMO.p, 1);
}
/**
@@ -276,7 +298,7 @@ public class PlayerListener implements Listener {
return;
}
- if (!UserManager.hasPlayerDataKey(player) || !PrimarySkillType.FISHING.getPermissions(player)) {
+ if (!UserManager.hasPlayerDataKey(player) || !mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.FISHING)) {
return;
}
@@ -295,7 +317,7 @@ public class PlayerListener implements Listener {
if(event.getCaught() != null) {
Item fishingCatch = (Item) event.getCaught();
- if (Config.getInstance().getFishingOverrideTreasures() &&
+ if (mcMMO.p.getGeneralConfig().getFishingOverrideTreasures() &&
fishingCatch.getItemStack().getType() != Material.SALMON &&
fishingCatch.getItemStack().getType() != Material.COD &&
fishingCatch.getItemStack().getType() != Material.TROPICAL_FISH &&
@@ -363,7 +385,7 @@ public class PlayerListener implements Listener {
return;
}
- if (!UserManager.hasPlayerDataKey(player) || !PrimarySkillType.FISHING.getPermissions(player)) {
+ if (!UserManager.hasPlayerDataKey(player) || !mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.FISHING)) {
return;
}
@@ -570,11 +592,11 @@ public class PlayerListener implements Listener {
//Delay loading for 3 seconds in case the player has a save task running, its hacky but it should do the trick
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 60);
- if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
+ if (mcMMO.p.getGeneralConfig().getMOTDEnabled() && Permissions.motd(player)) {
Motd.displayAll(player);
}
- if (plugin.isXPEventEnabled() && Config.getInstance().playerJoinEventInfo()) {
+ if (plugin.isXPEventEnabled() && mcMMO.p.getGeneralConfig().playerJoinEventInfo()) {
player.sendMessage(LocaleLoader.getString("XPRate.Event", ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier()));
}
}
@@ -657,10 +679,10 @@ public class PlayerListener implements Listener {
case RIGHT_CLICK_BLOCK:
Material type = clickedBlock.getType();
- if (!Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
+ if (!mcMMO.p.getGeneralConfig().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
/* REPAIR CHECKS */
if (type == Repair.anvilMaterial
- && PrimarySkillType.REPAIR.getPermissions(player)
+ && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.REPAIR)
&& mcMMO.getRepairableManager().isRepairable(heldItem)
&& heldItem.getAmount() <= 1) {
RepairManager repairManager = ((McMMOPlayer) (mmoPlayer)).getRepairManager();
@@ -674,7 +696,7 @@ public class PlayerListener implements Listener {
}
/* SALVAGE CHECKS */
else if (type == Salvage.anvilMaterial
- && PrimarySkillType.SALVAGE.getPermissions(player)
+ && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SALVAGE)
&& RankUtils.hasUnlockedSubskill(player, SubSkillType.SALVAGE_SCRAP_COLLECTOR)
&& mcMMO.getSalvageableManager().isSalvageable(heldItem)
&& heldItem.getAmount() <= 1) {
@@ -705,9 +727,9 @@ public class PlayerListener implements Listener {
case LEFT_CLICK_BLOCK:
type = clickedBlock.getType();
- if (!Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
+ if (!mcMMO.p.getGeneralConfig().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
/* REPAIR CHECKS */
- if (type == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
+ if (type == Repair.anvilMaterial && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.REPAIR) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
RepairManager repairManager = ((McMMOPlayer) (mmoPlayer)).getRepairManager();
// Cancel repairing an enchanted item
@@ -717,7 +739,7 @@ public class PlayerListener implements Listener {
}
}
/* SALVAGE CHECKS */
- else if (type == Salvage.anvilMaterial && PrimarySkillType.SALVAGE.getPermissions(player) && mcMMO.getSalvageableManager().isSalvageable(heldItem)) {
+ else if (type == Salvage.anvilMaterial && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SALVAGE) && mcMMO.getSalvageableManager().isSalvageable(heldItem)) {
SalvageManager salvageManager = ((McMMOPlayer) (mmoPlayer)).getSalvageManager();
// Cancel salvaging an enchanted item
@@ -799,7 +821,7 @@ public class PlayerListener implements Listener {
/* ACTIVATION & ITEM CHECKS */
if (BlockUtils.canActivateTools(blockState)) {
- if (Config.getInstance().getAbilitiesEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getAbilitiesEnabled()) {
if (BlockUtils.canActivateHerbalism(blockState)) {
mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
}
@@ -865,7 +887,7 @@ public class PlayerListener implements Listener {
}
/* ACTIVATION CHECKS */
- if (Config.getInstance().getAbilitiesEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getAbilitiesEnabled()) {
mcMMOPlayer.processAbilityActivation(PrimarySkillType.AXES);
mcMMOPlayer.processAbilityActivation(PrimarySkillType.EXCAVATION);
mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
@@ -897,13 +919,13 @@ public class PlayerListener implements Listener {
Material type = heldItem.getType();
TamingManager tamingManager = mcMMOPlayer.getTamingManager();
- if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry())) {
+ if (type == mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry())) {
tamingManager.summonWolf();
}
- else if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry())) {
+ else if (type == mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry())) {
tamingManager.summonOcelot();
}
- else if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry())) {
+ else if (type == mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry())) {
tamingManager.summonHorse();
}
@@ -956,7 +978,7 @@ public class PlayerListener implements Listener {
*/
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
- if (!Config.getInstance().getLocale().equalsIgnoreCase("en_US")) {
+ if (!mcMMO.p.getGeneralConfig().getLocale().equalsIgnoreCase("en_US")) {
String message = event.getMessage();
String command = message.substring(1).split(" ")[0];
String lowerCaseCommand = command.toLowerCase(Locale.ENGLISH);
@@ -964,7 +986,7 @@ public class PlayerListener implements Listener {
// Do these ACTUALLY have to be lower case to work properly?
for (PrimarySkillType skill : PrimarySkillType.values()) {
String skillName = skill.toString().toLowerCase(Locale.ENGLISH);
- String localizedName = skill.getName().toLowerCase(Locale.ENGLISH);
+ String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
if (lowerCaseCommand.equals(localizedName)) {
event.setMessage(message.replace(command, skillName));
diff --git a/src/main/java/com/gmail/nossr50/listeners/SelfListener.java b/src/main/java/com/gmail/nossr50/listeners/SelfListener.java
index cab7bba9a..d545b61bc 100644
--- a/src/main/java/com/gmail/nossr50/listeners/SelfListener.java
+++ b/src/main/java/com/gmail/nossr50/listeners/SelfListener.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.listeners;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.events.experience.McMMOPlayerLevelUpEvent;
@@ -10,6 +9,7 @@ import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.PlayerLevelUtils;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.RankUtils;
+import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.gmail.nossr50.worldguard.WorldGuardUtils;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
@@ -50,7 +50,7 @@ public class SelfListener implements Listener {
//Reset the delay timer
RankUtils.resetUnlockDelayTimer();
- if(Config.getInstance().getScoreboardsEnabled())
+ if(mcMMO.p.getGeneralConfig().getScoreboardsEnabled())
ScoreboardManager.handleLevelUp(player, skill);
if(Config.getInstance().getScoreboardsEnabled())
@@ -63,7 +63,7 @@ public class SelfListener implements Listener {
Player player = event.getPlayer();
if(player.isOnline()) {
- if(Config.getInstance().getScoreboardsEnabled())
+ if(mcMMO.p.getGeneralConfig().getScoreboardsEnabled())
ScoreboardManager.handleXp(player, event.getSkill());
}
}
@@ -72,7 +72,7 @@ public class SelfListener implements Listener {
public void onAbility(McMMOPlayerAbilityActivateEvent event) {
Player player = event.getPlayer();
if(player.isOnline()) {
- if(Config.getInstance().getScoreboardsEnabled())
+ if(mcMMO.p.getGeneralConfig().getScoreboardsEnabled())
ScoreboardManager.cooldownUpdate(event.getPlayer(), event.getSkill());
}
}
@@ -141,7 +141,7 @@ public class SelfListener implements Listener {
return;
}
- if (primarySkillType.isChildSkill()) {
+ if (SkillTools.isChildSkill(primarySkillType)) {
return;
}
@@ -149,7 +149,7 @@ public class SelfListener implements Listener {
float guaranteedMinimum = ExperienceConfig.getInstance().getDiminishedReturnsCap() * rawXp;
- float modifiedThreshold = (float) (threshold / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
+ float modifiedThreshold = (float) (threshold / ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType) * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
float difference = (mmoPlayer.getExperienceHandler().getRegisteredXpGain(primarySkillType) - modifiedThreshold) / modifiedThreshold;
if (difference > 0) {
diff --git a/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java b/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java
index f4f57ceaf..0fed62f4f 100644
--- a/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java
+++ b/src/main/java/com/gmail/nossr50/locale/LocaleLoader.java
@@ -1,22 +1,24 @@
package com.gmail.nossr50.locale;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.text.TextUtils;
import net.kyori.adventure.text.TextComponent;
import org.bukkit.ChatColor;
+import org.jetbrains.annotations.NotNull;
-import java.io.IOException;
-import java.io.Reader;
+import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.logging.Level;
public final class LocaleLoader {
private static final String BUNDLE_ROOT = "com.gmail.nossr50.locale.locale";
+ private static final String OVERRIDE_FILE_NAME = "locale_override.properties";
private static Map bundleCache = new HashMap<>();
private static ResourceBundle bundle = null;
private static ResourceBundle filesystemBundle = null;
@@ -31,8 +33,9 @@ public final class LocaleLoader {
/**
* Gets the appropriate string from the Locale files.
*
- * @param key The key to look up the string with
+ * @param key The key to look up the string with
* @param messageArguments Any arguments to be added to the string
+ *
* @return The properly formatted locale string
*/
public static String getString(String key, Object... messageArguments) {
@@ -45,11 +48,13 @@ public final class LocaleLoader {
}
//TODO: Remove this hacky crap with something better later
+
/**
* Gets the appropriate TextComponent representation of a formatted string from the Locale files.
*
- * @param key The key to look up the string with
+ * @param key The key to look up the string with
* @param messageArguments Any arguments to be added to the text component
+ *
* @return The properly formatted text component
*/
public static TextComponent getTextComponent(String key, Object... messageArguments) {
@@ -76,19 +81,18 @@ public final class LocaleLoader {
if (filesystemBundle != null) {
try {
return filesystemBundle.getString(key);
+ } catch (MissingResourceException ignored) {
}
- catch (MissingResourceException ignored) {}
}
try {
return bundle.getString(key);
+ } catch (MissingResourceException ignored) {
}
- catch (MissingResourceException ignored) {}
try {
return enBundle.getString(key);
- }
- catch (MissingResourceException ignored) {
+ } catch (MissingResourceException ignored) {
if (!key.contains("Guides")) {
mcMMO.p.getLogger().warning("Could not find locale string: " + key);
}
@@ -130,31 +134,169 @@ public final class LocaleLoader {
if (bundle == null) {
Locale.setDefault(new Locale("en", "US"));
Locale locale = null;
- String[] myLocale = Config.getInstance().getLocale().split("[-_ ]");
+
+ String[] myLocale = mcMMO.p.getGeneralConfig().getLocale().split("[-_ ]");
if (myLocale.length == 1) {
locale = new Locale(myLocale[0]);
- }
- else if (myLocale.length >= 2) {
+ } else if (myLocale.length >= 2) {
locale = new Locale(myLocale[0], myLocale[1]);
}
if (locale == null) {
- throw new IllegalStateException("Failed to parse locale string '" + Config.getInstance().getLocale() + "'");
+ throw new IllegalStateException("Failed to parse locale string '" + mcMMO.p.getGeneralConfig().getLocale() + "'");
}
Path localePath = Paths.get(mcMMO.getLocalesDirectory() + "locale_" + locale.toString() + ".properties");
+ Path overridePath = Paths.get(mcMMO.getLocalesDirectory() + OVERRIDE_FILE_NAME);
+ File overrideFile = overridePath.toFile();
+
if (Files.exists(localePath) && Files.isRegularFile(localePath)) {
- try (Reader localeReader = Files.newBufferedReader(localePath)) {
- mcMMO.p.getLogger().log(Level.INFO, "Loading locale from {0}", localePath);
- filesystemBundle = new PropertyResourceBundle(localeReader);
+
+ File oldOverrideFile = localePath.toFile();
+
+ try {
+ //Copy the file
+ com.google.common.io.Files.copy(oldOverrideFile, overrideFile);
+ //Remove the old file now
+ oldOverrideFile.delete();
+
+ //Insert our helpful text
+ StringBuilder stringBuilder = new StringBuilder();
+
+ try(BufferedReader bufferedReader = new BufferedReader(new FileReader(overrideFile.getPath()))) {
+ // Open the file
+ String line;
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
+ LocalDateTime localDateTime = LocalDateTime.now();
+ stringBuilder.append("# mcMMO Locale Override File created on ").append(localDateTime.format(dateTimeFormatter)).append("\r\n"); //Empty file
+ stringBuilder.append(getLocaleHelpTextWithoutExamples()); //Add our helpful text
+ while ((line = bufferedReader.readLine()) != null) {
+ stringBuilder.append(line).append("\r\n");
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try(FileWriter fileWriter = new FileWriter(overrideFile.getPath())) {
+ fileWriter.write(stringBuilder.toString());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
} catch (IOException e) {
- mcMMO.p.getLogger().log(Level.WARNING, "Failed to load locale from " + localePath, e);
+ e.printStackTrace();
}
}
+
+ //Use the new locale file
+ if (Files.exists(overridePath) && Files.isRegularFile(overridePath)) {
+ try (Reader localeReader = Files.newBufferedReader(overridePath)) {
+ mcMMO.p.getLogger().log(Level.INFO, "Loading locale from {0}", overridePath);
+ filesystemBundle = new PropertyResourceBundle(localeReader);
+ } catch (IOException e) {
+ mcMMO.p.getLogger().log(Level.WARNING, "Failed to load locale from " + overridePath, e);
+ }
+ } else {
+ //Create a blank file and fill it in with some helpful text
+ try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(overrideFile, true))) {
+ // Open the file to write the player
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm");
+ LocalDateTime localDateTime = LocalDateTime.now();
+ bufferedWriter.append("# mcMMO Locale Override File created on ").append(localDateTime.format(dateTimeFormatter)).append("\r\n"); //Empty file
+ String localeExplanation = getLocaleHelpText();
+ bufferedWriter.append(localeExplanation);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
bundle = ResourceBundle.getBundle(BUNDLE_ROOT, locale);
- enBundle = ResourceBundle.getBundle(BUNDLE_ROOT, Locale.US);
}
+
+ enBundle = ResourceBundle.getBundle(BUNDLE_ROOT, Locale.US);
+ }
+
+ @NotNull
+ private static String getLocaleHelpText() {
+ String localeExplanation =
+ "# -- Are you looking to change the language of mcMMO but without editing it yourself? --\n" +
+ "\n" +
+ "# mcMMO has quite a few built in translations, you can choose which translation by editing config.yml with the appropriate locale code. The setting is `General.Locale` in config.yml\n" +
+ "# Odds are, if you speak a popular language on earth we already have a translation for it.\n" +
+ "# However our translations are done by the community, and update infrequently. (Please help us out <3)\n" +
+ "# We would love more people to help update our locales, submit any updated translation file to our GitHub or email it to me at business@neetgames.com\n" +
+ "# For a list of built in translations, view this link: https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "\n" +
+ "\n" +
+ "# -- Using a built in translation -- \n" +
+ "# Assuming you read the above section, edit config.yml's General.Locale from en_US to the locale code that we support (see the above link), then reboot your server\n" +
+ "\n" +
+ "\n" +
+ "# -- Do you want to change the text in mcMMO? Including adding colors? ( Locale Override ) -- \n" +
+ "# First, a brief explanation.\n" +
+ "# Locales are the language files used by mcMMO, they also contain color codes and most of the styling used by mcMMO.\n" +
+ "# You can customize a locale outside of the JAR in version 2.1.51 and up.\n" +
+ "#\n" +
+ "# Locales can be overridden by editing this file\n" +
+ "# You can find the up to date current locale files here https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "# The master file is en_US, if a translation is missing entries (as they often are) it will pull from the en_US file https://github.com/mcMMO-Dev/mcMMO/blob/master/src/main/resources/locale/locale_en_US.properties\n" +
+ "#\n" +
+ "# To override a locale, add entries to this file and copy ** only ** the strings you want to replace, otherwise you will not see any updated strings when mcMMO updates and will have to manually change them and read patch notes carefully.\n" +
+ "# If you wish to replace every line in some way, feel free to copy the entire contents of this file, just be advised that you will need to be on top of locale updates in mcMMO and follow our changelog closely.\n" +
+ "\n" +
+ "\n" +
+ "# WARNING: Locales only support ASCII and UTF16 characters at the moment, so you'll need to run special characters through a UTF16 converter (google it) to get them to work. This will be fixed in the future!\n" +
+ "# FIND KEYS HERE: On our github repo (en_US is our master file and has ALL the keys) -> https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "# WARNING: Some keys in our master file are unused, make gratuitous use of Ctrl+F\n" +
+ "# HOW TO APPLY: You can either restart the server for these changes to take effect or run /mcreloadlocale.\n" +
+ "# -- Add Keys Below --\n" +
+ getExamples();
+ return localeExplanation;
+ }
+
+ @NotNull
+ private static String getExamples() {
+ return "This.Is.An.Example.Put.Locale.Keys.Here.One=&aExample text using hex color codes\n" +
+ "This.Is.An.Example.Put.Locale.Keys.Here.Two=[[DARK_AQUA]]Example text using our own color codes\n" +
+ "This.Is.An.Example.Put.Locale.Keys.Here.Three=Example text with no colors\n";
+ }
+
+ @NotNull
+ private static String getLocaleHelpTextWithoutExamples() {
+ String localeExplanation =
+ "# -- Are you looking to change the language of mcMMO but without editing it yourself? --\n" +
+ "\n" +
+ "# mcMMO has quite a few built in translations, you can choose which translation by editing config.yml with the appropriate locale code. The setting is `General.Locale` in config.yml\n" +
+ "# Odds are, if you speak a popular language on earth we already have a translation for it.\n" +
+ "# However our translations are done by the community, and update infrequently. (Please help us out <3)\n" +
+ "# We would love more people to help update our locales, submit any updated translation file to our GitHub or email it to me at business@neetgames.com\n" +
+ "# For a list of built in translations, view this link: https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "\n" +
+ "\n" +
+ "# -- Using a built in translation -- \n" +
+ "# Assuming you read the above section, edit config.yml's General.Locale from en_US to the locale code that we support (see the above link), then reboot your server\n" +
+ "\n" +
+ "\n" +
+ "# -- Do you want to change the text in mcMMO? Including adding colors? ( Locale Override ) -- \n" +
+ "# First, a brief explanation.\n" +
+ "# Locales are the language files used by mcMMO, they also contain color codes and most of the styling used by mcMMO.\n" +
+ "# You can customize a locale outside of the JAR in version 2.1.51 and up.\n" +
+ "#\n" +
+ "# Locales can be overridden by editing this file\n" +
+ "# You can find the up to date current locale files here https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "# The master file is en_US, if a translation is missing entries (as they often are) it will pull from the en_US file https://github.com/mcMMO-Dev/mcMMO/blob/master/src/main/resources/locale/locale_en_US.properties\n" +
+ "#\n" +
+ "# To override a locale, add entries to this file and copy ** only ** the strings you want to replace, otherwise you will not see any updated strings when mcMMO updates and will have to manually change them and read patch notes carefully.\n" +
+ "# If you wish to replace every line in some way, feel free to copy the entire contents of this file, just be advised that you will need to be on top of locale updates in mcMMO and follow our changelog closely.\n" +
+ "\n" +
+ "\n" +
+ "# WARNING: Locales only support ASCII and UTF16 characters at the moment, so you'll need to run special characters through a UTF16 converter (google it) to get them to work. This will be fixed in the future!\n" +
+ "# FIND KEYS HERE: On our github repo (en_US is our master file and has ALL the keys) -> https://github.com/mcMMO-Dev/mcMMO/tree/master/src/main/resources/locale\n" +
+ "# WARNING: Some keys in our master file are unused, make gratuitous use of Ctrl+F\n" +
+ "# HOW TO APPLY: You can either restart the server for these changes to take effect or run /mcreloadlocale.\n" +
+ "# -- Add Keys Below --\n";
+ return localeExplanation;
}
public static String addColors(String input) {
diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java
index c8ec55b9a..04b847791 100644
--- a/src/main/java/com/gmail/nossr50/mcMMO.java
+++ b/src/main/java/com/gmail/nossr50/mcMMO.java
@@ -43,6 +43,7 @@ import com.gmail.nossr50.util.player.PlayerLevelUtils;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.RankUtils;
+import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.util.skills.SmeltingTracker;
import com.gmail.nossr50.util.upgrade.UpgradeManager;
import com.gmail.nossr50.worldguard.WorldGuardManager;
@@ -55,8 +56,10 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.metadata.FixedMetadataValue;
+import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.plugin.java.JavaPluginLoader;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -87,6 +90,9 @@ public class mcMMO extends JavaPlugin {
private static ChatManager chatManager;
private static CommandManager commandManager; //ACF
private static TransientEntityTracker transientEntityTracker;
+
+ private @NotNull SkillTools skillTools;
+
private static boolean serverShutdownExecuted = false;
/* Adventure */
@@ -147,21 +153,46 @@ public class mcMMO extends JavaPlugin {
public final static String PROJECTILE_ORIGIN_METAKEY = "mcMMO: Projectile Origin";
public static FixedMetadataValue metadataValue;
+ private long purgeTime = 2630000000L;
- public static final String ULTRA_PERMISSONS = "UltraPermissons";
+ private GeneralConfig generalConfig;
+ private AdvancedConfig advancedConfig;
+// private RepairConfig repairConfig;
+// private SalvageConfig salvageConfig;
+// private PersistentDataConfig persistentDataConfig;
+// private ChatConfig chatConfig;
+// private CoreSkillsConfig coreSkillsConfig;
+// private RankConfig rankConfig;
+// private TreasureConfig treasureConfig;
+// private FishingTreasureConfig fishingTreasureConfig;
+// private SoundConfig soundConfig;
public mcMMO() {
p = this;
}
+
+ protected mcMMO(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file)
+ {
+ super(loader, description, dataFolder, file);
+ }
+
+
/**
* Things to be run when the plugin is enabled.
*/
@Override
public void onEnable() {
try {
+ setupFilePaths();
+ generalConfig = new GeneralConfig(getDataFolder()); //Load before skillTools
+ skillTools = new SkillTools(this); //Load after general config
+
+ //Init configs
+ advancedConfig = new AdvancedConfig(getDataFolder());
+
//Store this value so other plugins can check it
- isRetroModeEnabled = Config.getInstance().getIsRetroMode();
+ isRetroModeEnabled = generalConfig.getIsRetroMode();
//Platform Manager
platformManager = new PlatformManager();
@@ -177,7 +208,6 @@ public class mcMMO extends JavaPlugin {
upgradeManager = new UpgradeManager();
- setupFilePaths();
modManager = new ModManager();
@@ -203,7 +233,10 @@ public class mcMMO extends JavaPlugin {
getLogger().warning("mcMMO will not work properly alongside NoCheatPlus without CompatNoCheatPlus");
}
- databaseManager = DatabaseManagerFactory.getDatabaseManager();
+ // One month in milliseconds
+ this.purgeTime = 2630000000L * generalConfig.getOldUsersCutoff();
+
+ databaseManager = DatabaseManagerFactory.getDatabaseManager(mcMMO.getUsersFilePath(), getLogger(), purgeTime, mcMMO.p.getAdvancedConfig().getStartingLevel());
//Check for the newer API and tell them what to do if its missing
checkForOutdatedAPI();
@@ -243,7 +276,7 @@ public class mcMMO extends JavaPlugin {
placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
- if (Config.getInstance().getPTPCommandWorldPermissions()) {
+ if (generalConfig.getPTPCommandWorldPermissions()) {
Permissions.generateWorldTeleportPermissions();
}
@@ -254,11 +287,11 @@ public class mcMMO extends JavaPlugin {
//If anonymous statistics are enabled then use them
Metrics metrics;
- if(Config.getInstance().getIsMetricsEnabled()) {
+ if(generalConfig.getIsMetricsEnabled()) {
metrics = new Metrics(this, 3894);
metrics.addCustomChart(new SimplePie("version", () -> getDescription().getVersion()));
- if(Config.getInstance().getIsRetroMode())
+ if(generalConfig.getIsRetroMode())
metrics.addCustomChart(new SimplePie("leveling_system", () -> "Retro"));
else
metrics.addCustomChart(new SimplePie("leveling_system", () -> "Standard"));
@@ -350,7 +383,7 @@ public class mcMMO extends JavaPlugin {
mcMMO.getPartyManager().saveParties(); // Save our parties
//TODO: Needed?
- if(Config.getInstance().getScoreboardsEnabled())
+ if(generalConfig.getScoreboardsEnabled())
ScoreboardManager.teardownAll();
formulaManager.saveFormula();
@@ -360,7 +393,7 @@ public class mcMMO extends JavaPlugin {
e.printStackTrace();
}
- if (Config.getInstance().getBackupsEnabled()) {
+ if (generalConfig.getBackupsEnabled()) {
// Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
try {
ZipLibrary.mcMMOBackup();
@@ -532,7 +565,7 @@ public class mcMMO extends JavaPlugin {
TreasureConfig.getInstance();
FishingTreasureConfig.getInstance();
HiddenConfig.getInstance();
- AdvancedConfig.getInstance();
+ mcMMO.p.getAdvancedConfig();
PotionConfig.getInstance();
CoreSkillsConfig.getInstance();
SoundConfig.getInstance();
@@ -592,7 +625,7 @@ public class mcMMO extends JavaPlugin {
private void registerCustomRecipes() {
getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
- if (Config.getInstance().getChimaeraEnabled()) {
+ if (generalConfig.getChimaeraEnabled()) {
getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
}
}, 40);
@@ -603,7 +636,7 @@ public class mcMMO extends JavaPlugin {
long second = 20;
long minute = second * 60;
- long saveIntervalTicks = Math.max(minute, Config.getInstance().getSaveInterval() * minute);
+ long saveIntervalTicks = Math.max(minute, generalConfig.getSaveInterval() * minute);
new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
@@ -611,7 +644,7 @@ public class mcMMO extends JavaPlugin {
new CleanBackupsTask().runTaskAsynchronously(mcMMO.p);
// Old & Powerless User remover
- long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
+ long purgeIntervalTicks = generalConfig.getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
if (purgeIntervalTicks == 0) {
new UserPurgeTask().runTaskLaterAsynchronously(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
@@ -621,7 +654,7 @@ public class mcMMO extends JavaPlugin {
}
// Automatically remove old members from parties
- long kickIntervalTicks = Config.getInstance().getAutoPartyKickInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
+ long kickIntervalTicks = generalConfig.getAutoPartyKickInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
if (kickIntervalTicks == 0) {
new PartyAutoKickTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
@@ -638,7 +671,7 @@ public class mcMMO extends JavaPlugin {
new ClearRegisteredXPGainTask().runTaskTimer(this, 60, 60);
}
- if(AdvancedConfig.getInstance().allowPlayerTips())
+ if(mcMMO.p.getAdvancedConfig().allowPlayerTips())
{
new NotifySquelchReminderTask().runTaskTimer(this, 60, ((20 * 60) * 60));
}
@@ -710,4 +743,20 @@ public class mcMMO extends JavaPlugin {
private static synchronized void setServerShutdown(boolean bool) {
serverShutdownExecuted = bool;
}
+
+ public long getPurgeTime() {
+ return purgeTime;
+ }
+
+ public @NotNull SkillTools getSkillTools() {
+ return skillTools;
+ }
+
+ public @NotNull GeneralConfig getGeneralConfig() {
+ return generalConfig;
+ }
+
+ public @NotNull AdvancedConfig getAdvancedConfig() {
+ return advancedConfig;
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/party/PartyFeature.java b/src/main/java/com/gmail/nossr50/party/PartyFeature.java
index 3c032ef8a..a299e2b4f 100644
--- a/src/main/java/com/gmail/nossr50/party/PartyFeature.java
+++ b/src/main/java/com/gmail/nossr50/party/PartyFeature.java
@@ -1,8 +1,8 @@
package com.gmail.nossr50.party;
import com.gmail.nossr50.commands.party.PartySubCommandType;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.entity.Player;
@@ -17,7 +17,7 @@ public enum PartyFeature {
}
public String getFeatureLockedLocaleString() {
- return LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Party.Feature.Locked." + StringUtils.getPrettyPartyFeatureString(this).replace(" ", ""), Config.getInstance().getPartyFeatureUnlockLevel(this)));
+ return LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Party.Feature.Locked." + StringUtils.getPrettyPartyFeatureString(this).replace(" ", ""), mcMMO.p.getGeneralConfig().getPartyFeatureUnlockLevel(this)));
}
public boolean hasPermission(Player player) {
diff --git a/src/main/java/com/gmail/nossr50/party/PartyManager.java b/src/main/java/com/gmail/nossr50/party/PartyManager.java
new file mode 100644
index 000000000..4cd483329
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/party/PartyManager.java
@@ -0,0 +1,845 @@
+package com.gmail.nossr50.party;
+
+import com.gmail.nossr50.datatypes.chat.ChatChannel;
+import com.gmail.nossr50.datatypes.interactions.NotificationType;
+import com.gmail.nossr50.datatypes.party.ItemShareType;
+import com.gmail.nossr50.datatypes.party.Party;
+import com.gmail.nossr50.datatypes.party.PartyLeader;
+import com.gmail.nossr50.datatypes.party.ShareMode;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.events.party.McMMOPartyAllianceChangeEvent;
+import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
+import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.player.NotificationManager;
+import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.sounds.SoundManager;
+import com.gmail.nossr50.util.sounds.SoundType;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.UUID;
+
+public final class PartyManager {
+ private static final String partiesFilePath = mcMMO.getFlatFileDirectory() + "parties.yml";
+ private static final List parties = new ArrayList<>();
+ private static final File partyFile = new File(partiesFilePath);
+
+ private PartyManager() {}
+
+ /**
+ * Check if a party with a given name already exists.
+ *
+ * @param player The player to notify
+ * @param partyName The name of the party to check
+ * @return true if a party with that name exists, false otherwise
+ */
+ public static boolean checkPartyExistence(Player player, String partyName) {
+ if (getParty(partyName) == null) {
+ return false;
+ }
+
+ player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", partyName));
+ return true;
+ }
+
+ /**
+ * Checks if the player can join a party, parties can have a size limit, although there is a permission to bypass this
+ * @param player player who is attempting to join the party
+ * @param targetParty the target party
+ * @return true if party is full and cannot be joined
+ */
+ public static boolean isPartyFull(Player player, Party targetParty)
+ {
+ return !Permissions.partySizeBypass(player) && mcMMO.p.getGeneralConfig().getPartyMaxSize() >= 1 && targetParty.getOnlineMembers().size() >= mcMMO.p.getGeneralConfig().getPartyMaxSize();
+ }
+
+ /**
+ * Attempt to change parties or join a new party.
+ *
+ * @param mcMMOPlayer The player changing or joining parties
+ * @param newPartyName The name of the party being joined
+ * @return true if the party was joined successfully, false otherwise
+ */
+ public static boolean changeOrJoinParty(McMMOPlayer mcMMOPlayer, String newPartyName) {
+ Player player = mcMMOPlayer.getPlayer();
+
+ if (mcMMOPlayer.inParty()) {
+ Party oldParty = mcMMOPlayer.getParty();
+
+ if (!handlePartyChangeEvent(player, oldParty.getName(), newPartyName, EventReason.CHANGED_PARTIES)) {
+ return false;
+ }
+
+ removeFromParty(mcMMOPlayer);
+ }
+ else return handlePartyChangeEvent(player, null, newPartyName, EventReason.JOINED_PARTY);
+
+ return true;
+ }
+
+ /**
+ * Check if two online players are in the same party.
+ *
+ * @param firstPlayer The first player
+ * @param secondPlayer The second player
+ * @return true if they are in the same party, false otherwise
+ */
+ public static boolean inSameParty(Player firstPlayer, Player secondPlayer) {
+ //Profile not loaded
+ if(UserManager.getPlayer(firstPlayer) == null)
+ {
+ return false;
+ }
+
+ //Profile not loaded
+ if(UserManager.getPlayer(secondPlayer) == null)
+ {
+ return false;
+ }
+
+ Party firstParty = UserManager.getPlayer(firstPlayer).getParty();
+ Party secondParty = UserManager.getPlayer(secondPlayer).getParty();
+
+ if (firstParty == null || secondParty == null) {
+ return false;
+ }
+
+ return firstParty.equals(secondParty);
+ }
+
+ public static boolean areAllies(Player firstPlayer, Player secondPlayer) {
+ //Profile not loaded
+ if(UserManager.getPlayer(firstPlayer) == null)
+ {
+ return false;
+ }
+
+ //Profile not loaded
+ if(UserManager.getPlayer(secondPlayer) == null)
+ {
+ return false;
+ }
+
+ Party firstParty = UserManager.getPlayer(firstPlayer).getParty();
+ Party secondParty = UserManager.getPlayer(secondPlayer).getParty();
+
+ if (firstParty == null || secondParty == null || firstParty.getAlly() == null || secondParty.getAlly() == null) {
+ return false;
+ }
+
+ return firstParty.equals(secondParty.getAlly()) && secondParty.equals(firstParty.getAlly());
+ }
+
+ /**
+ * Get the near party members.
+ *
+ * @param mcMMOPlayer The player to check
+ * @return the near party members
+ */
+ public static List getNearMembers(McMMOPlayer mcMMOPlayer) {
+ List nearMembers = new ArrayList<>();
+ Party party = mcMMOPlayer.getParty();
+
+ if (party != null) {
+ Player player = mcMMOPlayer.getPlayer();
+ double range = mcMMO.p.getGeneralConfig().getPartyShareRange();
+
+ for (Player member : party.getOnlineMembers()) {
+ if (!player.equals(member) && member.isValid() && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
+ nearMembers.add(member);
+ }
+ }
+ }
+
+ return nearMembers;
+ }
+
+ public static List getNearVisibleMembers(McMMOPlayer mcMMOPlayer) {
+ List nearMembers = new ArrayList<>();
+ Party party = mcMMOPlayer.getParty();
+
+ if (party != null) {
+ Player player = mcMMOPlayer.getPlayer();
+ double range = mcMMO.p.getGeneralConfig().getPartyShareRange();
+
+ for (Player member : party.getVisibleMembers(player)) {
+ if (!player.equals(member)
+ && member.isValid()
+ && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
+ nearMembers.add(member);
+ }
+ }
+ }
+
+ return nearMembers;
+ }
+
+
+ /**
+ * Get a list of all players in this player's party.
+ *
+ * @param player The player to check
+ * @return all the players in the player's party
+ */
+ public static LinkedHashMap getAllMembers(Player player) {
+ Party party = getParty(player);
+
+ return party == null ? new LinkedHashMap<>() : party.getMembers();
+ }
+
+ /**
+ * Get a list of all online players in this party.
+ *
+ * @param partyName The party to check
+ * @return all online players in this party
+ */
+ public static List getOnlineMembers(String partyName) {
+ return getOnlineMembers(getParty(partyName));
+ }
+
+ /**
+ * Get a list of all online players in this party.
+ *
+ * @param player The player to check
+ * @return all online players in this party
+ */
+ public static List getOnlineMembers(Player player) {
+ return getOnlineMembers(getParty(player));
+ }
+
+ private static List getOnlineMembers(Party party) {
+ return party == null ? new ArrayList<>() : party.getOnlineMembers();
+ }
+
+ /**
+ * Retrieve a party by its name
+ *
+ * @param partyName The party name
+ * @return the existing party, null otherwise
+ */
+ public static Party getParty(String partyName) {
+ for (Party party : parties) {
+ if (party.getName().equalsIgnoreCase(partyName)) {
+ return party;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a party by a members name
+ *
+ * @param playerName The members name
+ * @return the existing party, null otherwise
+ */
+ @Deprecated
+ public static Party getPlayerParty(String playerName) {
+ for (Party party : parties) {
+ if (party.getMembers().containsKey(playerName)) {
+ return party;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a party by a members uuid
+ *
+ * @param uuid The members uuid
+ * @return the existing party, null otherwise
+ */
+ public static Party getPlayerParty(String playerName, UUID uuid) {
+ for (Party party : parties) {
+ LinkedHashMap members = party.getMembers();
+ if (members.containsKey(uuid) || members.containsValue(playerName)) {
+
+ // Name changes
+ if (members.get(uuid) == null || !members.get(uuid).equals(playerName)) {
+ members.put(uuid, playerName);
+ }
+
+ return party;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Retrieve a party by member
+ *
+ * @param player The member
+ * @return the existing party, null otherwise
+ */
+ public static Party getParty(Player player) {
+ //Profile not loaded
+ if(UserManager.getPlayer(player) == null)
+ {
+ return null;
+ }
+
+ McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+
+ return mcMMOPlayer.getParty();
+ }
+
+ /**
+ * Get a list of all current parties.
+ *
+ * @return the list of parties.
+ */
+ public static List getParties() {
+ return parties;
+ }
+
+ /**
+ * Remove a player from a party.
+ *
+ * @param player The player to remove
+ * @param party The party
+ */
+ public static void removeFromParty(OfflinePlayer player, Party party) {
+ LinkedHashMap members = party.getMembers();
+ String playerName = player.getName();
+
+ members.remove(player.getUniqueId());
+
+ if (player.isOnline()) {
+ party.getOnlineMembers().remove(player.getPlayer());
+ }
+
+ if (members.isEmpty()) {
+ parties.remove(party);
+ }
+ else {
+ // If the leaving player was the party leader, appoint a new leader from the party members
+ if (party.getLeader().getUniqueId().equals(player.getUniqueId())) {
+ setPartyLeader(members.keySet().iterator().next(), party);
+ }
+
+ informPartyMembersQuit(party, playerName);
+ }
+ }
+
+ /**
+ * Remove a player from a party.
+ *
+ * @param mcMMOPlayer The player to remove
+ */
+ public static void removeFromParty(McMMOPlayer mcMMOPlayer) {
+ removeFromParty(mcMMOPlayer.getPlayer(), mcMMOPlayer.getParty());
+ processPartyLeaving(mcMMOPlayer);
+ }
+
+ /**
+ * Disband a party. Kicks out all members and removes the party.
+ *
+ * @param party The party to remove
+ */
+ public static void disbandParty(Party party) {
+ //TODO: Potential issues with unloaded profile?
+ for (Player member : party.getOnlineMembers()) {
+ //Profile not loaded
+ if(UserManager.getPlayer(member) == null)
+ {
+ continue;
+ }
+
+ processPartyLeaving(UserManager.getPlayer(member));
+ }
+
+ // Disband the alliance between the disbanded party and it's ally
+ if (party.getAlly() != null) {
+ party.getAlly().setAlly(null);
+ }
+
+ parties.remove(party);
+ }
+
+ /**
+ * Create a new party
+ *
+ * @param mcMMOPlayer The player to add to the party
+ * @param partyName The party to add the player to
+ * @param password The password for this party, null if there was no password
+ */
+ public static void createParty(McMMOPlayer mcMMOPlayer, String partyName, String password) {
+ Player player = mcMMOPlayer.getPlayer();
+
+ Party party = new Party(new PartyLeader(player.getUniqueId(), player.getName()), partyName.replace(".", ""), password);
+
+ if (password != null) {
+ player.sendMessage(LocaleLoader.getString("Party.Password.Set", password));
+ }
+
+ parties.add(party);
+
+ player.sendMessage(LocaleLoader.getString("Commands.Party.Create", party.getName()));
+ addToParty(mcMMOPlayer, party);
+ }
+
+ /**
+ * Check if a player can join a party
+ *
+ * @param player The player trying to join a party
+ * @param party The party
+ * @param password The password provided by the player
+ * @return true if the player can join the party
+ */
+ public static boolean checkPartyPassword(Player player, Party party, String password) {
+ if (party.isLocked()) {
+ String partyPassword = party.getPassword();
+
+ if (partyPassword == null) {
+ player.sendMessage(LocaleLoader.getString("Party.Locked"));
+ return false;
+ }
+
+ if (password == null) {
+ player.sendMessage(LocaleLoader.getString("Party.Password.None"));
+ return false;
+ }
+
+ if (!password.equals(partyPassword)) {
+ player.sendMessage(LocaleLoader.getString("Party.Password.Incorrect"));
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Accept a party invitation
+ *
+ * @param mcMMOPlayer The player to add to the party
+ */
+ public static void joinInvitedParty(McMMOPlayer mcMMOPlayer) {
+ Party invite = mcMMOPlayer.getPartyInvite();
+
+ // Check if the party still exists, it might have been disbanded
+ if (!parties.contains(invite)) {
+ NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.PARTY_MESSAGE, "Party.Disband");
+ return;
+ }
+
+ /*
+ * Don't let players join a full party
+ */
+ if(mcMMO.p.getGeneralConfig().getPartyMaxSize() > 0 && invite.getMembers().size() >= mcMMO.p.getGeneralConfig().getPartyMaxSize())
+ {
+ NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.PARTY_MESSAGE, "Commands.Party.PartyFull.InviteAccept", invite.getName(), String.valueOf(mcMMO.p.getGeneralConfig().getPartyMaxSize()));
+ return;
+ }
+
+ NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.PARTY_MESSAGE, "Commands.Party.Invite.Accepted", invite.getName());
+ mcMMOPlayer.removePartyInvite();
+ addToParty(mcMMOPlayer, invite);
+ }
+
+ /**
+ * Accept a party alliance invitation
+ *
+ * @param mcMMOPlayer The player who accepts the alliance invite
+ */
+ public static void acceptAllianceInvite(McMMOPlayer mcMMOPlayer) {
+ Party invite = mcMMOPlayer.getPartyAllianceInvite();
+ Player player = mcMMOPlayer.getPlayer();
+
+ // Check if the party still exists, it might have been disbanded
+ if (!parties.contains(invite)) {
+ player.sendMessage(LocaleLoader.getString("Party.Disband"));
+ return;
+ }
+
+ if (!handlePartyChangeAllianceEvent(player, mcMMOPlayer.getParty().getName(), invite.getName(), McMMOPartyAllianceChangeEvent.EventReason.FORMED_ALLIANCE)) {
+ return;
+ }
+
+ player.sendMessage(LocaleLoader.getString("Commands.Party.Alliance.Invite.Accepted", invite.getName()));
+ mcMMOPlayer.removePartyAllianceInvite();
+
+ createAlliance(mcMMOPlayer.getParty(), invite);
+ }
+
+ public static void createAlliance(Party firstParty, Party secondParty) {
+ firstParty.setAlly(secondParty);
+ secondParty.setAlly(firstParty);
+
+ for (Player member : firstParty.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.Alliance.Formed", secondParty.getName()));
+ }
+
+ for (Player member : secondParty.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.Alliance.Formed", firstParty.getName()));
+ }
+ }
+
+ public static boolean disbandAlliance(Player player, Party firstParty, Party secondParty){
+ if (!handlePartyChangeAllianceEvent(player, firstParty.getName(), secondParty.getName(), McMMOPartyAllianceChangeEvent.EventReason.DISBAND_ALLIANCE)) {
+ return false;
+ }
+
+ PartyManager.disbandAlliance(firstParty, secondParty);
+ return true;
+ }
+
+ private static void disbandAlliance(Party firstParty, Party secondParty) {
+ firstParty.setAlly(null);
+ secondParty.setAlly(null);
+
+ for (Player member : firstParty.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.Alliance.Disband", secondParty.getName()));
+ }
+
+ for (Player member : secondParty.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.Alliance.Disband", firstParty.getName()));
+ }
+ }
+
+ /**
+ * Add a player to a party
+ *
+ * @param mcMMOPlayer The player to add to the party
+ * @param party The party
+ */
+ public static void addToParty(McMMOPlayer mcMMOPlayer, Party party) {
+ Player player = mcMMOPlayer.getPlayer();
+ String playerName = player.getName();
+
+ informPartyMembersJoin(party, playerName);
+ mcMMOPlayer.setParty(party);
+ party.getMembers().put(player.getUniqueId(), player.getName());
+ party.getOnlineMembers().add(player);
+ }
+
+ /**
+ * Get the leader of a party.
+ *
+ * @param partyName The party name
+ * @return the leader of the party
+ */
+ public static String getPartyLeaderName(String partyName) {
+ Party party = getParty(partyName);
+
+ return party == null ? null : party.getLeader().getPlayerName();
+ }
+
+ /**
+ * Set the leader of a party.
+ *
+ * @param uuid The uuid of the player to set as leader
+ * @param party The party
+ */
+ public static void setPartyLeader(UUID uuid, Party party) {
+ OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(uuid);
+ UUID leaderUniqueId = party.getLeader().getUniqueId();
+
+ for (Player member : party.getOnlineMembers()) {
+ UUID memberUniqueId = member.getUniqueId();
+
+ if (memberUniqueId.equals(player.getUniqueId())) {
+ member.sendMessage(LocaleLoader.getString("Party.Owner.Player"));
+ }
+ else if (memberUniqueId.equals(leaderUniqueId)) {
+ member.sendMessage(LocaleLoader.getString("Party.Owner.NotLeader"));
+ }
+ else {
+ member.sendMessage(LocaleLoader.getString("Party.Owner.New", player.getName()));
+ }
+ }
+
+ party.setLeader(new PartyLeader(player.getUniqueId(), player.getName()));
+ }
+
+ /**
+ * Check if a player can invite others to his party.
+ *
+ * @return true if the player can invite
+ */
+ public static boolean canInvite(McMMOPlayer mcMMOPlayer) {
+ Party party = mcMMOPlayer.getParty();
+
+ return !party.isLocked() || party.getLeader().getUniqueId().equals(mcMMOPlayer.getPlayer().getUniqueId());
+ }
+
+ /**
+ * Load party file.
+ */
+ public static void loadParties() {
+ if (!partyFile.exists()) {
+ return;
+ }
+
+// if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS_PARTY)) {
+// loadAndUpgradeParties();
+// return;
+// }
+
+ try {
+ YamlConfiguration partiesFile;
+ partiesFile = YamlConfiguration.loadConfiguration(partyFile);
+
+ ArrayList hasAlly = new ArrayList<>();
+
+ for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
+ Party party = new Party(partyName);
+
+ String[] leaderSplit = partiesFile.getString(partyName + ".Leader").split("[|]");
+ party.setLeader(new PartyLeader(UUID.fromString(leaderSplit[0]), leaderSplit[1]));
+ party.setPassword(partiesFile.getString(partyName + ".Password"));
+ party.setLocked(partiesFile.getBoolean(partyName + ".Locked"));
+ party.setLevel(partiesFile.getInt(partyName + ".Level"));
+ party.setXp(partiesFile.getInt(partyName + ".Xp"));
+
+ if (partiesFile.getString(partyName + ".Ally") != null) {
+ hasAlly.add(party);
+ }
+
+ party.setXpShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ExpShareMode", "NONE")));
+ party.setItemShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ItemShareMode", "NONE")));
+
+ for (ItemShareType itemShareType : ItemShareType.values()) {
+ party.setSharingDrops(itemShareType, partiesFile.getBoolean(partyName + ".ItemShareType." + itemShareType.toString(), true));
+ }
+
+ LinkedHashMap members = party.getMembers();
+
+ for (String memberEntry : partiesFile.getStringList(partyName + ".Members")) {
+ String[] memberSplit = memberEntry.split("[|]");
+ members.put(UUID.fromString(memberSplit[0]), memberSplit[1]);
+ }
+
+ parties.add(party);
+ }
+
+ mcMMO.p.debug("Loaded (" + parties.size() + ") Parties...");
+
+ for (Party party : hasAlly) {
+ party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally")));
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Save party file.
+ */
+ public static void saveParties() {
+ mcMMO.p.debug("[Party Data] Saving...");
+
+ if (partyFile.exists()) {
+ if (!partyFile.delete()) {
+ mcMMO.p.getLogger().warning("Could not delete party file. Party saving failed!");
+ return;
+ }
+ }
+
+ YamlConfiguration partiesFile = new YamlConfiguration();
+
+ for (Party party : parties) {
+ String partyName = party.getName();
+ PartyLeader leader = party.getLeader();
+
+ partiesFile.set(partyName + ".Leader", leader.getUniqueId().toString() + "|" + leader.getPlayerName());
+ partiesFile.set(partyName + ".Password", party.getPassword());
+ partiesFile.set(partyName + ".Locked", party.isLocked());
+ partiesFile.set(partyName + ".Level", party.getLevel());
+ partiesFile.set(partyName + ".Xp", (int) party.getXp());
+ partiesFile.set(partyName + ".Ally", (party.getAlly() != null) ? party.getAlly().getName() : "");
+ partiesFile.set(partyName + ".ExpShareMode", party.getXpShareMode().toString());
+ partiesFile.set(partyName + ".ItemShareMode", party.getItemShareMode().toString());
+
+ for (ItemShareType itemShareType : ItemShareType.values()) {
+ partiesFile.set(partyName + ".ItemShareType." + itemShareType.toString(), party.sharingDrops(itemShareType));
+ }
+
+ List members = new ArrayList<>();
+
+ for (Entry memberEntry : party.getMembers().entrySet()) {
+ String memberUniqueId = memberEntry.getKey() == null ? "" : memberEntry.getKey().toString();
+ String memberName = memberEntry.getValue();
+
+ if (!members.contains(memberName)) {
+ members.add(memberUniqueId + "|" + memberName);
+ }
+ }
+
+ partiesFile.set(partyName + ".Members", members);
+ }
+
+ try {
+ partiesFile.save(partyFile);
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+// private static void loadAndUpgradeParties() {
+// YamlConfiguration partiesFile = YamlConfiguration.loadConfiguration(partyFile);
+//
+// if (!partyFile.renameTo(new File(mcMMO.getFlatFileDirectory() + "parties.yml.converted"))) {
+// mcMMO.p.getLogger().severe("Could not rename parties.yml to parties.yml.converted!");
+// return;
+// }
+//
+// ArrayList hasAlly = new ArrayList<>();
+//
+// for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
+// Party party = new Party(partyName);
+//
+// String leaderName = partiesFile.getString(partyName + ".Leader");
+// PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(leaderName, false);
+//
+// if (!profile.isLoaded()) {
+// mcMMO.p.getLogger().warning("Could not find UUID in database for party leader " + leaderName + " in party " + partyName);
+// continue;
+// }
+//
+// UUID leaderUniqueId = profile.getUniqueId();
+//
+// party.setLeader(new PartyLeader(leaderUniqueId, leaderName));
+// party.setPassword(partiesFile.getString(partyName + ".Password"));
+// party.setLocked(partiesFile.getBoolean(partyName + ".Locked"));
+// party.setLevel(partiesFile.getInt(partyName + ".Level"));
+// party.setXp(partiesFile.getInt(partyName + ".Xp"));
+//
+// if (partiesFile.getString(partyName + ".Ally") != null) {
+// hasAlly.add(party);
+// }
+//
+// party.setXpShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ExpShareMode", "NONE")));
+// party.setItemShareMode(ShareMode.getShareMode(partiesFile.getString(partyName + ".ItemShareMode", "NONE")));
+//
+// for (ItemShareType itemShareType : ItemShareType.values()) {
+// party.setSharingDrops(itemShareType, partiesFile.getBoolean(partyName + ".ItemShareType." + itemShareType.toString(), true));
+// }
+//
+// LinkedHashMap members = party.getMembers();
+//
+// for (String memberName : partiesFile.getStringList(partyName + ".Members")) {
+// PlayerProfile memberProfile = mcMMO.getDatabaseManager().loadPlayerProfile(memberName, false);
+//
+// if (!memberProfile.isLoaded()) {
+// mcMMO.p.getLogger().warning("Could not find UUID in database for party member " + memberName + " in party " + partyName);
+// continue;
+// }
+//
+// UUID memberUniqueId = memberProfile.getUniqueId();
+//
+// members.put(memberUniqueId, memberName);
+// }
+//
+// parties.add(party);
+// }
+//
+// mcMMO.p.debug("Loaded (" + parties.size() + ") Parties...");
+//
+// for (Party party : hasAlly) {
+// party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally")));
+// }
+//
+// mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_UUIDS_PARTY);
+// }
+
+ /**
+ * Handle party change event.
+ *
+ * @param player The player changing parties
+ * @param oldPartyName The name of the old party
+ * @param newPartyName The name of the new party
+ * @param reason The reason for changing parties
+ * @return true if the change event was successful, false otherwise
+ */
+ public static boolean handlePartyChangeEvent(Player player, String oldPartyName, String newPartyName, EventReason reason) {
+ McMMOPartyChangeEvent event = new McMMOPartyChangeEvent(player, oldPartyName, newPartyName, reason);
+ mcMMO.p.getServer().getPluginManager().callEvent(event);
+
+ return !event.isCancelled();
+ }
+
+ /**
+ * Handle party alliance change event.
+ *
+ * @param player The player changing party alliances
+ * @param oldAllyName The name of the old ally
+ * @param newAllyName The name of the new ally
+ * @param reason The reason for changing allies
+ * @return true if the change event was successful, false otherwise
+ */
+ public static boolean handlePartyChangeAllianceEvent(Player player, String oldAllyName, String newAllyName, McMMOPartyAllianceChangeEvent.EventReason reason) {
+ McMMOPartyAllianceChangeEvent event = new McMMOPartyAllianceChangeEvent(player, oldAllyName, newAllyName, reason);
+ mcMMO.p.getServer().getPluginManager().callEvent(event);
+
+ return !event.isCancelled();
+ }
+
+ /**
+ * Remove party data from the mcMMOPlayer.
+ *
+ * @param mcMMOPlayer The player to remove party data from.
+ */
+ public static void processPartyLeaving(McMMOPlayer mcMMOPlayer) {
+ mcMMOPlayer.removeParty();
+ mcMMOPlayer.setChatMode(ChatChannel.NONE);
+ mcMMOPlayer.setItemShareModifier(10);
+ }
+
+ /**
+ * Notify party members when the party levels up.
+ *
+ * @param party The concerned party
+ * @param levelsGained The amount of levels gained
+ * @param level The current party level
+ */
+ public static void informPartyMembersLevelUp(Party party, int levelsGained, int level) {
+ boolean levelUpSoundsEnabled = mcMMO.p.getGeneralConfig().getLevelUpSoundsEnabled();
+ for (Player member : party.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, level));
+
+ if (levelUpSoundsEnabled) {
+ SoundManager.sendSound(member, member.getLocation(), SoundType.LEVEL_UP);
+ }
+ }
+ }
+
+ /**
+ * Notify party members when a player joins.
+ *
+ * @param party The concerned party
+ * @param playerName The name of the player that joined
+ */
+ private static void informPartyMembersJoin(Party party, String playerName) {
+ for (Player member : party.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.InformedOnJoin", playerName));
+ }
+ }
+
+ /**
+ * Notify party members when a party member quits.
+ *
+ * @param party The concerned party
+ * @param playerName The name of the player that left
+ */
+ private static void informPartyMembersQuit(Party party, String playerName) {
+ for (Player member : party.getOnlineMembers()) {
+ member.sendMessage(LocaleLoader.getString("Party.InformedOnQuit", playerName));
+ }
+ }
+}
diff --git a/src/main/java/com/gmail/nossr50/party/PartyTeleportRecord.java b/src/main/java/com/gmail/nossr50/party/PartyTeleportRecord.java
index c0c6f0564..2df50c937 100644
--- a/src/main/java/com/gmail/nossr50/party/PartyTeleportRecord.java
+++ b/src/main/java/com/gmail/nossr50/party/PartyTeleportRecord.java
@@ -1,6 +1,6 @@
package com.gmail.nossr50.party;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import org.bukkit.entity.Player;
@@ -12,7 +12,7 @@ public class PartyTeleportRecord {
public PartyTeleportRecord() {
requestor = null;
enabled = true;
- confirmRequired = Config.getInstance().getPTPCommandConfirmRequired();
+ confirmRequired = mcMMO.p.getGeneralConfig().getPTPCommandConfirmRequired();
timeout = 0;
lastUse = 0;
}
diff --git a/src/main/java/com/gmail/nossr50/party/ShareHandler.java b/src/main/java/com/gmail/nossr50/party/ShareHandler.java
index 426e0814c..883bfbabf 100644
--- a/src/main/java/com/gmail/nossr50/party/ShareHandler.java
+++ b/src/main/java/com/gmail/nossr50/party/ShareHandler.java
@@ -3,6 +3,7 @@ package com.gmail.nossr50.party;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.mcMMO;
import com.neetgames.mcmmo.experience.XPGainReason;
import com.neetgames.mcmmo.experience.XPGainSource;
import com.neetgames.mcmmo.party.Party;
@@ -38,7 +39,7 @@ public final class ShareHandler {
nearMembers.add(mmoPlayer.getPlayer());
int partySize = nearMembers.size();
- double shareBonus = Math.min(Config.getInstance().getPartyShareBonusBase() + (partySize * Config.getInstance().getPartyShareBonusIncrease()), Config.getInstance().getPartyShareBonusCap());
+ double shareBonus = Math.min(mcMMO.p.getGeneralConfig().getPartyShareBonusBase() + (partySize * mcMMO.p.getGeneralConfig().getPartyShareBonusIncrease()), mcMMO.p.getGeneralConfig().getPartyShareBonusCap());
float splitXp = (float) (xp / partySize * shareBonus);
for (Player otherMember : nearMembers) {
diff --git a/src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java b/src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java
index 52b01e34f..b7630ea4f 100644
--- a/src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.backups;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.scheduler.BukkitRunnable;
@@ -48,11 +47,11 @@ public class CleanBackupsTask extends BukkitRunnable {
int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
int year = cal.get(Calendar.YEAR);
- if (isPast24Hours(date) && Config.getInstance().getKeepLast24Hours()) {
+ if (isPast24Hours(date) && mcMMO.p.getGeneralConfig().getKeepLast24Hours()) {
// Keep all files from the last 24 hours
continue;
}
- else if (isLastWeek(date) && !savedDays.contains(dayOfWeek) && Config.getInstance().getKeepDailyLastWeek()) {
+ else if (isLastWeek(date) && !savedDays.contains(dayOfWeek) && mcMMO.p.getGeneralConfig().getKeepDailyLastWeek()) {
// Keep daily backups of the past week
savedDays.add(dayOfWeek);
continue;
@@ -60,7 +59,7 @@ public class CleanBackupsTask extends BukkitRunnable {
else {
List savedWeeks = savedYearsWeeks.computeIfAbsent(year, k -> new ArrayList<>());
- if (!savedWeeks.contains(weekOfYear) && Config.getInstance().getKeepWeeklyPastMonth()) {
+ if (!savedWeeks.contains(weekOfYear) && mcMMO.p.getGeneralConfig().getKeepWeeklyPastMonth()) {
// Keep one backup of each week
savedWeeks.add(weekOfYear);
continue;
diff --git a/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java b/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java
index 353e0ea04..8b3c96dfe 100644
--- a/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java
@@ -1,10 +1,10 @@
package com.gmail.nossr50.runnables.commands;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
+import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@@ -30,7 +30,7 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
@Override
public void run() {
- if (useBoard && Config.getInstance().getScoreboardsEnabled()) {
+ if (useBoard && mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
displayBoard();
}
@@ -47,13 +47,13 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
- for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
-// if (!skill.getPermissions(player)) {
+ for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
+// if (!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, skill)) {
// continue;
// }
rank = skills.get(skill);
- sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", skill.getName(), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
+ sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", mcMMO.p.getSkillTools().getLocalizedSkillName(skill), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));
}
rank = skills.get(null);
diff --git a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java
index 6af50d467..8bbec1606 100644
--- a/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.commands;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -36,7 +35,7 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
@Override
public void run() {
- if (useBoard && Config.getInstance().getScoreboardsEnabled()) {
+ if (useBoard && mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
displayBoard();
}
@@ -62,10 +61,10 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
}
else {
if(sender instanceof Player) {
- sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", primarySkillType.getName()));
+ sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", mcMMO.p.getSkillTools().getLocalizedSkillName(skill)));
}
else {
- sender.sendMessage(ChatColor.stripColor(LocaleLoader.getString("Commands.Skill.Leaderboard", primarySkillType.getName())));
+ sender.sendMessage(ChatColor.stripColor(LocaleLoader.getString("Commands.Skill.Leaderboard", mcMMO.p.getSkillTools().getLocalizedSkillName(skill))));
}
}
diff --git a/src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java b/src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java
index 337999308..4ade25c8c 100644
--- a/src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java
@@ -10,6 +10,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
@@ -57,7 +58,7 @@ public class FormulaConversionTask extends BukkitRunnable {
private void editValues(PlayerProfile profile) {
mcMMO.p.debug("========================================================================");
mcMMO.p.debug("Conversion report for " + profile.getPlayerName() + ":");
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
int oldLevel = profile.getSkillLevel(primarySkillType);
int oldXPLevel = profile.getSkillXpLevel(primarySkillType);
int totalOldXP = mcMMO.getFormulaManager().calculateTotalExperience(oldLevel, oldXPLevel);
diff --git a/src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java b/src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java
index 8ce66bfa8..cf570e3f2 100644
--- a/src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.database;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.mcMMO;
import org.bukkit.scheduler.BukkitRunnable;
@@ -13,7 +12,7 @@ public class UserPurgeTask extends BukkitRunnable {
lock.lock();
mcMMO.getDatabaseManager().purgePowerlessUsers();
- if (Config.getInstance().getOldUsersCutoff() != -1) {
+ if (mcMMO.p.getGeneralConfig().getOldUsersCutoff() != -1) {
mcMMO.getDatabaseManager().purgeOldUsers();
}
lock.unlock();
diff --git a/src/main/java/com/gmail/nossr50/runnables/items/ChimaeraWingWarmup.java b/src/main/java/com/gmail/nossr50/runnables/items/ChimaeraWingWarmup.java
index 943aac775..7feaf8a97 100644
--- a/src/main/java/com/gmail/nossr50/runnables/items/ChimaeraWingWarmup.java
+++ b/src/main/java/com/gmail/nossr50/runnables/items/ChimaeraWingWarmup.java
@@ -1,8 +1,8 @@
package com.gmail.nossr50.runnables.items;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.ChimaeraWing;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Misc;
@@ -36,13 +36,13 @@ public class ChimaeraWingWarmup extends BukkitRunnable {
ItemStack inHand = player.getInventory().getItemInMainHand();
- if (!ItemUtils.isChimaeraWing(inHand) || inHand.getAmount() < Config.getInstance().getChimaeraUseCost()) {
+ if (!ItemUtils.isChimaeraWing(inHand) || inHand.getAmount() < mcMMO.p.getGeneralConfig().getChimaeraUseCost()) {
player.sendMessage(LocaleLoader.getString("Skills.NeedMore", LocaleLoader.getString("Item.ChimaeraWing.Name")));
return;
}
long recentlyHurt = mmoPlayer.getRecentlyHurtTimestamp();
- int hurtCooldown = Config.getInstance().getChimaeraRecentlyHurtCooldown();
+ int hurtCooldown = mcMMO.p.getGeneralConfig().getChimaeraRecentlyHurtCooldown();
if (hurtCooldown > 0) {
int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, player);
diff --git a/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java b/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java
index 904c84165..78f810231 100644
--- a/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java
+++ b/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java
@@ -1,9 +1,9 @@
package com.gmail.nossr50.runnables.items;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
@@ -42,7 +42,7 @@ public class TeleportationWarmup extends BukkitRunnable {
return;
}
- int hurtCooldown = Config.getInstance().getPTPCommandRecentlyHurtCooldown();
+ int hurtCooldown = mcMMO.p.getGeneralConfig().getPTPCommandRecentlyHurtCooldown();
if (hurtCooldown > 0) {
int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, teleportingPlayer);
@@ -53,7 +53,7 @@ public class TeleportationWarmup extends BukkitRunnable {
}
}
- if (Config.getInstance().getPTPCommandWorldPermissions()) {
+ if (mcMMO.p.getGeneralConfig().getPTPCommandWorldPermissions()) {
World targetWorld = targetPlayer.getWorld();
World playerWorld = teleportingPlayer.getWorld();
diff --git a/src/main/java/com/gmail/nossr50/runnables/party/PartyAutoKickTask.java b/src/main/java/com/gmail/nossr50/runnables/party/PartyAutoKickTask.java
index a7174da25..d5c586623 100644
--- a/src/main/java/com/gmail/nossr50/runnables/party/PartyAutoKickTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/party/PartyAutoKickTask.java
@@ -13,7 +13,7 @@ import java.util.Map.Entry;
import java.util.UUID;
public class PartyAutoKickTask extends BukkitRunnable {
- private final static long KICK_TIME = 24L * 60L * 60L * 1000L * Config.getInstance().getAutoPartyKickTime();
+ private final static long KICK_TIME = 24L * 60L * 60L * 1000L * mcMMO.p.getGeneralConfig().getAutoPartyKickTime();
@Override
public void run() {
diff --git a/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java b/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java
index 8944fb043..5a82b43da 100644
--- a/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/player/PlayerProfileLoadingTask.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.runnables.player;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -42,7 +41,7 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
return;
}
- PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getUniqueId(), player.getName());
+ PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player);
if(!profile.isLoaded()) {
mcMMO.p.getLogger().info("Creating new data for player: "+player.getName());
@@ -93,20 +92,22 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
return;
}
+ mcMMOPlayer.getProfile().updateLastLogin();
+
mcMMOPlayer.setupPartyData();
UserManager.track(mcMMOPlayer);
mcMMOPlayer.actualizeRespawnATS();
- if (Config.getInstance().getScoreboardsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getScoreboardsEnabled()) {
ScoreboardManager.setupPlayer(player);
- if (Config.getInstance().getShowStatsAfterLogin()) {
+ if (mcMMO.p.getGeneralConfig().getShowStatsAfterLogin()) {
ScoreboardManager.enablePlayerStatsScoreboard(player);
new McScoreboardKeepTask(player).runTaskLater(mcMMO.p, Misc.TICK_CONVERSION_FACTOR);
}
}
- if (Config.getInstance().getShowProfileLoadedMessage()) {
+ if (mcMMO.p.getGeneralConfig().getShowProfileLoadedMessage()) {
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
}
diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java
index da93d5dfc..2b31e55d2 100644
--- a/src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/skills/AbilityDisableTask.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.runnables.skills;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
@@ -41,7 +39,7 @@ public class AbilityDisableTask extends BukkitRunnable {
// Fallthrough
case BERSERK:
- if (Config.getInstance().getRefreshChunksEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getRefreshChunksEnabled()) {
resendChunkRadiusAt(player);
}
// Fallthrough
@@ -62,10 +60,12 @@ public class AbilityDisableTask extends BukkitRunnable {
NotificationManager.sendPlayerInformation(player, NotificationType.ABILITY_OFF, ability.getAbilityOff());
}
- if (AdvancedConfig.getInstance().sendAbilityNotificationToOtherPlayers()) {
+ if (mcMMO.p.getAdvancedConfig().sendAbilityNotificationToOtherPlayers()) {
SkillUtils.sendSkillMessage(player, NotificationType.SUPER_ABILITY_ALERT_OTHERS, ability.getAbilityPlayerOff());
}
- new AbilityCooldownTask(mmoPlayer, ability).runTaskLater(mcMMO.p, PerksUtils.handleCooldownPerks(player, ability.getCooldown()) * Misc.TICK_CONVERSION_FACTOR);
+ if(!mcMMO.isServerShutdownExecuted()) {
+ new AbilityCooldownTask(mmoPlayer, ability).runTaskLater(mcMMO.p, PerksUtils.handleCooldownPerks(player, ability.getCooldown()) * Misc.TICK_CONVERSION_FACTOR);
+ }
}
private void resendChunkRadiusAt(Player player) {
diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java
index 49298c2bb..839358afd 100644
--- a/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/skills/BleedTimerTask.java
@@ -57,7 +57,7 @@
// double damage;
//
// if (target instanceof Player) {
-// damage = AdvancedConfig.getInstance().getRuptureDamagePlayer();
+// damage = mcMMO.p.getAdvancedConfig().getRuptureDamagePlayer();
//
// //Above Bleed Rank 3 deals 50% more damage
// if (containerEntry.getValue().toolTier >= 4 && containerEntry.getValue().bleedRank >= 3)
@@ -78,7 +78,7 @@
// }
//
// } else {
-// damage = AdvancedConfig.getInstance().getRuptureDamageMobs();
+// damage = mcMMO.p.getAdvancedConfig().getRuptureDamageMobs();
//
//// debugMessage+="BaseDMG=["+damage+"], ";
//
diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java
index 9e4f3ee2b..e740a3fcd 100644
--- a/src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java
@@ -1,9 +1,7 @@
package com.gmail.nossr50.runnables.skills;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.util.MobHealthbarUtils;
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
import com.google.common.base.Objects;
import org.bukkit.entity.LivingEntity;
@@ -28,7 +26,7 @@ public class RuptureTask extends BukkitRunnable {
public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, double pureTickDamage, double explosionDamage) {
this.ruptureSource = ruptureSource;
this.targetEntity = targetEntity;
- this.expireTick = AdvancedConfig.getInstance().getRuptureDurationSeconds(targetEntity instanceof Player) * 20;
+ this.expireTick = mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(targetEntity instanceof Player) * 20;
this.ruptureTick = 0;
this.damageTickTracker = 0;
diff --git a/src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java b/src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java
index fc1e4e797..2dd8a8990 100644
--- a/src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java
+++ b/src/main/java/com/gmail/nossr50/runnables/skills/ToolLowerTask.java
@@ -1,8 +1,8 @@
package com.gmail.nossr50.runnables.skills;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.AbilityToolType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.NotificationManager;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
import org.bukkit.scheduler.BukkitRunnable;
@@ -24,7 +24,7 @@ public class ToolLowerTask extends BukkitRunnable {
mmoPlayer.getSuperAbilityManager().setAbilityToolPrime(tool, false);
- if (Config.getInstance().getAbilityMessagesEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getAbilityMessagesEnabled()) {
NotificationManager.sendPlayerInformation(Misc.adaptPlayer(mmoPlayer), NotificationType.TOOL, tool.getLowerToolLocaleKey());
}
}
diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java
index 1c72521f8..60f948d90 100644
--- a/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java
+++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/Acrobatics.java
@@ -1,13 +1,12 @@
package com.gmail.nossr50.skills.acrobatics;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.mcMMO;
public final class Acrobatics {
- public static double dodgeDamageModifier = AdvancedConfig.getInstance().getDodgeDamageModifier();
+ public static double dodgeDamageModifier = mcMMO.p.getAdvancedConfig().getDodgeDamageModifier();
public static int dodgeXpModifier = ExperienceConfig.getInstance().getDodgeXPModifier();
- public static boolean dodgeLightningDisabled = Config.getInstance().getDodgeLightningDisabled();
+ public static boolean dodgeLightningDisabled = mcMMO.p.getGeneralConfig().getDodgeLightningDisabled();
private Acrobatics() {}
diff --git a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java
index 40274a31f..a62593147 100644
--- a/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/acrobatics/AcrobaticsManager.java
@@ -72,7 +72,7 @@ public class AcrobaticsManager extends SkillManager {
return false;
}
- return skill.shouldProcess(damager);
+ return mcMMO.p.getSkillTools().canCombatSkillsTrigger(skill, damager);
}
return false;
diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java
index 58ac14bee..387a35550 100644
--- a/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java
+++ b/src/main/java/com/gmail/nossr50/skills/alchemy/Alchemy.java
@@ -1,10 +1,7 @@
package com.gmail.nossr50.skills.alchemy;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.skills.AlchemyBrewTask;
-import com.gmail.nossr50.util.skills.RankUtils;
import org.bukkit.Location;
import java.util.ArrayList;
@@ -43,16 +40,15 @@ public final class Alchemy {
}
protected int getLevel() {
- return AdvancedConfig.getInstance().getConcoctionsTierLevel(this);
+ return mcMMO.p.getAdvancedConfig().getConcoctionsTierLevel(this);
}
}*/
public static final int INGREDIENT_SLOT = 3;
- public static int catalysisUnlockLevel = RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS);
- public static int catalysisMaxBonusLevel = AdvancedConfig.getInstance().getCatalysisMaxBonusLevel();
- public static double catalysisMinSpeed = AdvancedConfig.getInstance().getCatalysisMinSpeed();
- public static double catalysisMaxSpeed = AdvancedConfig.getInstance().getCatalysisMaxSpeed();
+ public static int catalysisMaxBonusLevel = mcMMO.p.getAdvancedConfig().getCatalysisMaxBonusLevel();
+ public static double catalysisMinSpeed = mcMMO.p.getAdvancedConfig().getCatalysisMinSpeed();
+ public static double catalysisMaxSpeed = mcMMO.p.getAdvancedConfig().getCatalysisMaxSpeed();
public static Map brewingStandMap = new HashMap<>();
diff --git a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java
index 08a6db83d..aacf63be8 100644
--- a/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyManager.java
@@ -43,11 +43,11 @@ public class AlchemyManager extends SkillManager {
public double calculateBrewSpeed(boolean isLucky) {
int skillLevel = getSkillLevel();
- if (skillLevel < Alchemy.catalysisUnlockLevel) {
+ if (skillLevel < RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS)) {
return Alchemy.catalysisMinSpeed;
}
- return Math.min(Alchemy.catalysisMaxSpeed, Alchemy.catalysisMinSpeed + (Alchemy.catalysisMaxSpeed - Alchemy.catalysisMinSpeed) * (skillLevel - Alchemy.catalysisUnlockLevel) / (Alchemy.catalysisMaxBonusLevel - Alchemy.catalysisUnlockLevel)) * (isLucky ? LUCKY_MODIFIER : 1.0);
+ return Math.min(Alchemy.catalysisMaxSpeed, Alchemy.catalysisMinSpeed + (Alchemy.catalysisMaxSpeed - Alchemy.catalysisMinSpeed) * (skillLevel - RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS)) / (Alchemy.catalysisMaxBonusLevel - RankUtils.getUnlockLevel(SubSkillType.ALCHEMY_CATALYSIS))) * (isLucky ? LUCKY_MODIFIER : 1.0);
}
public void handlePotionBrewSuccesses(PotionStage potionStage, int amount) {
diff --git a/src/main/java/com/gmail/nossr50/skills/archery/Archery.java b/src/main/java/com/gmail/nossr50/skills/archery/Archery.java
index 7710a7bd3..b16456ec2 100644
--- a/src/main/java/com/gmail/nossr50/skills/archery/Archery.java
+++ b/src/main/java/com/gmail/nossr50/skills/archery/Archery.java
@@ -1,9 +1,9 @@
package com.gmail.nossr50.skills.archery;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.RankUtils;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
@@ -19,9 +19,9 @@ import java.util.List;
public class Archery {
private static final List trackedEntities = new ArrayList<>();
- public static double skillShotMaxBonusDamage = AdvancedConfig.getInstance().getSkillShotDamageMax();
+ public static double skillShotMaxBonusDamage = mcMMO.p.getAdvancedConfig().getSkillShotDamageMax();
- public static double dazeBonusDamage = AdvancedConfig.getInstance().getDazeBonusDamage();
+ public static double dazeBonusDamage = mcMMO.p.getAdvancedConfig().getDazeBonusDamage();
public static final double DISTANCE_XP_MULTIPLIER = ExperienceConfig.getInstance().getArcheryDistanceMultiplier();
@@ -71,6 +71,6 @@ public class Archery {
}
public static double getDamageBonusPercent(@NotNull OnlineMMOPlayer mmoPlayer) {
- return ((RankUtils.getRank(mmoPlayer, SubSkillType.ARCHERY_SKILL_SHOT)) * (AdvancedConfig.getInstance().getSkillShotRankDamageMultiplier()) / 100.0D);
+ return ((RankUtils.getRank(mmoPlayer, SubSkillType.ARCHERY_SKILL_SHOT)) * (mcMMO.p.getAdvancedConfig().getSkillShotRankDamageMultiplier()) / 100.0D);
}
}
diff --git a/src/main/java/com/gmail/nossr50/skills/axes/Axes.java b/src/main/java/com/gmail/nossr50/skills/axes/Axes.java
index 7f1ba62df..47d95be3f 100644
--- a/src/main/java/com/gmail/nossr50/skills/axes/Axes.java
+++ b/src/main/java/com/gmail/nossr50/skills/axes/Axes.java
@@ -1,7 +1,7 @@
package com.gmail.nossr50.skills.axes;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.skills.RankUtils;
import org.bukkit.entity.LivingEntity;
@@ -9,18 +9,18 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class Axes {
- public static double axeMasteryRankDamageMultiplier = AdvancedConfig.getInstance().getAxeMasteryRankDamageMultiplier();
+ public static double axeMasteryRankDamageMultiplier = mcMMO.p.getAdvancedConfig().getAxeMasteryRankDamageMultiplier();
- public static double criticalHitPVPModifier = AdvancedConfig.getInstance().getCriticalStrikesPVPModifier();
- public static double criticalHitPVEModifier = AdvancedConfig.getInstance().getCriticalStrikesPVEModifier();
+ public static double criticalHitPVPModifier = mcMMO.p.getAdvancedConfig().getCriticalStrikesPVPModifier();
+ public static double criticalHitPVEModifier = mcMMO.p.getAdvancedConfig().getCriticalStrikesPVEModifier();
- public static double impactChance = AdvancedConfig.getInstance().getImpactChance();
+ public static double impactChance = mcMMO.p.getAdvancedConfig().getImpactChance();
- public static double greaterImpactBonusDamage = AdvancedConfig.getInstance().getGreaterImpactBonusDamage();
- public static double greaterImpactChance = AdvancedConfig.getInstance().getGreaterImpactChance();
- public static double greaterImpactKnockbackMultiplier = AdvancedConfig.getInstance().getGreaterImpactModifier();
+ public static double greaterImpactBonusDamage = mcMMO.p.getAdvancedConfig().getGreaterImpactBonusDamage();
+ public static double greaterImpactChance = mcMMO.p.getAdvancedConfig().getGreaterImpactChance();
+ public static double greaterImpactKnockbackMultiplier = mcMMO.p.getAdvancedConfig().getGreaterImpactModifier();
- public static double skullSplitterModifier = AdvancedConfig.getInstance().getSkullSplitterModifier();
+ public static double skullSplitterModifier = mcMMO.p.getAdvancedConfig().getSkullSplitterModifier();
protected static boolean hasArmor(LivingEntity target) {
if(target == null || !target.isValid() || target.getEquipment() == null)
diff --git a/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java b/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java
index 3cfee3b39..99831c0bc 100644
--- a/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/axes/AxesManager.java
@@ -1,11 +1,12 @@
package com.gmail.nossr50.skills.axes;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.AbilityToolType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
+import com.gmail.nossr50.datatypes.skills.ToolType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.ItemUtils;
import com.gmail.nossr50.util.Permissions;
@@ -127,7 +128,7 @@ public class AxesManager extends SkillManager {
}
public double getImpactDurabilityDamage() {
- return AdvancedConfig.getInstance().getImpactDurabilityDamageMultiplier() * RankUtils.getRank(getPlayer(), SubSkillType.AXES_ARMOR_IMPACT);
+ return mcMMO.p.getAdvancedConfig().getImpactDurabilityDamageMultiplier() * RankUtils.getRank(getPlayer(), SubSkillType.AXES_ARMOR_IMPACT);
}
/**
diff --git a/src/main/java/com/gmail/nossr50/skills/child/ChildConfig.java b/src/main/java/com/gmail/nossr50/skills/child/ChildConfig.java
index 66e3b48e6..4944fb97c 100644
--- a/src/main/java/com/gmail/nossr50/skills/child/ChildConfig.java
+++ b/src/main/java/com/gmail/nossr50/skills/child/ChildConfig.java
@@ -2,6 +2,7 @@ package com.gmail.nossr50.skills.child;
import com.gmail.nossr50.config.AutoUpdateConfigLoader;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.text.StringUtils;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -16,12 +17,12 @@ public class ChildConfig extends AutoUpdateConfigLoader {
@Override
protected void loadKeys() {
- config.setDefaults(YamlConfiguration.loadConfiguration(plugin.getResourceAsReader("child.yml")));
+ config.setDefaults(YamlConfiguration.loadConfiguration(mcMMO.p.getResourceAsReader("child.yml")));
FamilyTree.clearRegistrations(); // when reloading, need to clear statics
- for (PrimarySkillType skill : PrimarySkillType.CHILD_SKILLS) {
- plugin.debug("Finding parents of " + skill.name());
+ for (PrimarySkillType skill : mcMMO.p.getSkillTools().CHILD_SKILLS) {
+ mcMMO.p.debug("Finding parents of " + skill.name());
EnumSet parentSkills = EnumSet.noneOf(PrimarySkillType.class);
boolean useDefaults = false; // If we had an error we back out and use defaults
@@ -33,7 +34,7 @@ public class ChildConfig extends AutoUpdateConfigLoader {
parentSkills.add(parentSkill);
}
catch (IllegalArgumentException ex) {
- plugin.getLogger().warning(name + " is not a valid skill type, or is a child skill!");
+ mcMMO.p.getLogger().warning(name + " is not a valid skill type, or is a child skill!");
useDefaults = true;
break;
}
@@ -52,7 +53,7 @@ public class ChildConfig extends AutoUpdateConfigLoader {
// Register them
for (PrimarySkillType parentSkill : parentSkills) {
- plugin.debug("Registering " + parentSkill.name() + " as parent of " + skill.name());
+ mcMMO.p.debug("Registering " + parentSkill.name() + " as parent of " + skill.name());
FamilyTree.registerParent(skill, parentSkill);
}
}
diff --git a/src/main/java/com/gmail/nossr50/skills/child/FamilyTree.java b/src/main/java/com/gmail/nossr50/skills/child/FamilyTree.java
index eb0e60d94..44e91fc41 100644
--- a/src/main/java/com/gmail/nossr50/skills/child/FamilyTree.java
+++ b/src/main/java/com/gmail/nossr50/skills/child/FamilyTree.java
@@ -5,6 +5,7 @@ import com.neetgames.mcmmo.exceptions.UnknownSkillException;
import com.neetgames.mcmmo.skill.RootSkill;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import com.gmail.nossr50.util.skills.SkillTools;
import java.util.HashSet;
import java.util.Set;
diff --git a/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java b/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java
index 6acad4c41..b7599ac61 100644
--- a/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/excavation/ExcavationManager.java
@@ -5,6 +5,7 @@ import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.treasure.ExcavationTreasure;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
@@ -97,6 +98,6 @@ public class ExcavationManager extends SkillManager {
excavationBlockCheck(blockState);
excavationBlockCheck(blockState);
- SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), Config.getInstance().getAbilityToolDamage());
+ SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.p.getGeneralConfig().getAbilityToolDamage());
}
}
diff --git a/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java b/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
index 28d8261a7..dab10cccf 100644
--- a/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java
@@ -1,8 +1,6 @@
package com.gmail.nossr50.skills.fishing;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.treasure.FishingTreasureConfig;
import com.gmail.nossr50.datatypes.experience.XPGainReason;
@@ -198,11 +196,11 @@ public class FishingManager extends SkillManager {
}
public double getShakeChance() {
- return AdvancedConfig.getInstance().getShakeChance(RankUtils.getRank(mmoPlayer.getPlayer(), SubSkillType.FISHING_SHAKE));
+ return mcMMO.p.getAdvancedConfig().getShakeChance(RankUtils.getRank(mmoPlayer.getPlayer(), SubSkillType.FISHING_SHAKE));
}
protected int getVanillaXPBoostModifier() {
- return AdvancedConfig.getInstance().getFishingVanillaXPModifier(getLootTier());
+ return mcMMO.p.getAdvancedConfig().getFishingVanillaXPModifier(getLootTier());
}
/**
@@ -273,8 +271,8 @@ public class FishingManager extends SkillManager {
int maxWaitReduction = getMasterAnglerTickMaxWaitReduction(masterAnglerRank, boatBonus, convertedLureBonus);
//Ticks for minWait and maxWait never go below this value
- int bonusCapMin = AdvancedConfig.getInstance().getFishingReductionMinWaitCap();
- int bonusCapMax = AdvancedConfig.getInstance().getFishingReductionMaxWaitCap();
+ int bonusCapMin = mcMMO.p.getAdvancedConfig().getFishingReductionMinWaitCap();
+ int bonusCapMax = mcMMO.p.getAdvancedConfig().getFishingReductionMaxWaitCap();
int reducedMinWaitTime = getReducedTicks(minWaitTicks, minWaitReduction, bonusCapMin);
int reducedMaxWaitTime = getReducedTicks(maxWaitTicks, maxWaitReduction, bonusCapMax);
@@ -337,7 +335,7 @@ public class FishingManager extends SkillManager {
}
public int getMasterAnglerTickMaxWaitReduction(int masterAnglerRank, boolean boatBonus, int emulatedLureBonus) {
- int totalBonus = AdvancedConfig.getInstance().getFishingReductionMaxWaitTicks() * masterAnglerRank;
+ int totalBonus = mcMMO.p.getAdvancedConfig().getFishingReductionMaxWaitTicks() * masterAnglerRank;
if(boatBonus) {
totalBonus += getFishingBoatMaxWaitReduction();
@@ -349,7 +347,7 @@ public class FishingManager extends SkillManager {
}
public int getMasterAnglerTickMinWaitReduction(int masterAnglerRank, boolean boatBonus) {
- int totalBonus = AdvancedConfig.getInstance().getFishingReductionMinWaitTicks() * masterAnglerRank;
+ int totalBonus = mcMMO.p.getAdvancedConfig().getFishingReductionMinWaitTicks() * masterAnglerRank;
if(boatBonus) {
totalBonus += getFishingBoatMinWaitReduction();
@@ -359,11 +357,11 @@ public class FishingManager extends SkillManager {
}
public int getFishingBoatMinWaitReduction() {
- return AdvancedConfig.getInstance().getFishingBoatReductionMinWaitTicks();
+ return mcMMO.p.getAdvancedConfig().getFishingBoatReductionMinWaitTicks();
}
public int getFishingBoatMaxWaitReduction() {
- return AdvancedConfig.getInstance().getFishingBoatReductionMaxWaitTicks();
+ return mcMMO.p.getAdvancedConfig().getFishingBoatReductionMaxWaitTicks();
}
public boolean isMagicHunterEnabled() {
@@ -386,7 +384,7 @@ public class FishingManager extends SkillManager {
FishingTreasure treasure = null;
boolean fishingSucceeds = false;
- if (Config.getInstance().getFishingDropsEnabled() && Permissions.isSubSkillEnabled(player, SubSkillType.FISHING_TREASURE_HUNTER)) {
+ if (mcMMO.p.getGeneralConfig().getFishingDropsEnabled() && Permissions.isSubSkillEnabled(player, SubSkillType.FISHING_TREASURE_HUNTER)) {
treasure = getFishingTreasure();
this.fishingCatch = null;
}
@@ -447,7 +445,7 @@ public class FishingManager extends SkillManager {
}
if(fishingSucceeds) {
- if (Config.getInstance().getFishingExtraFish()) {
+ if (mcMMO.p.getGeneralConfig().getFishingExtraFish()) {
Misc.spawnItem(player.getEyeLocation(), fishingCatch.getItemStack(), ItemSpawnReason.FISHING_EXTRA_FISH);
}
@@ -579,7 +577,7 @@ public class FishingManager extends SkillManager {
}
// Rather than subtracting luck (and causing a minimum 3% chance for every drop), scale by luck.
- diceRoll *= (1.0 - luck * Config.getInstance().getFishingLureModifier() / 100);
+ diceRoll *= (1.0 - luck * mcMMO.p.getGeneralConfig().getFishingLureModifier() / 100);
FishingTreasure treasure = null;
diff --git a/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java b/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java
index 2a688958f..d0aa99f43 100644
--- a/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/herbalism/HerbalismManager.java
@@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.herbalism;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.treasure.TreasureConfig;
import com.gmail.nossr50.datatypes.BlockSnapshot;
@@ -208,7 +207,7 @@ public class HerbalismManager extends SkillManager {
public void processHerbalismBlockBreakEvent(BlockBreakEvent blockBreakEvent) {
Player player = getPlayer();
- if (Config.getInstance().getHerbalismPreventAFK() && player.isInsideVehicle()) {
+ if (mcMMO.p.getGeneralConfig().getHerbalismPreventAFK() && player.isInsideVehicle()) {
return;
}
@@ -255,7 +254,7 @@ public class HerbalismManager extends SkillManager {
//TODO: The design of Green Terra needs to change, this is a mess
if(Permissions.greenThumbPlant(getPlayer(), originalBreak.getType())) {
- if(Config.getInstance().isGreenThumbReplantableCrop(originalBreak.getType())) {
+ if(mcMMO.p.getGeneralConfig().isGreenThumbReplantableCrop(originalBreak.getType())) {
if(!getPlayer().isSneaking()) {
greenThumbActivated = processGreenThumbPlants(originalBreak, blockBreakEvent, isGreenTerraActive());
}
diff --git a/src/main/java/com/gmail/nossr50/skills/mining/BlastMining.java b/src/main/java/com/gmail/nossr50/skills/mining/BlastMining.java
index 5c14999a1..a71b99d4c 100644
--- a/src/main/java/com/gmail/nossr50/skills/mining/BlastMining.java
+++ b/src/main/java/com/gmail/nossr50/skills/mining/BlastMining.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.skills.mining;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.skills.RankUtils;
@@ -32,7 +31,7 @@ public class BlastMining {
}
protected int getLevel() {
- return AdvancedConfig.getInstance().getBlastMiningRankLevel(this);
+ return mcMMO.p.getAdvancedConfig().getBlastMiningRankLevel(this);
}
@@ -41,13 +40,13 @@ public class BlastMining {
public final static int MAXIMUM_REMOTE_DETONATION_DISTANCE = 100;
public static double getBlastRadiusModifier(int rank) {
- return AdvancedConfig.getInstance().getBlastRadiusModifier(rank);
+ return mcMMO.p.getAdvancedConfig().getBlastRadiusModifier(rank);
}
public static double getBlastDamageDecrease(int rank) {
- return AdvancedConfig.getInstance().getBlastDamageDecrease(rank);
+ return mcMMO.p.getAdvancedConfig().getBlastDamageDecrease(rank);
}
diff --git a/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java b/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
index c48ff47dc..424760e7d 100644
--- a/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
@@ -1,8 +1,6 @@
package com.gmail.nossr50.skills.mining;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -47,7 +45,7 @@ public class MiningManager extends SkillManager {
Player player = getPlayer();
return canUseBlastMining() && player.isSneaking()
- && (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == Config.getInstance().getDetonatorItem())
+ && (ItemUtils.isPickaxe(getPlayer().getInventory().getItemInMainHand()) || player.getInventory().getItemInMainHand().getType() == mcMMO.p.getGeneralConfig().getDetonatorItem())
&& Permissions.remoteDetonation(player);
}
@@ -85,17 +83,17 @@ public class MiningManager extends SkillManager {
SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), Config.getInstance().getAbilityToolDamage());
}
- if(!Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || !canDoubleDrop())
+ if(!mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType()) || !canDoubleDrop())
return;
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);
- if(silkTouch && !AdvancedConfig.getInstance().getDoubleDropSilkTouchEnabled())
+ if(silkTouch && !mcMMO.p.getAdvancedConfig().getDoubleDropSilkTouchEnabled())
return;
//TODO: Make this readable
if (RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS, true)) {
- boolean useTriple = mmoPlayer.getAbilityMode(skill.getAbility()) && AdvancedConfig.getInstance().getAllowMiningTripleDrops();
+ boolean useTriple = mmoPlayer.getAbilityMode(mcMMO.p.getSkillTools().getSuperAbility(skill)) && mcMMO.p.getAdvancedConfig().getAllowMiningTripleDrops();
BlockUtils.markDropsAsBonus(blockState, useTriple);
}
}
@@ -158,8 +156,10 @@ public class MiningManager extends SkillManager {
//TODO: Rewrite this garbage
//TODO: Rewrite this garbage
public void blastMiningDropProcessing(float yield, EntityExplodeEvent event) {
- //Strip out only stuff that gives mining XP
+ if (yield == 0)
+ return;
+ //Strip out only stuff that gives mining XP
List ores = new ArrayList<>();
List notOres = new ArrayList<>();
@@ -248,11 +248,11 @@ public class MiningManager extends SkillManager {
}
public static double getOreBonus(int rank) {
- return AdvancedConfig.getInstance().getOreBonus(rank);
+ return mcMMO.p.getAdvancedConfig().getOreBonus(rank);
}
public static double getDebrisReduction(int rank) {
- return AdvancedConfig.getInstance().getDebrisReduction(rank);
+ return mcMMO.p.getAdvancedConfig().getDebrisReduction(rank);
}
/**
@@ -265,7 +265,7 @@ public class MiningManager extends SkillManager {
}
public static int getDropMultiplier(int rank) {
- return AdvancedConfig.getInstance().getDropMultiplier(rank);
+ return mcMMO.p.getAdvancedConfig().getDropMultiplier(rank);
}
/**
diff --git a/src/main/java/com/gmail/nossr50/skills/repair/ArcaneForging.java b/src/main/java/com/gmail/nossr50/skills/repair/ArcaneForging.java
index f7ea4fd70..05bcfb160 100644
--- a/src/main/java/com/gmail/nossr50/skills/repair/ArcaneForging.java
+++ b/src/main/java/com/gmail/nossr50/skills/repair/ArcaneForging.java
@@ -1,9 +1,9 @@
package com.gmail.nossr50.skills.repair;
-import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.mcMMO;
public class ArcaneForging {
- public static boolean arcaneForgingDowngrades = AdvancedConfig.getInstance().getArcaneForgingDowngradeEnabled();
- public static boolean arcaneForgingEnchantLoss = AdvancedConfig.getInstance().getArcaneForgingEnchantLossEnabled();
+ public static boolean arcaneForgingDowngrades = mcMMO.p.getAdvancedConfig().getArcaneForgingDowngradeEnabled();
+ public static boolean arcaneForgingEnchantLoss = mcMMO.p.getAdvancedConfig().getArcaneForgingEnchantLossEnabled();
}
diff --git a/src/main/java/com/gmail/nossr50/skills/repair/Repair.java b/src/main/java/com/gmail/nossr50/skills/repair/Repair.java
index 4ee346ea1..36ba8cdc5 100644
--- a/src/main/java/com/gmail/nossr50/skills/repair/Repair.java
+++ b/src/main/java/com/gmail/nossr50/skills/repair/Repair.java
@@ -1,13 +1,12 @@
package com.gmail.nossr50.skills.repair;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.Material;
public class Repair {
- public static int repairMasteryMaxBonusLevel = AdvancedConfig.getInstance().getMaxBonusLevel(SubSkillType.REPAIR_REPAIR_MASTERY);
- public static double repairMasteryMaxBonus = AdvancedConfig.getInstance().getRepairMasteryMaxBonus();
+ public static int repairMasteryMaxBonusLevel = mcMMO.p.getAdvancedConfig().getMaxBonusLevel(SubSkillType.REPAIR_REPAIR_MASTERY);
+ public static double repairMasteryMaxBonus = mcMMO.p.getAdvancedConfig().getRepairMasteryMaxBonus();
- public static Material anvilMaterial = Config.getInstance().getRepairAnvilMaterial();
+ public static Material anvilMaterial = mcMMO.p.getGeneralConfig().getRepairAnvilMaterial();
}
diff --git a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java
index 1e8997995..88a9aa045 100644
--- a/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/repair/RepairManager.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.skills.repair;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -50,11 +48,11 @@ public class RepairManager extends SkillManager {
return;
}
- if (Config.getInstance().getRepairAnvilMessagesEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getRepairAnvilMessagesEnabled()) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Repair.Listener.Anvil");
}
- if (Config.getInstance().getRepairAnvilPlaceSoundsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getRepairAnvilPlaceSoundsEnabled()) {
SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
}
@@ -152,7 +150,7 @@ public class RepairManager extends SkillManager {
* ExperienceConfig.getInstance().getRepairXP(repairable.getRepairMaterialType())), XPGainReason.PVE);
// BWONG BWONG BWONG
- if (Config.getInstance().getRepairAnvilUseSoundsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getRepairAnvilUseSoundsEnabled()) {
SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
}
@@ -174,7 +172,7 @@ public class RepairManager extends SkillManager {
Player player = getPlayer();
long lastUse = getLastAnvilUse();
- if (!SkillUtils.cooldownExpired(lastUse, 3) || !Config.getInstance().getRepairConfirmRequired()) {
+ if (!SkillUtils.cooldownExpired(lastUse, 3) || !mcMMO.p.getGeneralConfig().getRepairConfirmRequired()) {
return true;
}
@@ -203,7 +201,7 @@ public class RepairManager extends SkillManager {
* @return The chance of keeping the enchantment
*/
public double getKeepEnchantChance() {
- return AdvancedConfig.getInstance().getArcaneForgingKeepEnchantsChance(getArcaneForgingRank());
+ return mcMMO.p.getAdvancedConfig().getArcaneForgingKeepEnchantsChance(getArcaneForgingRank());
}
/**
@@ -212,7 +210,7 @@ public class RepairManager extends SkillManager {
* @return The chance of the enchantment being downgraded
*/
public double getDowngradeEnchantChance() {
- return AdvancedConfig.getInstance().getArcaneForgingDowngradeChance(getArcaneForgingRank());
+ return mcMMO.p.getAdvancedConfig().getArcaneForgingDowngradeChance(getArcaneForgingRank());
}
/*
diff --git a/src/main/java/com/gmail/nossr50/skills/salvage/Salvage.java b/src/main/java/com/gmail/nossr50/skills/salvage/Salvage.java
index 0e94b0589..4f510f909 100644
--- a/src/main/java/com/gmail/nossr50/skills/salvage/Salvage.java
+++ b/src/main/java/com/gmail/nossr50/skills/salvage/Salvage.java
@@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.salvage;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.Material;
public final class Salvage {
@@ -12,15 +11,15 @@ public final class Salvage {
*/
private Salvage() {}
- public static Material anvilMaterial = Config.getInstance().getSalvageAnvilMaterial();
+ public static Material anvilMaterial = mcMMO.p.getGeneralConfig().getSalvageAnvilMaterial();
- /*public static int salvageMaxPercentageLevel = AdvancedConfig.getInstance().getSalvageMaxPercentageLevel();
- public static double salvageMaxPercentage = AdvancedConfig.getInstance().getSalvageMaxPercentage();
+ /*public static int salvageMaxPercentageLevel = mcMMO.p.getAdvancedConfig().getSalvageMaxPercentageLevel();
+ public static double salvageMaxPercentage = mcMMO.p.getAdvancedConfig().getSalvageMaxPercentage();
public static int advancedSalvageUnlockLevel = RankUtils.getRankUnlockLevel(SubSkillType.SALVAGE_SCRAP_COLLECTOR, 1);*/
- public static boolean arcaneSalvageDowngrades = AdvancedConfig.getInstance().getArcaneSalvageEnchantDowngradeEnabled();
- public static boolean arcaneSalvageEnchantLoss = AdvancedConfig.getInstance().getArcaneSalvageEnchantLossEnabled();
+ public static boolean arcaneSalvageDowngrades = mcMMO.p.getAdvancedConfig().getArcaneSalvageEnchantDowngradeEnabled();
+ public static boolean arcaneSalvageEnchantLoss = mcMMO.p.getAdvancedConfig().getArcaneSalvageEnchantLossEnabled();
static int calculateSalvageableAmount(int currentDurability, short maxDurability, int baseAmount) {
double percentDamaged = (maxDurability <= 0) ? 1D : (double) (maxDurability - currentDurability) / maxDurability;
diff --git a/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java b/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java
index ff9a6de14..127880da3 100644
--- a/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/salvage/SalvageManager.java
@@ -1,8 +1,6 @@
package com.gmail.nossr50.skills.salvage;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -53,11 +51,11 @@ public class SalvageManager extends SkillManager {
return;
}
- if (Config.getInstance().getSalvageAnvilMessagesEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getSalvageAnvilMessagesEnabled()) {
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Listener.Anvil");
}
- if (Config.getInstance().getSalvageAnvilPlaceSoundsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getSalvageAnvilPlaceSoundsEnabled()) {
SoundManager.sendSound(player, player.getLocation(), SoundType.ANVIL);
}
@@ -168,7 +166,7 @@ public class SalvageManager extends SkillManager {
Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed, ItemSpawnReason.SALVAGE_MATERIALS);
// BWONG BWONG BWONG - CLUNK!
- if (Config.getInstance().getSalvageAnvilUseSoundsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getSalvageAnvilUseSoundsEnabled()) {
SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
}
@@ -220,11 +218,11 @@ public class SalvageManager extends SkillManager {
if(Permissions.hasSalvageEnchantBypassPerk(getPlayer()))
return 100.0D;
- return AdvancedConfig.getInstance().getArcaneSalvageExtractFullEnchantsChance(getArcaneSalvageRank());
+ return mcMMO.p.getAdvancedConfig().getArcaneSalvageExtractFullEnchantsChance(getArcaneSalvageRank());
}
public double getExtractPartialEnchantChance() {
- return AdvancedConfig.getInstance().getArcaneSalvageExtractPartialEnchantsChance(getArcaneSalvageRank());
+ return mcMMO.p.getAdvancedConfig().getArcaneSalvageExtractPartialEnchantsChance(getArcaneSalvageRank());
}
private ItemStack arcaneSalvageCheck(Map enchants) {
@@ -293,7 +291,7 @@ public class SalvageManager extends SkillManager {
Player player = getPlayer();
long lastUse = getLastAnvilUse();
- if (!SkillUtils.cooldownExpired(lastUse, 3) || !Config.getInstance().getSalvageConfirmRequired()) {
+ if (!SkillUtils.cooldownExpired(lastUse, 3) || !mcMMO.p.getGeneralConfig().getSalvageConfirmRequired()) {
return true;
}
diff --git a/src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java b/src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java
index f39fee051..ab29e2212 100644
--- a/src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/smelting/SmeltingManager.java
@@ -3,6 +3,7 @@ package com.gmail.nossr50.skills.smelting;
import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.RandomChanceUtil;
@@ -123,7 +124,7 @@ public class SmeltingManager extends SkillManager {
*/
//Process double smelt
- if (Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.SMELTING, resultItemStack.getType())
+ if (mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.SMELTING, resultItemStack.getType())
&& canDoubleSmeltItemStack(furnace) //Effectively two less than max stack size
&& isSecondSmeltSuccessful()) {
diff --git a/src/main/java/com/gmail/nossr50/skills/swords/Swords.java b/src/main/java/com/gmail/nossr50/skills/swords/Swords.java
index 0c2bd8fad..7dda504ea 100644
--- a/src/main/java/com/gmail/nossr50/skills/swords/Swords.java
+++ b/src/main/java/com/gmail/nossr50/skills/swords/Swords.java
@@ -1,9 +1,9 @@
package com.gmail.nossr50.skills.swords;
-import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.mcMMO;
public class Swords {
- public static double counterAttackModifier = AdvancedConfig.getInstance().getCounterModifier();
+ public static double counterAttackModifier = mcMMO.p.getAdvancedConfig().getCounterModifier();
- public static double serratedStrikesModifier = AdvancedConfig.getInstance().getSerratedStrikesModifier();
+ public static double serratedStrikesModifier = mcMMO.p.getAdvancedConfig().getSerratedStrikesModifier();
}
diff --git a/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java b/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java
index 37255a435..d7e26073d 100644
--- a/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.skills.swords;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.meta.RuptureTaskMeta;
import com.gmail.nossr50.datatypes.skills.AbilityToolType;
@@ -76,7 +75,7 @@ public class SwordsManager extends SkillManager {
return; //Don't apply bleed
}
- if (RandomChanceUtil.rollDice(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(getRuptureRank()), 100)) {
+ if (RandomChanceUtil.rollDice(mcMMO.p.getAdvancedConfig().getRuptureChanceToApplyOnHit(getRuptureRank()), 100)) {
if (target instanceof Player) {
Player defender = (Player) target;
@@ -91,8 +90,8 @@ public class SwordsManager extends SkillManager {
}
RuptureTask ruptureTask = new RuptureTask(mmoPlayer, target,
- AdvancedConfig.getInstance().getRuptureTickDamage(target instanceof Player, getRuptureRank()),
- AdvancedConfig.getInstance().getRuptureExplosionDamage(target instanceof Player, getRuptureRank()));
+ mcMMO.p.getAdvancedConfig().getRuptureTickDamage(target instanceof Player, getRuptureRank()),
+ mcMMO.p.getAdvancedConfig().getRuptureExplosionDamage(target instanceof Player, getRuptureRank()));
RuptureTaskMeta ruptureTaskMeta = new RuptureTaskMeta(mcMMO.p, ruptureTask);
@@ -136,7 +135,7 @@ public class SwordsManager extends SkillManager {
}
public int getRuptureBleedTicks(boolean isTargetPlayer) {
- return AdvancedConfig.getInstance().getRuptureDurationSeconds(isTargetPlayer) / RuptureTask.DAMAGE_TICK_INTERVAL;
+ return mcMMO.p.getAdvancedConfig().getRuptureDurationSeconds(isTargetPlayer) / RuptureTask.DAMAGE_TICK_INTERVAL;
}
/**
diff --git a/src/main/java/com/gmail/nossr50/skills/taming/Taming.java b/src/main/java/com/gmail/nossr50/skills/taming/Taming.java
index 1313c4c46..26ee15a67 100644
--- a/src/main/java/com/gmail/nossr50/skills/taming/Taming.java
+++ b/src/main/java/com/gmail/nossr50/skills/taming/Taming.java
@@ -1,20 +1,20 @@
package com.gmail.nossr50.skills.taming;
-import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.EntityEffect;
import org.bukkit.entity.*;
public class Taming {
- public static double fastFoodServiceActivationChance = AdvancedConfig.getInstance().getFastFoodChance();
+ public static double fastFoodServiceActivationChance = mcMMO.p.getAdvancedConfig().getFastFoodChance();
public static int goreBleedTicks = 2; //Equivalent to rank 1 in Rupture
- public static double goreModifier = AdvancedConfig.getInstance().getGoreModifier();
+ public static double goreModifier = mcMMO.p.getAdvancedConfig().getGoreModifier();
- public static double sharpenedClawsBonusDamage = AdvancedConfig.getInstance().getSharpenedClawsBonus();
+ public static double sharpenedClawsBonusDamage = mcMMO.p.getAdvancedConfig().getSharpenedClawsBonus();
- public static double shockProofModifier = AdvancedConfig.getInstance().getShockProofModifier();
+ public static double shockProofModifier = mcMMO.p.getAdvancedConfig().getShockProofModifier();
- public static double thickFurModifier = AdvancedConfig.getInstance().getThickFurModifier();
+ public static double thickFurModifier = mcMMO.p.getAdvancedConfig().getThickFurModifier();
public static boolean canPreventDamage(Tameable pet, AnimalTamer owner) {
return pet.isTamed() && owner instanceof Player && pet instanceof Wolf;
diff --git a/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java b/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
index 33bedb4c8..c009bc1f0 100644
--- a/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/taming/TamingManager.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.skills.taming;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -63,9 +61,9 @@ public class TamingManager extends SkillManager {
if(summoningItems == null) {
summoningItems = new HashMap<>();
- summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry()), CallOfTheWildType.CAT);
- summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry()), CallOfTheWildType.WOLF);
- summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry()), CallOfTheWildType.HORSE);
+ summoningItems.put(mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry()), CallOfTheWildType.CAT);
+ summoningItems.put(mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry()), CallOfTheWildType.WOLF);
+ summoningItems.put(mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry()), CallOfTheWildType.HORSE);
}
//TODO: Temporary static cache, will be changed in 2.2
@@ -74,11 +72,11 @@ public class TamingManager extends SkillManager {
cotwSummonDataProperties = new HashMap<>();
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
- Material itemSummonMaterial = Config.getInstance().getTamingCOTWMaterial(callOfTheWildType.getConfigEntityTypeEntry());
- int itemAmountRequired = Config.getInstance().getTamingCOTWCost(callOfTheWildType.getConfigEntityTypeEntry());
- int entitiesSummonedPerCOTW = Config.getInstance().getTamingCOTWAmount(callOfTheWildType.getConfigEntityTypeEntry());
- int summonLifespanSeconds = Config.getInstance().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
- int perPlayerMaxAmount = Config.getInstance().getTamingCOTWMaxAmount(callOfTheWildType.getConfigEntityTypeEntry());
+ Material itemSummonMaterial = mcMMO.p.getGeneralConfig().getTamingCOTWMaterial(callOfTheWildType.getConfigEntityTypeEntry());
+ int itemAmountRequired = mcMMO.p.getGeneralConfig().getTamingCOTWCost(callOfTheWildType.getConfigEntityTypeEntry());
+ int entitiesSummonedPerCOTW = mcMMO.p.getGeneralConfig().getTamingCOTWAmount(callOfTheWildType.getConfigEntityTypeEntry());
+ int summonLifespanSeconds = mcMMO.p.getGeneralConfig().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
+ int perPlayerMaxAmount = mcMMO.p.getGeneralConfig().getTamingCOTWMaxAmount(callOfTheWildType.getConfigEntityTypeEntry());
TamingSummon tamingSummon = new TamingSummon(callOfTheWildType, itemSummonMaterial, itemAmountRequired, entitiesSummonedPerCOTW, summonLifespanSeconds, perPlayerMaxAmount);
cotwSummonDataProperties.put(callOfTheWildType, tamingSummon);
@@ -272,7 +270,7 @@ public class TamingManager extends SkillManager {
if(!RankUtils.hasUnlockedSubskill(mmoPlayer, SubSkillType.TAMING_PUMMEL))
return;
- if(!RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(AdvancedConfig.getInstance().getPummelChance(), getPlayer(), SubSkillType.TAMING_PUMMEL)))
+ if(!RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkillStatic(mcMMO.p.getAdvancedConfig().getPummelChance(), getPlayer(), SubSkillType.TAMING_PUMMEL)))
return;
ParticleEffectUtils.playGreaterImpactEffect(target);
@@ -458,7 +456,7 @@ public class TamingManager extends SkillManager {
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
- horse.setJumpStrength(Math.max(AdvancedConfig.getInstance().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, AdvancedConfig.getInstance().getMaxHorseJumpStrength())));
+ horse.setJumpStrength(Math.max(mcMMO.p.getAdvancedConfig().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, mcMMO.p.getAdvancedConfig().getMaxHorseJumpStrength())));
horse.setAdult();
//TODO: setSpeed, once available
diff --git a/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java b/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java
index 9116c4fdf..79cd4802b 100644
--- a/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java
+++ b/src/main/java/com/gmail/nossr50/skills/taming/TrackedTamingEntity.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.skills.taming;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
@@ -19,7 +18,7 @@ public class TrackedTamingEntity extends BukkitRunnable {
this.callOfTheWildType = callOfTheWildType;
this.livingEntity = livingEntity;
- int tamingCOTWLength = Config.getInstance().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
+ int tamingCOTWLength = mcMMO.p.getGeneralConfig().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
if (tamingCOTWLength > 0) {
int length = tamingCOTWLength * Misc.TICK_CONVERSION_FACTOR;
diff --git a/src/main/java/com/gmail/nossr50/skills/unarmed/Unarmed.java b/src/main/java/com/gmail/nossr50/skills/unarmed/Unarmed.java
index a39cbccc5..cb1124dd4 100644
--- a/src/main/java/com/gmail/nossr50/skills/unarmed/Unarmed.java
+++ b/src/main/java/com/gmail/nossr50/skills/unarmed/Unarmed.java
@@ -1,6 +1,6 @@
package com.gmail.nossr50.skills.unarmed;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
import org.bukkit.entity.Player;
@@ -8,7 +8,7 @@ import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.inventory.ItemStack;
public class Unarmed {
- public static boolean blockCrackerSmoothBrick = Config.getInstance().getUnarmedBlockCrackerSmoothbrickToCracked();
+ public static boolean blockCrackerSmoothBrick = mcMMO.p.getGeneralConfig().getUnarmedBlockCrackerSmoothbrickToCracked();
public static double berserkDamageModifier = 1.5;
public static void handleItemPickup(Player player, EntityPickupItemEvent event) {
diff --git a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
index 35863772b..82029417f 100644
--- a/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
@@ -1,7 +1,6 @@
package com.gmail.nossr50.skills.unarmed;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.AbilityToolType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -112,7 +111,7 @@ public class UnarmedManager extends SkillManager {
Item item = Misc.spawnItem(defender.getLocation(), defender.getInventory().getItemInMainHand(), ItemSpawnReason.UNARMED_DISARMED_ITEM);
- if (item != null && AdvancedConfig.getInstance().getDisarmProtected()) {
+ if (item != null && mcMMO.p.getAdvancedConfig().getDisarmProtected()) {
item.setMetadata(mcMMO.disarmedItemKey, UserManager.queryPlayer(defender).getPlayerMetadata());
}
@@ -166,8 +165,8 @@ public class UnarmedManager extends SkillManager {
double finalBonus = bonus + 0.5 + (rank / 2);
- if(AdvancedConfig.getInstance().isSteelArmDamageCustom()) {
- return AdvancedConfig.getInstance().getSteelArmOverride(RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_STEEL_ARM_STYLE), finalBonus);
+ if(mcMMO.p.getAdvancedConfig().isSteelArmDamageCustom()) {
+ return mcMMO.p.getAdvancedConfig().getSteelArmOverride(RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_STEEL_ARM_STYLE), finalBonus);
} else {
return finalBonus;
}
diff --git a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java
index 2514a7a2f..e30213cef 100644
--- a/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java
+++ b/src/main/java/com/gmail/nossr50/skills/woodcutting/WoodcuttingManager.java
@@ -1,8 +1,6 @@
package com.gmail.nossr50.skills.woodcutting;
import com.gmail.nossr50.api.ItemSpawnReason;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -53,7 +51,7 @@ public class WoodcuttingManager extends SkillManager {
public WoodcuttingManager(OnlineMMOPlayer mmoPlayer) {
super(mmoPlayer, PrimarySkillType.WOODCUTTING);
- treeFellerThreshold = Config.getInstance().getTreeFellerThreshold();
+ treeFellerThreshold = mcMMO.p.getGeneralConfig().getTreeFellerThreshold();
}
public boolean canUseLeafBlower(ItemStack heldItem) {
@@ -71,7 +69,7 @@ public class WoodcuttingManager extends SkillManager {
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RankUtils.hasReachedRank(1, mmoPlayer, SubSkillType.WOODCUTTING_HARVEST_LUMBER)
&& RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.WOODCUTTING_HARVEST_LUMBER, getPlayer())
- && Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
+ && mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, material);
}
/**
@@ -108,6 +106,11 @@ public class WoodcuttingManager extends SkillManager {
treeFellerReachedThreshold = false;
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Woodcutting.Skills.TreeFeller.Threshold");
+
+ //Tree feller won't be activated for this block, award normal xp.
+ processWoodcuttingBlockXP(blockState);
+ processHarvestLumber(blockState);
+
return;
}
@@ -216,7 +219,7 @@ public class WoodcuttingManager extends SkillManager {
for (BlockState blockState : treeFellerBlocks) {
if (BlockUtils.hasWoodcuttingXP(blockState)) {
- durabilityLoss += Config.getInstance().getAbilityToolDamage();
+ durabilityLoss += mcMMO.p.getGeneralConfig().getAbilityToolDamage();
}
}
@@ -283,7 +286,7 @@ public class WoodcuttingManager extends SkillManager {
Block block = blockState.getBlock();
if (!EventUtils.simulateBlockBreak(block, player, true)) {
- break; // TODO: Shouldn't we use continue instead?
+ continue;
}
/*
@@ -306,7 +309,7 @@ public class WoodcuttingManager extends SkillManager {
Misc.spawnItemsFromCollection(Misc.getBlockCenter(blockState), block.getDrops(), ItemSpawnReason.TREE_FELLER_DISPLACED_BLOCK);
if(RankUtils.hasReachedRank(2, mmoPlayer, SubSkillType.WOODCUTTING_KNOCK_ON_WOOD)) {
- if(AdvancedConfig.getInstance().isKnockOnWoodXPOrbEnabled()) {
+ if(mcMMO.p.getAdvancedConfig().isKnockOnWoodXPOrbEnabled()) {
if(RandomChanceUtil.rollDice(10, 100)) {
int randOrbCount = Math.max(1, Misc.getRandom().nextInt(100));
Misc.spawnExperienceOrb(blockState.getLocation(), randOrbCount);
diff --git a/src/main/java/com/gmail/nossr50/util/BlockUtils.java b/src/main/java/com/gmail/nossr50/util/BlockUtils.java
index 8c5dd11c1..f8a2e9b47 100644
--- a/src/main/java/com/gmail/nossr50/util/BlockUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/BlockUtils.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.meta.BonusDropMeta;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -8,14 +7,17 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.repair.Repair;
import com.gmail.nossr50.skills.salvage.Salvage;
+import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
import com.gmail.nossr50.util.random.RandomChanceSkill;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import org.bukkit.Material;
+import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
@@ -53,7 +55,7 @@ public final class BlockUtils {
* @return true if the player succeeded in the check
*/
public static boolean checkDoubleDrops(Player player, BlockState blockState, PrimarySkillType skillType, SubSkillType subSkillType) {
- if (Config.getInstance().getDoubleDropsEnabled(skillType, blockState.getType()) && Permissions.isSubSkillEnabled(player, subSkillType)) {
+ if (mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(skillType, blockState.getType()) && Permissions.isSubSkillEnabled(player, subSkillType)) {
return RandomChanceUtil.checkRandomChanceExecutionSuccess(new RandomChanceSkill(player, subSkillType, true));
}
@@ -68,10 +70,10 @@ public final class BlockUtils {
*/
public static boolean shouldBeWatched(BlockState blockState) {
return affectedByGigaDrillBreaker(blockState) || affectedByGreenTerra(blockState) || affectedBySuperBreaker(blockState) || hasWoodcuttingXP(blockState)
- || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType())
- || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.EXCAVATION, blockState.getType())
- || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, blockState.getType())
- || Config.getInstance().getDoubleDropsEnabled(PrimarySkillType.SMELTING, blockState.getType());
+ || mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.MINING, blockState.getType())
+ || mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.EXCAVATION, blockState.getType())
+ || mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.WOODCUTTING, blockState.getType())
+ || mcMMO.p.getGeneralConfig().getDoubleDropsEnabled(PrimarySkillType.SMELTING, blockState.getType());
}
/**
@@ -339,4 +341,12 @@ public final class BlockUtils {
public static boolean isPartOfTree(Block rayCast) {
return hasWoodcuttingXP(rayCast.getState()) || isNonWoodPartOfTree(rayCast.getType());
}
+
+ public static boolean isWithinWorldBounds(@NotNull WorldCompatibilityLayer worldCompatibilityLayer, @NotNull Block block) {
+ World world = block.getWorld();
+
+ //World min height = inclusive | World max height = exclusive
+ return block.getY() >= worldCompatibilityLayer.getMinWorldHeight(world) && block.getY() < worldCompatibilityLayer.getMaxWorldHeight(world);
+ }
+
}
diff --git a/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java b/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java
index a5d4aeb9d..4a6c99300 100644
--- a/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java
+++ b/src/main/java/com/gmail/nossr50/util/ChimaeraWing.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.locale.LocaleLoader;
@@ -37,7 +36,7 @@ public final class ChimaeraWing {
* @param player Player whose item usage to check
*/
public static void activationCheck(Player player) {
- if (!Config.getInstance().getChimaeraEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getChimaeraEnabled()) {
return;
}
@@ -64,13 +63,13 @@ public final class ChimaeraWing {
int amount = inHand.getAmount();
- if (amount < Config.getInstance().getChimaeraUseCost()) {
- NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.ChimaeraWing.NotEnough",String.valueOf(Config.getInstance().getChimaeraUseCost() - amount), "Item.ChimaeraWing.Name");
+ if (amount < mcMMO.p.getGeneralConfig().getChimaeraUseCost()) {
+ NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.ChimaeraWing.NotEnough",String.valueOf(mcMMO.p.getGeneralConfig().getChimaeraUseCost() - amount), "Item.ChimaeraWing.Name");
return;
}
long lastTeleport = mmoPlayer.getChimeraWingLastUse();
- int cooldown = Config.getInstance().getChimaeraCooldown();
+ int cooldown = mcMMO.p.getGeneralConfig().getChimaeraCooldown();
if (cooldown > 0) {
int timeRemaining = SkillUtils.calculateTimeLeft(lastTeleport * Misc.TIME_CONVERSION_FACTOR, cooldown, player);
@@ -82,7 +81,7 @@ public final class ChimaeraWing {
}
long recentlyHurt = mmoPlayer.getRecentlyHurtTimestamp();
- int hurtCooldown = Config.getInstance().getChimaeraRecentlyHurtCooldown();
+ int hurtCooldown = mcMMO.p.getGeneralConfig().getChimaeraRecentlyHurtCooldown();
if (hurtCooldown > 0) {
int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, player);
@@ -95,9 +94,9 @@ public final class ChimaeraWing {
location = player.getLocation();
- if (Config.getInstance().getChimaeraPreventUseUnderground()) {
+ if (mcMMO.p.getGeneralConfig().getChimaeraPreventUseUnderground()) {
if (location.getY() < player.getWorld().getHighestBlockYAt(location)) {
- player.getInventory().setItemInMainHand(new ItemStack(getChimaeraWing(amount - Config.getInstance().getChimaeraUseCost())));
+ player.getInventory().setItemInMainHand(new ItemStack(getChimaeraWing(amount - mcMMO.p.getGeneralConfig().getChimaeraUseCost())));
NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.ChimaeraWing.Fail");
player.updateInventory();
player.setVelocity(new Vector(0, 0.5D, 0));
@@ -109,7 +108,7 @@ public final class ChimaeraWing {
mmoPlayer.actualizeTeleportCommenceLocation(player);
- long warmup = Config.getInstance().getChimaeraWarmup();
+ long warmup = mcMMO.p.getGeneralConfig().getChimaeraWarmup();
if (warmup > 0) {
NotificationManager.sendPlayerInformation(player, NotificationType.ITEM_MESSAGE, "Teleport.Commencing", String.valueOf(warmup));
@@ -123,7 +122,7 @@ public final class ChimaeraWing {
public static void chimaeraExecuteTeleport() {
Player player = Misc.adaptPlayer(mmoPlayer);
- if (Config.getInstance().getChimaeraUseBedSpawn() && player.getBedSpawnLocation() != null) {
+ if (mcMMO.p.getGeneralConfig().getChimaeraUseBedSpawn() && player.getBedSpawnLocation() != null) {
player.teleport(player.getBedSpawnLocation());
}
else {
@@ -136,12 +135,12 @@ public final class ChimaeraWing {
}
}
- player.getInventory().setItemInMainHand(new ItemStack(getChimaeraWing(player.getInventory().getItemInMainHand().getAmount() - Config.getInstance().getChimaeraUseCost())));
+ player.getInventory().setItemInMainHand(new ItemStack(getChimaeraWing(player.getInventory().getItemInMainHand().getAmount() - mcMMO.p.getGeneralConfig().getChimaeraUseCost())));
player.updateInventory();
mmoPlayer.actualizeChimeraWingLastUse();
mmoPlayer.setTeleportCommenceLocation(null);
- if (Config.getInstance().getChimaeraSoundEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getChimaeraSoundEnabled()) {
SoundManager.sendSound(player, location, SoundType.CHIMAERA_WING);
}
@@ -149,7 +148,7 @@ public final class ChimaeraWing {
}
public static ItemStack getChimaeraWing(int amount) {
- ItemStack itemStack = new ItemStack(Config.getInstance().getChimaeraItem(), amount);
+ ItemStack itemStack = new ItemStack(mcMMO.p.getGeneralConfig().getChimaeraItem(), amount);
ItemMeta itemMeta = itemStack.getItemMeta();
//noinspection ConstantConditions
@@ -165,8 +164,8 @@ public final class ChimaeraWing {
}
public static ShapelessRecipe getChimaeraWingRecipe() {
- Material ingredient = Config.getInstance().getChimaeraItem();
- int amount = Config.getInstance().getChimaeraRecipeCost();
+ Material ingredient = mcMMO.p.getGeneralConfig().getChimaeraItem();
+ int amount = mcMMO.p.getGeneralConfig().getChimaeraRecipeCost();
ShapelessRecipe chimeraWing = new ShapelessRecipe(new NamespacedKey(mcMMO.p, "Chimera"), getChimaeraWing(1));
chimeraWing.addIngredient(amount, ingredient);
diff --git a/src/main/java/com/gmail/nossr50/util/EventUtils.java b/src/main/java/com/gmail/nossr50/util/EventUtils.java
index e80cec0b8..614eeb926 100644
--- a/src/main/java/com/gmail/nossr50/util/EventUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/EventUtils.java
@@ -1,6 +1,8 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.experience.XPGainReason;
+import com.gmail.nossr50.datatypes.experience.XPGainSource;
+import com.gmail.nossr50.datatypes.party.Party;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -35,6 +37,7 @@ import com.gmail.nossr50.util.skills.CombatUtils;
import com.neetgames.mcmmo.experience.XPGainReason;
import com.neetgames.mcmmo.party.Party;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
+import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
@@ -405,10 +408,10 @@ public final class EventUtils {
experienceChanged = event.getExperienceChanged();
PlayerProfile playerProfile = UserManager.queryPlayer(player);
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
String skillName = primarySkillType.toString();
int playerSkillLevel = playerProfile.getSkillLevel(primarySkillType);
- int threshold = Config.getInstance().getHardcoreDeathStatPenaltyLevelThreshold();
+ int threshold = mcMMO.p.getGeneralConfig().getHardcoreDeathStatPenaltyLevelThreshold();
if(playerSkillLevel > threshold) {
playerProfile.modifySkill(primarySkillType, Math.max(threshold, playerSkillLevel - levelChanged.get(skillName)));
playerProfile.removeXp(primarySkillType, experienceChanged.get(skillName));
@@ -454,7 +457,7 @@ public final class EventUtils {
PlayerProfile victimProfile = UserManager.queryPlayer(victim);
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
String skillName = primarySkillType.toString();
int victimSkillLevel = victimProfile.getSkillLevel(primarySkillType);
@@ -478,7 +481,7 @@ public final class EventUtils {
}
public static McMMOPlayerAbilityDeactivateEvent callAbilityDeactivateEvent(Player player, SuperAbilityType ability) {
- McMMOPlayerAbilityDeactivateEvent event = new McMMOPlayerAbilityDeactivateEvent(player, PrimarySkillType.byAbility(ability));
+ McMMOPlayerAbilityDeactivateEvent event = new McMMOPlayerAbilityDeactivateEvent(player, mcMMO.p.getSkillTools().getPrimarySkillBySuperAbility(ability));
mcMMO.p.getServer().getPluginManager().callEvent(event);
return event;
diff --git a/src/main/java/com/gmail/nossr50/util/HardcoreManager.java b/src/main/java/com/gmail/nossr50/util/HardcoreManager.java
index 6290a962a..dfe4117ac 100644
--- a/src/main/java/com/gmail/nossr50/util/HardcoreManager.java
+++ b/src/main/java/com/gmail/nossr50/util/HardcoreManager.java
@@ -1,10 +1,12 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.NotificationManager;
+import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.gmail.nossr50.worldguard.WorldGuardUtils;
import org.bukkit.entity.Player;
@@ -21,8 +23,8 @@ public final class HardcoreManager {
return;
}
- double statLossPercentage = Config.getInstance().getHardcoreDeathStatPenaltyPercentage();
- int levelThreshold = Config.getInstance().getHardcoreDeathStatPenaltyLevelThreshold();
+ double statLossPercentage = mcMMO.p.getGeneralConfig().getHardcoreDeathStatPenaltyPercentage();
+ int levelThreshold = mcMMO.p.getGeneralConfig().getHardcoreDeathStatPenaltyLevelThreshold();
if(UserManager.queryPlayer(player) == null)
return;
@@ -33,8 +35,8 @@ public final class HardcoreManager {
HashMap levelChanged = new HashMap<>();
HashMap experienceChanged = new HashMap<>();
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
- if (!primarySkillType.getHardcoreStatLossEnabled()) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
+ if (!mcMMO.p.getGeneralConfig().getHardcoreStatLossEnabled(primarySkillType)) {
levelChanged.put(primarySkillType.toString(), 0);
experienceChanged.put(primarySkillType.toString(), 0F);
continue;
@@ -72,8 +74,8 @@ public final class HardcoreManager {
return;
}
- double vampirismStatLeechPercentage = Config.getInstance().getHardcoreVampirismStatLeechPercentage();
- int levelThreshold = Config.getInstance().getHardcoreVampirismLevelThreshold();
+ double vampirismStatLeechPercentage = mcMMO.p.getGeneralConfig().getHardcoreVampirismStatLeechPercentage();
+ int levelThreshold = mcMMO.p.getGeneralConfig().getHardcoreVampirismLevelThreshold();
if(UserManager.queryPlayer(killer) == null || UserManager.queryPlayer(victim) == null)
return;
@@ -85,8 +87,8 @@ public final class HardcoreManager {
HashMap levelChanged = new HashMap<>();
HashMap experienceChanged = new HashMap<>();
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
- if (!primarySkillType.getHardcoreVampirismEnabled()) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
+ if (!mcMMO.p.getGeneralConfig().getHardcoreVampirismEnabled(primarySkillType)) {
levelChanged.put(primarySkillType.toString(), 0);
experienceChanged.put(primarySkillType.toString(), 0F);
continue;
@@ -134,8 +136,8 @@ public final class HardcoreManager {
public static boolean isStatLossEnabled() {
boolean enabled = false;
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
- if (primarySkillType.getHardcoreStatLossEnabled()) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
+ if (mcMMO.p.getGeneralConfig().getHardcoreStatLossEnabled(primarySkillType)) {
enabled = true;
break;
}
@@ -152,8 +154,8 @@ public final class HardcoreManager {
public static boolean isVampirismEnabled() {
boolean enabled = false;
- for (PrimarySkillType primarySkillType : PrimarySkillType.NON_CHILD_SKILLS) {
- if (primarySkillType.getHardcoreVampirismEnabled()) {
+ for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
+ if (mcMMO.p.getGeneralConfig().getHardcoreVampirismEnabled(primarySkillType)) {
enabled = true;
break;
}
diff --git a/src/main/java/com/gmail/nossr50/util/ItemUtils.java b/src/main/java/com/gmail/nossr50/util/ItemUtils.java
index 4ae96356e..b0e780314 100644
--- a/src/main/java/com/gmail/nossr50/util/ItemUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/ItemUtils.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.config.party.ItemWeightConfig;
import com.gmail.nossr50.datatypes.treasure.EnchantmentWrapper;
@@ -233,7 +231,7 @@ public final class ItemUtils {
* @return true if the item counts as unarmed, false otherwise
*/
public static boolean isUnarmed(@NotNull ItemStack item) {
- if (Config.getInstance().getUnarmedItemsAsUnarmed()) {
+ if (mcMMO.p.getGeneralConfig().getUnarmedItemsAsUnarmed()) {
return !isMinecraftTool(item);
}
@@ -669,7 +667,7 @@ public final class ItemUtils {
if(itemMeta == null)
return;
- itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + AdvancedConfig.getInstance().getEnchantBuff(), true);
+ itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
itemStack.setItemMeta(itemMeta);
}
diff --git a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
index 9503c3ba6..8f2cd7f20 100644
--- a/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
+++ b/src/main/java/com/gmail/nossr50/util/MaterialMapStore.java
@@ -422,6 +422,7 @@ public class MaterialMapStore {
enchantables.addAll(pickAxes);
enchantables.addAll(tridents);
enchantables.addAll(bows);
+ enchantables.addAll(crossbows);
enchantables.add("shears");
enchantables.add("fishing_rod");
diff --git a/src/main/java/com/gmail/nossr50/util/Misc.java b/src/main/java/com/gmail/nossr50/util/Misc.java
index 8a83887f2..44ca57008 100644
--- a/src/main/java/com/gmail/nossr50/util/Misc.java
+++ b/src/main/java/com/gmail/nossr50/util/Misc.java
@@ -8,7 +8,6 @@ import com.google.common.collect.ImmutableSet;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.entity.*;
import org.bukkit.inventory.ItemStack;
@@ -259,12 +258,6 @@ public final class Misc {
}
}
- public static int getWorldMinCompat(World world)
- {
- // TODO this method should access the world min variable in a version safe manner so that we don't restrict usage to new versions of spigot only
- return 0;
- }
-
public static void printProgress(int convertedUsers, int progressInterval, long startMillis) {
if ((convertedUsers % progressInterval) == 0) {
mcMMO.p.getLogger().info(String.format("Conversion progress: %d users at %.2f users/second", convertedUsers, convertedUsers / (double) ((System.currentTimeMillis() - startMillis) / TIME_CONVERSION_FACTOR)));
diff --git a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java
index d6b032db4..6df53461e 100644
--- a/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/MobHealthbarUtils.java
@@ -1,6 +1,7 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.MobHealthbarType;
import com.gmail.nossr50.datatypes.meta.OldName;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.MobHealthDisplayUpdaterTask;
@@ -36,7 +37,7 @@ public final class MobHealthbarUtils {
* @param damage damage done by the attack triggering this
*/
public static void handleMobHealthbars(LivingEntity target, double damage, mcMMO plugin) {
- if (mcMMO.isHealthBarPluginEnabled() || !Config.getInstance().getMobHealthbarEnabled()) {
+ if (mcMMO.isHealthBarPluginEnabled() || !mcMMO.p.getGeneralConfig().getMobHealthbarEnabled()) {
return;
}
@@ -63,12 +64,12 @@ public final class MobHealthbarUtils {
}
boolean oldNameVisible = target.isCustomNameVisible();
- String newName = createHealthDisplay(Config.getInstance().getMobHealthbarDefault(), target, damage);
+ String newName = createHealthDisplay(mcMMO.p.getGeneralConfig().getMobHealthbarDefault(), target, damage);
target.setCustomName(newName);
target.setCustomNameVisible(true);
- int displayTime = Config.getInstance().getMobHealthbarTime();
+ int displayTime = mcMMO.p.getGeneralConfig().getMobHealthbarTime();
if (displayTime != -1) {
boolean updateName = !ChatColor.stripColor(oldName).equalsIgnoreCase(ChatColor.stripColor(newName));
diff --git a/src/main/java/com/gmail/nossr50/util/ModManager.java b/src/main/java/com/gmail/nossr50/util/ModManager.java
index 184b571b1..62646466a 100644
--- a/src/main/java/com/gmail/nossr50/util/ModManager.java
+++ b/src/main/java/com/gmail/nossr50/util/ModManager.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.mods.CustomArmorConfig;
import com.gmail.nossr50.config.mods.CustomBlockConfig;
import com.gmail.nossr50.config.mods.CustomEntityConfig;
@@ -89,67 +88,67 @@ public class ModManager {
}
public boolean isCustomBoots(Material material) {
- return Config.getInstance().getArmorModsEnabled() && customBoots.contains(material);
+ return mcMMO.p.getGeneralConfig().getArmorModsEnabled() && customBoots.contains(material);
}
public boolean isCustomChestplate(Material material) {
- return Config.getInstance().getArmorModsEnabled() && customChestplates.contains(material);
+ return mcMMO.p.getGeneralConfig().getArmorModsEnabled() && customChestplates.contains(material);
}
public boolean isCustomHelmet(Material material) {
- return Config.getInstance().getArmorModsEnabled() && customHelmets.contains(material);
+ return mcMMO.p.getGeneralConfig().getArmorModsEnabled() && customHelmets.contains(material);
}
public boolean isCustomLeggings(Material material) {
- return Config.getInstance().getArmorModsEnabled() && customLeggings.contains(material);
+ return mcMMO.p.getGeneralConfig().getArmorModsEnabled() && customLeggings.contains(material);
}
public boolean isCustomAxe(Material material) {
- return Config.getInstance().getToolModsEnabled() && customAxes.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customAxes.contains(material);
}
public boolean isCustomBow(Material material) {
- return Config.getInstance().getToolModsEnabled() && customBows.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customBows.contains(material);
}
public boolean isCustomHoe(Material material) {
- return Config.getInstance().getToolModsEnabled() && customHoes.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customHoes.contains(material);
}
public boolean isCustomPickaxe(Material material) {
- return Config.getInstance().getToolModsEnabled() && customPickaxes.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customPickaxes.contains(material);
}
public boolean isCustomShovel(Material material) {
- return Config.getInstance().getToolModsEnabled() && customShovels.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customShovels.contains(material);
}
public boolean isCustomSword(Material material) {
- return Config.getInstance().getToolModsEnabled() && customSwords.contains(material);
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && customSwords.contains(material);
}
public boolean isCustomOre(Material data) {
- return Config.getInstance().getBlockModsEnabled() && customOres.contains(data);
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customOres.contains(data);
}
public boolean isCustomLog(BlockState state) {
- return Config.getInstance().getBlockModsEnabled() && customLogs.contains(state.getType());
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customLogs.contains(state.getType());
}
public boolean isCustomAbilityBlock(BlockState state) {
- return Config.getInstance().getBlockModsEnabled() && customAbilityBlocks.contains(state.getType());
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customAbilityBlocks.contains(state.getType());
}
public boolean isCustomExcavationBlock(BlockState state) {
- return Config.getInstance().getBlockModsEnabled() && customExcavationBlocks.contains(state.getType());
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customExcavationBlocks.contains(state.getType());
}
public boolean isCustomHerbalismBlock(BlockState state) {
- return Config.getInstance().getBlockModsEnabled() && customHerbalismBlocks.contains(state.getType());
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customHerbalismBlocks.contains(state.getType());
}
public boolean isCustomMiningBlock(BlockState state) {
- return Config.getInstance().getBlockModsEnabled() && customMiningBlocks.contains(state.getType());
+ return mcMMO.p.getGeneralConfig().getBlockModsEnabled() && customMiningBlocks.contains(state.getType());
}
public CustomBlock getBlock(BlockState state) {
@@ -167,7 +166,7 @@ public class ModManager {
* @return true if the item is a custom tool, false otherwise
*/
public boolean isCustomTool(ItemStack item) {
- return Config.getInstance().getToolModsEnabled() && item != null && customToolMap.containsKey(item.getType());
+ return mcMMO.p.getGeneralConfig().getToolModsEnabled() && item != null && customToolMap.containsKey(item.getType());
}
/**
@@ -185,7 +184,7 @@ public class ModManager {
}
public boolean isCustomEntity(Entity entity) {
- if (!Config.getInstance().getEntityModsEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getEntityModsEnabled()) {
return false;
}
@@ -227,7 +226,7 @@ public class ModManager {
}
public void addCustomEntity(Entity entity) {
- if (!Config.getInstance().getEntityModsEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getEntityModsEnabled()) {
return;
}
diff --git a/src/main/java/com/gmail/nossr50/util/Motd.java b/src/main/java/com/gmail/nossr50/util/Motd.java
index ac3fd4e70..ddad205c0 100644
--- a/src/main/java/com/gmail/nossr50/util/Motd.java
+++ b/src/main/java/com/gmail/nossr50/util/Motd.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
@@ -70,11 +69,11 @@ public final class Motd {
player.sendMessage(LocaleLoader.getString("MOTD.Hardcore.Enabled", statLossInfo + seperator + vampirismInfo));
if (deathStatLossEnabled) {
- player.sendMessage(LocaleLoader.getString("MOTD.Hardcore.DeathStatLoss.Stats", Config.getInstance().getHardcoreDeathStatPenaltyPercentage()));
+ player.sendMessage(LocaleLoader.getString("MOTD.Hardcore.DeathStatLoss.Stats", mcMMO.p.getGeneralConfig().getHardcoreDeathStatPenaltyPercentage()));
}
if (vampirismEnabled) {
- player.sendMessage(LocaleLoader.getString("MOTD.Hardcore.Vampirism.Stats", Config.getInstance().getHardcoreVampirismStatLeechPercentage()));
+ player.sendMessage(LocaleLoader.getString("MOTD.Hardcore.Vampirism.Stats", mcMMO.p.getGeneralConfig().getHardcoreVampirismStatLeechPercentage()));
}
}
diff --git a/src/main/java/com/gmail/nossr50/util/Permissions.java b/src/main/java/com/gmail/nossr50/util/Permissions.java
index 3d8026311..0e9f3d079 100644
--- a/src/main/java/com/gmail/nossr50/util/Permissions.java
+++ b/src/main/java/com/gmail/nossr50/util/Permissions.java
@@ -27,7 +27,6 @@ public final class Permissions {
*/
public static boolean motd(Permissible permissible) { return permissible.hasPermission("mcmmo.motd"); }
public static boolean levelUpBroadcast(Permissible permissible) { return permissible.hasPermission("mcmmo.broadcast.levelup"); }
- public static boolean mobHealthDisplay(Permissible permissible) { return permissible.hasPermission("mcmmo.mobhealthdisplay"); }
public static boolean updateNotifications(Permissible permissible) {return permissible.hasPermission("mcmmo.tools.updatecheck"); }
public static boolean chimaeraWing(Permissible permissible) { return permissible.hasPermission("mcmmo.item.chimaerawing"); }
public static boolean showversion(Permissible permissible) { return permissible.hasPermission("mcmmo.showversion"); }
@@ -35,8 +34,6 @@ public final class Permissions {
/* BYPASS */
public static boolean hardcoreBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.hardcoremode"); }
public static boolean arcaneBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.arcanebypass"); }
- public static boolean krakenBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.kraken"); }
- public static boolean trapsBypass(Permissible permissible) { return permissible.hasPermission("mcmmo.bypass.fishingtraps"); }
/* CHAT */
public static boolean partyChat(Permissible permissible) { return permissible.hasPermission("mcmmo.chat.partychat"); }
@@ -61,9 +58,6 @@ public final class Permissions {
public static boolean inspectFar(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.far")); }
public static boolean inspectHidden(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.inspect.hidden")); }
- public static boolean kraken(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.kraken"); }
- public static boolean krakenOthers(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.kraken.others"); }
-
public static boolean mcability(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability")); }
public static boolean mcabilityOthers(Permissible permissible) { return (permissible.hasPermission("mcmmo.commands.mcability.others")); }
@@ -99,9 +93,6 @@ public final class Permissions {
public static boolean xprateSet(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.xprate.set"); }
public static boolean xprateReset(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.xprate.reset"); }
- public static boolean vampirismModify(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.vampirism.modify"); }
- public static boolean vampirismToggle(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.vampirism.toggle"); }
-
public static boolean mcpurge(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcpurge"); }
public static boolean mcremove(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mcremove"); }
public static boolean mmoupdate(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.mmoupdate"); }
@@ -176,7 +167,6 @@ public final class Permissions {
public static boolean vanillaXpBoost(Permissible permissible, PrimarySkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase(Locale.ENGLISH) + ".vanillaxpboost"); }
public static boolean isSubSkillEnabled(Permissible permissible, SubSkillType subSkillType) { return permissible.hasPermission(subSkillType.getPermissionNodeAddress()); }
public static boolean isSubSkillEnabled(Permissible permissible, AbstractSubSkill abstractSubSkill) { return permissible.hasPermission(abstractSubSkill.getPermissionNode()); }
- public static boolean bonusDamage(Permissible permissible, PrimarySkillType skill) { return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase(Locale.ENGLISH) + ".bonusdamage"); }
/* ACROBATICS */
public static boolean dodge(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.acrobatics.dodge"); }
@@ -213,7 +203,6 @@ public final class Permissions {
public static boolean repairMaterialType(Permissible permissible, MaterialType repairMaterialType) { return permissible.hasPermission("mcmmo.ability.repair." + repairMaterialType.toString().toLowerCase(Locale.ENGLISH) + "repair"); }
/* SALVAGE */
- public static boolean advancedSalvage(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.salvage.advancedsalvage"); }
public static boolean arcaneSalvage(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.salvage.arcanesalvage"); }
public static boolean salvageItemType(Permissible permissible, ItemType salvageItemType) { return permissible.hasPermission("mcmmo.ability.salvage." + salvageItemType.toString().toLowerCase(Locale.ENGLISH) + "salvage"); }
diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/BitSetChunkStore.java b/src/main/java/com/gmail/nossr50/util/blockmeta/BitSetChunkStore.java
index 4830c9045..d850cec06 100644
--- a/src/main/java/com/gmail/nossr50/util/blockmeta/BitSetChunkStore.java
+++ b/src/main/java/com/gmail/nossr50/util/blockmeta/BitSetChunkStore.java
@@ -1,6 +1,6 @@
package com.gmail.nossr50.util.blockmeta;
-import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.mcMMO;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
@@ -25,7 +25,7 @@ public class BitSetChunkStore implements ChunkStore {
private transient boolean dirty = false;
public BitSetChunkStore(@NotNull World world, int cx, int cz) {
- this(world.getUID(), Misc.getWorldMinCompat(world), world.getMaxHeight(), cx, cz);
+ this(world.getUID(), mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(world), world.getMaxHeight(), cx, cz);
}
private BitSetChunkStore(@NotNull UUID worldUid, int worldMin, int worldMax, int cx, int cz) {
@@ -109,15 +109,14 @@ public class BitSetChunkStore implements ChunkStore {
return (z * 16 + x) + (256 * (y + yOffset));
}
- private static int getWorldMin(@NotNull UUID worldUid, int storedWorldMin)
- {
+ private static int getWorldMin(@NotNull UUID worldUid, int storedWorldMin) {
World world = Bukkit.getWorld(worldUid);
// Not sure how this case could come up, but might as well handle it gracefully. Loading a chunkstore for an unloaded world?
if (world == null)
return storedWorldMin;
- return Misc.getWorldMinCompat(world);
+ return mcMMO.getCompatibilityManager().getWorldCompatibilityLayer().getMinWorldHeight(world);
}
private static int getWorldMax(@NotNull UUID worldUid, int storedWorldMax)
diff --git a/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java b/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java
index e2c47662e..a1e61fd5c 100644
--- a/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java
+++ b/src/main/java/com/gmail/nossr50/util/blockmeta/ChunkManagerFactory.java
@@ -1,13 +1,12 @@
package com.gmail.nossr50.util.blockmeta;
-import com.gmail.nossr50.config.HiddenConfig;
+import com.gmail.nossr50.config.PersistentDataConfig;
import org.jetbrains.annotations.NotNull;
public class ChunkManagerFactory {
public static @NotNull ChunkManager getChunkManager() {
- HiddenConfig hConfig = HiddenConfig.getInstance();
- if (hConfig.getChunkletsEnabled()) {
+ if (PersistentDataConfig.getInstance().useBlockTracker()) {
return new HashChunkManager();
}
diff --git a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
index 4e1810d0a..2ab31c393 100644
--- a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
+++ b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
@@ -16,7 +16,6 @@ import com.gmail.nossr50.commands.party.PartyCommand;
import com.gmail.nossr50.commands.party.teleport.PtpCommand;
import com.gmail.nossr50.commands.player.*;
import com.gmail.nossr50.commands.skills.*;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
@@ -35,7 +34,7 @@ public final class CommandRegistrationManager {
private static void registerSkillCommands() {
for (PrimarySkillType skill : PrimarySkillType.values()) {
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
- String localizedName = skill.getName().toLowerCase(Locale.ENGLISH);
+ String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
PluginCommand command;
@@ -290,7 +289,7 @@ public final class CommandRegistrationManager {
private static void registerMcpurgeCommand() {
PluginCommand command = mcMMO.p.getCommand("mcpurge");
- command.setDescription(LocaleLoader.getString("Commands.Description.mcpurge", Config.getInstance().getOldUsersCutoff()));
+ command.setDescription(LocaleLoader.getString("Commands.Description.mcpurge", mcMMO.p.getGeneralConfig().getOldUsersCutoff()));
command.setPermission("mcmmo.commands.mcpurge");
command.setPermissionMessage(permissionsMessage);
command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mcpurge"));
@@ -396,15 +395,6 @@ public final class CommandRegistrationManager {
command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mcnotify"));
command.setExecutor(new McnotifyCommand());
}
-
- private static void registerMHDCommand() {
- PluginCommand command = mcMMO.p.getCommand("mhd");
- command.setDescription("Resets all mob health bar settings for all players to the default"); //TODO: Localize
- command.setPermission("mcmmo.commands.mhd");
- command.setPermissionMessage(permissionsMessage);
- command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mhd"));
- command.setExecutor(new MHDCommand());
- }
private static void registerMcscoreboardCommand() {
PluginCommand command = mcMMO.p.getCommand("mcscoreboard");
@@ -452,7 +442,6 @@ public final class CommandRegistrationManager {
registerMcnotifyCommand();
registerMcrefreshCommand();
registerMcscoreboardCommand();
- registerMHDCommand();
registerXprateCommand();
// Database Commands
diff --git a/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java b/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java
index 666928da1..01cafe833 100644
--- a/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.commands;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -8,6 +7,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.SkillTools;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.util.text.StringUtils;
import com.google.common.collect.ImmutableList;
@@ -28,7 +28,7 @@ public final class CommandUtils {
private CommandUtils() {}
public static boolean isChildSkill(CommandSender sender, PrimarySkillType skill) {
- if (skill == null || !skill.isChildSkill()) {
+ if (skill == null || !SkillTools.isChildSkill(skill)) {
return false;
}
@@ -40,7 +40,7 @@ public final class CommandUtils {
if(!target.isOnline() && !hasPermission) {
sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
return true;
- } else if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), Config.getInstance().getInspectDistance()) && !hasPermission) {
+ } else if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), mcMMO.p.getGeneralConfig().getInspectDistance()) && !hasPermission) {
sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
return true;
}
@@ -176,7 +176,7 @@ public final class CommandUtils {
* @param display The sender to display stats to
*/
public static void printGatheringSkills(Player inspect, CommandSender display) {
- printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Gathering"), PrimarySkillType.GATHERING_SKILLS);
+ printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Gathering"), mcMMO.p.getSkillTools().GATHERING_SKILLS);
}
public static void printGatheringSkills(Player player) {
@@ -190,7 +190,7 @@ public final class CommandUtils {
* @param display The sender to display stats to
*/
public static void printCombatSkills(Player inspect, CommandSender display) {
- printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Combat"), PrimarySkillType.COMBAT_SKILLS);
+ printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Combat"), mcMMO.p.getSkillTools().COMBAT_SKILLS);
}
public static void printCombatSkills(Player player) {
@@ -204,7 +204,7 @@ public final class CommandUtils {
* @param display The sender to display stats to
*/
public static void printMiscSkills(Player inspect, CommandSender display) {
- printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Misc"), PrimarySkillType.MISC_SKILLS);
+ printGroupedSkillData(inspect, display, LocaleLoader.getString("Stats.Header.Misc"), mcMMO.p.getSkillTools().getMiscSkills());
}
public static void printMiscSkills(Player player) {
@@ -212,27 +212,27 @@ public final class CommandUtils {
}
public static String displaySkill(@NotNull PlayerProfile profile, @NotNull PrimarySkillType skill) {
- if (skill.isChildSkill()) {
+ if (SkillTools.isChildSkill(skill)) {
return LocaleLoader.getString("Skills.ChildStats", LocaleLoader.getString(StringUtils.getCapitalized(skill.toString()) + ".Listener") + " ", profile.getSkillLevel(skill));
}
- if (profile.getExperienceHandler().getSkillLevel(skill) == Config.getInstance().getLevelCap(skill)){
+ if (profile.getExperienceHandler().getSkillLevel(skill) == mcMMO.p.getSkillTools().getLevelCap(skill)){
return LocaleLoader.getString("Skills.Stats", LocaleLoader.getString(StringUtils.getCapitalized(skill.toString()) + ".Listener") + " ", profile.getSkillLevel(skill), profile.getSkillXpLevel(skill), LocaleLoader.getString("Skills.MaxXP"));
}
return LocaleLoader.getString("Skills.Stats", LocaleLoader.getString(StringUtils.getCapitalized(skill.toString()) + ".Listener") + " ", profile.getSkillLevel(skill), profile.getSkillXpLevel(skill), profile.getXpToLevel(skill));
}
- private static void printGroupedSkillData(Player inspect, CommandSender display, String header, List skillGroup) {
- if(UserManager.getPlayer(inspect) == null)
+ private static void printGroupedSkillData(Player inspectTarget, CommandSender display, String header, List skillGroup) {
+ if(UserManager.getPlayer(inspectTarget) == null)
return;
- PlayerProfile profile = UserManager.getPlayer(inspect).getProfile();
+ PlayerProfile profile = UserManager.getPlayer(inspectTarget).getProfile();
List displayData = new ArrayList<>();
displayData.add(header);
- for (PrimarySkillType skill : skillGroup) {
- if (skill.getPermissions(inspect)) {
- displayData.add(displaySkill(profile, skill));
+ for (PrimarySkillType primarySkillType : skillGroup) {
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(inspectTarget, primarySkillType)) {
+ displayData.add(displaySkill(profile, primarySkillType));
}
}
@@ -257,7 +257,7 @@ public final class CommandUtils {
}
public static String getMatchedPlayerName(String partialName) {
- if (Config.getInstance().getMatchOfflinePlayers()) {
+ if (mcMMO.p.getGeneralConfig().getMatchOfflinePlayers()) {
List matches = matchPlayer(partialName);
if (matches.size() == 1) {
diff --git a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityLayer.java b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityLayer.java
index d09c52f99..51b240338 100644
--- a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityLayer.java
+++ b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityLayer.java
@@ -8,5 +8,5 @@ public interface CompatibilityLayer {
* Whether or not this CompatibilityLayer successfully initialized and in theory should be functional
* @return true if this CompatibilityLayer is functional
*/
- boolean noErrorsOnInitialize();
+ default boolean noErrorsOnInitialize() { return true; };
}
diff --git a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
index 7a0a0e72a..1b78a55df 100644
--- a/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
+++ b/src/main/java/com/gmail/nossr50/util/compat/CompatibilityManager.java
@@ -10,9 +10,12 @@ import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataL
import com.gmail.nossr50.util.compat.layers.persistentdata.SpigotPersistentDataLayer_1_14;
import com.gmail.nossr50.util.compat.layers.skills.AbstractMasterAnglerCompatibility;
import com.gmail.nossr50.util.compat.layers.skills.MasterAnglerCompatibilityLayer;
+import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer;
+import com.gmail.nossr50.util.compat.layers.world.WorldCompatibilityLayer_1_16_4;
import com.gmail.nossr50.util.nms.NMSVersion;
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import com.gmail.nossr50.util.text.StringUtils;
+import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -37,6 +40,7 @@ public class CompatibilityManager {
private AbstractPersistentDataLayer persistentDataLayer;
private AbstractBungeeSerializerCompatibilityLayer bungeeSerializerCompatibilityLayer;
private AbstractMasterAnglerCompatibility masterAnglerCompatibility;
+ private WorldCompatibilityLayer worldCompatibilityLayer;
public CompatibilityManager(MinecraftGameVersion minecraftGameVersion) {
mcMMO.p.getLogger().info("Loading compatibility layers...");
@@ -67,10 +71,44 @@ public class CompatibilityManager {
initPersistentDataLayer();
initBungeeSerializerLayer();
initMasterAnglerLayer();
+ initWorldCompatibilityLayer();
isFullyCompatibleServerSoftware = true;
}
+ private void initWorldCompatibilityLayer() {
+ if((minecraftGameVersion.getMinorVersion().asInt() >= 16 && minecraftGameVersion.getPatchVersion().asInt() >= 4)
+ || minecraftGameVersion.getMajorVersion().asInt() >= 2) {
+ if(hasNewWorldMinHeightAPI()) {
+ worldCompatibilityLayer = new WorldCompatibilityLayer_1_16_4();
+ } else {
+ worldCompatibilityLayer = new WorldCompatibilityLayer() {
+ @Override
+ public int getMinWorldHeight(@NotNull World world) {
+ return WorldCompatibilityLayer.super.getMinWorldHeight(world);
+ }
+
+ @Override
+ public int getMaxWorldHeight(@NotNull World world) {
+ return WorldCompatibilityLayer.super.getMaxWorldHeight(world);
+ }
+ };
+ }
+ } else {
+ worldCompatibilityLayer = new WorldCompatibilityLayer() {
+ @Override
+ public int getMinWorldHeight(@NotNull World world) {
+ return WorldCompatibilityLayer.super.getMinWorldHeight(world);
+ }
+
+ @Override
+ public int getMaxWorldHeight(@NotNull World world) {
+ return WorldCompatibilityLayer.super.getMaxWorldHeight(world);
+ }
+ };
+ }
+ }
+
private void initMasterAnglerLayer() {
if(minecraftGameVersion.getMinorVersion().asInt() >= 16 || minecraftGameVersion.getMajorVersion().asInt() >= 2) {
if(hasNewFishingHookAPI()) {
@@ -81,6 +119,16 @@ public class CompatibilityManager {
}
}
+ private boolean hasNewWorldMinHeightAPI() {
+ try {
+ Class> checkForClass = Class.forName("org.bukkit.World");
+ checkForClass.getMethod("getMinHeight");
+ return true;
+ } catch (ClassNotFoundException | NoSuchMethodException e) {
+ return false;
+ }
+ }
+
private boolean hasNewFishingHookAPI() {
try {
Class> checkForClass = Class.forName("org.bukkit.entity.FishHook");
@@ -182,4 +230,8 @@ public class CompatibilityManager {
public @Nullable AbstractMasterAnglerCompatibility getMasterAnglerCompatibilityLayer() {
return masterAnglerCompatibility;
}
+
+ public @NotNull WorldCompatibilityLayer getWorldCompatibilityLayer() {
+ return worldCompatibilityLayer;
+ }
}
diff --git a/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer.java b/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer.java
new file mode 100644
index 000000000..115aeb7fb
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer.java
@@ -0,0 +1,11 @@
+package com.gmail.nossr50.util.compat.layers.world;
+
+import com.gmail.nossr50.util.compat.CompatibilityLayer;
+import org.bukkit.World;
+import org.jetbrains.annotations.NotNull;
+
+public interface WorldCompatibilityLayer extends CompatibilityLayer {
+ default int getMinWorldHeight(@NotNull World world) { return 0; }
+
+ default int getMaxWorldHeight(@NotNull World world) { return 256; }
+}
diff --git a/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer_1_16_4.java b/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer_1_16_4.java
new file mode 100644
index 000000000..4e67aaf5c
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/compat/layers/world/WorldCompatibilityLayer_1_16_4.java
@@ -0,0 +1,16 @@
+package com.gmail.nossr50.util.compat.layers.world;
+
+import org.bukkit.World;
+import org.jetbrains.annotations.NotNull;
+
+public class WorldCompatibilityLayer_1_16_4 implements WorldCompatibilityLayer {
+ @Override
+ public int getMinWorldHeight(@NotNull World world) {
+ return world.getMinHeight();
+ }
+
+ @Override
+ public int getMaxWorldHeight(@NotNull World world) {
+ return world.getMaxHeight();
+ }
+}
diff --git a/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java b/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java
index 382c00d0b..21816c1ce 100644
--- a/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java
+++ b/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.experience;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.FormulaType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -81,7 +80,7 @@ public class FormulaManager {
public int[] calculateNewLevel(PrimarySkillType primarySkillType, int experience, FormulaType formulaType) {
int newLevel = 0;
int remainder = 0;
- int maxLevel = Config.getInstance().getLevelCap(primarySkillType);
+ int maxLevel = mcMMO.p.getSkillTools().getLevelCap(primarySkillType);
while (experience > 0 && newLevel < maxLevel) {
int experienceToNextLevel = getXPtoNextLevel(newLevel, formulaType);
diff --git a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java
index c582c6c3d..b2cfef92a 100644
--- a/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java
+++ b/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.util.player;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.LevelUpBroadcastPredicate;
import com.gmail.nossr50.datatypes.PowerLevelUpBroadcastPredicate;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
@@ -52,7 +50,7 @@ public class NotificationManager {
if(mmoPlayer == null || !mmoPlayer.hasSkillChatNotifications())
return;
- McMMOMessageType destination = AdvancedConfig.getInstance().doesNotificationUseActionBar(notificationType) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
+ McMMOMessageType destination = mcMMO.p.getAdvancedConfig().doesNotificationUseActionBar(notificationType) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
Component message = TextComponentFactory.getNotificationTextComponentFromLocale(key);
McMMOPlayerNotificationEvent customEvent = checkNotificationEvent(player, notificationType, destination, message);
@@ -116,7 +114,7 @@ public class NotificationManager {
if(mmoPlayer != null && !mmoPlayer.hasSkillChatNotifications())
return;
- McMMOMessageType destination = AdvancedConfig.getInstance().doesNotificationUseActionBar(notificationType) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
+ McMMOMessageType destination = mcMMO.p.getAdvancedConfig().doesNotificationUseActionBar(notificationType) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
Component message = TextComponentFactory.getNotificationMultipleValues(key, values);
McMMOPlayerNotificationEvent customEvent = checkNotificationEvent(player, notificationType, destination, message);
@@ -148,7 +146,7 @@ public class NotificationManager {
private static @NotNull McMMOPlayerNotificationEvent checkNotificationEvent(@NotNull Player player, @NotNull NotificationType notificationType, @NotNull McMMOMessageType destination, @NotNull Component message) {
//Init event
McMMOPlayerNotificationEvent customEvent = new McMMOPlayerNotificationEvent(player,
- notificationType, message, destination, AdvancedConfig.getInstance().doesNotificationSendCopyToChat(notificationType));
+ notificationType, message, destination, mcMMO.p.getAdvancedConfig().doesNotificationSendCopyToChat(notificationType));
//Call event
Bukkit.getServer().getPluginManager().callEvent(customEvent);
@@ -166,7 +164,7 @@ public class NotificationManager {
if(!mmoPlayer.hasSkillChatNotifications())
return;
- McMMOMessageType destination = AdvancedConfig.getInstance().doesNotificationUseActionBar(NotificationType.LEVEL_UP_MESSAGE) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
+ McMMOMessageType destination = mcMMO.p.getAdvancedConfig().doesNotificationUseActionBar(NotificationType.LEVEL_UP_MESSAGE) ? McMMOMessageType.ACTION_BAR : McMMOMessageType.SYSTEM;
Component levelUpTextComponent = TextComponentFactory.getNotificationLevelUpTextComponent(PrimarySkillType.getSkill(primarySkillType), levelsGained, newLevel);
McMMOPlayerNotificationEvent customEvent = checkNotificationEvent(Misc.adaptPlayer(mmoPlayer), NotificationType.LEVEL_UP_MESSAGE, destination, levelUpTextComponent);
@@ -194,7 +192,7 @@ public class NotificationManager {
SoundManager.sendCategorizedSound(Misc.adaptPlayer(mmoPlayer), Misc.adaptPlayer(mmoPlayer).getLocation(), SoundType.SKILL_UNLOCKED, SoundCategory.MASTER);
//ACTION BAR MESSAGE
- /*if(AdvancedConfig.getInstance().doesNotificationUseActionBar(NotificationType.SUBSKILL_UNLOCKED))
+ /*if(mcMMO.p.getAdvancedConfig().doesNotificationUseActionBar(NotificationType.SUBSKILL_UNLOCKED))
Misc.adaptPlayer(mmoPlayer).spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent(LocaleLoader.getString("JSON.SkillUnlockMessage",
subSkillType.getLocaleName(),
String.valueOf(RankUtils.getRank(Misc.adaptPlayer(mmoPlayer),
@@ -208,7 +206,7 @@ public class NotificationManager {
*/
private static void sendAdminNotification(@NotNull String msg) {
//If its not enabled exit
- if(!Config.getInstance().adminNotifications())
+ if(!mcMMO.p.getGeneralConfig().adminNotifications())
return;
for(Player player : Bukkit.getServer().getOnlinePlayers())
@@ -285,13 +283,13 @@ public class NotificationManager {
return;
//Check if broadcasting is enabled
- if(Config.getInstance().shouldLevelUpBroadcasts()) {
+ if(mcMMO.p.getGeneralConfig().shouldLevelUpBroadcasts()) {
//Permission check
if(!Permissions.levelUpBroadcast(mmoPlayer.getPlayer())) {
return;
}
- int levelInterval = Config.getInstance().getLevelUpBroadcastInterval();
+ int levelInterval = mcMMO.p.getGeneralConfig().getLevelUpBroadcastInterval();
int remainder = level % levelInterval;
if(remainder == 0) {
@@ -302,10 +300,10 @@ public class NotificationManager {
.append(Component.newline())
.append(Component.text(LocalDate.now().toString()))
.append(Component.newline())
- .append(Component.text(primarySkillType.getName()+" reached level "+level)).color(TextColor.fromHexString(HEX_BEIGE_COLOR))
+ .append(Component.text(mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType)+" reached level "+level)).color(TextColor.fromHexString(HEX_BEIGE_COLOR))
.asHoverEvent();
- String localeMessage = LocaleLoader.getString("Broadcasts.LevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), level, primarySkillType.getName());
+ String localeMessage = LocaleLoader.getString("Broadcasts.LevelUpMilestone", mmoPlayer.getPlayer().getDisplayName(), level, mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType));
Component message = Component.text(localeMessage).hoverEvent(levelMilestoneHover);
Bukkit.getScheduler().runTaskLater(mcMMO.p, () -> audience.sendMessage(Identity.nil(), message), 0);
@@ -320,13 +318,13 @@ public class NotificationManager {
return;
//Check if broadcasting is enabled
- if(Config.getInstance().shouldPowerLevelUpBroadcasts()) {
+ if(mcMMO.p.getGeneralConfig().shouldPowerLevelUpBroadcasts()) {
//Permission check
if(!Permissions.levelUpBroadcast(mmoPlayer.getPlayer())) {
return;
}
- int levelInterval = Config.getInstance().getPowerLevelUpBroadcastInterval();
+ int levelInterval = mcMMO.p.getGeneralConfig().getPowerLevelUpBroadcastInterval();
int remainder = powerLevel % levelInterval;
if(remainder == 0) {
diff --git a/src/main/java/com/gmail/nossr50/util/random/RandomChanceUtil.java b/src/main/java/com/gmail/nossr50/util/random/RandomChanceUtil.java
index a59cd2861..67982ce59 100644
--- a/src/main/java/com/gmail/nossr50/util/random/RandomChanceUtil.java
+++ b/src/main/java/com/gmail/nossr50/util/random/RandomChanceUtil.java
@@ -1,10 +1,10 @@
package com.gmail.nossr50.util.random;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.events.skills.secondaryabilities.SubSkillEvent;
import com.gmail.nossr50.events.skills.secondaryabilities.SubSkillRandomCheckEvent;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.EventUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.skills.SkillActivationType;
@@ -252,11 +252,11 @@ public class RandomChanceUtil {
public static double getStaticRandomChance(@NotNull SubSkillType subSkillType) throws InvalidStaticChance {
switch (subSkillType) {
case AXES_ARMOR_IMPACT:
- return AdvancedConfig.getInstance().getImpactChance();
+ return mcMMO.p.getAdvancedConfig().getImpactChance();
case AXES_GREATER_IMPACT:
- return AdvancedConfig.getInstance().getGreaterImpactChance();
+ return mcMMO.p.getAdvancedConfig().getGreaterImpactChance();
case TAMING_FAST_FOOD_SERVICE:
- return AdvancedConfig.getInstance().getFastFoodChance();
+ return mcMMO.p.getAdvancedConfig().getFastFoodChance();
default:
throw new InvalidStaticChance();
}
@@ -328,10 +328,10 @@ public class RandomChanceUtil {
}
public static double getMaximumProbability(@NotNull SubSkillType subSkillType) {
- return AdvancedConfig.getInstance().getMaximumProbability(subSkillType);
+ return mcMMO.p.getAdvancedConfig().getMaximumProbability(subSkillType);
}
public static double getMaxBonusLevelCap(@NotNull SubSkillType subSkillType) {
- return AdvancedConfig.getInstance().getMaxBonusLevel(subSkillType);
+ return mcMMO.p.getAdvancedConfig().getMaxBonusLevel(subSkillType);
}
}
diff --git a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java
index b4c24ff40..bbc308ed8 100644
--- a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java
+++ b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardManager.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.scoreboards;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -71,7 +70,7 @@ public class ScoreboardManager {
* Stylizes the targetBoard in a Rainbow Pattern
* This is off by default
*/
- if (Config.getInstance().getScoreboardRainbows()) {
+ if (mcMMO.p.getGeneralConfig().getScoreboardRainbows()) {
// Everything but black, gray, gold
List colors = Lists.newArrayList(
ChatColor.WHITE,
@@ -91,14 +90,14 @@ public class ScoreboardManager {
Collections.shuffle(colors, Misc.getRandom());
int i = 0;
- for (PrimarySkillType type : PrimarySkillType.values()) {
+ for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
// Include child skills
- skillLabelBuilder.put(type, getShortenedName(colors.get(i) + type.getName(), false));
+ skillLabelBuilder.put(primarySkillType, getShortenedName(colors.get(i) + mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType), false));
- if (type.getSuperAbilityType() != null) {
- abilityLabelBuilder.put(type.getSuperAbilityType(), getShortenedName(colors.get(i) + type.getSuperAbilityType().getLocalizedName()));
+ if (mcMMO.p.getSkillTools().getSuperAbility(primarySkillType) != null) {
+ abilityLabelBuilder.put(mcMMO.p.getSkillTools().getSuperAbility(primarySkillType), getShortenedName(colors.get(i) + mcMMO.p.getSkillTools().getSuperAbility(primarySkillType).getLocalizedName()));
- if (type == PrimarySkillType.MINING) {
+ if (primarySkillType == PrimarySkillType.MINING) {
abilityLabelBuilder.put(SuperAbilityType.BLAST_MINING, getShortenedName(colors.get(i) + SuperAbilityType.BLAST_MINING.getLocalizedName()));
}
}
@@ -113,14 +112,14 @@ public class ScoreboardManager {
* Stylizes the targetBoard using our normal color scheme
*/
else {
- for (PrimarySkillType type : PrimarySkillType.values()) {
+ for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
// Include child skills
- skillLabelBuilder.put(type, getShortenedName(ChatColor.GREEN + type.getName()));
+ skillLabelBuilder.put(primarySkillType, getShortenedName(ChatColor.GREEN + mcMMO.p.getSkillTools().getLocalizedSkillName(primarySkillType)));
- if (type.getSuperAbilityType() != null) {
- abilityLabelBuilder.put(type.getSuperAbilityType(), formatAbility(type.getSuperAbilityType().getLocalizedName()));
+ if (mcMMO.p.getSkillTools().getSuperAbility(primarySkillType) != null) {
+ abilityLabelBuilder.put(mcMMO.p.getSkillTools().getSuperAbility(primarySkillType), formatAbility(mcMMO.p.getSkillTools().getSuperAbility(primarySkillType).getLocalizedName()));
- if (type == PrimarySkillType.MINING) {
+ if (primarySkillType == PrimarySkillType.MINING) {
abilityLabelBuilder.put(SuperAbilityType.BLAST_MINING, formatAbility(SuperAbilityType.BLAST_MINING.getLocalizedName()));
}
}
@@ -152,7 +151,7 @@ public class ScoreboardManager {
}
private static String formatAbility(ChatColor color, String abilityName) {
- if (Config.getInstance().getShowAbilityNames()) {
+ if (mcMMO.p.getGeneralConfig().getShowAbilityNames()) {
return getShortenedName(color + abilityName);
}
else {
@@ -243,11 +242,11 @@ public class ScoreboardManager {
}
}
- if (Config.getInstance().getPowerLevelTagsEnabled() && !dirtyPowerLevels.contains(playerName)) {
+ if (mcMMO.p.getGeneralConfig().getPowerLevelTagsEnabled() && !dirtyPowerLevels.contains(playerName)) {
dirtyPowerLevels.add(playerName);
}
- if (Config.getInstance().getSkillLevelUpBoard()) {
+ if (mcMMO.p.getGeneralConfig().getSkillLevelUpBoard()) {
enablePlayerSkillLevelUpScoreboard(player, skill);
}
@@ -298,7 +297,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeSkill(skill);
- changeScoreboard(wrapper, Config.getInstance().getSkillScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getSkillScoreboardTime());
}
}
@@ -317,7 +316,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeSkill(primarySkillType);
- changeScoreboard(wrapper, Config.getInstance().getSkillScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getSkillScoreboardTime());
}
}
@@ -332,7 +331,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeSkill(skill);
- changeScoreboard(wrapper, Config.getInstance().getSkillLevelUpTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getSkillLevelUpTime());
}
}
@@ -346,7 +345,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeSelfStats();
- changeScoreboard(wrapper, Config.getInstance().getStatsScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getStatsScoreboardTime());
}
public static void enablePlayerInspectScoreboard(@NotNull Player player, @NotNull PlayerProfile targetProfile) {
@@ -361,7 +360,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeInspectStats(targetProfile);
- changeScoreboard(wrapper, Config.getInstance().getInspectScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getInspectScoreboardTime());
}
}
@@ -377,7 +376,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeInspectStats(targetMcMMOPlayer);
- changeScoreboard(wrapper, Config.getInstance().getInspectScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getInspectScoreboardTime());
}
}
@@ -393,7 +392,7 @@ public class ScoreboardManager {
wrapper.setOldScoreboard();
wrapper.setTypeCooldowns();
- changeScoreboard(wrapper, Config.getInstance().getCooldownScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getCooldownScoreboardTime());
}
}
@@ -410,7 +409,7 @@ public class ScoreboardManager {
wrapper.setTypeSelfRank();
wrapper.acceptRankData(rank);
- changeScoreboard(wrapper, Config.getInstance().getRankScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getRankScoreboardTime());
}
}
@@ -427,7 +426,7 @@ public class ScoreboardManager {
wrapper.setTypeInspectRank(targetName);
wrapper.acceptRankData(rank);
- changeScoreboard(wrapper, Config.getInstance().getRankScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getRankScoreboardTime());
}
}
@@ -445,7 +444,7 @@ public class ScoreboardManager {
wrapper.setTypeTop(skill, pageNumber);
wrapper.acceptLeaderboardData(stats);
- changeScoreboard(wrapper, Config.getInstance().getTopScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getTopScoreboardTime());
}
}
@@ -462,7 +461,7 @@ public class ScoreboardManager {
wrapper.setTypeTopPower(pageNumber);
wrapper.acceptLeaderboardData(stats);
- changeScoreboard(wrapper, Config.getInstance().getTopScoreboardTime());
+ changeScoreboard(wrapper, mcMMO.p.getGeneralConfig().getTopScoreboardTime());
}
}
@@ -516,7 +515,7 @@ public class ScoreboardManager {
* @return the main targetBoard objective, or null if disabled
*/
public static @Nullable Objective getPowerLevelObjective() {
- if (!Config.getInstance().getPowerLevelTagsEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getPowerLevelTagsEnabled()) {
if(getScoreboardManager() == null)
return null;
diff --git a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java
index 0b85db49f..eef08679e 100644
--- a/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java
+++ b/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.scoreboards;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -17,6 +16,7 @@ import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.player.NotificationManager;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.scoreboards.ScoreboardManager.SidebarType;
+import com.gmail.nossr50.util.skills.SkillTools;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -75,7 +75,7 @@ public class ScoreboardWrapper {
registered = true;
}
- if (Config.getInstance().getPowerLevelTagsEnabled()) {
+ if (mcMMO.p.getGeneralConfig().getPowerLevelTagsEnabled()) {
powerObjective.setDisplayName(ScoreboardManager.TAG_POWER_LEVEL);
powerObjective.setDisplaySlot(DisplaySlot.BELOW_NAME);
@@ -225,7 +225,7 @@ public class ScoreboardWrapper {
PlayerProfile profile = UserManager.getPlayer(player).getProfile();
- if (profile.getScoreboardTipsShown() >= Config.getInstance().getTipsAmount()) {
+ if (profile.getScoreboardTipsShown() >= mcMMO.p.getGeneralConfig().getTipsAmount()) {
return;
}
@@ -489,7 +489,7 @@ public class ScoreboardWrapper {
case SKILL_BOARD:
Validate.notNull(targetSkill);
- if (!targetSkill.isChildSkill()) {
+ if (!SkillTools.isChildSkill(targetSkill)) {
int currentXP = mcMMOPlayer.getSkillXpLevel(targetSkill);
sidebarObjective.getScore(ScoreboardManager.LABEL_CURRENT_XP).setScore(currentXP);
@@ -503,7 +503,7 @@ public class ScoreboardWrapper {
sidebarObjective.getScore(ScoreboardManager.LABEL_LEVEL).setScore(mcMMOPlayer.getSkillLevel(targetSkill));
- if (targetSkill.getAbility() != null) {
+ if (mcMMO.p.getSkillTools().getSuperAbility(targetSkill) != null) {
boolean stopUpdating;
if (targetSkill == PrimarySkillType.MINING) {
@@ -519,7 +519,7 @@ public class ScoreboardWrapper {
stopUpdating = (secondsSB == 0 && secondsBM == 0);
}
else {
- SuperAbilityType ability = targetSkill.getAbility();
+ SuperAbilityType ability = mcMMO.p.getSkillTools().getSuperAbility(targetSkill);
Score cooldown = sidebarObjective.getScore(ScoreboardManager.abilityLabelsSkill.get(ability));
int seconds = Math.max(mcMMOPlayer.calculateTimeRemaining(ability), 0);
@@ -574,13 +574,13 @@ public class ScoreboardWrapper {
// Calculate power level here
int powerLevel = 0;
- for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) { // Don't include child skills, makes the list too long
+ for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) { // Don't include child skills, makes the list too long
int level = newProfile.getSkillLevel(skill);
powerLevel += level;
// TODO: Verify that this is what we want - calculated in power level but not displayed
- if (!skill.getPermissions(player)) {
+ if (!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, skill)) {
continue;
}
@@ -607,8 +607,8 @@ public class ScoreboardWrapper {
Integer rank;
Player player = mcMMO.p.getServer().getPlayerExact(playerName);
- for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
- if (!skill.getPermissions(player)) {
+ for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
+ if (!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, skill)) {
continue;
}
diff --git a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
index 6e8b88fe4..d9fd1d7c1 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.skills;
-import com.gmail.nossr50.config.AdvancedConfig;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.meta.OldName;
@@ -405,7 +404,7 @@ public final class CombatUtils {
}
if (ItemUtils.isSword(player.getInventory().getItemInMainHand())) {
- if (!PrimarySkillType.SWORDS.shouldProcess(target)) {
+ if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.SWORDS, target)) {
return;
}
@@ -443,29 +442,29 @@ public final class CombatUtils {
}
if (ItemUtils.isSword(heldItem)) {
- if (!PrimarySkillType.SWORDS.shouldProcess(target)) {
+ if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.SWORDS, target)) {
return;
}
- if (PrimarySkillType.SWORDS.getPermissions(player)) {
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SWORDS)) {
processSwordCombat(target, player, event);
}
}
else if (ItemUtils.isAxe(heldItem)) {
- if (!PrimarySkillType.AXES.shouldProcess(target)) {
+ if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.AXES, target)) {
return;
}
- if (PrimarySkillType.AXES.getPermissions(player)) {
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.AXES)) {
processAxeCombat(target, player, event);
}
}
else if (ItemUtils.isUnarmed(heldItem)) {
- if (!PrimarySkillType.UNARMED.shouldProcess(target)) {
+ if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.UNARMED, target)) {
return;
}
- if (PrimarySkillType.UNARMED.getPermissions(player)) {
+ if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.UNARMED)) {
processUnarmedCombat(target, player, event);
}
}
@@ -484,10 +483,10 @@ public final class CombatUtils {
Wolf wolf = (Wolf) painSource;
AnimalTamer tamer = wolf.getOwner();
- if (tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) {
+ if (tamer instanceof Player && mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.TAMING, target)) {
Player master = (Player) tamer;
- if (!Misc.isNPCEntityExcludingVillagers(master) && PrimarySkillType.TAMING.getPermissions(master)) {
+ if (!Misc.isNPCEntityExcludingVillagers(master) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(master, PrimarySkillType.TAMING)) {
processTamingCombat(target, master, wolf, event);
}
}
@@ -504,7 +503,7 @@ public final class CombatUtils {
if(arrow.getMetadata(mcMMO.PROJECTILE_ORIGIN_METAKEY).size() > 0) {
if (isProjectileFromBow(arrow)) {
if (PrimarySkillType.ARCHERY.shouldProcess(target)) {
- if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.ARCHERY.getPermissions(player)) {
+ if (!Misc.isNPCEntityExcludingVillagers(player) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.ARCHERY)) {
processArcheryCombat(target, player, event, arrow);
}
}
@@ -520,7 +519,7 @@ public final class CombatUtils {
cleanupArrowMetadata(arrow);
}
- if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.TAMING.getPermissions(player)) {
+ if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.TAMING)) {
OnlineMMOPlayer mmoPlayer = UserManager.queryPlayer(player);
if(mmoPlayer == null) {
@@ -628,7 +627,7 @@ public final class CombatUtils {
* @return true if the mmoPlayer has access to the limit break
*/
public static boolean canUseLimitBreak(@NotNull OnlineMMOPlayer mmoPlayer, LivingEntity target, @NotNull SubSkillType subSkillType) {
- if(target instanceof Player || AdvancedConfig.getInstance().canApplyLimitBreakPVE()) {
+ if(target instanceof Player || mcMMO.p.getAdvancedConfig().canApplyLimitBreakPVE()) {
return RankUtils.hasUnlockedSubskill(mmoPlayer, subSkillType)
&& Permissions.isSubSkillEnabled(Misc.adaptPlayer(mmoPlayer), subSkillType);
} else {
diff --git a/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java b/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
index f63b5dd83..a70f09471 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/ParticleEffectUtils.java
@@ -1,6 +1,6 @@
package com.gmail.nossr50.util.skills;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.sounds.SoundManager;
import com.gmail.nossr50.util.sounds.SoundType;
import org.apache.commons.lang.math.RandomUtils;
@@ -24,7 +24,7 @@ public final class ParticleEffectUtils {
}
public static void playBleedEffect(LivingEntity livingEntity) {
- if (!Config.getInstance().getBleedEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getBleedEffectEnabled()) {
return;
}
@@ -63,7 +63,7 @@ public final class ParticleEffectUtils {
public static void playDodgeEffect(Player player) {
- if (!Config.getInstance().getDodgeEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getDodgeEffectEnabled()) {
return;
}
@@ -71,7 +71,7 @@ public final class ParticleEffectUtils {
}
public static void playFluxEffect(Location location) {
- if (!Config.getInstance().getFluxEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getFluxEffectEnabled()) {
return;
}
@@ -100,7 +100,7 @@ public final class ParticleEffectUtils {
}
public static void playGreaterImpactEffect(LivingEntity livingEntity) {
- if (!Config.getInstance().getGreaterImpactEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getGreaterImpactEffectEnabled()) {
return;
}
@@ -110,7 +110,7 @@ public final class ParticleEffectUtils {
}
public static void playCallOfTheWildEffect(LivingEntity livingEntity) {
- if (!Config.getInstance().getCallOfTheWildEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getCallOfTheWildEffectEnabled()) {
return;
}
@@ -118,7 +118,7 @@ public final class ParticleEffectUtils {
}
public static void playAbilityDisabledEffect(Player player) {
- if (!Config.getInstance().getAbilityDeactivationEffectEnabled()) {
+ if (!mcMMO.p.getGeneralConfig().getAbilityDeactivationEffectEnabled()) {
}
/*if (hasHeadRoom(player)) {
diff --git a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java
index b9d39ca1a..08268909c 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/RankUtils.java
@@ -6,6 +6,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
import com.gmail.nossr50.listeners.InteractionManager;
+import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.skills.SkillUnlockNotificationTask;
import com.gmail.nossr50.util.Permissions;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
@@ -27,7 +28,7 @@ public class RankUtils {
*/
public static void executeSkillUnlockNotifications(@NotNull Plugin plugin, @NotNull OnlineMMOPlayer mmoPlayer, @NotNull PrimarySkillType primarySkillType, int newLevel)
{
- for(SubSkillType subSkillType : mcMMO.p.getSkillRegister().getSkillAbilities())
+ for(SubSkillType subSkillType : mcMMO.p.getSkillTools().getSubSkills(primarySkillType))
{
int playerRankInSkill = getRank(mmoPlayer, subSkillType);
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
new file mode 100644
index 000000000..8d50873c5
--- /dev/null
+++ b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java
@@ -0,0 +1,453 @@
+package com.gmail.nossr50.util.skills;
+
+import com.gmail.nossr50.api.exceptions.InvalidSkillException;
+import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
+import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
+import com.gmail.nossr50.datatypes.skills.ToolType;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.text.StringUtils;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Tameable;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class SkillTools {
+ private final mcMMO pluginRef;
+
+ //TODO: Figure out which ones we don't need, this was copy pasted from a diff branch
+ public final @NotNull ImmutableList LOCALIZED_SKILL_NAMES;
+ public final @NotNull ImmutableList FORMATTED_SUBSKILL_NAMES;
+ public final @NotNull ImmutableSet EXACT_SUBSKILL_NAMES;
+ public final @NotNull ImmutableList CHILD_SKILLS;
+ public final static @NotNull ImmutableList NON_CHILD_SKILLS;
+ public final @NotNull ImmutableList COMBAT_SKILLS;
+ public final @NotNull ImmutableList GATHERING_SKILLS;
+ public final @NotNull ImmutableList MISC_SKILLS;
+
+ private final @NotNull ImmutableMap subSkillParentRelationshipMap;
+ private final @NotNull ImmutableMap superAbilityParentRelationshipMap;
+ private final @NotNull ImmutableMap> primarySkillChildrenMap;
+
+ // The map below is for the super abilities which require readying a tool, its everything except blast mining
+ private final ImmutableMap mainActivatedAbilityChildMap;
+ private final ImmutableMap primarySkillToolMap;
+
+ static {
+ ArrayList tempNonChildSkills = new ArrayList<>();
+ for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
+ if (primarySkillType != PrimarySkillType.SALVAGE && primarySkillType != PrimarySkillType.SMELTING)
+ tempNonChildSkills.add(primarySkillType);
+ }
+
+ NON_CHILD_SKILLS = ImmutableList.copyOf(tempNonChildSkills);
+ }
+
+ public SkillTools(@NotNull mcMMO pluginRef) {
+ this.pluginRef = pluginRef;
+
+ /*
+ * Setup subskill -> parent relationship map
+ */
+ EnumMap tempSubParentMap = new EnumMap(SubSkillType.class);
+
+ //Super hacky and disgusting
+ for(PrimarySkillType primarySkillType1 : PrimarySkillType.values()) {
+ for(SubSkillType subSkillType : SubSkillType.values()) {
+ String[] splitSubSkillName = subSkillType.toString().split("_");
+
+ if(primarySkillType1.toString().equalsIgnoreCase(splitSubSkillName[0])) {
+ //Parent Skill Found
+ tempSubParentMap.put(subSkillType, primarySkillType1);
+ }
+ }
+ }
+
+ subSkillParentRelationshipMap = ImmutableMap.copyOf(tempSubParentMap);
+
+ /*
+ * Setup primary -> (collection) subskill map
+ */
+
+ EnumMap> tempPrimaryChildMap = new EnumMap>(PrimarySkillType.class);
+
+ //Init the empty Hash Sets
+ for(PrimarySkillType primarySkillType1 : PrimarySkillType.values()) {
+ tempPrimaryChildMap.put(primarySkillType1, new HashSet<>());
+ }
+
+ //Fill in the hash sets
+ for(SubSkillType subSkillType : SubSkillType.values()) {
+ PrimarySkillType parentSkill = subSkillParentRelationshipMap.get(subSkillType);
+
+ //Add this subskill as a child
+ tempPrimaryChildMap.get(parentSkill).add(subSkillType);
+ }
+
+ primarySkillChildrenMap = ImmutableMap.copyOf(tempPrimaryChildMap);
+
+ /*
+ * Setup primary -> tooltype map
+ */
+ EnumMap tempToolMap = new EnumMap(PrimarySkillType.class);
+
+ tempToolMap.put(PrimarySkillType.AXES, ToolType.AXE);
+ tempToolMap.put(PrimarySkillType.WOODCUTTING, ToolType.AXE);
+ tempToolMap.put(PrimarySkillType.UNARMED, ToolType.FISTS);
+ tempToolMap.put(PrimarySkillType.SWORDS, ToolType.SWORD);
+ tempToolMap.put(PrimarySkillType.EXCAVATION, ToolType.SHOVEL);
+ tempToolMap.put(PrimarySkillType.HERBALISM, ToolType.HOE);
+ tempToolMap.put(PrimarySkillType.MINING, ToolType.PICKAXE);
+
+ primarySkillToolMap = ImmutableMap.copyOf(tempToolMap);
+
+ /*
+ * Setup ability -> primary map
+ * Setup primary -> ability map
+ */
+
+ EnumMap tempAbilityParentRelationshipMap = new EnumMap(SuperAbilityType.class);
+ EnumMap tempMainActivatedAbilityChildMap = new EnumMap(PrimarySkillType.class);
+
+ for(SuperAbilityType superAbilityType : SuperAbilityType.values()) {
+ try {
+ PrimarySkillType parent = getSuperAbilityParent(superAbilityType);
+ tempAbilityParentRelationshipMap.put(superAbilityType, parent);
+
+ if(superAbilityType != SuperAbilityType.BLAST_MINING) {
+ //This map is used only for abilities that have a tool readying phase, so blast mining is ignored
+ tempMainActivatedAbilityChildMap.put(parent, superAbilityType);
+ }
+ } catch (InvalidSkillException e) {
+ e.printStackTrace();
+ }
+ }
+
+ superAbilityParentRelationshipMap = ImmutableMap.copyOf(tempAbilityParentRelationshipMap);
+ mainActivatedAbilityChildMap = ImmutableMap.copyOf(tempMainActivatedAbilityChildMap);
+
+ /*
+ * Build child skill and nonchild skill lists
+ */
+
+ List childSkills = new ArrayList<>();
+// List nonChildSkills = new ArrayList<>();
+
+ for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
+ if (isChildSkill(primarySkillType))
+ childSkills.add(primarySkillType);
+// } {
+// nonChildSkills.add(primarySkillType);
+// }
+ }
+
+ CHILD_SKILLS = ImmutableList.copyOf(childSkills);
+// NON_CHILD_SKILLS = ImmutableList.copyOf(nonChildSkills);
+
+ /*
+ * Build categorized skill lists
+ */
+
+ COMBAT_SKILLS = ImmutableList.of(PrimarySkillType.ARCHERY, PrimarySkillType.AXES, PrimarySkillType.SWORDS, PrimarySkillType.TAMING, PrimarySkillType.UNARMED);
+ GATHERING_SKILLS = ImmutableList.of(PrimarySkillType.EXCAVATION, PrimarySkillType.FISHING, PrimarySkillType.HERBALISM, PrimarySkillType.MINING, PrimarySkillType.WOODCUTTING);
+ MISC_SKILLS = ImmutableList.of(PrimarySkillType.ACROBATICS, PrimarySkillType.ALCHEMY, PrimarySkillType.REPAIR, PrimarySkillType.SALVAGE, PrimarySkillType.SMELTING);
+
+ /*
+ * Build formatted/localized/etc string lists
+ */
+
+ LOCALIZED_SKILL_NAMES = ImmutableList.copyOf(buildLocalizedPrimarySkillNames());
+ FORMATTED_SUBSKILL_NAMES = ImmutableList.copyOf(buildFormattedSubSkillNameList());
+ EXACT_SUBSKILL_NAMES = ImmutableSet.copyOf(buildExactSubSkillNameList());
+ }
+
+ private @NotNull PrimarySkillType getSuperAbilityParent(SuperAbilityType superAbilityType) throws InvalidSkillException {
+ switch(superAbilityType) {
+ case BERSERK:
+ return PrimarySkillType.UNARMED;
+ case GREEN_TERRA:
+ return PrimarySkillType.HERBALISM;
+ case TREE_FELLER:
+ return PrimarySkillType.WOODCUTTING;
+ case SUPER_BREAKER:
+ case BLAST_MINING:
+ return PrimarySkillType.MINING;
+ case SKULL_SPLITTER:
+ return PrimarySkillType.AXES;
+ case SERRATED_STRIKES:
+ return PrimarySkillType.SWORDS;
+ case GIGA_DRILL_BREAKER:
+ return PrimarySkillType.EXCAVATION;
+ default:
+ throw new InvalidSkillException("No parent defined for super ability! "+superAbilityType.toString());
+ }
+ }
+
+ /**
+ * Makes a list of the "nice" version of sub skill names
+ * Used in tab completion mostly
+ * @return a list of formatted sub skill names
+ */
+ private @NotNull ArrayList buildFormattedSubSkillNameList() {
+ ArrayList subSkillNameList = new ArrayList<>();
+
+ for(SubSkillType subSkillType : SubSkillType.values()) {
+ subSkillNameList.add(subSkillType.getNiceNameNoSpaces(subSkillType));
+ }
+
+ return subSkillNameList;
+ }
+
+ private @NotNull HashSet buildExactSubSkillNameList() {
+ HashSet subSkillNameExactSet = new HashSet<>();
+
+ for(SubSkillType subSkillType : SubSkillType.values()) {
+ subSkillNameExactSet.add(subSkillType.toString());
+ }
+
+ return subSkillNameExactSet;
+ }
+
+ /**
+ * Builds a list of localized {@link PrimarySkillType} names
+ * @return list of localized {@link PrimarySkillType} names
+ */
+ @VisibleForTesting
+ private @NotNull ArrayList buildLocalizedPrimarySkillNames() {
+ ArrayList localizedSkillNameList = new ArrayList<>();
+
+ for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
+ localizedSkillNameList.add(getLocalizedSkillName(primarySkillType));
+ }
+
+ Collections.sort(localizedSkillNameList);
+
+ return localizedSkillNameList;
+ }
+
+ /**
+ * Matches a string of a skill to a skill
+ * This is NOT case sensitive
+ * First it checks the locale file and tries to match by the localized name of the skill
+ * Then if nothing is found it checks against the hard coded "name" of the skill, which is just its name in English
+ *
+ * @param skillName target skill name
+ * @return the matching PrimarySkillType if one is found, otherwise null
+ */
+ public PrimarySkillType matchSkill(String skillName) {
+ if (!pluginRef.getGeneralConfig().getLocale().equalsIgnoreCase("en_US")) {
+ for (PrimarySkillType type : PrimarySkillType.values()) {
+ if (skillName.equalsIgnoreCase(LocaleLoader.getString(StringUtils.getCapitalized(type.name()) + ".SkillName"))) {
+ return type;
+ }
+ }
+ }
+
+ for (PrimarySkillType type : PrimarySkillType.values()) {
+ if (type.name().equalsIgnoreCase(skillName)) {
+ return type;
+ }
+ }
+
+ if (!skillName.equalsIgnoreCase("all")) {
+ pluginRef.getLogger().warning("Invalid mcMMO skill (" + skillName + ")"); //TODO: Localize
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets the PrimarySkillStype to which a SubSkillType belongs
+ * Return null if it does not belong to one.. which should be impossible in most circumstances
+ * @param subSkillType target subskill
+ * @return the PrimarySkillType of this SubSkill, null if it doesn't exist
+ */
+ public PrimarySkillType getPrimarySkillBySubSkill(SubSkillType subSkillType) {
+ return subSkillParentRelationshipMap.get(subSkillType);
+ }
+
+ /**
+ * Gets the PrimarySkillStype to which a SuperAbilityType belongs
+ * Return null if it does not belong to one.. which should be impossible in most circumstances
+ * @param superAbilityType target super ability
+ * @return the PrimarySkillType of this SuperAbilityType, null if it doesn't exist
+ */
+ public PrimarySkillType getPrimarySkillBySuperAbility(SuperAbilityType superAbilityType) {
+ return superAbilityParentRelationshipMap.get(superAbilityType);
+ }
+
+ public SuperAbilityType getSuperAbility(PrimarySkillType primarySkillType) {
+ if(mainActivatedAbilityChildMap.get(primarySkillType) == null)
+ return null;
+
+ return mainActivatedAbilityChildMap.get(primarySkillType);
+ }
+
+ public boolean isSuperAbilityUnlocked(PrimarySkillType primarySkillType, Player player) {
+ SuperAbilityType superAbilityType = mcMMO.p.getSkillTools().getSuperAbility(primarySkillType);
+ SubSkillType subSkillType = superAbilityType.getSubSkillTypeDefinition();
+ return RankUtils.hasUnlockedSubskill(player, subSkillType);
+ }
+
+ public boolean getPVPEnabled(PrimarySkillType primarySkillType) {
+ return pluginRef.getGeneralConfig().getPVPEnabled(primarySkillType);
+ }
+
+ public boolean getPVEEnabled(PrimarySkillType primarySkillType) {
+ return pluginRef.getGeneralConfig().getPVEEnabled(primarySkillType);
+ }
+
+ public boolean getHardcoreStatLossEnabled(PrimarySkillType primarySkillType) {
+ return pluginRef.getGeneralConfig().getHardcoreStatLossEnabled(primarySkillType);
+ }
+
+ public boolean getHardcoreVampirismEnabled(PrimarySkillType primarySkillType) {
+ return pluginRef.getGeneralConfig().getHardcoreVampirismEnabled(primarySkillType);
+ }
+
+ public ToolType getPrimarySkillToolType(PrimarySkillType primarySkillType) {
+ return primarySkillToolMap.get(primarySkillType);
+ }
+
+ public Set getSubSkills(PrimarySkillType primarySkillType) {
+ //TODO: Cache this!
+ return primarySkillChildrenMap.get(primarySkillType);
+ }
+
+ public double getXpModifier(PrimarySkillType primarySkillType) {
+ return ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType);
+ }
+
+ // TODO: This is a little "hacky", we probably need to add something to distinguish child skills in the enum, or to use another enum for them
+ public static boolean isChildSkill(PrimarySkillType primarySkillType) {
+ switch (primarySkillType) {
+ case SALVAGE:
+ case SMELTING:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Get the localized name for a {@link PrimarySkillType}
+ * @param primarySkillType target {@link PrimarySkillType}
+ * @return the localized name for a {@link PrimarySkillType}
+ */
+ public String getLocalizedSkillName(PrimarySkillType primarySkillType) {
+ //TODO: Replace with current impl
+ return StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(primarySkillType.toString()) + ".SkillName"));
+ }
+
+ public boolean doesPlayerHaveSkillPermission(Player player, PrimarySkillType primarySkillType) {
+ return Permissions.skillEnabled(player, primarySkillType);
+ }
+
+ public boolean canCombatSkillsTrigger(PrimarySkillType primarySkillType, Entity target) {
+ return (target instanceof Player || (target instanceof Tameable && ((Tameable) target).isTamed())) ? getPVPEnabled(primarySkillType) : getPVEEnabled(primarySkillType);
+ }
+
+ public String getCapitalizedPrimarySkillName(PrimarySkillType primarySkillType) {
+ return StringUtils.getCapitalized(primarySkillType.toString());
+ }
+
+ public int getSuperAbilityCooldown(SuperAbilityType superAbilityType) {
+ return pluginRef.getGeneralConfig().getCooldown(superAbilityType);
+ }
+
+ public int getSuperAbilityMaxLength(SuperAbilityType superAbilityType) {
+ return pluginRef.getGeneralConfig().getMaxLength(superAbilityType);
+ }
+
+ public String getSuperAbilityOnLocaleKey(SuperAbilityType superAbilityType) {
+ return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".On";
+ }
+
+ public String getSuperAbilityOffLocaleKey(SuperAbilityType superAbilityType) {
+ return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Off";
+ }
+
+ public String getSuperAbilityOtherPlayerActivationLocaleKey(SuperAbilityType superAbilityType) {
+ return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Other.On";
+ }
+
+ public String getSuperAbilityOtherPlayerDeactivationLocaleKey(SuperAbilityType superAbilityType) {
+ return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + "Other.Off";
+ }
+
+ public String getSuperAbilityRefreshedLocaleKey(SuperAbilityType superAbilityType) {
+ return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Refresh";
+ }
+
+ public int getLevelCap(@NotNull PrimarySkillType primarySkillType) {
+ return mcMMO.p.getGeneralConfig().getLevelCap(primarySkillType);
+ }
+
+ /**
+ * Get the permissions for this ability.
+ *
+ * @param player Player to check permissions for
+ * @param superAbilityType target super ability
+ * @return true if the player has permissions, false otherwise
+ */
+ public boolean superAbilityPermissionCheck(SuperAbilityType superAbilityType, Player player) {
+ switch (superAbilityType) {
+ case BERSERK:
+ return Permissions.berserk(player);
+
+ case BLAST_MINING:
+ return Permissions.remoteDetonation(player);
+
+ case GIGA_DRILL_BREAKER:
+ return Permissions.gigaDrillBreaker(player);
+
+ case GREEN_TERRA:
+ return Permissions.greenTerra(player);
+
+ case SERRATED_STRIKES:
+ return Permissions.serratedStrikes(player);
+
+ case SKULL_SPLITTER:
+ return Permissions.skullSplitter(player);
+
+ case SUPER_BREAKER:
+ return Permissions.superBreaker(player);
+
+ case TREE_FELLER:
+ return Permissions.treeFeller(player);
+
+ default:
+ return false;
+ }
+ }
+
+ public @NotNull List getChildSkills() {
+ return CHILD_SKILLS;
+ }
+
+ public @NotNull ImmutableList getNonChildSkills() {
+ return NON_CHILD_SKILLS;
+ }
+
+ public @NotNull ImmutableList getCombatSkills() {
+ return COMBAT_SKILLS;
+ }
+
+ public @NotNull ImmutableList getGatheringSkills() {
+ return GATHERING_SKILLS;
+ }
+
+ public @NotNull ImmutableList getMiscSkills() {
+ return MISC_SKILLS;
+ }
+}
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
index dcdd446c0..6574224aa 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/SkillUtils.java
@@ -1,7 +1,5 @@
package com.gmail.nossr50.util.skills;
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.HiddenConfig;
import com.gmail.nossr50.datatypes.interactions.NotificationType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -64,10 +62,10 @@ public final class SkillUtils {
* Skill Stat Calculations
*/
- public static @NotNull String[] calculateLengthDisplayValues(@NotNull OnlineMMOPlayer mmoPlayer, float skillValue, @NotNull PrimarySkillType skill) {
- int maxLength = skill.getSuperAbilityType().getMaxLength();
- int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
- int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();
+ public static String[] calculateLengthDisplayValues(Player player, float skillValue, PrimarySkillType skill) {
+ int maxLength = mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill));
+ int abilityLengthVar = mcMMO.p.getAdvancedConfig().getAbilityLength();
+ int abilityLengthCap = mcMMO.p.getAdvancedConfig().getAbilityLengthCap();
int length;
@@ -134,8 +132,8 @@ public final class SkillUtils {
* @param skillName The name of the skill to check
* @return true if this is a valid skill, false otherwise
*/
- public static boolean isSkill(@NotNull String skillName) {
- return Config.getInstance().getLocale().equalsIgnoreCase("en_US") ? mcMMO.p.getSkillRegister().getSkill(skillName) != null : isLocalizedSkill(skillName);
+ public static boolean isSkill(String skillName) {
+ return mcMMO.p.getGeneralConfig().getLocale().equalsIgnoreCase("en_US") ? mcMMO.p.getSkillTools().matchSkill(skillName) != null : isLocalizedSkill(skillName);
}
public static void sendSkillMessage(@NotNull Player player, @NotNull NotificationType notificationType, @NotNull String key) {
@@ -170,8 +168,7 @@ public final class SkillUtils {
//1.13.2+ will have persistent metadata for this item
AbstractPersistentDataLayer compatLayer = mcMMO.getCompatibilityManager().getPersistentDataLayer();
compatLayer.setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
- }
- else {
+ } else {
int duration = 0;
int amplifier = 0;
@@ -193,18 +190,18 @@ public final class SkillUtils {
PrimarySkillType skill = mmoPlayer.getSuperAbilityManager().getAbilityMode(SuperAbilityType.SUPER_BREAKER) ? PrimarySkillType.MINING : PrimarySkillType.EXCAVATION;
- int abilityLengthVar = AdvancedConfig.getInstance().getAbilityLength();
- int abilityLengthCap = AdvancedConfig.getInstance().getAbilityLengthCap();
+ int abilityLengthVar = mcMMO.p.getAdvancedConfig().getAbilityLength();
+ int abilityLengthCap = mcMMO.p.getAdvancedConfig().getAbilityLengthCap();
int ticks;
if(abilityLengthCap > 0)
{
- ticks = PerksUtils.handleActivationPerks(player, Math.min(abilityLengthCap, 2 + (mmoPlayer.getExperienceHandler().getSkillLevel(skill) / abilityLengthVar)),
- skill.getSuperAbilityType().getMaxLength()) * Misc.TICK_CONVERSION_FACTOR;
+ ticks = PerksUtils.handleActivationPerks(player, Math.min(abilityLengthCap, 2 + (mcMMOPlayer.getSkillLevel(skill) / abilityLengthVar)),
+ mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR;
} else {
- ticks = PerksUtils.handleActivationPerks(player, 2 + ((mmoPlayer.getExperienceHandler().getSkillLevel(skill)) / abilityLengthVar),
- skill.getSuperAbilityType().getMaxLength()) * Misc.TICK_CONVERSION_FACTOR;
+ ticks = PerksUtils.handleActivationPerks(player, 2 + ((mcMMOPlayer.getSkillLevel(skill)) / abilityLengthVar),
+ mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR;
}
PotionEffect abilityBuff = new PotionEffect(PotionEffectType.FAST_DIGGING, duration + ticks, amplifier + 10);
diff --git a/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java b/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java
index 234377269..c2218441c 100644
--- a/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java
+++ b/src/main/java/com/gmail/nossr50/util/skills/SmeltingTracker.java
@@ -2,7 +2,6 @@ package com.gmail.nossr50.util.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.util.Permissions;
import com.neetgames.mcmmo.player.OnlineMMOPlayer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -88,7 +87,7 @@ public class SmeltingTracker {
}
public void processFurnaceOwnership(Furnace furnace, Player player) {
- if(!Permissions.skillEnabled(player, PrimarySkillType.SMELTING))
+ if(!mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.SMELTING))
return;
//Don't swap ownership if its the same player
diff --git a/src/main/java/com/gmail/nossr50/util/text/StringUtils.java b/src/main/java/com/gmail/nossr50/util/text/StringUtils.java
index fe4ceeae3..c1ea94ad9 100644
--- a/src/main/java/com/gmail/nossr50/util/text/StringUtils.java
+++ b/src/main/java/com/gmail/nossr50/util/text/StringUtils.java
@@ -31,6 +31,35 @@ public class StringUtils {
return shortDecimal.format(ticks / 20);
}
+ public static String convertToCamelCaseString(String baseString, String splitBy) {
+ String[] substrings = baseString.split(splitBy);
+ String prettyString = "";
+ int size = 1;
+
+ for (String string : substrings) {
+ prettyString = prettyString.concat(getCapitalized(string));
+
+ if (size < substrings.length) {
+ prettyString = prettyString.concat("");
+ }
+
+ size++;
+ }
+
+ return prettyString;
+ }
+
+ public static String getPrettyCamelCaseName(Object o) {
+ return StringUtils.convertToCamelCaseString(o.toString(), "_");
+ }
+
+ public static String getPrettySuperAbilityName(SuperAbilityType superAbilityType) {
+ return StringUtils.getPrettySuperAbilityString(superAbilityType);
+ }
+
+ public static String getPrettySuperAbilityString(SuperAbilityType ability) {
+ return createPrettyString(ability.toString());
+ }
/**
* Creates a string from an array skipping the first n elements
diff --git a/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java b/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java
index 205fcba77..23cb13e06 100644
--- a/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java
+++ b/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java
@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.text;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.config.RankConfig;
import com.gmail.nossr50.datatypes.json.McMMOUrl;
import com.gmail.nossr50.datatypes.json.McMMOWebLinks;
@@ -66,7 +65,7 @@ public class TextComponentFactory {
public static void sendPlayerSubSkillWikiLink(OnlineMMOPlayer mmoPlayer, String subskillformatted)
{
- if(!Config.getInstance().getUrlLinksEnabled())
+ if(!mcMMO.p.getGeneralConfig().getUrlLinksEnabled())
return;
TextComponent.Builder wikiLinkComponent = Component.text().content(LocaleLoader.getString("Overhaul.mcMMO.MmoInfo.Wiki"));
diff --git a/src/main/java/com/gmail/nossr50/util/upgrade/UpgradeManager.java b/src/main/java/com/gmail/nossr50/util/upgrade/UpgradeManager.java
index 55c747ffd..3ed01d378 100644
--- a/src/main/java/com/gmail/nossr50/util/upgrade/UpgradeManager.java
+++ b/src/main/java/com/gmail/nossr50/util/upgrade/UpgradeManager.java
@@ -2,6 +2,7 @@ package com.gmail.nossr50.util.upgrade;
import com.gmail.nossr50.config.ConfigLoader;
import com.gmail.nossr50.datatypes.database.UpgradeType;
+import com.gmail.nossr50.mcMMO;
import java.util.Arrays;
import java.util.EnumSet;
@@ -40,7 +41,7 @@ public class UpgradeManager extends ConfigLoader {
return;
}
- plugin.debug("Saving upgrade status for type " + type.toString() + "...");
+ mcMMO.p.debug("Saving upgrade status for type " + type.toString() + "...");
config.set("Upgrades_Finished." + type.toString(), true);
@@ -60,6 +61,6 @@ public class UpgradeManager extends ConfigLoader {
}
}
- plugin.debug("Needed upgrades: " + Arrays.toString(setNeededUpgrades.toArray(new UpgradeType[setNeededUpgrades.size()])));
+ mcMMO.p.debug("Needed upgrades: " + Arrays.toString(setNeededUpgrades.toArray(new UpgradeType[setNeededUpgrades.size()])));
}
}
diff --git a/src/main/java/net/shatteredlands/shatt/backup/ZipLibrary.java b/src/main/java/net/shatteredlands/shatt/backup/ZipLibrary.java
index 6c1c926ea..398f99449 100644
--- a/src/main/java/net/shatteredlands/shatt/backup/ZipLibrary.java
+++ b/src/main/java/net/shatteredlands/shatt/backup/ZipLibrary.java
@@ -1,6 +1,5 @@
package net.shatteredlands.shatt.backup;
-import com.gmail.nossr50.config.Config;
import com.gmail.nossr50.mcMMO;
import java.io.File;
@@ -27,7 +26,7 @@ public class ZipLibrary {
private static final File REPAIR_FILE = new File(mcMMO.getMainDirectory() + "repair.vanilla.yml");
public static void mcMMOBackup() throws IOException {
- if (Config.getInstance().getUseMySQL()) {
+ if (mcMMO.p.getGeneralConfig().getUseMySQL()) {
mcMMO.p.getLogger().info("This server is running in SQL Mode.");
mcMMO.p.getLogger().info("Only config files will be backed up.");
}
diff --git a/src/main/resources/locale/locale_de.properties b/src/main/resources/locale/locale_de.properties
index 87cfc4240..74333581c 100644
--- a/src/main/resources/locale/locale_de.properties
+++ b/src/main/resources/locale/locale_de.properties
@@ -94,10 +94,10 @@ Broadcasts.LevelUpMilestone = &6(&amcMMO&6) {0}&7 hat nun Level &a{1}&7 mit der
Chat.Channel.Off = &6(&amcMMO-Chat&6) &7Deine Nachrichten werden nicht l\u00E4nger automatisch an die spezifischen Kan\u00E4le versendet.
Chat.Channel.On = &6(&amcMMO-Chat&6) &eDeine Nachrichten werden nun automatisch an den &a{0}&e Kanal gesendet.
Chat.Identity.Console = &6* Konsole *
-Chat.Spy.Party = &6[&eSPION&6-&a{2}&6] &r{0} &b\u2192�� &r{1}
-Chat.Style.Admin = &b(A) &r{0} &b\u2192�� &r{1}
-Chat.Style.Party = &a(P) &r{0} &a\u2192�� &r{1}
-Chat.Style.Party.Leader = &a(P) &r{0} &6\u2192�� &r{1}
+Chat.Spy.Party = &6[&eSPION&6-&a{2}&6] &r{0} &b\u2192 &r{1}
+Chat.Style.Admin = &b(A) &r{0} &b\u2192 &r{1}
+Chat.Style.Party = &a(P) &r{0} &a\u2192 &r{1}
+Chat.Style.Party.Leader = &a(P) &r{0} &6\u2192 &r{1}
Combat.ArrowDeflect = &a&o**Pfeil abgelenkt**
Combat.BeastLore = &a&o**Biestkunde**
@@ -112,9 +112,9 @@ Combat.TouchedFuzzy = &a&o**Du wurdest ungl\u00FCcklich ber\u00FChrt, ein Schwin
Commands.Ability.Off = F\u00E4higkeiten Benutzung &cdeaktiviert
Commands.Ability.On = F\u00E4higkeiten Benutzung &aaktiviert
-Commands.Ability.Toggle = Benutzung von F\u00E4higkeiten wurde f\u00FCr &e{0} ge\u00E4ndert
-Commands.AdminChat.Off = Exklusiver Admin-Chat wurde &c deaktiviert
-Commands.AdminChat.On = Exklusiver Admin-Chat wurde &a aktiviert
+Commands.Ability.Toggle = Benutzung von F\u00E4higkeiten wurde f\u00FCr &e{0} ge\u00E4ndert.
+Commands.AdminChat.Off = Exklusiver Admin-Chat wurde &c deaktiviert.
+Commands.AdminChat.On = Exklusiver Admin-Chat wurde &a aktiviert.
Commands.AdminChatSpy.Chat = &6[Spy: &a{0}&6] &f{1}
Commands.AdminChatSpy.Disabled = mcMMO Party Chat-Spy deaktiviert
Commands.AdminChatSpy.Enabled = mcMMO Party Chat-Spy aktiviert
@@ -137,7 +137,7 @@ Commands.Description.mcability = Schalte die Bereitschaft von F\u00E4higkeiten b
Commands.Description.mcchatspy = Schalte den Party Chat-Spy an oder aus.
Commands.Description.mcconvert = Konvertiert Datenbanktypen oder Erfahrungsformeln.
Commands.Description.mccooldown = Sieh alle F\u00E4higkeiten-Cooldowns.
-Commands.Description.mcgod = Schalte mcMMO godmode an oder aus.
+Commands.Description.mcgod = Schalte mcMMO Godmode an oder aus.
Commands.Description.mchud = \u00C4ndere deinen HUD Stil.
Commands.Description.mcmmo = Zeige eine kurze Beschreibung \u00FCber mcMMO.
Commands.Description.mcnotify = Schalte F\u00E4higkeiten-Hinweise im Chat an oder aus.
@@ -151,7 +151,7 @@ Commands.Description.mctop = Zeige die Skill-Bestenlisten.
Commands.Description.mmocompat = Informationen dar\u00FCber, ob mcMMO im Kompatibilit\u00E4tsmodus oder voll funktionsf\u00E4hig ist.
Commands.Description.mmodebug = (De)aktiviere den Debugging-Modus, welcher n\u00FCtzliche Informationen ausgibt, wenn du einen Block schl\u00E4gst.
Commands.Description.mmoedit = Editiere die Skill-Level eines Spielers.
-Commands.Description.mmoinfo = Lese Details \u00FCber einen Skill oder andere Funktionen.
+Commands.Description.mmoinfo = Zeige Details \u00FCber einen Skill oder andere Funktionen.
Commands.Description.mmoshowdb = Zeige den Namen der aktuellen Datenbank (zur Benutzung mit /mmoupdate).
Commands.Description.mmoupdate = Kopiere Daten von einer alten Datenbank zur aktuell benutzen.
Commands.Description.mmoxpbar = Spielereinstellungen f\u00FCr die mcMMO Erfahrungsleisten.
@@ -174,7 +174,7 @@ Commands.GodMode.Forbidden = [mcMMO] Der Godmode ist in dieser Welt nicht erlaub
Commands.GodMode.Toggle = Godmode wurde f\u00FCr &e{0} aktiviert.
Commands.Healthbars.Changed.BAR = [mcMMO] Deine Lebensanzeige wurde zu &eK\u00E4stchen&f ge\u00E4ndert.
Commands.Healthbars.Changed.DISABLED = [mcMMO] Die Mob-Lebensanzeige wurde &7deaktiviert&f.
-Commands.Healthbars.Changed.HEARTS = [mcMMO]Deine Lebensanzeige wurde zu &cHerzen&f ge\u00E4ndert.
+Commands.Healthbars.Changed.HEARTS = [mcMMO] Deine Lebensanzeige wurde zu &cHerzen&f ge\u00E4ndert.
Commands.Healthbars.Invalid = Ung\u00FCltiger Lebensanzeige-Typ!
Commands.Inspect = &a- Siehe detaillierte Spielerinformationen
Commands.Invite.Success = &aEinladung erfolgreich gesendet.
@@ -184,25 +184,25 @@ Commands.MmoInfo.Header = &3-=[]=====[]&6 MMO Info &3[]=====[]=-
Commands.MmoInfo.Mechanics = &3-=[]=====[]&6 Funktionen &3[]=====[]=-
Commands.MmoInfo.Mystery = &7Diese F\u00E4higkeit hast du noch nicht freigeschaltet, wenn du das tust, kannst du hier Details \u00FCber diese finden!
Commands.MmoInfo.NoMatch = Diese F\u00E4higkeit existiert nicht!
-Commands.MmoInfo.OldSkill = &7mcMMO skills are being converted into an improved modular skill system, unfortunately this skill has not been converted yet and lacks detailed stats. The new system will allow for faster release times for new mcMMO skills and greater flexibility with existing skills.
-Commands.MmoInfo.Stats = STATS: {0}
+Commands.MmoInfo.OldSkill = &7mcMMO Skills werden in ein verbessertes und modulares Skill-System konvertiert - wovon dieser Skill jedoch noch nicht betroffen ist, weswegen detaillierte Statistiken fehlen. Das neue System erm\u00F6glicht eine schnellere Ver\u00F6ffentlichung neuer mcMMO-Skills und eine gr\u00F6ßere Flexibilit\u00E4t mit bereits existenten Skills.
+Commands.MmoInfo.Stats = Statistik: {0}
Commands.MmoInfo.SubSkillHeader = &6Name:&e {0}
Commands.Mmodebug.Toggle = Der mcMMO Debugging-Modus ist nun &6{0}&7, benutze den Befehl erneut, um dies r\u00FCckg\u00E4ngig zu machen. Wenn der Debugging-Modus aktiviert wurde kannst du Bl\u00F6cke schlagen, um n\u00FCtzliche Informationen zu erhalten. Dies ist f\u00FCr den Support sehr n\u00FCtzlich.
Commands.ModDescription = &a- Kurze Modbeschreibung
Commands.NegativeNumberWarn = Benutze keine negativen Zahlen!
Commands.NoConsole = Dieser Befehl kann nicht aus der Konsole verwendet werden.
Commands.NotLoaded = Spielerprofil wurde noch nicht geladen.
-Commands.Notifications.Off = F\u00E4higkeiten Hinweise wurden &cdeaktiviert
-Commands.Notifications.On = F\u00E4higkeiten Hinweise wurden &aaktiviert
+Commands.Notifications.Off = F\u00E4higkeiten Hinweise wurden &cdeaktiviert.
+Commands.Notifications.On = F\u00E4higkeiten Hinweise wurden &aaktiviert.
Commands.Offline = Dieser Befehl funktioniert nur bei eingeloggten Spielern.
Commands.Other = ---[]&aBesondere Befehle&c[]---
Commands.Party.Accept = &a- Nimm Party-Einladung an
Commands.Party.Alliance.Ally = &f{0} &8Ist verb\u00FCndet mit: &f{1}
-Commands.Party.Alliance.AlreadyAllies = Deine Party ist bereits in einem B\u00FCndnis. Trenne es mit&3/party alliance disband
+Commands.Party.Alliance.AlreadyAllies = Deine Party ist bereits in einem B\u00FCndnis. Trenne es mit&3/party alliance disband&e.
Commands.Party.Alliance.Header = -----[]&aParty-B\u00FCndnisse&c[]-----
Commands.Party.Alliance.Help.0 = Diese Party ist in keinem B\u00FCndnis. Lade einen Party-Anf\u00FChrer ein.
-Commands.Party.Alliance.Help.1 = &c um zu verb\u00FCnden &3/party alliance invite &c.
-Commands.Party.Alliance.Invite.0 = ALERT: &aDu hast eine B\u00FCndnis-Anfrage f\u00FCr {0} von {1} erhalten.
+Commands.Party.Alliance.Help.1 = &c Zum Verb\u00FCnden: &3/party alliance invite &c.
+Commands.Party.Alliance.Invite.0 = ACHTUNG: &aDu hast eine B\u00FCndnis-Anfrage f\u00FCr {0} von {1} erhalten.
Commands.Party.Alliance.Invite.1 = Tippe &a/party alliance accept&e um die Anfrage anzunehmen.
Commands.Party.Alliance.Invite.Accepted = &aB\u00FCndnis-Anfrage angenommen
Commands.Party.Alliance.Members.Header = -----[]&aB\u00FCndnis-Mitglieder&c[]-----
@@ -216,7 +216,7 @@ Commands.Party.ExpShare = &7Erfahrung &3({0})
Commands.Party.Features.Header = -----[]&aFunktionen&c[]-----
Commands.Party.Header = &c-----[]&aParty&c[]-----
Commands.Party.Invite = &a- Sende eine Party-Einladung
-Commands.Party.Invite.0 = ALERT: &aDu hast eine Party-Einladung f\u00FCr {0} von {1} erhalten.
+Commands.Party.Invite.0 = ACHTUNG: &aDu hast eine Party-Einladung f\u00FCr {0} von {1} erhalten.
Commands.Party.Invite.1 = &eBenutze &a/party accept&e um die Einladung anzunehmen.
Commands.Party.Invite.Accepted = &aEinladung angenommen. Du bist der {0} Party beigetreten.
Commands.Party.ItemShare = &7Item &3({0})
@@ -231,7 +231,7 @@ Commands.Party.PartyFull = &6{0}&c ist voll!
Commands.Party.PartyFull.Invite = Du kannst &e{0}&c nicht zur Party &a{1}&c einladen, weil sie schon &3{2}&c Spieler hat!
Commands.Party.PartyFull.InviteAccept = Du kannst der Party &a{0}&c nicht beitreten, weil sie schon &3{1}&c Spieler hat!
Commands.Party.Quit = &a- Verlasse deine aktuelle Party.
-Commands.Party.Rename = &7Party Name wurde zu &f{0} &7ver\u00E4ndert
+Commands.Party.Rename = &7Party Name wurde zu &f{0} &7ver\u00E4ndert.
Commands.Party.SetSharing = &7Party {0} teilen: &3{1}
Commands.Party.ShareMode = &8Teilen-Modus:
Commands.Party.Status = &8Name: &f{0} {1} &8Level: &3{2}
@@ -245,11 +245,11 @@ Commands.Party2 = &a- Tritt der Party eines Spielers bei.
Commands.PowerLevel = &4Gesamtlevel: &a{0}
Commands.PowerLevel.Capped = &4Gesamtlevel: &a{0} &4H\u00F6chstlevel: &e{1}
Commands.PowerLevel.Leaderboard = --mcMMO&9 Power-Level &eBestenliste--
-Commands.Reset = &a- Setze ein Skilllevel auf 0
-Commands.Reset.All = &aAlle deine Skilllevel wurden erfolgreich zur\u00FCckgesetzt.
-Commands.Reset.Single = &aDein {0} Skilllevel wurde erfolgreich zur\u00FCckgesetzt.
+Commands.Reset = &a- Setze ein Skill-Level auf 0
+Commands.Reset.All = &aAlle deine Skill-Level wurden erfolgreich zur\u00FCckgesetzt.
+Commands.Reset.Single = &aDein {0} Skill-Level wurde erfolgreich zur\u00FCckgesetzt.
Commands.Scoreboard.Clear = &3Das Scoreboard wurde ausgeblendet.
-Commands.Scoreboard.Help.0 = &6 == &aHilfe f\u00FCr&c/mcscoreboard&6 ==
+Commands.Scoreboard.Help.0 = &6 == &aHilfe f\u00FCr&c /mcscoreboard&6 ==
Commands.Scoreboard.Help.1 = &3/mcscoreboard&b clear &f - blende die \u00DCbersicht aus
Commands.Scoreboard.Help.2 = &3/mcscoreboard&b keep &f - behalte die \u00DCbersicht offen
Commands.Scoreboard.Help.3 = &3/mcscoreboard&b time [n] &f - blende die \u00DCbersicht nach &dn&f Sekunden aus
@@ -281,10 +281,10 @@ Commands.Usage.Rate = Rate
Commands.Usage.Skill = Skill
Commands.Usage.SubSkill = F\u00E4higkeit
Commands.Usage.XP = Erfahrung
-Commands.XPBar.DisableAll = &6Alle mcMMO Erfahrungsleisten wurden deaktiviert, benutze /mmoxpbar reset um die Standardeinstellungen wiederherzustellen.
+Commands.XPBar.DisableAll = &6Alle mcMMO Erfahrungsleisten wurden deaktiviert, benutze &c/mmoxpbar reset&6 um die Standardeinstellungen wiederherzustellen.
Commands.XPBar.Reset = &6Die Erfahrungsleisten-Einstellungen f\u00FCr mcMMO wurden zur\u00FCckgesetzt.
Commands.XPBar.SettingChanged = &6Die Erfahrungsleisten-Einstellungen f\u00FCr &a{0}&6 wurden gesetzt auf: &a{1}
-Commands.XPBar.Usage = Die korrekte Verwendung ist /mmoxpbar
+Commands.XPBar.Usage = Die korrekte Verwendung ist &a/mmoxpbar
Commands.XPGain = &8XP-Zuwachs: &f{0}
Commands.XPGain.Acrobatics = Fallen
Commands.XPGain.Alchemy = Tr\u00E4nke brauen
@@ -316,7 +316,7 @@ Commands.mcconvert.Experience.Finish = &7Konvertierung vollendet - es wird jetzt
Commands.mcconvert.Experience.Invalid = Unbekannter Formeltyp! G\u00FCltige Typen sind: &aLINEAR &cund &aEXPONENTIAL.
Commands.mcconvert.Experience.Same = Formeltyp {0} wird bereits verwendet.
Commands.mcconvert.Experience.Start = &7Beginne Konvertierung von Kurve {0} zu Kurve {1}.
-Commands.mcgod = &a- Schalte Godmode um
+Commands.mcgod = &a- Schalte den Godmode um
Commands.mchud.Invalid = Das ist kein g\u00FCltiger HUD Typ.
Commands.mcpurge.Success = &aDie Datenbank wurde erfolgreich ges\u00E4ubert!
Commands.mcrank.Heading = &6-=Pers\u00F6nliche Rangliste=-
@@ -339,19 +339,19 @@ Commands.ptp.Enabled = Party-Teleportierung &aaktiviert
Commands.ptp.NoRequests = Du hast aktuell keine Teleportierungsanfragen.
Commands.ptp.NoWorldPermissions = &c[mcMMO] Du hast nicht die n\u00F6tigen Rechte um dich in die Welt {0} zu teleportieren.
Commands.ptp.Request1 = {0} &am\u00F6chte sich zu dir teleportieren.
-Commands.ptp.Request2 = &aUm zu teleportieren tippe &e/ptp accept&a. Die Anfrage l\u00E4uft in &c{0} &aSekunden aus.
+Commands.ptp.Request2 = &aZum Teleportieren tippe &e/ptp accept&a. Die Anfrage l\u00E4uft in &c{0} &aSekunden aus.
Commands.ptp.RequestExpired = &cParty-Teleportierungsanfrage ist ausgelaufen.
Commands.xplock.locked = &6Deine Erfahrungsanzeige ist nun auf {0} festgesetzt!
Commands.xplock.unlocked = &6Deine Erfahrungsanzeige ist nun wieder &afreigeschaltet&6!
Commands.xprate.modified = Die Erfahrungsrate wurde auf {0} gesetzt!
Commands.xprate.over = Das Bonuserfahrungs-Event f\u00FCr Skills ist vor\u00FCber!
-Commands.xprate.proper.0 = &cKorrekte Eingabe f\u00FCr Erfahrungs Raten Wechsel: /xprate
-Commands.xprate.proper.1 = &cKorrekte Eingabe f\u00FCr R\u00FCcksetzung auf Standard Erfahrungs Rate: /xprate reset
+Commands.xprate.proper.0 = &cKorrekte Eingabe f\u00FCr Erfahrungsratenwechsel: /xprate
+Commands.xprate.proper.1 = &cKorrekte Eingabe f\u00FCr R\u00FCcksetzung auf Standard-Erfahrungsrate: /xprate reset
Commands.xprate.proper.2 = &cBitte entscheide mit true/false ob dies ein XP-Event ist oder nicht.
Commands.xprate.started.0 = &6Ein Bonuserfahrungs-Event f\u00FCr Skills hat begonnen!
Commands.xprate.started.1 = &6Die Erfahrungsrate f\u00FCr Skills liegt jetzt bei {0}x!
-Compatibility.Layer.PartialSupport = &6Diese Version besitzt keine vollst\u00E4ndige Unterst\u00FCtzung f\u00FCr &a{0}&6, jedoch verwendet mcMMO ein System, was die fehlenden Features versucht zu emulieren.
+Compatibility.Layer.PartialSupport = &6Diese Version besitzt keine vollst\u00E4ndige Unterst\u00FCtzung f\u00FCr &a{0}&6, jedoch verwendet mcMMO ein System, welches versucht die fehlenden Features zu emulieren.
Compatibility.Layer.Unsupported = &6Diese Version von Minecraft ist nicht kompatibel mit &a{0}&6.
Effects.Child.Overhaul = &3Unterskill Level&e {0}&3: {1}
@@ -375,7 +375,7 @@ Excavation.SubSkill.Archaeology.Description = Ergrabe die Sch\u00E4tze der Unter
Excavation.SubSkill.Archaeology.Name = Arch\u00E4ologie
Excavation.SubSkill.Archaeology.Stat = Arch\u00E4ologie Erfahrungspunkte-Chance
Excavation.SubSkill.Archaeology.Stat.Extra = Arch\u00E4ologie Erfahrungspunkte-Anzahl
-Excavation.SubSkill.GigaDrillBreaker.Description = Dreifache Droprate, dreifache Erfahrung und Bonus-Geschwindigkeit.
+Excavation.SubSkill.GigaDrillBreaker.Description = Dreifache Droprate, dreifache Erfahrung und Bonus-Abbaugeschwindigkeit.
Excavation.SubSkill.GigaDrillBreaker.Name = Gigabohrer
Excavation.SubSkill.GigaDrillBreaker.Stat = Gigabohrer-Dauer
@@ -395,8 +395,8 @@ Fishing.Scared = &7&oHektische Bewegungen ver\u00E4ngstigen Fische!
Fishing.SkillName = Angeln
Fishing.SubSkill.FishermansDiet.Description = Verbessert den N\u00E4hrwert von geangelter Nahrung.
Fishing.SubSkill.FishermansDiet.Name = Fischers-Di\u00E4t
-Fishing.SubSkill.FishermansDiet.Stat = Fishers-Di\u00E4t:&a Rang {0}
-Fishing.SubSkill.IceFishing.Description = Erm\u00F6glicht dir in Eisbiomen zu angeln.
+Fishing.SubSkill.FishermansDiet.Stat = Fischers-Di\u00E4t:&a Rang {0}
+Fishing.SubSkill.IceFishing.Description = Erm\u00F6glicht es dir in Eisbiomen zu angeln.
Fishing.SubSkill.IceFishing.Name = Eisangeln
Fishing.SubSkill.IceFishing.Stat = Eisangeln
Fishing.SubSkill.MagicHunter.Description = Finde verzauberte Gegenst\u00E4nde.
@@ -406,7 +406,7 @@ Fishing.SubSkill.MasterAngler.Description = Fische k\u00F6nnen h\u00E4ufiger gef
Fishing.SubSkill.MasterAngler.Name = Superangel
Fishing.SubSkill.MasterAngler.Stat = Mindestwartezeit beim Angeln reduziert um: &a-{0} Sekunden
Fishing.SubSkill.MasterAngler.Stat.Extra = Maximalwartezeit beim Angeln reduziert um: &a-{0} Sekunden
-Fishing.SubSkill.Shake.Description = Rei\u00DFe mit deiner Angel Gegenst\u00E4nde weg von Lebewesen und Spielern.
+Fishing.SubSkill.Shake.Description = Entrei\u00DFe Lebewesen und Spielern mit deiner Angel Gegenst\u00E4nde.
Fishing.SubSkill.Shake.Name = Rei\u00DFen
Fishing.SubSkill.Shake.Stat = Rei\u00DFen Chance
Fishing.SubSkill.TreasureHunter.Description = Angle verschiedene Objekte.
@@ -414,10 +414,10 @@ Fishing.SubSkill.TreasureHunter.Name = Schatz-J\u00E4ger
Fishing.SubSkill.TreasureHunter.Stat = Schatz-J\u00E4ger Rang: &a{0}&3/&a{1}
Fishing.SubSkill.TreasureHunter.Stat.Extra = Drop-Rate: &7\u00DCblich: &e{0} &aUn\u00FCblich: &e{1}\n&9Selten: &e{2} &dEpisch: &e{3} &6Legend\u00E4r: &e{4} &bMythic: &e{5}
-Guides.Acrobatics.Section.0 = &3\u00DCber Akrobatik:\n&eAkrobatik ist die Kunst sich anmutig fortzubewegen.\n&eFall- und Kampfschaden werden reduziert\n\n&3XP GAIN:\n&eErfahrung sammelst du indem du in K\u00E4mpfen\n&eausweichst oder St\u00FCrze aus gro\u00DFen H\u00F6hen \u00FCberlebst.
+Guides.Acrobatics.Section.0 = &3\u00DCber Akrobatik:\n&eAkrobatik ist die Kunst sich anmutig fortzubewegen.\n&eFall- und Kampfschaden werden reduziert.\n\n&3XP-Zuwachs:\n&eErfahrung sammelst du indem du in K\u00E4mpfen\n&eausweichst oder St\u00FCrze aus gro\u00DFen H\u00F6hen \u00FCberlebst.
Guides.Acrobatics.Section.1 = &3Wie funktioniert Abrollen?\n&eAb und zu rollst du beim Fallen ab und der Fallschaden wird\n&ereduziert. Wenn du die Schleichen-Taste w\u00E4hrend dem Fallen\n&eh\u00E4ltst, verdoppelt sich die Chance abzurollen.\n&eIn dem Fall rollst du anmutig ab.\n&eAnmutige Rollen sind wie normale Rollen, nur dass\n&esie \u00F6fter passieren und damit mehr Schutz vor St\u00FCrzen\n&eliefern.
Guides.Acrobatics.Section.2 = &3Wie funktioniert Ausweichen?\n&eAusweichen ist eine passive F\u00E4higkeit\n&edie ab und zu den Schaden in K\u00E4mpfen halbiert.\n&eDie Chance auszuweichen ist abh\u00E4ngig vom \n&eAkrobatiklevel.
-Guides.Alchemy.Section.0 = &3\u00DCber Alchemie:\n&eIn Alchemie musst du Tr\u00E4nke brauen.\n&eMit h\u00F6herem Level werden die Tr\u00E4nke schneller\n&egebraut und neue Zutaten f\u00FCr zun\u00E4chst unerh\u00E4ltliche Tr\u00E4nke \n&efreigeschaltet.\n\n&3XP ZUWACHS:\n&eTr\u00E4nke brauen.
+Guides.Alchemy.Section.0 = &3\u00DCber Alchemie:\n&eIn Alchemie musst du Tr\u00E4nke brauen.\n&eMit h\u00F6herem Level werden die Tr\u00E4nke schneller\n&egebraut und neue Zutaten f\u00FCr zun\u00E4chst unerh\u00E4ltliche Tr\u00E4nke \n&efreigeschaltet.\n\n&3XP-Zuwachs:\n&eTr\u00E4nke brauen.
Guides.Alchemy.Section.1 = &3Wie funktioniert Katalyse?\n&eKatalyse beschleunigt das Brauen von Tr\u00E4nken bis\n&ezu 4-facher Geschwindigkeit bei Level 1000.
Guides.Alchemy.Section.2 = &3Wie funktioniert Gebr\u00E4u?\n&eGebr\u00E4u erm\u00F6glich das Brauen weiterer Tr\u00E4nke mit neuen\n&eZutaten.\n&eWelche Zutaten m\u00F6glich sind, h\u00E4ngt vom Rang ab.\n&eInsgesamt gibt es 8 R\u00E4nge freizuschalten.
Guides.Alchemy.Section.3 = &3Gebr\u00E4u Tier 1 Zutaten:\n&eLohnenstaub, Fermentierte Spinnenaugen, Ghast Tr\u00E4nen,\n&eRedstone, Glowstonestaub, Zucker, Glitzernde Melone,\n&eGoldene Karotte, Magma Creme, Netherwarzen, Spinnenaugen, \n&eSchwarzpulver, Seerose, Kugelfisch (Vanilla Tr\u00E4nke)
@@ -425,23 +425,23 @@ Guides.Alchemy.Section.4 = &3Gebr\u00E4u Tier 2 Zutaten:\n&eKarotte (Eile)\n&eSc
Guides.Alchemy.Section.5 = &3Gebr\u00E4u Tier 4 Zutaten:\n&eApfel (Gesundheitsboost)\n&eVerrottetes Fleisch (Hunger)\n\n&3Gebr\u00E4u Tier 5 Zutaten:\n&eBrauner Pilz(\u00DCbelkeit)\n&eTintensack (Blindheit)
Guides.Alchemy.Section.6 = &3Gebr\u00E4u Tier 6 Zutaten:\n&eGras (S\u00E4ttigung)\n\n&3Gebr\u00E4u Tier 7 Zutaten:\n&eGiftige Kartoffel (Verwesung)\n\n&3Gebr\u00E4u Tier 8 Zutaten:\n&eNormaler Goldener Apfel (Resistenz)
Guides.Archery.Section.0 = &3\u00DCber Bogenschie\u00DFen:\n&eIn Bogenschie\u00DFen geht es um die Verwendung von Pfeil und\n&eBogen.\n\n&eEs gibt unterschiedliche Kampfboni, wie Zusatzschaden,\n&eder mit dem Level steigt und der F\u00E4higkeit Feinde im PVP\n&ezu bet\u00E4uben. Zus\u00E4tzlich kannst du einige verschossene\n&ePfeile aus den Leichen deiner Feinde wiedergewinnen.
-Guides.Archery.Section.1 = &3XP ZUWACHS:\n&eXP erh\u00E4ltst du durch das Abschie\u00DFen von Monstern und\n&eanderen Spielern.
+Guides.Archery.Section.1 = &3XP-Zuwachs:\n&eXP erh\u00E4ltst du durch das Abschie\u00DFen von Monstern und\n&eanderen Spielern.
Guides.Archery.Section.2 = &3Wie funktioniert der Kunstschuss?\n&eKunstschuss erh\u00F6ht den Schaden deines Schusses.\n&eDer Zusatzschaden steigt mit deinem Bogen-Level.\n&eIn den Standardeinstellungen steigt der Schaden um 10%\n&ealle 50 Level, mit einem Maximum von 200% extra.
Guides.Archery.Section.3 = &3Wie Funktioniert Bet\u00E4ubung?\n&eDu hast eine passive Chance andere Spieler\n&ezu bet\u00E4uben wenn du sie anschie\u00DFt. Der Spieler wird\n&egezwungen f\u00FCr eine kurze Weile senkrecht nach oben zu\n&eschauen.\n&eEin Bet\u00E4ubungsschuss f\u00FCgt au\u00DFerdem 4 Schadenspunkte \n&e(2 Herzen) extra zu.
Guides.Available = &7Anleitung f\u00FCr {0} vorhanden - tippe /{1} ? [Seite]
Guides.Axes.Section.0 = &3\u00DCber Axt:\n&eMit dem Axt-Skill kannst du die Axt f\u00FCr viel mehr als\n&enur abholzen verwenden! Du kannst Monster und Spieler\n&esprichw\u00F6rtlich weghacken und ihnen t\u00F6dliche\n&eSchl\u00E4ge verpassen oder sie zur\u00FCckweichen lassen.\n&eDeine Axt zerst\u00F6rt au\u00DFerdem sehr gut R\u00FCstungen,\n&ewas mit h\u00F6herem Level noch mehr ansteigt.
-Guides.Axes.Section.1 = &3XP ZUWACHS:\n&eUm XP zu bekommen musst du Spieler oder Monster \n&emit einer Axt schlagen.
+Guides.Axes.Section.1 = &3XP-Zuwachs:\n&eUm XP zu bekommen musst du Spieler oder Monster \n&emit einer Axt schlagen.
Guides.Axes.Section.2 = &3Wie funktioniert der Sch\u00E4delspalter?\n&eDiese F\u00E4higkeit erlaubt dir einen Angriff mit Fl\u00E4chenschaden\n&eauszuf\u00FChren.\n&eDer Fl\u00E4chenschaden ist halb so gro\u00DF wie der \n&eHauptangriff, also perfekt f\u00FCr gro\u00DFe Ansammlungen von Mobs.
-Guides.Axes.Section.3 = &3Wie funktionieren kritische Treffer?\n&eKritische Treffer sind eine passive F\u00E4higkeit\n&edie ab und zu Zusatzschaden zuf\u00FCgen.\n&eIn den Standardeinstellungen wird alle 2 Level \n&edie Chance um 0.1% erh\u00F6ht. Das f\u00FCgt Mobs\n&edoppelten und anderen Spielern 1,5 fachen Schaden zu.
+Guides.Axes.Section.3 = &3Wie funktionieren kritische Treffer?\n&eKritische Treffer sind eine passive F\u00E4higkeit\n&edie ab und zu Zusatzschaden zuf\u00FCgen.\n&eIn den Standardeinstellungen wird alle 2 Level \n&edie Chance um 0.1% erh\u00F6ht. Das f\u00FCgt Mobs\n&edoppelten und anderen Spielern 1,5-fachen Schaden zu.
Guides.Axes.Section.4 = &3Wie funktioniert die Axt-Beherrschung?\n&eAxt-Beherrschung ist eine passive F\u00E4higkeit die deinen\n&eAxt-Schl\u00E4gen Zusatzschaden hinzuf\u00FCgt.\n&eStandardm\u00E4\u00DFig steigt der Schaden um 1 alle 50 Level,\n&emaximal auf 4 Extraschaden bei Level 200.
Guides.Axes.Section.5 = &3Wie funktioniert Wucht?\n&eSchlage m\u00E4chtig zu und zerst\u00F6re R\u00FCstungen!\n&eWucht hat eine passive Chance gegnerische\n&eR\u00FCstung zu besch\u00E4digen. Dieser Schaden steigt mit deinem Axt-\n&eLevel.
-Guides.Excavation.Section.0 = &3\u00DCber Graben:\n&eGraben ist die F\u00E4higkeit Sch\u00E4tze im Dreck zu finden.\n&eDurch Aufgraben des Landes wirst du Sch\u00E4tze finden.\n&eJe l\u00E4nger du das tust, desto mehr Sch\u00E4tze findest du.\n\n&3XP ZUWACHS:\n&eXP erh\u00E4ltst du durch Schaufeln.\n&eNur bestimmte Materialen geben XP und Sch\u00E4tze.
+Guides.Excavation.Section.0 = &3\u00DCber Graben:\n&eGraben ist die F\u00E4higkeit Sch\u00E4tze im Dreck zu finden.\n&eDurch Aufgraben des Landes wirst du Sch\u00E4tze finden.\n&eJe l\u00E4nger du das tust, desto mehr Sch\u00E4tze findest du.\n\n&3XP-Zuwachs:\n&eXP erh\u00E4ltst du durch Schaufeln.\n&eNur bestimmte Materialen geben XP und Sch\u00E4tze.
Guides.Excavation.Section.1 = &3Kompatible Materialien:\n&eGras, Erde, Sand, Lehm, Kies, Myzel, Seelensand, Schnee
Guides.Excavation.Section.2 = &3Wie funktioniert der Giga-Bohrer?\n&eHalte eine Schaufel in der Hand und mach Rechtsklick.\n&eVon nun an hast du ca. 4 Sekunden um einen kompatiblem\n&eBlock abzubauen.\n&eDaraufhin wird der Giga-Bohrer aktiviert.
Guides.Excavation.Section.3 = &3Was ist der Giga-Bohrer?\n&eGiga-Bohrer ist eine F\u00E4higkeit deren Dauer vom Graben-Skill\n&eabh\u00E4ngt.\n&eEs verdreifacht die Chance Sch\u00E4tze zu finden\n&eund erm\u00F6glicht sofortiges Abbauen kompatibler Materialien.
Guides.Excavation.Section.4 = &3Wie funktioniert der Schatz-J\u00E4ger?\n&eJeder m\u00F6gliche Schatz hat seine eigene Level-Voraussetzung\n&eum zu erscheinen, folglich ist es schwer&ezu sagen inwiefern es \n&edir hilft ein h\u00F6heres Level zu haben.\n&eJe h\u00F6her das Level, desto mehr Sch\u00E4tze k\u00F6nnen gefunden\n&ewerden.
Guides.Excavation.Section.5 = Beachte au\u00DFerdem, dass jedes kompatible Material seine\n&eeigenen einzigartigen Sch\u00E4tze hat.\n&eAnders ausgedr\u00FCckt: Sch\u00E4tze die du in Kies findest\n&egibt es nicht zwingend in Erde.
-Guides.Fishing.Section.0 = &3\u00DCber Angeln:\n&eMit dem Angeln-Skill ist Angeln wieder aufregend!\n&eFinde versteckte Sch\u00E4tze oder rei\u00DFe Items von Monstern.\n\n&3XP ZUWACHS:\n&eFang Fische.
+Guides.Fishing.Section.0 = &3\u00DCber Angeln:\n&eMit dem Angeln-Skill ist Angeln wieder aufregend!\n&eFinde versteckte Sch\u00E4tze oder rei\u00DFe Items von Monstern.\n\n&3XP-Zuwachs:\n&eFange Fische.
Guides.Fishing.Section.1 = &3Wie funktioniert der Schatz-J\u00E4ger?\n&eMit dieser F\u00E4higkeit kannst du beim Angeln Sch\u00E4tze finden.\n&eDiese k\u00F6nnen sogar verzaubert sein!\n&eJeder m\u00F6gliche Schatz kann mit jedem Level gefunden\n&ewerden. Die H\u00E4ufigkeit h\u00E4ngt von dem Wert des Items ab.\n&eJe h\u00F6her der Angeln-Skill ist, desto einfacher wird es\n&ewertvolle Sch\u00E4tze zu finden.
Guides.Fishing.Section.2 = &3Wie funktioniert Eisangeln?\n&eMit dieser F\u00E4higkeit kannst du in Eisseen angeln!\n&eWirf deine Angeln in einem Eissee aus\n&eum ein kleines Loch zum Angeln zu erstellen.
Guides.Fishing.Section.3 = &3Wie funktioniert die Profiangel?\n&eMit dieser passiven F\u00E4higkeit bei\u00DFen mehr Fische an.\n&eSobald die F\u00E4higkeit freigeschaltet ist bringt das Angeln\n&ein einem Boot oder Ozean die doppelte \n&eAnbei\u00DFchance.
@@ -449,15 +449,15 @@ Guides.Fishing.Section.4 = &3Wie funktioniert Rei\u00DFen?\n&eDiese F\u00E4higke
Guides.Fishing.Section.5 = &3Wie funktioniert die Fischer-Mahlzeit?\n&eDu wirst beim Essen von Fisch besser satt.
Guides.Fishing.Section.6 = &3Bemerkung zum Angeln:\n&eAngel-Drops sind vollkommen anpassbar.\n&eErgebnisse unterscheiden sich deshalb von Server zu Server.
Guides.Header = &6-=&a{0} Anleitung&6=-
-Guides.Herbalism.Section.0 = &3\u00DCber Kr\u00E4uterkunde\n&eIn Kr\u00E4uterkunde geht es um das Ernten.\n\n&3XP ZUWACHS:\n&eErnte Pflanzen.
+Guides.Herbalism.Section.0 = &3\u00DCber Kr\u00E4uterkunde\n&eIn Kr\u00E4uterkunde geht es um das Ernten.\n\n&3XP-Zuwachs:\n&eErnte Pflanzen.
Guides.Herbalism.Section.1 = &3Kompatible Pflanzen:\n&eWeizen, Kartoffeln, Karotten, Melonen, K\u00FCrbisse,\n&eZuckerrohr, Kakaobohnen, Blumen, Kakteen,\n&ePilze, Netherwarzen, Seerosen und Ranken.
Guides.Herbalism.Section.2 = &3Wie funktioniert Gr\u00FCnes Land?\n&eGr\u00FCnes Land ist eine aktive F\u00E4higkeit die du aktivierst indem du\n&emit einer Harke in der Hand rechtsklickst.\n&eGr\u00FCnes Land erm\u00F6glicht einen 3-fachen Ertrag beim Ernten.\n&eAu\u00DFerdem erm\u00F6glich es Leben einzuhauchen und sie\n&emithilfe von Samen aus dem Inventar zu verwandeln.
Guides.Herbalism.Section.3 = &3Wie funktioniert der Gr\u00FCne Daumen (Samen)?\n&eDiese passive F\u00E4higkeit pflanz automatisch beim Ernten nach.\n&eDer Erfolg h\u00E4ngt vom Kr\u00E4uterkunde Level ab.
-Guides.Herbalism.Section.4 = &3Wie funktioniert der Gr\u00FCne Daumen(Blocks)?\n&eDiese aktive F\u00E4higkeit erm\u00F6glich es Bl\u00F6cke in ihre \n&e"naturverwandte" Form zu verwandeln. Klicke dazu mit der\n&erechten Maustaste auf einen Block, w\u00E4hrend du Samen in\n&eder Hand h\u00E4ltst. \n&ePro Versuch kostet es dich einen Samen.\n&eDer Erfolg h\u00E4ngt vom Kr\u00E4uterkunde-Level ab.
+Guides.Herbalism.Section.4 = &3Wie funktioniert der Gr\u00FCne Daumen (Bl\u00F6cke)?\n&eDiese aktive F\u00E4higkeit erm\u00F6glich es Bl\u00F6cke in ihre \n&e"naturverwandte" Form zu verwandeln. Klicke dazu mit der\n&erechten Maustaste auf einen Block, w\u00E4hrend du Samen in\n&eder Hand h\u00E4ltst. \n&ePro Versuch kostet es dich einen Samen.\n&eDer Erfolg h\u00E4ngt vom Kr\u00E4uterkunde-Level ab.
Guides.Herbalism.Section.5 = &3Wie funktioniert das Bauernfr\u00FChst\u00FCck?\n&eDu wirst beim Essen von Brot, Keksen, Melonen, Pilzsuppe,\n&eKarotten und Kartoffeln satter.
Guides.Herbalism.Section.6 = &3Wie funktioniert Hylians Gl\u00FCck?\n&eDiese passive F\u00E4higkeit gibt dir eine Chance Items zu finden\n&ewenn du bestimmte Bl\u00F6cke mit dem Schwert abbaust.
Guides.Herbalism.Section.7 = &3Wie funktionieren Doppeldrops?\n&eDu erh\u00E4ltst beim Ernten mehr Ertrag.
-Guides.Mining.Section.0 = &3\u00DCber Bergbau:\n&eIm Bergbau musst du Steine und Erze sammeln. Du erh\u00E4ltst\n&eab und zu zus\u00E4tzliche Drops.\n\n&3XP ZUWACHS:\n&eUm Erfahrung zu sammeln musst du mit der Spitzhacke abbauen.\n&eNur bestimmte Bl\u00F6cke geben XP.
+Guides.Mining.Section.0 = &3\u00DCber Bergbau:\n&eIm Bergbau musst du Steine und Erze sammeln. Du erh\u00E4ltst\n&eab und zu zus\u00E4tzliche Drops.\n\n&3XP-Zuwachs:\n&eUm Erfahrung zu sammeln musst du mit der Spitzhacke abbauen.\n&eNur bestimmte Bl\u00F6cke geben XP.
Guides.Mining.Section.1 = &3Kompatible Materialien:\n&eStein, Kohleerz, Eisenerz, Golderz, Diamanterz, Redstoneerz,\n&eLapiserz, Obsidian, Bemooster Bruchstein, Endstein,\n&eGlowstone, und Netherrack.
Guides.Mining.Section.2 = &3Wie funktioniert der Super-Brecher?:\n&eMache einen Rechtsklick w\u00E4hrend du eine Spitzhacke in der\n&eHand h\u00E4ltst.\n&eVon nun an hast du ungef\u00E4hr 4 Sekunden um ein mit Bergbau\n&ekompatibles Material abzubauen, daraufhin wird der Super-Brecher\n&eaktiviert.
Guides.Mining.Section.3 = &3Was ist der Super-Brecher?\n&eSuper-Brecher ist eine F\u00E4higkeit deren Dauer\n&evom Bergbau-Skill abh\u00E4ngt. Es verdreifacht die \n&eChance Sch\u00E4tze zu finden und erm\u00F6glicht\n&esofortiges Abbauen kompatibler Materialien.
@@ -465,45 +465,45 @@ Guides.Mining.Section.4 = &3Wie benutzt man Z\u00FCndstoff?:\n&eHalte eine Spitz
Guides.Mining.Section.5 = &3Wie funktioniert Z\u00FCndstoff?\n&eZ\u00FCndstoff ist eine F\u00E4higkeit mit einer Abklingzeit, deren St\u00E4rke\n&evom Level abh\u00E4ngt. Sie erlaubt dir beim Abbauen mit TNT dieses\n&eaus der Ferne zu z\u00FCnden. Z\u00FCndstoff besteht aus 3 Teilen.\n&eErstens dem Sprengmeister mit gr\u00F6\u00DFeren Explosionen.\n&eZweitens dem Explosions-Experten, der Schaden von TNT\n&ereduziert.\n&eDie dritte F\u00E4higkeit erh\u00F6ht einfach den Erzertrag\n&eund reduziert den Schutt.
Guides.Page.Invalid = Keine g\u00FCltige Seitenzahl!
Guides.Page.OutOfRange = Es gibt nur insgesamt {0} Seiten.
-Guides.Repair.Section.0 = &3\u00DCber Reparatur:\n&eReparatur erlaubt dir an einem Eisenblock Werkzeuge und\n&eWaffen zu reparieren.\n\n&3XP ZUWACHS:\n&eRepariere Werkzeuge am Eisenblock-Amboss\n&cAchtung: &eDas ist nicht der normale Minecraft Amboss!
+Guides.Repair.Section.0 = &3\u00DCber Reparatur:\n&eReparatur erlaubt dir an einem Eisenblock Werkzeuge und\n&eWaffen zu reparieren.\n\n&3XP-Zuwachs:\n&eRepariere Werkzeuge am Eisenblock-Amboss\n&cAchtung: &eDas ist nicht der normale Minecraft Amboss!
Guides.Repair.Section.1 = &3Wie kann ich Reparatur verwenden?\n&ePlatziere einen mcMMO Amboss, halte das zu reparierende Item\n&ein der Hand und klicke mit der rechten Maustaste auf ihn. Zum\n&eReparieren ben\u00F6tigst du die Ausgangsmaterialien im Inventar,\n&ediese werden dir im Zuge der Reparatur abgezogen.
Guides.Repair.Section.2 = &3Wie funktioniert der Reparatur Meister?\n&eMit dem Reparatur Meister wird dein Werkzeug ein bisschen\n&ebesser als normalerweise repariert.\n&eDer Bonus ist abh\u00E4ngig vom Reparatur Level.
Guides.Repair.Section.3 = &3Wie funktioniert Super-Reparatur?\n&eMit Super-Reparatur werden ab und zu deine Items\n&edoppelt so gut repariert.
Guides.Repair.Section.4 = &3Wie funktioniert Arkanes Schmieden?\n&eDiese F\u00E4higkeit erm\u00F6glicht dir mit einer gewissen\n&eChance Verzauberungen auf Items zu erhalten.\n&eVerzauberungen k\u00F6nnen erhalten werden, vermindert werden oder\n&eganz verloren gehen.
-Guides.Salvage.Section.0 = &3\u00DCber Verwerten:\n&eMit einem Goldamboss kannst du R\u00FCstungen und\n&eWerkzeuge verwerten.\n\n&3XP ZUWACHS:\n&eVerwerten ist ein vom Angeln und Reparieren abh\u00E4ngiger Skill.\n&eSein Level ist die H\u00E4lfte von deren Summe.
+Guides.Salvage.Section.0 = &3\u00DCber Verwerten:\n&eMit einem Goldamboss kannst du R\u00FCstungen und\n&eWerkzeuge verwerten.\n\n&3XP-Zuwachs:\n&eVerwerten ist ein vom Angeln und Reparieren abh\u00E4ngiger Skill.\n&eSein Level ist die H\u00E4lfte von deren Summe.
Guides.Salvage.Section.1 = &3Wie funktioniert Verwerten?\n&ePlatziere einen Goldamboss und rechtsklicke mit dem Item in\n&eder Hand. Das Item wird zerst\u00F6rt und in seine\n&eBestandteile zerlegt.\n\n&eBeispielsweise gibt eine Eisenaxt Eisenbarren.
Guides.Salvage.Section.2 = &3Wie funktioniert Fortgeschrittenes Verwerten?\n&eSobald freigeschaltet, kannst du besch\u00E4digte Items verwerten.\n&eDer Ertrag steigt mit dem Level.\n&eDer Mindestertrag ist immer 1 Item, ansonsten kannst du nicht\n&everwerten.
Guides.Salvage.Section.3 = &3Zur Verbildlichung ein Beispiel:\n&eVerwerten wir eine Goldspitzhacke mit 80%\n&eHaltbarkeit, bedeutet das, dass wir nur 2 Gold bekommen\n&ek\u00F6nnen (Spitzhacke=3 Goldbarren, also jeder 33,33%\n&eHaltbarkeit) was 66% entspricht. Wenn dein\n&eErtragsprozentsatz unter 66% liegt wirst du keine 2 Barren\n&ebekommen k\u00F6nnen. Wenn sie dar\u00FCber ist, kannst du den\n&e"gesamten Betrag" bekommen, der aus 2 Eisenbarren besteht.
Guides.Salvage.Section.4 = &3Wie funktioniert Arkanes Verwerten?\n&eDiese F\u00E4higkeit erm\u00F6glicht es verzauberte B\u00FCcher beim\n&eVerwerten von verzauberten Items zu bekommen.\n&eVerzauberungen k\u00F6nnen vollkommen oder teilweise extrahiert\n&ewerden.\n&eBei einer teilweisen Extraktion wird das Verzauberungslevel\n&ereduziert.
Guides.Smelting.Section.0 = Kommt irgendwann mal...
-Guides.Swords.Section.0 = &3\u00DCber Schwerter:\n&eDiese F\u00E4higkeit gibt Kampfboni bei Benutzung\n&edes Schwertes.\n\n&3XP ZUWACHS:\n&eVerletze Monster und Spieler mit dem Schwert.
+Guides.Swords.Section.0 = &3\u00DCber Schwerter:\n&eDiese F\u00E4higkeit gibt Kampfboni bei Benutzung\n&edes Schwertes.\n\n&3XP-Zuwachs:\n&eVerletze Monster und Spieler mit dem Schwert.
Guides.Swords.Section.1 = &3Wie funktioniert der S\u00E4gezahnschlag?\n&eS\u00E4gezahnschlag ist eine aktive F\u00E4higkeit die du mit Rechtsklick \n&eaktivierst.\n&eMit dieser F\u00E4higkeit kannst du Fl\u00E4chenschaden verteilen.\n&eAu\u00DFerdem blutet das Ziel f\u00FCr kurze Zeit.
Guides.Swords.Section.2 = &3Wie funktioniert der Gegenangriff?\n&eGegenangriff ist eine aktive F\u00E4higkeit,\n&ebei der Angriffe von Monstern beim Blocken um bis zu 50%\n&edes erhaltenen Schadens reflektiert werden k\u00F6nnen.
Guides.Swords.Section.3 = &3Wie funktioniert Blutung?\n&eBlutung f\u00FCgt den Gegnern alle 2 Sekunden Schaden zu. Das\n&eBluten geht solange bis die F\u00E4higkeit ausl\u00E4uft oder der\n&eGegner stirbt.\n&eDie Dauer der Blutung erh\u00F6ht sich mit dem Schwert-Skill.
-Guides.Taming.Section.0 = &3\u00DCber Z\u00E4hmen:\n&eZ\u00E4hmen gibt dem Spieler diverse Kampfboni beim Kampf mit\n&egez\u00E4hmten W\u00F6lfen.\n\n&3XP ZUWACHS:\n&eUm XP zu bekommen musst du Tiere z\u00E4hmen oder mit\n&edeinen W\u00F6lfen k\u00E4mpfen.
+Guides.Taming.Section.0 = &3\u00DCber Z\u00E4hmen:\n&eZ\u00E4hmen gibt dem Spieler diverse Kampfboni beim Kampf mit\n&egez\u00E4hmten W\u00F6lfen.\n\n&3XP-Zuwachs:\n&eUm XP zu bekommen musst du Tiere z\u00E4hmen oder mit\n&edeinen W\u00F6lfen k\u00E4mpfen.
Guides.Taming.Section.1 = &3Wie funktioniert Ruf der Wildnis?\n&eRuf der Wildnis ist eine aktive F\u00E4higkeit die dir erlaubt\n&eeinen Wolf, einen Ozelot oder ein Pferd an deine Seite zu\n&erufen.\n&eDas tust du, indem du linksklickst w\u00E4hrend du Knochen, Fisch\n&eoder \u00C4pfel in der Hand h\u00E4ltst.
Guides.Taming.Section.2 = &3Wie funktioniert Bestienkunde?\n&eBestienkunde erlaubt es die Haustiere zu inspizieren.\n&eHalte einen Knochen in der Hand und klick mit linker Maustaste\n&eauf das Haustier um Bestienkunde zu aktivieren.
Guides.Taming.Section.3 = &3Wie funktioniert Aufschlitzen?\n&eAufschlitzen ist eine passive F\u00E4higkeit die beim Ziel\n&edes Wolfes Blutungen hervorrufen kann. Der Erfolg h\u00E4ngt\n&evom Z\u00E4hmen-Level ab.
-Guides.Taming.Section.4 = &3Wie funktionieren gesch\u00E4rfte Klauen?\n&eGesch\u00E4rfte Klauen geben Zusatzschaden in Abh\u00E4ngigkeit\n&evom Z\u00E4hmen Level.
+Guides.Taming.Section.4 = &3Wie funktionieren gesch\u00E4rfte Klauen?\n&eGesch\u00E4rfte Klauen geben Zusatzschaden in Abh\u00E4ngigkeit\n&evom Z\u00E4hmen-Level.
Guides.Taming.Section.5 = &3Wie funktioniert Umweltbewusst?\n&eDiese passive F\u00E4higkeit erm\u00F6glich W\u00F6lfen sich zu dir zu\n&eteleportieren wenn sie in die N\u00E4he von Gefahren wie\n&eKakteen/Lava kommen.\n&eZus\u00E4tzlich sind W\u00F6lfe immun gegen Fallschaden.
Guides.Taming.Section.6 = &3Wie funktioniert Dicker Pelz?\n&eDiese passive F\u00E4higkeit reduziert Schaden und\n&emacht W\u00F6lfe feuerresistent.
Guides.Taming.Section.7 = &3Wie funktioniert Schocksicher?\n&eDiese passive F\u00E4higkeit reduziert den Schaden\n&edurch Explosionen.
Guides.Taming.Section.8 = &3Wie funktioniert Schnell-Imbiss?\n&eDiese passive F\u00E4higkeit gibt dem Wolf eine Chance sich zu\n&eerholen wann immer er einen Gegner verletzt.
-Guides.Unarmed.Section.0 = &3\u00DCber Unbewaffnet:\n&eMit Unbewaffnet kann der echte Mann endlich mit seinen\n&eF\u00E4usten angemessen zuschlagen.\n\n&3XP ZUWACHS:\n&eK\u00E4mpfe unbewaffnet gegen Monster und andere Spieler.
+Guides.Unarmed.Section.0 = &3\u00DCber Unbewaffnet:\n&eMit Unbewaffnet kann der echte Mann endlich mit seinen\n&eF\u00E4usten angemessen zuschlagen.\n\n&3XP-Zuwachs:\n&eK\u00E4mpfe unbewaffnet gegen Monster und andere Spieler.
Guides.Unarmed.Section.1 = &3Wie funktioniert Berserker?\n&eBerserker ist eine aktive F\u00E4higkeit die mit Rechtsklick\n&eaktiviert wird.\n&eIm Berserker-Modus f\u00FCgst du 50% mehr Schaden zu und\n&ekannst weiche Materialien wie Gras und Erde sofort abbauen.
Guides.Unarmed.Section.2 = &3Wie funktioniert der Eiserne Arm?\n&eEiserner Arm erh\u00F6ht den Monstern und Spielern mit den\n&eF\u00E4usten zugef\u00FCgten Schaden.
Guides.Unarmed.Section.3 = &3Wie funktioniert Pfeilablenkung?\n&ePfeilablenkung ist eine passive F\u00E4higkeit die ab und zu\n&ePfeile von Skeletten und angreifenden Spielern ablenkt.\n&eDiese Pfeile prallen einfach ab und fallen auf den Boden.
Guides.Unarmed.Section.4 = &3Wie funktioniert der Eiserne Griff?\n&eEiserner Griff ist eine passive F\u00E4higkeit die Entwaffnung\n&everhindert. Mit h\u00F6herem Level ist es umso einfacher\n&eEntwaffnung zu verhindern.
Guides.Unarmed.Section.5 = &3Wie funktioniert Entwaffnen?\n&eDiese passive F\u00E4higkeit erm\u00F6glich es den Gegner zu\n&eentwaffnen, sodass seine Waffe auf den Boden f\u00E4llt.
Guides.Usage = Der Befehl ist /{0} ? [Seite]
-Guides.Woodcutting.Section.0 = &3\u00DCber Holzf\u00E4ller:\n&eIm Holzf\u00E4llen geht es um das F\u00E4llen von B\u00E4umen.\n\n&3XP ZUWACHS:\n&eDu bekommst XP f\u00FCr das Abholzen von Baumst\u00E4mmen.
+Guides.Woodcutting.Section.0 = &3\u00DCber Holzf\u00E4ller:\n&eIm Holzf\u00E4llen geht es um das F\u00E4llen von B\u00E4umen.\n\n&3XP-Zuwachs:\n&eDu bekommst XP f\u00FCr das Abholzen von Baumst\u00E4mmen.
Guides.Woodcutting.Section.1 = &3Wie funktioniert der Baumf\u00E4ller?\n&eBaumf\u00E4ller ist eine aktive F\u00E4higkeit. Mache mit der Axt in der\n&eHand einen Rechtsklick um sie zu aktivieren. Der Baum\n&ewird sofortig gef\u00E4llt und alle St\u00E4mme abgebaut.
Guides.Woodcutting.Section.2 = &3Wie funktioniert Bl\u00E4ttersturm?\n&eBl\u00E4ttersturm ist eine passive F\u00E4higkeit die Bl\u00E4tter\n&ebei Ber\u00FChrung mit der Axt sofortig bricht. Standardm\u00E4\u00DFig\n&ewird diese F\u00E4higkeit bei Level 100 freigeschaltet.
Guides.Woodcutting.Section.3 = &3Wie funktionieren Doppel-Drops?\n&eDiese passive F\u00E4higkeit gibt dir ab und zu doppelten\n&eErtrag f\u00FCr jeden Stamm den du f\u00E4llst.
Hardcore.DeathStatLoss.Name = Skillverlust bei Tod:
Hardcore.DeathStatLoss.PercentageChanged = &6[mcMMO] Der Verlustprozentsatz wurde auf {0} ge\u00E4ndert.
-Hardcore.DeathStatLoss.PlayerDeath = &6[mcMMO] &4Du hast durch den Tod&9{0}&4 Level verloren.
+Hardcore.DeathStatLoss.PlayerDeath = &6[mcMMO] &4Du hast durch den Tod &9{0}&4 Level verloren.
Hardcore.Mode.Disabled = &6[mcMMO] Hardcore Modus {0} deaktiviert f\u00FCr {1}.
Hardcore.Mode.Enabled = &6[mcMMO] Hardcore Modus {0} aktiviert f\u00FCr {1}.
Hardcore.Vampirism.Killer.Failure = &6[mcMMO] &e{0}&7 war nicht erfahren genug um dir Wissen zu hinterlassen.
@@ -511,14 +511,14 @@ Hardcore.Vampirism.Killer.Success = &6[mcMMO] &3Du hast &9{0}&3 Level von &e{1}
Hardcore.Vampirism.Name = Vampirismus
Hardcore.Vampirism.PercentageChanged = &6[mcMMO] Der Vampirismus Prozentsatz wurde auf {0} ge\u00E4ndert.
Hardcore.Vampirism.Victim.Failure = &6[mcMMO] &e{0}&7 hat es nicht geschafft Wissen von dir zu stehlen!
-Hardcore.Vampirism.Victim.Success = &6[mcMMO] &e{0}&4 hat&9{1}&4 Level von dir gestohlen!
+Hardcore.Vampirism.Victim.Success = &6[mcMMO] &e{0}&4 hat &9{1}&4 Level von dir gestohlen!
Herbalism.Ability.GTe.NeedMore = Du brauchst mehr Samen um Gr\u00FCnes Land zu verbreiten.
Herbalism.Ability.GTh = &a**Gr\u00FCner Daumen**
Herbalism.Ability.GTh.Fail = **Gr\u00FCner Daumen gescheitert**
Herbalism.Ability.Lower = &7&o**Du senkst deine Harke.**
Herbalism.Ability.Ready = &a&o**Du hebst deine Harke...**
-Herbalism.Ability.ShroomThumb.Fail = **Gr\u00FCne Zehe gescheitert**
+Herbalism.Ability.ShroomThumb.Fail = **Gr\u00FCner Daumen gescheitert**
Herbalism.Effect.4 = Gr\u00FCner Daumen
Herbalism.HylianLuck = &aHeute ist das Gl\u00FCck von Hyrule mit dir!
Herbalism.Listener = Kr\u00E4uterkunde:
@@ -546,10 +546,10 @@ Herbalism.SubSkill.HylianLuck.Description = Gibt eine kleine M\u00F6glichkeit, s
Herbalism.SubSkill.HylianLuck.Name = Hylian Gl\u00FCck
Herbalism.SubSkill.HylianLuck.Stat = Hylian Gl\u00FCck Chance
Herbalism.SubSkill.ShroomThumb.Description = Verbreite Myzel auf Gras und Erde.
-Herbalism.SubSkill.ShroomThumb.Name = Pilz-Zehe
-Herbalism.SubSkill.ShroomThumb.Stat = Pilz-Zehe Chance
+Herbalism.SubSkill.ShroomThumb.Name = Pilz-Daumen
+Herbalism.SubSkill.ShroomThumb.Stat = Pilz-Daumen Chance
-Holiday.Anniversary = &9Alles gute zu mcMMO's {0} j\u00E4hrigen Geburtstag!\n&9In Ehren von nossr50 und all den anderen flei\u00DFigen Entwicklern, hier ist eine kleine Feuerwerk Show!
+Holiday.Anniversary = &9Alles Gute zu mcMMO's {0} j\u00E4hrigen Geburtstag!\n&9In Ehren von nossr50 und all den anderen flei\u00DFigen Entwicklern ist hier eine kleine Feuerwerk-Show!
Holiday.AprilFools.Levelup = &6{0} ist jetzt Level &a{1}&6!
Inspect.Offline = &cDu hast nicht die Rechte um Offline-Spieler zu inspizieren!
@@ -561,7 +561,7 @@ Item.ChimaeraWing.Fail = &c**Chimaera Fl\u00FCgel gescheitert!**
Item.ChimaeraWing.Lore = &7Teleportiert dich zu deinem Bett.
Item.ChimaeraWing.Name = Chimaera Fl\u00FCgel
Item.ChimaeraWing.NotEnough = Du ben\u00F6tigst &e{0}&c weitere &6{1}&c!
-Item.ChimaeraWing.Pass = **CHIMAERA FL\u00DCGEL*
+Item.ChimaeraWing.Pass = **Chimarea Fl\u00FCgel**
Item.FluxPickaxe.Lore.1 = &7Hat eine Chance Erze sofort zu schmelzen.
Item.FluxPickaxe.Lore.2 = &7Ben\u00F6tigt Schmelzen-Level {0} oder mehr.
Item.FluxPickaxe.Name = Schmelzhacke
@@ -620,14 +620,14 @@ JSON.Woodcutting = Holzf\u00E4llen
LevelCap.PowerLevel = &6(&amcMMO&6) &eDu hast das Level-Limit von &c{0}&e erreicht. Du kannst deine F\u00E4higkeiten nun nicht mehr weiter verbessern.
LevelCap.Skill = &6(&amcMMO&6) &eDu hast das Level-Limit von &c{0}&e f\u00FCr &6{1}&e erreicht. Du kannst diese F\u00E4higkeit von nun an nicht mehr weiter verbessern.
-Locale.Reloaded = &aDie Sprachdateien wurden neugeladen!
+Locale.Reloaded = &aDie Sprachdateien wurden neu geladen!
MOTD.Donate = &3Spenden Info:
MOTD.Hardcore.DeathStatLoss.Stats = &6[mcMMO] &3Skillverlust bei Tod: &4{0}%
MOTD.Hardcore.Enabled = &6[mcMMO] &3Hardcore Modus aktiviert: &4{0}
MOTD.Hardcore.Vampirism.Stats = &6[mcMMO] &3Vampirismus Prozentsatz: &4{0}%
MOTD.PerksPrefix = &6[mcMMO Boni]
-MOTD.Version = &6[mcMMO] Verwende Version&3{0}
+MOTD.Version = &6[mcMMO] Verwende Version &3{0}
MOTD.Version.Overhaul = &6[mcMMO] &3\u00DCberholungs Era&6 - &3{0}
MOTD.Website = &6[mcMMO] &a{0}&e - mcMMO Website
@@ -648,7 +648,7 @@ Mining.Skills.SuperBreaker.On = &a&o**Super-Brecher aktiviert**
Mining.Skills.SuperBreaker.Other.Off = {0}s &cSuper-Brecher&a ist &aausgelaufen.
Mining.Skills.SuperBreaker.Other.On = &a{0}&2 benutzte &cSuper-Brecher!
Mining.Skills.SuperBreaker.Refresh = &aDein &eSuper-Brecher &aist wieder bereit!
-Mining.SubSkill.BiggerBombs.Description = Erh\u00F6ht den Explosions-Radius.
+Mining.SubSkill.BiggerBombs.Description = Erh\u00F6ht den Explosionsradius.
Mining.SubSkill.BiggerBombs.Name = Sprengmeister
Mining.SubSkill.BlastMining.Description = Bonus beim Abbauen mit TNT.
Mining.SubSkill.BlastMining.Name = Z\u00FCndstoff
@@ -785,7 +785,7 @@ Profile.Loading.FailurePlayer = &cmcMMO hat Probleme beim Laden deiner Daten nac
Profile.Loading.Success = &aDein Profil wurde geladen.
Profile.PendingLoad = &cDeine mcMMO Daten wurden noch nicht geladen.
-Reminder.Squelched = &7Erinnerung: Du erh\u00E4lst aktuell keinerlei Benachrichtigungen von mcMMO, um dies zu \u00E4ndern, nutze den /mcnotify Befehl. Dies ist eine st\u00FCndliche, automatische Erinnerung.
+Reminder.Squelched = &7Erinnerung: Du erh\u00E4ltst aktuell keinerlei Benachrichtigungen von mcMMO, um dies zu \u00E4ndern, nutze den /mcnotify Befehl. Dies ist eine st\u00FCndliche, automatische Erinnerung.
Repair.Arcane.Downgrade = Zauber-Wert des Gegenstands vermindert.
Repair.Arcane.Fail = Der Gegenstands wurde entzaubert.
@@ -863,7 +863,7 @@ Scoreboard.Misc.CurrentXP = &aAktuelle XP
Scoreboard.Misc.Level = &3Level
Scoreboard.Misc.Overall = &6Insgesamt
Scoreboard.Misc.PowerLevel = &6Gesamt-Level
-Scoreboard.Misc.RemainingXP = Verbliebene XP
+Scoreboard.Misc.RemainingXP = Verbleibende XP
Server.ConsoleName = &e[Server]
@@ -890,7 +890,7 @@ Smelting.Effect.4 = Vanilla XP-Boost
Smelting.Effect.5 = Erh\u00F6ht die erhaltene Erfahrung beim Schmelzen.
Smelting.Listener = Schmelzen:
Smelting.SkillName = Schmelzen
-Smelting.SubSkill.FluxMining.Description = M\u00F6glichkeit, Erze direkt beim Abbauen zu schmelzen.
+Smelting.SubSkill.FluxMining.Description = M\u00F6glichkeit, um Erze direkt beim Abbauen zu schmelzen.
Smelting.SubSkill.FluxMining.Name = Schmelztiegel
Smelting.SubSkill.FluxMining.Stat = Schmelztiegel Chance
Smelting.SubSkill.FuelEfficiency.Description = Erh\u00F6he die Brenndauer des Brennstoffes in \u00D6fen.
@@ -936,7 +936,7 @@ Swords.SubSkill.Rupture.Stat.Extra = Entzweiung: &a{0} ticks [{1} Schaden gegen
Swords.SubSkill.SerratedStrikes.Description = {0} Fl\u00E4chenschaden, Fl\u00E4chenblutung+
Swords.SubSkill.SerratedStrikes.Name = S\u00E4gezahnschlag
Swords.SubSkill.SerratedStrikes.Stat = S\u00E4gezahnschlag L\u00E4nge
-Swords.SubSkill.Stab.Description = F\u00FCgt extra Schaden zu deinem Angriff hinzu.
+Swords.SubSkill.Stab.Description = F\u00FCgt deinem Angriff extra Schaden hinzu.
Swords.SubSkill.Stab.Name = Erstechen
Swords.SubSkill.Stab.Stat = Schaden durch Erstechen
Swords.SubSkill.SwordsLimitBreak.Description = \u00DCberschreite deine Grenzen.
@@ -946,7 +946,7 @@ Swords.SubSkill.SwordsLimitBreak.Stat = Bonus-Schaden durch \u00DCberwindung
Taming.Ability.Bonus.0 = Umweltbewusst
Taming.Ability.Bonus.1 = W\u00F6lfe weichen Gefahren aus.
Taming.Ability.Bonus.10 = Heiliger Hund
-Taming.Ability.Bonus.11 = Regenerierung auch mit Tr\u00E4nken und Zaubern m\u00F6glich.
+Taming.Ability.Bonus.11 = Regenerierung ist auch mit Tr\u00E4nken und Zaubern m\u00F6glich.
Taming.Ability.Bonus.2 = Dicker Pelz
Taming.Ability.Bonus.3 = 1/{0} Schaden, Feuer-Resistent
Taming.Ability.Bonus.4 = Schock-Sicher
@@ -968,7 +968,7 @@ Taming.SkillName = Z\u00C4HMEN
Taming.SubSkill.BeastLore.Description = Knochenschlag inspiziert W\u00F6lfe und Ozelots.
Taming.SubSkill.BeastLore.Name = Bestienkunde
Taming.SubSkill.CallOfTheWild.Description = Beschw\u00F6re ein Tier an deine Seite.
-Taming.SubSkill.CallOfTheWild.Description.2 = &7RdW: B\u00FCcken und Linksklick mit {0} {1} (Ozelot), {2} {3} (Wolf), {4} {5} (Pferd)
+Taming.SubSkill.CallOfTheWild.Description.2 = &7Ruf der Wildnis: B\u00FCcken und Linksklick mit {0} {1} (Ozelot), {2} {3} (Wolf), {4} {5} (Pferd)
Taming.SubSkill.CallOfTheWild.Name = Ruf der Wildnis
Taming.SubSkill.EnvironmentallyAware.Description = Kaktus/Lava-Furcht, Immun gegen Fallschaden
Taming.SubSkill.EnvironmentallyAware.Name = Umweltbewusst
@@ -1004,11 +1004,11 @@ Unarmed.Ability.Bonus.1 = +{0} Schadens-Bonus
Unarmed.Ability.IronGrip.Attacker = Dein Gegner hat einen eisernen Griff!
Unarmed.Ability.IronGrip.Defender = &aDein eiserner Griff hat dich vor Entwaffnung gesch\u00FCtzt!
Unarmed.Ability.Lower = &7&o**Du senkst deine F\u00E4uste.**
-Unarmed.Ability.Ready = &a&o**Du hebste deine F\u00E4uste...**
+Unarmed.Ability.Ready = &a&o**Du hebst deine F\u00E4uste...**
Unarmed.Listener = Faustkampf:
Unarmed.SkillName = Faustkampf
Unarmed.Skills.Berserk.Off = **Berserker ausgelaufen**
-Unarmed.Skills.Berserk.On = &a**Berserker aktiviertT**
+Unarmed.Skills.Berserk.On = &a**Berserker aktiviert**
Unarmed.Skills.Berserk.Other.Off = {0}s &cBerserker&a ist &aausgelaufen.
Unarmed.Skills.Berserk.Other.On = &a{0}&2 benutzte &cBerserker!
Unarmed.Skills.Berserk.Refresh = &aDein &eBerserker &aist wieder bereit!
@@ -1020,7 +1020,7 @@ Unarmed.SubSkill.Berserk.Name = Berserker
Unarmed.SubSkill.Berserk.Stat = Berserker L\u00E4nge
Unarmed.SubSkill.BlockCracker.Description = Durchbreche Stein mit deinen F\u00E4usten.
Unarmed.SubSkill.BlockCracker.Name = Schwarzgurt
-Unarmed.SubSkill.Disarm.Description = L\u00E4sst Gegenstand aus der Hand des Feindes fallen.
+Unarmed.SubSkill.Disarm.Description = L\u00E4sst den Gegenstand aus der Hand des Feindes fallen.
Unarmed.SubSkill.Disarm.Name = Entwaffnen
Unarmed.SubSkill.Disarm.Stat = Entwaffnen Chance
Unarmed.SubSkill.IronGrip.Description = Sch\u00FCtzt dich davor, entwaffnet zu werden.
diff --git a/src/main/resources/locale/locale_pl.properties b/src/main/resources/locale/locale_pl.properties
index 4cbc5109c..96bc89e2e 100644
--- a/src/main/resources/locale/locale_pl.properties
+++ b/src/main/resources/locale/locale_pl.properties
@@ -21,7 +21,7 @@ JSON.Alchemy=Alchemia
JSON.Archery=\u0141ucznictwo
JSON.Axes=Siekiery
JSON.Excavation=Wykopalisko
-JSON.Fishing=Rybarz
+JSON.Fishing=Rybak
JSON.Herbalism=Zielarstwo
JSON.Mining=G\u00f3rnictwo
JSON.Repair=Naprawiacz
@@ -29,7 +29,7 @@ JSON.Salvage=Odzyskiwacz
JSON.Swords=Miecze
JSON.Taming=Tresowanie
JSON.Unarmed=Niezr\u0119czno\u015b\u0107
-JSON.Woodcutting=\u015acinacz Drzew
+JSON.Woodcutting=Drwal
JSON.URL.Website=Oficjalna strona mcMMO!
JSON.URL.Discord=Oficjalny discord mcMMO!
JSON.URL.Patreon=Wesprzyj nossr50 i jego projekt mcMMO na Patreon!
@@ -88,7 +88,7 @@ Overhaul.Name.Alchemy=Alchemia
Overhaul.Name.Archery=\u0141ucznictwo
Overhaul.Name.Axes=Siekiery
Overhaul.Name.Excavation=Wykopalisko
-Overhaul.Name.Fishing=Rybarz
+Overhaul.Name.Fishing=Rybak
Overhaul.Name.Herbalism=Zielarstwo
Overhaul.Name.Mining=G\u00f3rnictwo
Overhaul.Name.Repair=Naprawiacz
@@ -97,7 +97,7 @@ Overhaul.Name.Smelting=Przepalanie
Overhaul.Name.Swords=Miecze
Overhaul.Name.Taming=Tresowanie
Overhaul.Name.Unarmed=Niezr\u0119czno\u015b\u0107
-Overhaul.Name.Woodcutting=\u015acinacz Drzew
+Overhaul.Name.Woodcutting=Drwal
# /mcMMO Command Style Stuff
Commands.mcc.Header=&c---[]&amcMMO Komendy&c[]---
Commands.Other=&c---[]&aSPECJALNE KOMENDY&c[]---
@@ -112,7 +112,7 @@ XPBar.Alchemy=Alchemia Lv.&6{0}
XPBar.Archery=\u0141ucznictwo Lv.&6{0}
XPBar.Axes=Siekiery Lv.&6{0}
XPBar.Excavation=Wykopalisko Lv.&6{0}
-XPBar.Fishing=Rybarz Lv.&6{0}
+XPBar.Fishing=Rybak Lv.&6{0}
XPBar.Herbalism=Zielarstwo Lv.&6{0}
XPBar.Mining=G\u00f3rnictwo Lv.&6{0}
XPBar.Repair=Naprawiacz Lv.&6{0}
@@ -121,7 +121,7 @@ XPBar.Smelting=Przepalanie Lv.&6{0}
XPBar.Swords=Miecze Lv.&6{0}
XPBar.Taming=Tresowanie Lv.&6{0}
XPBar.Unarmed=Niezr\u0119czno\u015b\u0107 Lv.&6{0}
-XPBar.Woodcutting=\u015acinacz Drzew Lv.&6{0}
+XPBar.Woodcutting=Drwal Lv.&6{0}
#This is just a preset template that gets used if the 'ExtraDetails' setting is turned on in experience.yml (off by default), you can ignore this template and just edit the strings above
XPBar.Complex.Template={0} &3 {4}&f% &3(&f{1}&3/&f{2}&3)
# XP BAR Allows for the following variables -- {0} = Skill Level, {1} Current XP, {2} XP Needed for next level, {3} Power Level, {4} Percentage of Level
@@ -132,7 +132,7 @@ XPBar.Complex.Template={0} &3 {4}&f% &3(&f{1}&3/&f{2}&3)
Acrobatics.Ability.Proc=&a**\u0141askawe L\u0105dowanie**
Acrobatics.Combat.Proc=&a**Unik**
Acrobatics.SubSkill.Roll.Stats=&6Szansa na &e{0}%&6 Szansa na \u0142\u0105ske&e {1}%
-Acrobatics.SubSkill.Roll.Stat=Szansa na
+Acrobatics.SubSkill.Roll.Stat=Szansa na Przewr\u00f3t
Acrobatics.SubSkill.Roll.Stat.Extra=Szansa na \u0141agodny Przewr\u00f3t
Acrobatics.SubSkill.Roll.Name=Przewr\u00f3t
Acrobatics.SubSkill.Roll.Description=Wyl\u0105duj strategicznie, aby unikn\u0105\u0107 uszkodze\u0144.
@@ -143,7 +143,7 @@ Acrobatics.SubSkill.GracefulRoll.Name=\u0141agodny przewr\u00f3t
Acrobatics.SubSkill.GracefulRoll.Description=Podwaja efekt normalnego przewrotu.
Acrobatics.SubSkill.Dodge.Name=Unik
Acrobatics.SubSkill.Dodge.Description=Redukuje obra\u017cenia od ataku o po\u0142ow\u0119
-Acrobatics.SubSkill.Dodge.Stat=Szansa na unik
+Acrobatics.SubSkill.Dodge.Stat=Szansa na Unik
Acrobatics.Listener=Akrobatyka:
Acrobatics.Roll.Text=&o**Przewr\u00f3t**
Acrobatics.SkillName=AKROBATYKA
@@ -267,7 +267,7 @@ Fishing.SkillName=W\u0118DKARSTWO
#HERBALISM
Herbalism.Ability.GTe.NeedMore=Potrzebujesz wi\u0119cej nasion, aby rozprzestrzeni\u0107 Zielona Tera.
Herbalism.Ability.GTh.Fail=**ZIELONA TERA ZAWODZI**
-Herbalism.Ability.GTh=&a**GREEN THUMB**
+Herbalism.Ability.GTh=&a**ZIELONY L\u0104D**
Herbalism.Ability.Lower=&7Opuszczasz swoj\u0105 motyk\u0119.
Herbalism.Ability.Ready=&6Przygotowujesz&3 swoj\u0105 motyk\u0119.
Herbalism.Ability.ShroomThumb.Fail=**HALUCYNKI ZAWODZ\u0104**
@@ -304,22 +304,22 @@ Mining.Ability.Locked.0=ZABLOKOWANE DO {0}+ UMIEJ\u0118TNO\u015a\u0106 (PODMUCH
Mining.Ability.Locked.1=ZABLOKOWANE DO {0}+ UMIEJ\u0118TNO\u015a\u0106 (WI\u0118KSZE BOMBY)
Mining.Ability.Locked.2=ZABLOKOWANE DO {0}+ UMIEJ\u0118TNO\u015a\u0106 (EKSPERTYZY ROZBI\u00d3RKI)
Mining.Ability.Lower=&7Opuszczasz sw\u00f3j kilof.
-Mining.Ability.Ready=&3You &6ready&3 Tw\u00f3j kilof.
+Mining.Ability.Ready=&6Przygotowujesz&3 sw\u00f3j kilof.
Mining.SubSkill.SuperBreaker.Name=Super Niszczyciel
Mining.SubSkill.SuperBreaker.Description=Pr\u0119dko\u015b\u0107+, Szansa na potr\u00f3jny \u0142up
Mining.SubSkill.SuperBreaker.Stat=Trwanie: Super Niszczyciel
Mining.SubSkill.DoubleDrops.Name=Podw\u00f3jny drop
Mining.SubSkill.DoubleDrops.Description=Podwaja normalny \u0142up
-Mining.SubSkill.DoubleDrops.Stat=Podw\u00f3jna szansa na upuszczenie
+Mining.SubSkill.DoubleDrops.Stat=Podw\u00f3jna szansa na upuszczenie \u0142upu
Mining.SubSkill.BlastMining.Name=Podmuch G\u00f3rnictwa
Mining.SubSkill.BlastMining.Description=Premie do wydobywania z TNT
-Mining.SubSkill.BlastMining.Stat=Blast Mining:&a Rank {0}/{1} &7({2})
-Mining.SubSkill.BlastMining.Stat.Extra=Blast Radius Increase: &a+{0}
+Mining.SubSkill.BlastMining.Stat=Ranga Podmuchu G\u00f3rnictwa:&a {0}/{1} &7({2})
+Mining.SubSkill.BlastMining.Stat.Extra=Dodatkowy Zasi\u0119g Podmuchu G\u00f3rnictwa: &a+{0}
Mining.SubSkill.BiggerBombs.Name=Wi\u0119ksze bomby
Mining.SubSkill.BiggerBombs.Description=Zwi\u0119ksza promie\u0144 wybuchu
-Mining.SubSkill.DemolitionsExpertise.Name=Ekspertyzy Rozbi\u00f3rki
+Mining.SubSkill.DemolitionsExpertise.Name=Ekspertyza Rozbi\u00f3rki
Mining.SubSkill.DemolitionsExpertise.Description=Zmniejsza obra\u017cenia zadawane TNT
-Mining.SubSkill.DemolitionsExpertise.Stat=Zmniejszenie obra\u017ce\u0144 od eksperta od wyburze\u0144
+Mining.SubSkill.DemolitionsExpertise.Stat=Zmniejszenie obra\u017ce\u0144 od Eksperyza Rozbi\u00f3rki
Mining.Listener=G\u00f3rnictwo:
Mining.SkillName=G\u00d3RNICTWO
Mining.Skills.SuperBreaker.Off=**Super Niszczyciel wy\u0142\u0105czy\u0142 si\u0119**
@@ -405,7 +405,7 @@ Anvil.Unbreakable=Ten przedmiot jest niezniszczalny!
#SWORDS
Swords.Ability.Lower=&7Opuszczasz sw\u00f3j miecz.
Swords.Ability.Ready=&6Przygotowujesz&3 sw\u00f3j miecz.
-Swords.Combat.Rupture.Note=&7NOTATKA: &e1 P\u0119kni\u0119cie zdarza si\u0119 co 0,5 sekundy!
+Swords.Combat.Rupture.Note=&7NOTATKA: &eP\u0119kni\u0119cie to okresowe obra\u017cenia, kt\u00f3re s\u0105 zadawane 2 razy na sekunde oraz omijaj\u0105 one zbroj\u0119!
Swords.Combat.Bleeding.Started=&4 Krwawisz!
Swords.Combat.Bleeding.Stopped=&7Krwawienie ju\u017c si\u0119 zatrzyma\u0142o&7!
Swords.Combat.Bleeding=&a**PRZECIWNIK KRWAWI**
@@ -427,7 +427,9 @@ Swords.SubSkill.SwordsLimitBreak.Name=Prze\u0142amywanie limit\u00f3w miecza
Swords.SubSkill.SwordsLimitBreak.Description=Prze\u0142amywanie limit\u00f3w. Zwi\u0119kszone obra\u017cenia zadawane trudnym przeciwnikom. Przeznaczony dla PVP, zale\u017cnie od ustawie\u0144 serwera, czy zwi\u0119kszy obra\u017cenia w PVE, czy nie.
Swords.SubSkill.SwordsLimitBreak.Stat=Prze\u0142amywanie limit\u00f3w max obra\u017ce\u0144
Swords.SubSkill.Rupture.Stat=Szansa na Rozerwanie
-Swords.SubSkill.Rupture.Stat.Extra=Rozerwanie: &a{0} ticks [{1} DMG vs Gracz] [{2} DMG vs Moby]
+Swords.SubSkill.Rupture.Stat.Extra=[[DARK_AQUA]]Czas Rozerwania: &a{0}s przeciwko Graczom, {1}s przeciwko Mobom.
+Swords.SubSkill.Rupture.Stat.TickDamage=[[DARK_AQUA]]Obra\u017cenia Rozerwania na tik: &e{0}&a przeciwko Graczom, &e{1}&a przeciwko Mobom.
+Swords.SubSkill.Rupture.Stat.ExplosionDamage=[[DARK_AQUA]]Obra\u017cenia eksplozji Rozerwania: &e{0}&a przeciwko Graczom, &e{1}&a przeciwko Mobom.
Swords.Effect.4=Krwawienie+ z\u0105bkowane uderzenia
Swords.Effect.5={0} Tick Rupture
Swords.Listener=Miecze:
@@ -547,8 +549,8 @@ Woodcutting.SubSkill.BarkSurgeon.Name=Chirurg Kory
Woodcutting.SubSkill.BarkSurgeon.Description=Wydobywaj przydatne materia\u0142y podczas \u015bcinania drzew.
Woodcutting.SubSkill.NaturesBounty.Name=Nagroda natury
Woodcutting.SubSkill.NaturesBounty.Description=Zbieraj do\u015bwiadczenie z natury.
-Woodcutting.Listener=\u015acinacz Drzew:
-Woodcutting.SkillName=\u015aCINACZ DRZEW
+Woodcutting.Listener=Drwal:
+Woodcutting.SkillName=DRWAL
Woodcutting.Skills.TreeFeller.Off=**\u015acinacz Drzew przesta\u0142 dzia\u0142a\u0107**
Woodcutting.Skills.TreeFeller.On=&a**\u015aCINACZ DRZEW AKTYWOWANY**
Woodcutting.Skills.TreeFeller.Refresh=&aTwoja umiej\u0119tno\u015b\u015b &e\u015acinacz Drzew &azosta\u0142a od\u015bwie\u017cona!
@@ -822,7 +824,7 @@ Party.ItemShare.Category.Herbalism=Tresowanie
Party.ItemShare.Category.Woodcutting=\u015acinanie Drzew
Party.ItemShare.Category.Misc=R\u00f3\u017cne
##xp
-Commands.XPGain.Acrobatics=Spadanie
+Commands.XPGain.Acrobatics=Spadanie z wysoko\u015bci
Commands.XPGain.Alchemy=Warzenie Mikstur
Commands.XPGain.Archery=Atakowanie potwor\u00f3w
Commands.XPGain.Axes=Atakowanie potwor\u00f3w
@@ -831,7 +833,7 @@ Commands.XPGain.Excavation=Kopanie i znajdowanie skarb\u00f3w
Commands.XPGain.Fishing=\u0141owienie
Commands.XPGain.Herbalism=Zbieranie zi\u00f3\u0142
Commands.XPGain.Mining=Kopanie kamienia & rud
-Commands.XPGain.Repair=Naprawa
+Commands.XPGain.Repair=Naprawa u\u017cywaj\u0105c specjalnego kowad\u0142a
Commands.XPGain.Swords=Atakowanie potwor\u00f3w
Commands.XPGain.Taming=Rozmna\u017canie zwierz\u0105t, albo walka w/ z twoimi psami
Commands.XPGain.Unarmed=Atakowanie potwor\u00f3w
@@ -872,88 +874,88 @@ Guides.Page.OutOfRange=Ta strona nie istnieje, jest/s\u0105 tylko {0} stron/a/y.
Guides.Usage= Prawod\u0142owe u\u017cycie to /{0} ? [strona]
##Acrobatics
Guides.Acrobatics.Section.0=&3O Akrobatyce:\n&eakrobatyka to sztuka poruszania si\u0119 z wdzi\u0119kiem w mcMMO.\n&eZapewnia premie bojowe i premie do obra\u017ce\u0144 otoczenia.\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 PD w tej umiej\u0119tno\u015bci, musisz wykona\u0107 unik\n&ew walce lub przetrwa\u0107 upadki z wysoko\u015bci, kt\u00f3re ci\u0119 rani\u0105.
-Guides.Acrobatics.Section.1=&3How does Rolling work?\n&eYou have a passive chance when you take fall damage\n&eto negate the damage done. You can hold the sneak button to\n&edouble your chances during the fall.\n&eThis triggers a Graceful Roll instead of a standard one.\n&eGraceful Rolls are like regular rolls but are twice as likely to\n&eoccur and provide more damage safety than regular rolls.\n&eRolling chance is tied to your skill level
-Guides.Acrobatics.Section.2=&3How does Dodge work?\n&eDodge is a passive chance when you are\n&einjured in combat to halve the damage taken.\n&eIt is tied to your skill level.
+Guides.Acrobatics.Section.1=&3Jak dzia\u0142a Przewr\u00f3t??\n&eMasz pasywn\u0105 szans\u0119, gdy odniesiesz obra\u017cenia od upadku, aby zneutralizowa\u0107 zadane obra\u017cenia. Mo\u017cesz przytrzyma\u0107 przycisk skradania si\u0119, aby podwoi\u0107 swoje szanse podczas upadku. To wyzwala \u014agodny Przwr\u00f3t zamiast standardowego. \u0141agodne Przewroty s\u0105 jak zwyk\u0142e, ale prawdopodobie\u0144stwo wyst\u0105pienia Przewrotu jest dwukrotnie wi\u0119ksze i zapewnia wi\u0119ksze bezpiecze\u0144stwo obra\u017ce\u0144 ni\u017c zwyk\u0142e Przewroty.\n&eSzansa na przewr\u00f3t zale\u017cy od poziomu Twojej umiej\u0119tno\u015bci.
+Guides.Acrobatics.Section.2=&3Jak dzia\u0142a unik?\n&eUnik to pasywna szansa na zmniejszenie o po\u0142ow\u0119 otrzymywanych obra\u017ce\u0144, gdy odniesiesz obra\u017cenia w walce. Jest to powi\u0105zane z Twoim poziomem umiej\u0119tno\u015bci.
##Alchemy
Guides.Alchemy.Section.0=&3O Alchemi:\n&eAlchemia polega na warzeniu mikstur.\n&eZapewnia przyspieszenie czasu warzenia mikstury,\n&ea tak\u017ce dodanie nowych (wcze\u015bniej) nieosi\u0105galnych mikstur. \n\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 XP tej umiej\u0119tno\u015bci, musisz warzy\u0107 mikstury.
-Guides.Alchemy.Section.1=&3How does Catalysis work?\n&eCatalysis speeds of the brewing process, with a\n&emax speed of 4x at level 1000.\n&eThis ability is unlocked at level 100 by default.
-Guides.Alchemy.Section.2=&3How does Concoctions work?\n&eConcoctions allows brewing of more potions with custom ingredients.\n&eWhich special ingredients are unlocked is determined\n&eby your Rank. There are 8 ranks to unlock.
-Guides.Alchemy.Section.3=&3Concoctions tier 1 ingredients:\n&eBlaze Powder, Fermented Spider Eye, Ghast Tear, Redstone,\n&eGlowstone Dust, Sugar, Glistering Melon, Golden Carrot,\n&eMagma Cream, Nether Wart, Spider Eye, Suplhur, Water Lily,\n&ePufferfish\n&e(Vanilla Potions)
-Guides.Alchemy.Section.4=&3Concoctions tier 2 ingredients:\n&eCarrot (Potion of Haste)\n&eSlimeball (Potion of Dullness)\n\n&3Concoctions tier 3 ingredients:\n&eQuartz (Potion of Absorption)\n&eRed Mushroom (Potion of Leaping)
-Guides.Alchemy.Section.5=&3Concoctions tier 4 ingredients:\n&eApple (Potion of Health Boost)\n&eRotten Flesh (Potion of Hunger)\n\n&3Concoctions tier 5 ingredients:\n&eBrown Mushroom (Potion of Nausea)\n&eInk Sack (Potion of Blindness)
-Guides.Alchemy.Section.6=&3Concoctions tier 6 ingredients:\n&eFern (Potion of Saturation)\n\n&3Concoctions tier 7 ingredients:\n&ePoisonous Potato (Potion of Decay)\n\n&3Concoctions tier 8 ingredients:\n&eRegular Golden Apple (Potion of Resistance)
+Guides.Alchemy.Section.1=&3Jak dzia\u0142a Kataliza?\n&eSzybko\u015b\u0107 katalizy procesu warzenia, z maksymaln\u0105 pr\u0119dko\u015bci\u0105 4x na poziomie 1000. Ta umiej\u0119tno\u015b\u0107 jest domy\u015blnie odblokowywana na poziomie 100.
+Guides.Alchemy.Section.2=&3Jak dzia\u0142aj\u0105 Mikstury?\n&eMikstury pozwalaj\u0105 na warzenie wi\u0119kszej liczby mikstur z niestandardowych sk\u0142adnik\u00f3w. To, kt\u00f3re specjalne sk\u0142adniki zostan\u0105 odblokowane, zale\u017cy od Twojej rangi. Do odblokowania jest 8 stopni.
+Guides.Alchemy.Section.3=&3Sk\u0142adniki mikstur tieru 1:\n&eP\u0142omienny Proszek, Fermentowane Oko Paj\u0105ka, \u0141za Ghasta, Redstone,\n&eJasnopy\u0142, Cukier, Poz\u0142acany Arbuz, Z\u0142ota Marchewka,\n&eMagmowy Krem, Brodawka, Oko Paj\u0105ka, Proch, Lilia Wodna,\n&eRozdymka\n&e(Mikstury Wanilla)
+Guides.Alchemy.Section.4=&3Sk\u0142adniki mikstur tieru 2:\n&eMarchwka (Miktura Szybko\u015bci)\n&eKulka Szlamu (Miktura Ot\u0119pienia)\n\n&3Sk\u0142adniki mikstur tieru 3:\n&eKwarc (Miksutra Absorpcji)\n&eMuchomor (Mikstura Skoku)
+Guides.Alchemy.Section.5=&3Sk\u0142adniki mikstur tieru 4:\n&eJab\u0142ko (Mikstura boostu zdrowia)\n&eZgni\u0142e Mi\u0119so (PMiksutra G\u0142odu)\n\n&3Sk\u0142adniki mikstur tieru 5:\n&eBr\u0105zowy Grzyb (Mikstura Md\u0142o\u015bci)\n&eAtrament (Mikstura O\u015blepienia)
+Guides.Alchemy.Section.6=&3Sk\u0142adniki mikstur tieru 6:\n&ePapro\u0107 (Mikstura Nasycenia)\n\n&3Sk\u0142adniki mikstur tieru 7:\n&eZatruty Ziemniak (Mikstura Rozk\u0142adu)\n\n&3Sk\u0142adniki mikstur tieru 8:\n&eZ\u0142ote Jab\u0142ko (Mikstura Odporno\u015bci)
##Archery
Guides.Archery.Section.0=&3O \u0141ucznictwie:\n&e\u0141ucznictwo polega na strzelaniu z \u0142uku strza\u0142.\n&eZapewnia r\u00f3\u017cne bonusy bojowe, takie jak zwi\u0119kszenie obra\u017ce\u0144,\n&ekt\u00f3re skaluje si\u0119 z twoim poziomem i daje mo\u017cliwo\u015b\u0107 oszo\u0142omienia\n&eprzeciwnik\u00f3w w PvP. W dodatku mo\u017cesz odzyska\u0107\n&ecz\u0119\u015b\u0107 strza\u0142 z martwych wrog\u00f3w.\n\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 XP w tej umiej\u0119tno\u015bci, musisz strzela\u0107 do mob\u00f3w lub\n&edo innych graczy.
-Guides.Archery.Section.1=&3How does Skill Shot work?\n&eSkill Shot provides additional damage to your shots.\n&eThe bonus damage from Skill Shot increases as you\n&elevel in Archery.\n&eWith the default settings, your archery damage increases 10%\n&eevery 50 levels, to a maximum of 200% bonus damage.
-Guides.Archery.Section.2=&3How does Daze work?\n&eYou have a passive chance to daze other players when\n&eyou shoot them. When Daze triggers it forces your opponents\n&eto look straight up for a short duration.\n&eA Daze shot also deals an additional 4 damage (2 hearts).
-Guides.Archery.Section.3=&3How does Arrow Retrieval work?\n&eYou have a passive chance to retrieve some of your arrows\n&ewhen you kill a mob with your bow.\n&eThis chance increases as you level in Archery.\n&eBy default, this ability increases by 0.1% per level, up to 100%\n&eat level 1000.
+Guides.Archery.Section.1=&3Jak dzia\u0142a Umiej\u0119tne Strzelanie??\n&eUmiej\u0119tne strzelanie zapewnia dodatkowe obra\u017cenia strza\u0142om.\n&eDodatkowe obra\u017cenia rosn\u0105 wraz z poziomem \u0141ucznictwa.\n&ePrzy domy\u015blnych ustawieniach twoje obra\u017cenia zwi\u0119kszaj\u0105 si\u0119 o 10% co 50 poziom\u00f3w, do maksymalnie 200% dodatkowych obra\u017ce\u0144.
+Guides.Archery.Section.2=&3Jak dzia\u0142a Oszo\u0142omienie?\n&eMasz pasywn\u0105 szans\u0119 oszo\u0142omienia innych graczy, gdy do nich strzelasz. Aktywacja Oszo\u0142omienia zmusza przeciwnik\u00f3w do patrzenia prosto w g\u00f3r\u0119 przez kr\u00f3tki czas. Strza\u0142a oszo\u0142omiaj\u0105ca zadaje dodatkowe 4 obra\u017cenia (2 serca).
+Guides.Archery.Section.3=&3Jak dzia\u0142a Odzyskiwanie Strza\u0142?\n&eMasz pasywn\u0105 szans\u0119 na odzyskanie niekt\u00f3rych strza\u0142, gdy zabijesz \u0142ukiem. Ta szansa ro\u015bnie wraz ze zdobywaniem kolejnych poziom\u00f3w w \u0141ucznictwie. Domy\u015blnie zdolno\u015b\u0107 ta ro\u015bnie o 0,1% na poziom, do 100% na poziomie 1000.
##Axes
-Guides.Axes.Section.0=&3About Axes:\n&eZ umiej\u0119tno\u015bci\u0105 Topory mo\u017cesz zrobi\u0107 co\u015b wi\u0119cej\n&eni\u017c niszczy\u0107 lasy! Mo\u017cesz hakowa\u0107 i sieka\u0107 moby\n&ei graczy, aby zdobywa\u0107 XP, musisz atakowa\u0107 moby siekier\u0105 z efektem\n&eodrzucenie i zada\u0107 \u015bmiertelny cios.\n&eTw\u00f3j top\u00f3r r\u00f3wnie\u017c staje si\u0119 r\u0119cznym r\u0119bakiem,\n&eponiewa\u017c bardzo obni\u017casz poziom zbroi\n&przeciwnika wraz z poziomiem umiej\u0119tno\u015bci.\n&3ZDOBYWANIE XP:\n&eAby zdobywa\u0107 XP musisz atakowa\u0107 moby\n&elub graczy siekier\u0105.
-Guides.Axes.Section.1=&3How does Skull Splitter work?\n&eThis ability allows you to deal an AoE (Area of Effect) hit.\n&eThis AoE hit will deal half as much damage as you did to the\n&emain target, so it's great for clearing out large piles of mobs.
-Guides.Axes.Section.2=&3How does Critical Strikes work?\n&eCritical Strikes is a passive ability which gives players a\n&echance to deal additional damage.\n&eWith the default settings, every 2 skill levels in Axes awards a\n&e0.1% chance to deal a Critical Strike, causing 2.0 times damage\n&eto mobs or 1.5 times damage against other players.
-Guides.Axes.Section.3=&3How does Axe Mastery work?\n&eAxe Mastery is a passive ability that will add additional damage\n&eto your hits when using Axes.\n&eBy default, the bonus damage increases by 1 every 50 levels,\n&eup to a cap of 4 extra damage at level 200.
-Guides.Axes.Section.4=&3How does Armor Impact work?\n&eStrike with enough force to shatter armor!\n&eArmor Impact has a passive chance to damage your\n&eopponent's armor. This damage increases as you level in Axes.
-Guides.Axes.Section.5=&3How does Greater Impact work?\n&eYou have a passive chance to achieve a greater impact when\n&ehitting mobs or players with your axe.\n&eBy default this chance is 25%. This passive ability has an\n&eextreme knockback effect, similar to the Knockback II\n&eenchantment. In addition, it deals bonus damage to the target.
+Guides.Axes.Section.0=&3O Siekierach:\n&eZ umiej\u0119tno\u015bci\u0105 Topory mo\u017cesz zrobi\u0107 co\u015b wi\u0119cej\n&eni\u017c niszczy\u0107 lasy! Mo\u017cesz hakowa\u0107 i sieka\u0107 moby\n&ei graczy, aby zdobywa\u0107 XP, musisz atakowa\u0107 moby siekier\u0105 z efektem\n&eodrzucenie i zada\u0107 \u015bmiertelny cios.\n&eTw\u00f3j top\u00f3r r\u00f3wnie\u017c staje si\u0119 r\u0119cznym r\u0119bakiem,\n&eponiewa\u017c bardzo obni\u017casz poziom zbroi\n&eprzeciwnikom wraz z poziomiem umiej\u0119tno\u015bci.\n&3ZDOBYWANIE XP:\n&eAby zdobywa\u0107 XP musisz atakowa\u0107 moby\n&elub graczy siekier\u0105.
+Guides.Axes.Section.1=&3Jak dzia\u0142a Przecinacz Czaszek?\n&eTa umiej\u0119tno\u015b\u0107 pozwala Ci zada\u0107 obra\u017cenia AoE (Obszarowe). Obra\u017cenia obszarowe zadaj\u0105 po\u0142ow\u0119 Twoich obra\u017ce\u0144, co czyni je dobrym sposobem do zabijania grup mob\u00f3w.
+Guides.Axes.Section.2=&3Jak dzia\u0142a Trafienie Krytyczne?\n&eTrafienia krytyczne jest to pasywna umiej\u0119tno\u015b\u0107, kt\u00f3ra daje Ci mo\u017cliwo\u015b\u0107 zadania dodatkowych obra\u017ce\u0144. Przy domy\u015blnych ustawieniach co 2 poziom umiej\u0119tno\u015bci daje Ci 0.1% szansy na trafienie krytyczne, kt\u00f3re zadaje 2x mobom lub 1.5x przeciwko graczom.
+Guides.Axes.Section.3=&3Jak dzia\u0142a Mistrz Siekier?\n&eJest to umiej\u0119tno\u015b\u0107 pasywna, kt\u00f3ra daje Ci mo\u017cliwo\u015b\u0107 zadania dodatkowych obra\u017ce\u0144 przy u\u017cyciu toporka. Obra\u017cenia zwi\u0119kszaj\u0105 si\u0119 o 1 co 50 poziom\u00f3w, do maksymalnie 4 obra\u017ce\u0144 na poziomie 200.
+Guides.Axes.Section.4=&3Jak dzia\u0142a Uderzenie Pancerza?\n&eUderz z wystarczaj\u0105c\u0105 si\u0142\u0105, aby rozbi\u0107 zbroj\u0119! Uderzenie Pancerza posiada pasywn\u0105 umiej\u0119tno\u015b\u0107, kt\u00f3ra mo\u017ce uszkodzi\u0107 pancerz Twojego przeciwnika. Obra\u017cenia te s\u0105 zwi\u0119kszanie wraz z poziomem Siekiery.
+Guides.Axes.Section.5=&3Jak dzia\u0142a Wi\u0119kszy Wp\u0142yw?\n&eZ ka\u017cdym uderzeniem masz coraz wi\u0119ksz\u0105 szanse na aktywacje Wi\u0119kszy Wp\u0142yw, gdy uderzasz gracza lub moba skiekier\u0105. Domy\u015blna szansa wynosi 25%. Pasywna umiej\u0119tno\u015b\u0107 posiada extremalny efekt odrzutu, podobny do Odrzutu II, jednak\u017ce zadaje ona wi\u0119cej obra\u017ce\u0144\n&eenchantment. Ponadto zadaje dodatkowe obra\u017cenia celowi.
##Excavation
-Guides.Excavation.Section.0=&3About Excavation:\n&eExcavation is the act of digging up dirt to find treasures.\n&eBy excavating the land you will find treasures.\n&eThe more you do this the more treasures you can find.\n\n&3XP GAIN:\n&eTo gain XP in this skill you must dig with a shovel in hand.\n&eOnly certain materials can be dug up for treasures and XP.
-Guides.Excavation.Section.1=&3Compatible Materials:\n&eGrass, Dirt, Sand, Clay, Gravel, Mycelium, Soul Sand, Snow
-Guides.Excavation.Section.2=&3How to use Giga Drill Breaker:\n&eWith a shovel in hand right click to ready your tool.\n&eOnce in this state you have about 4 seconds to make\n&econtact with Excavation compatible materials this will\n&eactivate Giga Drill Breaker.
-Guides.Excavation.Section.3=&3What is Giga Drill Breaker?\n&eGiga Drill Breaker is an ability with a cooldown\n&etied to Excavation skill. It triples your chance\n&eof finding treasures and enables instant break\n&eon Excavation materials.
-Guides.Excavation.Section.4=&3How does Archaeology work?\n&eEvery possible treasure for Excavation has its own\n&eskill level requirement for it to drop, as a result it's\n&edifficult to say how much it is helping you.\n&eJust keep in mind that the higher your Excavation skill\n&eis, the more treasures that can be found.\n&eAnd also keep in mind that each type of Excavation\n&ecompatible material has its own unique list of treasures.\n&eIn other words you will find different treasures in Dirt\nðan you would in Gravel.
-Guides.Excavation.Section.5=&3Notes about Excavation:\n&eExcavation drops are completely customizeable\n&eSo results vary server to server.
+Guides.Excavation.Section.0=&3O Wykopalisku:\n&eWykopaliska to czynno\u015b\u0107 polegaj\u0105ca na wykopywaniu ziemi w celu znalezienia skarb\u00f3w..\n&eIm wi\u0119cej b\u0119dziesz kopa\u0107, tym wi\u0119cej znajdziesz skarb\u00f3w.\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 XP w tej umiej\u0119tno\u015bci nale\u017cy kopa\u0107 \u0142opat\u0105. Tylko niekt\u00f3re rzeczy mo\u017cna wykopa\u0107, aby zdoby\u0107 skarby i EXP. Aby przygotowa\u0107 narz\u0119dzie wci\u015bnij prawy przycisk myszy z \u0142opat\u0105 w d\u0142oni.
+Guides.Excavation.Section.1=&3Kompatybilne Materia\u0142y:\n&eTrawa, Ziemia, Piasek, Glina, \u017bwir, Mycelinium, Piasek Dusz, \u015anieg
+Guides.Excavation.Section.2=&3Jak u\u017cy\u0107 Giga Wiert\u0142o:\n&eKliknij prawy przycisk z \u0142opat\u0105 w r\u0119ce, aby aktywowa\u0107 Giga Wiert\u0142o.\n&eGdy znajdziesz si\u0119 w tym stanie, masz oko\u0142o 4 sekund na kontakt z materia\u0142ami kompatybilnymi z Wykopalisko, aktywuje to Giga Wiert\u0142o.
+Guides.Excavation.Section.3=&3Co to Giga Wiert\u0142o?\n&eGiga Wiert\u0142o to umiej\u0119tno\u015b\u0107 posiadaj\u0105ca czas odnowienia. Daje Ci potr\u00f3jn\u0105 szans\u0119 na znalezienie skarb\u00f3w oraz umo\u017cliwia natychmiastowe kopanie.
+Guides.Excavation.Section.4=&3Jak dzia\u0142a Archeologia?\n&eKa\u017cdy skarb posiada sw\u00f3j wymagany poziom, dlatego otrzymujesz skarb w zale\u017clo\u015bci od Twojego poziomu umiej\u0119tno\u015bci. Pami\u0119taj im wy\u017cszy jest Tw\u00f3j poziom umiej\u0119tno\u015bci, tym wi\u0119cej skarb\u00f3w mo\u017cesz znale\u017a\u0107. Ka\u017cdy skarb, wykopywany z r\u00f3\u017cnych materia\u0142\u00f3w posiada swoj\u0105 unikalna list\u0119 przedmiot\u00f3w, kt\u00f3re si\u0119 w nim znajduj\u0105. Inny skarb otrzymasz z bruku, a zupe\u0142nie inny ze \u017cwiru.
+Guides.Excavation.Section.5=&3Notatki o Wykopaliskach:\n&ePrzedmioty z wykopalisk s\u0105 w pe\u0142ni konfigurowalne, tak wi\u0119c wyniki r\u00f3\u017cni\u0105 si\u0119 mi\u0119dzy serwerami.
##Fishing
-Guides.Fishing.Section.0=&3About Fishing:\n&eWith the Fishing skill, Fishing is exciting again!\n&eFind hidden treasures, and shake items off mobs.\n\n&3XP GAIN:\n&eCatch fish.
-Guides.Fishing.Section.1=&3How does Treasure Hunter work?\n&eThis ability allows you to find treasure from fishing \n&ewith a small chance of the items being enchanted.\n&eEvery possible treasure for Fishing has a chance\n&eto drop on any level. It depends however\n&ewhat the rarity of the item is how often it will drop.\n&eThe higher your Fishing skill is, the better\n&eyour chances are to find better treasures.
-Guides.Fishing.Section.2=&3How does Ice Fishing work?\n&eThis passive skill allows you to fish in ice lakes!\n&eCast your fishing rod in an ice lake and the ability will\n&ecreate a small hole in the ice to fish in.
-Guides.Fishing.Section.3=&3How does Master Angler work?\n&eThis passive skill increases the bite chance while fishing.\n&eWhen you've unlocked this ability, fishing while in\n&ea boat improves odds of catching a fish.
-Guides.Fishing.Section.4=&3How does Shake work?\n&eThis active ability allows you to shake items loose from mobs\n&eby hooking them with the fishing rod. \n&eMobs will drop items they would normally drop on death.\n&eIt is also possible to acquire mob skulls, which are normally \n&eunobtainable in survival mode.
-Guides.Fishing.Section.5=&3How does Fisherman's Diet work?\n&eThis passive skill increases the amount of hunger restored \n&efrom eating fish.
-Guides.Fishing.Section.6=&3Notes about Fishing:\n&eFishing drops are completely customizable,\n&eso results vary server to server.
+Guides.Fishing.Section.0=&3O W\u0119dkarstwie:\n&eDzi\u0119ki umiej\u0119tno\u015bci W\u0119dkarstwo, w\u0119dkarstwo zn\u00f3w jest ekscytuj\u0105ce! Znajd\u017a ukryte skarby i strz\u0105\u015bnij przedmioty z mob\u00f3w.\n\n&3ZDOBYWANIE XP:\n&e\u0141owienie ryb.
+Guides.Fishing.Section.1=&3Jak dzia\u0142a \u0141owca Skarb\u00f3w?\n&eTa umiej\u0119tno\u015b\u0107 pozwala ci znale\u017a\u0107 skarb z \u0142owienia z niewielk\u0105 szans\u0105 na zakl\u0119cie przedmiot\u00f3w. Ka\u017cdy mo\u017cliwy skarb dla w\u0119dkarzy ma szans\u0119 spa\u015b\u0107 na dowolnym poziomie. Zale\u017cy to jednak od rzadko\u015bci przedmiotu, jak cz\u0119sto b\u0119dzie on wypada\u0142. Im wy\u017cszy poziom umiej\u0119tno\u015bci \u0141owienie ryb, tym wi\u0119ksze masz szanse na znalezienie lepszych skarb\u00f3w.
+Guides.Fishing.Section.2=&3Jak dzia\u0142aj\u0105 Mro\u017ane Po\u0142owy?\n&eTa umiej\u0119tno\u015b\u0107 pasywna pozwala \u0142owi\u0107 ryby w lodowych jeziorach! Wrzu\u0107 w\u0119dk\u0119 do lodowego jeziora, a stworzysz w lodzie ma\u0142\u0105 dziur\u0119 do \u0142owienia.
+Guides.Fishing.Section.3=&3Jak dzia\u0142a Mistrz W\u0119dkarstwa?\n&eTa umiej\u0119tno\u015b\u0107 pasywna zwi\u0119ksza szans\u0119 brania podczas \u0142owienia. Po odblokowaniu tej umiej\u0119tno\u015bci \u0142owienie na \u0142odzi zwi\u0119ksza szanse na z\u0142owienie ryby.
+Guides.Fishing.Section.4=&3Jak dzia\u0142a Potrz\u0105sanie?\n&eTa aktywna umiej\u0119tno\u015b\u0107 pozwala strz\u0105sa\u0107 przedmioty z mob\u00f3w poprzez zaczepienie ich w\u0119dk\u0105. Moby upuszczaj\u0105 przedmioty, kt\u00f3re normalnie upuszczaj\u0105 po \u015bmierci. Mo\u017cliwe jest r\u00f3wnie\u017c zdobycie czaszek mob\u00f3w, kt\u00f3re normalnie s\u0105 nieosi\u0105galne w trybie przetrwania.
+Guides.Fishing.Section.5=&3Jak dzia\u0142a Dieta Rybaka?\n&eTa umiej\u0119tno\u015b\u0107 pasywna zwi\u0119ksza ilo\u015b\u0107 przywracanego g\u0142odu po jedzeniu ryby.
+Guides.Fishing.Section.6=&3Notatki o W\u0119dkarstwie:\n&ePrzedmioty z \u0142owienia s\u0105 w pe\u0142ni konfigurowalne, tak wi\u0119c wyniki r\u00f3\u017cni\u0105 si\u0119 mi\u0119dzy serwerami.
##Herbalism
-Guides.Herbalism.Section.0=&3About Herbalism:\n&eHerbalism is about collecting herbs and plants.\n\n\n&3XP GAIN:\n&eCollect plants and herbs.
-Guides.Herbalism.Section.1=&3Compatible Blocks\n&eWheat, Potatoes, Carrots, Melons, \n&ePumpkins, Sugar Canes, Cocoa Beans, Flowers, Cacti, Mushrooms,\n&eNether Wart, Lily Pads, and Vines.
-Guides.Herbalism.Section.2=&3How does Green Terra work?\n&eGreen Terra is an active ability, you can right-click\n&ewhile holding a hoe to activate Green Terra.\n&eGreen Terra grants players a chance to get 3x drops from\n&eharvesting plants. It also gives players the ability to\n&espread life into blocks and transform them using seeds\n&efrom your inventory.
-Guides.Herbalism.Section.3=&3How does Green Thumb (Crops) work?\n&eThis passive ability will automatically replant crops when\n&eharvesting.\n&eYour chance of success depends on your Herbalism skill.
-Guides.Herbalism.Section.4=&3How does Green Thumb (Cobble/Stone Brick/Dirt) work?\n&eThis active ability allows you to turn blocks into their\n&e"plant-related" counterparts. You can do this by right-clicking\n&ea block, while holding seeds. This will consume 1 seed.
-Guides.Herbalism.Section.5=&3How does Farmer's Diet work?\n&eThis passive skill increases the amount of hunger restored \n&ewhen eating Bread, Cookies, Melons, Mushroom Soup, Carrots,\n&eand Potatoes.
-Guides.Herbalism.Section.6=&3How does Hylian Luck work?\n&eThis passive ability gives you a chance to find rare items\n&ewhen certain blocks are broken with a sword.
-Guides.Herbalism.Section.7=&3How do Double Drops work?\n&eThis passive ability gives players more yield from their\n&eharvests.
+Guides.Herbalism.Section.0=&3O Zielarstwie:\n&eZielarstwo polega na zbieraniu zi\u00f3\u0142 i ro\u015blin.\n\n\n&3ZDOBYWANIE XP:\n&eZbieraj ro\u015bliny i zio\u0142a.
+Guides.Herbalism.Section.1=&3Kompatybilne ro\u015bliny:\n&eSiano, Ziemniaki, Marchewki, Arbuzy, \n&eDynie, Trzcina Cukrowa, Kakao, Kwiaty, Kaktusy, Grzyby,\n&eBrodawka, Lilie Wodne, i Liany.
+Guides.Herbalism.Section.2=&3Jak dzia\u0142a Zielona Terra?\n&eZielona Terra to umiej\u0119tno\u015b\u0107 aktywna, mo\u017cesz przytrzyma\u0107 motyk\u0119 prawym przyciskiem myszy, aby aktywowa\u0107 Zielon\u0105 Terr\u0119. Zielona Terra daje graczom szans\u0119 na zdobycie 3x przedmiot\u00f3w ze zbioru ro\u015blin. Daje tak\u017ce graczom mo\u017cliwo\u015b\u0107 dzielenia \u017cycia na bloki i przekszta\u0142cania ich za pomoc\u0105 nasion z ekwipunku.
+Guides.Herbalism.Section.3=&3Jak dzia\u0142a Zielona R\u0105czka (Nasiona)?\n&eTa pasywna umiej\u0119tno\u015b\u0107 automatycznie przesadza plony podczas zbioru. Twoja szansa na sukces zale\u017cy od umiej\u0119tno\u015bci zielarstwa.
+Guides.Herbalism.Section.4=&3Jak dzia\u0142a Zielona R\u0105czka (Bruk/Kamienne Ceg\u0142y/Ziemia)?\n&eTa aktywna zdolno\u015b\u0107 pozwala zamieni\u0107 bloki w ich odpowiedniki „zwi\u0105zane z ro\u015blinami”. Mo\u017cesz to zrobi\u0107, klikaj\u0105c prawym przyciskiem myszy blok, trzymaj\u0105c jednocze\u015bnie nasiona. To poch\u0142onie 1 ziarno.
+Guides.Herbalism.Section.5=&3Jak dzia\u0142a Dieta Farmera?\n&eTa umiej\u0119tno\u015b\u0107 pasywna zwi\u0119ksza ilo\u015b\u0107 przywracanego g\u0142odu podczas jedzenia chleba, ciastek, arbuz\u00f3w, zupy grzybowej, marchwi i ziemniak\u00f3w.
+Guides.Herbalism.Section.6=&3Jak dzia\u0142a Wielkie Szcz\u0119\u015bcie?\n&eTa pasywna umiej\u0119tno\u015b\u0107 daje ci szans\u0119 na znalezienie rzadkich przedmiot\u00f3w, gdy niekt\u00f3re bloki zostan\u0105 rozbite mieczem.
+Guides.Herbalism.Section.7=&3Jak dzia\u0142a Podw\u00f3jny \u0141up?\n&eTa pasywna umiej\u0119tno\u015b\u0107 zapewnia graczom wi\u0119ksze plony.
##Mining
-Guides.Mining.Section.0=&3About Mining:\n&eMining consists of mining stone and ores. It provides bonuses\n&eto the amount of materials dropped while mining.\n\n&3XP GAIN:\n&eTo gain XP in this skill, you must mine with a pickaxe in hand.\n&eOnly certain blocks award XP.
-Guides.Mining.Section.1=&3Compatible Materials:\n&eStone, Coal Ore, Iron Ore, Gold Ore, Diamond Ore, Redstone Ore,\n&eLapis Ore, Obsidian, Mossy Cobblestone, Ender Stone,\n&eGlowstone, and Netherrack.
-Guides.Mining.Section.2=&3How to use Super Breaker:\n&eWith a pickaxe in your hand, right click to ready your tool.\n&eOnce in this state, you have about 4 seconds to make contact\n&ewith Mining compatible materials, which will activate Super\n&eBreaker.
-Guides.Mining.Section.3=&3What is Super Breaker?\n&eSuper Breaker is an ability with a cooldown tied to the Mining\n&eskill. It triples your chance of extra items dropping and\n&eenables instant break on Mining materials.
-Guides.Mining.Section.4=&3How to use Blast Mining:\n&eWith a pickaxe in hand,\n&ecrouch and right-click on TNT from a distance. This will cause the TNT\n&eto instantly explode.
-Guides.Mining.Section.5=&3How does Blast Mining work?\n&eBlast Mining is an ability with a cooldown tied to the Mining\n&eskill. It gives bonuses when mining with TNT and allows you\n&eto remote detonate TNT. There are three parts to Blast Mining.\n&eThe first part is Bigger Bombs, which increases blast radius.\n&eThe second is Demolitions Expert, which decreases damage\n&efrom TNT explosions. The third part simply increases the\n&eamount of ores dropped from TNT and decreases the\n&edebris dropped.
+Guides.Mining.Section.0=&3O G\u00f3rnictwie:\n&eG\u00f3rnictwo obejmuje wydobywanie kamienia i rud. Zapewnia bonusy do ilo\u015bci upuszczanych materia\u0142\u00f3w podczas wydobywania.\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 XP w tej umiej\u0119tno\u015bci, musisz kopa\u0107 z kilofem w d\u0142oni. Tylko niekt\u00f3re bloki zapewniaj\u0105 XP .
+Guides.Mining.Section.1=&3Kompatybilne Minera\u0142y:\n&eKamie\u0144, Ruda W\u0119gla, Ruda \u017belaza, Ruda Z\u0142ota, Ruda Diamentu, Ruda Redstone,\n&eRuda Lapisu, Obsydian, Zamszony Bruk, Kamie\u0144 Endu,\n&eJasnog\u0142az, i Netherrack.
+Guides.Mining.Section.2=&3Jak u\u017cy\u0107 Super Niszczyciela:\n&eKliknij prawy przycisk z kilofem w r\u0119ce, aby aktywowa\u0107 Super Niszczyciel.\n&eGdy znajdziesz si\u0119 w tym stanie, masz oko\u0142o 4 sekund na kontakt z materia\u0142ami kompatybilnymi z Wykopalisko, aktywuje to Super Niszczyciel.
+Guides.Mining.Section.3=&3Co to Super Niszczyciel?\n&eSuper Niszczyciel to umiej\u0119tno\u015b\u0107, kt\u00f3rej czas odnowienia jest powi\u0105zany z umiej\u0119tno\u015bci\u0105 G\u00f3rnictwo. Potroi szans\u0119 na upuszczenie dodatkowych przedmiot\u00f3w i umo\u017cliwia natychmiastowe niszczenie przy wydobywaniu materia\u0142\u00f3w.
+Guides.Mining.Section.4=&3Jak u\u017cy\u0107 Podm\u00f3ch G\u00f3rnictwa:\n&eZ kilofem w d\u0142oni kucnij i kliknij prawym przyciskiem myszy na TNT z daleka. Spowoduje to natychmiastow\u0105 eksplozj\u0119 TNT.
+Guides.Mining.Section.5=&3Jak dzia\u0142\u0105 Podm\u00f3ch G\u00f3rnictwa?\n&ePodm\u00f3ch G\u00f3rnictwa to umiej\u0119tno\u015b\u0107, kt\u00f3rej czas odnowienia jest powi\u0105zany z umiej\u0119tno\u015bci\u0105 G\u00f3rnictwo. Daje bonusy podczas wydobywania z TNT i pozwala zdalnie zdetonowa\u0107 TNT. Podm\u00f3ch G\u00f3rnictwa sk\u0142ada si\u0119 z trzech cz\u0119\u015bci. Pierwsza cz\u0119\u015b\u0107 to Wi\u0119ksze Bomby, kt\u00f3ra zwi\u0119ksza zasi\u0119g ra\u017cenia. Druga to Eksportyza Rozbi\u00f3rki, kt\u00f3ra zmniejsza obra\u017cenia od wybuch\u00f3w TNT. Trzecia cz\u0119\u015b\u0107 po prostu zwi\u0119ksza ilo\u015b\u0107 rud zrzucanych z trotylu i zmniejsza ilo\u015b\u0107 upuszczanych gruzu.
##Repair
-Guides.Repair.Section.0=&3About Repair:\n&eRepair allows you to use an iron block to repair armor and\n&etools.\n\n&3XP GAIN:\n&eRepair tools or armor using the mcMMO Anvil. This is an\n&eiron block by default and should not be confused with\nðe Vanilla Minecraft Anvil.
-Guides.Repair.Section.1=&3How can I use Repair?\n&ePlace down a mcMMO Anvil and right-click to repair the item \n&eyou're currently holding. This consumes 1 item on every use.
-Guides.Repair.Section.2=&3How does Repair Mastery work?\n&eRepair Mastery increases the repair amount. The extra amount\n&erepaired is influenced by your Repair skill level.
-Guides.Repair.Section.3=&3How does Super Repair work?\n&eSuper Repair is a passive ability. When repairing an item,\n&eit grants players a chance to repair an item with\n&edouble effectiveness.
-Guides.Repair.Section.4=&3How does Arcane Forging work?\n&eThis passive ability allows you to repair items with a certain\n&echance of maintaining its enchantments. The enchants may be\n&ekept at their existing levels, downgraded to a lower level,\n&eor lost entirely.
+Guides.Repair.Section.0=&3O Naprawianiu:\n&eNaprawa umo\u017cliwia u\u017cycie \u017celaznego bloku do naprawy zbroi i narz\u0119dzi .\n\n&3ZDOBYWANIE XP:\n&eNapraw narz\u0119dzia lub zbroj\u0119 za pomoc\u0105 kowad\u0142a mcMMO. Jest to domy\u015blnie \u017celazny blok i nie nale\u017cy go myli\u0107 z kowad\u0142em Vanilla.
+Guides.Repair.Section.1=&3Jak naprawia\u0107 w mcMMO?\n&ePo\u0142\u00f3\u017c kowad\u0142o mcMMO i kliknij prawym przyciskiem myszy, aby naprawi\u0107 przedmiot, kt\u00f3ry aktualnie trzymasz. Przy ka\u017cdym u\u017cyciu zu\u017cywa 1 przedmiot (Na przyk\u0142ad przy \u017celaznych narz\u0119dziach zu\u017cyje jedno \u017celazo).
+Guides.Repair.Section.2=&3Jak dzia\u0142a Mistrz Napraw?\n&ePoziom Mistrza Napraw zwi\u0119ksza si\u0119 wraz z naprawianymi przedmiotami. Dodatkow\u0105 przywr\u00f3con\u0105 wytrzyma\u0142o\u015b\u0107 zale\u017cy od poziomu Naprawianie.
+Guides.Repair.Section.3=&3Jak dzia\u0142a Super Naprawa?\n&eSuper Naprawa to umiej\u0119tno\u015b\u0107 pasywna. Podczas naprawy przedmiotu daje graczom szans\u0119 na naprawienie przedmiotu z podw\u00f3jn\u0105 skuteczno\u015bci\u0105.
+Guides.Repair.Section.4=&3Jak dzia\u0142a Tajemne Fa\u0142szowanie?\n&eTa pasywna umiej\u0119tno\u015b\u0107 pozwala naprawia\u0107 przedmioty z pewn\u0105 szans\u0105 na utrzymanie zakl\u0119\u0107. Zakl\u0119cia mog\u0105 pozosta\u0107 na dotychczasowych poziomach, zdegradowane do ni\u017cszych lub ca\u0142kowicie utracone.
##Salvage
-Guides.Salvage.Section.0=&3About Salvage:\n&eSalvage allows you to use a gold block to salvage armor and\n&etools.\n\n&3XP GAIN:\n&eSalvage is a child skill of Repair and Fishing, your Salvage\n&eskill level is based on your Fishing and Repair skill levels.
-Guides.Salvage.Section.1=&3How can I use Salvage?\n&ePlace down a mcMMO Salvage Anvil and right-click to salvage\nðe item you're currently holding. This will break apart the item,\n&eand give back materials used to craft the item.\n\n&eFor example, salvaging an iron pickaxe will give you iron bars.
-Guides.Salvage.Section.2=&3How does Advanced Salvage work?\n&eWhen unlocked, this ability allows you to salvage damaged items.\n&eThe yield percentage increases as you level up. A higher yield\n&emeans that you can get more materials back.\n&eWith advanced salvage you will always get 1 material back,\n&eunless the item is too damaged. So you don't have to worry\n&eabout destroying items without getting anything in return.
-Guides.Salvage.Section.3=&3To illustrate how this works, here's an example:\n&eLet's say we salvage a gold pickaxe which is damaged for 20%,\nðis means that the maximum amount you could get is only 2\n&e(because the pick is crafted with 3 ingots - each worth\n&e33,33% durability) which is equal to 66%. If your yield\n&epercentage is below 66% you are not able to get 2 ingots.\n&eIf it is above this value you are able to gain the "full amount",\n&ewhich means that you will get 2 ingots.
-Guides.Salvage.Section.4=&3How does Arcane Salvage work?\n&eThis ability allows you to get enchanted books when salvaging\n&eenchanted items. Depending on your level the chance of\n&esuccessfully extracting a full or partial enchantment varies.\n\n&eWhen an enchantment is partially extracted, the enchantment\n&ebook will have a lower level enchantment compared to what\n&eit was on the item.
+Guides.Salvage.Section.0=&3O odzyskiwaniu:\n&eUmie\u015bci\u0142e\u015b odzyskiwanie pozwala ci u\u017cy\u015b z\u0142otego bloku do odzyskania zbroi i narz\u0119dzi..\n\n&3ZDOBYWANIE XP:\n&eOdzyskiwanie to umiej\u0119tno\u015b\u0107 podrz\u0119dna Naprawy i W\u0119dkarstwa, wi\u0119c Tw\u00f3j poziom umiej\u0119tno\u015bci Odzyskiwania jest oparty na twoich poziomach umiej\u0119tno\u015bci W\u0119dkarstwa i Naprawy.
+Guides.Salvage.Section.1=&3Jak u\u017cwa\u0107 Odzyskiwanie?\n&ePo\u0142\u00f3\u017c kowad\u0142o mcMMO (tj. z\u0142oty blok) i kliknij prawym przyciskiem myszy, aby odzyska\u0107 przedmioty z narz\u0119dzia, kt\u00f3ry aktualnie trzymasz. Spowoduje to zniszczenie przedmiotu i zwr\u00f3cenie materia\u0142\u00f3w u\u017cytych do wytworzenia przedmiotu.
+Guides.Salvage.Section.2=&3Jak dzia\u0142a Zaawansowane Odzyskiwanie?\n&ePo odblokowaniu umiej\u0119tno\u015b\u0107 ta pozwala na odzyskanie uszkodzonych przedmiot\u00f3w. Procent zysku ro\u015bnie wraz ze wzrostem poziomu. Wy\u017csza wydajno\u015b\u0107 oznacza, \u017ce mo\u017cna odzyska\u0107 wi\u0119cej materia\u0142\u00f3w. Dzi\u0119ki zaawansowanemu odzyskowi zawsze otrzymasz 1 materia\u0142 z powrotem, chyba \u017ce przedmiot jest zbyt uszkodzony. Nie musisz wi\u0119c martwi\u0107 si\u0119 o niszczenie przedmiot\u00f3w, nie otrzymuj\u0105c niczego w zamian.
+Guides.Salvage.Section.3=&3Aby pokaza\u0107 przyk\u0142ad, tutaj go opisujemy:\n&ePowiedzmy, \u017ce odzyskujemy z\u0142oty kilof, kt\u00f3ry jest uszkodzony o 20%, co oznacza, \u017ce maksymalna kwota, jak\u0105 mo\u017cesz zdoby\u0107, to tylko 2 (poniewa\u017c kilof jest tworzony z 3 sztabek - ka\u017cdy wart 33,33% wytrzyma\u0142o\u015bci), co jest r\u00f3wne 66% . Je\u015bli Tw\u00f3j procent wytrzyma\u0142o\u015bci jest ni\u017cszy ni\u017c 66%, nie jeste\u015b w stanie uzyska\u0107 2 sztabek. Je\u015bli jest powy\u017cej tej warto\u015bci, mo\u017cesz uzyska\u0107 „pe\u0142n\u0105 kwot\u0119”, co oznacza, \u017ce otrzymasz 2 sztabki.
+Guides.Salvage.Section.4=&3Jak dzia\u0142a Tajemne Odzyskiwanie?\n&eTa umiej\u0119tno\u015b\u0107 pozwala zdoby\u0107 zakl\u0119te ksi\u0105\u017cki podczas odzyskiwania zakl\u0119tych przedmiot\u00f3w. W zale\u017cno\u015bci od twojego poziomu, szansa na pomy\u015blne wyodr\u0119bnienie pe\u0142nego lub cz\u0119\u015bciowego zakl\u0119cia jest r\u00f3\u017cna.\n\n&eKiedy zakl\u0119cie zostanie cz\u0119\u015bciowo wydobyte, ksi\u0119ga zakl\u0119\u0107 b\u0119dzie mia\u0142a ni\u017cszy poziom zakl\u0119cia w por\u00f3wnaniu z tym, co znajdowa\u0142o si\u0119 na przedmiocie.
##Smelting
-Guides.Smelting.Section.0=Coming soon...
+Guides.Smelting.Section.0=Wkr\u00f3tce...
##Swords
-Guides.Swords.Section.0=&3About Swords:\n&eThis skill awards combat bonuses to anyone fighting with a\n&esword.\n\n&3XP GAIN:\n&eXP is gained based on the amount of damage dealt to mobs or \n&eother players when wielding a sword.
-Guides.Swords.Section.1=&3How does Serrated Strikes work?\n&eSerrated Strikes is an active ability, you can activate it by\n&eright-clicking with a sword. This ability allows you to deal \n&ean AoE (Area of Effect) hit. This AoE will do a bonus 25%\n&edamage and will inflict a bleed effect that lasts for 5 ticks.
-Guides.Swords.Section.2=&3How does Counter Attack work?\n&eCounter Attack is an active ability. When blocking and taking\n&ehits from mobs, you will have a chance to reflect 50% of \nðe damage that was taken.
-Guides.Swords.Section.3=&3How does Rupture work?\n&eRupture causes enemies to take damage every two seconds. The \n&etarget will bleed until the effect wears off, or death, \n&ewhichever comes first.\n&eThe duration of the bleed is increased by your sword skill.
+Guides.Swords.Section.0=&3O Mieczach:\n&eTa umiej\u0119tno\u015b\u0107 zapewnia premie bojowe ka\u017cdemu, kto walczy mieczem..\n\n&3ZDOBYWANIE XP:\n&eXP jest zdobywane w oparciu o ilo\u015b\u0107 obra\u017ce\u0144 zadanych mobom lub innym graczom, gdy dzier\u017cysz miecz. .
+Guides.Swords.Section.1=&3Jak dzia\u0142aj\u0105 Z\u0105bkowane Uderzenia?\n&eZ\u0105bkowane Uderzenia to umiej\u0119tno\u015b\u0107 aktywna, kt\u00f3r\u0105 mo\u017cna aktywowa\u0107, klikaj\u0105c prawym przyciskiem myszy mieczem. Ta umiej\u0119tno\u015b\u0107 pozwala na zadanie trafienia obszarowego. Ten obszar dzia\u0142ania zadaje dodatkowe 25% obra\u017ce\u0144 i wywo\u0142a efekt krwawienia trwaj\u0105cy 5 tik\u00f3w.
+Guides.Swords.Section.2=&3Jak dzia\u0142a Kontraatak?\n&eKontratak to aktywna umiej\u0119tno\u015b\u0107. Podczas blokowania i przyjmowania trafie\u0144 od mob\u00f3w, b\u0119dziesz mia\u0142 szans\u0119 odbi\u0107 50% otrzymanych obra\u017ce\u0144.
+Guides.Swords.Section.3=&3Jak dzia\u0142a Rozerwanie?\n&eRozerwanie powoduje, \u017ce wrogowie otrzymuj\u0105 obra\u017cenia co dwie sekundy. Cel b\u0119dzie krwawi\u0142 do momentu ust\u0105pienia efektu lub \u015bmierci, w zale\u017cno\u015bci od tego, co nast\u0105pi wcze\u015bniej. Poziom umiej\u0119tno\u015bci Miecze zwi\u0119ksza czas trwania krwawienia.
##Taming
-Guides.Taming.Section.0=&3About Taming:\n&eTaming will give players various combat bonuses when using\n&etamed wolves.\n\n&3XP GAIN:\n&eTo gain XP in this skill, you need to tame wolves/ocelots or\n&eget into combat with your wolves.
-Guides.Taming.Section.1=&3How does Call of the Wild work?\n&eCall of the Wild is an active ability that will allow you to summon\n&ea wolf or an ocelot by your side. You can do this by\n&esneaking + left-clicking while holding bones or fish.
-Guides.Taming.Section.2=&3How does Beast Lore work?\n&eBeast Lore allows players to inspect pets and to check the\n&estats of wolves and ocelots. Left-click a wolf or ocelot to use\n&eBeast Lore.
-Guides.Taming.Section.3=&3How does Gore work?\n&eGore is a passive ability that has a chance of inflicting a\n&ebleeding effect on your wolves' targets.
-Guides.Taming.Section.4=&3How does Sharpened Claws work?\n&eSharpened Claws provides a damage bonus to damage dealt\n&eby wolves. The damage bonus depends on your Taming level.
-Guides.Taming.Section.5=&3How does Environmentally Aware work?\n&eThis passive ability will allow wolves to teleport to you when\nðey get near hazards, such as Cacti/Lava. It will also give\n&ewolves fall damage immunity.
-Guides.Taming.Section.6=&3How does Thick Fur work?\n&eThis passive ability will reduce damage and make wolves\n&efire resistant.
-Guides.Taming.Section.7=&3How does Shock Proof work?\n&eThis passive ability reduces damage done to wolves\n&efrom explosions.
-Guides.Taming.Section.8=&3How does Fast Food Service work?\n&eThis passive ability gives wolves a chance to heal whenever\nðey perform an attack.
+Guides.Taming.Section.0=&3O Oswajaniu:\n&eOswajanie zapewni graczom r\u00f3\u017cne bonusy bojowe podczas u\u017cywania oswojonych wilk\u00f3w.\n\n&3ZDOBYWANIE XP:\n&eAby zdoby\u0107 XP w tej umiej\u0119tno\u015bci, musisz oswoi\u0107 wilki lub oceloty i wyruszy\u0107 do walki ze swoimi sprzymierze\u0144cami.
+Guides.Taming.Section.1=&3Jak dzia\u0142a Zew Natury?\n&eZew Natury to aktywna umiej\u0119tno\u015b\u0107, kt\u00f3ra pozwoli ci przywo\u0142a\u0107 wilka lub ocelota do swojego boku. Mo\u017cesz to zrobi\u0107 kucaj\u0105c (shift) + klikni\u0119cie lewym przyciskiem myszy, trzymaj\u0105c ko\u015bci lub ryb\u0119.
+Guides.Taming.Section.2=&3Jak dzia\u0142a Wiedza Bestii?\n&eWiedza Bestii pozwala graczom na zbadanie zwierzak\u00f3w i sprawdzanie stanu wilk\u00f3w i ocelot\u00f3w. Kliknij lewym przyciskiem myszy na wilka lub ocelota, aby u\u017cy\u0107 Wiedzy Bestii.
+Guides.Taming.Section.3=&3How does Gore work?\n&eKrwawienie to pasywna umiej\u0119tno\u015b\u0107, kt\u00f3ra ma szans\u0119 wywo\u0142a\u0107 efekt krwawienia na celach przez Twoich wilk\u00f3w.
+Guides.Taming.Section.4=&3Jak dzia\u0142aj\u0105 Zaostrzone Pazury?\n&eZaostrzone Pazury zapewnia premi\u0119 do obra\u017ce\u0144 zadawanych przez wilki. Premia do obra\u017ce\u0144 zale\u017cy od Twojego poziomu Oswajania.
+Guides.Taming.Section.5=&3Jak dzia\u0142a Sprzymierzeniec Natury?\n&eTa pasywna umiej\u0119tno\u015b\u0107 pozwoli wilkom teleportowa\u0107 si\u0119 do ciebie, gdy zbli\u017c\u0105 si\u0119 do niebezpiecze\u0144stw, takich jak kaktusy czy lawa. Zapewni tak\u017ce wilkom odporno\u015b\u0107 na obra\u017cenia od upadku.
+Guides.Taming.Section.6=&3Jak dzia\u0142a grube futro??\n&eTa pasywna umiej\u0119tno\u015b\u0107 zmniejszy obra\u017cenia i sprawi, \u017ce wilki b\u0119d\u0105 odporne na ogie\u0144.
+Guides.Taming.Section.7=&3Jak dzia\u0142a odporno\u015b\u0107 na wstrz\u0105sy?\n&eTa umiej\u0119tno\u015b\u0107 pasywna zmniejsza obra\u017cenia zadawane wilkom od eksplozji.
+Guides.Taming.Section.8=&3Jak dzia\u0142a serwis Fast Food??\n&eTa pasywna umiej\u0119tno\u015b\u0107 daje wilkom szans\u0119 na uleczenie si\u0119, gdy wykonaj\u0105 atak.
##Unarmed
Guides.Unarmed.Section.0=&3About Unarmed:\n&eUnarmed will give players various combat bonuses when using\n&eyour fists as a weapon. \n\n&3XP GAIN:\n&eXP is gained based on the amount of damage dealt to mobs \n&eor other players when unarmed.
Guides.Unarmed.Section.1=&3How does Berserk work?\n&eBeserk is an active ability that is activated by\n&eright-clicking. While in Beserk mode, you deal 50% more\n&edamage and you can break weak materials instantly, such as\n&eDirt and Grass.
@@ -962,10 +964,10 @@ Guides.Unarmed.Section.3=&3How does Arrow Deflect work?\n&eArrow Deflect is a pa
Guides.Unarmed.Section.4=&3How does Iron Grip work?\n&eIron Grip is a passive ability that counters disarm. As your\n&eunarmed level increases, the chance of preventing a disarm increases.
Guides.Unarmed.Section.5=&3How does Disarm work?\n&eThis passive ability allows players to disarm other players,\n&ecausing the target's equipped item to fall to the ground.
##Woodcutting
-Guides.Woodcutting.Section.0=&3About Woodcutting:\n&eWoodcutting is all about chopping down trees.\n\n&3XP GAIN:\n&eXP is gained whenever you break log blocks.
-Guides.Woodcutting.Section.1=&3How does Tree Feller work?\n&eTree Feller is an active ability, you can right-click\n&ewhile holding an ax to activate Tree Feller. This will\n&ecause the entire tree to break instantly, dropping all\n&eof its logs at once.
-Guides.Woodcutting.Section.2=&3How does Leaf Blower work?\n&eLeaf Blower is a passive ability that will cause leaf\n&eblocks to break instantly when hit with an axe. By default,\nðis ability unlocks at level 100.
-Guides.Woodcutting.Section.3=&3How do Double Drops work?\n&eThis passive ability gives you a chance to obtain an extra\n&eblock for every log you chop.
+Guides.Woodcutting.Section.0=&3O Drwalu:\n&eDrwal polega na wycinaniu drzew.\n\n&3ZDOBYWANIE XP:\n&eXP jest zdobywany za ka\u017cdym razem, gdy niszczysz bloki k\u0142\u00f3d.
+Guides.Woodcutting.Section.1=&3Jak dzia\u0142a \u015acinacz Drzew?\n&e\u015cinacz Drzew to aktywna umiej\u0119tno\u015b\u0107, mo\u0107na klikn\u0105\u0107 prawym przyciskiem trzymaj\u0105c siekier\u0119, aby aktywowa\u0107 \u015cinacz Drzew. Spowoduje to natychmiastowe zniszczenie ca\u0142ego drzewa, zrzucaj\u0105c jednocze\u015bnie wszystkie k\u0142ody.
+Guides.Woodcutting.Section.2=&3Jak dzia\u0142a Dmuchawa Do Li\u015bci?\n&eDmuchawa do li\u015bci to umiej\u0119tno\u015b\u0107 pasywna, kt\u00f3ra powoduje, \u017ce bloki li\u015bci natychmiast si\u0119 niszcz\u0105 po uderzeniu siekier\u0105. Umiej\u0119tno\u015b\u0107 ta domy\u015blnie odblokowuje si\u0119 na poziomie 100.
+Guides.Woodcutting.Section.3=&3Jak dzia\u0142a Podw\u00f3jny \u0141up?\n&eTa pasywna umiej\u0119tno\u015b\u0107 daje ci szans\u0119 na uzyskanie dodatkowego bloku za ka\u017cd\u0105 posiekan\u0105 k\u0142od\u0119.
#INSPECT
Inspect.Offline= &cNie masz uprawnie\u0144 do sprawdzania graczy offline!
Inspect.OfflineStats=Statystyki mcMMO dla gracza off-line &e{0}
@@ -982,7 +984,7 @@ Item.Generic.Wait=Musisz odczeka\u0107 zanim ponownie to u\u017cyjesz! &e({0}s)
Item.Injured.Wait=Niedawno by\u0142e\u015b kontuzjowany i musisz poczeka\u0107, zanim to wykorzystasz. &e({0}s)
Item.FluxPickaxe.Name=Topi\u0105cy Kilof
Item.FluxPickaxe.Lore.1=&7Ma szanse na natychmiastowe przepalenie rudy.
-Item.FluxPickaxe.Lore.2=&7Wymaga poziomu &6Przepalanie: &7{0}+
+Item.FluxPickaxe.Lore.2=&7Wymaga poziomu &6Przepalania: &7{0}+
#TELEPORTATION
Teleport.Commencing=&7Rozpoczynanie teleportacji… Przez &6({0}) &7sekund, nie ruszaj si\u0119...
Teleport.Cancelled=&4Teleportacja anulowana!
diff --git a/src/main/resources/persistent_data.yml b/src/main/resources/persistent_data.yml
index 6b39879cd..8508ab84f 100644
--- a/src/main/resources/persistent_data.yml
+++ b/src/main/resources/persistent_data.yml
@@ -29,4 +29,9 @@ Persistent_Data:
Saved_To_Disk: false
# By default mcMMO gives 0 XP for this type of mob, not adjustable currently
PLAYER_TAMED_MOB:
- Saved_To_Disk: false
\ No newline at end of file
+ Saved_To_Disk: false
+# When players put down a block we track it, the system used to track player blocks is super efficient and has been coded extremely well
+# It is never recommended to turn this off as it allows exploits such as player dupes etc
+# We use our own file system for this outside of NBT which has been programmed to be lightning fast
+mcMMO_Region_System:
+ Enabled: true
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 9b0b03ab4..64f2c982d 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -171,9 +171,6 @@ commands:
aliases: [notify]
description: Toggle mcMMO abilities chat display notifications on/off
permission: mcmmo.commands.mcnotify
- mhd:
- description: Sets all players mob health settings to default
- permission: mcmmo.commands.mhd
mcscoreboard:
aliases: [mcsb]
description: Manage your mcMMO Scoreboard
diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java
new file mode 100644
index 000000000..2acbd41f8
--- /dev/null
+++ b/src/test/java/com/gmail/nossr50/database/FlatFileDataProcessorTest.java
@@ -0,0 +1,23 @@
+package com.gmail.nossr50.database;
+
+import org.junit.Test;
+
+public class FlatFileDataProcessorTest {
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ @Test
+ public void testGetExpectedValueType() {
+ for(int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT; i++) {
+ FlatFileDataProcessor.getExpectedValueType(i);
+ }
+ }
+
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testGetExpectedValueTypeException() {
+ for(int i = 0; i < FlatFileDatabaseManager.DATA_ENTRY_COUNT+1; i++) {
+ FlatFileDataProcessor.getExpectedValueType(i);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java
new file mode 100644
index 000000000..62d13f69a
--- /dev/null
+++ b/src/test/java/com/gmail/nossr50/database/FlatFileDatabaseManagerTest.java
@@ -0,0 +1,1019 @@
+package com.gmail.nossr50.database;
+
+import com.gmail.nossr50.TestUtil;
+import com.gmail.nossr50.database.flatfile.LeaderboardStatus;
+import com.gmail.nossr50.datatypes.database.DatabaseType;
+import com.gmail.nossr50.datatypes.player.PlayerProfile;
+import com.gmail.nossr50.datatypes.player.UniqueDataType;
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
+import com.gmail.nossr50.util.skills.SkillTools;
+import com.google.common.io.Files;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.Statistic;
+import org.bukkit.entity.EntityType;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.logging.Filter;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+//This class uses JUnit5/Jupiter
+public class FlatFileDatabaseManagerTest {
+
+ public static final @NotNull String TEST_FILE_NAME = "test.mcmmo.users";
+ public static final @NotNull String BAD_FILE_LINE_ONE = "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:";
+ public static final @NotNull String BAD_DATA_FILE_LINE_TWENTY_THREE = "nossr51:baddata:::baddata:baddata:640:baddata:1000:1000:1000:baddata:baddata:baddata:baddata:16:0:500:20273:0:0:0:0::1000:0:0:baddata:1593543012:0:0:0:0::1000:0:0:baddata:IGNORED:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1:0:";
+ public static final @NotNull String DB_BADDATA = "baddatadb.users";
+ public static final @NotNull String DB_HEALTHY = "healthydb.users";
+ public static final @NotNull String HEALTHY_DB_LINE_1 = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:IGNORED:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:2020:";
+ public static final @NotNull String HEALTHY_DB_LINE_ONE_UUID_STR = "588fe472-1c82-4c4e-9aa1-7eefccb277e3";
+ public static final String DB_MISSING_LAST_LOGIN = "missinglastlogin.users";
+ public static final String LINE_TWO_FROM_MISSING_DB = "nossr50:1:IGNORED:IGNORED:10:2:20:3:4:5:6:7:8:9:10:30:40:50:60:70:80:90:100:IGNORED:11:110:111:222:333:444:555:666:777:IGNORED:12:120:888:0:HEARTS:13:130:588fe472-1c82-4c4e-9aa1-7eefccb277e3:1111:999:";
+ private static File tempDir;
+ private final static @NotNull Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+ private final long PURGE_TIME = 2630000000L;
+ private static @Nullable FlatFileDatabaseManager db;
+
+ //Making them all unique makes it easier on us to edit this stuff later
+ int expectedLvlMining = 1, expectedLvlWoodcutting = 2, expectedLvlRepair = 3,
+ expectedLvlUnarmed = 4, expectedLvlHerbalism = 5, expectedLvlExcavation = 6,
+ expectedLvlArchery = 7, expectedLvlSwords = 8, expectedLvlAxes = 9, expectedLvlAcrobatics = 10,
+ expectedLvlTaming = 11, expectedLvlFishing = 12, expectedLvlAlchemy = 13;
+
+ float expectedExpMining = 10, expectedExpWoodcutting = 20, expectedExpRepair = 30,
+ expectedExpUnarmed = 40, expectedExpHerbalism = 50, expectedExpExcavation = 60,
+ expectedExpArchery = 70, expectedExpSwords = 80, expectedExpAxes = 90, expectedExpAcrobatics = 100,
+ expectedExpTaming = 110, expectedExpFishing = 120, expectedExpAlchemy = 130;
+
+ long expectedBerserkCd = 111, expectedGigaDrillBreakerCd = 222, expectedTreeFellerCd = 333,
+ expectedGreenTerraCd = 444, expectedSerratedStrikesCd = 555, expectedSkullSplitterCd = 666,
+ expectedSuperBreakerCd = 777, expectedBlastMiningCd = 888, expectedChimaeraWingCd = 999;
+
+ int expectedScoreboardTips = 1111;
+ Long expectedLastLogin = 2020L;
+
+ @BeforeAll
+ static void initBeforeAll() {
+ logger.setFilter(new DebugFilter());
+ }
+
+ @BeforeEach
+ public void init() {
+ assertNull(db);
+ //noinspection UnstableApiUsage
+ tempDir = Files.createTempDir();
+ db = new FlatFileDatabaseManager(new File(getTemporaryUserFilePath()), logger, PURGE_TIME, 0, true);
+ }
+
+ private @NotNull String getTemporaryUserFilePath() {
+ return tempDir.getPath() + File.separator + TEST_FILE_NAME;
+ }
+
+ @AfterEach
+ public void tearDown() {
+ TestUtil.recursiveDelete(tempDir);
+ db = null;
+ }
+
+ //Nothing wrong with this database
+ private static final String[] normalDatabaseData = {
+ "nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
+ "powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
+ };
+
+ private static final String[] badUUIDDatabaseData = {
+ "nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "z750:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:3:5:1600906906:", //This one has an incorrect UUID representation
+ "powerless:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
+ };
+
+ private static final String[] outdatedDatabaseData = {
+ "nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
+ "electronicboy:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:" //This user is missing data added after UUID index
+ };
+
+ private static final String[] emptyLineDatabaseData = {
+ "nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
+ "kashike:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:",
+ "" //EMPTY LINE
+ };
+
+ private static final String[] emptyNameDatabaseData = {
+ ":1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
+ "aikar:0:::0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0::0:0:0:0:0:0:0:0:0::0:0:0:0:HEARTS:0:0:e0d07db8-f7e8-43c7-9ded-864dfc6f3b7c:5:1600906906:"
+ };
+
+ private static final String[] duplicateNameDatabaseData = {
+ "mochi:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mochi:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:631e3896-da2a-4077-974b-d047859d76bc:0:0:",
+ };
+
+ private static final String[] duplicateUUIDDatabaseData = {
+ "nossr50:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:1000:::0:1000:640:1000:1000:1000:1000:1000:1000:1000:1000:16:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ };
+
+ private static final String[] corruptDatabaseData = {
+ "nossr50:1000:::0:100:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:",
+ "corruptdataboy:の:::ののの0:2452:0:1983:1937:1790:3042ののののの:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617のののののの583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:d20c6e8d-5615-4284-b8d1-e20b92011530:5:1600906906:",
+ "のjapaneseuserの:333:::0:2452:0:444:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:25870f0e-7558-4659-9f60-417e24cb3332:5:1600906906:",
+ "sameUUIDasjapaneseuser:333:::0:442:0:544:1937:1790:3042:1138:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:25870f0e-7558-4659-9f60-417e24cb3332:5:1600906906:",
+ };
+
+ private static final String[] badDatabaseData = {
+ //First entry here is missing some values
+ "nossr50:1000:0:500:0:0:0:0:0::1000:0:0:0:1593543012:0:0:0:0::1000:0:0:1593806053:HEARTS:1000:0:588fe472-1c82-4c4e-9aa1-7eefccb277e3:0:0:",
+ //Second entry here has an integer value replaced by a string
+ "mrfloris:2420:::0:2452:0:1983:1937:1790:3042:badvalue:3102:2408:3411:0:0:0:0:0:0:0:0::642:0:1617583171:0:1617165043:0:1617583004:1617563189:1616785408::2184:0:0:1617852413:HEARTS:415:0:631e3896-da2a-4077-974b-d047859d76bc:5:1600906906:"
+ };
+
+ @Test
+ public void testDefaultInit() {
+ db = new FlatFileDatabaseManager(getTemporaryUserFilePath(), logger, PURGE_TIME, 0);
+ }
+
+ @Test
+ public void testUpdateLeaderboards() {
+ assertNotNull(db);
+ assertEquals(LeaderboardStatus.UPDATED, db.updateLeaderboards());
+ }
+
+ @Test
+ public void testSaveUser() {
+ //Make a Profile to save and check to see if it worked
+ UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
+ String playerName = "nossr50";
+ PlayerProfile testProfile = new PlayerProfile(playerName, uuid, 0);
+ //The above profile should be "zero" initialized
+
+ //Save the zero version and see if it looks correct
+ assertNotNull(db);
+ assertTrue(db.getUsersFile().exists()); //Users file should have been created from the above com.gmail.nossr50.database.FlatFileDatabaseManager.checkFileHealthAndStructure
+ assertNotNull(db.getUsersFile());
+
+ //The DB is empty at this point, add our user
+ assertTrue(db.saveUser(testProfile)); //True means we saved the user
+
+ //Check for the empty profile
+ PlayerProfile retrievedFromData = db.loadPlayerProfile(uuid);
+ assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
+ assertEquals(uuid, retrievedFromData.getUniqueId());
+ assertEquals(playerName, retrievedFromData.getPlayerName());
+
+ /*
+ * Test overwriting names with new names
+ */
+
+ String alteredName = "changedmyname";
+ PlayerProfile changedNameProfile = new PlayerProfile(alteredName, uuid, 0);
+ assertTrue(db.saveUser(changedNameProfile)); //True means we saved the user
+
+ retrievedFromData = db.loadPlayerProfile(uuid);
+ assertTrue(retrievedFromData.isLoaded()); //PlayerProfile::isLoaded returns true if the data was created from the file, false if it wasn't found and a dummy profile was returned
+ assertEquals(uuid, retrievedFromData.getUniqueId());
+ assertEquals(alteredName, retrievedFromData.getPlayerName());
+ }
+
+ @Test
+ public void testAddedMissingLastLoginValues() {
+ File dbFile = prepareDatabaseTestResource(DB_MISSING_LAST_LOGIN);
+
+ //This makes sure our private method is working before the tests run afterwards
+ ArrayList dataFromFile = getSplitDataFromFile(dbFile);
+ logger.info("File Path: "+ dbFile.getAbsolutePath());
+ assertArrayEquals(LINE_TWO_FROM_MISSING_DB.split(":"), dataFromFile.get(1));
+ assertEquals(dataFromFile.get(1)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
+
+ db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
+ List flagsFound = db.checkFileHealthAndStructure();
+ assertNotNull(flagsFound);
+ assertTrue(flagsFound.contains(FlatFileDataFlag.LAST_LOGIN_SCHEMA_UPGRADE));
+
+ //Check for the fixed value
+ PlayerProfile profile = db.loadPlayerProfile("nossr50");
+ assertEquals(-1, (long) profile.getLastLogin());
+ }
+
+ @Test
+ public void testLoadByName() {
+ File healthyDB = prepareDatabaseTestResource(DB_HEALTHY);
+
+ /*
+ * We have established the files are in good order, so now for the actual testing
+ */
+
+ //This makes sure our private method is working before the tests run afterwards
+ ArrayList dataFromFile = getSplitDataFromFile(healthyDB);
+ logger.info("File Path: "+healthyDB.getAbsolutePath());
+ assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
+ assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
+ UUID healthDBEntryOneUUID = UUID.fromString(HEALTHY_DB_LINE_ONE_UUID_STR);
+
+ db = new FlatFileDatabaseManager(healthyDB, logger, PURGE_TIME, 0, true);
+ List flagsFound = db.checkFileHealthAndStructure();
+ assertNull(flagsFound); //No flags should be found
+
+ /*
+ * Once the DB looks fine load the profile
+ */
+
+ String playerName = "nossr50";
+ UUID uuid = UUID.fromString("588fe472-1c82-4c4e-9aa1-7eefccb277e3");
+
+ PlayerProfile profile = db.loadPlayerProfile(playerName);
+ testHealthyDataProfileValues(playerName, uuid, profile);
+ }
+
+ @Test
+ public void testNewUser() {
+ //We will test that new user values line up with our expectations
+ UUID uuid = new UUID(0, 1);
+ String playerName = "nossr50";
+
+ int newUserTestStartingLvl = 1337;
+ db = new FlatFileDatabaseManager(new File(tempDir.getPath() + File.separator + TEST_FILE_NAME), logger, PURGE_TIME, newUserTestStartingLvl, true);
+ db.checkFileHealthAndStructure();
+
+ PlayerProfile playerProfile = db.newUser(playerName, uuid);
+
+ assertTrue(playerProfile.isLoaded());
+ assertEquals(playerName, playerProfile.getPlayerName());
+ assertEquals(uuid, playerProfile.getUniqueId());
+
+ PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
+ assertTrue(retrievedFromDisk.isLoaded());
+ assertEquals(playerName, retrievedFromDisk.getPlayerName());
+ assertEquals(uuid, retrievedFromDisk.getUniqueId());
+
+ //Checking a new user for being "zero" initialized
+ checkNewUserValues(playerProfile, newUserTestStartingLvl);
+ checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
+
+ //TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
+ db.newUser("disco", new UUID(3, 3));
+ db.newUser("dingus", new UUID(3, 4));
+ db.newUser("duped_dingus", new UUID(3, 4));
+
+ assertEquals(5, getSplitDataFromFile(db.getUsersFile()).size());
+ }
+
+ @Test
+ public void testAddingUsersToEndOfExistingDB() {
+ //We will test that new user values line up with our expectations
+ UUID uuid = new UUID(0, 80);
+ String playerName = "the_kitty_man";
+
+ File file = prepareDatabaseTestResource(DB_HEALTHY); //Existing DB
+
+ int newUserTestStartingLvl = 1337;
+ db = new FlatFileDatabaseManager(file, logger, PURGE_TIME, newUserTestStartingLvl, true);
+ db.checkFileHealthAndStructure();
+
+ PlayerProfile playerProfile = db.newUser(playerName, uuid);
+
+ assertTrue(playerProfile.isLoaded());
+ assertEquals(playerName, playerProfile.getPlayerName());
+ assertEquals(uuid, playerProfile.getUniqueId());
+
+ PlayerProfile retrievedFromDisk = db.loadPlayerProfile(uuid);
+ assertTrue(retrievedFromDisk.isLoaded());
+ assertEquals(playerName, retrievedFromDisk.getPlayerName());
+ assertEquals(uuid, retrievedFromDisk.getUniqueId());
+
+ //Checking a new user for being "zero" initialized
+ checkNewUserValues(playerProfile, newUserTestStartingLvl);
+ checkNewUserValues(retrievedFromDisk, newUserTestStartingLvl);
+
+ //TODO: Should we do any dupe checking? Probably not needed as it would be caught on the next load
+ db.newUser("bidoof", new UUID(3, 3));
+ db.newUser("derp", new UUID(3, 4));
+ db.newUser("pizza", new UUID(3, 4));
+
+ assertEquals(7, getSplitDataFromFile(db.getUsersFile()).size());
+
+ //Now we *fix* the DB and there should be one less
+ db.checkFileHealthAndStructure();
+ assertEquals(6, getSplitDataFromFile(db.getUsersFile()).size());
+ }
+
+ private void checkNewUserValues(@NotNull PlayerProfile playerProfile, int startingLevel) {
+ //Checking a new user for being zero initialized
+ for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
+ if(SkillTools.isChildSkill(primarySkillType))
+ continue;
+
+ assertEquals(startingLevel, playerProfile.getSkillLevel(primarySkillType));
+ assertEquals(0, playerProfile.getSkillXpLevelRaw(primarySkillType), 0);
+ }
+
+ for(SuperAbilityType superAbilityType : SuperAbilityType.values()) {
+ assertEquals(0, playerProfile.getAbilityDATS(superAbilityType));
+ }
+
+ assertTrue(playerProfile.getLastLogin() > 0);
+ assertEquals(playerProfile.getChimaerWingDATS(), 0);
+ assertEquals(playerProfile.getScoreboardTipsShown(), 0);
+ }
+
+ @Test
+ public void testLoadByUUID() {
+ File dbFile = prepareDatabaseTestResource(DB_HEALTHY);
+
+ /*
+ * We have established the files are in good order, so now for the actual testing
+ */
+
+ //This makes sure our private method is working before the tests run afterwards
+ ArrayList dataFromFile = getSplitDataFromFile(dbFile);
+ logger.info("File Path: " + dbFile.getAbsolutePath());
+ assertArrayEquals(HEALTHY_DB_LINE_1.split(":"), dataFromFile.get(0));
+ assertEquals(dataFromFile.get(0)[FlatFileDatabaseManager.UUID_INDEX], HEALTHY_DB_LINE_ONE_UUID_STR);
+
+ db = new FlatFileDatabaseManager(dbFile, logger, PURGE_TIME, 0, true);
+ List