Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.denizenscript.denizen.paper.datacomponents;

import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.core.ElementTag;
import io.papermc.paper.datacomponent.DataComponentTypes;
import net.kyori.adventure.key.Key;

public class BreakSoundAdapter extends DataComponentAdapter.Valued<ElementTag, Key> {

// <--[property]
// @object ItemTag
// @name break_sound
// @input ElementTag
// @description
// Controls an item's break sound <@link language Item Components> in namespaced key format.
// The default namespace is "minecraft", so for example an input of "block.anvil.land" becomes "minecraft:block.anvil.land".
// @mechanism
// Provide no input to reset the item to its default value.
// -->

public BreakSoundAdapter() {
super(ElementTag.class, DataComponentTypes.BREAK_SOUND, "break_sound");
}

@Override
public ElementTag toDenizen(Key value) {
return new ElementTag(value.asMinimalString(), true);
}

@Override
public Key fromDenizen(ElementTag value, Mechanism mechanism) {
return Utilities.parseNamespacedKey(value.asString());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ public static void register() {
DataComponentAdapter.register(new MaxDurabilityAdapter());
DataComponentAdapter.register(new MaxStackSizeAdapter());
DataComponentAdapter.register(new RarityAdapter());
DataComponentAdapter.register(new WeaponAdapter());
DataComponentAdapter.register(new BreakSoundAdapter());
DataComponentAdapter.register(new SwingAnimationAdapter());
DataComponentAdapter.register(new EquippableAdapter());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.denizenscript.denizen.paper.datacomponents;

import com.denizenscript.denizen.utilities.Utilities;
import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.Equippable;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import io.papermc.paper.registry.set.RegistrySet;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.EquipmentSlot;

import java.util.ArrayList;
import java.util.List;

public class EquippableAdapter extends DataComponentAdapter.Valued<MapTag, Equippable> {

// <--[property]
// @object ItemTag
// @name equippable
// @input MapTag
// @description
// Controls the properties of an item's equippable <@link language Item Components>.
// The map includes keys:
// - "slot", an ElementTag representing the equipment slot. Valid values: HAND, OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY.
// - "equip_sound", an ElementTag representing the sound played when equipping this item in namespaced key format.
// - "asset_id", an ElementTag representing the asset id for this item in namespaced key format.
// - "camera_overlay", an ElementTag representing the camera overlay to use when the item is equipped in namespaced key format.
// - "allowed_entities", a ListTag(EntityTag) representing entity types that can equip this item. If not set, all entities are allowed to wear this item.
// - "dispensable", a ElementTag(Boolean) controlling whether the item can be dispensed.
// - "swappable", a ElementTag(Boolean) controlling whether the item can be swapped.
// - "damage_on_hurt", a ElementTag(Boolean) controlling whether the item takes damage when the wearer is hurt.
// - "equip_on_interact", a ElementTag(Boolean) controlling whether the item is equipped on entity interaction.
// - "can_be_sheared", a ElementTag(Boolean) controlling whether the item can be sheared off an entity.
// - "shear_sound", an ElementTag representing the sound played when shearing using this item in namespaced key format.
// @mechanism
// Provide no input to reset the item to its default value.
// -->

public EquippableAdapter() {
super(MapTag.class, DataComponentTypes.EQUIPPABLE, "equippable");
}

@Override
public MapTag toDenizen(Equippable value) {
MapTag map = new MapTag();
map.putObject("slot", new ElementTag(value.slot()));
map.putObject("equip_sound", new ElementTag(value.equipSound().asMinimalString(), true));
if (value.assetId() != null) {
map.putObject("asset_id", new ElementTag(value.assetId().asMinimalString(), true));
}
if (value.cameraOverlay() != null) {
map.putObject("camera_overlay", new ElementTag(value.cameraOverlay().asMinimalString(), true));
}
if (value.allowedEntities() != null) {
ListTag entities = new ListTag();
value.allowedEntities().forEach(key -> entities.addObject(new ElementTag(key.key().asMinimalString(), true)));
map.putObject("allowed_entities", entities);
}
map.putObject("dispensable", new ElementTag(value.dispensable()));
map.putObject("swappable", new ElementTag(value.swappable()));
map.putObject("damage_on_hurt", new ElementTag(value.damageOnHurt()));
map.putObject("equip_on_interact", new ElementTag(value.equipOnInteract()));
map.putObject("can_be_sheared", new ElementTag(value.canBeSheared()));
map.putObject("shear_sound", new ElementTag(value.shearSound().asMinimalString(), true));
return map;
}

@Override
public Equippable fromDenizen(MapTag value, Mechanism mechanism) {
ElementTag slot = value.getObjectAs("slot", ElementTag.class, mechanism.context);
if (slot == null) {
mechanism.echoError("Equippable map must have a 'slot' key.");
return null;
}
if (!slot.matchesEnum(EquipmentSlot.class)) {
mechanism.echoError("Invalid 'slot' specified for equippable: must be a valid EquipmentSlot.");
return null;
}
Equippable.Builder builder = Equippable.equippable(slot.asEnum(EquipmentSlot.class));
setIfValid(builder::equipSound, value, "equip_sound", ElementTag.class, null, element -> Utilities.parseNamespacedKey(element.asString()), "namespaced key", mechanism);
setIfValid(builder::assetId, value, "asset_id", ElementTag.class, null, element -> Utilities.parseNamespacedKey(element.asString()), "namespaced key", mechanism);
setIfValid(builder::cameraOverlay, value, "camera_overlay", ElementTag.class, null, element -> Utilities.parseNamespacedKey(element.asString()), "namespaced key", mechanism);
setIfValid(builder::dispensable, value, "dispensable", ElementTag.class, ElementTag::isBoolean, ElementTag::asBoolean, "boolean", mechanism);
setIfValid(builder::swappable, value, "swappable", ElementTag.class, ElementTag::isBoolean, ElementTag::asBoolean, "boolean", mechanism);
setIfValid(builder::damageOnHurt, value, "damage_on_hurt", ElementTag.class, ElementTag::isBoolean, ElementTag::asBoolean, "boolean", mechanism);
setIfValid(builder::equipOnInteract, value, "equip_on_interact", ElementTag.class, ElementTag::isBoolean, ElementTag::asBoolean, "boolean", mechanism);
setIfValid(builder::canBeSheared, value, "can_be_sheared", ElementTag.class, ElementTag::isBoolean, ElementTag::asBoolean, "boolean", mechanism);
setIfValid(builder::shearSound, value, "shear_sound", ElementTag.class, null, element -> Utilities.parseNamespacedKey(element.asString()), "namespaced key", mechanism);
ListTag entityList = value.getObjectAs("allowed_entities", ListTag.class, mechanism.context);
if (entityList != null) {
List<TypedKey<EntityType>> keys = new ArrayList<>();
for (String entry : entityList) {
keys.add(TypedKey.create(RegistryKey.ENTITY_TYPE, Utilities.parseNamespacedKey(entry)));
}
builder.allowedEntities(RegistrySet.keySet(RegistryKey.ENTITY_TYPE, keys));
}
return builder.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.denizenscript.denizen.paper.datacomponents;

import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.SwingAnimation;

public class SwingAnimationAdapter extends DataComponentAdapter.Valued<MapTag, SwingAnimation> {

// <--[property]
// @object ItemTag
// @name swing_animation
// @input ElementTag
// @description
// Controls an item's swing animation <@link language Item Components>.
// The map includes keys:
// - "animation_type", an ElementTag representing the animation type. Valid animation types can be found at <@link url https://jd.papermc.io/paper/io/papermc/paper/datacomponent/item/SwingAnimation.Animation.html>
// - "duration", an ElementTag(Number) representing the duration of the animation.
// @mechanism
// Provide no input to reset the item to its default value.
// -->

public SwingAnimationAdapter() {
super(MapTag.class, DataComponentTypes.SWING_ANIMATION, "swing_animation");
}

@Override
public MapTag toDenizen(SwingAnimation value) {
MapTag result = new MapTag();
result.putObject("animation_type", new ElementTag(value.type()));
result.putObject("duration", new ElementTag(value.duration()));
return result;
}

@Override
public SwingAnimation fromDenizen(MapTag value, Mechanism mechanism) {
SwingAnimation.Builder builder = SwingAnimation.swingAnimation();
setIfValid(builder::type, value, "animation_type", ElementTag.class,
element -> element.matchesEnum(SwingAnimation.Animation.class),
element -> element.asEnum(SwingAnimation.Animation.class),
"animation type", mechanism);
setIfValid(builder::duration, value, "duration", ElementTag.class, ElementTag::isInt, ElementTag::asInt, "number", mechanism);
return builder.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.denizenscript.denizen.paper.datacomponents;

import com.denizenscript.denizencore.objects.Mechanism;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.MapTag;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.Weapon;

public class WeaponAdapter extends DataComponentAdapter.Valued<MapTag, Weapon> {

// <--[property]
// @object ItemTag
// @name weapon
// @input MapTag
// @description
// Controls an item's weapon <@link language Item Components>.
// The map includes keys:
// - "disable_blocking_duration", an ElementTag(Decimal) representing the number of seconds that a shield will be disabled for after blocking an attack from this item.
// - "item_damage_per_attack", an ElementTag(Number) representing the amount of durability damage this item will take when used to attack an entity or break a block.
// @mechanism
// Provide no input to reset the item to its default value.
// -->

public WeaponAdapter() {
super(MapTag.class, DataComponentTypes.WEAPON, "weapon");
}

@Override
public MapTag toDenizen(Weapon value) {
MapTag weaponData = new MapTag();
weaponData.putObject("disable_blocking_duration", new ElementTag(value.disableBlockingForSeconds()));
weaponData.putObject("item_damage_per_attack", new ElementTag(value.itemDamagePerAttack()));
return weaponData;
}

@Override
public Weapon fromDenizen(MapTag value, Mechanism mechanism) {
Weapon.Builder builder = Weapon.weapon();
setIfValid(builder::disableBlockingForSeconds, value, "disable_blocking_duration", ElementTag.class, ElementTag::isFloat, ElementTag::asFloat, "decimal number", mechanism);
setIfValid(builder::itemDamagePerAttack, value, "item_damage_per_attack", ElementTag.class, ElementTag::isInt, ElementTag::asInt, "number", mechanism);
return builder.build();
}
}