Skip to content

Commit fd89186

Browse files
committed
OP Predictions
1 parent a9ab201 commit fd89186

File tree

1 file changed

+77
-63
lines changed

1 file changed

+77
-63
lines changed

common/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt

Lines changed: 77 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import com.lambda.graphics.renderer.gui.font.FontRenderer
3030
import com.lambda.graphics.renderer.gui.font.LambdaEmoji
3131
import com.lambda.graphics.renderer.gui.font.LambdaFont
3232
import com.lambda.interaction.RotationManager.rotate
33-
import com.lambda.interaction.rotation.Rotation.Companion.rotationTo
3433
import com.lambda.interaction.rotation.RotationRequest
3534
import com.lambda.module.Module
3635
import com.lambda.module.tag.ModuleTag
@@ -43,14 +42,14 @@ import com.lambda.util.math.*
4342
import com.lambda.util.math.MathUtils.ceilToInt
4443
import com.lambda.util.math.MathUtils.roundToStep
4544
import com.lambda.util.world.fastEntitySearch
46-
import com.lambda.util.world.raycast.RayCastMask
47-
import com.lambda.util.world.raycast.RayCastUtils.blockResult
4845
import net.minecraft.block.Blocks
4946
import net.minecraft.entity.Entity
5047
import net.minecraft.entity.LivingEntity
5148
import net.minecraft.entity.decoration.EndCrystalEntity
49+
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket
5250
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket
5351
import net.minecraft.util.Hand
52+
import net.minecraft.util.hit.BlockHitResult
5453
import net.minecraft.util.math.*
5554
import kotlin.concurrent.fixedRateTimer
5655
import kotlin.math.max
@@ -83,7 +82,6 @@ object CrystalAura : Module(
8382
/* Prediction */
8483
private val prediction by setting("Prediction", PredictionMode.None) { page == Page.Prediction }
8584
private val predictionPackets by setting("Prediction Packets", 1, 1..20) { page == Page.Prediction && prediction.isActive }
86-
private val postPlace by setting("Post Place", false) { page == Page.Prediction && prediction.isActive && predictionPackets > 1 }
8785
private val packetLifetime by setting("Packet Lifetime", 300L, 50L..1000L) { page == Page.Prediction && prediction.onPlace }
8886

8987
/* Targeting */
@@ -105,7 +103,6 @@ object CrystalAura : Module(
105103
private val placeTimer = SimpleTimer()
106104
private val explodeTimer = SimpleTimer()
107105

108-
// ToDo: pending prediction decay queue (crystalId s)
109106
private val predictionTimer = SimpleTimer()
110107
private var lastEntityId = 0
111108

@@ -171,10 +168,10 @@ object CrystalAura : Module(
171168
if (getBestOpportunity() != opportunity) return@listen
172169

173170
repeat(predictionPackets) {
174-
val offset = if (postPlace) 0 else it
171+
val offset = if (prediction.postPlace) 0 else it
175172
explodeInternal(lastEntityId + offset)
176173

177-
if (postPlace) {
174+
if (prediction.postPlace) {
178175
placeInternal(pos, Hand.MAIN_HAND)
179176
lastEntityId++
180177
placeTimer.reset()
@@ -187,7 +184,6 @@ object CrystalAura : Module(
187184
val pos = crystal.baseBlockPos
188185

189186
blueprint[pos]?.crystal = null
190-
//pendingExplosions.remove(blockPos)
191187
}
192188

193189
onEnable {
@@ -211,26 +207,7 @@ object CrystalAura : Module(
211207
// Choosing and running the best opportunity
212208
val best = getBestOpportunity() ?: return
213209

214-
if (!best.blocked) {
215-
best.explode()
216-
best.place()
217-
return
218-
}
219-
220-
val mutableBlockPos = BlockPos.Mutable()
221-
222-
// Break crystals nearby if the best crystal placement is blocked by other crystals
223-
collidingOffsets.mapNotNull {
224-
mutableBlockPos.set(
225-
best.blockPos.x + it.x,
226-
best.blockPos.y + it.y,
227-
best.blockPos.z + it.z
228-
)
229-
230-
blueprint[mutableBlockPos]
231-
}.filter { it.hasCrystal }.maxByOrNull { it.priority }?.explode()
232-
233-
best.place()
210+
tickInteraction(best)
234211
}
235212

236213
private fun SafeContext.buildBlueprint(target: LivingEntity) = updateTimer.runIfPassed(updateDelay) {
@@ -335,8 +312,6 @@ object CrystalAura : Module(
335312
blueprint[it.blockPos] = it
336313
}
337314

338-
// ToDo: force place
339-
340315
// Associate by actions
341316
blueprint.values.forEach { opportunity ->
342317
actionMap.getOrPut(opportunity.actionType, ::mutableListOf) += opportunity
@@ -347,6 +322,54 @@ object CrystalAura : Module(
347322
}
348323
}
349324

325+
private fun tickInteraction(best: Opportunity) {
326+
if (!best.blocked) {
327+
best.explode()
328+
best.place()
329+
return
330+
}
331+
332+
val mutableBlockPos = BlockPos.Mutable()
333+
334+
// Break crystals nearby if the best crystal placement is blocked by other crystals
335+
collidingOffsets.mapNotNull {
336+
mutableBlockPos.set(
337+
best.blockPos.x + it.x,
338+
best.blockPos.y + it.y,
339+
best.blockPos.z + it.z
340+
)
341+
342+
blueprint[mutableBlockPos]
343+
}.filter { it.hasCrystal }.maxByOrNull { it.priority }?.explode()
344+
345+
best.place()
346+
}
347+
348+
private fun getBestOpportunity() =
349+
actionMap[actionType]?.maxByOrNull {
350+
it.priority
351+
}
352+
353+
private fun SafeContext.placeInternal(blockPos: BlockPos, hand: Hand) {
354+
connection.sendPacket(
355+
PlayerInteractBlockC2SPacket(
356+
hand, BlockHitResult(blockPos.crystalPosition, Direction.UP, blockPos, false), 0
357+
)
358+
)
359+
360+
player.swingHand(hand)
361+
}
362+
363+
private fun SafeContext.explodeInternal(id: Int) {
364+
connection.sendPacket(
365+
PlayerInteractEntityC2SPacket(
366+
id, player.isSneaking, PlayerInteractEntityC2SPacket.ATTACK
367+
)
368+
)
369+
370+
player.swingHand(Hand.MAIN_HAND)
371+
}
372+
350373
/**
351374
* Represents the damage information resulting from placing an end crystal on a given [blockPos]
352375
* and causing an explosion that targets current target entity.
@@ -366,7 +389,7 @@ object CrystalAura : Module(
366389
) {
367390
var actionType = ActionType.Normal
368391
val priority = priorityMode.factor(target, self)
369-
val hasCrystal = crystal != null
392+
val hasCrystal get() = crystal != null
370393

371394
/**
372395
* Places the crystal on [blockPos]
@@ -382,10 +405,19 @@ object CrystalAura : Module(
382405
run {
383406
if (!prediction.onPlace || predictionTimer.timePassed(packetLifetime)) return@run
384407

408+
val last = lastEntityId
409+
385410
repeat(predictionPackets) {
386-
if (it != 0) placeInternal(blockPos, Hand.MAIN_HAND)
411+
if (it != 0 && prediction.postPlace) {
412+
placeInternal(blockPos, Hand.MAIN_HAND)
413+
}
387414
explodeInternal(++lastEntityId)
388415
}
416+
417+
if (prediction == PredictionMode.StepDeferred) {
418+
lastEntityId = last + 1
419+
crystal = null
420+
}
389421
}
390422

391423
placeTimer.reset()
@@ -434,33 +466,6 @@ object CrystalAura : Module(
434466
}
435467
}
436468

437-
private fun getBestOpportunity() =
438-
actionMap[actionType]?.maxByOrNull {
439-
it.priority
440-
}
441-
442-
private fun SafeContext.placeInternal(blockPos: BlockPos, hand: Hand): Boolean {
443-
val angles = player.eyePos.rotationTo(blockPos.crystalPosition)
444-
val cast = angles.rayCast(placeRange, mask = RayCastMask.BLOCK)?.blockResult ?: return false
445-
if (cast.blockPos != blockPos) return false
446-
447-
val actionResult = interaction.interactBlock(player, hand, cast)
448-
if (!actionResult.isAccepted || !actionResult.shouldSwingHand()) return false
449-
450-
player.swingHand(hand)
451-
return true
452-
}
453-
454-
private fun SafeContext.explodeInternal(id: Int) {
455-
connection.sendPacket(
456-
PlayerInteractEntityC2SPacket(
457-
id, player.isSneaking, PlayerInteractEntityC2SPacket.ATTACK
458-
)
459-
)
460-
461-
player.swingHand(Hand.MAIN_HAND)
462-
}
463-
464469
private val EndCrystalEntity.baseBlockPos get() =
465470
(pos - Vec3d(0.0, 0.5, 0.0)).flooredBlockPos
466471

@@ -495,10 +500,18 @@ object CrystalAura : Module(
495500
Ticked
496501
}
497502

498-
private enum class PredictionMode(val onPacket: Boolean, val onPlace: Boolean) {
499-
None(false, false),
500-
Packet(true, false),
501-
Deferred(false, true);
503+
private enum class PredictionMode(val onPacket: Boolean, val onPlace: Boolean, val postPlace: Boolean) {
504+
// Prediction disable
505+
None(false, false, false),
506+
507+
// Predict on packet receive
508+
SemiPacket(true, false, false),
509+
Packet(true, false, true),
510+
511+
// Predict on place
512+
SemiDeferred(false, true, false),
513+
Deferred(false, true, true),
514+
StepDeferred(false, true, false); // the best method
502515

503516
val isActive = onPacket || onPlace
504517
}
@@ -512,6 +525,7 @@ object CrystalAura : Module(
512525
})
513526
}
514527

528+
// ToDo: implement actions
515529
private enum class ActionType(val priority: Int) {
516530
Normal(0),
517531
ForcePlace(1),

0 commit comments

Comments
 (0)