|
17 | 17 |
|
18 | 18 | package com.lambda.util.item |
19 | 19 |
|
20 | | -import com.lambda.context.SafeContext |
21 | 20 | import com.lambda.util.collections.Cacheable.Companion.cacheable |
22 | 21 | import net.minecraft.component.DataComponentTypes |
23 | 22 | import net.minecraft.component.type.AttributeModifiersComponent |
| 23 | +import net.minecraft.entity.EquipmentSlot |
24 | 24 | import net.minecraft.entity.LivingEntity |
| 25 | +import net.minecraft.entity.attribute.EntityAttribute |
| 26 | +import net.minecraft.entity.attribute.EntityAttributeModifier |
25 | 27 | import net.minecraft.entity.attribute.EntityAttributes |
26 | 28 | import net.minecraft.item.ItemStack |
| 29 | +import net.minecraft.registry.entry.RegistryEntry |
27 | 30 |
|
28 | 31 | object ItemStackUtils { |
29 | 32 | // FixMe: Change this fucking retarded stuff when mojang wake up from their coma and realize they fucked this shit up |
30 | 33 | // - The client and the server entity attributes are not synced, |
31 | 34 | // - Enchantments do not change attributes, |
32 | 35 | // - All enchantment utils are bound to the server |
33 | 36 |
|
34 | | - /** |
35 | | - * Returns the attack damage for the given [stack], the value is affected by potion effects and enchantments |
36 | | - */ |
37 | | - fun SafeContext.attackDamage(entity: LivingEntity = player, stack: ItemStack = entity.mainHandStack) = |
38 | | - entity.attackDamage(stack) |
| 37 | + fun LivingEntity.attributeBaseValue(attribute: RegistryEntry<EntityAttribute>) = |
| 38 | + if (attributes.hasAttribute(attribute)) getAttributeBaseValue(attribute) else 0.0 |
| 39 | + |
| 40 | + fun AttributeModifiersComponent.filteredApply(base: Double, slot: EquipmentSlot, vararg attributes: RegistryEntry<EntityAttribute>): Double = |
| 41 | + modifiers.filter { attributes.contains(it.attribute) && it.slot.matches(slot) } |
| 42 | + .foldRight(base) { entry, acc -> |
| 43 | + val v = entry.modifier.value |
| 44 | + |
| 45 | + acc + when (entry.modifier.operation) { |
| 46 | + EntityAttributeModifier.Operation.ADD_VALUE -> v |
| 47 | + EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE -> v * base |
| 48 | + EntityAttributeModifier.Operation.ADD_MULTIPLIED_TOTAL -> v * acc |
| 49 | + } |
| 50 | + } |
| 51 | + |
39 | 52 |
|
40 | 53 | /** |
41 | 54 | * Returns the attack damage for the given [stack], the value is affected by potion effects and enchantments |
42 | 55 | */ |
43 | 56 | fun LivingEntity.attackDamage(stack: ItemStack = mainHandStack) = |
44 | | - (stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT) |
45 | | - .modifiers.find { it.attribute == EntityAttributes.ATTACK_DAMAGE }?.modifier?.value ?: 0.0) + |
46 | | - getAttributeValue(EntityAttributes.ATTACK_DAMAGE) |
| 57 | + stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT) |
| 58 | + .filteredApply(attributeBaseValue(EntityAttributes.ATTACK_DAMAGE), EquipmentSlot.MAINHAND, EntityAttributes.ATTACK_DAMAGE) |
47 | 59 |
|
48 | 60 | /** |
49 | 61 | * Returns the attack speed for the given [stack], the value is affected by potion effects |
50 | 62 | * |
51 | 63 | * The value represents the number of attacks-per-tick |
52 | | - */ |
53 | | - fun SafeContext.attackSpeed(entity: LivingEntity = player, stack: ItemStack = entity.mainHandStack) = |
54 | | - entity.attackSpeed(stack) |
55 | | - |
56 | | - /** |
57 | | - * Returns the attack speed for the given [stack], the value is affected by potion effects |
58 | 64 | * |
59 | | - * The value represents the number of attacks-per-tick |
| 65 | + * To get the number of ticks per attack do the following: |
| 66 | + * ``` |
| 67 | + * ticks = 1 / speed * 20 |
| 68 | + * ``` |
60 | 69 | */ |
61 | 70 | fun LivingEntity.attackSpeed(stack: ItemStack = mainHandStack) = |
62 | | - (stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT) |
63 | | - .modifiers.find { it.attribute == EntityAttributes.ATTACK_SPEED }?.modifier?.value ?: 0.0) + |
64 | | - getAttributeValue(EntityAttributes.ATTACK_SPEED) |
65 | | - |
66 | | - /** |
67 | | - * Returns the mining speed for the given [stack], the value is affected by potion effects and enchantments |
68 | | - */ |
69 | | - fun SafeContext.miningSpeed(entity: LivingEntity = player, stack: ItemStack = entity.mainHandStack) = |
70 | | - entity.miningSpeed(stack) |
71 | | - |
72 | | - /** |
73 | | - * Returns the mining speed for the given [stack], the value is affected by potion effects and enchantments |
74 | | - */ |
75 | | - fun LivingEntity.miningSpeed(stack: ItemStack = mainHandStack) = |
76 | | - (stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT) |
77 | | - .modifiers.find { |
78 | | - it.attribute == EntityAttributes.MINING_EFFICIENCY || |
79 | | - it.attribute == EntityAttributes.SUBMERGED_MINING_SPEED |
80 | | - }?.modifier?.value ?: 0.0) + |
81 | | - if (isSubmergedInWater) getAttributeValue(EntityAttributes.SUBMERGED_MINING_SPEED) |
82 | | - else getAttributeValue(EntityAttributes.MINING_EFFICIENCY) |
| 71 | + stack.getOrDefault(DataComponentTypes.ATTRIBUTE_MODIFIERS, AttributeModifiersComponent.DEFAULT) |
| 72 | + .filteredApply(attributeBaseValue(EntityAttributes.ATTACK_SPEED), EquipmentSlot.MAINHAND, EntityAttributes.ATTACK_SPEED) |
83 | 73 |
|
84 | 74 | val ItemStack.spaceLeft get() = maxCount - count |
85 | 75 | val ItemStack.hasSpace get() = spaceLeft > 0 |
|
0 commit comments