diff --git a/src/main/java/org/spongepowered/api/data/Keys.java b/src/main/java/org/spongepowered/api/data/Keys.java index a22f3aacd7..793332a390 100644 --- a/src/main/java/org/spongepowered/api/data/Keys.java +++ b/src/main/java/org/spongepowered/api/data/Keys.java @@ -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.ItemAction; import org.spongepowered.api.data.type.ItemTier; import org.spongepowered.api.data.type.LlamaType; import org.spongepowered.api.data.type.MatterType; @@ -779,6 +780,11 @@ public final class Keys { */ public static final Key> CONNECTED_DIRECTIONS = Keys.setKey(ResourceKey.sponge("connected_directions"), Direction.class); + /** + * The {@link ItemAction}s an {@link ItemStack} will apply when consumed. + */ + public static final Key> CONSUME_ACTIONS = Keys.listKey(ResourceKey.sponge("consume_effects"), ItemAction.class); + /** * The container {@link ItemType} of an {@link ItemStack}. * e.g. {@link ItemTypes#BUCKET} for a {@link ItemTypes#WATER_BUCKET} stack. @@ -929,6 +935,11 @@ public final class Keys { */ public static final Key> DAMAGE_PER_BLOCK = Keys.key(ResourceKey.sponge("damage_per_block"), Double.class); + /** + * The {@link ItemAction}s an {@link ItemStack} will apply on death. + */ + public static final Key> DEATH_PROTECTION_ACTIONS = Keys.listKey(ResourceKey.sponge("death_protection_effects"), ItemAction.class); + /** * The distance at which a {@link BlockState} will decay. * This usually applies to leaves, for example {@link BlockTypes#OAK_LEAVES}. diff --git a/src/main/java/org/spongepowered/api/data/type/ItemAction.java b/src/main/java/org/spongepowered/api/data/type/ItemAction.java new file mode 100644 index 0000000000..2516dfaaf9 --- /dev/null +++ b/src/main/java/org/spongepowered/api/data/type/ItemAction.java @@ -0,0 +1,202 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * 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 action an {@link ItemStack} can apply to {@link Living} in different circumstances. + * + * @see Keys#CONSUME_ACTIONS + * @see Keys#DEATH_PROTECTION_ACTIONS + */ +public interface ItemAction { + + static ApplyEffects applyEffects(final Collection effects) { + return ItemAction.applyEffects(1.0D, effects); + } + + static ApplyEffects applyEffects(final PotionEffect... effects) { + return ItemAction.applyEffects(1.0D, effects); + } + + static ApplyEffects applyEffects(final double chance, final Collection effects) { + return ItemAction.factory().applyEffects(chance, List.copyOf(effects)); + } + + static ApplyEffects applyEffects(final double chance, final PotionEffect... effects) { + return ItemAction.factory().applyEffects(chance, List.of(effects)); + } + + static RemoveEffects removeEffects(final Collection effectTypes) { + return ItemAction.factory().removeEffects(Set.copyOf(effectTypes)); + } + + static RemoveEffects removeEffects(final PotionEffectType... effectTypes) { + return ItemAction.factory().removeEffects(Set.of(effectTypes)); + } + + @SafeVarargs + static RemoveEffects removeEffects(final Supplier... effectTypes) { + return ItemAction.factory().removeEffects(Arrays.stream(effectTypes).map(Supplier::get).collect(Collectors.toSet())); + } + + static RemoveEffects removeEffects(final Tag effectTypeTag) { + return ItemAction.factory().removeEffects(effectTypeTag); + } + + static ClearEffects clearEffects() { + return ItemAction.factory().clearEffects(); + } + + static PlaySound playSound(final SoundType soundType) { + return ItemAction.factory().playSound(soundType); + } + + static PlaySound playSound(final Supplier soundType) { + return ItemAction.factory().playSound(soundType.get()); + } + + static TeleportRandomly teleportRandomly(final double distance) { + return ItemAction.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 + */ + ItemActionType 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 ItemAction { + /** + * 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 effects(); + } + + /** + * Removes {@link PotionEffect}s with matching {@link PotionEffectType}s. + */ + interface RemoveEffects extends ItemAction { + /** + * Returns {@link PotionEffectType}s that will be removed. + * @return {@link PotionEffectType}s that will be removed + */ + Set effectTypes(); + } + + /** + * Clears all {@link PotionEffect}s. + */ + interface ClearEffects extends ItemAction { + } + + /** + * Plays {@link SoundType}. + */ + interface PlaySound extends ItemAction { + /** + * Returns the consumption {@link SoundType}. + * @return The consumption {@link SoundType} + */ + SoundType soundType(); + } + + /** + * Teleports randomly within maximum distance. + */ + interface TeleportRandomly extends ItemAction { + /** + * 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 effects); + + RemoveEffects removeEffects(Set effectTypes); + + RemoveEffects removeEffects(Tag effectTypeTag); + + ClearEffects clearEffects(); + + PlaySound playSound(SoundType soundType); + + TeleportRandomly teleportRandomly(double distance); + } +} diff --git a/src/main/java/org/spongepowered/api/data/type/ItemActionType.java b/src/main/java/org/spongepowered/api/data/type/ItemActionType.java new file mode 100644 index 0000000000..16d0bfcae8 --- /dev/null +++ b/src/main/java/org/spongepowered/api/data/type/ItemActionType.java @@ -0,0 +1,35 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * 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 ItemAction}. + */ +@CatalogedBy(ItemActionTypes.class) +public interface ItemActionType extends DefaultedRegistryValue { +} diff --git a/src/main/java/org/spongepowered/api/data/type/ItemActionTypes.java b/src/main/java/org/spongepowered/api/data/type/ItemActionTypes.java new file mode 100644 index 0000000000..e01c637e80 --- /dev/null +++ b/src/main/java/org/spongepowered/api/data/type/ItemActionTypes.java @@ -0,0 +1,63 @@ +/* + * This file is part of SpongeAPI, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * 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; + +/** + * + */ +@SuppressWarnings("unused") +@RegistryScopes(scopes = RegistryScope.GAME) +public final class ItemActionTypes { + + public static final DefaultedRegistryReference APPLY_EFFECTS = ItemActionTypes.key(ResourceKey.minecraft("apply_effects")); + + public static final DefaultedRegistryReference CLEAR_ALL_EFFECTS = ItemActionTypes.key(ResourceKey.minecraft("clear_all_effects")); + + public static final DefaultedRegistryReference PLAY_SOUND = ItemActionTypes.key(ResourceKey.minecraft("play_sound")); + + public static final DefaultedRegistryReference REMOVE_EFFECTS = ItemActionTypes.key(ResourceKey.minecraft("remove_effects")); + + public static final DefaultedRegistryReference TELEPORT_RANDOMLY = ItemActionTypes.key(ResourceKey.minecraft("teleport_randomly")); + + private ItemActionTypes() { + } + + public static Registry registry() { + return Sponge.game().registry(RegistryTypes.ITEM_ACTION_TYPE); + } + + private static DefaultedRegistryReference key(final ResourceKey location) { + return RegistryKey.of(RegistryTypes.ITEM_ACTION_TYPE, location).asDefaultedReference(Sponge::game); + } +} diff --git a/src/main/java/org/spongepowered/api/effect/potion/PotionEffectType.java b/src/main/java/org/spongepowered/api/effect/potion/PotionEffectType.java index 1641f495db..300f888df1 100644 --- a/src/main/java/org/spongepowered/api/effect/potion/PotionEffectType.java +++ b/src/main/java/org/spongepowered/api/effect/potion/PotionEffectType.java @@ -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, ComponentLike { /** * Gets whether this potion effect is applied instantly or over time. diff --git a/src/main/java/org/spongepowered/api/registry/RegistryTypes.java b/src/main/java/org/spongepowered/api/registry/RegistryTypes.java index b4cc7d8aad..067ebe1f63 100644 --- a/src/main/java/org/spongepowered/api/registry/RegistryTypes.java +++ b/src/main/java/org/spongepowered/api/registry/RegistryTypes.java @@ -65,6 +65,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.ItemActionType; import org.spongepowered.api.data.type.ItemTier; import org.spongepowered.api.data.type.JigsawBlockOrientation; import org.spongepowered.api.data.type.LlamaType; @@ -224,6 +225,8 @@ public final class RegistryTypes { public static final DefaultedRegistryType CHUNK_STATE = RegistryTypes.minecraftKeyInGame("chunk_status"); + public static final DefaultedRegistryType ITEM_ACTION_TYPE = RegistryTypes.minecraftKeyInGame("consume_effect_type"); + public static final DefaultedRegistryType CONTAINER_TYPE = RegistryTypes.minecraftKeyInGame("menu"); public static final DefaultedRegistryType DENSITY_FUNCTION = RegistryTypes.minecraftKeyInServer("worldgen/density_function");