Skip to content

Commit

Permalink
redesign input for attribute_modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed May 20, 2021
1 parent 32aa336 commit 88a68e0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 36 deletions.
Expand Up @@ -22,6 +22,7 @@
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;

public class EntityAttributeModifiers implements Property {

Expand Down Expand Up @@ -194,6 +195,26 @@ public ObjectTag getObjectAttribute(Attribute attribute) {
return null;
}

public static void addAttributeModifiers(Consumer<AttributeModifier> addModifier, org.bukkit.attribute.Attribute attr, ObjectTag subValue) {
if (subValue instanceof MapTag) {
MapTag attrMap = (MapTag) subValue;
List<StringHolder> keys = new ArrayList<>(attrMap.map.keySet());
keys.sort((k, k2) -> {
int a = Integer.parseInt(k.str);
int b = Integer.parseInt(k2.str);
return Integer.compare(a, b);
});
for (StringHolder index : keys) {
addModifier.accept(modiferForMap(attr, (MapTag) attrMap.map.get(index)));
}
}
else {
for (ObjectTag listValue : (((ListTag) subValue).objectForms)) {
addModifier.accept(modiferForMap(attr, (MapTag) listValue));
}
}
}

@Override
public void adjust(Mechanism mechanism) {

Expand All @@ -204,7 +225,7 @@ public void adjust(Mechanism mechanism) {
// @description
// Sets the attribute modifiers of an entity.
// This is a SET operation, meaning pre-existing modifiers are removed.
// Specify a MapTag where the keys are attribute names, and values are a ListTag of modifiers,
// Specify a MapTag where the keys are attribute names, and values are a ListTag of modifiers (or a numbered-index MapTag),
// where each modifier is itself a MapTag with required keys 'operation' and 'amount', and optional keys 'name', 'slot', and 'id'.
// Valid operations: ADD_NUMBER, ADD_SCALAR, and MULTIPLY_SCALAR_1
// Valid slots: HAND, OFF_HAND, FEET, LEGS, CHEST, HEAD, ANY
Expand All @@ -218,22 +239,25 @@ public void adjust(Mechanism mechanism) {
// <EntityTag.attribute_value>
// -->
if (mechanism.matches("attribute_modifiers") && mechanism.requireObject(MapTag.class)) {
MapTag input = mechanism.valueAsType(MapTag.class);
Attributable ent = (Attributable) entity.getBukkitEntity();
for (Map.Entry<StringHolder, ObjectTag> subValue : input.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(subValue.getKey().str.toUpperCase());
AttributeInstance instance = ent.getAttribute(attr);
if (instance == null) {
mechanism.echoError("Attribute " + attr.name() + " is not applicable to entity of type " + entity.getBukkitEntity().getType().name());
continue;
}
for (AttributeModifier modifier : instance.getModifiers()) {
instance.removeModifier(modifier);
}
for (ObjectTag listValue : (((ListTag) subValue.getValue()).objectForms)) {
instance.addModifier(modiferForMap(attr, (MapTag) listValue));
try {
MapTag input = mechanism.valueAsType(MapTag.class);
Attributable ent = (Attributable) entity.getBukkitEntity();
for (Map.Entry<StringHolder, ObjectTag> subValue : input.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(subValue.getKey().str.toUpperCase());
AttributeInstance instance = ent.getAttribute(attr);
if (instance == null) {
mechanism.echoError("Attribute " + attr.name() + " is not applicable to entity of type " + entity.getBukkitEntity().getType().name());
continue;
}
for (AttributeModifier modifier : instance.getModifiers()) {
instance.removeModifier(modifier);
}
addAttributeModifiers(instance::addModifier, attr, subValue.getValue());
}
}
catch (Throwable ex) {
Debug.echoError(ex);
}
}

// <--[mechanism]
Expand All @@ -251,19 +275,22 @@ public void adjust(Mechanism mechanism) {
// <EntityTag.attribute_value>
// -->
if (mechanism.matches("add_attribute_modifiers") && mechanism.requireObject(MapTag.class)) {
MapTag input = mechanism.valueAsType(MapTag.class);
Attributable ent = (Attributable) entity.getBukkitEntity();
for (Map.Entry<StringHolder, ObjectTag> subValue : input.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(subValue.getKey().str.toUpperCase());
AttributeInstance instance = ent.getAttribute(attr);
if (instance == null) {
mechanism.echoError("Attribute " + attr.name() + " is not applicable to entity of type " + entity.getBukkitEntity().getType().name());
continue;
}
for (ObjectTag listValue : (((ListTag) subValue.getValue()).objectForms)) {
instance.addModifier(modiferForMap(attr, (MapTag) listValue));
try {
MapTag input = mechanism.valueAsType(MapTag.class);
Attributable ent = (Attributable) entity.getBukkitEntity();
for (Map.Entry<StringHolder, ObjectTag> subValue : input.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(subValue.getKey().str.toUpperCase());
AttributeInstance instance = ent.getAttribute(attr);
if (instance == null) {
mechanism.echoError("Attribute " + attr.name() + " is not applicable to entity of type " + entity.getBukkitEntity().getType().name());
continue;
}
addAttributeModifiers(instance::addModifier, attr, subValue.getValue());
}
}
catch (Throwable ex) {
Debug.echoError(ex);
}
}

// <--[mechanism]
Expand Down
Expand Up @@ -135,10 +135,7 @@ public void adjust(Mechanism mechanism) {
MapTag map = mechanism.valueAsType(MapTag.class);
for (Map.Entry<StringHolder, ObjectTag> mapEntry : map.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(mapEntry.getKey().str.toUpperCase());
for (ObjectTag modifier : ((ListTag) mapEntry.getValue()).objectForms) {
AttributeModifier attrMod = EntityAttributeModifiers.modiferForMap(attr, (MapTag) modifier);
metaMap.put(attr, attrMod);
}
EntityAttributeModifiers.addAttributeModifiers((mod) -> metaMap.put(attr, mod), attr, mapEntry.getValue());
}
ItemMeta meta = item.getItemMeta();
meta.setAttributeModifiers(metaMap);
Expand All @@ -160,9 +157,7 @@ public void adjust(Mechanism mechanism) {
MapTag input = mechanism.valueAsType(MapTag.class);
for (Map.Entry<StringHolder, ObjectTag> subValue : input.map.entrySet()) {
org.bukkit.attribute.Attribute attr = org.bukkit.attribute.Attribute.valueOf(subValue.getKey().str.toUpperCase());
for (ObjectTag listValue : (((ListTag) subValue.getValue()).objectForms)) {
meta.addAttributeModifier(attr, EntityAttributeModifiers.modiferForMap(attr, (MapTag) listValue));
}
EntityAttributeModifiers.addAttributeModifiers((mod) -> meta.addAttributeModifier(attr, mod), attr, subValue.getValue());
}
item.setItemMeta(meta);
}
Expand Down
Expand Up @@ -58,10 +58,21 @@ public class ItemScriptContainer extends ScriptContainer {
// unbreakable: true
// # Other common example
// custom_model_data: 5
// # This mess demonstrates how to add a custom attribute modifier.
// # This demonstrates how to add a custom attribute modifier.
// attribute_modifiers:
// # One subkey for each attribute you want to modify.
// generic_armor:
// - <map.with[operation].as[add_number].with[amount].as[5].with[slot].as[head]>
// # Each attribute can have a list of modifiers, using numbered keys. They will be applied in numeric order, low to high.
// 1:
// # Each modifier requires keys 'operation' and 'amount', and can optionally have keys 'name', 'slot', and 'id'.
// # Operations can be: ADD_NUMBER, ADD_SCALAR, and MULTIPLY_SCALAR_1
// operation: add_number
// amount: 5
// # Slots can be: HAND, OFF_HAND, FEET, LEGS, CHEST, HEAD, ANY
// slot: head
// # ID is a UUID used to uniquely identify modifiers. If unspecified the ID will be randomly generated.
// # Items with modifiers that lack IDs cannot be stacked due to the random generation.
// id: 10000000-1000-1000-1000-100000000000
//
// # The 'custom name' can be anything you wish. Use color tags to make colored custom names.
// # | Some item scripts should have this key!
Expand All @@ -78,7 +89,7 @@ public class ItemScriptContainer extends ScriptContainer {
// # | Most item scripts should exclude this key!
// durability: 12
//
// # Each line must specify a valid Minecranft enchantment name.
// # Each line must specify a valid Minecraft enchantment name.
// # | Some item scripts should have this key!
// enchantments:
// - enchantment_name:level
Expand Down

0 comments on commit 88a68e0

Please sign in to comment.