123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- package com.gmail.nossr50.util.skills;
- import com.gmail.nossr50.api.exceptions.InvalidSkillException;
- import com.gmail.nossr50.config.experience.ExperienceConfig;
- import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
- import com.gmail.nossr50.datatypes.skills.SubSkillType;
- import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
- import com.gmail.nossr50.datatypes.skills.ToolType;
- import com.gmail.nossr50.locale.LocaleLoader;
- import com.gmail.nossr50.mcMMO;
- import com.gmail.nossr50.util.Permissions;
- import com.gmail.nossr50.util.text.StringUtils;
- import com.google.common.collect.ImmutableList;
- import com.google.common.collect.ImmutableMap;
- import com.google.common.collect.ImmutableSet;
- import org.bukkit.entity.Entity;
- import org.bukkit.entity.Player;
- import org.bukkit.entity.Tameable;
- import org.jetbrains.annotations.NotNull;
- import org.jetbrains.annotations.VisibleForTesting;
- import java.util.*;
- public class SkillTools {
- private final mcMMO pluginRef;
- //TODO: Figure out which ones we don't need, this was copy pasted from a diff branch
- public final @NotNull ImmutableList<String> LOCALIZED_SKILL_NAMES;
- public final @NotNull ImmutableList<String> FORMATTED_SUBSKILL_NAMES;
- public final @NotNull ImmutableSet<String> EXACT_SUBSKILL_NAMES;
- public final @NotNull ImmutableList<PrimarySkillType> CHILD_SKILLS;
- public final static @NotNull ImmutableList<PrimarySkillType> NON_CHILD_SKILLS;
- public final @NotNull ImmutableList<PrimarySkillType> COMBAT_SKILLS;
- public final @NotNull ImmutableList<PrimarySkillType> GATHERING_SKILLS;
- public final @NotNull ImmutableList<PrimarySkillType> MISC_SKILLS;
- private final @NotNull ImmutableMap<SubSkillType, PrimarySkillType> subSkillParentRelationshipMap;
- private final @NotNull ImmutableMap<SuperAbilityType, PrimarySkillType> superAbilityParentRelationshipMap;
- private final @NotNull ImmutableMap<PrimarySkillType, Set<SubSkillType>> primarySkillChildrenMap;
- // The map below is for the super abilities which require readying a tool, its everything except blast mining
- private final ImmutableMap<PrimarySkillType, SuperAbilityType> mainActivatedAbilityChildMap;
- private final ImmutableMap<PrimarySkillType, ToolType> primarySkillToolMap;
- static {
- ArrayList<PrimarySkillType> tempNonChildSkills = new ArrayList<>();
- for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
- if (primarySkillType != PrimarySkillType.SALVAGE && primarySkillType != PrimarySkillType.SMELTING)
- tempNonChildSkills.add(primarySkillType);
- }
- NON_CHILD_SKILLS = ImmutableList.copyOf(tempNonChildSkills);
- }
- public SkillTools(@NotNull mcMMO pluginRef) {
- this.pluginRef = pluginRef;
- /*
- * Setup subskill -> parent relationship map
- */
- EnumMap<SubSkillType, PrimarySkillType> tempSubParentMap = new EnumMap<>(SubSkillType.class);
- //Super hacky and disgusting
- for(PrimarySkillType primarySkillType1 : PrimarySkillType.values()) {
- for(SubSkillType subSkillType : SubSkillType.values()) {
- String[] splitSubSkillName = subSkillType.toString().split("_");
- if(primarySkillType1.toString().equalsIgnoreCase(splitSubSkillName[0])) {
- //Parent Skill Found
- tempSubParentMap.put(subSkillType, primarySkillType1);
- }
- }
- }
- subSkillParentRelationshipMap = ImmutableMap.copyOf(tempSubParentMap);
- /*
- * Setup primary -> (collection) subskill map
- */
- EnumMap<PrimarySkillType, Set<SubSkillType>> tempPrimaryChildMap = new EnumMap<>(PrimarySkillType.class);
- //Init the empty Hash Sets
- for(PrimarySkillType primarySkillType1 : PrimarySkillType.values()) {
- tempPrimaryChildMap.put(primarySkillType1, new HashSet<>());
- }
- //Fill in the hash sets
- for(SubSkillType subSkillType : SubSkillType.values()) {
- PrimarySkillType parentSkill = subSkillParentRelationshipMap.get(subSkillType);
- //Add this subskill as a child
- tempPrimaryChildMap.get(parentSkill).add(subSkillType);
- }
- primarySkillChildrenMap = ImmutableMap.copyOf(tempPrimaryChildMap);
- /*
- * Setup primary -> tooltype map
- */
- EnumMap<PrimarySkillType, ToolType> tempToolMap = new EnumMap<>(PrimarySkillType.class);
- tempToolMap.put(PrimarySkillType.AXES, ToolType.AXE);
- tempToolMap.put(PrimarySkillType.WOODCUTTING, ToolType.AXE);
- tempToolMap.put(PrimarySkillType.UNARMED, ToolType.FISTS);
- tempToolMap.put(PrimarySkillType.SWORDS, ToolType.SWORD);
- tempToolMap.put(PrimarySkillType.EXCAVATION, ToolType.SHOVEL);
- tempToolMap.put(PrimarySkillType.HERBALISM, ToolType.HOE);
- tempToolMap.put(PrimarySkillType.MINING, ToolType.PICKAXE);
- primarySkillToolMap = ImmutableMap.copyOf(tempToolMap);
- /*
- * Setup ability -> primary map
- * Setup primary -> ability map
- */
- EnumMap<SuperAbilityType, PrimarySkillType> tempAbilityParentRelationshipMap = new EnumMap<>(SuperAbilityType.class);
- EnumMap<PrimarySkillType, SuperAbilityType> tempMainActivatedAbilityChildMap = new EnumMap<>(PrimarySkillType.class);
- for(SuperAbilityType superAbilityType : SuperAbilityType.values()) {
- try {
- PrimarySkillType parent = getSuperAbilityParent(superAbilityType);
- tempAbilityParentRelationshipMap.put(superAbilityType, parent);
- if(superAbilityType != SuperAbilityType.BLAST_MINING) {
- //This map is used only for abilities that have a tool readying phase, so blast mining is ignored
- tempMainActivatedAbilityChildMap.put(parent, superAbilityType);
- }
- } catch (InvalidSkillException e) {
- e.printStackTrace();
- }
- }
- superAbilityParentRelationshipMap = ImmutableMap.copyOf(tempAbilityParentRelationshipMap);
- mainActivatedAbilityChildMap = ImmutableMap.copyOf(tempMainActivatedAbilityChildMap);
- /*
- * Build child skill and nonchild skill lists
- */
- List<PrimarySkillType> childSkills = new ArrayList<>();
- // List<PrimarySkillType> nonChildSkills = new ArrayList<>();
- for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
- if (isChildSkill(primarySkillType))
- childSkills.add(primarySkillType);
- // } {
- // nonChildSkills.add(primarySkillType);
- // }
- }
- CHILD_SKILLS = ImmutableList.copyOf(childSkills);
- // NON_CHILD_SKILLS = ImmutableList.copyOf(nonChildSkills);
- /*
- * Build categorized skill lists
- */
- COMBAT_SKILLS = ImmutableList.of(PrimarySkillType.ARCHERY, PrimarySkillType.AXES, PrimarySkillType.SWORDS, PrimarySkillType.TAMING, PrimarySkillType.UNARMED);
- GATHERING_SKILLS = ImmutableList.of(PrimarySkillType.EXCAVATION, PrimarySkillType.FISHING, PrimarySkillType.HERBALISM, PrimarySkillType.MINING, PrimarySkillType.WOODCUTTING);
- MISC_SKILLS = ImmutableList.of(PrimarySkillType.ACROBATICS, PrimarySkillType.ALCHEMY, PrimarySkillType.REPAIR, PrimarySkillType.SALVAGE, PrimarySkillType.SMELTING);
- /*
- * Build formatted/localized/etc string lists
- */
- LOCALIZED_SKILL_NAMES = ImmutableList.copyOf(buildLocalizedPrimarySkillNames());
- FORMATTED_SUBSKILL_NAMES = ImmutableList.copyOf(buildFormattedSubSkillNameList());
- EXACT_SUBSKILL_NAMES = ImmutableSet.copyOf(buildExactSubSkillNameList());
- }
- private @NotNull PrimarySkillType getSuperAbilityParent(SuperAbilityType superAbilityType) throws InvalidSkillException {
- return switch (superAbilityType) {
- case BERSERK -> PrimarySkillType.UNARMED;
- case GREEN_TERRA -> PrimarySkillType.HERBALISM;
- case TREE_FELLER -> PrimarySkillType.WOODCUTTING;
- case SUPER_BREAKER, BLAST_MINING -> PrimarySkillType.MINING;
- case SKULL_SPLITTER -> PrimarySkillType.AXES;
- case SERRATED_STRIKES -> PrimarySkillType.SWORDS;
- case GIGA_DRILL_BREAKER -> PrimarySkillType.EXCAVATION;
- case SUPER_SHOTGUN -> PrimarySkillType.CROSSBOWS;
- case TRIDENT_ABILITY -> PrimarySkillType.TRIDENTS;
- default ->
- throw new InvalidSkillException("No parent defined for super ability! " + superAbilityType.toString());
- };
- }
- /**
- * Makes a list of the "nice" version of sub skill names
- * Used in tab completion mostly
- * @return a list of formatted sub skill names
- */
- private @NotNull ArrayList<String> buildFormattedSubSkillNameList() {
- ArrayList<String> subSkillNameList = new ArrayList<>();
- for(SubSkillType subSkillType : SubSkillType.values()) {
- subSkillNameList.add(subSkillType.getNiceNameNoSpaces(subSkillType));
- }
- return subSkillNameList;
- }
- private @NotNull HashSet<String> buildExactSubSkillNameList() {
- HashSet<String> subSkillNameExactSet = new HashSet<>();
- for(SubSkillType subSkillType : SubSkillType.values()) {
- subSkillNameExactSet.add(subSkillType.toString());
- }
- return subSkillNameExactSet;
- }
- /**
- * Builds a list of localized {@link PrimarySkillType} names
- * @return list of localized {@link PrimarySkillType} names
- */
- @VisibleForTesting
- private @NotNull ArrayList<String> buildLocalizedPrimarySkillNames() {
- ArrayList<String> localizedSkillNameList = new ArrayList<>();
- for(PrimarySkillType primarySkillType : PrimarySkillType.values()) {
- localizedSkillNameList.add(getLocalizedSkillName(primarySkillType));
- }
- Collections.sort(localizedSkillNameList);
- return localizedSkillNameList;
- }
- /**
- * Matches a string of a skill to a skill
- * This is NOT case sensitive
- * First it checks the locale file and tries to match by the localized name of the skill
- * Then if nothing is found it checks against the hard coded "name" of the skill, which is just its name in English
- *
- * @param skillName target skill name
- * @return the matching PrimarySkillType if one is found, otherwise null
- */
- public PrimarySkillType matchSkill(String skillName) {
- if (!pluginRef.getGeneralConfig().getLocale().equalsIgnoreCase("en_US")) {
- for (PrimarySkillType type : PrimarySkillType.values()) {
- if (skillName.equalsIgnoreCase(LocaleLoader.getString(StringUtils.getCapitalized(type.name()) + ".SkillName"))) {
- return type;
- }
- }
- }
- for (PrimarySkillType type : PrimarySkillType.values()) {
- if (type.name().equalsIgnoreCase(skillName)) {
- return type;
- }
- }
- if (!skillName.equalsIgnoreCase("all")) {
- pluginRef.getLogger().warning("Invalid mcMMO skill (" + skillName + ")"); //TODO: Localize
- }
- return null;
- }
- /**
- * Gets the PrimarySkillStype to which a SubSkillType belongs
- * Return null if it does not belong to one.. which should be impossible in most circumstances
- * @param subSkillType target subskill
- * @return the PrimarySkillType of this SubSkill, null if it doesn't exist
- */
- public PrimarySkillType getPrimarySkillBySubSkill(SubSkillType subSkillType) {
- return subSkillParentRelationshipMap.get(subSkillType);
- }
- /**
- * Gets the PrimarySkillStype to which a SuperAbilityType belongs
- * Return null if it does not belong to one.. which should be impossible in most circumstances
- * @param superAbilityType target super ability
- * @return the PrimarySkillType of this SuperAbilityType, null if it doesn't exist
- */
- public PrimarySkillType getPrimarySkillBySuperAbility(SuperAbilityType superAbilityType) {
- return superAbilityParentRelationshipMap.get(superAbilityType);
- }
- public SuperAbilityType getSuperAbility(PrimarySkillType primarySkillType) {
- if(mainActivatedAbilityChildMap.get(primarySkillType) == null)
- return null;
- return mainActivatedAbilityChildMap.get(primarySkillType);
- }
- public boolean isSuperAbilityUnlocked(PrimarySkillType primarySkillType, Player player) {
- SuperAbilityType superAbilityType = mcMMO.p.getSkillTools().getSuperAbility(primarySkillType);
- SubSkillType subSkillType = superAbilityType.getSubSkillTypeDefinition();
- return RankUtils.hasUnlockedSubskill(player, subSkillType);
- }
- public boolean getPVPEnabled(PrimarySkillType primarySkillType) {
- return pluginRef.getGeneralConfig().getPVPEnabled(primarySkillType);
- }
- public boolean getPVEEnabled(PrimarySkillType primarySkillType) {
- return pluginRef.getGeneralConfig().getPVEEnabled(primarySkillType);
- }
- public boolean getHardcoreStatLossEnabled(PrimarySkillType primarySkillType) {
- return pluginRef.getGeneralConfig().getHardcoreStatLossEnabled(primarySkillType);
- }
- public boolean getHardcoreVampirismEnabled(PrimarySkillType primarySkillType) {
- return pluginRef.getGeneralConfig().getHardcoreVampirismEnabled(primarySkillType);
- }
- public ToolType getPrimarySkillToolType(PrimarySkillType primarySkillType) {
- return primarySkillToolMap.get(primarySkillType);
- }
- public Set<SubSkillType> getSubSkills(PrimarySkillType primarySkillType) {
- //TODO: Cache this!
- return primarySkillChildrenMap.get(primarySkillType);
- }
- public double getXpModifier(PrimarySkillType primarySkillType) {
- return ExperienceConfig.getInstance().getFormulaSkillModifier(primarySkillType);
- }
- // TODO: This is a little "hacky", we probably need to add something to distinguish child skills in the enum, or to use another enum for them
- public static boolean isChildSkill(PrimarySkillType primarySkillType) {
- switch (primarySkillType) {
- case SALVAGE:
- case SMELTING:
- return true;
- default:
- return false;
- }
- }
- /**
- * Get the localized name for a {@link PrimarySkillType}
- * @param primarySkillType target {@link PrimarySkillType}
- * @return the localized name for a {@link PrimarySkillType}
- */
- public String getLocalizedSkillName(PrimarySkillType primarySkillType) {
- //TODO: Replace with current impl
- return StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(primarySkillType.toString()) + ".SkillName"));
- }
- public boolean doesPlayerHaveSkillPermission(Player player, PrimarySkillType primarySkillType) {
- return Permissions.skillEnabled(player, primarySkillType);
- }
- public boolean canCombatSkillsTrigger(PrimarySkillType primarySkillType, Entity target) {
- return (target instanceof Player || (target instanceof Tameable && ((Tameable) target).isTamed())) ? getPVPEnabled(primarySkillType) : getPVEEnabled(primarySkillType);
- }
- public String getCapitalizedPrimarySkillName(PrimarySkillType primarySkillType) {
- return StringUtils.getCapitalized(primarySkillType.toString());
- }
- public int getSuperAbilityCooldown(SuperAbilityType superAbilityType) {
- return pluginRef.getGeneralConfig().getCooldown(superAbilityType);
- }
- public int getSuperAbilityMaxLength(SuperAbilityType superAbilityType) {
- return pluginRef.getGeneralConfig().getMaxLength(superAbilityType);
- }
- public String getSuperAbilityOnLocaleKey(SuperAbilityType superAbilityType) {
- return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".On";
- }
- public String getSuperAbilityOffLocaleKey(SuperAbilityType superAbilityType) {
- return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Off";
- }
- public String getSuperAbilityOtherPlayerActivationLocaleKey(SuperAbilityType superAbilityType) {
- return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Other.On";
- }
- public String getSuperAbilityOtherPlayerDeactivationLocaleKey(SuperAbilityType superAbilityType) {
- return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + "Other.Off";
- }
- public String getSuperAbilityRefreshedLocaleKey(SuperAbilityType superAbilityType) {
- return "SuperAbility." + StringUtils.getPrettyCamelCaseName(superAbilityType) + ".Refresh";
- }
- public int getLevelCap(@NotNull PrimarySkillType primarySkillType) {
- return mcMMO.p.getGeneralConfig().getLevelCap(primarySkillType);
- }
- /**
- * Get the permissions for this ability.
- *
- * @param player Player to check permissions for
- * @param superAbilityType target super ability
- * @return true if the player has permissions, false otherwise
- */
- public boolean superAbilityPermissionCheck(SuperAbilityType superAbilityType, Player player) {
- switch (superAbilityType) {
- case BERSERK:
- return Permissions.berserk(player);
- case BLAST_MINING:
- return Permissions.remoteDetonation(player);
- case GIGA_DRILL_BREAKER:
- return Permissions.gigaDrillBreaker(player);
- case GREEN_TERRA:
- return Permissions.greenTerra(player);
- case SERRATED_STRIKES:
- return Permissions.serratedStrikes(player);
- case SKULL_SPLITTER:
- return Permissions.skullSplitter(player);
- case SUPER_BREAKER:
- return Permissions.superBreaker(player);
- case TREE_FELLER:
- return Permissions.treeFeller(player);
- default:
- return false;
- }
- }
- public @NotNull List<PrimarySkillType> getChildSkills() {
- return CHILD_SKILLS;
- }
- public @NotNull ImmutableList<PrimarySkillType> getNonChildSkills() {
- return NON_CHILD_SKILLS;
- }
- public @NotNull ImmutableList<PrimarySkillType> getCombatSkills() {
- return COMBAT_SKILLS;
- }
- public @NotNull ImmutableList<PrimarySkillType> getGatheringSkills() {
- return GATHERING_SKILLS;
- }
- public @NotNull ImmutableList<PrimarySkillType> getMiscSkills() {
- return MISC_SKILLS;
- }
- }
|