Skip to content

Commit f531ad0

Browse files
committed
Fixed killaura cooldown and swap
1 parent d25b461 commit f531ad0

File tree

3 files changed

+55
-80
lines changed

3 files changed

+55
-80
lines changed

src/main/kotlin/com/lambda/interaction/material/StackSelection.kt

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import kotlin.reflect.KClass
3333
* [StackSelection] is a class that holds a predicate for matching [ItemStack]s.
3434
*/
3535
class StackSelection {
36-
var selector: (ItemStack) -> Boolean = { true }
37-
var comparator: Comparator<ItemStack>? = null
36+
var selector: (ItemStack) -> Boolean = EVERYTHING
37+
var comparator: Comparator<ItemStack> = NO_COMPARE
3838
var count: Int = DEFAULT_AMOUNT
3939
var inShulkerBox: Boolean = false
4040

@@ -48,25 +48,22 @@ class StackSelection {
4848
val optimalStack: ItemStack?
4949
get() = itemStack ?: item?.let { ItemStack(it, count) }
5050

51+
/**
52+
* Filters the given [stacks], sorts them with the [comparator] and returns the first value
53+
*/
54+
fun bestItemMatch(stacks: List<ItemStack>): ItemStack? = filterStacks(stacks).firstOrNull()
55+
5156
fun filterStack(stack: ItemStack) =
5257
if (inShulkerBox) stack.shulkerBoxContents.any { selector(it) }
5358
else selector(stack)
5459

55-
fun filterSlot(slot: Slot) = filterStack(slot.stack)
60+
fun filterSlot(slot: Slot): Boolean = filterStack(slot.stack)
5661

5762
fun filterStacks(stacks: List<ItemStack>): List<ItemStack> =
58-
stacks.filter(::filterStack).let { filteredStacks ->
59-
comparator?.run {
60-
filteredStacks.sortedWith(this)
61-
} ?: filteredStacks
62-
}
63+
stacks.filter(::filterStack).sortedWith(comparator)
6364

6465
fun filterSlots(slots: List<Slot>): List<Slot> =
65-
slots.filter(::filterSlot).let { filteredSlots ->
66-
comparator?.run {
67-
filteredSlots.sortedWith { slot, slot2 -> compare(slot.stack, slot2.stack) }
68-
} ?: filteredSlots
69-
}
66+
slots.filter(::filterSlot).sortedWith { slot, slot2 -> comparator.compare(slot.stack, slot2.stack) }
7067

7168
/**
7269
* returns a function that finds a shulker box to push matching items into.
@@ -235,15 +232,14 @@ class StackSelection {
235232
annotation class StackSelectionDsl
236233

237234
const val DEFAULT_AMOUNT = 1
238-
val FULL_SHULKERS: (ItemStack) -> Boolean = { stack ->
239-
stack.shulkerBoxContents.none { it.isEmpty }
240-
}
241-
val EMPTY_SHULKERS: (ItemStack) -> Boolean = { stack ->
242-
stack.shulkerBoxContents.all { it.isEmpty }
243-
}
235+
236+
val FULL_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.none { it.isEmpty } }
237+
val EMPTY_SHULKERS: (ItemStack) -> Boolean = { stack -> stack.shulkerBoxContents.all { it.isEmpty } }
244238
val EVERYTHING: (ItemStack) -> Boolean = { true }
245239
val NOTHING: (ItemStack) -> Boolean = { false }
246240

241+
val NO_COMPARE: Comparator<ItemStack> = compareBy { 69-420 }
242+
247243
@StackSelectionDsl
248244
fun Item.select() = selectStack { isItem(this@select) }
249245

@@ -271,7 +267,7 @@ class StackSelection {
271267
fun selectStack(
272268
count: Int = DEFAULT_AMOUNT,
273269
inShulkerBox: Boolean = false,
274-
block: StackSelection.() -> (ItemStack) -> Boolean,
270+
block: StackSelection.() -> (ItemStack) -> Boolean = { EVERYTHING },
275271
) = StackSelection().apply {
276272
selector = block()
277273
this.count = count
@@ -282,8 +278,8 @@ class StackSelection {
282278
fun selectStack(
283279
count: Int = DEFAULT_AMOUNT,
284280
inShulkerBox: Boolean = false,
285-
sorter: Comparator<ItemStack>? = null,
286-
block: StackSelection.() -> (ItemStack) -> Boolean,
281+
sorter: Comparator<ItemStack> = NO_COMPARE,
282+
block: StackSelection.() -> (ItemStack) -> Boolean = { EVERYTHING },
287283
) = StackSelection().apply {
288284
selector = block()
289285
comparator = sorter

src/main/kotlin/com/lambda/module/modules/combat/KillAura.kt

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ import com.lambda.task.RootTask.run
3636
import com.lambda.util.NamedEnum
3737
import com.lambda.util.item.ItemStackUtils.attackDamage
3838
import com.lambda.util.item.ItemStackUtils.attackSpeed
39+
import com.lambda.util.item.ItemStackUtils.equal
3940
import com.lambda.util.math.random
41+
import com.lambda.util.player.SlotUtils.hotbarAndStorage
4042
import com.lambda.util.world.raycast.InteractionMask
4143
import com.lambda.util.world.raycast.RayCastUtils.entityResult
4244
import net.minecraft.entity.LivingEntity
45+
import net.minecraft.entity.attribute.EntityAttributes
4346
import net.minecraft.registry.tag.ItemTags
4447
import net.minecraft.util.Hand
4548
import net.minecraft.util.math.Vec3d
@@ -52,7 +55,7 @@ object KillAura : Module(
5255
// Interact
5356
private val interactionSettings = InteractionSettings(this, Group.Interaction, InteractionMask.Entity)
5457
private val interactSettings = InteractSettings(this, listOf(Group.Interact))
55-
private val swap by setting("Swap", true, "Swap to the item with the highest damage")
58+
private val swap by setting("Swap", true, "Swap to the item with the highest damage").group(Group.Interact)
5659
private val attackMode by setting("Attack Mode", AttackMode.Cooldown).group(Group.Interact)
5760
private val cooldownOffset by setting("Cooldown Offset", 0, -5..5, 1) { attackMode == AttackMode.Cooldown }.group(Group.Interact)
5861
private val hitDelay1 by setting("Hit Delay 1", 2.0, 0.0..20.0, 1.0) { attackMode == AttackMode.Delay }.group(Group.Interact)
@@ -101,20 +104,11 @@ object KillAura : Module(
101104
listen<TickEvent.Pre> {
102105
target?.let { entity ->
103106
if (swap) {
104-
val selection = selectStack(
105-
sorter = compareByDescending { attackDamage(stack = it) }
106-
) { isTag(ItemTags.SWORDS) }
107+
val selection =
108+
selectStack(sorter = compareByDescending { player.attackDamage(stack = it) })
107109

108-
109-
if (!selection.selector(player.mainHandStack)) {
110-
selection.transfer(MainHandContainer)
111-
?.finally {
112-
// Wait until the rotation has a hit result on the entity
113-
if (lookAtEntity(entity).requestBy(rotation).done) runAttack(entity)
114-
}?.run()
115-
116-
return@listen
117-
}
110+
if (!selection.bestItemMatch(player.hotbarAndStorage).equal(player.mainHandStack))
111+
selection.transfer(MainHandContainer)?.run()
118112
}
119113

120114
// Wait until the rotation has a hit result on the entity
@@ -129,13 +123,8 @@ object KillAura : Module(
129123
private fun SafeContext.runAttack(target: LivingEntity) {
130124
// Cooldown check
131125
when (attackMode) {
132-
AttackMode.Cooldown -> {
133-
if (player.lastAttackedTicks < 20 / player.attackSpeed() + cooldownOffset) return
134-
}
135-
136-
AttackMode.Delay -> {
137-
if (System.currentTimeMillis() - lastAttackTime < hitDelay) return
138-
}
126+
AttackMode.Cooldown -> if (player.lastAttackedTicks < 1 / player.attackSpeed() * 20 + cooldownOffset) return
127+
AttackMode.Delay -> if (System.currentTimeMillis() - lastAttackTime < hitDelay) return
139128
}
140129

141130
// Rotation check

src/main/kotlin/com/lambda/util/item/ItemStackUtils.kt

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,69 +17,59 @@
1717

1818
package com.lambda.util.item
1919

20-
import com.lambda.context.SafeContext
2120
import com.lambda.util.collections.Cacheable.Companion.cacheable
2221
import net.minecraft.component.DataComponentTypes
2322
import net.minecraft.component.type.AttributeModifiersComponent
23+
import net.minecraft.entity.EquipmentSlot
2424
import net.minecraft.entity.LivingEntity
25+
import net.minecraft.entity.attribute.EntityAttribute
26+
import net.minecraft.entity.attribute.EntityAttributeModifier
2527
import net.minecraft.entity.attribute.EntityAttributes
2628
import net.minecraft.item.ItemStack
29+
import net.minecraft.registry.entry.RegistryEntry
2730

2831
object ItemStackUtils {
2932
// FixMe: Change this fucking retarded stuff when mojang wake up from their coma and realize they fucked this shit up
3033
// - The client and the server entity attributes are not synced,
3134
// - Enchantments do not change attributes,
3235
// - All enchantment utils are bound to the server
3336

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+
3952

4053
/**
4154
* Returns the attack damage for the given [stack], the value is affected by potion effects and enchantments
4255
*/
4356
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)
4759

4860
/**
4961
* Returns the attack speed for the given [stack], the value is affected by potion effects
5062
*
5163
* 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
5864
*
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+
* ```
6069
*/
6170
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)
8373

8474
val ItemStack.spaceLeft get() = maxCount - count
8575
val ItemStack.hasSpace get() = spaceLeft > 0

0 commit comments

Comments
 (0)