Unlimited custom xp perks Part 1

This commit is contained in:
nossr50
2019-05-08 06:44:19 -07:00
parent 0331c98c9b
commit 40598a0e96
52 changed files with 1579 additions and 1543 deletions

View File

@@ -171,6 +171,7 @@ public final class BlockUtils {
/**
* Whether or not a block is gathered via Pickaxes
*
* @param material target blocks material
* @return
*/

View File

@@ -7,9 +7,8 @@ import java.util.HashSet;
/**
* Stores hash tables for item and block names
* This allows for better support across multiple versions of Minecraft
*
* <p>
* This is a temporary class, mcMMO is spaghetti and I'l clean it up later
*
*/
public class MaterialMapStore {
@@ -22,8 +21,7 @@ public class MaterialMapStore {
private HashSet<String> canMakeShroomyWhiteList;
private HashSet<String> multiBlockEntities;
public MaterialMapStore()
{
public MaterialMapStore() {
abilityBlackList = new HashSet<>();
toolBlackList = new HashSet<>();
mossyWhiteList = new HashSet<>();
@@ -36,48 +34,39 @@ public class MaterialMapStore {
fillHardcodedHashSets();
}
public boolean isMultiBlock(Material material)
{
public boolean isMultiBlock(Material material) {
return multiBlockEntities.contains(material.getKey().getKey());
}
public boolean isAbilityActivationBlackListed(Material material)
{
public boolean isAbilityActivationBlackListed(Material material) {
return abilityBlackList.contains(material.getKey().getKey());
}
public boolean isToolActivationBlackListed(Material material)
{
public boolean isToolActivationBlackListed(Material material) {
return toolBlackList.contains(material.getKey().getKey());
}
public boolean isMossyWhiteListed(Material material)
{
public boolean isMossyWhiteListed(Material material) {
return mossyWhiteList.contains(material.getKey().getKey());
}
public boolean isLeavesWhiteListed(Material material)
{
public boolean isLeavesWhiteListed(Material material) {
return leavesWhiteList.contains(material.getKey().getKey());
}
public boolean isHerbalismAbilityWhiteListed(Material material)
{
public boolean isHerbalismAbilityWhiteListed(Material material) {
return herbalismAbilityBlackList.contains(material.getKey().getKey());
}
public boolean isBlockCrackerWhiteListed(Material material)
{
public boolean isBlockCrackerWhiteListed(Material material) {
return blockCrackerWhiteList.contains(material.getKey().getKey());
}
public boolean isShroomyWhiteListed(Material material)
{
public boolean isShroomyWhiteListed(Material material) {
return canMakeShroomyWhiteList.contains(material.getKey().getKey());
}
private void fillHardcodedHashSets()
{
private void fillHardcodedHashSets() {
fillAbilityBlackList();
filltoolBlackList();
fillMossyWhiteList();
@@ -88,8 +77,7 @@ public class MaterialMapStore {
fillMultiBlockEntitiesList();
}
private void fillMultiBlockEntitiesList()
{
private void fillMultiBlockEntitiesList() {
multiBlockEntities.add("cactus");
multiBlockEntities.add("chorus_plant");
multiBlockEntities.add("sugar_cane");
@@ -100,28 +88,24 @@ public class MaterialMapStore {
multiBlockEntities.add("bamboo");
}
private void fillShroomyWhiteList()
{
private void fillShroomyWhiteList() {
canMakeShroomyWhiteList.add("dirt");
canMakeShroomyWhiteList.add("grass");
canMakeShroomyWhiteList.add("grass_path");
}
private void fillBlockCrackerWhiteList()
{
private void fillBlockCrackerWhiteList() {
blockCrackerWhiteList.add("stone_bricks");
}
private void fillHerbalismAbilityBlackList()
{
private void fillHerbalismAbilityBlackList() {
herbalismAbilityBlackList.add("dirt");
herbalismAbilityBlackList.add("grass");
herbalismAbilityBlackList.add("grass_path");
herbalismAbilityBlackList.add("farmland");
}
private void fillLeavesWhiteList()
{
private void fillLeavesWhiteList() {
leavesWhiteList.add("oak_leaves");
leavesWhiteList.add("acacia_leaves");
leavesWhiteList.add("birch_leaves");
@@ -130,8 +114,7 @@ public class MaterialMapStore {
leavesWhiteList.add("spruce_leaves");
}
private void fillMossyWhiteList()
{
private void fillMossyWhiteList() {
mossyWhiteList.add("cobblestone");
mossyWhiteList.add("dirt");
mossyWhiteList.add("grass_path");
@@ -139,8 +122,7 @@ public class MaterialMapStore {
mossyWhiteList.add("cobblestone_wall");
}
private void fillAbilityBlackList()
{
private void fillAbilityBlackList() {
abilityBlackList.add("black_bed");
abilityBlackList.add("blue_bed");
abilityBlackList.add("brown_bed");
@@ -239,9 +221,8 @@ public class MaterialMapStore {
abilityBlackList.add("wall_sign"); //1.13 and lower?
abilityBlackList.add("sign"); //1.13 and lower?
}
private void filltoolBlackList()
{
private void filltoolBlackList() {
//TODO: Add anvils / missing logs
toolBlackList.add("black_bed");
toolBlackList.add("blue_bed");
@@ -364,8 +345,7 @@ public class MaterialMapStore {
toolBlackList.add("spruce_wood");
}
private void addToHashSet(String string, HashSet<String> stringHashSet)
{
private void addToHashSet(String string, HashSet<String> stringHashSet) {
stringHashSet.add(string.toLowerCase());
}
}

View File

@@ -1,6 +1,7 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.commands.party.PartySubcommandType;
import com.gmail.nossr50.datatypes.experience.CustomXPPerk;
import com.gmail.nossr50.datatypes.skills.ItemMaterialCategory;
import com.gmail.nossr50.datatypes.skills.ItemType;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -233,7 +234,9 @@ public final class Permissions {
return permissible.hasPermission("mcmmo.commands.mmoupdate");
}
public static boolean reloadlocale(Permissible permissible) { return permissible.hasPermission("mcmmo.commands.reloadlocale"); }
public static boolean reloadlocale(Permissible permissible) {
return permissible.hasPermission("mcmmo.commands.reloadlocale");
}
/*
* PERKS
@@ -278,8 +281,8 @@ public final class Permissions {
return permissible.hasPermission("mcmmo.perks.xp.10percentboost." + skill.toString().toLowerCase());
}
public static boolean customXpBoost(Permissible permissible, PrimarySkillType skill) {
return permissible.hasPermission("mcmmo.perks.xp.customboost." + skill.toString().toLowerCase());
public static boolean hasCustomXPPerk(Permissible permissible, CustomXPPerk customXPPerk) {
return permissible.hasPermission(customXPPerk.getPerkPermissionAddress());
}
/* ACTIVATION PERKS */
@@ -515,6 +518,22 @@ public final class Permissions {
}
}
/**
* XP Perks are defined by user config files and are not known until runtime
* This method registers Permissions with the server software as needed
*/
public static void addCustomXPPerks() {
mcMMO.p.getLogger().info("Registering custom XP perks with server software...");
PluginManager pluginManager = mcMMO.p.getServer().getPluginManager();
for (CustomXPPerk customXPPerk : mcMMO.getConfigManager().getConfigExperience().getCustomXPBoosts()) {
Permission permission = new Permission(customXPPerk.getPerkPermissionAddress());
permission.setDefault(PermissionDefault.FALSE);
pluginManager.addPermission(permission);
}
}
private static void addDynamicPermission(String permissionName, PluginManager pluginManager) {
Permission permission = new Permission(permissionName);
permission.setDefault(PermissionDefault.OP);

View File

@@ -38,9 +38,8 @@ public class ExperienceMapManager implements Unload {
* This method servers two purposes
* 1) It adds user config values to a hash table
* 2) It converts user config values into their fully qualified names
*
* <p>
* This is done to avoid namespace conflicts, which don't happen in Bukkit but could easily happen in Sponge
*
*/
public void buildBlockXPMaps() {
buildMiningBlockXPMap();
@@ -53,33 +52,27 @@ public class ExperienceMapManager implements Unload {
/**
* Taming entries in the config are case insensitive, but for faster lookups we convert them to ENUMs
*/
private void buildTamingXPMap()
{
private void buildTamingXPMap() {
mcMMO.p.getLogger().info("Building Taming XP list...");
HashMap<String, Integer> userTamingConfigMap = mcMMO.getConfigManager().getConfigExperience().getTamingExperienceMap();
for(String s : userTamingConfigMap.keySet())
{
for (String s : userTamingConfigMap.keySet()) {
boolean matchFound = false;
for(EntityType entityType : EntityType.values())
{
if(entityType.toString().equalsIgnoreCase(s))
{
for (EntityType entityType : EntityType.values()) {
if (entityType.toString().equalsIgnoreCase(s)) {
//Match!
matchFound = true;
tamingExperienceMap.put(entityType, (float) userTamingConfigMap.get(s));
}
}
if(!matchFound)
{
mcMMO.p.getLogger().info("Unable to find entity with matching name - "+s);
if (!matchFound) {
mcMMO.p.getLogger().info("Unable to find entity with matching name - " + s);
}
}
}
private void fillBlockXPMap(HashMap<String, Integer> userConfigMap, HashMap<String, Integer> fullyQualifiedBlockXPMap)
{
for(String string : userConfigMap.keySet()) {
private void fillBlockXPMap(HashMap<String, Integer> userConfigMap, HashMap<String, Integer> fullyQualifiedBlockXPMap) {
for (String string : userConfigMap.keySet()) {
//matchMaterial can match fully qualified names and names without domain
Material matchingMaterial = Material.matchMaterial(string);
@@ -87,7 +80,7 @@ public class ExperienceMapManager implements Unload {
//Map the fully qualified name
fullyQualifiedBlockXPMap.put(matchingMaterial.getKey().getKey(), userConfigMap.get(string));
} else {
mcMMO.p.getLogger().info("Could not find a match for the block named '"+string+"' among vanilla block registers");
mcMMO.p.getLogger().info("Could not find a match for the block named '" + string + "' among vanilla block registers");
}
}
}
@@ -115,6 +108,7 @@ public class ExperienceMapManager implements Unload {
/**
* Change the gloabl xp multiplier, this is temporary and will not be serialiized
*
* @param newGlobalXpMult new global xp multiplier value
*/
public void setGlobalXpMult(double newGlobalXpMult) {
@@ -123,7 +117,7 @@ public class ExperienceMapManager implements Unload {
}
public void resetGlobalXpMult() {
mcMMO.p.getLogger().info("Resetting the global XP multiplier "+globalXpMult+" -> "+getOriginalGlobalXpMult());
mcMMO.p.getLogger().info("Resetting the global XP multiplier " + globalXpMult + " -> " + getOriginalGlobalXpMult());
globalXpMult = getOriginalGlobalXpMult();
}
@@ -150,6 +144,7 @@ public class ExperienceMapManager implements Unload {
/**
* Gets the current global xp multiplier value
* This value can be changed by the xprate command
*
* @return
*/
public double getGlobalXpMult() {
@@ -158,16 +153,16 @@ public class ExperienceMapManager implements Unload {
/**
* Gets the block break XP value for a specific skill
*
* @param primarySkillType target skill
* @param material target material
* @param material target material
* @return XP value for breaking this block for said skill
* @throws InvalidSkillException for skills that don't give block break experience
* @deprecated its faster to use direct calls to get XP, for example getMiningXP(Material material) instead of using this method
*/
@Deprecated
public float getBlockBreakXpValue(PrimarySkillType primarySkillType, Material material) throws InvalidSkillException {
switch(primarySkillType)
{
switch (primarySkillType) {
case MINING:
return getMiningXp(material);
case HERBALISM:
@@ -183,6 +178,7 @@ public class ExperienceMapManager implements Unload {
/**
* Gets the taming XP for this entity
*
* @param entityType target entity
* @return value of XP for this entity
*/
@@ -194,6 +190,7 @@ public class ExperienceMapManager implements Unload {
* Gets the original value of the global XP multiplier
* This is defined by the users config
* This value can be different from the current working value (due to xprate etc)
*
* @return the original global xp multiplier value from the user config file
*/
public double getOriginalGlobalXpMult() {

View File

@@ -1,29 +1,58 @@
package com.gmail.nossr50.util.player;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.experience.CustomXPPerk;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
public class PlayerLevelUtils {
HashMap<PrimarySkillType, Integer> earlyGameBoostCutoffs;
private HashMap<PrimarySkillType, Integer> earlyGameBoostCutoffs;
private HashSet<CustomXPPerk> customXpPerkNodes;
public PlayerLevelUtils()
{
public PlayerLevelUtils() {
registerCustomPerkPermissions();
earlyGameBoostCutoffs = new HashMap<>();
calculateEarlyGameBoostCutoffs();
applyConfigPerks();
}
private void calculateEarlyGameBoostCutoffs()
{
for(PrimarySkillType primarySkillType : PrimarySkillType.values())
{
/**
* Register our custom permission perks with bukkit
*/
private void registerCustomPerkPermissions() {
Permissions.addCustomXPPerks();
}
/**
* Updates our custom XP boost map
*/
private void applyConfigPerks() {
//Make a copy
customXpPerkNodes = new HashSet<>(mcMMO.getConfigManager().getConfigExperience().getCustomXPBoosts());
}
/**
* Get the the final level at which players will still receive an early game XP boost
* Note: This doesn't mean early game boosts are enabled on the server, as that is a config toggle
*
* @param primarySkillType target skill
* @return this skills maximum early game boost level
*/
public int getEarlyGameCutoff(PrimarySkillType primarySkillType) {
return earlyGameBoostCutoffs.get(primarySkillType);
}
private void calculateEarlyGameBoostCutoffs() {
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
int levelCap = mcMMO.getConfigManager().getConfigLeveling().getLevelCap(primarySkillType);
int cap;
if(levelCap == Integer.MAX_VALUE || levelCap <= 0)
{
if (levelCap == Integer.MAX_VALUE || levelCap <= 0) {
cap = mcMMO.isRetroModeEnabled() ? 50 : 5;
} else {
cap = (int) (levelCap * mcMMO.getConfigManager().getConfigLeveling().getEarlyGameBoostMultiplier());
@@ -33,8 +62,73 @@ public class PlayerLevelUtils {
}
}
public int getEarlyGameCutoff(PrimarySkillType primarySkillType)
{
return earlyGameBoostCutoffs.get(primarySkillType);
/**
* Finds all custom XP perks that a player currently qualifies for
* Used in figuring out which XP boost to give the player
*
* @param player target player
* @return a set of all CustomXPPerk that a player has positive permissions for
*/
public HashSet<CustomXPPerk> findCustomXPPerks(Player player) {
HashSet<CustomXPPerk> enabledXPPerks = new HashSet<>();
//Check all registered XP Perk nodes for this player
for (CustomXPPerk customXPPerk : customXpPerkNodes) {
if (Permissions.hasCustomXPPerk(player, customXPPerk)) {
enabledXPPerks.add(customXPPerk);
}
}
return enabledXPPerks;
}
/**
* Determines a players XP boost in a specific skill
* If a player has no custom XP perks or other boosts this value should always return 1.0
* Since a player can have multiple XP perks and boosts, this method only returns the highest that a player qualifies for
*
* @param player target player
* @param skill target skill
* @return the highest XP boost that this player qualifies for through perks or otherwise for target skill
*/
public float determineXpPerkValue(Player player, PrimarySkillType skill) {
HashSet<CustomXPPerk> enabledCustomXPPerks = findCustomXPPerks(player);
//A player can have multiple overlapping perks at a time, we need to compile a list and then sort it for the highest value
HashSet<Float> xpPerkValues = new HashSet<>();
if (enabledCustomXPPerks.size() >= 1) {
//Player has custom XP perks
for (CustomXPPerk customXPPerk : enabledCustomXPPerks) {
//Note: This returns 1.0 on skills with unset values
//Only add results that are not equal to 1.0
if (customXPPerk.getXPMultiplierValue(skill) != 1.0F)
xpPerkValues.add(customXPPerk.getXPMultiplierValue(skill));
}
}
//Disgusting legacy support start
if (Permissions.quadrupleXp(player, skill)) {
xpPerkValues.add(4f);
} else if (Permissions.tripleXp(player, skill)) {
xpPerkValues.add(3f);
} else if (Permissions.doubleAndOneHalfXp(player, skill)) {
xpPerkValues.add(2.5f);
} else if (Permissions.doubleXp(player, skill)) {
xpPerkValues.add(2.0f);
} else if (Permissions.oneAndOneHalfXp(player, skill)) {
xpPerkValues.add(1.5f);
} else if (Permissions.oneAndOneTenthXp(player, skill)) {
xpPerkValues.add(1.1f);
}
//Disgusting legacy support end
//Return
if (xpPerkValues.size() >= 1)
return Collections.max(xpPerkValues);
else
return 1.0F;
}
}

View File

@@ -1,6 +1,5 @@
package com.gmail.nossr50.util.skills;
import com.gmail.nossr50.config.experience.ExperienceConfig;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.util.Permissions;
import org.bukkit.entity.Player;
@@ -40,26 +39,6 @@ public final class PerksUtils {
return ticks;
}
public static float handleXpPerks(Player player, float xp, PrimarySkillType skill) {
if (Permissions.customXpBoost(player, skill)) {
xp *= ExperienceConfig.getInstance().getCustomXpPerkBoost();
} else if (Permissions.quadrupleXp(player, skill)) {
xp *= 4;
} else if (Permissions.tripleXp(player, skill)) {
xp *= 3;
} else if (Permissions.doubleAndOneHalfXp(player, skill)) {
xp *= 2.5;
} else if (Permissions.doubleXp(player, skill)) {
xp *= 2;
} else if (Permissions.oneAndOneHalfXp(player, skill)) {
xp *= 1.5;
} else if (Permissions.oneAndOneTenthXp(player, skill)) {
xp *= 1.1;
}
return xp;
}
/**
* Calculate activation chance for a skill.
*

View File

@@ -39,8 +39,7 @@ public class UUIDFetcher implements Callable<Map<String, UUID>> {
List<String> nameSubList = names.subList(i * PROFILES_PER_REQUEST, Math.min((i + 1) * PROFILES_PER_REQUEST, names.size()));
JsonArray array = new JsonArray();
for(String name : nameSubList)
{
for (String name : nameSubList) {
JsonPrimitive element = new JsonPrimitive(name);
array.add(element);
}