mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-06-28 03:34:43 +02:00
WIP 1.20.6 support
This commit is contained in:
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