Expand PotionMeta Api to allow getting effective potion colour and effects (#12390)

This commit is contained in:
Isaac - The456
2025-05-02 21:31:39 +01:00
committed by GitHub
parent 825685f82f
commit 2bd84f6f0e
4 changed files with 83 additions and 0 deletions

View File

@@ -60,6 +60,27 @@ public interface PotionContents {
@Contract(pure = true) @Contract(pure = true)
@Nullable String customName(); @Nullable String customName();
/**
* All effects that this component applies.
* <p>
* This is a combination of the base potion type and any custom effects.
*
* @return an unmodifiable list of all effects.
*/
@Contract(pure = true)
@Unmodifiable List<PotionEffect> allEffects();
/**
* Computes the effective colour of this potion contents component.
* <p>
* This blends all custom effects, or uses a default fallback colour.
* It may or may not have an alpha channel, used for tipped arrows.
*
* @return the effective colour this component would display with.
*/
@Contract(pure = true)
Color computeEffectiveColor();
@ApiStatus.Experimental @ApiStatus.Experimental
@ApiStatus.NonExtendable @ApiStatus.NonExtendable
interface Builder extends DataComponentBuilder<PotionContents> { interface Builder extends DataComponentBuilder<PotionContents> {

View File

@@ -8,6 +8,7 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType; import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
/** /**
* Represents a potion or item that can have custom effects. * Represents a potion or item that can have custom effects.
@@ -74,6 +75,16 @@ public interface PotionMeta extends ItemMeta {
@NotNull @NotNull
List<PotionEffect> getCustomEffects(); List<PotionEffect> getCustomEffects();
/**
* All effects that this potion meta holds.
* <p>
* This is a combination of the base potion type and any custom effects.
*
* @return an unmodifiable list of all effects.
*/
@NotNull
@Unmodifiable List<PotionEffect> getAllEffects();
/** /**
* Adds a custom potion effect to this potion. * Adds a custom potion effect to this potion.
* *
@@ -146,6 +157,16 @@ public interface PotionMeta extends ItemMeta {
*/ */
void setColor(@Nullable Color color); void setColor(@Nullable Color color);
/**
* Computes the effective colour of this potion meta.
* <p>
* This blends all custom effects, or uses a default fallback color.
*
* @return the effective potion color
*/
@NotNull
Color computeEffectiveColor();
/** /**
* Checks for existence of a custom potion name translation suffix. * Checks for existence of a custom potion name translation suffix.
* *

View File

@@ -5,6 +5,8 @@ import io.papermc.paper.util.MCUtil;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffectInstance;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.craftbukkit.potion.CraftPotionType; import org.bukkit.craftbukkit.potion.CraftPotionType;
@@ -48,6 +50,19 @@ public record PaperPotionContents(
return this.impl.customName().orElse(null); return this.impl.customName().orElse(null);
} }
@Override
public @Unmodifiable List<PotionEffect> allEffects() {
//noinspection SimplifyStreamApiCallChains - explicity want it unmodifiable, as toList() api doesnt guarantee this.
return StreamSupport.stream(this.impl.getAllEffects().spliterator(), false)
.map(CraftPotionUtil::toBukkit)
.collect(Collectors.toUnmodifiableList());
}
@Override
public Color computeEffectiveColor() {
return Color.fromARGB(this.impl.getColor());
}
static final class BuilderImpl implements PotionContents.Builder { static final class BuilderImpl implements PotionContents.Builder {
private final List<MobEffectInstance> customEffects = new ObjectArrayList<>(); private final List<MobEffectInstance> customEffects = new ObjectArrayList<>();

View File

@@ -1,6 +1,7 @@
package org.bukkit.craftbukkit.inventory; package org.bukkit.craftbukkit.inventory;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMap.Builder;
import java.util.ArrayList; import java.util.ArrayList;
@@ -25,6 +26,7 @@ import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType; import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.NotNull;
@DelegateDeserialization(SerializableMeta.class) @DelegateDeserialization(SerializableMeta.class)
class CraftMetaPotion extends CraftMetaItem implements PotionMeta { class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
@@ -202,6 +204,19 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
return ImmutableList.of(); return ImmutableList.of();
} }
@Override
@NotNull
public List<PotionEffect> getAllEffects() {
final ImmutableList.Builder<PotionEffect> builder = ImmutableList.builder();
if (this.hasBasePotionType()) {
builder.addAll(this.getBasePotionType().getPotionEffects());
}
if (this.hasCustomEffects()) {
builder.addAll(this.customEffects);
}
return builder.build();
}
@Override @Override
public boolean addCustomEffect(PotionEffect effect, boolean overwrite) { public boolean addCustomEffect(PotionEffect effect, boolean overwrite) {
Preconditions.checkArgument(effect != null, "Potion effect cannot be null"); Preconditions.checkArgument(effect != null, "Potion effect cannot be null");
@@ -305,6 +320,17 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta {
this.color = color == null ? null : color.asRGB(); this.color = color == null ? null : color.asRGB();
} }
@Override
@NotNull
public Color computeEffectiveColor() {
if (hasColor()) return getColor();
return Color.fromRGB(
PotionContents.getColorOptional(Collections2.transform(getAllEffects(), CraftPotionUtil::fromBukkit))
.orElse(PotionContents.BASE_POTION_COLOR) & 0xFFFFFF
);
}
@Override @Override
public boolean hasCustomPotionName() { public boolean hasCustomPotionName() {
return this.customName != null; return this.customName != null;