mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-25 02:04:44 +02:00
WIP 1.20.6 support
This commit is contained in:
@ -0,0 +1,56 @@
|
||||
//package com.gmail.nossr50.commands.skills;
|
||||
//
|
||||
//import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
//import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
//import com.gmail.nossr50.util.player.UserManager;
|
||||
//import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
//import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
//import com.gmail.nossr50.util.text.TextComponentFactory;
|
||||
//import net.kyori.adventure.text.Component;
|
||||
//import org.bukkit.ChatColor;
|
||||
//import org.bukkit.entity.Player;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//
|
||||
//import static com.gmail.nossr50.datatypes.skills.SubSkillType.MACES_MACES_LIMIT_BREAK;
|
||||
//
|
||||
//public class MacesCommand extends SkillCommand {
|
||||
//
|
||||
// public MacesCommand() {
|
||||
// super(PrimarySkillType.MACES);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void dataCalculations(Player player, float skillValue) {}
|
||||
//
|
||||
// @Override
|
||||
// protected void permissionsCheck(Player player) {}
|
||||
//
|
||||
// @Override
|
||||
// protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
|
||||
// List<String> messages = new ArrayList<>();
|
||||
// McMMOPlayer mmoPlayer = UserManager.getPlayer(player);
|
||||
// if (mmoPlayer == null) {
|
||||
// return messages;
|
||||
// }
|
||||
//
|
||||
// if(SkillUtils.canUseSubskill(player, MACES_MACES_LIMIT_BREAK)) {
|
||||
// messages.add(getStatMessage(MACES_MACES_LIMIT_BREAK,
|
||||
// String.valueOf(CombatUtils.getLimitBreakDamageAgainstQuality(player, MACES_MACES_LIMIT_BREAK, 1000))));
|
||||
// }
|
||||
//
|
||||
// messages.add(ChatColor.GRAY + "The Maces skill is a work in progress and is still being developed," +
|
||||
// " feedback would be appreciated in the mcMMO discord server.");
|
||||
// return messages;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected List<Component> getTextComponents(Player player) {
|
||||
// List<Component> textComponents = new ArrayList<>();
|
||||
//
|
||||
// TextComponentFactory.getSubSkillTextComponents(player, textComponents, PrimarySkillType.MACES);
|
||||
//
|
||||
// return textComponents;
|
||||
// }
|
||||
//}
|
@ -4,31 +4,40 @@ import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.LogUtils;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@Deprecated
|
||||
public abstract class LegacyConfigLoader {
|
||||
protected final File configFile;
|
||||
protected final @NotNull File configFile;
|
||||
protected final @NotNull File dataFolder;
|
||||
protected String fileName;
|
||||
protected @NotNull String fileName;
|
||||
protected YamlConfiguration config;
|
||||
|
||||
public LegacyConfigLoader(String relativePath, String fileName, @NotNull File dataFolder) {
|
||||
public LegacyConfigLoader(@NotNull String relativePath, @NotNull String fileName, @NotNull File dataFolder) {
|
||||
this.fileName = fileName;
|
||||
this.dataFolder = dataFolder;
|
||||
configFile = new File(dataFolder, relativePath + File.separator + fileName);
|
||||
loadFile();
|
||||
}
|
||||
|
||||
public LegacyConfigLoader(String fileName, @NotNull File dataFolder) {
|
||||
public LegacyConfigLoader(@NotNull String fileName, @NotNull File dataFolder) {
|
||||
this.fileName = fileName;
|
||||
this.dataFolder = dataFolder;
|
||||
configFile = new File(dataFolder, fileName);
|
||||
loadFile();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public LegacyConfigLoader(@NotNull File file) {
|
||||
this.fileName = file.getName();
|
||||
this.dataFolder = file.getParentFile();
|
||||
configFile = new File(dataFolder, fileName);
|
||||
loadFile();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public LegacyConfigLoader(String relativePath, String fileName) {
|
||||
this.fileName = fileName;
|
||||
|
@ -2,22 +2,30 @@ package com.gmail.nossr50.config.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.LegacyConfigLoader;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.LogUtils;
|
||||
import com.gmail.nossr50.util.ItemUtils;
|
||||
import com.gmail.nossr50.util.PotionUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.*;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionUtil.*;
|
||||
|
||||
public class PotionConfig extends LegacyConfigLoader {
|
||||
private static PotionConfig instance;
|
||||
|
||||
private final List<ItemStack> concoctionsIngredientsTierOne = new ArrayList<>();
|
||||
private final List<ItemStack> concoctionsIngredientsTierTwo = new ArrayList<>();
|
||||
@ -28,30 +36,34 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
private final List<ItemStack> concoctionsIngredientsTierSeven = new ArrayList<>();
|
||||
private final List<ItemStack> concoctionsIngredientsTierEight = new ArrayList<>();
|
||||
|
||||
private final Map<String, AlchemyPotion> potionMap = new HashMap<>();
|
||||
/**
|
||||
* Map of potion names to AlchemyPotion objects.
|
||||
*/
|
||||
private final Map<String, AlchemyPotion> loadedPotions = new HashMap<>();
|
||||
|
||||
private PotionConfig() {
|
||||
public PotionConfig() {
|
||||
super("potions.yml");
|
||||
loadKeys();
|
||||
}
|
||||
|
||||
public static PotionConfig getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new PotionConfig();
|
||||
}
|
||||
|
||||
return instance;
|
||||
@VisibleForTesting
|
||||
PotionConfig(File file) {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadKeys() {
|
||||
}
|
||||
|
||||
public void loadPotions() {
|
||||
loadConcoctions();
|
||||
loadPotionMap();
|
||||
}
|
||||
|
||||
private void loadConcoctions() {
|
||||
ConfigurationSection concoctionSection = config.getConfigurationSection("Concoctions");
|
||||
@VisibleForTesting
|
||||
void loadConcoctions() {
|
||||
final ConfigurationSection concoctionSection = config.getConfigurationSection("Concoctions");
|
||||
|
||||
// Load the ingredients for each tier
|
||||
loadConcoctionsTier(concoctionsIngredientsTierOne, concoctionSection.getStringList("Tier_One_Ingredients"));
|
||||
loadConcoctionsTier(concoctionsIngredientsTierTwo, concoctionSection.getStringList("Tier_Two_Ingredients"));
|
||||
loadConcoctionsTier(concoctionsIngredientsTierThree, concoctionSection.getStringList("Tier_Three_Ingredients"));
|
||||
@ -71,7 +83,7 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
}
|
||||
|
||||
private void loadConcoctionsTier(List<ItemStack> ingredientList, List<String> ingredientStrings) {
|
||||
if (ingredientStrings != null && ingredientStrings.size() > 0) {
|
||||
if (ingredientStrings != null && !ingredientStrings.isEmpty()) {
|
||||
for (String ingredientString : ingredientStrings) {
|
||||
ItemStack ingredient = loadIngredient(ingredientString);
|
||||
|
||||
@ -85,23 +97,24 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
/**
|
||||
* Find the Potions configuration section and load all defined potions.
|
||||
*/
|
||||
private void loadPotionMap() {
|
||||
int loadPotionMap() {
|
||||
ConfigurationSection potionSection = config.getConfigurationSection("Potions");
|
||||
int pass = 0;
|
||||
int fail = 0;
|
||||
int potionsLoaded = 0;
|
||||
int failures = 0;
|
||||
|
||||
for (String potionName : potionSection.getKeys(false)) {
|
||||
AlchemyPotion potion = loadPotion(potionSection.getConfigurationSection(potionName));
|
||||
|
||||
if (potion != null) {
|
||||
potionMap.put(potionName, potion);
|
||||
pass++;
|
||||
loadedPotions.put(potionName, potion);
|
||||
potionsLoaded++;
|
||||
} else {
|
||||
fail++;
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
|
||||
LogUtils.debug(mcMMO.p.getLogger(), "Loaded " + pass + " Alchemy potions, skipped " + fail + ".");
|
||||
mcMMO.p.getLogger().info("Loaded " + potionsLoaded + " Alchemy potions, skipped " + failures + ".");
|
||||
return potionsLoaded;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,37 +127,88 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
*/
|
||||
private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
|
||||
try {
|
||||
final String key = potion_section.getName();
|
||||
final String displayName = potion_section.getString("Name") != null
|
||||
? LocaleLoader.addColors(potion_section.getString("Name"))
|
||||
: null;
|
||||
|
||||
final ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
|
||||
boolean extended = false;
|
||||
boolean upgraded = false;
|
||||
|
||||
String name = potion_section.getString("Name");
|
||||
if (name != null) {
|
||||
name = ChatColor.translateAlternateColorCodes('&', name);
|
||||
if (potionData != null) {
|
||||
extended = potionData.getBoolean("Extended", false);
|
||||
upgraded = potionData.getBoolean("Upgraded", false);
|
||||
}
|
||||
|
||||
PotionData data;
|
||||
if (!potion_section.contains("PotionData")) { // Backwards config compatability
|
||||
short dataValue = Short.parseShort(potion_section.getName());
|
||||
Potion potion = Potion.fromDamage(dataValue);
|
||||
data = new PotionData(potion.getType(), potion.hasExtendedDuration(), potion.getLevel() == 2);
|
||||
Material material;
|
||||
final String materialString = potion_section.getString("Material", null);
|
||||
if (materialString != null) {
|
||||
material = ItemUtils.exhaustiveMaterialLookup(materialString);
|
||||
if (material == null) {
|
||||
mcMMO.p.getLogger().warning("PotionConfig: Failed to parse material for potion " + key + ": " + materialString);
|
||||
mcMMO.p.getLogger().warning("PotionConfig: Defaulting to POTION");
|
||||
material = Material.POTION;
|
||||
}
|
||||
} else {
|
||||
ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
|
||||
data = new PotionData(PotionType.valueOf(potionData.getString("PotionType", "WATER")), potionData.getBoolean("Extended", false), potionData.getBoolean("Upgraded", false));
|
||||
mcMMO.p.getLogger().warning("PotionConfig: Missing Material config entry for potion " + key + "," +
|
||||
" from configuration section: " + potion_section + ", defaulting to POTION");
|
||||
material = Material.POTION;
|
||||
}
|
||||
|
||||
Material material = Material.POTION;
|
||||
String mat = potion_section.getString("Material", null);
|
||||
if (mat != null) {
|
||||
material = Material.valueOf(mat);
|
||||
final ItemStack itemStack = new ItemStack(material, 1);
|
||||
final PotionMeta potionMeta = (PotionMeta) itemStack.getItemMeta();
|
||||
|
||||
if (potionMeta == null) {
|
||||
mcMMO.p.getLogger().severe("PotionConfig: Failed to get PotionMeta for " + displayName + ", from configuration section:" +
|
||||
" " + potion_section);
|
||||
return null;
|
||||
}
|
||||
|
||||
// extended and upgraded seem to be mutually exclusive
|
||||
if (extended && upgraded) {
|
||||
mcMMO.p.getLogger().warning("Potion " + key + " has both Extended and Upgraded set to true," +
|
||||
" defaulting to Extended.");
|
||||
upgraded = false;
|
||||
}
|
||||
String potionTypeStr = potionData.getString("PotionType", null);
|
||||
if (potionTypeStr == null) {
|
||||
mcMMO.p.getLogger().severe("PotionConfig: Missing PotionType for " + displayName + ", from configuration section:" +
|
||||
" " + potion_section);
|
||||
return null;
|
||||
}
|
||||
|
||||
PotionType potionType = matchPotionType(potionTypeStr, upgraded, extended);
|
||||
if (potionType == null) {
|
||||
// try matching to key
|
||||
mcMMO.p.getLogger().warning("Failed to match potion type, trying to match with config key...");
|
||||
matchPotionType(key, upgraded, extended);
|
||||
}
|
||||
|
||||
if (potionType == null) {
|
||||
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse potion type for: " + potionTypeStr);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set base potion type
|
||||
// NOTE: extended/ignored are effectively ignored here on 1.20.5 and later
|
||||
PotionUtil.setBasePotionType(potionMeta, potionType, extended, upgraded);
|
||||
|
||||
// // Use the name of the potion to indicate upgrade status if not set in PotionData
|
||||
// if(convertPotionConfigName(key).toUpperCase().contains("STRONG"))
|
||||
// upgraded = true;
|
||||
//
|
||||
// if(convertPotionConfigName(key).toUpperCase().contains("LONG"))
|
||||
// extended = true;
|
||||
|
||||
List<String> lore = new ArrayList<>();
|
||||
if (potion_section.contains("Lore")) {
|
||||
for (String line : potion_section.getStringList("Lore")) {
|
||||
lore.add(ChatColor.translateAlternateColorCodes('&', line));
|
||||
}
|
||||
}
|
||||
potionMeta.setLore(lore);
|
||||
|
||||
List<PotionEffect> effects = new ArrayList<>();
|
||||
if (potion_section.contains("Effects")) {
|
||||
for (String effect : potion_section.getStringList("Effects")) {
|
||||
String[] parts = effect.split(" ");
|
||||
@ -154,9 +218,9 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
int duration = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
|
||||
|
||||
if (type != null) {
|
||||
effects.add(new PotionEffect(type, duration, amplifier));
|
||||
potionMeta.addCustomEffect(new PotionEffect(type, duration, amplifier), true);
|
||||
} else {
|
||||
mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
|
||||
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse effect for potion " + displayName + ": " + effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -165,8 +229,9 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
if (potion_section.contains("Color")) {
|
||||
color = Color.fromRGB(potion_section.getInt("Color"));
|
||||
} else {
|
||||
color = this.generateColor(effects);
|
||||
color = this.generateColor(potionMeta.getCustomEffects());
|
||||
}
|
||||
potionMeta.setColor(color);
|
||||
|
||||
Map<ItemStack, String> children = new HashMap<>();
|
||||
if (potion_section.contains("Children")) {
|
||||
@ -175,14 +240,15 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
if (ingredient != null) {
|
||||
children.put(ingredient, potion_section.getConfigurationSection("Children").getString(child));
|
||||
} else {
|
||||
mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
|
||||
mcMMO.p.getLogger().severe("PotionConfig: Failed to parse child for potion " + displayName + ": " + child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new AlchemyPotion(material, data, name, lore, effects, color, children);
|
||||
// TODO: Might not need to .setItemMeta
|
||||
itemStack.setItemMeta(potionMeta);
|
||||
return new AlchemyPotion(itemStack, children);
|
||||
} catch (Exception e) {
|
||||
mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getName());
|
||||
mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -210,39 +276,52 @@ public class PotionConfig extends LegacyConfigLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ingredients for the given tier.
|
||||
* @param tier Tier to get ingredients for.
|
||||
* @return List of ingredients for the given tier.
|
||||
*/
|
||||
public List<ItemStack> getIngredients(int tier) {
|
||||
switch (tier) {
|
||||
case 8:
|
||||
return concoctionsIngredientsTierEight;
|
||||
case 7:
|
||||
return concoctionsIngredientsTierSeven;
|
||||
case 6:
|
||||
return concoctionsIngredientsTierSix;
|
||||
case 5:
|
||||
return concoctionsIngredientsTierFive;
|
||||
case 4:
|
||||
return concoctionsIngredientsTierFour;
|
||||
case 3:
|
||||
return concoctionsIngredientsTierThree;
|
||||
case 2:
|
||||
return concoctionsIngredientsTierTwo;
|
||||
case 1:
|
||||
default:
|
||||
return concoctionsIngredientsTierOne;
|
||||
}
|
||||
return switch (tier) {
|
||||
case 8 -> concoctionsIngredientsTierEight;
|
||||
case 7 -> concoctionsIngredientsTierSeven;
|
||||
case 6 -> concoctionsIngredientsTierSix;
|
||||
case 5 -> concoctionsIngredientsTierFive;
|
||||
case 4 -> concoctionsIngredientsTierFour;
|
||||
case 3 -> concoctionsIngredientsTierThree;
|
||||
case 2 -> concoctionsIngredientsTierTwo;
|
||||
default -> concoctionsIngredientsTierOne;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given ItemStack is a valid potion.
|
||||
* @param item ItemStack to be checked.
|
||||
* @return True if the given ItemStack is a valid potion, false otherwise.
|
||||
*/
|
||||
public boolean isValidPotion(ItemStack item) {
|
||||
return getPotion(item) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AlchemyPotion that corresponds to the given name.
|
||||
* @param name Name of the potion to be checked.
|
||||
* @return AlchemyPotion that corresponds to the given name.
|
||||
*/
|
||||
public AlchemyPotion getPotion(String name) {
|
||||
return potionMap.get(name);
|
||||
return loadedPotions.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AlchemyPotion that corresponds to the given ItemStack.
|
||||
*
|
||||
* @param item ItemStack to be checked.
|
||||
*
|
||||
* @return AlchemyPotion that corresponds to the given ItemStack.
|
||||
*/
|
||||
public AlchemyPotion getPotion(ItemStack item) {
|
||||
for (AlchemyPotion potion : potionMap.values()) {
|
||||
if (potion.isSimilar(item)) {
|
||||
for (AlchemyPotion potion : loadedPotions.values()) {
|
||||
if (potion.isSimilarPotion(item)) {
|
||||
return potion;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.treasure.*;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.EnchantmentUtils;
|
||||
import com.gmail.nossr50.util.LogUtils;
|
||||
import com.gmail.nossr50.util.PotionUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -13,12 +14,13 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
|
||||
|
||||
public class FishingTreasureConfig extends BukkitConfig {
|
||||
|
||||
public static final String FILENAME = "fishing_treasures.yml";
|
||||
@ -204,30 +206,40 @@ public class FishingTreasureConfig extends BukkitConfig {
|
||||
}
|
||||
|
||||
if (materialName.contains("POTION")) {
|
||||
// Update for 1.20.5
|
||||
|
||||
Material mat = Material.matchMaterial(materialName);
|
||||
if (mat == null) {
|
||||
reason.add("Potion format for " + FILENAME + " has changed");
|
||||
continue;
|
||||
} else {
|
||||
item = new ItemStack(mat, amount, data);
|
||||
PotionMeta itemMeta = (PotionMeta) item.getItemMeta();
|
||||
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
|
||||
|
||||
if (itemMeta == null) {
|
||||
mcMMO.p.getLogger().severe("Item meta when adding potion to fishing treasure was null, contact the mcMMO devs!");
|
||||
if (potionMeta == null) {
|
||||
mcMMO.p.getLogger().severe("FishingConfig: Item meta when adding potion to fishing treasure was null," +
|
||||
" contact the mcMMO devs!");
|
||||
reason.add("FishingConfig: Item meta when adding potion to fishing treasure was null");
|
||||
continue;
|
||||
}
|
||||
|
||||
PotionType potionType = null;
|
||||
try {
|
||||
potionType = PotionType.valueOf(config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
reason.add("Invalid Potion_Type: " + config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
|
||||
}
|
||||
String potionTypeStr;
|
||||
potionTypeStr = config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER");
|
||||
boolean extended = config.getBoolean(type + "." + treasureName + ".PotionData.Extended", false);
|
||||
boolean upgraded = config.getBoolean(type + "." + treasureName + ".PotionData.Upgraded", false);
|
||||
itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
|
||||
final PotionType potionType = matchPotionType(potionTypeStr, extended, upgraded);
|
||||
|
||||
if (potionType == null) {
|
||||
reason.add("FishingConfig: Could not derive potion type from: " + potionTypeStr +", " + extended + ", " + upgraded);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set the base potion type
|
||||
// NOTE: Upgraded/Extended are ignored in 1.20.5 and later
|
||||
PotionUtil.setBasePotionType(potionMeta, potionType, upgraded, extended);
|
||||
|
||||
if (customName != null) {
|
||||
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', customName));
|
||||
potionMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', customName));
|
||||
}
|
||||
|
||||
if (config.contains(type + "." + treasureName + ".Lore")) {
|
||||
@ -235,9 +247,9 @@ public class FishingTreasureConfig extends BukkitConfig {
|
||||
for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
|
||||
lore.add(ChatColor.translateAlternateColorCodes('&', s));
|
||||
}
|
||||
itemMeta.setLore(lore);
|
||||
potionMeta.setLore(lore);
|
||||
}
|
||||
item.setItemMeta(itemMeta);
|
||||
item.setItemMeta(potionMeta);
|
||||
}
|
||||
} else if (material == Material.ENCHANTED_BOOK) {
|
||||
//If any whitelisted enchants exist we use whitelist-based matching
|
||||
@ -355,7 +367,8 @@ public class FishingTreasureConfig extends BukkitConfig {
|
||||
Enchantment enchantment = EnchantmentUtils.getByName(enchantmentName);
|
||||
|
||||
if (enchantment == null) {
|
||||
mcMMO.p.getLogger().warning("Skipping invalid enchantment in " + FILENAME + ": " + enchantmentName);
|
||||
mcMMO.p.getLogger().info("Skipping invalid enchantment in '" + FILENAME + "', named:"
|
||||
+ enchantmentName);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ import com.gmail.nossr50.datatypes.treasure.HylianTreasure;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.LogUtils;
|
||||
import com.gmail.nossr50.util.PotionUtil;
|
||||
import com.gmail.nossr50.util.text.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
@ -14,7 +15,6 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -165,22 +165,33 @@ public class TreasureConfig extends BukkitConfig {
|
||||
Material mat = Material.matchMaterial(materialName);
|
||||
if (mat == null) {
|
||||
reason.add("Potion format for " + FILENAME + " has changed");
|
||||
continue;
|
||||
} else {
|
||||
item = new ItemStack(mat, amount, data);
|
||||
PotionMeta itemMeta = (PotionMeta) item.getItemMeta();
|
||||
|
||||
PotionType potionType = null;
|
||||
try {
|
||||
potionType = PotionType.valueOf(config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
|
||||
} catch (IllegalArgumentException ex) {
|
||||
reason.add("Invalid Potion_Type: " + config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
|
||||
PotionMeta potionMeta = (PotionMeta) item.getItemMeta();
|
||||
if (potionMeta == null) {
|
||||
mcMMO.p.getLogger().severe("Item meta when adding potion to treasure was null, contact the mcMMO devs!");
|
||||
reason.add("Item meta when adding potion to treasure was null, contact the mcMMO devs!");
|
||||
continue;
|
||||
}
|
||||
|
||||
String potionTypeStr;
|
||||
potionTypeStr = config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER");
|
||||
boolean extended = config.getBoolean(type + "." + treasureName + ".PotionData.Extended", false);
|
||||
boolean upgraded = config.getBoolean(type + "." + treasureName + ".PotionData.Upgraded", false);
|
||||
itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
|
||||
PotionType potionType = PotionUtil.matchPotionType(potionTypeStr, extended, upgraded);
|
||||
|
||||
if (potionType == null) {
|
||||
reason.add("Could not derive potion type from: " + potionTypeStr +", " + extended + ", " + upgraded);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set the base potion type
|
||||
// NOTE: extended/upgraded are ignored in 1.20.5 and later
|
||||
PotionUtil.setBasePotionType(potionMeta, potionType, extended, upgraded);
|
||||
|
||||
if (config.contains(type + "." + treasureName + ".Custom_Name")) {
|
||||
itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
|
||||
potionMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
|
||||
}
|
||||
|
||||
if (config.contains(type + "." + treasureName + ".Lore")) {
|
||||
@ -188,9 +199,9 @@ public class TreasureConfig extends BukkitConfig {
|
||||
for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
|
||||
lore.add(ChatColor.translateAlternateColorCodes('&', s));
|
||||
}
|
||||
itemMeta.setLore(lore);
|
||||
potionMeta.setLore(lore);
|
||||
}
|
||||
item.setItemMeta(itemMeta);
|
||||
item.setItemMeta(potionMeta);
|
||||
}
|
||||
} else if (material != null) {
|
||||
item = new ItemStack(material, amount, data);
|
||||
|
@ -253,68 +253,26 @@ public class FlatFileDataProcessor {
|
||||
}
|
||||
|
||||
public static @NotNull ExpectedType getExpectedValueType(int dataIndex) throws IndexOutOfBoundsException {
|
||||
switch(dataIndex) {
|
||||
case USERNAME_INDEX:
|
||||
return ExpectedType.STRING;
|
||||
case 2: //Assumption: Used to be for something, no longer used
|
||||
case 3: //Assumption: Used to be for something, no longer used
|
||||
case 23: //Assumption: Used to be used for something, no longer used
|
||||
case 33: //Assumption: Used to be used for something, no longer used
|
||||
case HEALTHBAR:
|
||||
case LEGACY_LAST_LOGIN:
|
||||
return ExpectedType.IGNORED;
|
||||
case SKILLS_MINING:
|
||||
case SKILLS_REPAIR:
|
||||
case SKILLS_UNARMED:
|
||||
case SKILLS_HERBALISM:
|
||||
case SKILLS_EXCAVATION:
|
||||
case SKILLS_ARCHERY:
|
||||
case SKILLS_SWORDS:
|
||||
case SKILLS_AXES:
|
||||
case SKILLS_WOODCUTTING:
|
||||
case SKILLS_ACROBATICS:
|
||||
case SKILLS_TAMING:
|
||||
case SKILLS_FISHING:
|
||||
case SKILLS_ALCHEMY:
|
||||
case SKILLS_CROSSBOWS:
|
||||
case SKILLS_TRIDENTS:
|
||||
case COOLDOWN_BERSERK:
|
||||
case COOLDOWN_GIGA_DRILL_BREAKER:
|
||||
case COOLDOWN_TREE_FELLER:
|
||||
case COOLDOWN_GREEN_TERRA:
|
||||
case COOLDOWN_SERRATED_STRIKES:
|
||||
case COOLDOWN_SKULL_SPLITTER:
|
||||
case COOLDOWN_SUPER_BREAKER:
|
||||
case COOLDOWN_BLAST_MINING:
|
||||
case SCOREBOARD_TIPS:
|
||||
case COOLDOWN_CHIMAERA_WING:
|
||||
case COOLDOWN_SUPER_SHOTGUN:
|
||||
case COOLDOWN_TRIDENTS:
|
||||
case COOLDOWN_ARCHERY:
|
||||
return ExpectedType.INTEGER;
|
||||
case EXP_MINING:
|
||||
case EXP_WOODCUTTING:
|
||||
case EXP_REPAIR:
|
||||
case EXP_UNARMED:
|
||||
case EXP_HERBALISM:
|
||||
case EXP_EXCAVATION:
|
||||
case EXP_ARCHERY:
|
||||
case EXP_SWORDS:
|
||||
case EXP_AXES:
|
||||
case EXP_ACROBATICS:
|
||||
case EXP_TAMING:
|
||||
case EXP_FISHING:
|
||||
case EXP_ALCHEMY:
|
||||
case EXP_CROSSBOWS:
|
||||
case EXP_TRIDENTS:
|
||||
return ExpectedType.FLOAT;
|
||||
case UUID_INDEX:
|
||||
return ExpectedType.UUID;
|
||||
case OVERHAUL_LAST_LOGIN:
|
||||
return ExpectedType.LONG;
|
||||
}
|
||||
|
||||
throw new IndexOutOfBoundsException();
|
||||
return switch (dataIndex) {
|
||||
case USERNAME_INDEX -> ExpectedType.STRING; //Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
case 2, 3, 23, 33, HEALTHBAR, LEGACY_LAST_LOGIN -> ExpectedType.IGNORED;
|
||||
case SKILLS_MINING, SKILLS_REPAIR, SKILLS_UNARMED, SKILLS_HERBALISM, SKILLS_EXCAVATION, SKILLS_ARCHERY,
|
||||
SKILLS_SWORDS, SKILLS_AXES, SKILLS_WOODCUTTING, SKILLS_ACROBATICS, SKILLS_TAMING, SKILLS_FISHING,
|
||||
SKILLS_ALCHEMY, SKILLS_CROSSBOWS, SKILLS_TRIDENTS, SKILLS_MACES, COOLDOWN_BERSERK,
|
||||
COOLDOWN_GIGA_DRILL_BREAKER, COOLDOWN_TREE_FELLER, COOLDOWN_GREEN_TERRA, COOLDOWN_SERRATED_STRIKES,
|
||||
COOLDOWN_SKULL_SPLITTER, COOLDOWN_SUPER_BREAKER, COOLDOWN_BLAST_MINING, SCOREBOARD_TIPS,
|
||||
COOLDOWN_CHIMAERA_WING, COOLDOWN_SUPER_SHOTGUN, COOLDOWN_TRIDENTS, COOLDOWN_ARCHERY, COOLDOWN_MACES ->
|
||||
ExpectedType.INTEGER;
|
||||
case EXP_MINING, EXP_WOODCUTTING, EXP_REPAIR, EXP_UNARMED, EXP_HERBALISM, EXP_EXCAVATION, EXP_ARCHERY,
|
||||
EXP_SWORDS, EXP_AXES, EXP_ACROBATICS, EXP_TAMING, EXP_FISHING, EXP_ALCHEMY, EXP_CROSSBOWS,
|
||||
EXP_TRIDENTS, EXP_MACES -> ExpectedType.FLOAT;
|
||||
case UUID_INDEX -> ExpectedType.UUID;
|
||||
case OVERHAUL_LAST_LOGIN -> ExpectedType.LONG;
|
||||
default -> throw new IndexOutOfBoundsException();
|
||||
};
|
||||
}
|
||||
|
||||
public @NotNull List<FlatFileDataContainer> getFlatFileDataContainers() {
|
||||
|
@ -87,8 +87,11 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
public static final int COOLDOWN_SUPER_SHOTGUN = 49;
|
||||
public static final int COOLDOWN_TRIDENTS = 50;
|
||||
public static final int COOLDOWN_ARCHERY = 51;
|
||||
public static final int EXP_MACES = 52;
|
||||
public static final int SKILLS_MACES = 53;
|
||||
public static final int COOLDOWN_MACES = 54;
|
||||
//Update this everytime new data is added
|
||||
public static final int DATA_ENTRY_COUNT = COOLDOWN_ARCHERY + 1;
|
||||
public static final int DATA_ENTRY_COUNT = COOLDOWN_MACES + 1;
|
||||
|
||||
FlatFileDatabaseManager(@NotNull File usersFile, @NotNull Logger logger, long purgeTime, int startingLevel, boolean testing) {
|
||||
this.usersFile = usersFile;
|
||||
@ -478,6 +481,18 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.CROSSBOWS))).append(":");
|
||||
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.TRIDENTS))).append(":");
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.TRIDENTS))).append(":");
|
||||
// public static final int COOLDOWN_SUPER_SHOTGUN = 49;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.SUPER_SHOTGUN))).append(":");
|
||||
// public static final int COOLDOWN_TRIDENTS = 50;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.TRIDENTS_SUPER_ABILITY))).append(":");
|
||||
// public static final int COOLDOWN_ARCHERY = 51;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.EXPLOSIVE_SHOT))).append(":");
|
||||
// public static final int EXP_MACES = 52;
|
||||
appendable.append(String.valueOf(profile.getSkillXpLevel(PrimarySkillType.MACES))).append(":");
|
||||
// public static final int SKILLS_MACES = 53;
|
||||
appendable.append(String.valueOf(profile.getSkillLevel(PrimarySkillType.MACES))).append(":");
|
||||
// public static final int COOLDOWN_MACES = 54;
|
||||
appendable.append(String.valueOf(profile.getAbilityDATS(SuperAbilityType.MACES_SUPER_ABILITY))).append(":");
|
||||
appendable.append("\r\n");
|
||||
}
|
||||
|
||||
@ -987,6 +1002,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
List<PlayerStat> alchemy = new ArrayList<>();
|
||||
List<PlayerStat> crossbows = new ArrayList<>();
|
||||
List<PlayerStat> tridents = new ArrayList<>();
|
||||
List<PlayerStat> maces = new ArrayList<>();
|
||||
|
||||
BufferedReader in = null;
|
||||
String playerName = null;
|
||||
@ -1022,6 +1038,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
powerLevel += putStat(woodcutting, playerName, skills.get(PrimarySkillType.WOODCUTTING));
|
||||
powerLevel += putStat(crossbows, playerName, skills.get(PrimarySkillType.CROSSBOWS));
|
||||
powerLevel += putStat(tridents, playerName, skills.get(PrimarySkillType.TRIDENTS));
|
||||
powerLevel += putStat(maces, playerName, skills.get(PrimarySkillType.MACES));
|
||||
|
||||
putStat(powerLevels, playerName, powerLevel);
|
||||
}
|
||||
@ -1059,6 +1076,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
alchemy.sort(c);
|
||||
crossbows.sort(c);
|
||||
tridents.sort(c);
|
||||
maces.sort(c);
|
||||
powerLevels.sort(c);
|
||||
|
||||
playerStatHash.put(PrimarySkillType.MINING, mining);
|
||||
@ -1076,6 +1094,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
playerStatHash.put(PrimarySkillType.ALCHEMY, alchemy);
|
||||
playerStatHash.put(PrimarySkillType.CROSSBOWS, crossbows);
|
||||
playerStatHash.put(PrimarySkillType.TRIDENTS, tridents);
|
||||
playerStatHash.put(PrimarySkillType.MACES, maces);
|
||||
|
||||
return LeaderboardStatus.UPDATED;
|
||||
}
|
||||
@ -1239,6 +1258,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ALCHEMY, EXP_ALCHEMY, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.CROSSBOWS, EXP_CROSSBOWS, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.TRIDENTS, EXP_TRIDENTS, username);
|
||||
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.MACES, EXP_MACES, username);
|
||||
|
||||
// Taming - Unused
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_BREAKER, COOLDOWN_SUPER_BREAKER, username);
|
||||
@ -1254,6 +1274,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BLAST_MINING, COOLDOWN_BLAST_MINING, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_SHOTGUN, COOLDOWN_SUPER_SHOTGUN, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.TRIDENTS_SUPER_ABILITY, COOLDOWN_TRIDENTS, username);
|
||||
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.MACES_SUPER_ABILITY, COOLDOWN_MACES, username);
|
||||
|
||||
UUID uuid;
|
||||
try {
|
||||
@ -1343,6 +1364,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ALCHEMY, SKILLS_ALCHEMY, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.CROSSBOWS, SKILLS_CROSSBOWS, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.TRIDENTS, SKILLS_TRIDENTS, username);
|
||||
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.MACES, SKILLS_MACES, username);
|
||||
|
||||
return skills;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "taming = 0 AND mining = 0 AND woodcutting = 0 AND repair = 0 "
|
||||
+ "AND unarmed = 0 AND herbalism = 0 AND excavation = 0 AND "
|
||||
+ "archery = 0 AND swords = 0 AND axes = 0 AND acrobatics = 0 "
|
||||
+ "AND fishing = 0 AND alchemy = 0 AND crossbows = 0 AND tridents = 0;");
|
||||
+ "AND fishing = 0 AND alchemy = 0 AND crossbows = 0 AND tridents = 0 AND maces = 0;");
|
||||
|
||||
statement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "experience`.`user_id` = `s`.`user_id`)");
|
||||
statement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "huds`.`user_id` = `s`.`user_id`)");
|
||||
@ -291,7 +291,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
|
||||
+ ", unarmed = ?, herbalism = ?, excavation = ?"
|
||||
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, total = ? WHERE user_id = ?");
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, maces = ?, total = ? WHERE user_id = ?");
|
||||
statement.setInt(1, profile.getSkillLevel(PrimarySkillType.TAMING));
|
||||
statement.setInt(2, profile.getSkillLevel(PrimarySkillType.MINING));
|
||||
statement.setInt(3, profile.getSkillLevel(PrimarySkillType.REPAIR));
|
||||
@ -307,11 +307,12 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setInt(13, profile.getSkillLevel(PrimarySkillType.ALCHEMY));
|
||||
statement.setInt(14, profile.getSkillLevel(PrimarySkillType.CROSSBOWS));
|
||||
statement.setInt(15, profile.getSkillLevel(PrimarySkillType.TRIDENTS));
|
||||
statement.setInt(16, profile.getSkillLevel(PrimarySkillType.MACES));
|
||||
int total = 0;
|
||||
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS)
|
||||
total += profile.getSkillLevel(primarySkillType);
|
||||
statement.setInt(16, total);
|
||||
statement.setInt(17, id);
|
||||
statement.setInt(17, total);
|
||||
statement.setInt(18, id);
|
||||
success &= (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -323,7 +324,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ " taming = ?, mining = ?, repair = ?, woodcutting = ?"
|
||||
+ ", unarmed = ?, herbalism = ?, excavation = ?"
|
||||
+ ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
|
||||
+ ", fishing = ?, alchemy = ?, crossbows = ?, tridents = ?, maces = ? WHERE user_id = ?");
|
||||
statement.setInt(1, profile.getSkillXpLevel(PrimarySkillType.TAMING));
|
||||
statement.setInt(2, profile.getSkillXpLevel(PrimarySkillType.MINING));
|
||||
statement.setInt(3, profile.getSkillXpLevel(PrimarySkillType.REPAIR));
|
||||
@ -339,7 +340,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setInt(13, profile.getSkillXpLevel(PrimarySkillType.ALCHEMY));
|
||||
statement.setInt(14, profile.getSkillXpLevel(PrimarySkillType.CROSSBOWS));
|
||||
statement.setInt(15, profile.getSkillXpLevel(PrimarySkillType.TRIDENTS));
|
||||
statement.setInt(16, id);
|
||||
statement.setInt(16, profile.getSkillXpLevel(PrimarySkillType.MACES));
|
||||
statement.setInt(17, id);
|
||||
success &= (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -350,7 +352,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement = connection.prepareStatement("UPDATE " + tablePrefix + "cooldowns SET "
|
||||
+ " mining = ?, woodcutting = ?, unarmed = ?"
|
||||
+ ", herbalism = ?, excavation = ?, swords = ?"
|
||||
+ ", axes = ?, blast_mining = ?, chimaera_wing = ?, crossbows = ?, tridents = ? WHERE user_id = ?");
|
||||
+ ", axes = ?, blast_mining = ?, chimaera_wing = ?, crossbows = ?"
|
||||
+ ", tridents = ?, maces = ? WHERE user_id = ?");
|
||||
statement.setLong(1, profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER));
|
||||
statement.setLong(2, profile.getAbilityDATS(SuperAbilityType.TREE_FELLER));
|
||||
statement.setLong(3, profile.getAbilityDATS(SuperAbilityType.BERSERK));
|
||||
@ -362,7 +365,8 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
statement.setLong(9, profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS));
|
||||
statement.setLong(10, profile.getAbilityDATS(SuperAbilityType.SUPER_SHOTGUN));
|
||||
statement.setLong(11, profile.getAbilityDATS(SuperAbilityType.TRIDENTS_SUPER_ABILITY));
|
||||
statement.setInt(12, id);
|
||||
statement.setLong(12, profile.getAbilityDATS(SuperAbilityType.MACES_SUPER_ABILITY));
|
||||
statement.setInt(13, id);
|
||||
success = (statement.executeUpdate() != 0);
|
||||
statement.close();
|
||||
if (!success) {
|
||||
@ -648,9 +652,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
|
||||
statement = connection.prepareStatement(
|
||||
"SELECT " +
|
||||
"s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, s.crossbows, s.tridents, " +
|
||||
"e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, e.crossbows, e.tridents, " +
|
||||
"c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, c.crossbows, c.tridents, " +
|
||||
"s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, s.crossbows, s.tridents, s.maces, " +
|
||||
"e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, e.crossbows, e.tridents, e.maces, " +
|
||||
"c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, c.chimaera_wing, c.crossbows, c.tridents, c.maces, " +
|
||||
"h.mobhealthbar, h.scoreboardtips, u.uuid, u.`user` "
|
||||
+ "FROM " + tablePrefix + "users u "
|
||||
+ "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
|
||||
@ -922,6 +926,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "`chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`crossbows` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`tridents` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "`maces` int(32) unsigned NOT NULL DEFAULT '0',"
|
||||
+ "PRIMARY KEY (`user_id`)) "
|
||||
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
|
||||
tryClose(createStatement);
|
||||
@ -950,6 +955,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
+ "`alchemy` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`crossbows` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`tridents` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`maces` int(10) unsigned NOT NULL DEFAULT "+startingLevel+","
|
||||
+ "`total` int(10) unsigned NOT NULL DEFAULT "+totalLevel+","
|
||||
+ "PRIMARY KEY (`user_id`)) "
|
||||
+ "DEFAULT CHARSET=" + CHARSET_SQL + ";");
|
||||
@ -1017,20 +1023,24 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
tryClose(connection);
|
||||
}
|
||||
|
||||
String skills = "skills";
|
||||
String crossbows = "crossbows";
|
||||
String tridents = "tridents";
|
||||
String experience = "experience";
|
||||
String cooldowns = "cooldowns";
|
||||
final String skills = "skills";
|
||||
final String crossbows = "crossbows";
|
||||
final String tridents = "tridents";
|
||||
final String maces = "maces";
|
||||
final String experience = "experience";
|
||||
final String cooldowns = "cooldowns";
|
||||
|
||||
updateStructure(skills, crossbows, String.valueOf(32));
|
||||
updateStructure(skills, tridents, String.valueOf(32));
|
||||
updateStructure(skills, maces, String.valueOf(32));
|
||||
|
||||
updateStructure(experience, crossbows, String.valueOf(10));
|
||||
updateStructure(experience, tridents, String.valueOf(10));
|
||||
updateStructure(experience, maces, String.valueOf(10));
|
||||
|
||||
updateStructure(cooldowns, crossbows, String.valueOf(10));
|
||||
updateStructure(cooldowns, tridents, String.valueOf(10));
|
||||
updateStructure(cooldowns, maces, String.valueOf(10));
|
||||
}
|
||||
|
||||
private void updateStructure(String tableName, String columnName, String columnSize) {
|
||||
@ -1213,15 +1223,14 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
Map<PrimarySkillType, Float> skillsXp = new EnumMap<>(PrimarySkillType.class); // Skill & XP
|
||||
Map<SuperAbilityType, Integer> skillsDATS = new EnumMap<>(SuperAbilityType.class); // Ability & Cooldown
|
||||
Map<UniqueDataType, Integer> uniqueData = new EnumMap<>(UniqueDataType.class); //Chimaera wing cooldown and other misc info
|
||||
MobHealthbarType mobHealthbarType;
|
||||
UUID uuid;
|
||||
int scoreboardTipsShown;
|
||||
|
||||
final int OFFSET_SKILLS = 0; // TODO update these numbers when the query
|
||||
// changes (a new skill is added)
|
||||
final int OFFSET_XP = 15;
|
||||
final int OFFSET_DATS = 28;
|
||||
final int OFFSET_OTHER = 41;
|
||||
final int OFFSET_XP = 16;
|
||||
final int OFFSET_DATS = 29;
|
||||
final int OFFSET_OTHER = 42;
|
||||
|
||||
skills.put(PrimarySkillType.TAMING, result.getInt(OFFSET_SKILLS + 1));
|
||||
skills.put(PrimarySkillType.MINING, result.getInt(OFFSET_SKILLS + 2));
|
||||
@ -1238,6 +1247,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
skills.put(PrimarySkillType.ALCHEMY, result.getInt(OFFSET_SKILLS + 13));
|
||||
skills.put(PrimarySkillType.CROSSBOWS, result.getInt(OFFSET_SKILLS + 14));
|
||||
skills.put(PrimarySkillType.TRIDENTS, result.getInt(OFFSET_SKILLS + 15));
|
||||
skills.put(PrimarySkillType.MACES, result.getInt(OFFSET_SKILLS + 16));
|
||||
|
||||
skillsXp.put(PrimarySkillType.TAMING, result.getFloat(OFFSET_XP + 1));
|
||||
skillsXp.put(PrimarySkillType.MINING, result.getFloat(OFFSET_XP + 2));
|
||||
@ -1254,6 +1264,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
skillsXp.put(PrimarySkillType.ALCHEMY, result.getFloat(OFFSET_XP + 13));
|
||||
skillsXp.put(PrimarySkillType.CROSSBOWS, result.getFloat(OFFSET_XP + 14));
|
||||
skillsXp.put(PrimarySkillType.TRIDENTS, result.getFloat(OFFSET_XP + 15));
|
||||
skillsXp.put(PrimarySkillType.MACES, result.getFloat(OFFSET_XP + 16));
|
||||
|
||||
// Taming - Unused - result.getInt(OFFSET_DATS + 1)
|
||||
skillsDATS.put(SuperAbilityType.SUPER_BREAKER, result.getInt(OFFSET_DATS + 2));
|
||||
@ -1270,6 +1281,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
|
||||
skillsDATS.put(SuperAbilityType.SUPER_SHOTGUN, result.getInt(OFFSET_DATS + 14));
|
||||
skillsDATS.put(SuperAbilityType.TRIDENTS_SUPER_ABILITY, result.getInt(OFFSET_DATS + 15));
|
||||
skillsDATS.put(SuperAbilityType.MACES_SUPER_ABILITY, result.getInt(OFFSET_DATS + 16));
|
||||
|
||||
try {
|
||||
scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
|
||||
|
@ -56,67 +56,29 @@ public class FlatFileDataUtil {
|
||||
* @return the "zero" initialized data corresponding to the index
|
||||
*/
|
||||
public static @NotNull String getZeroInitialisedData(int index, int startingLevel) throws IndexOutOfBoundsException {
|
||||
switch(index) {
|
||||
case USERNAME_INDEX:
|
||||
return LEGACY_INVALID_OLD_USERNAME; //We'll keep using this value for legacy compatibility reasons (not sure if needed but don't care)
|
||||
case 2: //Assumption: Used to be for something, no longer used
|
||||
case 3: //Assumption: Used to be for something, no longer used
|
||||
case 23: //Assumption: Used to be used for something, no longer used
|
||||
case 33: //Assumption: Used to be used for something, no longer used
|
||||
case LEGACY_LAST_LOGIN:
|
||||
case HEALTHBAR:
|
||||
return "IGNORED";
|
||||
case SKILLS_MINING:
|
||||
case SKILLS_REPAIR:
|
||||
case SKILLS_UNARMED:
|
||||
case SKILLS_HERBALISM:
|
||||
case SKILLS_EXCAVATION:
|
||||
case SKILLS_ARCHERY:
|
||||
case SKILLS_SWORDS:
|
||||
case SKILLS_AXES:
|
||||
case SKILLS_WOODCUTTING:
|
||||
case SKILLS_ACROBATICS:
|
||||
case SKILLS_TAMING:
|
||||
case SKILLS_FISHING:
|
||||
case SKILLS_ALCHEMY:
|
||||
case SKILLS_CROSSBOWS:
|
||||
case SKILLS_TRIDENTS:
|
||||
return String.valueOf(startingLevel);
|
||||
case OVERHAUL_LAST_LOGIN:
|
||||
return String.valueOf(-1L);
|
||||
case COOLDOWN_BERSERK:
|
||||
case COOLDOWN_GIGA_DRILL_BREAKER:
|
||||
case COOLDOWN_TREE_FELLER:
|
||||
case COOLDOWN_GREEN_TERRA:
|
||||
case COOLDOWN_SERRATED_STRIKES:
|
||||
case COOLDOWN_SKULL_SPLITTER:
|
||||
case COOLDOWN_SUPER_BREAKER:
|
||||
case COOLDOWN_BLAST_MINING:
|
||||
case COOLDOWN_SUPER_SHOTGUN:
|
||||
case COOLDOWN_TRIDENTS:
|
||||
case COOLDOWN_ARCHERY:
|
||||
case SCOREBOARD_TIPS:
|
||||
case COOLDOWN_CHIMAERA_WING:
|
||||
case EXP_MINING:
|
||||
case EXP_WOODCUTTING:
|
||||
case EXP_REPAIR:
|
||||
case EXP_UNARMED:
|
||||
case EXP_HERBALISM:
|
||||
case EXP_EXCAVATION:
|
||||
case EXP_ARCHERY:
|
||||
case EXP_SWORDS:
|
||||
case EXP_AXES:
|
||||
case EXP_ACROBATICS:
|
||||
case EXP_TAMING:
|
||||
case EXP_FISHING:
|
||||
case EXP_ALCHEMY:
|
||||
case EXP_CROSSBOWS:
|
||||
case EXP_TRIDENTS:
|
||||
return "0";
|
||||
case UUID_INDEX:
|
||||
throw new IndexOutOfBoundsException(); //TODO: Add UUID recovery? Might not even be worth it.
|
||||
}
|
||||
//TODO: Add UUID recovery? Might not even be worth it.
|
||||
return switch (index) {
|
||||
case USERNAME_INDEX ->
|
||||
LEGACY_INVALID_OLD_USERNAME; //We'll keep using this value for legacy compatibility reasons (not sure if needed but don't care)
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
//Assumption: Used to be used for something, no longer used
|
||||
case 2, 3, 23, 33, LEGACY_LAST_LOGIN, HEALTHBAR -> "IGNORED";
|
||||
case SKILLS_MINING, SKILLS_REPAIR, SKILLS_UNARMED, SKILLS_HERBALISM, SKILLS_EXCAVATION, SKILLS_ARCHERY,
|
||||
SKILLS_SWORDS, SKILLS_AXES, SKILLS_WOODCUTTING, SKILLS_ACROBATICS, SKILLS_TAMING, SKILLS_FISHING,
|
||||
SKILLS_ALCHEMY, SKILLS_CROSSBOWS, SKILLS_TRIDENTS, SKILLS_MACES -> String.valueOf(startingLevel);
|
||||
case OVERHAUL_LAST_LOGIN -> String.valueOf(-1L);
|
||||
case COOLDOWN_BERSERK, COOLDOWN_GIGA_DRILL_BREAKER, COOLDOWN_TREE_FELLER, COOLDOWN_GREEN_TERRA,
|
||||
COOLDOWN_SERRATED_STRIKES, COOLDOWN_SKULL_SPLITTER, COOLDOWN_SUPER_BREAKER, COOLDOWN_BLAST_MINING,
|
||||
COOLDOWN_SUPER_SHOTGUN, COOLDOWN_TRIDENTS, COOLDOWN_ARCHERY, COOLDOWN_MACES, SCOREBOARD_TIPS, COOLDOWN_CHIMAERA_WING,
|
||||
EXP_MINING, EXP_WOODCUTTING, EXP_REPAIR, EXP_UNARMED, EXP_HERBALISM, EXP_EXCAVATION, EXP_ARCHERY,
|
||||
EXP_SWORDS, EXP_AXES, EXP_ACROBATICS, EXP_TAMING, EXP_FISHING, EXP_ALCHEMY, EXP_CROSSBOWS,
|
||||
EXP_TRIDENTS, EXP_MACES -> "0";
|
||||
case UUID_INDEX ->
|
||||
throw new IndexOutOfBoundsException(); //TODO: Add UUID recovery? Might not even be worth it.
|
||||
default -> throw new IndexOutOfBoundsException();
|
||||
};
|
||||
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import com.gmail.nossr50.skills.crossbows.CrossbowsManager;
|
||||
import com.gmail.nossr50.skills.excavation.ExcavationManager;
|
||||
import com.gmail.nossr50.skills.fishing.FishingManager;
|
||||
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
|
||||
import com.gmail.nossr50.skills.maces.MacesManager;
|
||||
import com.gmail.nossr50.skills.mining.MiningManager;
|
||||
import com.gmail.nossr50.skills.repair.RepairManager;
|
||||
import com.gmail.nossr50.skills.salvage.SalvageManager;
|
||||
@ -220,6 +221,9 @@ public class McMMOPlayer implements Identified {
|
||||
case WOODCUTTING:
|
||||
skillManagers.put(primarySkillType, new WoodcuttingManager(this));
|
||||
break;
|
||||
case MACES:
|
||||
skillManagers.put(primarySkillType, new MacesManager(this));
|
||||
break;
|
||||
default:
|
||||
throw new InvalidSkillException("The skill named has no manager! Contact the devs!");
|
||||
}
|
||||
@ -313,6 +317,10 @@ public class McMMOPlayer implements Identified {
|
||||
return (TridentsManager) skillManagers.get(PrimarySkillType.TRIDENTS);
|
||||
}
|
||||
|
||||
public MacesManager getMacesManager() {
|
||||
return (MacesManager) skillManagers.get(PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
public ExcavationManager getExcavationManager() {
|
||||
return (ExcavationManager) skillManagers.get(PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ public enum PrimarySkillType {
|
||||
EXCAVATION,
|
||||
FISHING,
|
||||
HERBALISM,
|
||||
MACES,
|
||||
MINING,
|
||||
REPAIR,
|
||||
SALVAGE,
|
||||
|
@ -57,6 +57,9 @@ public enum SubSkillType {
|
||||
HERBALISM_HYLIAN_LUCK,
|
||||
HERBALISM_SHROOM_THUMB,
|
||||
|
||||
/* Maces */
|
||||
MACES_MACES_LIMIT_BREAK(10),
|
||||
|
||||
/* Mining */
|
||||
MINING_BIGGER_BOMBS(1),
|
||||
MINING_BLAST_MINING(8),
|
||||
|
@ -72,19 +72,26 @@ public enum SuperAbilityType {
|
||||
"Swords.Skills.SS.Other.Off",
|
||||
"Swords.SubSkill.SerratedStrikes.Name"),
|
||||
SUPER_SHOTGUN(
|
||||
null,
|
||||
null,
|
||||
"Crossbows.Skills.SSG.Other.On",
|
||||
"Crossbows.Skills.SSG.Refresh",
|
||||
null,
|
||||
"Crossbows.SubSkill.SuperShotgun.Name"),
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
TRIDENTS_SUPER_ABILITY(
|
||||
"Tridents.Skills.TA.On",
|
||||
"Tridents.Skills.TA.Off",
|
||||
"Tridents.Skills.TA.Other.On",
|
||||
"Tridents.Skills.TA.Refresh",
|
||||
"Tridents.Skills.TA.Other.Off",
|
||||
"Tridents.SubSkill.TridentAbility.Name"),
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
MACES_SUPER_ABILITY(
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder",
|
||||
"Placeholder"),
|
||||
|
||||
/**
|
||||
* Has cooldown - but has to share a skill with Super Breaker, so needs special treatment
|
||||
@ -209,6 +216,7 @@ public enum SuperAbilityType {
|
||||
case SUPER_SHOTGUN -> Permissions.superShotgun(player);
|
||||
case TREE_FELLER -> Permissions.treeFeller(player);
|
||||
case TRIDENTS_SUPER_ABILITY -> Permissions.tridentsSuper(player);
|
||||
case MACES_SUPER_ABILITY -> Permissions.macesSuper(player);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,8 @@ public enum ToolType {
|
||||
SWORD("Swords.Ability.Lower", "Swords.Ability.Ready"),
|
||||
CROSSBOW("Crossbows.Ability.Lower", "Crossbows.Ability.Ready"),
|
||||
BOW("Archery.Ability.Lower", "Archery.Ability.Ready"),
|
||||
TRIDENTS("Tridents.Ability.Lower", "Tridents.Ability.Ready");
|
||||
TRIDENTS("Tridents.Ability.Lower", "Tridents.Ability.Ready"),
|
||||
MACES("Maces.Ability.Lower", "Maces.Ability.Ready");
|
||||
|
||||
private final String lowerTool;
|
||||
private final String raiseTool;
|
||||
@ -45,6 +46,8 @@ public enum ToolType {
|
||||
return ItemUtils.isCrossbow(itemStack);
|
||||
case TRIDENTS:
|
||||
return ItemUtils.isTrident(itemStack);
|
||||
case MACES:
|
||||
return ItemUtils.isMace(itemStack);
|
||||
|
||||
case FISTS:
|
||||
return itemStack.getType() == Material.AIR;
|
||||
|
@ -1,167 +1,120 @@
|
||||
package com.gmail.nossr50.datatypes.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import org.bukkit.Color;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.Potion;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionUtil.samePotionType;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public class AlchemyPotion {
|
||||
private final Material material;
|
||||
private PotionData data;
|
||||
private String name;
|
||||
private List<String> lore;
|
||||
private List<PotionEffect> effects;
|
||||
private Color color;
|
||||
private Map<ItemStack, String> children;
|
||||
private final ItemStack potion;
|
||||
private final Map<ItemStack, String> alchemyPotionChildren;
|
||||
|
||||
public AlchemyPotion(Material material, PotionData data, String name, List<String> lore, List<PotionEffect> effects, Color color, Map<ItemStack, String> children) {
|
||||
this.material = material;
|
||||
this.data = data;
|
||||
this.lore = lore;
|
||||
this.name = name;
|
||||
this.effects = effects;
|
||||
this.children = children;
|
||||
this.color = color;
|
||||
public AlchemyPotion(ItemStack potion, Map<ItemStack, String> alchemyPotionChildren) {
|
||||
this.potion = requireNonNull(potion, "potion cannot be null");
|
||||
this.alchemyPotionChildren = requireNonNull(alchemyPotionChildren, "alchemyPotionChildren cannot be null");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AlchemyPotion{" + data + ", " + name + ", Effects[" + effects.size() + "], Children[" + children.size() + "]}";
|
||||
}
|
||||
|
||||
public ItemStack toItemStack(int amount) {
|
||||
ItemStack potion = new ItemStack(material, amount);
|
||||
PotionMeta meta = (PotionMeta) potion.getItemMeta();
|
||||
|
||||
meta.setBasePotionData(data);
|
||||
if (this.getName() != null) {
|
||||
meta.setDisplayName(this.getName());
|
||||
}
|
||||
|
||||
if (this.getLore() != null && !this.getLore().isEmpty()) {
|
||||
meta.setLore(this.getLore());
|
||||
}
|
||||
|
||||
if (!this.getEffects().isEmpty()) {
|
||||
for (PotionEffect effect : this.getEffects()) {
|
||||
meta.addCustomEffect(effect, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getColor() != null) {
|
||||
meta.setColor(this.getColor());
|
||||
}
|
||||
|
||||
potion.setItemMeta(meta);
|
||||
public @NotNull ItemStack toItemStack(int amount) {
|
||||
final ItemStack potion = new ItemStack(this.potion);
|
||||
potion.setAmount(Math.max(1, amount));
|
||||
return potion;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
public Map<ItemStack, String> getAlchemyPotionChildren() {
|
||||
return alchemyPotionChildren;
|
||||
}
|
||||
|
||||
public Potion toPotion(int amount) {
|
||||
return Potion.fromItemStack(this.toItemStack(amount));
|
||||
}
|
||||
|
||||
public PotionData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(PotionData data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<String> getLore() {
|
||||
return lore;
|
||||
}
|
||||
|
||||
public void setLore(List<String> lore) {
|
||||
this.lore = lore;
|
||||
}
|
||||
|
||||
public List<PotionEffect> getEffects() {
|
||||
return effects;
|
||||
}
|
||||
|
||||
public void setEffects(List<PotionEffect> effects) {
|
||||
this.effects = effects;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public Map<ItemStack, String> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(Map<ItemStack, String> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public AlchemyPotion getChild(ItemStack ingredient) {
|
||||
if (!children.isEmpty()) {
|
||||
for (Entry<ItemStack, String> child : children.entrySet()) {
|
||||
public @Nullable AlchemyPotion getChild(@NotNull ItemStack ingredient) {
|
||||
if (!alchemyPotionChildren.isEmpty()) {
|
||||
for (Entry<ItemStack, String> child : alchemyPotionChildren.entrySet()) {
|
||||
if (ingredient.isSimilar(child.getKey())) {
|
||||
return PotionConfig.getInstance().getPotion(child.getValue());
|
||||
return mcMMO.p.getPotionConfig().getPotion(child.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isSimilar(ItemStack item) {
|
||||
if (item.getType() != material) {
|
||||
public boolean isSimilarPotion(@NotNull ItemStack otherPotion) {
|
||||
requireNonNull(otherPotion, "otherPotion cannot be null");
|
||||
// TODO: Investigate?
|
||||
// We currently don't compare base potion effects, likely because they are derived from the potion type
|
||||
if (otherPotion.getType() != potion.getType() || !otherPotion.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
if (!item.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
PotionMeta meta = (PotionMeta) item.getItemMeta();
|
||||
PotionData that = meta.getBasePotionData();
|
||||
if (data.getType() != that.getType()) {
|
||||
return false;
|
||||
}
|
||||
if (data.isExtended() != that.isExtended()) {
|
||||
return false;
|
||||
}
|
||||
if (data.isUpgraded() != that.isUpgraded()) {
|
||||
return false;
|
||||
}
|
||||
for (PotionEffect effect : effects) {
|
||||
if (!meta.hasCustomEffect(effect.getType())) {
|
||||
|
||||
final PotionMeta otherPotionMeta = (PotionMeta) otherPotion.getItemMeta();
|
||||
|
||||
// all custom effects must be present
|
||||
for (var effect : getAlchemyPotionMeta().getCustomEffects()) {
|
||||
if (!otherPotionMeta.hasCustomEffect(effect.getType())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!meta.hasLore() && !lore.isEmpty()) {
|
||||
|
||||
if (!samePotionType(getAlchemyPotionMeta(), otherPotionMeta)) {
|
||||
return false;
|
||||
}
|
||||
if (!(lore.isEmpty() && !meta.hasLore()) && !meta.getLore().equals(lore)) {
|
||||
|
||||
if (!otherPotionMeta.hasLore() && getAlchemyPotionMeta().hasLore()
|
||||
|| !getAlchemyPotionMeta().hasLore() && otherPotionMeta.hasLore()) {
|
||||
return false;
|
||||
}
|
||||
if (!meta.hasDisplayName() && name != null) {
|
||||
|
||||
if (otherPotionMeta.hasLore() && getAlchemyPotionMeta().hasLore()
|
||||
&& !otherPotionMeta.getLore().equals(getAlchemyPotionMeta().getLore())) {
|
||||
return false;
|
||||
}
|
||||
return (name == null && !meta.hasDisplayName()) || meta.getDisplayName().equals(name);
|
||||
|
||||
if (!otherPotionMeta.hasDisplayName() && getAlchemyPotionMeta().hasDisplayName()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var alchemyPotionName = getAlchemyPotionMeta().hasDisplayName() ? getAlchemyPotionMeta().getDisplayName() : null;
|
||||
|
||||
return (alchemyPotionName == null && !otherPotionMeta.hasDisplayName()) || otherPotionMeta.getDisplayName().equals(alchemyPotionName);
|
||||
}
|
||||
|
||||
public PotionMeta getAlchemyPotionMeta() {
|
||||
return (PotionMeta) potion.getItemMeta();
|
||||
}
|
||||
|
||||
public boolean isSplash() {
|
||||
return potion.getType() == Material.SPLASH_POTION;
|
||||
}
|
||||
|
||||
public boolean isLingering() {
|
||||
return potion.getType() == Material.LINGERING_POTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AlchemyPotion that = (AlchemyPotion) o;
|
||||
return Objects.equals(potion, that.potion) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(potion, alchemyPotionChildren);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AlchemyPotion{" +
|
||||
"potion=" + potion +
|
||||
", alchemyPotionChildren=" + alchemyPotionChildren +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.gmail.nossr50.datatypes.skills.alchemy;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.potion.PotionData;
|
||||
import com.gmail.nossr50.util.PotionUtil;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.util.List;
|
||||
import static com.gmail.nossr50.util.PotionUtil.*;
|
||||
|
||||
public enum PotionStage {
|
||||
FIVE(5),
|
||||
@ -43,27 +42,27 @@ public enum PotionStage {
|
||||
return potionStage;
|
||||
}
|
||||
|
||||
private static boolean isWaterBottle(AlchemyPotion input) {
|
||||
return input.getData().getType() == PotionType.WATER;
|
||||
private static boolean isWaterBottle(AlchemyPotion alchemyPotion) {
|
||||
return isPotionTypeWater(alchemyPotion.getAlchemyPotionMeta());
|
||||
}
|
||||
|
||||
public static PotionStage getPotionStage(AlchemyPotion alchemyPotion) {
|
||||
PotionData data = alchemyPotion.getData();
|
||||
List<PotionEffect> effects = alchemyPotion.getEffects();
|
||||
final PotionMeta potionMeta = alchemyPotion.getAlchemyPotionMeta();
|
||||
|
||||
int stage = 1;
|
||||
|
||||
// Check if potion has an effect of any sort
|
||||
if (data.getType().getEffectType() != null || !effects.isEmpty()) {
|
||||
if (!potionMeta.getCustomEffects().isEmpty()
|
||||
|| PotionUtil.hasBasePotionEffects(potionMeta)) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
// Check if potion has a glowstone dust amplifier
|
||||
// Else check if the potion has a custom effect with an amplifier added by mcMMO
|
||||
if (data.isUpgraded()) {
|
||||
if (isStrong(potionMeta)) {
|
||||
stage++;
|
||||
} else if(!effects.isEmpty()) {
|
||||
for (PotionEffect effect : effects){
|
||||
} else if (!potionMeta.getCustomEffects().isEmpty()) {
|
||||
for (PotionEffect effect : potionMeta.getCustomEffects()){
|
||||
if(effect.getAmplifier() > 0){
|
||||
stage++;
|
||||
break;
|
||||
@ -72,12 +71,12 @@ public enum PotionStage {
|
||||
}
|
||||
|
||||
// Check if potion has a redstone dust amplifier
|
||||
if (data.isExtended()) {
|
||||
if (isLong(potionMeta)) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
// Check if potion has a gunpowder amplifier
|
||||
if (alchemyPotion.getMaterial() == Material.SPLASH_POTION || alchemyPotion.getMaterial() == Material.LINGERING_POTION) {
|
||||
if (alchemyPotion.isSplash() || alchemyPotion.isLingering()) {
|
||||
stage++;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@ import net.kyori.adventure.text.TextComponent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.SoundCategory;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@ -317,7 +316,7 @@ public class Roll extends AcrobaticsSubSkill {
|
||||
ItemStack boots = player.getInventory().getBoots();
|
||||
float xp = (float) (damage * (isRoll ? ExperienceConfig.getInstance().getRollXPModifier() : ExperienceConfig.getInstance().getFallXPModifier()));
|
||||
|
||||
if (boots != null && boots.containsEnchantment(Enchantment.PROTECTION_FALL)) {
|
||||
if (boots != null && boots.containsEnchantment(mcMMO.p.getEnchantmentMapper().getFeatherFalling())) {
|
||||
xp *= ExperienceConfig.getInstance().getFeatherFallXPModifier();
|
||||
}
|
||||
|
||||
|
@ -120,7 +120,7 @@ public class EntityListener implements Listener {
|
||||
if (bow == null)
|
||||
return;
|
||||
|
||||
if (bow.containsEnchantment(Enchantment.ARROW_INFINITE)) {
|
||||
if (bow.containsEnchantment(mcMMO.p.getEnchantmentMapper().getInfinity())) {
|
||||
projectile.setMetadata(MetadataConstants.METADATA_KEY_INF_ARROW, MetadataConstants.MCMMO_METADATA_VALUE);
|
||||
}
|
||||
|
||||
|
@ -78,8 +78,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class mcMMO extends JavaPlugin {
|
||||
|
||||
|
||||
/* Managers & Services */
|
||||
private static PlatformManager platformManager;
|
||||
private static MetadataService metadataService;
|
||||
@ -140,21 +138,14 @@ public class mcMMO extends JavaPlugin {
|
||||
private GeneralConfig generalConfig;
|
||||
private AdvancedConfig advancedConfig;
|
||||
private PartyConfig partyConfig;
|
||||
private PotionConfig potionConfig;
|
||||
private CustomItemSupportConfig customItemSupportConfig;
|
||||
private EnchantmentMapper enchantmentMapper;
|
||||
private AttributeMapper attributeMapper;
|
||||
|
||||
private FoliaLib foliaLib;
|
||||
private PartyManager partyManager;
|
||||
|
||||
// private RepairConfig repairConfig;
|
||||
// private SalvageConfig salvageConfig;
|
||||
// private PersistentDataConfig persistentDataConfig;
|
||||
// private ChatConfig chatConfig;
|
||||
// private CoreSkillsConfig coreSkillsConfig;
|
||||
// private RankConfig rankConfig;
|
||||
// private TreasureConfig treasureConfig;
|
||||
// private FishingTreasureConfig fishingTreasureConfig;
|
||||
// private SoundConfig soundConfig;
|
||||
|
||||
public mcMMO() {
|
||||
p = this;
|
||||
}
|
||||
@ -207,8 +198,11 @@ public class mcMMO extends JavaPlugin {
|
||||
|
||||
modManager = new ModManager();
|
||||
|
||||
//Init Material Maps
|
||||
// Init Material Maps
|
||||
materialMapStore = new MaterialMapStore();
|
||||
// Init compatibility mappers
|
||||
enchantmentMapper = new EnchantmentMapper(this);
|
||||
attributeMapper = new AttributeMapper(this);
|
||||
|
||||
loadConfigFiles();
|
||||
|
||||
@ -567,7 +561,11 @@ public class mcMMO extends JavaPlugin {
|
||||
FishingTreasureConfig.getInstance();
|
||||
HiddenConfig.getInstance();
|
||||
mcMMO.p.getAdvancedConfig();
|
||||
PotionConfig.getInstance();
|
||||
|
||||
// init potion config
|
||||
potionConfig = new PotionConfig();
|
||||
potionConfig.loadPotions();
|
||||
|
||||
CoreSkillsConfig.getInstance();
|
||||
SoundConfig.getInstance();
|
||||
RankConfig.getInstance();
|
||||
@ -812,6 +810,18 @@ public class mcMMO extends JavaPlugin {
|
||||
return customItemSupportConfig;
|
||||
}
|
||||
|
||||
public PotionConfig getPotionConfig() {
|
||||
return potionConfig;
|
||||
}
|
||||
|
||||
public EnchantmentMapper getEnchantmentMapper() {
|
||||
return enchantmentMapper;
|
||||
}
|
||||
|
||||
public AttributeMapper getAttributeMapper() {
|
||||
return attributeMapper;
|
||||
}
|
||||
|
||||
public @NotNull FoliaLib getFoliaLib() {
|
||||
return foliaLib;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.gmail.nossr50.metadata;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
@ -74,12 +73,12 @@ public class ItemMetadataService {
|
||||
|
||||
if(itemMeta != null) {
|
||||
//TODO: can be optimized
|
||||
if (itemMeta.hasEnchant(Enchantment.DIG_SPEED)) {
|
||||
itemMeta.removeEnchant(Enchantment.DIG_SPEED);
|
||||
if (itemMeta.hasEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency())) {
|
||||
itemMeta.removeEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
}
|
||||
|
||||
if (originalSpeed > 0) {
|
||||
itemMeta.addEnchant(Enchantment.DIG_SPEED, originalSpeed, true);
|
||||
itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(), originalSpeed, true);
|
||||
}
|
||||
|
||||
PersistentDataContainer dataContainer = itemMeta.getPersistentDataContainer();
|
||||
|
@ -1,13 +1,13 @@
|
||||
package com.gmail.nossr50.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainReason;
|
||||
import com.gmail.nossr50.datatypes.experience.XPGainSource;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.text.StringUtils;
|
||||
@ -27,7 +27,7 @@ public class AlchemyManager extends SkillManager {
|
||||
}
|
||||
|
||||
public List<ItemStack> getIngredients() {
|
||||
return PotionConfig.getInstance().getIngredients(getTier());
|
||||
return mcMMO.p.getPotionConfig().getIngredients(getTier());
|
||||
}
|
||||
|
||||
public String getIngredientList() {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.gmail.nossr50.skills.alchemy;
|
||||
|
||||
import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
|
||||
import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
|
||||
@ -36,7 +35,7 @@ public final class AlchemyPotionBrewer {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getChildPotion(PotionConfig.getInstance().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
|
||||
if (getChildPotion(mcMMO.p.getPotionConfig().getPotion(contents[i]), contents[Alchemy.INGREDIENT_SLOT]) != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -94,12 +93,11 @@ public final class AlchemyPotionBrewer {
|
||||
}
|
||||
|
||||
private static List<ItemStack> getValidIngredients(Player player) {
|
||||
if(player == null || UserManager.getPlayer(player) == null)
|
||||
{
|
||||
return PotionConfig.getInstance().getIngredients(1);
|
||||
if(player == null || UserManager.getPlayer(player) == null) {
|
||||
return mcMMO.p.getPotionConfig().getIngredients(1);
|
||||
}
|
||||
|
||||
return PotionConfig.getInstance().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
return mcMMO.p.getPotionConfig().getIngredients(!Permissions.isSubSkillEnabled(player, SubSkillType.ALCHEMY_CONCOCTIONS) ? 1 : UserManager.getPlayer(player).getAlchemyManager().getTier());
|
||||
}
|
||||
|
||||
public static void finishBrewing(BlockState brewingStand, Player player, boolean forced) {
|
||||
@ -120,11 +118,11 @@ public final class AlchemyPotionBrewer {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ItemStack item = inventory.getItem(i);
|
||||
|
||||
if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !PotionConfig.getInstance().isValidPotion(item)) {
|
||||
if (isEmpty(item) || item.getType() == Material.GLASS_BOTTLE || !mcMMO.p.getPotionConfig().isValidPotion(item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
AlchemyPotion input = PotionConfig.getInstance().getPotion(item);
|
||||
AlchemyPotion input = mcMMO.p.getPotionConfig().getPotion(item);
|
||||
AlchemyPotion output = input.getChild(ingredient);
|
||||
|
||||
inputList.set(i, input);
|
||||
|
@ -18,7 +18,8 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Projectile;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionEffectMapper.getNausea;
|
||||
|
||||
public class ArcheryManager extends SkillManager {
|
||||
public ArcheryManager(McMMOPlayer mcMMOPlayer) {
|
||||
@ -95,10 +96,8 @@ public class ArcheryManager extends SkillManager {
|
||||
Location dazedLocation = defender.getLocation();
|
||||
dazedLocation.setPitch(90 - Misc.getRandom().nextInt(181));
|
||||
|
||||
// defender.teleport(dazedLocation);
|
||||
mcMMO.p.getFoliaLib().getImpl().teleportAsync(defender, dazedLocation);
|
||||
defender.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 20 * 10, 10));
|
||||
|
||||
defender.addPotionEffect(new PotionEffect(getNausea(), 20 * 10, 10));
|
||||
|
||||
if (NotificationManager.doesPlayerUseNotifications(defender)) {
|
||||
NotificationManager.sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Combat.TouchedFuzzy");
|
||||
|
@ -573,11 +573,13 @@ public class FishingManager extends SkillManager {
|
||||
int luck;
|
||||
|
||||
if (getPlayer().getInventory().getItemInMainHand().getType() == Material.FISHING_ROD) {
|
||||
luck = getPlayer().getInventory().getItemInMainHand().getEnchantmentLevel(Enchantment.LUCK);
|
||||
luck = getPlayer().getInventory().getItemInMainHand().getEnchantmentLevel(
|
||||
mcMMO.p.getEnchantmentMapper().getLuckOfTheSea());
|
||||
}
|
||||
else {
|
||||
// We know something was caught, so if the rod wasn't in the main hand it must be in the offhand
|
||||
luck = getPlayer().getInventory().getItemInOffHand().getEnchantmentLevel(Enchantment.LUCK);
|
||||
luck = getPlayer().getInventory().getItemInOffHand().getEnchantmentLevel(
|
||||
mcMMO.p.getEnchantmentMapper().getLuckOfTheSea());
|
||||
}
|
||||
|
||||
// Rather than subtracting luck (and causing a minimum 3% chance for every drop), scale by luck.
|
||||
|
@ -0,0 +1,21 @@
|
||||
package com.gmail.nossr50.skills.maces;
|
||||
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.ToolType;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
|
||||
public class MacesManager extends SkillManager {
|
||||
public MacesManager(McMMOPlayer mmoPlayer) {
|
||||
super(mmoPlayer, PrimarySkillType.MACES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the player can activate the Super Ability for Maces
|
||||
* @return true if the player can activate the Super Ability, false otherwise
|
||||
*/
|
||||
public boolean canActivateAbility() {
|
||||
return mmoPlayer.getToolPreparationMode(ToolType.MACES) && Permissions.macesSuper(getPlayer());
|
||||
}
|
||||
}
|
@ -233,7 +233,7 @@ public class TamingManager extends SkillManager {
|
||||
|
||||
// Bred mules & donkeys can actually have horse-like stats, but llamas cannot.
|
||||
if (beast instanceof AbstractHorse horseLikeCreature && !(beast instanceof Llama)) {
|
||||
AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(Attribute.HORSE_JUMP_STRENGTH);
|
||||
AttributeInstance jumpAttribute = horseLikeCreature.getAttribute(mcMMO.p.getAttributeMapper().getHorseJumpStrength());
|
||||
|
||||
if(jumpAttribute != null) {
|
||||
double jumpStrength = jumpAttribute.getValue();
|
||||
|
45
src/main/java/com/gmail/nossr50/util/AttributeMapper.java
Normal file
45
src/main/java/com/gmail/nossr50/util/AttributeMapper.java
Normal file
@ -0,0 +1,45 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.attribute.Attribute;
|
||||
|
||||
public class AttributeMapper {
|
||||
private final mcMMO pluginRef;
|
||||
private static final String GENERIC_JUMP_STRENGTH = "generic.jump_strength";
|
||||
private static final String HORSE_JUMP_STRENGTH = "horse.jump_strength";
|
||||
private final Attribute horseJumpStrength;
|
||||
|
||||
public AttributeMapper(mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
this.horseJumpStrength = initHorseJumpStrength();
|
||||
}
|
||||
|
||||
private Attribute initHorseJumpStrength() {
|
||||
// TODO: Use modern matching?
|
||||
// if (Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH) != null) {
|
||||
// return Registry.ATTRIBUTE.match(GENERIC_JUMP_STRENGTH);
|
||||
// }
|
||||
//
|
||||
// if (Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH) != null) {
|
||||
// return Registry.ATTRIBUTE.match(HORSE_JUMP_STRENGTH);
|
||||
// }
|
||||
|
||||
for (Attribute attr : Registry.ATTRIBUTE) {
|
||||
if (attr.getKey().getKey().equalsIgnoreCase(HORSE_JUMP_STRENGTH)
|
||||
|| attr.getKey().getKey().equalsIgnoreCase(GENERIC_JUMP_STRENGTH)
|
||||
|| attr.name().equalsIgnoreCase(HORSE_JUMP_STRENGTH)
|
||||
|| attr.name().equalsIgnoreCase(GENERIC_JUMP_STRENGTH)) {
|
||||
return attr;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Generic Jump Strength or Horse Jump Strength attribute, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Generic Jump Strength or Horse Jump Strength attribute");
|
||||
}
|
||||
|
||||
public Attribute getHorseJumpStrength() {
|
||||
return horseJumpStrength;
|
||||
}
|
||||
}
|
149
src/main/java/com/gmail/nossr50/util/EnchantmentMapper.java
Normal file
149
src/main/java/com/gmail/nossr50/util/EnchantmentMapper.java
Normal file
@ -0,0 +1,149 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
public class EnchantmentMapper {
|
||||
private final mcMMO pluginRef;
|
||||
private final Enchantment efficiency;
|
||||
private final Enchantment unbreaking;
|
||||
private final Enchantment infinity;
|
||||
private final Enchantment featherFalling;
|
||||
private final Enchantment luckOfTheSea;
|
||||
|
||||
public EnchantmentMapper(mcMMO pluginRef) {
|
||||
this.pluginRef = pluginRef;
|
||||
this.efficiency = initEfficiency();
|
||||
this.unbreaking = initUnbreaking();
|
||||
this.infinity = initInfinity();
|
||||
this.featherFalling = initFeatherFalling();
|
||||
this.luckOfTheSea = initLuckOfTheSea();
|
||||
}
|
||||
|
||||
private Enchantment initLuckOfTheSea() {
|
||||
// TODO: Make use of match if present
|
||||
// if (Registry.ENCHANTMENT.match("luck_of_the_sea") != null) {
|
||||
// return Registry.ENCHANTMENT.match("luck_of_the_sea");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("LUCK_OF_THE_SEA")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("LUCK")
|
||||
|| enchantment.getName().equalsIgnoreCase("LUCK_OF_THE_SEA")
|
||||
|| enchantment.getName().equalsIgnoreCase("LUCK")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Luck of the Sea enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Luck of the Sea enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initFeatherFalling() {
|
||||
// if (Registry.ENCHANTMENT.match("feather_falling") != null) {
|
||||
// return Registry.ENCHANTMENT.match("feather_falling");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("FEATHER_FALLING")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("PROTECTION_FALL")
|
||||
|| enchantment.getName().equalsIgnoreCase("FEATHER_FALLING")
|
||||
|| enchantment.getName().equalsIgnoreCase("PROTECTION_FALL")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Feather Falling enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Feather Falling enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initInfinity() {
|
||||
// if(Registry.ENCHANTMENT.match("infinity") != null) {
|
||||
// return Registry.ENCHANTMENT.match("infinity");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("INFINITY")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("ARROW_INFINITE")
|
||||
|| enchantment.getName().equalsIgnoreCase("INFINITY")
|
||||
|| enchantment.getName().equalsIgnoreCase("ARROW_INFINITE")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Infinity enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Infinity enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initEfficiency() {
|
||||
// if (Registry.ENCHANTMENT.match("efficiency") != null) {
|
||||
// return Registry.ENCHANTMENT.match("efficiency");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("EFFICIENCY")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("DIG_SPEED")
|
||||
|| enchantment.getName().equalsIgnoreCase("EFFICIENCY")
|
||||
|| enchantment.getName().equalsIgnoreCase("DIG_SPEED")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Efficiency enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Efficiency enchantment");
|
||||
}
|
||||
|
||||
private Enchantment initUnbreaking() {
|
||||
// if (Registry.ENCHANTMENT.match("unbreaking") != null) {
|
||||
// return Registry.ENCHANTMENT.match("unbreaking");
|
||||
// }
|
||||
|
||||
// Look for the enchantment by name
|
||||
for (Enchantment enchantment : Registry.ENCHANTMENT) {
|
||||
if (enchantment.getKey().getKey().equalsIgnoreCase("UNBREAKING")
|
||||
|| enchantment.getKey().getKey().equalsIgnoreCase("DURABILITY")
|
||||
|| enchantment.getName().equalsIgnoreCase("UNBREAKING")
|
||||
|| enchantment.getName().equalsIgnoreCase("DURABILITY")) {
|
||||
return enchantment;
|
||||
}
|
||||
}
|
||||
|
||||
pluginRef.getLogger().severe("Unable to find the Unbreaking enchantment, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Unbreaking enchantment");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the efficiency enchantment
|
||||
*
|
||||
* @return The efficiency enchantment
|
||||
*/
|
||||
public Enchantment getEfficiency() {
|
||||
return efficiency;
|
||||
}
|
||||
|
||||
public Enchantment getUnbreaking() {
|
||||
return unbreaking;
|
||||
}
|
||||
|
||||
public Enchantment getInfinity() {
|
||||
return infinity;
|
||||
}
|
||||
|
||||
public Enchantment getFeatherFalling() {
|
||||
return featherFalling;
|
||||
}
|
||||
|
||||
public Enchantment getLuckOfTheSea() {
|
||||
return luckOfTheSea;
|
||||
}
|
||||
}
|
@ -1,39 +1,34 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class EnchantmentUtils {
|
||||
|
||||
private static final HashMap<String, Enchantment> enchants = new HashMap<>();
|
||||
private static final HashMap<String, Enchantment> legacyEnchantments = new HashMap<>();
|
||||
|
||||
static {
|
||||
enchants.put("SHARPNESS", Enchantment.DAMAGE_ALL);
|
||||
enchants.put("POWER", Enchantment.ARROW_DAMAGE);
|
||||
enchants.put("FIRE_PROTECTION", Enchantment.PROTECTION_FIRE);
|
||||
enchants.put("FEATHER_FALLING", Enchantment.PROTECTION_FALL);
|
||||
enchants.put("PROTECTION", Enchantment.PROTECTION_ENVIRONMENTAL);
|
||||
enchants.put("BLAST_PROTECTION", Enchantment.PROTECTION_EXPLOSIONS);
|
||||
enchants.put("PROJECTILE_PROTECTION", Enchantment.PROTECTION_PROJECTILE);
|
||||
enchants.put("RESPIRATION", Enchantment.OXYGEN);
|
||||
enchants.put("INFINITY", Enchantment.ARROW_INFINITE);
|
||||
enchants.put("AQUA_AFFINITY", Enchantment.WATER_WORKER);
|
||||
enchants.put("UNBREAKING", Enchantment.DURABILITY);
|
||||
enchants.put("SMITE", Enchantment.DAMAGE_UNDEAD);
|
||||
enchants.put("BANE_OF_ARTHROPODS", Enchantment.DAMAGE_ARTHROPODS);
|
||||
enchants.put("EFFICIENCY", Enchantment.DIG_SPEED);
|
||||
enchants.put("FIRE_ASPECT", Enchantment.FIRE_ASPECT);
|
||||
enchants.put("SILK_TOUCH", Enchantment.SILK_TOUCH);
|
||||
enchants.put("FORTUNE", Enchantment.LOOT_BONUS_BLOCKS);
|
||||
enchants.put("LOOTING", Enchantment.LOOT_BONUS_MOBS);
|
||||
enchants.put("PUNCH", Enchantment.ARROW_KNOCKBACK);
|
||||
enchants.put("FLAME", Enchantment.ARROW_FIRE);
|
||||
enchants.put("KNOCKBACK", Enchantment.KNOCKBACK);
|
||||
enchants.put("THORNS", Enchantment.THORNS);
|
||||
enchants.put("MENDING", Enchantment.MENDING);
|
||||
enchants.put("DEPTH_STRIDER", Enchantment.DEPTH_STRIDER);
|
||||
enchants.put("FROST_WALKER", Enchantment.FROST_WALKER);
|
||||
// backwards compatibility for looking up legacy bukkit enums
|
||||
addLegacyEnchantmentLookup("SHARPNESS", "DAMAGE_ALL");
|
||||
addLegacyEnchantmentLookup("POWER", "ARROW_DAMAGE");
|
||||
addLegacyEnchantmentLookup("FIRE_PROTECTION", "PROTECTION_FIRE");
|
||||
addLegacyEnchantmentLookup("FEATHER_FALLING", "PROTECTION_FALL");
|
||||
addLegacyEnchantmentLookup("PROTECTION", "PROTECTION_ENVIRONMENTAL");
|
||||
addLegacyEnchantmentLookup("BLAST_PROTECTION", "PROTECTION_EXPLOSIONS");
|
||||
addLegacyEnchantmentLookup("PROJECTILE_PROTECTION", "PROTECTION_PROJECTILE");
|
||||
addLegacyEnchantmentLookup("RESPIRATION", "OXYGEN");
|
||||
addLegacyEnchantmentLookup("INFINITY", "ARROW_INFINITE");
|
||||
addLegacyEnchantmentLookup("AQUA_AFFINITY", "WATER_WORKER");
|
||||
addLegacyEnchantmentLookup("UNBREAKING", "DURABILITY");
|
||||
addLegacyEnchantmentLookup("SMITE", "DAMAGE_UNDEAD");
|
||||
addLegacyEnchantmentLookup("BANE_OF_ARTHROPODS", "DAMAGE_ARTHROPODS");
|
||||
addLegacyEnchantmentLookup("EFFICIENCY", "DIG_SPEED");
|
||||
addLegacyEnchantmentLookup("FORTUNE", "LOOT_BONUS_BLOCKS");
|
||||
addLegacyEnchantmentLookup("LOOTING", "LOOT_BONUS_MOBS");
|
||||
addLegacyEnchantmentLookup("PUNCH", "ARROW_KNOCKBACK");
|
||||
addLegacyEnchantmentLookup("FLAME", "ARROW_FIRE");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -43,11 +38,19 @@ public class EnchantmentUtils {
|
||||
*
|
||||
* @return Enchantment or null if no enchantment was found
|
||||
*/
|
||||
public static Enchantment getByName(String enchantmentName) {
|
||||
if (enchants.containsKey(enchantmentName)) {
|
||||
return enchants.get(enchantmentName);
|
||||
@SuppressWarnings("deprecation")
|
||||
public static @Nullable Enchantment getByName(String enchantmentName) {
|
||||
if (legacyEnchantments.containsKey(enchantmentName)) {
|
||||
return legacyEnchantments.get(enchantmentName);
|
||||
}
|
||||
|
||||
return Enchantment.getByName(enchantmentName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void addLegacyEnchantmentLookup(String enchantmentName, String legacyBukkitName) {
|
||||
if (Enchantment.getByName(legacyBukkitName) != null) {
|
||||
legacyEnchantments.put(enchantmentName, Enchantment.getByName(legacyBukkitName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public final class ItemUtils {
|
||||
/**
|
||||
* This is a static utility class, therefore we don't want any instances of
|
||||
@ -41,6 +43,37 @@ public final class ItemUtils {
|
||||
return mcMMO.getMaterialMapStore().isBow(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exhaustive lookup for a Material by name.
|
||||
* <p>
|
||||
* This method will first try a normal lookup, then a legacy lookup, then a lookup by ENUM name,
|
||||
* and finally a lookup by ENUM name with legacy name.
|
||||
* @param materialName The name of the material to lookup
|
||||
* @return The Material if found, or null if not found
|
||||
*/
|
||||
public static @Nullable Material exhaustiveMaterialLookup(@NotNull String materialName) {
|
||||
requireNonNull(materialName, "materialName cannot be null");
|
||||
|
||||
// First try a normal lookup
|
||||
Material material = Material.matchMaterial(materialName);
|
||||
|
||||
// If that fails, try a legacy lookup
|
||||
if (material == null) {
|
||||
material = Material.matchMaterial(materialName, true);
|
||||
}
|
||||
|
||||
// try to match to Material ENUM
|
||||
if (material == null) {
|
||||
material = Material.getMaterial(materialName.toUpperCase());
|
||||
}
|
||||
|
||||
// try to match to Material ENUM with legacy name
|
||||
if (material == null) {
|
||||
material = Material.getMaterial(materialName.toUpperCase(), true);
|
||||
}
|
||||
return material;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player has an item in their inventory or offhand.
|
||||
*
|
||||
@ -100,6 +133,10 @@ public final class ItemUtils {
|
||||
return mcMMO.getMaterialMapStore().isTrident(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
public static boolean isMace(@NotNull ItemStack item) {
|
||||
return mcMMO.getMaterialMapStore().isMace(item.getType().getKey().getKey());
|
||||
}
|
||||
|
||||
public static boolean hasItemInEitherHand(@NotNull Player player, Material material) {
|
||||
return player.getInventory().getItemInMainHand().getType() == material || player.getInventory().getItemInOffHand().getType() == material;
|
||||
}
|
||||
@ -681,7 +718,8 @@ public final class ItemUtils {
|
||||
if(itemMeta == null)
|
||||
return;
|
||||
|
||||
itemMeta.addEnchant(Enchantment.DIG_SPEED, existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
|
||||
itemMeta.addEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency(),
|
||||
existingEnchantLevel + mcMMO.p.getAdvancedConfig().getEnchantBuff(), true);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class MaterialMapStore {
|
||||
private final @NotNull HashSet<String> crossbows;
|
||||
private final @NotNull HashSet<String> tools;
|
||||
private final @NotNull HashSet<String> enchantables;
|
||||
private final @NotNull HashSet<String> maces;
|
||||
|
||||
private final @NotNull HashSet<String> ores;
|
||||
private final @NotNull HashSet<String> intendedToolPickAxe;
|
||||
@ -97,6 +98,7 @@ public class MaterialMapStore {
|
||||
shovels = new HashSet<>();
|
||||
hoes = new HashSet<>();
|
||||
tridents = new HashSet<>();
|
||||
maces = new HashSet<>();
|
||||
|
||||
enchantables = new HashSet<>();
|
||||
|
||||
@ -453,6 +455,7 @@ public class MaterialMapStore {
|
||||
enchantables.addAll(tridents);
|
||||
enchantables.addAll(bows);
|
||||
enchantables.addAll(crossbows);
|
||||
enchantables.addAll(maces);
|
||||
|
||||
enchantables.add("shears");
|
||||
enchantables.add("fishing_rod");
|
||||
@ -476,6 +479,7 @@ public class MaterialMapStore {
|
||||
fillHoes();
|
||||
fillShovels();
|
||||
fillTridents();
|
||||
fillMaces();
|
||||
fillStringTools();
|
||||
fillBows();
|
||||
fillCrossbows();
|
||||
@ -491,6 +495,7 @@ public class MaterialMapStore {
|
||||
tools.addAll(stringTools);
|
||||
tools.addAll(bows);
|
||||
tools.addAll(crossbows);
|
||||
tools.addAll(maces);
|
||||
}
|
||||
|
||||
private void fillBows() {
|
||||
@ -507,6 +512,10 @@ public class MaterialMapStore {
|
||||
stringTools.add("carrot_on_a_stick");
|
||||
}
|
||||
|
||||
private void fillMaces() {
|
||||
maces.add("mace");
|
||||
}
|
||||
|
||||
private void fillTridents() {
|
||||
tridents.add("trident");
|
||||
}
|
||||
@ -824,6 +833,14 @@ public class MaterialMapStore {
|
||||
return tridents.contains(id);
|
||||
}
|
||||
|
||||
public boolean isMace(@NotNull Material material) {
|
||||
return isMace(material.getKey().getKey());
|
||||
}
|
||||
|
||||
public boolean isMace(@NotNull String id) {
|
||||
return maces.contains(id);
|
||||
}
|
||||
|
||||
public boolean isLeatherArmor(@NotNull Material material) {
|
||||
return isLeatherArmor(material.getKey().getKey());
|
||||
}
|
||||
|
@ -246,6 +246,14 @@ public final class Permissions {
|
||||
}
|
||||
public static boolean tridentsLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.tridents.superability"); }
|
||||
|
||||
/* MACES */
|
||||
public static boolean macesSuper(Permissible permissible) {
|
||||
// TODO: When a super is added, change this
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean macesLimitBreak(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.maces.limitbreak"); }
|
||||
|
||||
/*
|
||||
* PARTY
|
||||
*/
|
||||
|
@ -0,0 +1,6 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
public enum PotionCompatibilityType {
|
||||
PRE_1_20_5,
|
||||
POST_1_20_5
|
||||
}
|
142
src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
Normal file
142
src/main/java/com/gmail/nossr50/util/PotionEffectMapper.java
Normal file
@ -0,0 +1,142 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
final public class PotionEffectMapper {
|
||||
private static final PotionEffectType haste;
|
||||
private static final PotionEffectType nausea;
|
||||
private static final Method potionEffectTypeWrapperGetPotionEffectType;
|
||||
private static final Class<?> classPotionEffectTypeWrapper;
|
||||
|
||||
private PotionEffectMapper() {
|
||||
// Utility class
|
||||
}
|
||||
|
||||
static {
|
||||
potionEffectTypeWrapperGetPotionEffectType = getPotionEffectTypeWrapperGetPotionEffectType();
|
||||
classPotionEffectTypeWrapper = getClassPotionEffectTypeWrapper();
|
||||
|
||||
haste = initHaste();
|
||||
nausea = initNausea();
|
||||
}
|
||||
|
||||
private static Method getPotionEffectTypeWrapperGetPotionEffectType() {
|
||||
try {
|
||||
return classPotionEffectTypeWrapper.getMethod("getType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getClassPotionEffectTypeWrapper() {
|
||||
try {
|
||||
return Class.forName("org.bukkit.potion.PotionEffectTypeWrapper");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType initNausea() {
|
||||
if (classPotionEffectTypeWrapper != null) {
|
||||
return getNauseaLegacy();
|
||||
} else {
|
||||
return getNauseaModern();
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getNauseaModern() {
|
||||
// PotionEffectType potionEffectType = Registry.EFFECT.match("nausea");
|
||||
// if (potionEffectType != null) {
|
||||
// return potionEffectType;
|
||||
// }
|
||||
//
|
||||
// // Look for the potion effect type by name
|
||||
// for (PotionEffectType pet : Registry.EFFECT) {
|
||||
// if (pet.getKey().getKey().equalsIgnoreCase("CONFUSION")
|
||||
// || pet.getKey().getKey().equalsIgnoreCase("NAUSEA")
|
||||
// || pet.getName().equalsIgnoreCase("CONFUSION")
|
||||
// || pet.getName().equalsIgnoreCase("NAUSEA")) {
|
||||
// return pet;
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
return (PotionEffectType) PotionEffectType.class.getField("NAUSEA").get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Nausea potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getNauseaLegacy() {
|
||||
try {
|
||||
Object potionEffectTypeWrapper = PotionEffectType.class.getField("CONFUSION").get(null);
|
||||
PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
|
||||
.invoke(potionEffectTypeWrapper);
|
||||
return potionEffectType;
|
||||
} catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Nausea potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Nausea potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType initHaste() {
|
||||
|
||||
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
|
||||
private static PotionEffectType getHasteLegacy() {
|
||||
try {
|
||||
Object potionEffectTypeWrapper = PotionEffectType.class.getField("FAST_DIGGING").get(null);
|
||||
PotionEffectType potionEffectType = (PotionEffectType) potionEffectTypeWrapperGetPotionEffectType
|
||||
.invoke(potionEffectTypeWrapper);
|
||||
return potionEffectType;
|
||||
} catch (IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
private static PotionEffectType getHasteModern() {
|
||||
// PotionEffectType potionEffectType = Registry.EFFECT.match("haste");
|
||||
// if (potionEffectType != null) {
|
||||
// return potionEffectType;
|
||||
// }
|
||||
//
|
||||
// // Look for the potion effect type by name
|
||||
// for (PotionEffectType pet : Registry.EFFECT) {
|
||||
// if (pet.getKey().getKey().equalsIgnoreCase("HASTE")
|
||||
// || pet.getKey().getKey().equalsIgnoreCase("FAST_DIGGING")
|
||||
// || pet.getName().equalsIgnoreCase("HASTE")
|
||||
// || pet.getName().equalsIgnoreCase("FAST_DIGGING")) {
|
||||
// return pet;
|
||||
// }
|
||||
// }
|
||||
|
||||
try {
|
||||
return (PotionEffectType) PotionEffectType.class.getField("HASTE").get(null);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().severe("Unable to find the Haste potion effect type, " +
|
||||
"mcMMO will not function properly.");
|
||||
throw new IllegalStateException("Unable to find the Haste potion effect type");
|
||||
}
|
||||
}
|
||||
|
||||
public static PotionEffectType getHaste() {
|
||||
return haste;
|
||||
}
|
||||
|
||||
public static PotionEffectType getNausea() {
|
||||
return nausea;
|
||||
}
|
||||
}
|
447
src/main/java/com/gmail/nossr50/util/PotionUtil.java
Normal file
447
src/main/java/com/gmail/nossr50/util/PotionUtil.java
Normal file
@ -0,0 +1,447 @@
|
||||
package com.gmail.nossr50.util;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.meta.PotionMeta;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PotionUtil {
|
||||
// Some of the old potion types got renamed, our configs can still contain these old names
|
||||
private static final Map<String, String> legacyPotionTypes = new HashMap<>();
|
||||
private static final Method methodPotionTypeGetKey;
|
||||
private static final Method methodPotionTypeGetEffectType;
|
||||
private static final Method methodPotionTypeGetPotionEffects;
|
||||
private static final Method methodPotionDataIsUpgraded;
|
||||
private static final Method methodPotionDataIsExtended;
|
||||
private static final Method methodPotionDataGetType;
|
||||
private static final Method methodPotionMetaGetBasePotionData;
|
||||
private static final Method methodPotionMetaGetBasePotionType;
|
||||
private static final Method methodPotionMetaSetBasePotionType;
|
||||
private static final Method methodSetBasePotionData;
|
||||
private static final Class<?> potionDataClass;
|
||||
|
||||
public static final String STRONG = "STRONG";
|
||||
public static final String LONG = "LONG";
|
||||
public static final String LEGACY_WATER_POTION_TYPE = "WATER";
|
||||
|
||||
private static final PotionCompatibilityType COMPATIBILITY_MODE;
|
||||
|
||||
static {
|
||||
// We used to use uncraftable as the potion type
|
||||
// this type isn't available anymore, so water will do
|
||||
legacyPotionTypes.put("UNCRAFTABLE", "WATER");
|
||||
legacyPotionTypes.put("JUMP", "LEAPING");
|
||||
legacyPotionTypes.put("SPEED", "SWIFTNESS");
|
||||
legacyPotionTypes.put("INSTANT_HEAL", "HEALING");
|
||||
legacyPotionTypes.put("INSTANT_DAMAGE", "HARMING");
|
||||
legacyPotionTypes.put("REGEN", "REGENERATION");
|
||||
methodPotionTypeGetKey = getKeyMethod();
|
||||
methodPotionDataIsUpgraded = getPotionDataIsUpgraded();
|
||||
methodPotionDataIsExtended = getIsExtended();
|
||||
methodPotionMetaGetBasePotionData = getBasePotionData();
|
||||
methodPotionMetaGetBasePotionType = getBasePotionType();
|
||||
methodPotionMetaSetBasePotionType = getMethodPotionMetaSetBasePotionType();
|
||||
methodPotionDataGetType = getPotionDataGetType();
|
||||
methodPotionTypeGetEffectType = getPotionTypeEffectType();
|
||||
methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
|
||||
methodSetBasePotionData = getSetBasePotionData();
|
||||
potionDataClass = getPotionDataClass();
|
||||
|
||||
if (methodPotionMetaGetBasePotionData != null) {
|
||||
COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
|
||||
} else {
|
||||
COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a potion from a partial name, and whether it should be upgraded or extended.
|
||||
* @param partialName potion type as a string, can be a substring of the potion type but must match exactly
|
||||
* @return The potion type
|
||||
*/
|
||||
public static PotionType matchPotionType(String partialName, boolean isUpgraded, boolean isExtended) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return matchLegacyPotionType(partialName);
|
||||
} else {
|
||||
String updatedName = convertLegacyNames(partialName);
|
||||
return Arrays.stream(PotionType.values())
|
||||
.filter(potionType -> getKeyGetKey(potionType).toUpperCase().contains(partialName)
|
||||
|| getKeyGetKey(potionType).toUpperCase().contains(convertLegacyNames(updatedName)))
|
||||
.filter(potionType -> !isUpgraded || potionType.name().toUpperCase().contains(STRONG))
|
||||
.filter(potionType -> !isExtended || potionType.name().toUpperCase().contains(LONG))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getKeyGetKey(PotionType potionType) {
|
||||
try {
|
||||
if (getKeyMethod() != null) {
|
||||
NamespacedKey key = (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
|
||||
return key.getKey();
|
||||
} else {
|
||||
return potionType.name();
|
||||
}
|
||||
} catch (InvocationTargetException | IllegalAccessException e) {
|
||||
mcMMO.p.getLogger().warning("Failed to get potion key for " + potionType.name());
|
||||
return potionType.name();
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> getPotionDataClass() {
|
||||
try {
|
||||
return Class.forName("org.bukkit.potion.PotionData");
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Older versions of Spigot do not have getKey() in PotionType
|
||||
* We need to check for the existence of this method before calling it
|
||||
* @return The getKey method
|
||||
*/
|
||||
private static @Nullable Method getKeyMethod() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getKey");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getMethodPotionMetaSetBasePotionType() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("setBasePotionType", PotionType.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getSetBasePotionData() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("setBasePotionData", potionDataClass);
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Method getPotionDataIsUpgraded() {
|
||||
try {
|
||||
// TODO: <?> Needed?
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("isUpgraded");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static @Nullable Method getIsExtended() {
|
||||
try {
|
||||
// TODO: <?> Needed?
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("isExtended");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Newer versions of Spigot do not have getBasePotionData() in PotionMeta
|
||||
*
|
||||
* @return the getBasePotionData method, or null if it does not exist
|
||||
*/
|
||||
private static @Nullable Method getBasePotionData() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getBasePotionData");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getBasePotionType() {
|
||||
try {
|
||||
return PotionMeta.class.getMethod("getBasePotionType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionDataGetType() {
|
||||
try {
|
||||
final Class<?> clazz = Class.forName("org.bukkit.potion.PotionData");
|
||||
return clazz.getMethod("getType");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionTypeEffectType() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getEffectType");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Method getPotionTypeGetPotionEffects() {
|
||||
try {
|
||||
return PotionType.class.getMethod("getPotionEffects");
|
||||
} catch (NoSuchMethodException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy matching for {@link PotionType}
|
||||
*
|
||||
* @param partialName The partial name of the potion
|
||||
* @return The potion type
|
||||
*/
|
||||
private static PotionType matchLegacyPotionType(String partialName) {
|
||||
String updatedName = convertLegacyNames(partialName);
|
||||
|
||||
return Arrays.stream(PotionType.values())
|
||||
.filter(potionType -> getKeyGetKey(potionType).equalsIgnoreCase(partialName)
|
||||
|| getKeyGetKey(potionType).equalsIgnoreCase(convertLegacyNames(updatedName))
|
||||
|| potionType.name().equalsIgnoreCase(partialName)
|
||||
|| potionType.name().equalsIgnoreCase(convertLegacyNames(updatedName)))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static String convertPotionConfigName(String legacyName) {
|
||||
String replacementName = legacyName;
|
||||
|
||||
// Remove generated potions.yml config naming convention
|
||||
if (replacementName.contains("POTION_OF_")) {
|
||||
replacementName = replacementName.replace("POTION_OF_", "");
|
||||
}
|
||||
|
||||
if (replacementName.contains("_II")) {
|
||||
replacementName = replacementName.replace("_II", "");
|
||||
replacementName = "STRONG_" + replacementName;
|
||||
} else if (replacementName.contains("_EXTENDED")) {
|
||||
replacementName = replacementName.replace("_EXTENDED", "");
|
||||
replacementName = "LONG_" + replacementName;
|
||||
}
|
||||
return replacementName;
|
||||
}
|
||||
|
||||
public static String convertLegacyNames(String legacyPotionType) {
|
||||
String modernized = legacyPotionType;
|
||||
// check for legacy names
|
||||
for (var key : legacyPotionTypes.keySet()) {
|
||||
if (modernized.contains(key)) {
|
||||
// Replace the legacy name with the new name
|
||||
modernized = modernized.replace(key, legacyPotionTypes.get(key));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return modernized;
|
||||
}
|
||||
|
||||
public static boolean hasLegacyName(String potionType) {
|
||||
for (var key : legacyPotionTypes.keySet()) {
|
||||
if (potionType.contains(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isStrong(PotionMeta potionMeta) {
|
||||
if (methodPotionMetaGetBasePotionData == null) {
|
||||
return isStrongModern(potionMeta);
|
||||
} else {
|
||||
return isStrongLegacy(potionMeta);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isLong(PotionMeta potionMeta) {
|
||||
if (methodPotionMetaGetBasePotionData == null) {
|
||||
return isLongModern(potionMeta);
|
||||
} else {
|
||||
return isLongLegacy(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLongLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
return (boolean) methodPotionDataIsExtended.invoke(potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLongModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().startsWith(LONG);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStrongLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
return (boolean) methodPotionDataIsUpgraded.invoke(potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStrongModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().startsWith(STRONG);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static NamespacedKey getModernPotionTypeKey(PotionMeta potionMeta) throws IllegalAccessException, InvocationTargetException {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
return (NamespacedKey) methodPotionTypeGetKey.invoke(potionType);
|
||||
}
|
||||
|
||||
public static boolean isPotionTypeWater(@NotNull PotionMeta potionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return isPotionTypeWaterLegacy(potionMeta);
|
||||
} else {
|
||||
return isPotionTypeWaterModern(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPotionTypeWaterLegacy(@NotNull PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
return potionType.name().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE)
|
||||
|| PotionType.valueOf(LEGACY_WATER_POTION_TYPE) == potionType;
|
||||
} catch (InvocationTargetException | IllegalAccessException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isPotionTypeWaterModern(@NotNull PotionMeta potionMeta) {
|
||||
try {
|
||||
return getModernPotionTypeKey(potionMeta).getKey().equalsIgnoreCase(LEGACY_WATER_POTION_TYPE);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean samePotionType(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return samePotionTypeLegacy(potionMeta, otherPotionMeta);
|
||||
} else {
|
||||
return samePotionTypeModern(potionMeta, otherPotionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionTypeLegacy(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
Object otherPotionData = methodPotionMetaGetBasePotionData.invoke(otherPotionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
PotionType otherPotionType = (PotionType) methodPotionDataGetType.invoke(otherPotionData);
|
||||
return potionType == otherPotionType;
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionTypeModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
try {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
PotionType otherPotionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(otherPotionMeta);
|
||||
return potionType == otherPotionType;
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean samePotionEffects(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return true;
|
||||
} else {
|
||||
return samePotionEffectsModern(potionMeta, otherPotionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean samePotionEffectsModern(PotionMeta potionMeta, PotionMeta otherPotionMeta) {
|
||||
return potionMeta.getCustomEffects().equals(otherPotionMeta.getCustomEffects());
|
||||
}
|
||||
|
||||
public static boolean hasBasePotionEffects(PotionMeta potionMeta) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
return hasBasePotionEffectsLegacy(potionMeta);
|
||||
} else {
|
||||
return hasBasePotionEffectsModern(potionMeta);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasBasePotionEffectsLegacy(PotionMeta potionMeta) {
|
||||
try {
|
||||
Object potionData = methodPotionMetaGetBasePotionData.invoke(potionMeta);
|
||||
PotionType potionType = (PotionType) methodPotionDataGetType.invoke(potionData);
|
||||
return methodPotionTypeGetEffectType.invoke(potionType) != null;
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasBasePotionEffectsModern(PotionMeta potionMeta) {
|
||||
try {
|
||||
PotionType potionType = (PotionType) methodPotionMetaGetBasePotionType.invoke(potionMeta);
|
||||
List<PotionEffectType> potionEffectTypeList = (List<PotionEffectType>) methodPotionTypeGetPotionEffects.invoke(potionType);
|
||||
return potionEffectTypeList != null || !potionEffectTypeList.isEmpty();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the base potion type of a potion meta.
|
||||
* Note that extended/upgraded are ignored in 1.20.5 and later.
|
||||
*
|
||||
* @param potionMeta the potion meta
|
||||
* @param extended true if the potion is extended
|
||||
* @param upgraded true if the potion is upgraded
|
||||
*/
|
||||
public static void setBasePotionType(PotionMeta potionMeta, PotionType potionType, boolean extended, boolean upgraded) {
|
||||
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
|
||||
setBasePotionTypeLegacy(potionMeta, potionType, extended, upgraded);
|
||||
} else {
|
||||
setBasePotionTypeModern(potionMeta, potionType);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setBasePotionTypeLegacy(PotionMeta potionMeta, PotionType potionType, boolean extended,
|
||||
boolean upgraded) {
|
||||
try {
|
||||
Object potionData = potionDataClass.getConstructor(PotionType.class, boolean.class, boolean.class)
|
||||
.newInstance(potionType, extended, upgraded);
|
||||
methodSetBasePotionData.invoke(potionMeta, potionData);
|
||||
} catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setBasePotionTypeModern(PotionMeta potionMeta, PotionType potionType) {
|
||||
try {
|
||||
methodPotionMetaSetBasePotionType.invoke(potionMeta, potionType);
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
@ -33,6 +33,9 @@ public final class CommandRegistrationManager {
|
||||
|
||||
private static void registerSkillCommands() {
|
||||
for (PrimarySkillType skill : PrimarySkillType.values()) {
|
||||
if (skill == PrimarySkillType.MACES)
|
||||
continue;
|
||||
|
||||
String commandName = skill.toString().toLowerCase(Locale.ENGLISH);
|
||||
String localizedName = mcMMO.p.getSkillTools().getLocalizedSkillName(skill).toLowerCase(Locale.ENGLISH);
|
||||
|
||||
@ -77,6 +80,10 @@ public final class CommandRegistrationManager {
|
||||
command.setExecutor(new HerbalismCommand());
|
||||
break;
|
||||
|
||||
case MACES:
|
||||
// command.setExecutor(new MacesCommand());
|
||||
break;
|
||||
|
||||
case MINING:
|
||||
command.setExecutor(new MiningCommand());
|
||||
break;
|
||||
@ -113,7 +120,7 @@ public final class CommandRegistrationManager {
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
throw new IllegalStateException("Unexpected value: " + skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import java.util.HashMap;
|
||||
* In 2.2 we are switching to modules and that will clean things up significantly
|
||||
*
|
||||
*/
|
||||
//TODO: I need to delete this crap
|
||||
public class CompatibilityManager {
|
||||
private @NotNull HashMap<CompatibilityType, Boolean> supportedLayers;
|
||||
private boolean isFullyCompatibleServerSoftware = true; //true if all compatibility layers load successfully
|
||||
@ -159,7 +158,7 @@ public class CompatibilityManager {
|
||||
return masterAnglerCompatibility;
|
||||
}
|
||||
|
||||
public @Nullable MinecraftGameVersion getMinecraftGameVersion() {
|
||||
public @NotNull MinecraftGameVersion getMinecraftGameVersion() {
|
||||
return minecraftGameVersion;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ public final class CombatUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void processTridentCombatMelee(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
@ -214,6 +215,32 @@ public final class CombatUtils {
|
||||
delayArrowMetaCleanup(arrow);
|
||||
}
|
||||
|
||||
private static void processMacesCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
}
|
||||
|
||||
double boostedDamage = event.getDamage();
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
//Make sure the profiles been loaded
|
||||
if(mcMMOPlayer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MacesManager macesManager = mcMMOPlayer.getMacesManager();
|
||||
|
||||
if(canUseLimitBreak(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK)) {
|
||||
boostedDamage += (getLimitBreakDamage(player, target, SubSkillType.MACES_MACES_LIMIT_BREAK) * mcMMOPlayer.getAttackStrength());
|
||||
}
|
||||
|
||||
event.setDamage(boostedDamage);
|
||||
processCombatXP(mcMMOPlayer, target, PrimarySkillType.MACES);
|
||||
|
||||
printFinalDamageDebug(player, event, mcMMOPlayer);
|
||||
}
|
||||
|
||||
private static void processAxeCombat(@NotNull LivingEntity target, @NotNull Player player, @NotNull EntityDamageByEntityEvent event) {
|
||||
if (event.getCause() == DamageCause.THORNS) {
|
||||
return;
|
||||
@ -498,6 +525,15 @@ public final class CombatUtils {
|
||||
processTridentCombatMelee(target, player, event);
|
||||
}
|
||||
}
|
||||
else if (ItemUtils.isMace(heldItem)) {
|
||||
if (!mcMMO.p.getSkillTools().canCombatSkillsTrigger(PrimarySkillType.MACES, target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mcMMO.p.getSkillTools().doesPlayerHaveSkillPermission(player, PrimarySkillType.MACES)) {
|
||||
processMacesCombat(target, player, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (entityType == EntityType.WOLF) {
|
||||
|
@ -198,6 +198,7 @@ public class SkillTools {
|
||||
case SUPER_SHOTGUN -> PrimarySkillType.CROSSBOWS;
|
||||
case TRIDENTS_SUPER_ABILITY -> PrimarySkillType.TRIDENTS;
|
||||
case EXPLOSIVE_SHOT -> PrimarySkillType.ARCHERY;
|
||||
case MACES_SUPER_ABILITY -> PrimarySkillType.MACES;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ import com.gmail.nossr50.util.text.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Recipe;
|
||||
@ -28,12 +27,13 @@ import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.ShapelessRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import static com.gmail.nossr50.util.PotionEffectMapper.getHaste;
|
||||
|
||||
public final class SkillUtils {
|
||||
/**
|
||||
* This is a static utility class, therefore we don't want any instances of
|
||||
@ -148,13 +148,8 @@ public final class SkillUtils {
|
||||
return;
|
||||
}
|
||||
|
||||
int originalDigSpeed = heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED);
|
||||
|
||||
//Add dig speed
|
||||
|
||||
//Lore no longer gets added, no point to it afaik
|
||||
//ItemUtils.addAbilityLore(heldItem); //lore can be a secondary failsafe for 1.13 and below
|
||||
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(Enchantment.DIG_SPEED));
|
||||
int originalDigSpeed = heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
ItemUtils.addDigSpeedToItem(heldItem, heldItem.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getEfficiency()));
|
||||
|
||||
//1.13.2+ will have persistent metadata for this item
|
||||
mcMMO.getMetadataService().getItemMetadataService().setSuperAbilityBoostedItem(heldItem, originalDigSpeed);
|
||||
@ -162,9 +157,9 @@ public final class SkillUtils {
|
||||
int duration = 0;
|
||||
int amplifier = 0;
|
||||
|
||||
if (player.hasPotionEffect(PotionEffectType.FAST_DIGGING)) {
|
||||
if (player.hasPotionEffect(getHaste())) {
|
||||
for (PotionEffect effect : player.getActivePotionEffects()) {
|
||||
if (effect.getType() == PotionEffectType.FAST_DIGGING) {
|
||||
if (effect.getType() == getHaste()) {
|
||||
duration = effect.getDuration();
|
||||
amplifier = effect.getAmplifier();
|
||||
break;
|
||||
@ -194,7 +189,7 @@ public final class SkillUtils {
|
||||
mcMMO.p.getSkillTools().getSuperAbilityMaxLength(mcMMO.p.getSkillTools().getSuperAbility(skill))) * Misc.TICK_CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
PotionEffect abilityBuff = new PotionEffect(PotionEffectType.FAST_DIGGING, duration + ticks, amplifier + 10);
|
||||
PotionEffect abilityBuff = new PotionEffect(getHaste(), duration + ticks, amplifier + 10);
|
||||
player.addPotionEffect(abilityBuff, true);
|
||||
}
|
||||
}
|
||||
@ -221,7 +216,7 @@ public final class SkillUtils {
|
||||
|
||||
if(itemMeta != null) {
|
||||
// This is safe to call without prior checks.
|
||||
itemMeta.removeEnchant(Enchantment.DIG_SPEED);
|
||||
itemMeta.removeEnchant(mcMMO.p.getEnchantmentMapper().getEfficiency());
|
||||
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
ItemUtils.removeAbilityLore(itemStack);
|
||||
@ -251,7 +246,7 @@ public final class SkillUtils {
|
||||
|
||||
Material type = itemStack.getType();
|
||||
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
|
||||
durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1), maxDurability * maxDamageModifier);
|
||||
durabilityModifier = (int) Math.min(durabilityModifier / (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1), maxDurability * maxDamageModifier);
|
||||
|
||||
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
|
||||
}
|
||||
@ -281,7 +276,7 @@ public final class SkillUtils {
|
||||
|
||||
Material type = itemStack.getType();
|
||||
short maxDurability = mcMMO.getRepairableManager().isRepairable(type) ? mcMMO.getRepairableManager().getRepairable(type).getMaximumDurability() : type.getMaxDurability();
|
||||
durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(Enchantment.DURABILITY) + 1)), maxDurability * maxDamageModifier);
|
||||
durabilityModifier = (int) Math.min(durabilityModifier * (0.6 + 0.4/ (itemStack.getEnchantmentLevel(mcMMO.p.getEnchantmentMapper().getUnbreaking()) + 1)), maxDurability * maxDamageModifier);
|
||||
|
||||
itemStack.setDurability((short) Math.min(itemStack.getDurability() + durabilityModifier, maxDurability));
|
||||
}
|
||||
|
Reference in New Issue
Block a user