Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into configurable

This commit is contained in:
nossr50
2019-06-26 21:55:41 -07:00
50 changed files with 1771 additions and 1301 deletions

View File

@ -744,7 +744,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevelCap(String skillType) {
return mcMMO.getPlayerLevelingSettings().getLevelCap(getSkillType(skillType));
return mcMMO.getPlayerLevelingSettings().getSkillLevelCap(getSkillType(skillType));
}
/**
@ -757,7 +757,7 @@ public final class ExperienceAPI {
* @throws InvalidSkillException if the given skill is not valid
*/
public static int getLevelCap(PrimarySkillType skillType) {
return mcMMO.getPlayerLevelingSettings().getLevelCap(skillType);
return mcMMO.getPlayerLevelingSettings().getSkillLevelCap(skillType);
}
/**
@ -767,7 +767,7 @@ public final class ExperienceAPI {
* @return true if the skill has a level cap
*/
public static boolean isSkillLevelCapped(PrimarySkillType skillType) {
return mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(skillType);
return mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(skillType);
}
/**
@ -778,7 +778,7 @@ public final class ExperienceAPI {
* @return the overall power level cap
*/
public static int getPowerLevelCap() {
return mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevel().getLevelCap();
return mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevelSettings().getLevelCap();
}
/**

View File

@ -0,0 +1,13 @@
package com.gmail.nossr50.commands.admin;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
public class PlayerDebug implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
return false;
}
}

View File

@ -30,7 +30,7 @@ public class AddlevelsCommand extends ExperienceCommand {
return;
}
EventUtils.handleLevelChangeEvent(player, skill, value, xpRemoved, true, XPGainReason.COMMAND);
EventUtils.tryLevelChangeEvent(player, skill, value, xpRemoved, true, XPGainReason.COMMAND);
}
@Override

View File

@ -36,7 +36,7 @@ public class MmoeditCommand extends ExperienceCommand {
return;
}
EventUtils.handleLevelChangeEventEdit(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
EventUtils.tryLevelEditEvent(player, skill, value, xpRemoved, value > skillLevel, XPGainReason.COMMAND, skillLevel);
}
@Override

View File

@ -131,7 +131,7 @@ public class SkillresetCommand implements TabExecutor {
return;
}
EventUtils.handleLevelChangeEvent(player, skill, levelsRemoved, xpRemoved, false, XPGainReason.COMMAND);
EventUtils.tryLevelChangeEvent(player, skill, levelsRemoved, xpRemoved, false, XPGainReason.COMMAND);
}
protected boolean permissionsCheckSelf(CommandSender sender) {

View File

@ -48,9 +48,9 @@ public class McstatsCommand implements TabExecutor {
CommandUtils.printCombatSkills(player);
CommandUtils.printMiscSkills(player);
int powerLevelCap = mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevel().getLevelCap();
int powerLevelCap = mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevelSettings().getLevelCap();
if (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevel().isLevelCapEnabled()) {
if (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevelSettings().isLevelCapEnabled()) {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
} else {
player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel()));

View File

@ -3,8 +3,10 @@ package com.gmail.nossr50.commands.skills;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.skills.excavation.ExcavationManager;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.TextComponentFactory;
import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.util.skills.RankUtils;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.entity.Player;
@ -43,6 +45,8 @@ public class ExcavationCommand extends SkillCommand {
protected List<String> statsDisplay(Player player, double skillValue, boolean hasEndurance, boolean isLucky) {
List<String> messages = new ArrayList<>();
ExcavationManager excavationManager = UserManager.getPlayer(player).getExcavationManager();
if (canGigaDrill) {
messages.add(getStatMessage(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, gigaDrillBreakerLength)
+ (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", gigaDrillBreakerLengthEndurance) : ""));
@ -50,6 +54,14 @@ public class ExcavationCommand extends SkillCommand {
//messages.add(LocaleLoader.getString("Excavation.Effect.Length", gigaDrillBreakerLength) + (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", gigaDrillBreakerLengthEndurance) : ""));
}
if(canUseSubskill(player, SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
messages.add(getStatMessage(false, false, SubSkillType.EXCAVATION_ARCHAEOLOGY,
percent.format(excavationManager.getArchaelogyExperienceOrbChance() / 100.0D)));
messages.add(getStatMessage(true, false, SubSkillType.EXCAVATION_ARCHAEOLOGY,
String.valueOf(excavationManager.getExperienceOrbsReward())));
}
return messages;
}

View File

@ -71,7 +71,7 @@ public class MiningCommand extends SkillCommand {
canBiggerBombs = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_BIGGER_BOMBS) && Permissions.biggerBombs(player);
canBlast = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_BLAST_MINING) && Permissions.remoteDetonation(player);
canDemoExpert = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_DEMOLITIONS_EXPERTISE) && Permissions.demolitionsExpertise(player);
canDoubleDrop = Permissions.isSubSkillEnabled(player, SubSkillType.MINING_DOUBLE_DROPS);
canDoubleDrop = canUseSubskill(player, SubSkillType.MINING_DOUBLE_DROPS);
canSuperBreaker = RankUtils.hasUnlockedSubskill(player, SubSkillType.MINING_SUPER_BREAKER) && Permissions.superBreaker(player);
}

View File

@ -9,7 +9,7 @@ public class ConfigSectionExploitAcrobatics {
private static final int ACROBATIC_LOCATION_LIMIT_DEFAULT = 50;
private static final boolean PREVENT_ACROBATICS_ABUSE_DEFAULT = true;
private static final int TELEPORT_COOLDOWN_DEFAULT = 30;
private static final int ROLL_XP_GAIN_CD_DEFAULT = 10;
private static final int ROLL_XP_GAIN_CD_DEFAULT = 3;
@Setting(value = "Player-Fall-Location-Tracking",
comment = "The amount of locations to keep track of for player falls." +

View File

@ -3,6 +3,7 @@ package com.gmail.nossr50.config.hocon.experience;
import com.gmail.nossr50.datatypes.experience.CustomXPPerk;
import com.gmail.nossr50.datatypes.experience.SpecialXPKey;
import com.gmail.nossr50.datatypes.skills.ItemMaterialCategory;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ -184,6 +185,10 @@ public class ConfigExperience {
return getConfigExperienceSkills().getExcavationExperienceMap();
}
public boolean isReduceTreeFellerXP() {
return getExperienceWoodcutting().isReduceTreeFellerXP();
}
public HashMap<String, Integer> getFishingXPMap() {
return getConfigExperienceSkills().getFishingXPMap();
}
@ -196,6 +201,12 @@ public class ConfigExperience {
return configExperienceSkills;
}
public double getSkillGlobalMultiplier(PrimarySkillType primarySkillType) {
return configExperienceSkillMultiplier.getSkillGlobalMultiplier(primarySkillType);
}
public double getGlobalXPMultiplier() {
return globalXPMultiplier;
}

View File

@ -45,6 +45,10 @@ public class ConfigExperienceSkills {
@Setting(value = "Z-Combat", comment = "XP Settings for Combat")
private ConfigExperienceCombat experienceCombat = new ConfigExperienceCombat();
public boolean isReduceTreeFellerXP() {
return experienceWoodcutting.isReduceTreeFellerXP();
}
/*
* BOILER PLATE GETTERS
*/

View File

@ -9,6 +9,7 @@ import java.util.HashMap;
public class ConfigExperienceWoodcutting {
private static final HashMap<String, Integer> WOODCUTTING_EXPERIENCE_DEFAULT;
public static final boolean REDUCE_TREE_FELLER_XP_DEFAULT = true;
static {
WOODCUTTING_EXPERIENCE_DEFAULT = new HashMap<>();
@ -46,10 +47,19 @@ public class ConfigExperienceWoodcutting {
WOODCUTTING_EXPERIENCE_DEFAULT.put("minecraft:mushroom_stem", 80);
}
@Setting(value = "Reduce-Tree-Feller-XP", comment = "If set to true players will receive diminishing returns on XP from tree feller." +
"\nIf set to false, players will get the full XP from every block destroyed by tree feller." +
"\nDefault value: "+REDUCE_TREE_FELLER_XP_DEFAULT)
private boolean reduceTreeFellerXP = REDUCE_TREE_FELLER_XP_DEFAULT;
@Setting(value = "Woodcutting-Experience")
private HashMap<String, Integer> woodcuttingExperienceMap = WOODCUTTING_EXPERIENCE_DEFAULT;
public HashMap<String, Integer> getWoodcuttingExperienceMap() {
return woodcuttingExperienceMap;
}
public boolean isReduceTreeFellerXP() {
return reduceTreeFellerXP;
}
}

View File

@ -134,6 +134,18 @@ public class ConfigLeveling {
return configSectionLevelCaps;
}
public ConfigSectionSkillLevelCap getPowerLevelSettings() {
return configSectionLevelCaps.getPowerLevelSettings();
}
public boolean getReducePlayerSkillsAboveCap() {
return configSectionLevelCaps.getReducePlayerSkillsAboveCap();
}
public ConfigSectionSkillLevelCaps getConfigSectionSkillLevelCaps() {
return configSectionLevelCaps.getConfigSectionSkillLevelCaps();
}
public ConfigSectionLevelingGeneral getConfigSectionLevelingGeneral() {
return configSectionLevelingGeneral;
}
@ -194,11 +206,19 @@ public class ConfigLeveling {
return configExperienceFormula.getLinearMultiplier();
}
public boolean isPowerLevelCapEnabled() {
return configSectionLevelCaps.isPowerLevelCapEnabled();
}
public int getPowerLevelCap() {
return configSectionLevelCaps.getPowerLevelCap();
}
/*
* HELPER METHODS
*/
public int getLevelCap(PrimarySkillType primarySkillType) {
public int getSkillLevelCap(PrimarySkillType primarySkillType) {
switch (primarySkillType) {
case ACROBATICS:
return configSectionLevelCaps.getConfigSectionSkillLevelCaps().getAcrobatics().getLevelCap();
@ -236,7 +256,7 @@ public class ConfigLeveling {
}
}
public boolean isLevelCapEnabled(PrimarySkillType primarySkillType) {
public boolean isSkillLevelCapEnabled(PrimarySkillType primarySkillType) {
switch (primarySkillType) {
case ACROBATICS:
return configSectionLevelCaps.getConfigSectionSkillLevelCaps().getAcrobatics().isLevelCapEnabled();

View File

@ -29,10 +29,18 @@ public class ConfigSectionLevelCaps {
* GETTER BOILERPLATE
*/
public ConfigSectionSkillLevelCap getPowerLevel() {
public ConfigSectionSkillLevelCap getPowerLevelSettings() {
return powerLevel;
}
public boolean isPowerLevelCapEnabled() {
return powerLevel.isLevelCapEnabled();
}
public int getPowerLevelCap() {
return powerLevel.getLevelCap();
}
public boolean getReducePlayerSkillsAboveCap() {
return truncateSkillsAboveCap;
}

View File

@ -899,8 +899,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
continue;
}
//Level Cap
if (mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(skill)) {
int cap = mcMMO.getPlayerLevelingSettings().getLevelCap(skill);
if (mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(skill)) {
int cap = mcMMO.getPlayerLevelingSettings().getSkillLevelCap(skill);
if (Integer.valueOf(character[index]) > cap) {
mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME]);
character[index] = cap + "";

View File

@ -891,11 +891,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
//Level Cap Stuff
if (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getReducePlayerSkillsAboveCap()) {
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
if (!mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(skill))
if (!mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(skill))
continue;
//Shrink skills above the cap
int cap = mcMMO.getPlayerLevelingSettings().getLevelCap(skill);
int cap = mcMMO.getPlayerLevelingSettings().getSkillLevelCap(skill);
statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase() + "` = " + cap + " WHERE `" + skill.name().toLowerCase() + "` > " + cap);
statement.executeUpdate();
tryClose(statement);

View File

@ -165,7 +165,15 @@ public class McMMOPlayer {
experienceBarManager.hideExperienceBar(primarySkillType);
}*/
public void processPostXpEvent(XPGainReason xpGainReason, PrimarySkillType primarySkillType, Plugin plugin, XPGainSource xpGainSource) {
public void processPostXpEvent(PrimarySkillType primarySkillType, Plugin plugin, XPGainSource xpGainSource)
{
//Check if they've reached the power level cap just now
if(hasReachedPowerLevelCap()) {
mcMMO.getNotificationManager().sendPlayerInformationChatOnly(player, "LevelCap.PowerLevel", String.valueOf(mcMMO.getConfigManager().getConfigLeveling().getPowerLevelCap()));
} else if(hasReachedLevelCap(primarySkillType)) {
mcMMO.getNotificationManager().sendPlayerInformationChatOnly(player, "LevelCap.Skill", String.valueOf(mcMMO.getConfigManager().getConfigLeveling().getSkillLevelCap(primarySkillType)), primarySkillType.getName());
}
//Updates from Party sources
if (xpGainSource == XPGainSource.PARTY_MEMBERS && !mcMMO.getConfigManager().getConfigLeveling().isPartyExperienceTriggerXpBarDisplay())
return;
@ -474,6 +482,31 @@ public class McMMOPlayer {
return powerLevel;
}
/**
* Whether or not a player is level capped
* If they are at the power level cap, this will return true, otherwise it checks their skill level
* @param primarySkillType
* @return
*/
public boolean hasReachedLevelCap(PrimarySkillType primarySkillType) {
if(hasReachedPowerLevelCap())
return true;
if(getSkillLevel(primarySkillType) >= mcMMO.getConfigManager().getConfigLeveling().getSkillLevelCap(primarySkillType))
return true;
return false;
}
/**
* Whether or not a player is power level capped
* Compares their power level total to the current set limit
* @return true if they have reached the power level cap
*/
public boolean hasReachedPowerLevelCap() {
return this.getPowerLevel() >= mcMMO.getConfigManager().getConfigLeveling().getPowerLevelCap();
}
/**
* Begins an experience gain. The amount will be affected by skill modifiers, global rate, perks, and may be shared with the party
*
@ -564,8 +597,11 @@ public class McMMOPlayer {
* @param primarySkillType The skill to check
*/
private void checkXp(PrimarySkillType primarySkillType, XPGainReason xpGainReason, XPGainSource xpGainSource) {
if(hasReachedLevelCap(primarySkillType))
return;
if (getSkillXpLevelRaw(primarySkillType) < getXpToLevel(primarySkillType)) {
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
processPostXpEvent(primarySkillType, mcMMO.p, xpGainSource);
return;
}
@ -573,7 +609,7 @@ public class McMMOPlayer {
double xpRemoved = 0;
while (getSkillXpLevelRaw(primarySkillType) >= getXpToLevel(primarySkillType)) {
if (mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(primarySkillType)
if (mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(primarySkillType)
&& hasReachedLevelCap(primarySkillType)) {
setSkillXpLevel(primarySkillType, 0);
break;
@ -583,8 +619,7 @@ public class McMMOPlayer {
levelsGained++;
}
if (!EventUtils.handleLevelChangeEvent(player, primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) {
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
if (EventUtils.tryLevelChangeEvent(player, primarySkillType, levelsGained, xpRemoved, true, xpGainReason)) {
return;
}
@ -597,7 +632,7 @@ public class McMMOPlayer {
mcMMO.getNotificationManager().sendPlayerLevelUpNotification(this, primarySkillType, levelsGained, profile.getSkillLevel(primarySkillType));
//UPDATE XP BARS
processPostXpEvent(xpGainReason, primarySkillType, mcMMO.p, xpGainSource);
processPostXpEvent(primarySkillType, mcMMO.p, xpGainSource);
}
/*
@ -770,8 +805,8 @@ public class McMMOPlayer {
*/
private double modifyXpGain(PrimarySkillType primarySkillType, double xp) {
if (((primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType))
&& mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(primarySkillType))
|| (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevel().getLevelCap() <= getPowerLevel())) {
&& mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(primarySkillType))
|| (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevelSettings().getLevelCap() <= getPowerLevel())) {
return 0;
}
@ -921,11 +956,6 @@ public class McMMOPlayer {
return (int) (((deactivatedTimestamp + (PerksUtils.handleCooldownPerks(player, ability.getCooldown()) * Misc.TIME_CONVERSION_FACTOR)) - System.currentTimeMillis()) / Misc.TIME_CONVERSION_FACTOR);
}
private boolean hasReachedLevelCap(PrimarySkillType skill) {
return (skill.getMaxLevel() < getSkillLevel(skill) + 1)
|| (mcMMO.getPlayerLevelingSettings().getConfigSectionLevelCaps().getPowerLevel().getLevelCap() < getPowerLevel() + 1);
}
/*
* These functions are wrapped from PlayerProfile so that we don't always have to store it alongside the McMMOPlayer object.
*/

View File

@ -419,7 +419,7 @@ public class PlayerProfile {
int sum = 0;
for (PrimarySkillType parent : parents) {
if (mcMMO.getPlayerLevelingSettings().isLevelCapEnabled(parent))
if (mcMMO.getPlayerLevelingSettings().isSkillLevelCapEnabled(parent))
sum += Math.min(getSkillLevel(parent), parent.getMaxLevel());
else
sum += getSkillLevel(parent);

View File

@ -179,7 +179,7 @@ public enum PrimarySkillType {
* @return the max level of this skill
*/
public int getMaxLevel() {
return mcMMO.getPlayerLevelingSettings().getLevelCap(this);
return mcMMO.getPlayerLevelingSettings().getSkillLevelCap(this);
}
/*public boolean getDoubleDropsDisabled() {

View File

@ -41,7 +41,7 @@ public enum SubSkillType {
FISHING_SHAKE(1),
/* Herbalism */
HERBALISM_DOUBLE_DROPS,
HERBALISM_DOUBLE_DROPS(1),
HERBALISM_FARMERS_DIET(5),
HERBALISM_GREEN_TERRA(1),
HERBALISM_GREEN_THUMB(4),
@ -52,7 +52,7 @@ public enum SubSkillType {
MINING_BIGGER_BOMBS(1),
MINING_BLAST_MINING(8),
MINING_DEMOLITIONS_EXPERTISE(1),
MINING_DOUBLE_DROPS,
MINING_DOUBLE_DROPS(1),
MINING_SUPER_BREAKER(1),
/* Repair */

View File

@ -169,10 +169,15 @@ public class BlockListener implements Listener {
/* WORLD BLACKLIST CHECK */
if (WorldBlacklist.isWorldBlacklisted(event.getBlock().getWorld()))
return;
Block newBlock = event.getNewState().getBlock();
Material material = newBlock.getType();
if (mcMMO.getConfigManager().getConfigExploitPrevention().getConfigSectionExploitSkills().isPreventCobblestoneStoneGeneratorXP()) {
if (event.getNewState().getType() != Material.OBSIDIAN && BlockUtils.shouldBeWatched(event.getNewState())) {
mcMMO.getPlaceStore().setTrue(event.getNewState());
if (material != Material.OBSIDIAN
&& BlockUtils.shouldBeWatched(material)
&& mcMMO.getDynamicSettingsManager().getExperienceManager().hasMiningXp(material)) { //Hacky fix to prevent trees growing from being marked as unnatural
mcMMO.getPlaceStore().setTrue(newBlock);
}
}
}
@ -275,7 +280,7 @@ public class BlockListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getPlayer()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getPlayer()))
return;
}
@ -284,7 +289,6 @@ public class BlockListener implements Listener {
}
BlockState blockState = event.getBlock().getState();
Location location = blockState.getLocation();
if (!BlockUtils.shouldBeWatched(blockState)) {
return;
@ -370,7 +374,7 @@ public class BlockListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getPlayer()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getPlayer()))
return;
}
@ -439,7 +443,7 @@ public class BlockListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getPlayer()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getPlayer()))
return;
}
@ -509,7 +513,7 @@ public class BlockListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getPlayer()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getPlayer()))
return;
}
@ -582,12 +586,12 @@ public class BlockListener implements Listener {
}
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (WorldGuardManager.getInstance().hasMainFlag(player))
if (plugin.getWorldGuardManager().hasMainFlag(player))
player.sendMessage("[mcMMO DEBUG] World Guard main flag is permitted for this player in this region");
else
player.sendMessage("[mcMMO DEBUG] World Guard main flag is DENIED for this player in this region");
if (WorldGuardManager.getInstance().hasXPFlag(player))
if (plugin.getWorldGuardManager().hasXPFlag(player))
player.sendMessage("[mcMMO DEBUG] World Guard xp flag is permitted for this player in this region");
else
player.sendMessage("[mcMMO DEBUG] World Guard xp flag is not permitted for this player in this region");

View File

@ -88,7 +88,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
}
@ -121,20 +121,17 @@ public class EntityListener implements Listener {
if(event.getEntity().getShooter() instanceof Player)
{
Player player = (Player) event.getEntity().getShooter();
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
Projectile projectile = event.getEntity();//Hacky stuff for 1.13/1.14 compat
Projectile projectile = event.getEntity();
String itemKey = player.getInventory().getItemInMainHand().getType().getKey().toString();
if(!itemKey.equalsIgnoreCase("minecraft:bow") && !itemKey.equalsIgnoreCase("minecraft:crossbow"))
if(!(projectile instanceof Arrow))
return;
projectile.setMetadata(MetadataConstants.BOW_FORCE_METAKEY, new FixedMetadataValue(plugin, 1.0));
@ -293,7 +290,7 @@ public class EntityListener implements Listener {
{
if(attacker instanceof Player) {
if(!WorldGuardManager.getInstance().hasMainFlag((Player) attacker))
if(!plugin.getWorldGuardManager().hasMainFlag((Player) attacker))
return;
} else if(attacker instanceof Projectile) {
@ -301,7 +298,7 @@ public class EntityListener implements Listener {
Projectile projectile = (Projectile) attacker;
if(projectile.getShooter() instanceof Player) {
if(!WorldGuardManager.getInstance().hasMainFlag((Player) projectile.getShooter()))
if(!plugin.getWorldGuardManager().hasMainFlag((Player) projectile.getShooter()))
return;
}
@ -398,6 +395,19 @@ public class EntityListener implements Listener {
}
}
/*
* This was put here to solve a plugin conflict with a mod called Project Korra
* Project Korra sends out a damage event with exactly 0 damage
* mcMMO does some calculations for the damage in an event and it ends up dividing by zero,
* as a result of the modifiers for the event being 0 and the damage set for this event being 0.
*
* Surprising this kind of thing
*
*/
if(damage <= 0) {
return;
}
CombatUtils.processCombatAttack(event, attacker, target);
CombatUtils.handleHealthbars(attacker, target, event.getFinalDamage(), plugin);
@ -452,7 +462,7 @@ public class EntityListener implements Listener {
Player player = (Player) event.getEntity();
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
}
@ -530,7 +540,7 @@ public class EntityListener implements Listener {
Player player = (Player) owner;
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
}
@ -724,7 +734,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -762,7 +772,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -825,7 +835,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -926,7 +936,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -972,7 +982,7 @@ public class EntityListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}

View File

@ -102,7 +102,7 @@ public class InventoryListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -135,7 +135,7 @@ public class InventoryListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -167,7 +167,7 @@ public class InventoryListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -234,7 +234,7 @@ public class InventoryListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -352,7 +352,7 @@ public class InventoryListener implements Listener {
//
// /* WORLD GUARD MAIN FLAG CHECK */
// if (WorldGuardUtils.isWorldGuardLoaded()) {
// if (!WorldGuardManager.getInstance().hasMainFlag(player))
// if (!plugin.getWorldGuardManager().hasMainFlag(player))
// return;
// }
//
@ -456,7 +456,7 @@ public class InventoryListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}

View File

@ -76,7 +76,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -115,7 +115,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getEntity()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getEntity()))
return;
}
@ -160,7 +160,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(killedPlayer))
if (!plugin.getWorldGuardManager().hasMainFlag(killedPlayer))
return;
}
@ -224,7 +224,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(event.getPlayer()))
if (!plugin.getWorldGuardManager().hasMainFlag(event.getPlayer()))
return;
}
@ -256,7 +256,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -331,7 +331,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -424,7 +424,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -576,7 +576,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}
@ -689,7 +689,7 @@ public class PlayerListener implements Listener {
/* WORLD GUARD MAIN FLAG CHECK */
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasMainFlag(player))
if (!plugin.getWorldGuardManager().hasMainFlag(player))
return;
}

View File

@ -73,7 +73,7 @@ public class SelfListener implements Listener {
event.getXpGainReason() == XPGainReason.SHARED_PVE ||
event.getXpGainReason() == XPGainReason.SHARED_PVP) {
if (WorldGuardUtils.isWorldGuardLoaded()) {
if (!WorldGuardManager.getInstance().hasXPFlag(player)) {
if (!plugin.getWorldGuardManager().hasXPFlag(player)) {
event.setRawXpGained(0);
event.setCancelled(true);
}

View File

@ -39,6 +39,7 @@ import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.gmail.nossr50.worldguard.WorldGuardUtils;
import net.shatteredlands.shatt.backup.ZipLibrary;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
@ -67,6 +68,7 @@ public class mcMMO extends JavaPlugin {
private static NotificationManager notificationManager;
private static CommandRegistrationManager commandRegistrationManager;
private static NBTManager nbtManager;
private static WorldGuardManager worldGuardManager;
/* File Paths */
private static String mainDirectory;
@ -196,9 +198,13 @@ public class mcMMO extends JavaPlugin {
}
@Override
public void onLoad() {
if (getServer().getPluginManager().getPlugin("WorldGuard") != null)
WorldGuardManager.getInstance().registerFlags();
public void onLoad()
{
worldGuardManager = new WorldGuardManager();
if(getServer().getPluginManager().getPlugin("WorldGuard") != null) {
worldGuardManager.registerFlags();
}
}
/**
@ -610,4 +616,8 @@ public class mcMMO extends JavaPlugin {
public static NotificationManager getNotificationManager() {
return notificationManager;
}
public WorldGuardManager getWorldGuardManager() {
return worldGuardManager;
}
}

View File

@ -53,6 +53,10 @@ public class ArcheryManager extends SkillManager {
* @param damager The {@link Entity} who shot the arrow
*/
public double distanceXpBonusMultiplier(LivingEntity target, Entity damager) {
//Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
if(!damager.hasMetadata(MetadataConstants.ARROW_DISTANCE_METAKEY))
return damager.getLocation().distance(target.getLocation());
Location firedLocation = (Location) damager.getMetadata(MetadataConstants.ARROW_DISTANCE_METAKEY).get(0).value();
Location targetLocation = target.getLocation();

View File

@ -10,9 +10,12 @@ import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.skills.RankUtils;
import com.gmail.nossr50.util.skills.SkillUtils;
import org.bukkit.Location;
import org.bukkit.block.BlockState;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import java.util.List;
@ -40,6 +43,13 @@ public class ExcavationManager extends SkillManager {
for (ExcavationTreasure treasure : treasures) {
if (skillLevel >= treasure.getDropLevel()
&& RandomChanceUtil.checkRandomChanceExecutionSuccess(getPlayer(), PrimarySkillType.EXCAVATION, treasure.getDropChance())) {
//Spawn Vanilla XP orbs if a dice roll succeeds
if(RandomChanceUtil.rollDice(getArchaelogyExperienceOrbChance(), 100)) {
ExperienceOrb experienceOrb = (ExperienceOrb) getPlayer().getWorld().spawnEntity(location, EntityType.EXPERIENCE_ORB);
experienceOrb.setExperience(getExperienceOrbsReward());
}
xp += treasure.getXp();
Misc.dropItem(location, treasure.getDrop());
}
@ -50,7 +60,20 @@ public class ExcavationManager extends SkillManager {
applyXpGain(xp, XPGainReason.PVE);
}
public void printExcavationDebug(Player player, BlockState blockState) {
public int getExperienceOrbsReward() {
return 1 * getArchaeologyRank();
}
public double getArchaelogyExperienceOrbChance() {
return getArchaeologyRank() * 2;
}
public int getArchaeologyRank() {
return RankUtils.getRank(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY);
}
public void printExcavationDebug(Player player, BlockState blockState)
{
if (Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.EXCAVATION_ARCHAEOLOGY)) {
List<ExcavationTreasure> treasures = Excavation.getTreasures(blockState);

View File

@ -72,6 +72,10 @@ public class MiningManager extends SkillManager {
return getSkillLevel() >= BlastMining.getBiggerBombsUnlockLevel() && Permissions.biggerBombs(getPlayer());
}
public boolean canDoubleDrop() {
return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS) && Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.MINING_DOUBLE_DROPS);
}
/**
* Process double drops & XP gain for Mining.
*
@ -82,16 +86,11 @@ public class MiningManager extends SkillManager {
applyXpGain(Mining.getBlockXp(blockState), XPGainReason.PVE);
if (!Permissions.isSubSkillEnabled(player, SubSkillType.MINING_DOUBLE_DROPS)) {
return;
}
if (mcMMOPlayer.getAbilityMode(skill.getSuperAbility())) {
SkillUtils.handleDurabilityChange(getPlayer().getInventory().getItemInMainHand(), mcMMO.getConfigManager().getConfigSuperAbilities().getSuperAbilityLimits().getToolDurabilityDamage());
}
//if ((mcMMO.getModManager().isCustomMiningBlock(blockState) && !mcMMO.getModManager().getBlock(blockState).isDoubleDropEnabled()) || !MainConfig.getInstance().getDoubleDropsEnabled(skill, material)) {
if (!mcMMO.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(blockState.getType()))
if (!canDoubleDrop() || !mcMMO.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(blockState.getType()))
return;
boolean silkTouch = player.getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH);

View File

@ -136,17 +136,28 @@ public class SalvageManager extends SkillManager {
return;
}
Location anvilLoc = location.clone();
Location playerLoc = player.getLocation().clone();
double distance = anvilLoc.distance(playerLoc);
double speedLimit = .6;
double minSpeed = .3;
//Clamp the speed and vary it by distance
double vectorSpeed = Math.min(speedLimit, Math.max(minSpeed, distance * .2));
//Add a very small amount of height
anvilLoc.add(0, .1, 0);
if (enchantBook != null) {
Misc.dropItem(location, enchantBook);
Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), enchantBook, vectorSpeed);
}
Misc.spawnItemTowardsLocation(location, player.getLocation().add(0, 0.25, 0), salvageResults);
Misc.spawnItemTowardsLocation(anvilLoc.clone(), playerLoc.clone(), salvageResults, vectorSpeed);
// BWONG BWONG BWONG - CLUNK!
if (mcMMO.getConfigManager().getConfigSalvage().getGeneral().isAnvilUseSounds()) {
SoundManager.sendSound(player, player.getLocation(), SoundType.ITEM_BREAK);
//player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1.0F, 1.0F);
}
mcMMO.getNotificationManager().sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Salvage.Skills.Success");

View File

@ -7,7 +7,6 @@ import com.gmail.nossr50.util.skills.SkillUtils;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
@ -29,23 +28,44 @@ public final class Woodcutting {
protected static boolean treeFellerReachedThreshold = false;
private Woodcutting() {
}
/**
* Retrieves the experience reward from a log
*
* @param blockState Log being broken
* @param experienceGainMethod How the log is being broken
* @param blockState Log being broken
* @return Amount of experience
*/
protected static int getExperienceFromLog(BlockState blockState, ExperienceGainMethod experienceGainMethod) {
/*if (mcMMO.getModManager().isCustomLog(blockState)) {
return mcMMO.getModManager().getBlock(blockState).getXpGain();
}*/
protected static int getExperienceFromLog(BlockState blockState) {
return mcMMO.getDynamicSettingsManager().getExperienceManager().getWoodcuttingXp(blockState.getType());
}
/**
* Retrieves the experience reward from logging via Tree Feller
* Experience is reduced per log processed so far
* Experience is only reduced if the config option to reduce Tree Feller XP is set
* Experience per log will not fall below 1 unless the experience for that log is set to 0 in the config
*
* @param blockState Log being broken
* @param woodCount how many logs have given out XP for this tree feller so far
* @return Amount of experience
*/
protected static int processTreeFellerXPGains(BlockState blockState, int woodCount) {
int rawXP = mcMMO.getDynamicSettingsManager().getExperienceManager().getWoodcuttingXp(blockState.getType());
if(rawXP <= 0)
return 0;
if(mcMMO.getConfigManager().getConfigExperience().getExperienceWoodcutting().isReduceTreeFellerXP()) {
int reducedXP = 1 + (woodCount * 5);
rawXP = Math.max(1, rawXP - reducedXP);
return rawXP;
} else {
return mcMMO.getDynamicSettingsManager().getExperienceManager().getWoodcuttingXp(blockState.getType());
}
}
/**
* Checks for double drops
*
@ -136,9 +156,8 @@ public final class Woodcutting {
* @return True if the tool can sustain the durability loss
*/
protected static boolean handleDurabilityLoss(Set<BlockState> treeFellerBlocks, ItemStack inHand) {
if((inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) != null && inHand.getItemMeta().getEnchants().get(Enchantment.DURABILITY) >= 1)
|| (inHand.getItemMeta() != null && inHand.getItemMeta().isUnbreakable())) {
//Treat the NBT tag for unbreakable and the durability enchant differently
if(inHand.getItemMeta() != null && inHand.getItemMeta().isUnbreakable()) {
return true;
}

View File

@ -8,7 +8,6 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.skills.SkillManager;
import com.gmail.nossr50.skills.woodcutting.Woodcutting.ExperienceGainMethod;
import com.gmail.nossr50.util.*;
import com.gmail.nossr50.util.random.RandomChanceUtil;
import com.gmail.nossr50.util.skills.CombatUtils;
@ -52,7 +51,7 @@ public class WoodcuttingManager extends SkillManager {
* @param blockState Block being broken
*/
public void woodcuttingBlockCheck(BlockState blockState) {
int xp = Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.DEFAULT);
int xp = Woodcutting.getExperienceFromLog(blockState);
switch (blockState.getType()) {
case BROWN_MUSHROOM_BLOCK:
@ -114,6 +113,7 @@ public class WoodcuttingManager extends SkillManager {
private void dropBlocks(Set<BlockState> treeFellerBlocks) {
Player player = getPlayer();
int xp = 0;
int processedLogCount = 0;
for (BlockState blockState : treeFellerBlocks) {
Block block = blockState.getBlock();
@ -124,30 +124,16 @@ public class WoodcuttingManager extends SkillManager {
Material material = blockState.getType();
//TODO: Update this to drop the correct items/blocks via NMS
if (material == Material.BROWN_MUSHROOM_BLOCK || material == Material.RED_MUSHROOM_BLOCK) {
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
xp += Woodcutting.processTreeFellerXPGains(blockState, processedLogCount);
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}
/*else if (mcMMO.getModManager().isCustomLog(blockState)) {
if (canGetDoubleDrops()) {
Woodcutting.checkForDoubleDrop(blockState);
}
CustomBlock customBlock = mcMMO.getModManager().getBlock(blockState);
xp = customBlock.getXpGain();
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}
else if (mcMMO.getModManager().isCustomLeaf(blockState)) {
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}*/
else {
} else {
if (BlockUtils.isLog(blockState)) {
if (canGetDoubleDrops()) {
Woodcutting.checkForDoubleDrop(blockState);
}
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
xp += Woodcutting.processTreeFellerXPGains(blockState, processedLogCount);
Misc.dropItems(Misc.getBlockCenter(blockState), block.getDrops());
}
if (BlockUtils.isLeaves(blockState)) {
@ -157,6 +143,7 @@ public class WoodcuttingManager extends SkillManager {
blockState.setType(Material.AIR);
blockState.update(true);
processedLogCount+=1;
}
applyXpGain(xp, XPGainReason.PVE);

View File

@ -207,7 +207,7 @@ public class EventUtils {
}
public static boolean handleLevelChangeEvent(Player player, PrimarySkillType skill, int levelsChanged, double xpRemoved, boolean isLevelUp, XPGainReason xpGainReason) {
public static boolean tryLevelChangeEvent(Player player, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
@ -220,10 +220,10 @@ public class EventUtils {
profile.addXp(skill, xpRemoved);
}
return !isCancelled;
return isCancelled;
}
public static void handleLevelChangeEventEdit(Player player, PrimarySkillType skill, int levelsChanged, double xpRemoved, boolean isLevelUp, XPGainReason xpGainReason, int oldLevel) {
public static boolean tryLevelEditEvent(Player player, PrimarySkillType skill, int levelsChanged, float xpRemoved, boolean isLevelUp, XPGainReason xpGainReason, int oldLevel) {
McMMOPlayerLevelChangeEvent event = isLevelUp ? new McMMOPlayerLevelUpEvent(player, skill, levelsChanged - oldLevel, xpGainReason) : new McMMOPlayerLevelDownEvent(player, skill, levelsChanged, xpGainReason);
mcMMO.p.getServer().getPluginManager().callEvent(event);
@ -236,6 +236,7 @@ public class EventUtils {
profile.addXp(skill, xpRemoved);
}
return isCancelled;
}
/**

View File

@ -119,40 +119,58 @@ public final class Misc {
/**
* Drop items at a given location.
*
* @param location The location to drop the items at
* @param fromLocation The location to drop the items at
* @param is The items to drop
* @param speed the speed that the item should travel
* @param quantity The amount of items to drop
*/
public static void spawnItemsTowardsLocation(Location location, Location targetLocation, ItemStack is, int quantity) {
public static void spawnItemsTowardsLocation(Location fromLocation, Location toLocation, ItemStack is, int quantity, double speed) {
for (int i = 0; i < quantity; i++) {
spawnItemTowardsLocation(location, targetLocation, is);
spawnItemTowardsLocation(fromLocation, toLocation, is, speed);
}
}
/**
* Drop an item at a given location.
* This method is fairly expensive as it creates clones of everything passed to itself since they are mutable objects
*
* @param spawnLocation The location to drop the item at
* @param itemStack The item to drop
* @param fromLocation The location to drop the item at
* @param toLocation The location the item will travel towards
* @param itemToSpawn The item to spawn
* @param speed the speed that the item should travel
* @return Dropped Item entity or null if invalid or cancelled
*/
public static Item spawnItemTowardsLocation(Location spawnLocation, Location targetLocation, ItemStack itemStack) {
if (itemStack.getType() == Material.AIR) {
public static Item spawnItemTowardsLocation(Location fromLocation, Location toLocation, ItemStack itemToSpawn, double speed) {
if (itemToSpawn.getType() == Material.AIR) {
return null;
}
//Work with fresh copies of everything
ItemStack clonedItem = itemToSpawn.clone();
Location spawnLocation = fromLocation.clone();
Location targetLocation = toLocation.clone();
// We can't get the item until we spawn it and we want to make it cancellable, so we have a custom event.
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(spawnLocation, itemStack);
McMMOItemSpawnEvent event = new McMMOItemSpawnEvent(spawnLocation, clonedItem);
mcMMO.p.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
//Something cancelled the event so back out
if (event.isCancelled() || event.getItemStack() == null) {
return null;
}
Item item = spawnLocation.getWorld().dropItem(spawnLocation, itemStack);
Vector vector = targetLocation.toVector().subtract(spawnLocation.toVector()).normalize();
item.setVelocity(vector);
return item;
//Use the item from the event
Item spawnedItem = spawnLocation.getWorld().dropItem(spawnLocation, clonedItem);
Vector vecFrom = spawnLocation.clone().toVector().clone();
Vector vecTo = targetLocation.clone().toVector().clone();
//Vector which is pointing towards out target location
Vector direction = vecTo.subtract(vecFrom).normalize();
//Modify the speed of the vector
direction = direction.multiply(speed);
spawnedItem.setVelocity(direction);
return spawnedItem;
}
public static void profileCleanup(String playerName) {

View File

@ -64,7 +64,7 @@ public class FormulaManager {
public int[] calculateNewLevel(PrimarySkillType primarySkillType, int experience) {
int newLevel = 0;
int remainder = 0;
int maxLevel = mcMMO.getConfigManager().getConfigLeveling().getLevelCap(primarySkillType);
int maxLevel = mcMMO.getConfigManager().getConfigLeveling().getSkillLevelCap(primarySkillType);
while (experience > 0 && newLevel < maxLevel) {
int experienceToNextLevel = getXPtoNextLevel(newLevel, currentFormula);

View File

@ -8,17 +8,13 @@ import com.gmail.nossr50.util.Permissions;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
public class PlayerLevelUtils {
private HashMap<PrimarySkillType, Integer> earlyGameBoostCutoffs;
private HashSet<CustomXPPerk> customXpPerkNodes;
public PlayerLevelUtils() {
registerCustomPerkPermissions();
earlyGameBoostCutoffs = new HashMap<>();
calculateEarlyGameBoostCutoffs();
applyConfigPerks();
}
@ -38,29 +34,14 @@ public class PlayerLevelUtils {
}
/**
* Get the the final level at which players will still receive an early game XP boost
* Note: This doesn't mean early game boosts are enabled on the server, as that is a config toggle
*
* Check if a player is currently qualifying for the early game boosted XP
* Will return false only if a player is above the boost level cutoff, it does not check config settings to see if the early game boost is on
* @param mcMMOPlayer target player
* @param primarySkillType target skill
* @return this skills maximum early game boost level
* @return if the player would qualify for the XP boost if its enabled
*/
public int getEarlyGameCutoff(PrimarySkillType primarySkillType) {
return earlyGameBoostCutoffs.get(primarySkillType);
}
private void calculateEarlyGameBoostCutoffs() {
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
int levelCap = mcMMO.getConfigManager().getConfigLeveling().getLevelCap(primarySkillType);
int cap;
if (levelCap == Integer.MAX_VALUE || levelCap <= 0) {
cap = mcMMO.isRetroModeEnabled() ? 50 : 5;
} else {
cap = (int) (levelCap * mcMMO.getConfigManager().getConfigLeveling().getEarlyGameBoostMultiplier());
}
earlyGameBoostCutoffs.put(primarySkillType, cap);
}
public static boolean qualifiesForEarlyGameBoost(McMMOPlayer mcMMOPlayer, PrimarySkillType primarySkillType) {
return mcMMOPlayer.getSkillLevel(primarySkillType) < 1;
}
/**
@ -131,15 +112,4 @@ public class PlayerLevelUtils {
return 1.0;
}
/**
* Check if a player is currently qualifying for the early game boosted XP
* Will return false only if a player is above the boost level cutoff, it does not check config settings to see if the early game boost is on
* @param mcMMOPlayer target player
* @param primarySkillType target skill
* @return if the player would qualify for the XP boost if its enabled
*/
public static boolean qualifiesForEarlyGameBoost(McMMOPlayer mcMMOPlayer, PrimarySkillType primarySkillType) {
return mcMMOPlayer.getSkillLevel(primarySkillType) < mcMMO.getPlayerLevelUtils().getEarlyGameCutoff(primarySkillType);
}
}

View File

@ -225,9 +225,13 @@ public final class CombatUtils {
}
double distanceMultiplier = archeryManager.distanceXpBonusMultiplier(target, arrow);
double forceMultiplier = 1.0; //Hacky Fix - some plugins spawn arrows and assign them to players after the ProjectileLaunchEvent fires
if(arrow.hasMetadata(MetadataConstants.BOW_FORCE_METAKEY))
forceMultiplier = arrow.getMetadata(MetadataConstants.BOW_FORCE_METAKEY).get(0).asDouble();
applyScaledModifiers(initialDamage, finalDamage, event);
startGainXp(mcMMOPlayer, target, PrimarySkillType.ARCHERY, arrow.getMetadata(MetadataConstants.BOW_FORCE_METAKEY).get(0).asDouble() * distanceMultiplier);
startGainXp(mcMMOPlayer, target, PrimarySkillType.ARCHERY, forceMultiplier * distanceMultiplier);
}
/**

View File

@ -399,7 +399,7 @@ public class RankUtils {
}
//Default to the max level for the skill if any errors were encountered incorrect
return mcMMO.getConfigManager().getConfigLeveling().getLevelCap(subSkillType.getParentSkill());
return mcMMO.getConfigManager().getConfigLeveling().getSkillLevelCap(subSkillType.getParentSkill());
}
public static boolean isPlayerMaxRankInSubSkill(Player player, SubSkillType subSkillType) {

View File

@ -253,8 +253,7 @@ public class SkillUtils {
* @param maxDamageModifier the amount to adjust the max damage by
*/
public static void handleDurabilityChange(ItemStack itemStack, double durabilityModifier, double maxDamageModifier) {
if((itemStack.getItemMeta().getEnchants().get(Enchantment.DURABILITY) != null && itemStack.getItemMeta().getEnchants().get(Enchantment.DURABILITY) >= 1)
|| (itemStack.getItemMeta() != null && itemStack.getItemMeta().isUnbreakable())) {
if(itemStack.getItemMeta() != null && itemStack.getItemMeta().isUnbreakable()) {
return;
}

View File

@ -6,7 +6,6 @@ import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.registry.FlagConflictException;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
@ -14,31 +13,18 @@ import org.bukkit.plugin.Plugin;
import static org.bukkit.Bukkit.getServer;
public class WorldGuardManager {
private static WorldGuardManager instance;
private WorldGuardPlugin worldGuardPluginRef;
public WorldGuardManager() {
}
public static WorldGuardManager getInstance() {
if (instance == null)
instance = new WorldGuardManager();
return instance;
}
public boolean hasMainFlag(Player player) {
if (player == null)
public boolean hasMainFlag(Player player)
{
if(player == null)
return false;
BukkitPlayer localPlayer = BukkitAdapter.adapt(player);
com.sk89q.worldedit.util.Location loc = localPlayer.getLocation();
//WorldGuardPlugin worldGuard = getWorldGuard();
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
//ApplicableRegionSet set = query.getApplicableRegions(loc);
@ -53,8 +39,7 @@ public class WorldGuardManager {
com.sk89q.worldedit.util.Location loc = localPlayer.getLocation();
//WorldGuardPlugin worldGuard = getWorldGuard();
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
//ApplicableRegionSet set = query.getApplicableRegions(loc);
@ -70,8 +55,7 @@ public class WorldGuardManager {
com.sk89q.worldedit.util.Location loc = localPlayer.getLocation();
//WorldGuardPlugin worldGuard = getWorldGuard();
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
RegionQuery query = WorldGuard.getInstance().getPlatform().getRegionContainer().createQuery();
//ApplicableRegionSet set = query.getApplicableRegions(loc);
@ -90,15 +74,12 @@ public class WorldGuardManager {
return worldGuardPluginRef;
}
public void registerFlags() {
if (getWorldGuard() == null)
return;
public void registerFlags()
{
FlagRegistry registry = WorldGuard.getInstance().getFlagRegistry();
try {
// register our flag with the registry
/*registry.register(WorldGuardFlags.MCMMO_ENABLE_WG_FLAG);
registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG);*/
registry.register(WorldGuardFlags.MCMMO_ENABLE_WG_FLAG);
registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG);
registry.register(WorldGuardFlags.MCMMO_HARDCORE_WG_FLAG);
@ -113,5 +94,4 @@ public class WorldGuardManager {
}
}
}

View File

@ -4,53 +4,122 @@ import com.gmail.nossr50.mcMMO;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import static org.bukkit.Bukkit.getServer;
public class WorldGuardUtils {
private static WorldGuardPlugin worldGuardPluginRef;
private static boolean isLoaded = false;
private static boolean hasWarned = false;
private static boolean detectedIncompatibleWG = false;
private static final ArrayList<String> WGClassList;
public static boolean isWorldGuardLoaded() {
WorldGuardPlugin plugin = getWorldGuard();
static {
/*
These are the classes mcMMO tries to hook into for WG support, if any of them are missing it is safe to consider WG is not compatible
com.sk89q.worldedit.bukkit.BukkitAdapter
com.sk89q.worldedit.bukkit.BukkitPlayer
com.sk89q.worldguard.WorldGuard
com.sk89q.worldguard.bukkit.WorldGuardPlugin
com.sk89q.worldguard.protection.flags.registry.FlagConflictException
com.sk89q.worldguard.protection.flags.registry.FlagRegistry
com.sk89q.worldguard.protection.regions.RegionContainer
com.sk89q.worldguard.protection.regions.RegionQuery
*/
try {
// WorldGuard may not be loaded
if (plugin == null) {
return false; // Maybe you want throw an exception instead
}
} catch (Exception e) {
e.printStackTrace();
//Silently Fail
//mcMMO.p.getLogger().severe("Failed to detect worldguard.");
WGClassList = new ArrayList<>();
WGClassList.add("com.sk89q.worldedit.bukkit.BukkitAdapter");
WGClassList.add("com.sk89q.worldedit.bukkit.BukkitPlayer");
WGClassList.add("com.sk89q.worldguard.WorldGuard");
WGClassList.add("com.sk89q.worldguard.bukkit.WorldGuardPlugin");
WGClassList.add("com.sk89q.worldguard.protection.flags.registry.FlagConflictException");
WGClassList.add("com.sk89q.worldguard.protection.flags.registry.FlagRegistry");
WGClassList.add("com.sk89q.worldguard.protection.regions.RegionContainer");
WGClassList.add("com.sk89q.worldguard.protection.regions.RegionQuery");
}
public static boolean isWorldGuardLoaded()
{
if(detectedIncompatibleWG)
return false;
worldGuardPluginRef = getWorldGuard();
return isLoaded;
}
/**
* Gets the instance of the WG plugin if its compatible
* Results are cached
* @return the instance of WG plugin, null if its not compatible or isn't present
*/
private static WorldGuardPlugin getWorldGuard()
{
//WG plugin reference is already cached so just return it
if(isLoaded)
return worldGuardPluginRef;
//Grab WG if it exists
Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard");
if(plugin == null) {
//WG is not present
detectedIncompatibleWG = true;
mcMMO.p.getLogger().info("WorldGuard was not detected.");
} else {
//Check that its actually of class WorldGuardPlugin
if(plugin instanceof WorldGuardPlugin)
{
if(isCompatibleVersion(plugin))
{
worldGuardPluginRef = (WorldGuardPlugin) plugin;
isLoaded = true;
}
} else {
//Plugin is not of the expected type
markWGIncompatible();
}
}
return true;
return worldGuardPluginRef;
}
private static WorldGuardPlugin getWorldGuard() {
if (isLoaded)
return worldGuardPluginRef;
Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard");
if (plugin instanceof WorldGuardPlugin) {
if (plugin.getDescription().getVersion().startsWith("7")) {
worldGuardPluginRef = (WorldGuardPlugin) plugin;
if (worldGuardPluginRef != null)
isLoaded = true;
} else {
if (!hasWarned) {
mcMMO.p.getLogger().severe("mcMMO only supports WorldGuard version 7! Make sure you have WG 7! This warning will not appear again.");
hasWarned = true;
/**
* Checks to make sure the version of WG installed is compatible
* Does this by checking for necessary WG classes via Reflection
* This does not guarantee compatibility, but it should help reduce the chance that mcMMO tries to hook into WG and its not compatible
* @return true if the version of WG appears to be compatible
*/
private static boolean isCompatibleVersion(Plugin plugin) {
//Check that the version of WG is at least version 7.xx
if(!plugin.getDescription().getVersion().startsWith("7")) {
markWGIncompatible();
} else {
//Use Reflection to check for a class not present in all versions of WG7
for(String classString : WGClassList) {
try {
Class<?> checkForClass = Class.forName(classString);
detectedIncompatibleWG = false; //In case this was set to true previously
} catch (ClassNotFoundException e) {
mcMMO.p.getLogger().severe("Missing WorldGuard class - "+classString);
markWGIncompatible();
return false;
}
}
}
return worldGuardPluginRef;
return true;
}
/**
* Mark WG as being incompatible to avoid unnecessary operations
*/
private static void markWGIncompatible() {
mcMMO.p.getLogger().severe("You are using a version of WG that is not compatible with mcMMO, " +
"WG features for mcMMO will be disabled. mcMMO requires you to be using a new version of WG7 " +
"in order for it to use WG features. Not all versions of WG7 are compatible.");
mcMMO.p.getLogger().severe("mcMMO will continue to function normally, but if you wish to use WG support you must use a compatible version.");
detectedIncompatibleWG = true;
}
}