Skip to content
Closed
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/main/java/org/spongepowered/api/data/Keys.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.spongepowered.api.data.type.HorseColor;
import org.spongepowered.api.data.type.HorseStyle;
import org.spongepowered.api.data.type.InstrumentType;
import org.spongepowered.api.data.type.ItemActionEffect;
import org.spongepowered.api.data.type.ItemTier;
import org.spongepowered.api.data.type.LlamaType;
import org.spongepowered.api.data.type.MatterType;
Expand Down Expand Up @@ -398,11 +399,6 @@ public final class Keys {
*/
public static final Key<Value<Integer>> ANGER_LEVEL = Keys.key(ResourceKey.sponge("anger_level"), Integer.class);

/**
* The set of {@link PotionEffect}s applied on use of an {@link ItemStack}.
*/
public static final Key<WeightedCollectionValue<PotionEffect>> APPLICABLE_POTION_EFFECTS = Keys.weightedKey(ResourceKey.sponge("applicable_potion_effects"), PotionEffect.class);
Copy link
Member

@Yeregorix Yeregorix Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because API-14 have been released, this would be a breaking change. Rebase the PR to API-15 or keep this key for now and remove it in later versions.


/**
* The enchantments applied to an {@link ItemStack}.
*
Expand Down Expand Up @@ -777,6 +773,11 @@ public final class Keys {
*/
public static final Key<SetValue<Direction>> CONNECTED_DIRECTIONS = Keys.setKey(ResourceKey.sponge("connected_directions"), Direction.class);

/**
* The {@link ItemActionEffect}s an {@link ItemStack} will apply when consumed.
*/
public static final Key<ListValue<ItemActionEffect>> CONSUME_EFFECTS = Keys.listKey(ResourceKey.sponge("consume_effects"), ItemActionEffect.class);

/**
* The container {@link ItemType} of an {@link ItemStack}.
* e.g. {@link ItemTypes#BUCKET} for a {@link ItemTypes#WATER_BUCKET} stack.
Expand Down Expand Up @@ -927,6 +928,11 @@ public final class Keys {
*/
public static final Key<Value<Double>> DAMAGE_PER_BLOCK = Keys.key(ResourceKey.sponge("damage_per_block"), Double.class);

/**
* The {@link ItemActionEffect}s an {@link ItemStack} will apply on death.
*/
public static final Key<ListValue<ItemActionEffect>> DEATH_PROTECTION_EFFECTS = Keys.listKey(ResourceKey.sponge("death_protection_effects"), ItemActionEffect.class);

/**
* The distance at which a {@link BlockState} will decay.
* This usually applies to leaves, for example {@link BlockTypes#OAK_LEAVES}.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* This file is part of SpongeAPI, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.api.data.type;

import org.spongepowered.api.ResourceKey;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.registry.DefaultedRegistryReference;
import org.spongepowered.api.registry.Registry;
import org.spongepowered.api.registry.RegistryKey;
import org.spongepowered.api.registry.RegistryScope;
import org.spongepowered.api.registry.RegistryScopes;
import org.spongepowered.api.registry.RegistryTypes;

/**
* <!-- This file is automatically generated. Any manual changes will be overwritten. -->
*/
@SuppressWarnings("unused")
@RegistryScopes(scopes = RegistryScope.GAME)
public final class ConsumeEffectTypes {

public static final DefaultedRegistryReference<ItemActionEffectType> APPLY_EFFECTS = ConsumeEffectTypes.key(ResourceKey.minecraft("apply_effects"));

public static final DefaultedRegistryReference<ItemActionEffectType> CLEAR_ALL_EFFECTS = ConsumeEffectTypes.key(ResourceKey.minecraft("clear_all_effects"));

public static final DefaultedRegistryReference<ItemActionEffectType> PLAY_SOUND = ConsumeEffectTypes.key(ResourceKey.minecraft("play_sound"));

public static final DefaultedRegistryReference<ItemActionEffectType> REMOVE_EFFECTS = ConsumeEffectTypes.key(ResourceKey.minecraft("remove_effects"));

public static final DefaultedRegistryReference<ItemActionEffectType> TELEPORT_RANDOMLY = ConsumeEffectTypes.key(ResourceKey.minecraft("teleport_randomly"));

private ConsumeEffectTypes() {
}

public static Registry<ItemActionEffectType> registry() {
return Sponge.game().registry(RegistryTypes.ITEM_ACTION_EFFECT_TYPE);
}

private static DefaultedRegistryReference<ItemActionEffectType> key(final ResourceKey location) {
return RegistryKey.of(RegistryTypes.ITEM_ACTION_EFFECT_TYPE, location).asDefaultedReference(Sponge::game);
}
}
202 changes: 202 additions & 0 deletions src/main/java/org/spongepowered/api/data/type/ItemActionEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
* This file is part of SpongeAPI, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.api.data.type;

import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.Keys;
import org.spongepowered.api.effect.potion.PotionEffect;
import org.spongepowered.api.effect.potion.PotionEffectType;
import org.spongepowered.api.effect.sound.SoundType;
import org.spongepowered.api.entity.living.Living;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.item.inventory.ItemStackLike;
import org.spongepowered.api.tag.Tag;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
* Represents an effect an {@link ItemStack} can apply after some actions.
*
* @see Keys#CONSUME_EFFECTS
* @see Keys#DEATH_PROTECTION_EFFECTS
*/
public interface ItemActionEffect {

static ApplyEffects applyEffects(final Collection<PotionEffect> effects) {
return ItemActionEffect.applyEffects(1.0D, effects);
}

static ApplyEffects applyEffects(final PotionEffect... effects) {
return ItemActionEffect.applyEffects(1.0D, effects);
}

static ApplyEffects applyEffects(final double chance, final Collection<PotionEffect> effects) {
return ItemActionEffect.factory().applyEffects(chance, List.copyOf(effects));
}

static ApplyEffects applyEffects(final double chance, final PotionEffect... effects) {
return ItemActionEffect.factory().applyEffects(chance, List.of(effects));
}

static RemoveEffects removeEffects(final Collection<PotionEffectType> effectTypes) {
return ItemActionEffect.factory().removeEffects(Set.copyOf(effectTypes));
}

static RemoveEffects removeEffects(final PotionEffectType... effectTypes) {
return ItemActionEffect.factory().removeEffects(Set.of(effectTypes));
}

@SafeVarargs
static RemoveEffects removeEffects(final Supplier<PotionEffectType>... effectTypes) {
return ItemActionEffect.factory().removeEffects(Arrays.stream(effectTypes).map(Supplier::get).collect(Collectors.toSet()));
}

static RemoveEffects removeEffects(final Tag<PotionEffectType> effectTypeTag) {
return ItemActionEffect.factory().removeEffects(effectTypeTag);
}

static ClearEffects clearEffects() {
return ItemActionEffect.factory().clearEffects();
}

static PlaySound playSound(final SoundType soundType) {
return ItemActionEffect.factory().playSound(soundType);
}

static PlaySound playSound(final Supplier<SoundType> soundType) {
return ItemActionEffect.factory().playSound(soundType.get());
}

static TeleportRandomly teleportRandomly(final double distance) {
return ItemActionEffect.factory().teleportRandomly(distance);
}

private static Factory factory() {
return Sponge.game().factoryProvider().provide(Factory.class);
}

/**
* Returns the type of this effect.
* @return The type of this effect
*/
ItemActionEffectType type();

/**
* Tries to apply this effect and returns whether it was successfully applied.
* The definition of success is purely left up to the implementation.
*
* @param entity The entity to apply effect to
* @param stack The item to apply effect with
* @return true if effect was successfully applied
*/
boolean apply(Living entity, ItemStackLike stack);

/**
* Applies this effect with {@link ItemStack#empty()}.
*
* @param entity The entity to apply effect to
* @return true if effect was successfully applied
* @see #apply(Living, ItemStackLike)
*/
default boolean apply(final Living entity) {
return this.apply(entity, ItemStack.empty());
}

/**
* Applies {@link PotionEffect}s with chance.
*/
interface ApplyEffects extends ItemActionEffect {
/**
* Returns the probability for effects to be applied.
* @return The probability for effects to be applied
*/
double chance();

/**
* Returns {@link PotionEffect}s that will be applied.
* @return {@link PotionEffect}s that will be applied
*/
List<PotionEffect> effects();
}

/**
* Removes {@link PotionEffect}s with matching {@link PotionEffectType}s.
*/
interface RemoveEffects extends ItemActionEffect {
/**
* Returns {@link PotionEffectType}s that will be removed.
* @return {@link PotionEffectType}s that will be removed
*/
Set<PotionEffectType> effectTypes();
}

/**
* Clears all {@link PotionEffect}s.
*/
interface ClearEffects extends ItemActionEffect {
}

/**
* Plays {@link SoundType}.
*/
interface PlaySound extends ItemActionEffect {
/**
* Returns the consumption {@link SoundType}.
* @return The consumption {@link SoundType}
*/
SoundType soundType();
}

/**
* Teleports randomly within maximum distance.
*/
interface TeleportRandomly extends ItemActionEffect {
/**
* Returns the maximum distance entity can be teleported.
* @return The maximum distance entity can be teleported
*/
double distance();
}

interface Factory {

ApplyEffects applyEffects(double chance, List<PotionEffect> effects);

RemoveEffects removeEffects(Set<PotionEffectType> effectTypes);

RemoveEffects removeEffects(Tag<PotionEffectType> effectTypeTag);

ClearEffects clearEffects();

PlaySound playSound(SoundType soundType);

TeleportRandomly teleportRandomly(double distance);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* This file is part of SpongeAPI, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.api.data.type;

import org.spongepowered.api.registry.DefaultedRegistryValue;
import org.spongepowered.api.util.annotation.CatalogedBy;

/**
* Represents a possible type of {@link ItemActionEffect}.
*/
@CatalogedBy(ConsumeEffectTypes.class)
public interface ItemActionEffectType extends DefaultedRegistryValue {
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
package org.spongepowered.api.effect.potion;

import net.kyori.adventure.text.ComponentLike;
import org.spongepowered.api.registry.DefaultedRegistryValue;
import org.spongepowered.api.tag.Taggable;
import org.spongepowered.api.util.annotation.CatalogedBy;

/**
* Represents a possible type of {@link PotionEffect}.
*/
@CatalogedBy(PotionEffectTypes.class)
public interface PotionEffectType extends DefaultedRegistryValue, ComponentLike {
public interface PotionEffectType extends Taggable<PotionEffectType>, ComponentLike {

/**
* Gets whether this potion effect is applied instantly or over time.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.spongepowered.api.data.type.HorseColor;
import org.spongepowered.api.data.type.HorseStyle;
import org.spongepowered.api.data.type.InstrumentType;
import org.spongepowered.api.data.type.ItemActionEffectType;
import org.spongepowered.api.data.type.ItemTier;
import org.spongepowered.api.data.type.JigsawBlockOrientation;
import org.spongepowered.api.data.type.LlamaType;
Expand Down Expand Up @@ -226,6 +227,8 @@ public final class RegistryTypes {

public static final DefaultedRegistryType<ChunkState> CHUNK_STATE = RegistryTypes.minecraftKeyInGame("chunk_status");

public static final DefaultedRegistryType<ItemActionEffectType> ITEM_ACTION_EFFECT_TYPE = RegistryTypes.minecraftKeyInGame("consume_effect_type");

public static final DefaultedRegistryType<ContainerType> CONTAINER_TYPE = RegistryTypes.minecraftKeyInGame("menu");

public static final DefaultedRegistryType<DensityFunction> DENSITY_FUNCTION = RegistryTypes.minecraftKeyInServer("worldgen/density_function");
Expand Down Expand Up @@ -373,7 +376,7 @@ public final class RegistryTypes {

public static final DefaultedRegistryType<EquipmentType> EQUIPMENT_TYPE = RegistryTypes.spongeKeyInGame("equipment_type");

public static final RegistryType<ExplosionBlockInteraction> EXPLOSION_BLOCK_INTERACTION = RegistryTypes.spongeKeyInGame("explosion_block_interaction");
public static final DefaultedRegistryType<ExplosionBlockInteraction> EXPLOSION_BLOCK_INTERACTION = RegistryTypes.spongeKeyInGame("explosion_block_interaction");

public static final DefaultedRegistryType<FireworkShape> FIREWORK_SHAPE = RegistryTypes.spongeKeyInGame("firework_shape");

Expand Down Expand Up @@ -517,7 +520,7 @@ public final class RegistryTypes {

public static final DefaultedRegistryType<Tilt> TILT = RegistryTypes.spongeKeyInGame("tilt");

public static final RegistryType<VaultState> VAULT_STATE = RegistryTypes.spongeKeyInGame("vault_state");
public static final DefaultedRegistryType<VaultState> VAULT_STATE = RegistryTypes.spongeKeyInGame("vault_state");

public static final DefaultedRegistryType<Visibility> VISIBILITY = RegistryTypes.spongeKeyInGame("visibility");

Expand Down