Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More fixing to the attribute and durability #8

Merged
merged 8 commits into from
Aug 29, 2021
Merged
Show file tree
Hide file tree
Changes from 7 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
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
57 changes: 33 additions & 24 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,7 +25,7 @@

public class ItemUtils {

public static final Map<Attribute, UUID> ATTRIBUTE_MAP = new HashMap<>();
public static final Map<CustomItem, 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
Expand Down Expand Up @@ -81,34 +82,42 @@ public static SkullMeta setSkinFromURL(SkullMeta meta, String skin) {
* @param operation The operation
* @param stack The itemstack
*/
public static void setAttriute(double number, Attribute attribute, AttributeModifier.Operation operation, ItemStack stack) {
if (ATTRIBUTE_MAP.isEmpty()) {
Random random = new Random("unique_seed".hashCode());
public static void setAttribute(double number, Attribute attribute, AttributeModifier.Operation operation, ItemStack stack, CustomItem ci) {
if (!(ATTRIBUTE_MAP.containsKey(ci))) {
ATTRIBUTE_MAP.put(ci, new HashMap<>());
}
Map<Attribute, UUID> ciMap = ATTRIBUTE_MAP.get(ci);
if (ATTRIBUTE_MAP.get(ci).isEmpty()) {
Random random = new Random(ci.getInternalName().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()));
Copy link
Owner

Choose a reason for hiding this comment

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

I don't think there is any point caching it anymore. Instead, we can just create a new random when we need to make the UUID again

Since we aren't caching them, each random will need to be different depending on the attribute name. Maybe make the seed itemId.hashCode() >> 16 + (attributeName.hashCode() * operationEnumOrdinal)

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()));
ciMap.put(Attribute.GENERIC_ATTACK_DAMAGE, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_ATTACK_SPEED, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_ATTACK_KNOCKBACK, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_MAX_HEALTH, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_ARMOR, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_ARMOR_TOUGHNESS, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_KNOCKBACK_RESISTANCE, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_MOVEMENT_SPEED, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_FLYING_SPEED, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_FOLLOW_RANGE, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.GENERIC_LUCK, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.HORSE_JUMP_STRENGTH, new UUID(random.nextLong(), random.nextLong()));
ciMap.put(Attribute.ZOMBIE_SPAWN_REINFORCEMENTS, new UUID(random.nextLong(), random.nextLong()));

if (!ciMap.containsKey(attribute)) { //Bodge for attributes added in future
ciMap.put(attribute, new UUID(random.nextLong(), random.nextLong()));
}
}

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(ciMap.get(attribute), attribute.name(), number, operation, getSlotForItem(stack.getType()));
ItemMeta meta = stack.getItemMeta();
meta.addAttributeModifier(attribute, mod);
stack.setItemMeta(meta);
} catch (IllegalArgumentException e) {

}
}

/**
Expand Down