This commit is contained in:
nossr50 2024-05-15 15:56:50 -07:00
parent 8d2a08c421
commit fc66c9f3fd
8 changed files with 87 additions and 33 deletions

View File

@ -1,8 +1,7 @@
Version 2.2.010
# TODO: Fix not moving mcMMO custom ingredients from hopper -> brewing stand
# TODO: Fix some potions are not rewarding XP ( strength 2, etc )
Fixed being unable to load REGEN potion type on new versions of Paper/Spigot 1.20.6
BrewingStand now remember who owns them, this persists across restarts (see notes)
Fixed some potions not gaining XP when brewed (Level 2 potions, etc)
BrewingStands will now remember who owns them, this persists across restarts (see notes)
Fixed rare NPE in mcMMO events when player data was unable to be retrieved
Fixed a NPE that could happen when damaging armor with Axes
Fixed a bug where Alchemy brewing would be cancelled if the player died
@ -40,6 +39,7 @@ Version 2.2.010
NOTES:
You can now use hoppers and brewing stands and not have to worry about having to re-interact with the brewing stand over and over again
Ownership of a brewing stand is whoever last interacted with it, this persists across restarts
This is not an exhaustive list of API changes in this update, but most of the important ones should be documented here.
Version 2.2.009

View File

@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.gmail.nossr50.mcMMO</groupId>
<artifactId>mcMMO</artifactId>
<version>2.2.010-SNAPSHOT</version>
<version>2.2.010</version>
<name>mcMMO</name>
<url>https://github.com/mcMMO-Dev/mcMMO</url>
<scm>

View File

@ -21,6 +21,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.gmail.nossr50.util.ItemUtils.setItemName;
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
@ -39,7 +40,7 @@ public class PotionConfig extends LegacyConfigLoader {
/**
* Map of potion names to AlchemyPotion objects.
*/
private final Map<String, AlchemyPotion> loadedPotions = new HashMap<>();
private final Map<String, AlchemyPotion> alchemyPotions = new HashMap<>();
public PotionConfig() {
super("potions.yml");
@ -106,7 +107,7 @@ public class PotionConfig extends LegacyConfigLoader {
AlchemyPotion potion = loadPotion(potionSection.getConfigurationSection(potionName));
if (potion != null) {
loadedPotions.put(potionName, potion);
alchemyPotions.put(potionName, potion);
potionsLoaded++;
} else {
failures++;
@ -250,7 +251,7 @@ public class PotionConfig extends LegacyConfigLoader {
// TODO: Might not need to .setItemMeta
itemStack.setItemMeta(potionMeta);
return new AlchemyPotion(itemStack, children);
return new AlchemyPotion(potion_section.getName(), itemStack, children);
} catch (Exception e) {
mcMMO.p.getLogger().warning("PotionConfig: Failed to load Alchemy potion: " + potion_section.getName());
return null;
@ -325,7 +326,7 @@ public class PotionConfig extends LegacyConfigLoader {
* @return AlchemyPotion that corresponds to the given name.
*/
public AlchemyPotion getPotion(String name) {
return loadedPotions.get(name);
return alchemyPotions.get(name);
}
/**
@ -336,12 +337,15 @@ public class PotionConfig extends LegacyConfigLoader {
* @return AlchemyPotion that corresponds to the given ItemStack.
*/
public AlchemyPotion getPotion(ItemStack item) {
for (AlchemyPotion potion : loadedPotions.values()) {
if (potion.isSimilarPotion(item)) {
return potion;
}
final List<AlchemyPotion> potionList = alchemyPotions.values()
.stream()
.filter(potion -> potion.isSimilarPotion(item))
.toList();
if(potionList.size() > 1) {
mcMMO.p.getLogger().severe("Multiple child potions matched for item, when there should only be one: " + item);
}
return null;
return potionList.isEmpty() ? null : potionList.get(0);
}
public Color generateColor(List<PotionEffect> effects) {

View File

@ -15,16 +15,19 @@ import static com.gmail.nossr50.util.PotionUtil.samePotionType;
import static java.util.Objects.requireNonNull;
public class AlchemyPotion {
private final @NotNull ItemStack potionItemstack;
private final @NotNull String potionConfigName;
private final @NotNull ItemStack potionItemStack;
private final @NotNull Map<ItemStack, String> alchemyPotionChildren;
public AlchemyPotion(@NotNull ItemStack potionItemStack, @NotNull Map<ItemStack, String> alchemyPotionChildren) {
this.potionItemstack = requireNonNull(potionItemStack, "potionItemStack cannot be null");
public AlchemyPotion(@NotNull String potionConfigName, @NotNull ItemStack potionItemStack, @NotNull Map<ItemStack, String> alchemyPotionChildren) {
this.potionConfigName = requireNonNull(potionConfigName, "potionConfigName cannot be null");
this.potionItemStack = requireNonNull(potionItemStack, "potionItemStack cannot be null");
this.alchemyPotionChildren = requireNonNull(alchemyPotionChildren, "alchemyPotionChildren cannot be null");
// mcMMO.p.getLogger().info("AlchemyPotion created: " + potionConfigName + ", with children: " + alchemyPotionChildren);
}
public @NotNull ItemStack toItemStack(int amount) {
final ItemStack clone = potionItemstack.clone();
final ItemStack clone = potionItemStack.clone();
clone.setAmount(Math.max(1, amount));
return clone;
}
@ -46,9 +49,12 @@ public class AlchemyPotion {
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() != potionItemstack.getType() || !otherPotion.hasItemMeta()) {
if (otherPotion.getType() != potionItemStack.getType()) {
return false;
}
// no potion meta, no match
if (!otherPotion.hasItemMeta()) {
return false;
}
@ -97,15 +103,15 @@ public class AlchemyPotion {
}
public PotionMeta getAlchemyPotionMeta() {
return (PotionMeta) potionItemstack.getItemMeta();
return (PotionMeta) potionItemStack.getItemMeta();
}
public boolean isSplash() {
return potionItemstack.getType() == Material.SPLASH_POTION;
return potionItemStack.getType() == Material.SPLASH_POTION;
}
public boolean isLingering() {
return potionItemstack.getType() == Material.LINGERING_POTION;
return potionItemStack.getType() == Material.LINGERING_POTION;
}
@Override
@ -113,18 +119,19 @@ public class AlchemyPotion {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AlchemyPotion that = (AlchemyPotion) o;
return Objects.equals(potionItemstack, that.potionItemstack) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
return Objects.equals(potionConfigName, that.potionConfigName) && Objects.equals(potionItemStack, that.potionItemStack) && Objects.equals(alchemyPotionChildren, that.alchemyPotionChildren);
}
@Override
public int hashCode() {
return Objects.hash(potionItemstack, alchemyPotionChildren);
return Objects.hash(potionConfigName, potionItemStack, alchemyPotionChildren);
}
@Override
public String toString() {
return "AlchemyPotion{" +
"potion=" + potionItemstack +
"potionConfigName='" + potionConfigName + '\'' +
", potionItemStack=" + potionItemStack +
", alchemyPotionChildren=" + alchemyPotionChildren +
'}';
}

View File

@ -1,6 +1,7 @@
package com.gmail.nossr50.datatypes.skills.alchemy;
import com.gmail.nossr50.util.PotionUtil;
import org.bukkit.Bukkit;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.potion.PotionEffect;

View File

@ -2,5 +2,5 @@ package com.gmail.nossr50.util;
public enum PotionCompatibilityType {
PRE_1_20_5,
POST_1_20_5
POST_1_20_6
}

View File

@ -58,10 +58,11 @@ public class PotionUtil {
methodPotionTypeGetPotionEffects = getPotionTypeGetPotionEffects();
methodSetBasePotionData = getSetBasePotionData();
if (potionDataClass != null) {
if (potionDataClass != null
&& !mcMMO.getCompatibilityManager().getMinecraftGameVersion().isAtLeast(1, 20, 5)) {
COMPATIBILITY_MODE = PotionCompatibilityType.PRE_1_20_5;
} else {
COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_5;
COMPATIBILITY_MODE = PotionCompatibilityType.POST_1_20_6;
}
}
@ -71,13 +72,13 @@ public class PotionUtil {
* @return The potion type
*/
public static PotionType matchPotionType(String partialName, boolean isUpgraded, boolean isExtended) {
String updatedName = convertLegacyNames(partialName).toUpperCase();
// updatedName = convertUpgradedOrExtended(updatedName, isUpgraded, isExtended);
if (COMPATIBILITY_MODE == PotionCompatibilityType.PRE_1_20_5) {
return matchLegacyPotionType(updatedName);
return matchLegacyPotionType(partialName);
} else {
String updatedName = convertLegacyNames(partialName).toUpperCase();
return Arrays.stream(PotionType.values())
.filter(potionType -> getKeyGetKey(potionType).toUpperCase().contains(partialName)
|| getKeyGetKey(potionType).toUpperCase().contains(convertLegacyNames(updatedName)))
.filter(potionType -> getKeyGetKey(potionType).toUpperCase().contains(updatedName))
.filter(potionType -> !isUpgraded || potionType.name().toUpperCase().contains(STRONG))
.filter(potionType -> !isExtended || potionType.name().toUpperCase().contains(LONG))
.findAny().orElse(null);
@ -99,6 +100,16 @@ public class PotionUtil {
.findAny().orElse(null);
}
private static String convertUpgradedOrExtended(String potionType, boolean isUpgraded, boolean isExtended) {
if (isUpgraded) {
potionType = STRONG + "_" + potionType;
}
if (isExtended) {
potionType = LONG + "_" + potionType;
}
return potionType;
}
public static String getKeyGetKey(PotionType potionType) {
try {
if (getKeyMethod() != null) {

View File

@ -1,14 +1,45 @@
package com.gmail.nossr50.util;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.compat.CompatibilityManager;
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import org.bukkit.potion.PotionType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static com.gmail.nossr50.util.PotionUtil.convertLegacyNames;
import static com.gmail.nossr50.util.PotionUtil.matchPotionType;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
class PotionUtilTest {
MockedStatic<mcMMO> mockedStaticMcMMO;
@BeforeEach
void setUp() {
mockedStaticMcMMO = mockStatic(mcMMO.class);
CompatibilityManager compatibilityManager = mock(CompatibilityManager.class);
MinecraftGameVersion minecraftGameVersion = mock(MinecraftGameVersion.class);
when(compatibilityManager.getMinecraftGameVersion()).thenReturn(minecraftGameVersion);
when(minecraftGameVersion.isAtLeast(1, 20, 5)).thenReturn(true);
when(mcMMO.getCompatibilityManager()).thenReturn(compatibilityManager);
}
@AfterEach
void tearDown() {
mockedStaticMcMMO.close();
}
@Test
void testMatchPotionTypeStrengthII() {
final String potionTypeStr = "STRENGTH";
final PotionType potionType = matchPotionType(potionTypeStr, true, false);
assertEquals(PotionType.STRONG_STRENGTH, potionType);
}
@Test
void testMatchPotionTypeRegen() {
final String potionTypeStr = "REGEN";