Skip to content

Commit

Permalink
More fixing to the attribute and durability (#8)
Browse files Browse the repository at this point in the history
* Update CustomItem.java

* Update CustomItem.java

* Fixed attribute stuff and some durability stuff too

* Another fix

* Update ItemUtils.java
  • Loading branch information
00Creamy authored Aug 29, 2021
1 parent 4168cb6 commit 30c355f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 83 deletions.
149 changes: 96 additions & 53 deletions src/main/java/com/strangeone101/holoitemsapi/CustomItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.w3c.dom.Attr;

import java.text.DecimalFormat;
import java.util.ArrayList;
Expand All @@ -39,7 +40,6 @@
import java.util.Set;
import java.util.UUID;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -67,7 +67,7 @@ public class CustomItem {
private BiConsumer<ItemStack, ItemMeta> onBuild;
private BiConsumer<ItemStack, ItemMeta> onUpdate;

private Map<Attribute, Pair<AttributeModifier.Operation, Double>> attributes = new HashMap<>();
private Map<Attribute, Map<AttributeModifier.Operation, Double>> attributes = new HashMap<>();
private Map<String, Function<PersistentDataContainer, String>> variables = new HashMap<>();
private Map<String, Object> nbt = new HashMap<>();

Expand Down Expand Up @@ -162,12 +162,11 @@ public ItemStack buildStack(Player player) {

//Add all attributes to the item
for (Attribute attr : getAttributes().keySet()) {
Pair<AttributeModifier.Operation, Double> pair = getAttributes().get(attr);
ItemUtils.setAttriute(pair.getRight(), attr, pair.getLeft(), stack);
for (AttributeModifier.Operation operation: getAttributes().get(attr).keySet()) {
ItemUtils.setAttribute(getAttributes().get(attr).get(operation), attr, operation, stack, this);
}
}



if (this.jsonLore) {
ReflectionUtils.setTrueLore(stack, lore);
}
Expand Down Expand Up @@ -258,8 +257,9 @@ public ItemStack updateStack(ItemStack stack, Player player) {

//Add all attributes to the item
for (Attribute attr : getAttributes().keySet()) {
Pair<AttributeModifier.Operation, Double> pair = getAttributes().get(attr);
ItemUtils.setAttriute(pair.getRight(), attr, pair.getLeft(), stack);
for (AttributeModifier.Operation operation: getAttributes().get(attr).keySet()) {
ItemUtils.setAttribute(getAttributes().get(attr).get(operation), attr, operation, stack, this);
}
}

if (this.jsonLore) {
Expand Down Expand Up @@ -375,7 +375,7 @@ public void setDurability(ItemStack stack, int durability) {
meta.getPersistentDataContainer().set(HoloItemsAPI.getKeys().CUSTOM_ITEM_DURABILITY, PersistentDataType.INTEGER, durability);

if (meta instanceof Damageable) {
((Damageable) meta).setDamage((durability / getMaxDurability()) * stack.getType().getMaxDurability());
((Damageable) meta).setDamage((int)(((double)durability / (double)getMaxDurability()) * stack.getType().getMaxDurability()));
}

stack.setItemMeta(meta); //Update item
Expand Down Expand Up @@ -661,84 +661,127 @@ public int hashCode() {
return name.hashCode();
}

public CustomItem setDamage(double damage) {
getAttributes().put(Attribute.GENERIC_ATTACK_DAMAGE,
new ImmutablePair<>(AttributeModifier.Operation.ADD_NUMBER, damage));
public CustomItem setAttribute(Attribute attribute, double amount, boolean percentage) {
AttributeModifier.Operation operation = AttributeModifier.Operation.ADD_NUMBER;
if (percentage) {
operation = AttributeModifier.Operation.ADD_SCALAR;
}
HashMap<AttributeModifier.Operation, Double> map = new HashMap<>();
map.put(operation, amount);
getAttributes().put(attribute, map);

return this;
}

public CustomItem setDamagePercentage(double percentage) {
getAttributes().put(Attribute.GENERIC_ATTACK_DAMAGE,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setArmor(double armor, boolean percentage) {
return setAttribute(Attribute.GENERIC_ARMOR, armor, percentage);
}

return this;
public CustomItem setArmor(double armor) {
return setArmor(armor, false);
}

public CustomItem setArmor(int armor) {
getAttributes().put(Attribute.GENERIC_ARMOR,
new ImmutablePair<>(AttributeModifier.Operation.ADD_NUMBER, (double)armor));
public CustomItem setArmorPercentage(double armorPercentage) {
return setArmor(armorPercentage, true);
}

return this;
public CustomItem setArmorToughness(double armorToughness, boolean percentage) {
return setAttribute(Attribute.GENERIC_ARMOR_TOUGHNESS, armorToughness, percentage);
}

public CustomItem setArmorToughness(int armor) {
getAttributes().put(Attribute.GENERIC_ARMOR_TOUGHNESS,
new ImmutablePair<>(AttributeModifier.Operation.ADD_NUMBER, (double)armor));
public CustomItem setArmorToughness(double armorToughness) {
return setArmorToughness(armorToughness, false);
}

return this;
public CustomItem setArmorToughnessPercentage(double armorToughnessPercentage) {
return setArmorToughness(armorToughnessPercentage, true);
}

public CustomItem setHealth(int health) {
getAttributes().put(Attribute.GENERIC_MAX_HEALTH,
new ImmutablePair<>(AttributeModifier.Operation.ADD_NUMBER, (double)health));
public CustomItem setDamage(double damage, boolean percentage) {
return setAttribute(Attribute.GENERIC_ATTACK_DAMAGE, damage, percentage);
}

return this;
public CustomItem setDamage(double damage) {
return setDamage(damage, false);
}

public CustomItem setHealthPercentage(double percentage) {
getAttributes().put(Attribute.GENERIC_MAX_HEALTH,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, (double)percentage));
public CustomItem setDamagePercentage(double damagePercentage) {
return setDamage(damagePercentage, true);
}

return this;
public CustomItem setAttackKnockback(double knockback, boolean percentage) {
return setAttribute(Attribute.GENERIC_ATTACK_KNOCKBACK, knockback, percentage);
}

public CustomItem setSpeed(double percentage) {
getAttributes().put(Attribute.GENERIC_MOVEMENT_SPEED,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setAttackKnockback(double knockback) {
return setAttackKnockback(knockback, false);
}

return this;
public CustomItem setAttackKnockbackPercentage(double knockbackPercentage) {
return setAttackKnockback(knockbackPercentage, true);
}

public CustomItem setKnockbackResistance(double percentage) {
getAttributes().put(Attribute.GENERIC_KNOCKBACK_RESISTANCE,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setAttackSpeed(double speed, boolean percentage) {
return setAttribute(Attribute.GENERIC_ATTACK_SPEED, speed, percentage);
}

return this;
public CustomItem setAttackSpeed(double speed) {
return setAttackSpeed(speed, false);
}

public CustomItem setAttackSpeed(double percentage) {
getAttributes().put(Attribute.GENERIC_ATTACK_SPEED,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setAttackSpeedPercentage(double speedPercentage) {
return setAttackSpeed(speedPercentage, true);
}

return this;
public CustomItem setKnockbackResistance(double resistance, boolean percentage) {
return setAttribute(Attribute.GENERIC_KNOCKBACK_RESISTANCE, resistance, percentage);
}

public CustomItem setAttackKnockback(double percentage) {
getAttributes().put(Attribute.GENERIC_ATTACK_KNOCKBACK,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setKnockbackResistance(double resistance) {
return setKnockbackResistance(resistance, false);
}

return this;
public CustomItem setKnockbackResistancePercentage(double resistancePercentage) {
return setKnockbackResistance(resistancePercentage, true);
}

public CustomItem setLuck(double percentage) {
getAttributes().put(Attribute.GENERIC_LUCK,
new ImmutablePair<>(AttributeModifier.Operation.ADD_SCALAR, percentage));
public CustomItem setLuck(double luck, boolean percentage) {
return setAttribute(Attribute.GENERIC_LUCK, luck, percentage);
}

return this;
public CustomItem setLuck(double luck) {
return setLuck(luck, false);
}

public CustomItem setLuckPercentage(double luckPercentage) {
return setLuck(luckPercentage, true);
}

public CustomItem setHealth(double health, boolean percentage) {
return setAttribute(Attribute.GENERIC_MAX_HEALTH, health, percentage);
}

public CustomItem setHealth(int health) {
return setHealth(health, false);
}

public CustomItem setHealthPercentage(double healthPercentage) {
return setHealth(healthPercentage, true);
}

public CustomItem setSpeed(double speed, boolean percentage) {
return setAttribute(Attribute.GENERIC_MOVEMENT_SPEED, speed, percentage);
}

public CustomItem setSpeed(double speed) {
return setSpeed(speed, false);
}

public CustomItem setSpeedPercentage(double speedPercentage) {
return setSpeed(speedPercentage, true);
}

public Map<Attribute, Pair<AttributeModifier.Operation, Double>> getAttributes() {
public Map<Attribute, Map<AttributeModifier.Operation, Double>> getAttributes() {
return attributes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,21 @@ static void triggerItemEvents(Event event) {
e.printStackTrace();
}
}

}
}
} else if (event instanceof EntityEvent && ((EntityEvent) event).getEntity() instanceof Player) {
Player player = ((Player) ((EntityEvent) event).getEntity());
if (POSITIONS_BY_ITEM.get(item).containsKey(player)) {
for (int slot : POSITIONS_BY_ITEM.get(item).get(player).keySet()) {
Pair<ItemStack, Position> pair = POSITIONS_BY_ITEM.get(item).get(player).get(slot);
if (t.getRight().matches(pair.getRight())) { //If activeConditions match Position
EventContext context = new EventContext(player, item, pair.getLeft(), pair.getRight());
try {
m.invoke(item, context, event);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
Expand Down
52 changes: 23 additions & 29 deletions src/main/java/com/strangeone101/holoitemsapi/util/ItemUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import com.strangeone101.holoitemsapi.CustomItem;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
Expand All @@ -24,8 +25,6 @@

public class ItemUtils {

public static final Map<Attribute, UUID> ATTRIBUTE_MAP = new HashMap<>();

/**
* Sets the skin of a Skull to the skin provided. Can be a UUID, name, texture ID or URL
* @param meta The skull meta
Expand Down Expand Up @@ -80,35 +79,19 @@ public static SkullMeta setSkinFromURL(SkullMeta meta, String skin) {
* @param attribute The attribute
* @param operation The operation
* @param stack The itemstack
* @param ci The custom item
*/
public static void setAttriute(double number, Attribute attribute, AttributeModifier.Operation operation, ItemStack stack) {
if (ATTRIBUTE_MAP.isEmpty()) {
Random random = new Random("unique_seed".hashCode());

//Due to the set random seed above, the UUIDs bellow should always be the same.
ATTRIBUTE_MAP.put(Attribute.GENERIC_ATTACK_DAMAGE, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_ATTACK_SPEED, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_ATTACK_KNOCKBACK, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_MAX_HEALTH, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_ARMOR, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_ARMOR_TOUGHNESS, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_KNOCKBACK_RESISTANCE, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_MOVEMENT_SPEED, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_FLYING_SPEED, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_FOLLOW_RANGE, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.GENERIC_LUCK, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.HORSE_JUMP_STRENGTH, new UUID(random.nextLong(), random.nextLong()));
ATTRIBUTE_MAP.put(Attribute.ZOMBIE_SPAWN_REINFORCEMENTS, new UUID(random.nextLong(), random.nextLong()));

if (!ATTRIBUTE_MAP.containsKey(attribute)) { //Bodge for attributes added in future
ATTRIBUTE_MAP.put(attribute, new UUID(random.nextLong(), random.nextLong()));
}
}
public static void setAttribute(double number, Attribute attribute, AttributeModifier.Operation operation, ItemStack stack, CustomItem ci) {
Random random = new Random(cantorFunction(ci.getInternalID(), cantorFunction(attribute.ordinal(), operation.ordinal())));

AttributeModifier mod = new AttributeModifier(ATTRIBUTE_MAP.get(attribute), attribute.name(), number, operation, getSlotForItem(stack.getType()));
ItemMeta meta = stack.getItemMeta();
meta.addAttributeModifier(attribute, mod);
stack.setItemMeta(meta);
try {
AttributeModifier mod = new AttributeModifier(new UUID(random.nextLong(), random.nextLong()), attribute.name(), number, operation, getSlotForItem(stack.getType()));
ItemMeta meta = stack.getItemMeta();
meta.addAttributeModifier(attribute, mod);
stack.setItemMeta(meta);
} catch (IllegalArgumentException e) {

}
}

/**
Expand Down Expand Up @@ -229,4 +212,15 @@ public static boolean isLeatherArmor(Material material) {
return false;
}
}

/**
* Create one unique number from two different number
* Note that cantorFunction(1,0) is different from cantorFunction(0,1)
* @param x The first number
* @param y The second number
* @return A unique number
*/
public static int cantorFunction(int x, int y) {
return (((x * x) + (3 * x) + (2 * x * y) + y + (y * y)) / 2);
}
}

0 comments on commit 30c355f

Please sign in to comment.