mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-25 22:56:45 +01:00
Some work on milestones is done
This commit is contained in:
parent
b9c8743ee3
commit
bec088c969
@ -9,6 +9,12 @@ Key:
|
||||
|
||||
Version 2.1.0
|
||||
+ Added config setting to enable or disable classic mcMMO mode
|
||||
+ (Config) Added rank settings for the new Woodcutting skill
|
||||
+ (Config) Added configurable parameters for the new Tree Feller
|
||||
+ (Config) Added classic toggle for Tree Feller
|
||||
+ (Permissions) Added permission nodes for Harvest Lumber, Splinter, Nature's Bounty, and Bark Surgeon
|
||||
! Woodcutting's Double Drop subskill is now named Harvest Lumber
|
||||
! Replaced the old Double Drop permission node for woodcutting with a new Harvest Lumber permission node
|
||||
! (API) SkillType is now PrimarySkill
|
||||
! (API) SecondarySkill is now SubSkill
|
||||
! (API) AbilityType is now SuperAbility
|
||||
|
@ -4,7 +4,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillMilestone;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.SkillMilestoneFactory;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
@ -20,6 +23,9 @@ public class WoodcuttingCommand extends SkillCommand {
|
||||
private boolean canTreeFell;
|
||||
private boolean canLeafBlow;
|
||||
private boolean canDoubleDrop;
|
||||
private boolean canSplinter;
|
||||
private boolean canBarkSurgeon;
|
||||
private boolean canNaturesBounty;
|
||||
|
||||
public WoodcuttingCommand() {
|
||||
super(PrimarySkill.WOODCUTTING);
|
||||
@ -36,17 +42,29 @@ public class WoodcuttingCommand extends SkillCommand {
|
||||
|
||||
// DOUBLE DROPS
|
||||
if (canDoubleDrop) {
|
||||
String[] doubleDropStrings = calculateAbilityDisplayValues(skillValue, SubSkill.WOODCUTTING_DOUBLE_DROPS, isLucky);
|
||||
doubleDropChance = doubleDropStrings[0];
|
||||
doubleDropChanceLucky = doubleDropStrings[1];
|
||||
if(AdvancedConfig.getInstance().isSubSkillClassic(SubSkill.WOODCUTTING_HARVEST_LUMBER))
|
||||
setDoubleDropClassicChanceStrings(skillValue, isLucky);
|
||||
else
|
||||
{
|
||||
//TODO: Set up datastrings for new harvest
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setDoubleDropClassicChanceStrings(float skillValue, boolean isLucky) {
|
||||
String[] doubleDropStrings = calculateAbilityDisplayValues(skillValue, SubSkill.WOODCUTTING_HARVEST_LUMBER, isLucky);
|
||||
doubleDropChance = doubleDropStrings[0];
|
||||
doubleDropChanceLucky = doubleDropStrings[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void permissionsCheck(Player player) {
|
||||
canTreeFell = Permissions.treeFeller(player);
|
||||
canDoubleDrop = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_DOUBLE_DROPS) && !skill.getDoubleDropsDisabled();
|
||||
canDoubleDrop = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_HARVEST_LUMBER) && !skill.getDoubleDropsDisabled();
|
||||
canLeafBlow = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_LEAF_BLOWER);
|
||||
canSplinter = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_SPLINTER);
|
||||
canBarkSurgeon = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_BARK_SURGEON);
|
||||
canNaturesBounty = Permissions.isSubSkillEnabled(player, SubSkill.WOODCUTTING_NATURES_BOUNTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -65,6 +83,20 @@ public class WoodcuttingCommand extends SkillCommand {
|
||||
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.4"), LocaleLoader.getString("Woodcutting.Effect.5")));
|
||||
}
|
||||
|
||||
if (canSplinter) {
|
||||
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.6"), LocaleLoader.getString("Woodcutting.Effect.7")));
|
||||
}
|
||||
|
||||
if(canBarkSurgeon) {
|
||||
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.8"), LocaleLoader.getString("Woodcutting.Effect.9")));
|
||||
}
|
||||
|
||||
if(canNaturesBounty) {
|
||||
messages.add(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.10"), LocaleLoader.getString("Woodcutting.Effect.11")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
return messages;
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
|
||||
import com.gmail.nossr50.skills.alchemy.Alchemy;
|
||||
import com.gmail.nossr50.skills.fishing.Fishing;
|
||||
@ -33,6 +34,11 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
// Validate all the settings!
|
||||
List<String> reason = new ArrayList<String>();
|
||||
|
||||
/*
|
||||
* In the future this method will check keys for all skills, but for now it only checks overhauled skills
|
||||
*/
|
||||
checkKeys(reason);
|
||||
|
||||
/* GENERAL */
|
||||
if (getAbilityLength() < 1) {
|
||||
reason.add("Skills.General.Ability.IncreaseLevel should be at least 1!");
|
||||
@ -648,16 +654,17 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
}
|
||||
|
||||
/* WOODCUTTING */
|
||||
|
||||
if (getLeafBlowUnlockLevel() < 0) {
|
||||
reason.add("Skills.Woodcutting.LeafBlower.UnlockLevel should be at least 0!");
|
||||
}
|
||||
|
||||
if (getMaxChance(SubSkill.WOODCUTTING_DOUBLE_DROPS) < 1) {
|
||||
reason.add("Skills.Woodcutting.DoubleDrops.ChanceMax should be at least 1!");
|
||||
if (getMaxChance(SubSkill.WOODCUTTING_HARVEST_LUMBER) < 1) {
|
||||
reason.add("Skills.Woodcutting.HarvestLumber.ChanceMax should be at least 1!");
|
||||
}
|
||||
|
||||
if (getMaxBonusLevel(SubSkill.WOODCUTTING_DOUBLE_DROPS) < 1) {
|
||||
reason.add("Skills.Woodcutting.DoubleDrops.MaxBonusLevel should be at least 1!");
|
||||
if (getMaxBonusLevel(SubSkill.WOODCUTTING_HARVEST_LUMBER) < 1) {
|
||||
reason.add("Skills.Woodcutting.HarvestLumber.MaxBonusLevel should be at least 1!");
|
||||
}
|
||||
|
||||
/* KRAKEN */
|
||||
@ -690,6 +697,30 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public int getMaxBonusLevel(SubSkill subSkill) { return config.getInt(subSkill.getAdvConfigAddress() + ".MaxBonusLevel"); }
|
||||
public double getMaxChance(SubSkill subSkill) { return config.getDouble(subSkill.getAdvConfigAddress() + ".ChanceMax", 100.0D);}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the level required to unlock a subskill at a given rank
|
||||
* @param subSkill The subskill
|
||||
* @param rank The rank of the skill
|
||||
* @return The level required to use this rank of the subskill
|
||||
* @deprecated Right now mcMMO is an overhaul process, this will only work for skills I have overhauled. I will be removing the deprecated tag when that is true.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getSubSkillUnlockLevel(SubSkill subSkill, int rank)
|
||||
{
|
||||
return config.getInt(subSkill.getAdvConfigAddress() + ".Rank_Levels.Rank_"+rank+".LevelReq");
|
||||
}
|
||||
|
||||
/**
|
||||
* Some SubSkills have the ability to retain classic functionality
|
||||
* @param subSkill SubSkill with classic functionality
|
||||
* @return true if the subskill is in classic mode
|
||||
*/
|
||||
public boolean isSubSkillClassic(SubSkill subSkill)
|
||||
{
|
||||
return config.getBoolean(subSkill.getAdvConfigAddress()+".Classic");
|
||||
}
|
||||
|
||||
/* ACROBATICS */
|
||||
public double getDodgeDamageModifier() { return config.getDouble("Skills.Acrobatics.Dodge.DamageModifier", 2.0D); }
|
||||
|
||||
@ -857,4 +888,39 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public String getPlayerUnleashMessage() { return config.getString("Kraken.Unleashed_Message.Player", ""); }
|
||||
public String getPlayerDefeatMessage() { return config.getString("Kraken.Defeated_Message.Killed", ""); }
|
||||
public String getPlayerEscapeMessage() { return config.getString("Kraken.Defeated_Message.Escape", ""); }
|
||||
|
||||
/**
|
||||
* Checks for valid keys in the advanced.yml file for subskill ranks
|
||||
*/
|
||||
private void checkKeys(List<String> reasons)
|
||||
{
|
||||
//For now we will only check ranks of stuff I've overhauled
|
||||
for(SubSkill subSkill : SubSkill.values())
|
||||
{
|
||||
if(subSkill.getParentSkill() == PrimarySkill.WOODCUTTING)
|
||||
{
|
||||
//Keeping track of the rank requirements and making sure there are no logical errors
|
||||
int curRank = 0;
|
||||
int prevRank = 0;
|
||||
|
||||
for(int x = 0; x < subSkill.getNumRanks(); x++)
|
||||
{
|
||||
if(curRank > 0)
|
||||
prevRank = curRank;
|
||||
|
||||
curRank = getSubSkillUnlockLevel(subSkill, x);
|
||||
|
||||
//Do we really care if its below 0? Probably not
|
||||
if(curRank < 0)
|
||||
reasons.add(subSkill.getAdvConfigAddress() + ".Rank_Levels.Rank_"+curRank+".LevelReq should be above or equal to 0!");
|
||||
|
||||
if(prevRank > curRank)
|
||||
{
|
||||
//We're going to allow this but we're going to warn them
|
||||
plugin.getLogger().info("You have the ranks for the subskill "+subSkill.toString()+" set up poorly, sequential ranks should have ascending requirements");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +244,16 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
*/
|
||||
|
||||
/* General Settings */
|
||||
|
||||
//Classic mode will default the value to true if the config file doesn't contain the entry (server is from a previous mcMMO install)
|
||||
public boolean getClassicMode() { return config.getBoolean("General.Classic_Mode", true); }
|
||||
|
||||
//XP needed to level is multiplied by this when using classic mode
|
||||
public int getClassicModeXPFormulaFactor() { return config.getInt("General.Skill_Scaling.Classic_XP_Formula_Factor", 1); }
|
||||
|
||||
//Level requirements for subskills is multiplied by this when using classic mode
|
||||
public int getClassicModeLevelReqFactor() { return config.getInt("General.Skill_Scaling.Classic_LevelReq_Factor", 10); }
|
||||
|
||||
public String getLocale() { return config.getString("General.Locale", "en_us"); }
|
||||
public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); }
|
||||
public boolean getShowProfileLoadedMessage() { return config.getBoolean("General.Show_Profile_Loaded", true); }
|
||||
|
@ -50,7 +50,7 @@ public enum PrimarySkill {
|
||||
SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbility.SERRATED_STRIKES, ToolType.SWORD, ImmutableList.of(SubSkill.SWORDS_BLEED, SubSkill.SWORDS_COUNTER)),
|
||||
TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SubSkill.TAMING_BEAST_LORE, SubSkill.TAMING_CALL_OF_THE_WILD, SubSkill.TAMING_ENVIRONMENTALLY_AWARE, SubSkill.TAMING_FAST_FOOD, SubSkill.TAMING_GORE, SubSkill.TAMING_HOLY_HOUND, SubSkill.TAMING_SHARPENED_CLAWS, SubSkill.TAMING_SHOCK_PROOF, SubSkill.TAMING_THICK_FUR, SubSkill.TAMING_PUMMEL)),
|
||||
UNARMED(UnarmedManager.class, Color.BLACK, SuperAbility.BERSERK, ToolType.FISTS, ImmutableList.of(SubSkill.UNARMED_BLOCK_CRACKER, SubSkill.UNARMED_DEFLECT, SubSkill.UNARMED_DISARM, SubSkill.UNARMED_IRON_ARM, SubSkill.UNARMED_IRON_GRIP)),
|
||||
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbility.TREE_FELLER, ToolType.AXE, ImmutableList.of(SubSkill.WOODCUTTING_LEAF_BLOWER, SubSkill.WOODCUTTING_DOUBLE_DROPS));
|
||||
WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbility.TREE_FELLER, ToolType.AXE, ImmutableList.of(SubSkill.WOODCUTTING_LEAF_BLOWER, SubSkill.WOODCUTTING_BARK_SURGEON, SubSkill.WOODCUTTING_SPLINTER, SubSkill.WOODCUTTING_NATURES_BOUNTY, SubSkill.WOODCUTTING_TREE_FELLER, SubSkill.WOODCUTTING_HARVEST_LUMBER));
|
||||
|
||||
private Class<? extends SkillManager> managerClass;
|
||||
private Color runescapeColor;
|
||||
|
@ -1,39 +1,106 @@
|
||||
package com.gmail.nossr50.datatypes.skills;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
||||
|
||||
/**
|
||||
* This class represents a gated subskill
|
||||
* A gated subskill is a subskill that requires a certain level to unlock
|
||||
* A SkillMilestone is a representation of a specific rank for a subskill
|
||||
* A SkillMilestone may contain a child, the child represents the next rank of the subskill
|
||||
* This class is mostly to make it easier to grab information about subskills for a player
|
||||
*/
|
||||
public class SkillMilestone {
|
||||
private int unlockLevel; //Level that grants access to this skill
|
||||
private SubSkill subskill; //Subskill that this milestone belongs to
|
||||
private final int unlockLevel; //Level that grants access to this skill
|
||||
private final SubSkill subskill; //Subskill that this milestone belongs to
|
||||
private SkillMilestone childMilestone; //Next rank in the milestone
|
||||
private SkillMilestone lastChild; //The final child milestone in this chain
|
||||
private final int curRank; //The current rank of this SkillMilestone
|
||||
|
||||
public SkillMilestone(SubSkill subskill, int unlockLevel, SkillMilestone childMilestone)
|
||||
public SkillMilestone(SubSkill subskill, int curRank)
|
||||
{
|
||||
this.subskill = subskill;
|
||||
this.unlockLevel = unlockLevel;
|
||||
|
||||
//Assign a child subskill if it exists
|
||||
if(childMilestone != null)
|
||||
this.childMilestone = childMilestone;
|
||||
}
|
||||
|
||||
public SkillMilestone(SubSkill subskill, int unlockLevel)
|
||||
{
|
||||
this(subskill, unlockLevel, null);
|
||||
this.curRank = curRank;
|
||||
this.unlockLevel = AdvancedConfig.getInstance().getSubSkillUnlockLevel(subskill, curRank);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the level requirement for this subskill's rank
|
||||
* @return The level required to use this subskill
|
||||
*/
|
||||
public int getUnlockLevel() {
|
||||
return unlockLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's the current milestone the player is working towards
|
||||
* @param playerProfile
|
||||
* @return
|
||||
*/
|
||||
public SkillMilestone getCurrentMilestoneForPlayer(PlayerProfile playerProfile)
|
||||
{
|
||||
if(playerProfile.getSkillLevel(subskill.getParentSkill()) >= unlockLevel)
|
||||
{
|
||||
if(childMilestone != null)
|
||||
return childMilestone.getCurrentMilestoneForPlayer(playerProfile);
|
||||
|
||||
return this;
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated SubSkill for this milestone
|
||||
* @return
|
||||
*/
|
||||
public SubSkill getSubskill() {
|
||||
return subskill;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child milestone, which is the next rank of this skill
|
||||
* @return The child milestone of this skill
|
||||
*/
|
||||
public SkillMilestone getChildMilestone() {
|
||||
return childMilestone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child milestone, which represents the next rank of this skill
|
||||
*/
|
||||
public void addChildMilestone()
|
||||
{
|
||||
childMilestone = new SkillMilestone(this.subskill, curRank+1);
|
||||
}
|
||||
|
||||
/**
|
||||
* This grabs the final child in the chain of child milestones, which represents the last rank of this subskill
|
||||
* @return The final child for this SkillMilestone, which is the final rank for the associated subskill. Null if this Milestone has no children.
|
||||
*/
|
||||
public SkillMilestone getFinalChild()
|
||||
{
|
||||
//Return lastchild if we already have the ref stored
|
||||
if(lastChild != null)
|
||||
return lastChild;
|
||||
|
||||
//If the next child doesn't exist return this
|
||||
if(childMilestone == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
//If we have children, find their children until the chain stops and store that reference and return it
|
||||
return lastChild = childMilestone.getFinalChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current rank of this SkillMilestone for the associated subskill
|
||||
* @return The current rank of this subskill
|
||||
*/
|
||||
public int getCurRank() { return curRank; }
|
||||
|
||||
/**
|
||||
* The requirement for the next rank of this subskill
|
||||
* @return The level requirement for the next rank of this SkillMilestone chain
|
||||
*/
|
||||
public int getNextRankReq() { return childMilestone.unlockLevel; }
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package com.gmail.nossr50.datatypes.skills;
|
||||
|
||||
import com.gmail.nossr50.util.StringUtils;
|
||||
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill.*;
|
||||
public enum SubSkill {
|
||||
/* !! Warning -- Do not let subskills share a name with any existing PrimarySkill as it will clash with the static import !! */
|
||||
|
||||
@ -85,12 +84,38 @@ public enum SubSkill {
|
||||
UNARMED_IRON_GRIP,
|
||||
|
||||
/* Woodcutting */
|
||||
WOODCUTTING_TREE_FELLER,
|
||||
WOODCUTTING_LEAF_BLOWER,
|
||||
WOODCUTTING_SURGEON,
|
||||
WOODCUTTING_NATURES_BOUNTY,
|
||||
WOODCUTTING_SPLINTER,
|
||||
WOODCUTTING_DOUBLE_DROPS;
|
||||
WOODCUTTING_TREE_FELLER(5),
|
||||
WOODCUTTING_LEAF_BLOWER(3),
|
||||
WOODCUTTING_BARK_SURGEON(3),
|
||||
WOODCUTTING_NATURES_BOUNTY(3),
|
||||
WOODCUTTING_SPLINTER(3),
|
||||
WOODCUTTING_HARVEST_LUMBER(3);
|
||||
|
||||
private final int numRanks;
|
||||
|
||||
/**
|
||||
* If our SubSkill has more than 1 rank define it
|
||||
* @param numRanks The number of ranks our SubSkill has
|
||||
*/
|
||||
SubSkill(int numRanks)
|
||||
{
|
||||
this.numRanks = numRanks;
|
||||
}
|
||||
|
||||
/**
|
||||
* SubSkills will default to having only 1 rank if not defined
|
||||
*/
|
||||
SubSkill()
|
||||
{
|
||||
this.numRanks = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getNumRanks()
|
||||
{
|
||||
return numRanks;
|
||||
}
|
||||
|
||||
/**
|
||||
* !!! This relies on the immutable lists in PrimarySkill being populated !!!
|
||||
@ -136,7 +161,7 @@ public enum SubSkill {
|
||||
* Find where to begin our substring (after the prefix)
|
||||
*/
|
||||
String endResult = "";
|
||||
char[] enumNameCharArray = subSkillName.toString().toCharArray();
|
||||
char[] enumNameCharArray = subSkillName.toCharArray();
|
||||
int subStringIndex = 0;
|
||||
|
||||
//Find where to start our substring for this constants name
|
||||
@ -152,12 +177,17 @@ public enum SubSkill {
|
||||
/*
|
||||
* Split the string up so we can capitalize each part
|
||||
*/
|
||||
String subskillNameWithoutPrefix = subSkillName.toString().substring(subStringIndex);
|
||||
String splitStrings[] = subskillNameWithoutPrefix.split("_");
|
||||
|
||||
for(String string : splitStrings)
|
||||
String subskillNameWithoutPrefix = subSkillName.substring(subStringIndex);
|
||||
if(subskillNameWithoutPrefix.contains("_"))
|
||||
{
|
||||
endResult += StringUtils.getCapitalized(string);
|
||||
String splitStrings[] = subskillNameWithoutPrefix.split("_");
|
||||
|
||||
for(String string : splitStrings)
|
||||
{
|
||||
endResult += StringUtils.getCapitalized(string);
|
||||
}
|
||||
} else {
|
||||
endResult += StringUtils.getCapitalized(subskillNameWithoutPrefix);
|
||||
}
|
||||
|
||||
return endResult;
|
||||
|
@ -47,7 +47,6 @@ import net.shatteredlands.shatt.backup.ZipLibrary;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -189,9 +188,6 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
//Grab the setting for classic mode
|
||||
classicModeEnabled = Config.getInstance().getClassicMode();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +38,7 @@ public class WoodcuttingManager extends SkillManager {
|
||||
}
|
||||
|
||||
protected boolean canGetDoubleDrops() {
|
||||
return Permissions.isSubSkillEnabled(getPlayer(), SubSkill.WOODCUTTING_DOUBLE_DROPS) && SkillUtils.isActivationSuccessful(SubSkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkill.WOODCUTTING_DOUBLE_DROPS, getPlayer(), this.skill, getSkillLevel(), activationChance);
|
||||
return Permissions.isSubSkillEnabled(getPlayer(), SubSkill.WOODCUTTING_HARVEST_LUMBER) && SkillUtils.isActivationSuccessful(SubSkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkill.WOODCUTTING_HARVEST_LUMBER, getPlayer(), this.skill, getSkillLevel(), activationChance);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,14 @@ public class FormulaManager {
|
||||
|
||||
private FormulaType previousFormula;
|
||||
|
||||
//Used for XP formula scaling
|
||||
private boolean classicModeEnabled;
|
||||
private int classicModeXPFormulaFactor;
|
||||
|
||||
public FormulaManager() {
|
||||
/* Setting for Classic Mode (Scales a lot of stuff up by * 10) */
|
||||
classicModeEnabled = Config.getInstance().getClassicMode();
|
||||
classicModeXPFormulaFactor = Config.getInstance().getClassicModeXPFormulaFactor();
|
||||
loadFormula();
|
||||
}
|
||||
|
||||
@ -105,6 +112,9 @@ public class FormulaManager {
|
||||
public int getCachedXpToLevel(int level, FormulaType formulaType) {
|
||||
int experience;
|
||||
|
||||
//If we're in classic we use the XP factor from config settings
|
||||
int skillSystemMultiplier = classicModeEnabled ? classicModeXPFormulaFactor : 10;
|
||||
|
||||
if (formulaType == FormulaType.UNKNOWN) {
|
||||
formulaType = FormulaType.LINEAR;
|
||||
}
|
||||
@ -116,7 +126,7 @@ public class FormulaManager {
|
||||
switch (formulaType) {
|
||||
case LINEAR:
|
||||
if (!experienceNeededLinear.containsKey(level)) {
|
||||
experience = (int) Math.floor( 10 * (base + level * multiplier));
|
||||
experience = (int) Math.floor( skillSystemMultiplier * (base + level * multiplier));
|
||||
experienceNeededLinear.put(level, experience);
|
||||
}
|
||||
|
||||
@ -124,7 +134,7 @@ public class FormulaManager {
|
||||
|
||||
case EXPONENTIAL:
|
||||
if (!experienceNeededExponential.containsKey(level)) {
|
||||
experience = (int) Math.floor( 10 * multiplier * Math.pow(level, exponent) + base);
|
||||
experience = (int) Math.floor( skillSystemMultiplier * (multiplier * Math.pow(level, exponent) + base));
|
||||
experienceNeededExponential.put(level, experience);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.gmail.nossr50.util.skills;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillMilestone;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This Factory class builds SkillMilestone chains as needed
|
||||
* SkillMilestones are stored in a hash map
|
||||
*/
|
||||
public class SkillMilestoneFactory {
|
||||
|
||||
private static HashMap<SubSkill, SkillMilestone> skillMilestoneMap;
|
||||
|
||||
/**
|
||||
* Gets a the SkillMilestone chain for this subskill
|
||||
* Builds that chain if it doesn't exist before returning the parent node
|
||||
* @param subSkill The SubSkill to get the SkillMilestone chain for
|
||||
* @return The parent node of the SkillMilestone chain for the target subskill
|
||||
*/
|
||||
public static SkillMilestone getSkillMilestone(SubSkill subSkill)
|
||||
{
|
||||
//Init the map
|
||||
if(skillMilestoneMap == null)
|
||||
skillMilestoneMap = new HashMap<>();
|
||||
|
||||
if(skillMilestoneMap.get(subSkill) == null)
|
||||
return buildSkillMilestone(subSkill);
|
||||
else
|
||||
return skillMilestoneMap.get(subSkill);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a SkillMilestone chain for a given subskill
|
||||
* @param subSkill The subskill to build the SkillMilestone chain for
|
||||
* @return The base node of the SkillMilestone chain
|
||||
*/
|
||||
private static SkillMilestone buildSkillMilestone(SubSkill subSkill)
|
||||
{
|
||||
//Init our parent node
|
||||
SkillMilestone newSkillMilestone = new SkillMilestone(subSkill, AdvancedConfig.getInstance().getSubSkillUnlockLevel(subSkill, 1));
|
||||
|
||||
//There's probably a better way to do this
|
||||
for(int x = 0; x < subSkill.getNumRanks()-1; x++)
|
||||
{
|
||||
newSkillMilestone.addChildMilestone();
|
||||
}
|
||||
|
||||
//DEBUG
|
||||
System.out.println("Milestone constructed for "+subSkill);
|
||||
return skillMilestoneMap.put(subSkill, newSkillMilestone);
|
||||
}
|
||||
}
|
@ -564,15 +564,80 @@ Skills:
|
||||
# Settings for Woodcutting
|
||||
###
|
||||
Woodcutting:
|
||||
LeafBlower:
|
||||
# UnlockLevel: At this level, the passive ability LeafBlower unlocks
|
||||
UnlockLevel: 100
|
||||
|
||||
DoubleDrops:
|
||||
# ChanceMax: Maximum chance of receiving double drops
|
||||
Splinter:
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 5
|
||||
Rank_2:
|
||||
LevelReq: 30
|
||||
Rank_3:
|
||||
LevelReq: 55
|
||||
TreeFeller:
|
||||
# If set to true then tree feller will not use the new system and will use its old behaviour
|
||||
Classic: false
|
||||
# This is the time in seconds to build a new charge of Tree Feller
|
||||
ChargeRate: 600
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 10
|
||||
TreeSizeMax: 100
|
||||
Charges: 1
|
||||
Rank_2:
|
||||
LevelReq: 25
|
||||
TreeSizeMax: 200
|
||||
Charges: 1
|
||||
Rank_3:
|
||||
LevelReq: 50
|
||||
TreeSizeMax: 200
|
||||
Charges: 2
|
||||
Rank_4:
|
||||
LevelReq: 75
|
||||
TreeSizeMax: 200
|
||||
Charges: 3
|
||||
Rank_5:
|
||||
LevelReq: 100
|
||||
TreeSizeMax: 500
|
||||
Charges: 3
|
||||
BarkSurgeon:
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 70
|
||||
Rank_2:
|
||||
LevelReq: 80
|
||||
Rank_3:
|
||||
LevelReq: 95
|
||||
NaturesBounty:
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 40
|
||||
Rank_2:
|
||||
LevelReq: 60
|
||||
Rank_3:
|
||||
LevelReq: 90
|
||||
# Double Drops
|
||||
HarvestLumber:
|
||||
Classic: false
|
||||
# ChanceMax & MaxBonusLevel are only used for Classic, I'll make that more clear in the future.
|
||||
# ChanceMax: Maximum chance of receiving double drops (100 = 100%)
|
||||
# MaxBonusLevel: Level when the maximum chance of receiving double drops is reached
|
||||
ChanceMax: 100.0
|
||||
MaxBonusLevel: 100
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 20
|
||||
Rank_2:
|
||||
LevelReq: 45
|
||||
Rank_3:
|
||||
LevelReq: 85
|
||||
LeafBlower:
|
||||
Rank_Levels:
|
||||
Rank_1:
|
||||
LevelReq: 15
|
||||
Rank_2:
|
||||
LevelReq: 35
|
||||
Rank_3:
|
||||
LevelReq: 65
|
||||
|
||||
#
|
||||
# Customize the kraken!
|
||||
###
|
||||
|
@ -8,7 +8,14 @@
|
||||
# Settings for mcMMO in general
|
||||
###
|
||||
General:
|
||||
Classic_Mode: false
|
||||
Skill_Scaling:
|
||||
# Turning this on will scale mcMMO around 1-1000 with default scaling factor
|
||||
Classic_Mode: false
|
||||
Skill_Scaling:
|
||||
# This is the value that is skill level requirements are multiplied by in Classic Mode (Default is 10)
|
||||
Classic_LevelReq_Factor: 10
|
||||
# This is the value that the xp required to level is multiplied by when in classic mode
|
||||
Classic_XP_Formula_Factor: 1
|
||||
Locale: en_US
|
||||
MOTD_Enabled: true
|
||||
# Send a message to the player when his profile was successfully loaded
|
||||
|
@ -408,8 +408,14 @@ Woodcutting.Effect.0=Tree Feller (ABILITY)
|
||||
Woodcutting.Effect.1=Make trees explode
|
||||
Woodcutting.Effect.2=Leaf Blower
|
||||
Woodcutting.Effect.3=Blow Away Leaves
|
||||
Woodcutting.Effect.4=Double Drops
|
||||
Woodcutting.Effect.5=Double the normal loot
|
||||
Woodcutting.Effect.4=Harvest Lumber
|
||||
Woodcutting.Effect.5=Skillfully extract more Lumber
|
||||
Woodcutting.Effect.6=Splinter
|
||||
Woodcutting.Effect.7=Cut down trees more efficiently.
|
||||
Woodcutting.Effect.8=Bark Surgeon
|
||||
Woodcutting.Effect.9=Extract useful materials when stripping trees.
|
||||
Woodcutting.Effect.10=Nature's Bounty
|
||||
Woodcutting.Effect.11=Gather experience from nature.
|
||||
Woodcutting.Listener=Woodcutting:
|
||||
Woodcutting.SkillName=WOODCUTTING
|
||||
Woodcutting.Skills.TreeFeller.Off=[[RED]]**Tree Feller has worn off**
|
||||
|
@ -12,7 +12,7 @@ description: >
|
||||
|
||||
author: nossr50
|
||||
authors: [GJ, NuclearW, bm01, Glitchfinder, TfT_02, t00thpick1, Riking]
|
||||
website: https://github.com/mcMMO-Dev/mcMMO
|
||||
website: https://mcmmo.org
|
||||
main: com.gmail.nossr50.mcMMO
|
||||
softdepend: [CombatTag, HealthBar]
|
||||
load: STARTUP
|
||||
@ -668,10 +668,19 @@ permissions:
|
||||
mcmmo.ability.woodcutting.all:
|
||||
description: Allows access to all Woodcutting abilities
|
||||
children:
|
||||
mcmmo.ability.woodcutting.doubledrops: true
|
||||
mcmmo.ability.woodcutting.harvestlumber: true
|
||||
mcmmo.ability.woodcutting.splinter: true
|
||||
mcmmo.ability.woodcutting.barksurgeon: true
|
||||
mcmmo.ability.woodcutting.naturesbounty: true
|
||||
mcmmo.ability.woodcutting.leafblower: true
|
||||
mcmmo.ability.woodcutting.treefeller: true
|
||||
mcmmo.ability.woodcutting.doubledrops:
|
||||
mcmmo.ability.woodcutting.splinter:
|
||||
description: Allows access to Splinter
|
||||
mcmmo.ability.woodcutting.barksurgeon:
|
||||
description: Allows access to Bark Surgeon
|
||||
mcmmo.ability.woodcutting.naturesbounty:
|
||||
description: Allows access to Natures Bounty
|
||||
mcmmo.ability.woodcutting.harvestlumber:
|
||||
description: Allows double drop chance when woodcutting
|
||||
mcmmo.ability.woodcutting.leafblower:
|
||||
description: Allows access to Leaf Blower ability
|
||||
|
Loading…
Reference in New Issue
Block a user