mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 11:03:43 +01:00 
			
		
		
		
	Added some JSON, much more to come.
This commit is contained in:
		@@ -8,6 +8,7 @@ Key:
 | 
			
		||||
  - Removal
 | 
			
		||||
 | 
			
		||||
Version 2.1.0
 | 
			
		||||
 + Added JSON support to Woodcutting command
 | 
			
		||||
 + 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
 | 
			
		||||
@@ -15,6 +16,8 @@ Version 2.1.0
 | 
			
		||||
 + (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
 | 
			
		||||
 ! (Locale) Super Abilities no longer have (ABILITY) in their Skill.Effect strings
 | 
			
		||||
 ! (API) mcMMO is now built against Spigot-API instead of Bukkit
 | 
			
		||||
 ! (API) SkillType is now PrimarySkill
 | 
			
		||||
 ! (API) SecondarySkill is now SubSkill
 | 
			
		||||
 ! (API) AbilityType is now SuperAbility
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								pom.xml
									
									
									
									
									
								
							@@ -122,11 +122,17 @@
 | 
			
		||||
            </extension>
 | 
			
		||||
        </extensions>
 | 
			
		||||
    </build>
 | 
			
		||||
    <repositories>
 | 
			
		||||
        <repository>
 | 
			
		||||
            <id>spigot-repo</id>
 | 
			
		||||
            <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
 | 
			
		||||
        </repository>
 | 
			
		||||
    </repositories>
 | 
			
		||||
    <dependencies>
 | 
			
		||||
        <dependency>
 | 
			
		||||
            <groupId>org.bukkit</groupId>
 | 
			
		||||
            <artifactId>bukkit</artifactId>
 | 
			
		||||
            <version>1.13.1-R0.1-SNAPSHOT</version>
 | 
			
		||||
            <groupId>org.spigotmc</groupId>
 | 
			
		||||
            <artifactId>spigot-api</artifactId>
 | 
			
		||||
            <version>1.13.2-R0.1-SNAPSHOT</version>
 | 
			
		||||
            <scope>provided</scope>
 | 
			
		||||
        </dependency>
 | 
			
		||||
        <dependency>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
@@ -94,4 +95,10 @@ public class AcrobaticsCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
@@ -100,4 +101,10 @@ public class AlchemyCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.text.DecimalFormat;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabExecutor;
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
@@ -93,4 +94,10 @@ public class ArcheryCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
@@ -118,4 +119,10 @@ public class AxesCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package com.gmail.nossr50.commands.skills;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
@@ -62,4 +63,10 @@ public class ExcavationCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.entity.EntityType;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
@@ -202,4 +203,10 @@ public class FishingCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.skills.herbalism.Herbalism;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
@@ -162,4 +163,10 @@ public class HerbalismCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
@@ -150,4 +151,10 @@ public class MiningCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,7 @@ import com.gmail.nossr50.skills.repair.RepairManager;
 | 
			
		||||
import com.gmail.nossr50.skills.repair.repairables.Repairable;
 | 
			
		||||
import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
@@ -155,4 +156,10 @@ public class RepairCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
@@ -76,4 +77,10 @@ public class SalvageCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,7 @@ import java.util.List;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabExecutor;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import com.gmail.nossr50.util.SkillTextComponentFactory;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
import com.gmail.nossr50.config.Config;
 | 
			
		||||
@@ -26,6 +22,13 @@ import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
 | 
			
		||||
import com.gmail.nossr50.util.skills.PerksUtils;
 | 
			
		||||
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import net.md_5.bungee.api.ChatColor;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
import org.bukkit.command.TabExecutor;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
public abstract class SkillCommand implements TabExecutor {
 | 
			
		||||
    protected PrimarySkill skill;
 | 
			
		||||
@@ -68,15 +71,59 @@ public abstract class SkillCommand implements TabExecutor {
 | 
			
		||||
                    ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if(skill == PrimarySkill.WOODCUTTING)
 | 
			
		||||
                {
 | 
			
		||||
                    sendSkillCommandHeader(player, mcMMOPlayer, (int) skillValue);
 | 
			
		||||
 | 
			
		||||
                    //Make JSON text components
 | 
			
		||||
                    List<TextComponent> subskillTextComponents = getTextComponents(player);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                    //Subskills Header
 | 
			
		||||
                    player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Effects.SubSkills")));
 | 
			
		||||
 | 
			
		||||
                    //Send JSON text components
 | 
			
		||||
                    for(TextComponent tc : subskillTextComponents)
 | 
			
		||||
                    {
 | 
			
		||||
                        player.spigot().sendMessage(new TextComponent[]{tc, new TextComponent(": TESTING")});
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    //Stats
 | 
			
		||||
                    getStatMessages(player, isLucky, hasEndurance, skillValue);
 | 
			
		||||
                } else {
 | 
			
		||||
                    displayOldSkillCommand(player, mcMMOPlayer, isLucky, hasEndurance, skillValue);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                return skillGuideCommand.onCommand(sender, command, label, args);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void getStatMessages(Player player, boolean isLucky, boolean hasEndurance, float skillValue) {
 | 
			
		||||
        List<String> statsMessages = statsDisplay(player, skillValue, hasEndurance, isLucky);
 | 
			
		||||
 | 
			
		||||
        if (!statsMessages.isEmpty()) {
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
 | 
			
		||||
 | 
			
		||||
            for (String message : statsMessages) {
 | 
			
		||||
                player.sendMessage(message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        player.sendMessage(LocaleLoader.getString("Guides.Available", skillName, skillName.toLowerCase()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void sendSkillCommandHeader(Player player, McMMOPlayer mcMMOPlayer, int skillValue) {
 | 
			
		||||
        if (!skill.isChildSkill()) {
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
 | 
			
		||||
                    player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, mcMMOPlayer.getSkillXpLevel(skill), mcMMOPlayer.getXpToLevel(skill)));
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Effects.Level", skillValue, mcMMOPlayer.getSkillXpLevel(skill), mcMMOPlayer.getXpToLevel(skill)));
 | 
			
		||||
        } else {
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child")));
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain.Child")));
 | 
			
		||||
                    player.sendMessage(LocaleLoader.getString("Effects.Child", (int) skillValue));
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Effects.Child", skillValue));
 | 
			
		||||
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Skills.Parents")));
 | 
			
		||||
            Set<PrimarySkill> parents = FamilyTree.getParents(skill);
 | 
			
		||||
@@ -85,6 +132,11 @@ public abstract class SkillCommand implements TabExecutor {
 | 
			
		||||
                player.sendMessage(parent.getName() + " - " + LocaleLoader.getString("Effects.Level", mcMMOPlayer.getSkillLevel(parent), mcMMOPlayer.getSkillXpLevel(parent), mcMMOPlayer.getXpToLevel(parent)));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void displayOldSkillCommand(Player player, McMMOPlayer mcMMOPlayer, boolean isLucky, boolean hasEndurance, float skillValue) {
 | 
			
		||||
        //Send headers
 | 
			
		||||
        sendSkillCommandHeader(player, mcMMOPlayer, (int) skillValue);
 | 
			
		||||
 | 
			
		||||
        List<String> effectMessages = effectsDisplay();
 | 
			
		||||
 | 
			
		||||
@@ -100,22 +152,7 @@ public abstract class SkillCommand implements TabExecutor {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                List<String> statsMessages = statsDisplay(player, skillValue, hasEndurance, isLucky);
 | 
			
		||||
 | 
			
		||||
                if (!statsMessages.isEmpty()) {
 | 
			
		||||
                    player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
 | 
			
		||||
 | 
			
		||||
                    for (String message : statsMessages) {
 | 
			
		||||
                        player.sendMessage(message);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                player.sendMessage(LocaleLoader.getString("Guides.Available", skillName, skillName.toLowerCase()));
 | 
			
		||||
                return true;
 | 
			
		||||
 | 
			
		||||
            default:
 | 
			
		||||
                return skillGuideCommand.onCommand(sender, command, label, args);
 | 
			
		||||
        }
 | 
			
		||||
        getStatMessages(player, isLucky, hasEndurance, skillValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -166,4 +203,6 @@ public abstract class SkillCommand implements TabExecutor {
 | 
			
		||||
    protected abstract List<String> effectsDisplay();
 | 
			
		||||
 | 
			
		||||
    protected abstract List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky);
 | 
			
		||||
 | 
			
		||||
    protected abstract List<TextComponent> getTextComponents(Player player);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
@@ -117,4 +118,10 @@ public class SmeltingCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
@@ -102,4 +103,10 @@ public class SwordsCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.EntityType;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
@@ -168,4 +169,10 @@ public class TamingCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import java.util.List;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
@@ -132,4 +133,10 @@ public class UnarmedCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,10 +4,9 @@ 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 com.gmail.nossr50.util.SkillTextComponentFactory;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
@@ -125,4 +124,35 @@ public class WoodcuttingCommand extends SkillCommand {
 | 
			
		||||
 | 
			
		||||
        return messages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected List<TextComponent> getTextComponents(Player player) {
 | 
			
		||||
        List<TextComponent> textComponents = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        if (canTreeFell) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_TREE_FELLER, 0, 1));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (canLeafBlow) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_LEAF_BLOWER, 2, 3));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (canDoubleDrop) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_HARVEST_LUMBER, 4, 5));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (canSplinter) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_SPLINTER, 6, 7));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(canBarkSurgeon) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_BARK_SURGEON, 8, 9));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(canNaturesBounty) {
 | 
			
		||||
            textComponents.add(SkillTextComponentFactory.getSubSkillTextComponent(player, SubSkill.WOODCUTTING_NATURES_BOUNTY, 10, 11));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return textComponents;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,106 +0,0 @@
 | 
			
		||||
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 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 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 curRank)
 | 
			
		||||
    {
 | 
			
		||||
        this.subskill = subskill;
 | 
			
		||||
        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; }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
package com.gmail.nossr50.datatypes.skills;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.util.StringUtils;
 | 
			
		||||
 | 
			
		||||
public enum SubSkill {
 | 
			
		||||
@@ -103,11 +104,11 @@ public enum SubSkill {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SubSkills will default to having only 1 rank if not defined
 | 
			
		||||
     * SubSkills will default to having 0 ranks if not defined
 | 
			
		||||
     */
 | 
			
		||||
    SubSkill()
 | 
			
		||||
    {
 | 
			
		||||
        this.numRanks = 1;
 | 
			
		||||
        this.numRanks = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -161,18 +162,7 @@ public enum SubSkill {
 | 
			
		||||
         * Find where to begin our substring (after the prefix)
 | 
			
		||||
         */
 | 
			
		||||
        String endResult = "";
 | 
			
		||||
        char[] enumNameCharArray = subSkillName.toCharArray();
 | 
			
		||||
        int subStringIndex = 0;
 | 
			
		||||
 | 
			
		||||
        //Find where to start our substring for this constants name
 | 
			
		||||
        for (int i = 0; i < enumNameCharArray.length; i++) {
 | 
			
		||||
            if(enumNameCharArray[i] == '_')
 | 
			
		||||
            {
 | 
			
		||||
                subStringIndex = i+1; //Start the substring after this char
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        int subStringIndex = getSubStringIndex(subSkillName);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * Split the string up so we can capitalize each part
 | 
			
		||||
@@ -192,4 +182,38 @@ public enum SubSkill {
 | 
			
		||||
 | 
			
		||||
        return endResult;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the name of the parent skill from the Locale file
 | 
			
		||||
     * @return The parent skill as defined in the locale
 | 
			
		||||
     */
 | 
			
		||||
    public String getParentNiceNameLocale()
 | 
			
		||||
    {
 | 
			
		||||
        return LocaleLoader.getString(StringUtils.getCapitalized(getParentSkill().toString())+".SkillName");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This finds the substring index for our SubSkill's name after its parent name prefix
 | 
			
		||||
     * @param subSkillName The name to process
 | 
			
		||||
     * @return The value of the substring index after our parent's prefix
 | 
			
		||||
     */
 | 
			
		||||
    private int getSubStringIndex(String subSkillName) {
 | 
			
		||||
        char[] enumNameCharArray = subSkillName.toCharArray();
 | 
			
		||||
        int subStringIndex = 0;
 | 
			
		||||
 | 
			
		||||
        //Find where to start our substring for this constants name
 | 
			
		||||
        for (int i = 0; i < enumNameCharArray.length; i++) {
 | 
			
		||||
            if (enumNameCharArray[i] == '_') {
 | 
			
		||||
                subStringIndex = i + 1; //Start the substring after this char
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return subStringIndex;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getLocalKeyRoot()
 | 
			
		||||
    {
 | 
			
		||||
        return StringUtils.getCapitalized(getParentSkill().toString()) + ".Effect.";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package com.gmail.nossr50.util;
 | 
			
		||||
import java.text.DecimalFormat;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.plugin.PluginDescriptionFile;
 | 
			
		||||
 | 
			
		||||
@@ -36,6 +37,8 @@ public final class Motd {
 | 
			
		||||
    public static void displayVersion(Player player, String version) {
 | 
			
		||||
        if (Permissions.showversion(player)) {
 | 
			
		||||
            player.sendMessage(LocaleLoader.getString("MOTD.Version", version));
 | 
			
		||||
            //TODO: Remove this at release
 | 
			
		||||
            player.sendMessage(ChatColor.YELLOW + "You're playing an "+ ChatColor.RED +"UNSTABLE" +ChatColor.YELLOW+" version of mcMMO! 2.1.0 is making many changes and if you are playing dev-snapshot you know the risks!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,84 @@
 | 
			
		||||
package com.gmail.nossr50.util;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import com.gmail.nossr50.util.skills.RankUtils;
 | 
			
		||||
import net.md_5.bungee.api.ChatColor;
 | 
			
		||||
import net.md_5.bungee.api.chat.BaseComponent;
 | 
			
		||||
import net.md_5.bungee.api.chat.ComponentBuilder;
 | 
			
		||||
import net.md_5.bungee.api.chat.HoverEvent;
 | 
			
		||||
import net.md_5.bungee.api.chat.TextComponent;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
public class SkillTextComponentFactory {
 | 
			
		||||
    public static HashMap<SubSkill, TextComponent> subSkillTextComponents;
 | 
			
		||||
    public static HashMap<SubSkill, BaseComponent[]> subSkillHoverComponents;
 | 
			
		||||
 | 
			
		||||
    public static TextComponent getSubSkillTextComponent(Player player, SubSkill subSkill, int localeKeyName, int localeKeyDescription)
 | 
			
		||||
    {
 | 
			
		||||
        boolean playerHasUnlocked = false;
 | 
			
		||||
 | 
			
		||||
        //Init our maps
 | 
			
		||||
        if (subSkillTextComponents == null)
 | 
			
		||||
        {
 | 
			
		||||
            subSkillTextComponents = new HashMap<>();
 | 
			
		||||
            subSkillHoverComponents = new HashMap<>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int curRank = RankUtils.getRank(player, subSkill);
 | 
			
		||||
 | 
			
		||||
        if(curRank > 0)
 | 
			
		||||
            playerHasUnlocked = true;
 | 
			
		||||
 | 
			
		||||
        //The skill milestone holds relevant information about the ranks of a skill
 | 
			
		||||
        PlayerProfile playerProfile = UserManager.getPlayer(player).getProfile();
 | 
			
		||||
 | 
			
		||||
        //Get skill name & description from our locale file
 | 
			
		||||
        String skillName = LocaleLoader.getString(subSkill.getLocalKeyRoot()+localeKeyName);
 | 
			
		||||
        String skillDescription = LocaleLoader.getString(subSkill.getLocalKeyRoot()+localeKeyDescription);
 | 
			
		||||
 | 
			
		||||
        if(subSkillTextComponents.get(subSkill) == null)
 | 
			
		||||
        {
 | 
			
		||||
            //Setup Text Component
 | 
			
		||||
            TextComponent textComponent = new TextComponent(skillName);
 | 
			
		||||
            textComponent.setColor(ChatColor.DARK_AQUA);
 | 
			
		||||
 | 
			
		||||
            //Hover Event
 | 
			
		||||
            textComponent.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, getBaseComponent(player, subSkill, skillName, skillDescription, curRank, playerHasUnlocked)));
 | 
			
		||||
 | 
			
		||||
            //Insertion
 | 
			
		||||
            textComponent.setInsertion(skillName);
 | 
			
		||||
 | 
			
		||||
            subSkillTextComponents.put(subSkill, textComponent);
 | 
			
		||||
            return subSkillTextComponents.get(subSkill);
 | 
			
		||||
        } else {
 | 
			
		||||
            return subSkillTextComponents.get(subSkill);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static BaseComponent[] getBaseComponent(Player player, SubSkill subSkill, String skillName, String skillDescription, int curRank, boolean playerHasUnlocked)
 | 
			
		||||
    {
 | 
			
		||||
        if(subSkillHoverComponents.get(subSkill) != null)
 | 
			
		||||
        {
 | 
			
		||||
            return subSkillHoverComponents.get(subSkill);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        BaseComponent[] newComponents;
 | 
			
		||||
 | 
			
		||||
        //TODO: Clean this up
 | 
			
		||||
        if(subSkill.getNumRanks() == 0)
 | 
			
		||||
            newComponents = new ComponentBuilder(skillName).bold(true).color(ChatColor.GOLD).append("\n\nDescription").bold(true).color(ChatColor.GREEN).append("\n"+skillDescription).bold(false).color(ChatColor.WHITE).create();
 | 
			
		||||
        else if(playerHasUnlocked)
 | 
			
		||||
            newComponents = new ComponentBuilder(skillName).bold(true).color(ChatColor.GOLD).append("\nRank "+curRank).bold(false).color(ChatColor.GREEN).append(" of ").color(ChatColor.WHITE).append(String.valueOf(subSkill.getNumRanks())).color(ChatColor.GOLD).append("\n\nDescription").bold(true).color(ChatColor.GREEN).append("\n"+skillDescription).bold(false).color(ChatColor.WHITE).create();
 | 
			
		||||
        else
 | 
			
		||||
            newComponents = new ComponentBuilder(skillName).bold(true).color(ChatColor.RED).append("\n-=LOCKED=-").color(ChatColor.GRAY).append("\n\nUnlock Requirements").color(ChatColor.YELLOW).append("\nLevel "+ AdvancedConfig.getInstance().getSubSkillUnlockLevel(subSkill, 1)+" "+subSkill.getParentNiceNameLocale()).bold(false).create();
 | 
			
		||||
 | 
			
		||||
        subSkillHoverComponents.put(subSkill, newComponents);
 | 
			
		||||
        return subSkillHoverComponents.get(subSkill);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								src/main/java/com/gmail/nossr50/util/skills/RankUtils.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/main/java/com/gmail/nossr50/util/skills/RankUtils.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
			
		||||
package com.gmail.nossr50.util.skills;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import com.gmail.nossr50.util.player.UserManager;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
public class RankUtils {
 | 
			
		||||
    public static HashMap<SubSkill, HashMap<Integer, Integer>> subSkillRanks;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds ranks to subSkillRanks for target SubSkill
 | 
			
		||||
     * @param subSkill Target SubSkill
 | 
			
		||||
     */
 | 
			
		||||
    private static void addRanks(SubSkill subSkill) {
 | 
			
		||||
        int numRanks = subSkill.getNumRanks();
 | 
			
		||||
 | 
			
		||||
        //Fill out the rank array
 | 
			
		||||
        for(int i = 0; i < numRanks; i++)
 | 
			
		||||
        {
 | 
			
		||||
            //This adds the highest ranks first
 | 
			
		||||
            addRank(subSkill, numRanks-i);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the current rank of the subskill for the player
 | 
			
		||||
     * @param player The player in question
 | 
			
		||||
     * @param subSkill Target subskill
 | 
			
		||||
     * @return The rank the player currently has achieved in this skill. -1 for skills without ranks.
 | 
			
		||||
     */
 | 
			
		||||
    public static int getRank(Player player, SubSkill subSkill)
 | 
			
		||||
    {
 | 
			
		||||
        if(subSkillRanks == null)
 | 
			
		||||
            subSkillRanks = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        if(subSkill.getNumRanks() == 0)
 | 
			
		||||
            return -1; //-1 Means the skill doesn't have ranks
 | 
			
		||||
 | 
			
		||||
        if(subSkillRanks.get(subSkill) == null && subSkill.getNumRanks() > 0)
 | 
			
		||||
            addRanks(subSkill);
 | 
			
		||||
 | 
			
		||||
        //Get our rank map
 | 
			
		||||
        HashMap<Integer, Integer> rankMap = subSkillRanks.get(subSkill);
 | 
			
		||||
 | 
			
		||||
        //Skill level of parent skill
 | 
			
		||||
        int currentSkillLevel = UserManager.getPlayer(player).getSkillLevel(subSkill.getParentSkill());
 | 
			
		||||
 | 
			
		||||
        for(int i = 0; i < subSkill.getNumRanks(); i++)
 | 
			
		||||
        {
 | 
			
		||||
            //Compare against the highest to lowest rank in that order
 | 
			
		||||
            int rank = subSkill.getNumRanks()-i;
 | 
			
		||||
            //System.out.println("Checking rank "+rank+" of "+subSkill.getNumRanks());
 | 
			
		||||
            int unlockLevel = getUnlockLevel(subSkill, rank);
 | 
			
		||||
            //System.out.println("Rank "+rank+" -- Unlock level: "+unlockLevel);
 | 
			
		||||
            //System.out.println("Rank" +rank+" -- Player Skill Level: "+currentSkillLevel);
 | 
			
		||||
 | 
			
		||||
            //If we check all ranks and still cannot unlock the skill, we return rank 0
 | 
			
		||||
            if(rank == 0)
 | 
			
		||||
                return 0;
 | 
			
		||||
 | 
			
		||||
            //True if our skill level can unlock the current rank
 | 
			
		||||
            if(currentSkillLevel >= unlockLevel)
 | 
			
		||||
                return rank;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 0; //We should never reach this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds ranks to our map
 | 
			
		||||
     * @param subSkill The subskill to add ranks for
 | 
			
		||||
     * @param rank The rank to add
 | 
			
		||||
     */
 | 
			
		||||
    private static void addRank(SubSkill subSkill, int rank)
 | 
			
		||||
    {
 | 
			
		||||
        if(subSkillRanks == null)
 | 
			
		||||
            subSkillRanks = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        if(subSkillRanks.get(subSkill) == null)
 | 
			
		||||
            subSkillRanks.put(subSkill, new HashMap<>());
 | 
			
		||||
 | 
			
		||||
        HashMap<Integer, Integer> rankMap = subSkillRanks.get(subSkill);
 | 
			
		||||
 | 
			
		||||
        rankMap.put(rank, getUnlockLevel(subSkill, rank));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the unlock level for a specific rank in a subskill
 | 
			
		||||
     * @param subSkill The target subskill
 | 
			
		||||
     * @param rank The target rank
 | 
			
		||||
     * @return The level at which this rank unlocks
 | 
			
		||||
     */
 | 
			
		||||
    private static int getUnlockLevel(SubSkill subSkill, int rank)
 | 
			
		||||
    {
 | 
			
		||||
        return AdvancedConfig.getInstance().getSubSkillUnlockLevel(subSkill, rank);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
package com.gmail.nossr50.util.skills;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SubSkill;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkill;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This class will handle the following things
 | 
			
		||||
 * 1) Informing the player of important milestones in a skill (Every 5 levels)
 | 
			
		||||
 * 2) Getting lists of milestones (skill unlocks) a player has
 | 
			
		||||
 * 3) Propagating events for milestones (API)
 | 
			
		||||
 *
 | 
			
		||||
 * By setting up a skill milestone system it will make managing the audio/visual feedback for progression a lot easier
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
//TODO: Inform players of milestones
 | 
			
		||||
//TODO: Helper methods for getting milestones
 | 
			
		||||
//TODO: Propagate events when milestones are achieved
 | 
			
		||||
//TODO: Update existing parts of the codebase to use this where appropriate
 | 
			
		||||
public class SkillMilestoneManager {
 | 
			
		||||
    public static final HashMap<PrimarySkill, SubSkill> subskillMilestones;
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        //Init our maps
 | 
			
		||||
        subskillMilestones = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
        for(PrimarySkill primarySkill : PrimarySkill.values())
 | 
			
		||||
        {
 | 
			
		||||
            //TODO: Setup these values
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -38,7 +38,7 @@ Axes.Combat.CriticalHit=[[RED]]CRITICAL HIT!
 | 
			
		||||
Axes.Combat.GI.Proc=[[GREEN]]**STRUCK WITH GREAT FORCE**
 | 
			
		||||
Axes.Combat.GI.Struck=[[RED]] ** ** BRIFO GAN EFFAITH FWYAF
 | 
			
		||||
Axes.Combat.SS.Length=[[RED]]Skull Splitter Length: [[YELLOW]]{0}s
 | 
			
		||||
Axes.Effect.0=Skull Splitter (Ability)
 | 
			
		||||
Axes.Effect.0=Skull Splitter
 | 
			
		||||
Axes.Effect.1=Deal AoE Damage
 | 
			
		||||
Axes.Effect.2=Critical Strikes
 | 
			
		||||
Axes.Effect.3=Double Damage
 | 
			
		||||
@@ -58,7 +58,7 @@ Axes.Skills.SS.Other.On=[[GREEN]] {0} [[DARK_GREEN]] wedi defnyddio [[RED]] Llor
 | 
			
		||||
Axes.Skillup=[[YELLOW]] sgiliau Echelau cynyddu {0}. Cyfanswm ({1})
 | 
			
		||||
Excavation.Ability.Lower=[[GRAY]]**YOU LOWER YOUR SHOVEL**
 | 
			
		||||
Excavation.Ability.Ready=[[GREEN]]**YOU READY YOUR SHOVEL**
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker (ABILITY)
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker
 | 
			
		||||
Excavation.Effect.1=3x Drop Rate, 3x EXP, +Speed
 | 
			
		||||
Excavation.Effect.2=Treasure Hunter
 | 
			
		||||
Excavation.Effect.3=Ability to dig for treasure
 | 
			
		||||
@@ -99,7 +99,7 @@ Herbalism.Ability.GTh.Stage=[[RED]]Green Thumb Stage: [[YELLOW]] Crops grow in s
 | 
			
		||||
Herbalism.Ability.GTh=[[GREEN]]**GREEN THUMB**
 | 
			
		||||
Herbalism.Ability.Lower=[[GRAY]]**YOU LOWER YOUR HOE**
 | 
			
		||||
Herbalism.Ability.Ready=[[GREEN]]**YOU READY YOUR HOE**
 | 
			
		||||
Herbalism.Effect.0=Green Terra (ABILITY)
 | 
			
		||||
Herbalism.Effect.0=Green Terra
 | 
			
		||||
Herbalism.Effect.1=Spread the Terra, 3x Drops
 | 
			
		||||
Herbalism.Effect.2=Green Thumb (Wheat)
 | 
			
		||||
Herbalism.Effect.3=Auto-Plants crops when harvesting
 | 
			
		||||
@@ -121,7 +121,7 @@ Mining.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (BIGGER BOMBS)
 | 
			
		||||
Mining.Ability.Locked.2=LOCKED UNTIL {0}+ SKILL (DEMOLITIONS EXPERTISE)
 | 
			
		||||
Mining.Ability.Lower=[[GRAY]]**YOU LOWER YOUR PICKAXE**
 | 
			
		||||
Mining.Ability.Ready=[[GREEN]] ** CHI\'N BAROD EICH PICKAXE **
 | 
			
		||||
Mining.Effect.0=Super Breaker (ABILITY)
 | 
			
		||||
Mining.Effect.0=Super Breaker
 | 
			
		||||
Mining.Effect.1=Speed+, Triple Drop Chance
 | 
			
		||||
Mining.Effect.2=Double Drops
 | 
			
		||||
Mining.Effect.3=Double the normal loot
 | 
			
		||||
@@ -203,7 +203,7 @@ Swords.Combat.Counter.Hit=[[DARK_RED]]Hit with a counter-attack!
 | 
			
		||||
Swords.Combat.Countered=[[GREEN]] ** GWRTH-YMOSOD **
 | 
			
		||||
Swords.Combat.SS.Struck=[[DARK_RED]] Taro gan Streiciau danheddog!
 | 
			
		||||
Swords.Effect.0=Counter Attack
 | 
			
		||||
Swords.Effect.2=Serrated Strikes (ABILITY)
 | 
			
		||||
Swords.Effect.2=Serrated Strikes
 | 
			
		||||
Swords.Effect.4=Serrated Strikes Bleed+
 | 
			
		||||
Swords.Effect.6=Bleed
 | 
			
		||||
Swords.Effect.7=Apply a bleed DoT
 | 
			
		||||
@@ -263,7 +263,7 @@ Unarmed.Ability.IronGrip.Attacker=[[RED]]Your opponent has an iron grip!
 | 
			
		||||
Unarmed.Ability.IronGrip.Defender=[[GREEN]]Your iron grip kept you from being disarmed!
 | 
			
		||||
Unarmed.Ability.Lower=[[GRAY]]**YOU LOWER YOUR FISTS**
 | 
			
		||||
Unarmed.Ability.Ready=[[GREEN]]**YOU READY YOUR FISTS**
 | 
			
		||||
Unarmed.Effect.0=Berserk (ABILITY)
 | 
			
		||||
Unarmed.Effect.0=Berserk
 | 
			
		||||
Unarmed.Effect.1=+50% DMG, Breaks weak materials
 | 
			
		||||
Unarmed.Effect.2=Disarm (Players)
 | 
			
		||||
Unarmed.Effect.3=Drops the foes item held in hand
 | 
			
		||||
@@ -284,7 +284,7 @@ Woodcutting.Ability.1=Chwythu i ffwrdd yn gadael
 | 
			
		||||
Woodcutting.Ability.Chance.DDrop=[[RED]]Double Drop Chance: [[YELLOW]]{0}
 | 
			
		||||
Woodcutting.Ability.Length=[[RED]]Tree Feller Length: [[YELLOW]]{0}s
 | 
			
		||||
Woodcutting.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (LEAF BLOWER)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller (ABILITY)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller
 | 
			
		||||
Woodcutting.Effect.1=Make trees explode
 | 
			
		||||
Woodcutting.Effect.2=Leaf Blower
 | 
			
		||||
Woodcutting.Effect.3=Blow Away Leaves
 | 
			
		||||
 
 | 
			
		||||
@@ -75,7 +75,7 @@ Axes.Combat.GI.Proc=[[GREEN]]**STRUCK WITH GREAT FORCE**
 | 
			
		||||
Axes.Combat.GI.Struck=[[RED]]**HIT BY GREATER IMPACT**
 | 
			
		||||
Axes.Combat.SS.Struck=[[DARK_RED]]Struck by SKULL SPLITTER!
 | 
			
		||||
Axes.Combat.SS.Length=[[RED]]Skull Splitter Length: [[YELLOW]]{0}s
 | 
			
		||||
Axes.Effect.0=Skull Splitter (Ability)
 | 
			
		||||
Axes.Effect.0=Skull Splitter
 | 
			
		||||
Axes.Effect.1=Deal AoE Damage
 | 
			
		||||
Axes.Effect.2=Critical Strikes
 | 
			
		||||
Axes.Effect.3=Double Damage
 | 
			
		||||
@@ -97,7 +97,7 @@ Axes.Skillup=[[YELLOW]]Axes skill increased by {0}. Total ({1})
 | 
			
		||||
#EXCAVATION
 | 
			
		||||
Excavation.Ability.Lower=[[GRAY]]**YOU LOWER YOUR SHOVEL**
 | 
			
		||||
Excavation.Ability.Ready=[[GREEN]]**YOU READY YOUR SHOVEL**
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker (ABILITY)
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker
 | 
			
		||||
Excavation.Effect.1=3x Drop Rate, 3x EXP, +Speed
 | 
			
		||||
Excavation.Effect.2=Treasure Hunter
 | 
			
		||||
Excavation.Effect.3=Ability to dig for treasure
 | 
			
		||||
@@ -157,7 +157,7 @@ Herbalism.Ability.Lower=[[GRAY]]**YOU LOWER YOUR HOE**
 | 
			
		||||
Herbalism.Ability.Ready=[[GREEN]]**YOU READY YOUR HOE**
 | 
			
		||||
Herbalism.Ability.ShroomThumb.Chance=[[RED]]Shroom Thumb Chance: [[YELLOW]]{0}
 | 
			
		||||
Herbalism.Ability.ShroomThumb.Fail=[[RED]]**SHROOM THUMB FAIL**
 | 
			
		||||
Herbalism.Effect.0=Green Terra (ABILITY)
 | 
			
		||||
Herbalism.Effect.0=Green Terra
 | 
			
		||||
Herbalism.Effect.1=Spread the Terra, 3x Drops
 | 
			
		||||
Herbalism.Effect.2=Green Thumb (Wheat)
 | 
			
		||||
Herbalism.Effect.3=Auto-Plants crops when harvesting
 | 
			
		||||
@@ -188,7 +188,7 @@ Mining.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (BIGGER BOMBS)
 | 
			
		||||
Mining.Ability.Locked.2=LOCKED UNTIL {0}+ SKILL (DEMOLITIONS EXPERTISE)
 | 
			
		||||
Mining.Ability.Lower=[[GRAY]]**YOU LOWER YOUR PICKAXE**
 | 
			
		||||
Mining.Ability.Ready=[[GREEN]]**YOU READY YOUR PICKAXE**
 | 
			
		||||
Mining.Effect.0=Super Breaker (ABILITY)
 | 
			
		||||
Mining.Effect.0=Super Breaker
 | 
			
		||||
Mining.Effect.1=Speed+, Triple Drop Chance
 | 
			
		||||
Mining.Effect.2=Double Drops
 | 
			
		||||
Mining.Effect.3=Double the normal loot
 | 
			
		||||
@@ -301,7 +301,7 @@ Swords.Combat.Countered=[[GREEN]]**COUNTER-ATTACKED**
 | 
			
		||||
Swords.Combat.SS.Struck=[[DARK_RED]]Struck by SERRATED STRIKES!
 | 
			
		||||
Swords.Effect.0=Counter Attack
 | 
			
		||||
Swords.Effect.1=Reflect {0} of damage taken while blocking
 | 
			
		||||
Swords.Effect.2=Serrated Strikes (ABILITY)
 | 
			
		||||
Swords.Effect.2=Serrated Strikes
 | 
			
		||||
Swords.Effect.3={0} DMG AoE, Bleed+ AoE
 | 
			
		||||
Swords.Effect.4=Serrated Strikes Bleed+
 | 
			
		||||
Swords.Effect.5={0} Tick Bleed
 | 
			
		||||
@@ -379,7 +379,7 @@ Unarmed.Ability.IronGrip.Attacker=[[RED]]Your opponent has an iron grip!
 | 
			
		||||
Unarmed.Ability.IronGrip.Defender=[[GREEN]]Your iron grip kept you from being disarmed!
 | 
			
		||||
Unarmed.Ability.Lower=[[GRAY]]**YOU LOWER YOUR FISTS**
 | 
			
		||||
Unarmed.Ability.Ready=[[GREEN]]**YOU READY YOUR FISTS**
 | 
			
		||||
Unarmed.Effect.0=Berserk (ABILITY)
 | 
			
		||||
Unarmed.Effect.0=Berserk
 | 
			
		||||
Unarmed.Effect.1=+50% DMG, Breaks weak materials
 | 
			
		||||
Unarmed.Effect.2=Disarm (Players)
 | 
			
		||||
Unarmed.Effect.3=Drops the foes item held in hand
 | 
			
		||||
@@ -404,7 +404,7 @@ Woodcutting.Ability.1=Blow away leaves
 | 
			
		||||
Woodcutting.Ability.Chance.DDrop=[[RED]]Double Drop Chance: [[YELLOW]]{0}
 | 
			
		||||
Woodcutting.Ability.Length=[[RED]]Tree Feller Length: [[YELLOW]]{0}s
 | 
			
		||||
Woodcutting.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (LEAF BLOWER)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller (ABILITY)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller
 | 
			
		||||
Woodcutting.Effect.1=Make trees explode
 | 
			
		||||
Woodcutting.Effect.2=Leaf Blower
 | 
			
		||||
Woodcutting.Effect.3=Blow Away Leaves
 | 
			
		||||
@@ -709,6 +709,7 @@ XPRate.Event= [[GOLD]]mcMMO is currently in an XP rate event! XP rate is {0}x!
 | 
			
		||||
#EFFECTS
 | 
			
		||||
##generic
 | 
			
		||||
Effects.Effects=EFFECTS
 | 
			
		||||
Effects.SubSkills=SUB-SKILLS
 | 
			
		||||
Effects.Child=[[DARK_GRAY]]LVL: [[GREEN]]{0}
 | 
			
		||||
Effects.Level=[[DARK_GRAY]]LVL: [[GREEN]]{0} [[DARK_AQUA]]XP[[YELLOW]]([[GOLD]]{1}[[YELLOW]]/[[GOLD]]{2}[[YELLOW]])
 | 
			
		||||
Effects.Parent = [[GOLD]]{0} -
 | 
			
		||||
 
 | 
			
		||||
@@ -47,7 +47,7 @@ Axes.Skills.SS.Other.On=[[GREEN]]{0}[[DARK_GREEN]] heeft [[RED]]Schedel Splijter
 | 
			
		||||
Axes.Skillup=[[YELLOW]]Bijl ervaring toegenomen met {0}. Totaal ({1})
 | 
			
		||||
Excavation.Ability.Lower=[[GRAY]]**JE STOP JE SCHEP WEER WEG**
 | 
			
		||||
Excavation.Ability.Ready=[[GREEN]]**JE HOUDT JE SCHEP GEREED**
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breker (ABILITY)
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breker
 | 
			
		||||
Excavation.Effect.1=3x Drop Rate, 3x EXP, +Speed
 | 
			
		||||
Excavation.Effect.2=Schatten Jager
 | 
			
		||||
Excavation.Effect.3=Mogelijkheid om  te graven naar schatten
 | 
			
		||||
@@ -220,7 +220,7 @@ Woodcutting.Ability.0=Bladblazer
 | 
			
		||||
Woodcutting.Ability.1=Bladeren wegblazen
 | 
			
		||||
Woodcutting.Ability.Length=[[RED]] Boom Feller Lengte: [[GEEL]]{0}s
 | 
			
		||||
Woodcutting.Ability.Locked.0=Vergrendeld totdat {0}+ VAARDIGHEID (BLADBLAZER)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller (ABILITY)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller
 | 
			
		||||
Woodcutting.Effect.1=Laat bomen ontploffen
 | 
			
		||||
Woodcutting.Effect.2=Bladblazer
 | 
			
		||||
Woodcutting.Effect.3=Blaas alle bladeren weg
 | 
			
		||||
 
 | 
			
		||||
@@ -69,7 +69,7 @@ Swords.Combat.Bleeding=[[GREEN]]**FIENDEN BL\u00d6DER**
 | 
			
		||||
Swords.Combat.Counter.Hit=[[DARK_RED]]Tr\u00e4ff med en motattack
 | 
			
		||||
Swords.Combat.Countered=[[GREEN]]**MOTATTACK**
 | 
			
		||||
Swords.Combat.SS.Struck=[[DARK_RED]]Tr\u00e4ffad av S\u00c5GTANDAT SLAG:
 | 
			
		||||
Swords.Effect.2=Bl\u00f6dande slag (ABILITY)
 | 
			
		||||
Swords.Effect.2=Bl\u00f6dande slag
 | 
			
		||||
Swords.Effect.4=S\u00e5gtandat slag bl\u00f6dning+
 | 
			
		||||
Swords.Listener=Sv\u00e4rd:
 | 
			
		||||
Swords.SkillName=SV\u00c4RD
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ Axes.Combat.CriticalHit=[[RED]]\u0e42\u0e08\u0e21\u0e15\u0e35 CRITICAL!
 | 
			
		||||
Axes.Combat.GI.Proc=[[GREEN]]**\u0e17\u0e33\u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e22\u0e2b\u0e32\u0e22\u0e14\u0e49\u0e27\u0e22 GREAT FORCE**
 | 
			
		||||
Axes.Combat.GI.Struck=[[RED]]**\u0e42\u0e08\u0e21\u0e15\u0e35\u0e14\u0e49\u0e27\u0e22 GREATER IMPACT**
 | 
			
		||||
Axes.Combat.SS.Length=[[RED]]Skull Splitter \u0e21\u0e35\u0e23\u0e30\u0e22\u0e30\u0e40\u0e27\u0e25\u0e32: [[YELLOW]]{0}\u0e27\u0e34\u0e19\u0e32\u0e17\u0e35
 | 
			
		||||
Axes.Effect.0=Skull Splitter (Ability)
 | 
			
		||||
Axes.Effect.0=Skull Splitter
 | 
			
		||||
Axes.Effect.1=\u0e17\u0e33\u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e22\u0e2b\u0e32\u0e22\u0e27\u0e07\u0e01\u0e27\u0e49\u0e32\u0e07
 | 
			
		||||
Axes.Effect.2=Critical Strikes
 | 
			
		||||
Axes.Effect.3=\u0e01\u0e32\u0e23\u0e42\u0e08\u0e21\u0e15\u0e35\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e02\u0e36\u0e49\u0e19
 | 
			
		||||
@@ -59,7 +59,7 @@ Axes.Skills.SS.Other.On=[[GREEN]]{0}[[DARK_GREEN]] \u0e44\u0e14\u0e49\u0e43\u0e0
 | 
			
		||||
Axes.Skillup=[[YELLOW]]\u0e17\u0e31\u0e01\u0e29\u0e30 Axes \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e02\u0e36\u0e49\u0e19 {0}. \u0e21\u0e35\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14 ({1})
 | 
			
		||||
Excavation.Ability.Lower=[[GRAY]]**\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 Shovel**
 | 
			
		||||
Excavation.Ability.Ready=[[GREEN]]**\u0e04\u0e38\u0e13\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e17\u0e35\u0e48\u0e08\u0e30\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 Shovel**
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker (ABILITY)
 | 
			
		||||
Excavation.Effect.0=Giga Drill Breaker
 | 
			
		||||
Excavation.Effect.1=\u0e2d\u0e31\u0e15\u0e23\u0e32\u0e14\u0e23\u0e2d\u0e1b 3x , EXP 3x, +\u0e04\u0e27\u0e32\u0e21\u0e40\u0e23\u0e47\u0e27
 | 
			
		||||
Excavation.Effect.2=Treasure Hunter
 | 
			
		||||
Excavation.Effect.3=\u0e04\u0e27\u0e32\u0e21\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e43\u0e19\u0e01\u0e32\u0e23\u0e02\u0e38\u0e14\u0e2b\u0e32\u0e2a\u0e21\u0e1a\u0e31\u0e15\u0e34
 | 
			
		||||
@@ -111,7 +111,7 @@ Herbalism.Ability.Lower=[[GRAY]]**\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e01\u0e
 | 
			
		||||
Herbalism.Ability.Ready=[[GREEN]]**\u0e04\u0e38\u0e13\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e17\u0e35\u0e48\u0e08\u0e30\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 Hoe**
 | 
			
		||||
Herbalism.Ability.ShroomThumb.Chance=[[RED]]Shroom Thumb \u0e42\u0e2d\u0e01\u0e32\u0e2a: [[YELLOW]]{0}
 | 
			
		||||
Herbalism.Ability.ShroomThumb.Fail=[[RED]]**SHROOM THUMB \u0e25\u0e49\u0e21\u0e40\u0e2b\u0e25\u0e27**
 | 
			
		||||
Herbalism.Effect.0=Green Terra (ABILITY)
 | 
			
		||||
Herbalism.Effect.0=Green Terra
 | 
			
		||||
Herbalism.Effect.1=\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e2d\u0e31\u0e15\u0e23\u0e32\u0e01\u0e32\u0e23\u0e14\u0e23\u0e2d\u0e1b x3
 | 
			
		||||
Herbalism.Effect.2=Green Thumb (\u0e02\u0e49\u0e32\u0e27\u0e40\u0e17\u0e48\u0e32\u0e19\u0e31\u0e49\u0e19)
 | 
			
		||||
Herbalism.Effect.3=\u0e1e\u0e37\u0e0a\u0e42\u0e15\u0e2d\u0e31\u0e15\u0e42\u0e19\u0e21\u0e31\u0e15\u0e34\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e40\u0e01\u0e47\u0e1a\u0e40\u0e01\u0e35\u0e48\u0e22\u0e27
 | 
			
		||||
@@ -138,7 +138,7 @@ Mining.Ability.Locked.1=\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e1b\u0e25\u0e14\u
 | 
			
		||||
Mining.Ability.Locked.2=\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e1b\u0e25\u0e14\u0e25\u0e47\u0e2d\u0e01\u0e44\u0e14\u0e49\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e23\u0e30\u0e14\u0e31\u0e1a {0}+ (DEMOLITIONS EXPERTISE)
 | 
			
		||||
Mining.Ability.Lower=[[GRAY]]**\u0e22\u0e01\u0e40\u0e25\u0e34\u0e01\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 Pickaxe**
 | 
			
		||||
Mining.Ability.Ready=[[GREEN]]**\u0e04\u0e38\u0e13\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e17\u0e35\u0e48\u0e08\u0e30\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 Pickaxe**
 | 
			
		||||
Mining.Effect.0=Super Breaker (ABILITY)
 | 
			
		||||
Mining.Effect.0=Super Breaker
 | 
			
		||||
Mining.Effect.1=+\u0e04\u0e27\u0e32\u0e21\u0e40\u0e23\u0e47\u0e27, \u0e40\u0e1e\u0e34\u0e48\u0e21\u0e42\u0e2d\u0e01\u0e32\u0e2a\u0e14\u0e23\u0e2d\u0e1b x3
 | 
			
		||||
Mining.Effect.2=Drops x2
 | 
			
		||||
Mining.Effect.3=\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e2d\u0e31\u0e04\u0e23\u0e32\u0e01\u0e32\u0e23 Drops
 | 
			
		||||
@@ -223,7 +223,7 @@ Swords.Combat.Counter.Hit=[[DARK_RED]]\u0e42\u0e08\u0e21\u0e15\u0e35\u0e14\u0e49
 | 
			
		||||
Swords.Combat.Countered=[[GREEN]]**\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30 COUNTER-ATTACKED**
 | 
			
		||||
Swords.Combat.SS.Struck=[[DARK_RED]]\u0e23\u0e39\u0e49\u0e2a\u0e36\u0e01\u0e21\u0e36\u0e19\u0e07\u0e07 \u0e40\u0e1e\u0e23\u0e32\u0e30 \u0e17\u0e31\u0e01\u0e29\u0e30 SERRATED STRIKES!
 | 
			
		||||
Swords.Effect.0=Counter Attack
 | 
			
		||||
Swords.Effect.2=Serrated Strikes (ABILITY)
 | 
			
		||||
Swords.Effect.2=Serrated Strikes
 | 
			
		||||
Swords.Effect.3={0} \u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e22\u0e2b\u0e32\u0e22\u0e01\u0e23\u0e30\u0e08\u0e32\u0e22, \u0e40\u0e25\u0e37\u0e2d\u0e14\u0e44\u0e2b\u0e25+ \u0e01\u0e23\u0e30\u0e08\u0e32\u0e22
 | 
			
		||||
Swords.Effect.4=Serrated Strikes Bleed+
 | 
			
		||||
Swords.Effect.5={0} Tick \u0e15\u0e48\u0e2d\u0e01\u0e32\u0e23\u0e40\u0e25\u0e37\u0e2d\u0e14\u0e44\u0e2b\u0e25
 | 
			
		||||
@@ -295,7 +295,7 @@ Unarmed.Ability.IronGrip.Attacker=[[RED]]\u0e1d\u0e48\u0e32\u0e22\u0e15\u0e23\u0
 | 
			
		||||
Unarmed.Ability.IronGrip.Defender=[[GREEN]]Iron grip \u0e17\u0e33\u0e43\u0e2b\u0e49\u0e04\u0e38\u0e13\u0e44\u0e21\u0e48\u0e44\u0e14\u0e49\u0e23\u0e31\u0e1a\u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e22\u0e2b\u0e32\u0e22!
 | 
			
		||||
Unarmed.Ability.Lower=[[GRAY]]**\u0e04\u0e38\u0e13\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e17\u0e35\u0e48\u0e08\u0e30\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 \u0e21\u0e37\u0e2d**
 | 
			
		||||
Unarmed.Ability.Ready=[[GREEN]]**\u0e04\u0e38\u0e13\u0e1e\u0e23\u0e49\u0e2d\u0e21\u0e17\u0e35\u0e48\u0e08\u0e30\u0e43\u0e0a\u0e49\u0e17\u0e31\u0e01\u0e29\u0e30\u0e02\u0e2d\u0e07 \u0e21\u0e37\u0e2d**
 | 
			
		||||
Unarmed.Effect.0=Berserk (ABILITY)
 | 
			
		||||
Unarmed.Effect.0=Berserk
 | 
			
		||||
Unarmed.Effect.1=\u0e40\u0e1e\u0e34\u0e48\u0e21\u0e01\u0e32\u0e23\u0e17\u0e33\u0e04\u0e27\u0e32\u0e21\u0e40\u0e2a\u0e35\u0e22\u0e2b\u0e32\u0e22 +50%, \u0e17\u0e33\u0e25\u0e32\u0e22\u0e27\u0e31\u0e15\u0e16\u0e38\u0e17\u0e35\u0e48\u0e2d\u0e48\u0e2d\u0e19
 | 
			
		||||
Unarmed.Effect.2=Disarm (Players)
 | 
			
		||||
Unarmed.Effect.3=\u0e02\u0e42\u0e21\u0e22\u0e2a\u0e34\u0e48\u0e07\u0e02\u0e2d\u0e07\u0e43\u0e19\u0e21\u0e37\u0e2d\u0e02\u0e2d\u0e07\u0e1c\u0e39\u0e49\u0e40\u0e25\u0e48\u0e19
 | 
			
		||||
@@ -318,7 +318,7 @@ Woodcutting.Ability.1=\u0e17\u0e33\u0e25\u0e32\u0e22\u0e43\u0e1a\u0e44\u0e21\u0e
 | 
			
		||||
Woodcutting.Ability.Chance.DDrop=[[RED]]Double Drop \u0e42\u0e2d\u0e01\u0e32\u0e2a: [[YELLOW]]{0}
 | 
			
		||||
Woodcutting.Ability.Length=[[RED]]Tree Feller \u0e21\u0e35\u0e23\u0e30\u0e22\u0e30\u0e40\u0e27\u0e25\u0e32: [[YELLOW]]{0}\u0e27\u0e34\u0e19\u0e32\u0e17\u0e35
 | 
			
		||||
Woodcutting.Ability.Locked.0=\u0e2a\u0e32\u0e21\u0e32\u0e23\u0e16\u0e1b\u0e25\u0e14\u0e25\u0e47\u0e2d\u0e01\u0e44\u0e14\u0e49\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e23\u0e30\u0e14\u0e31\u0e1a {0}+ (LEAF BLOWER)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller (ABILITY)
 | 
			
		||||
Woodcutting.Effect.0=Tree Feller
 | 
			
		||||
Woodcutting.Effect.1=\u0e17\u0e33\u0e43\u0e2b\u0e49\u0e15\u0e49\u0e19\u0e44\u0e21\u0e49\u0e23\u0e30\u0e40\u0e1a\u0e34\u0e14
 | 
			
		||||
Woodcutting.Effect.2=Leaf Blower
 | 
			
		||||
Woodcutting.Effect.3=\u0e17\u0e33\u0e25\u0e32\u0e22\u0e43\u0e1a\u0e44\u0e21\u0e49\u0e2d\u0e2d\u0e01
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user