Загрузка данных
package releon.ru.api.module.impl.combat.aura.attack;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
import net.minecraft.network.protocol.game.ServerboundClientTickEndPacket;
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket;
import net.minecraft.network.protocol.game.ServerboundSwingPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.AxeItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import releon.ru.IMinecraft;
import releon.ru.api.events.impl.PacketEvent;
import releon.ru.api.events.impl.UsingItemEvent;
import releon.ru.api.module.impl.combat.AuraModule;
import releon.ru.api.module.impl.combat.Criticals;
import releon.ru.api.module.impl.combat.TriggerBot;
import releon.ru.api.module.impl.combat.aura.AngleConnection;
import releon.ru.api.module.impl.combat.aura.context.AutoRegressionContext;
import releon.ru.api.module.impl.combat.aura.target.RaycastAngle;
import releon.ru.api.module.impl.combat.aura.util.MathUtils;
import releon.ru.api.module.impl.movement.ElytraTarget;
import releon.ru.api.module.impl.player.FreeCam;
import releon.ru.mixin.accessor.LivingEntityAccessor;
import releon.ru.utils.inventory.swap.SwapExecutor;
import releon.ru.utils.inventory.interaction.PlayerInteractionHelper;
import releon.ru.utils.player.PlayerSimulation;
import releon.ru.api.module.impl.combat.aura.util.StopWatch;
public class StrikeManager implements IMinecraft {
private static final long CRIT_STARTUP_HOLD_MS = 450L;
private long nextAttackDelayMs = 550L;
private final StopWatch attackTimer = new StopWatch();
private final Pressing clickScheduler = new Pressing();
private final SwapExecutor shieldSwapExecutor = new SwapExecutor();
private int count = 0;
private int tickCounter = 0;
private int shieldSuppressedUntilTick = -1;
private int lastShieldReleaseTick = -1;
private boolean waitingForPostReleaseTick = false;
void tick() {
if (shieldSwapExecutor.isRunning()) {
shieldSwapExecutor.tick();
}
tickCounter++;
syncShieldState();
}
void onPacket(PacketEvent e) {
if (!e.isSend()) {
return;
}
Object packet = e.getPacket();
if (packet instanceof ServerboundSwingPacket || packet instanceof ServerboundSetCarriedItemPacket) {
clickScheduler.recalculate();
return;
}
if (packet instanceof ServerboundMovePlayerPacket || packet instanceof ServerboundClientTickEndPacket) {
waitingForPostReleaseTick = false;
return;
}
if (packet instanceof ServerboundInteractPacket interactPacket
&& waitingForPostReleaseTick
&& isRightClickInteraction(interactPacket)) {
e.cancel();
}
}
void onUsingItem(UsingItemEvent e) {
}
public boolean unpressShield() {
return false;
}
public void resetPendingState() {
if (shieldSwapExecutor.isRunning()) {
shieldSwapExecutor.cancel();
}
shieldSuppressedUntilTick = -1;
lastShieldReleaseTick = -1;
waitingForPostReleaseTick = false;
}
public boolean shouldCancelShieldUse(InteractionHand hand) {
if (mc.player == null || hand == null) {
return false;
}
syncShieldState();
if (waitingForPostReleaseTick) {
return true;
}
return tickCounter <= shieldSuppressedUntilTick
&& mc.player.getItemInHand(hand).getItem() == Items.SHIELD;
}
public boolean shouldCancelUseItemOn() {
return waitingForPostReleaseTick;
}
public boolean shouldCancelEntityInteraction() {
return waitingForPostReleaseTick;
}
public void handleAttack(StrikerConstructor.AttackPerpetratorConfigurable config) {
if (canAttack(config, 1)) {
preAttackEntity(config);
}
if (checkElytraMode(config) && !checkElytraRaycast(config)) {
return;
}
if (shouldDelayRandomAttack(config)) {
return;
}
boolean raytrace = RaycastAngle.rayTrace(config);
boolean sprint = mc.player.isSprinting();
if (mc.player.isSwimming()) {
sprint = false;
}
PlayerSimulation simulated = PlayerSimulation.simulateLocalPlayer(0);
boolean wallSprintBypass = sprint && shouldBypassSprintGateInTightSpace(config, simulated);
boolean effectiveSprint = sprint && !wallSprintBypass;
boolean canAttackNow = canAttack(config, 0);
if (raytrace && canAttackNow && effectiveSprint && shouldDropGuiSprintForCritical(config)) {
stopSprintForAttack();
effectiveSprint = false;
}
if (raytrace && canAttackNow && !effectiveSprint) {
if (config.isShouldUnPressShield() && waitingForPostReleaseTick) {
return;
}
if (config.isShouldUnPressShield() && lastShieldReleaseTick == tickCounter) {
return;
}
if (config.isShouldUnPressShield() && releaseShieldForAttack()) {
return;
}
attackEntity(config);
}
}
void handleTriggerAttack(StrikerConstructor.AttackPerpetratorConfigurable config, TriggerBot triggerBot) {
if (triggerBot == null || config == null || config.getTarget() == null || !config.getTarget().isAlive()) {
return;
}
if (!attackTimer.finished(triggerBot.getAttackDelayMs())) {
return;
}
if (canAttackTrigger(config, triggerBot, 1)) {
if (!preAttackEntity(config)) {
return;
}
}
boolean raytrace = RaycastAngle.rayTrace(config);
if (raytrace && canAttackTrigger(config, triggerBot, 0)) {
if (shouldDelayAttackAfterShieldRelease(config)) {
return;
}
if (!triggerBot.shouldPassHitChance()) {
return;
}
if (triggerBot.isResetSprintLegit()) {
stopSprintForAttack();
}
attackEntity(config);
}
}
boolean preAttackEntity(StrikerConstructor.AttackPerpetratorConfigurable config) {
return true;
}
private boolean shouldDelayRandomAttack(StrikerConstructor.AttackPerpetratorConfigurable config) {
return isRandomAttackDelayMode(config)
&& count > 0
&& !attackTimer.finished(nextAttackDelayMs);
}
private boolean isRandomAttackDelayMode(StrikerConstructor.AttackPerpetratorConfigurable config) {
if (config == null || config.getAimMode() == null) {
return false;
}
String aimMode = config.getAimMode().getValue();
return "SpookyTime".equals(aimMode) || "SPAngle".equals(aimMode);
}
private boolean shouldDelayAttackAfterShieldRelease(StrikerConstructor.AttackPerpetratorConfigurable config) {
if (config == null || !config.isShouldUnPressShield()) {
return false;
}
if (waitingForPostReleaseTick) {
return true;
}
if (lastShieldReleaseTick == tickCounter) {
return true;
}
return releaseShieldForAttack();
}
private boolean shouldDropGuiSprintForCritical(StrikerConstructor.AttackPerpetratorConfigurable config) {
return config != null
&& config.isOnlyCritical()
&& mc.screen != null
&& mc.player != null
&& !mc.player.isSwimming();
}
private void stopSprintForAttack() {
if (mc.options != null) {
mc.options.keySprint.setDown(false);
}
if (mc.player != null) {
mc.player.setSprinting(false);
}
}
public void syncShieldState() {
if (mc.options == null || !mc.options.keyUse.isDown()) {
shieldSuppressedUntilTick = -1;
}
}
private boolean releaseShieldForAttack() {
if (mc.player == null || mc.gameMode == null) {
return false;
}
if (!mc.player.isUsingItem()
|| mc.player.getUseItem().isEmpty()
|| mc.player.getUseItem().getItem() != Items.SHIELD) {
return false;
}
mc.gameMode.releaseUsingItem(mc.player);
mc.player.stopUsingItem();
lastShieldReleaseTick = tickCounter;
shieldSuppressedUntilTick = tickCounter;
waitingForPostReleaseTick = true;
return true;
}
void attackEntity(StrikerConstructor.AttackPerpetratorConfigurable config) {
mc.gameMode.attack(mc.player, config.getTarget());
mc.player.swing(InteractionHand.MAIN_HAND);
attackTimer.reset();
count++;
if (isRandomAttackDelayMode(config)) {
nextAttackDelayMs = (long) MathUtils.getRandom(500, 600);
}
if (config != null && config.getAimMode() != null && "FunTime".equals(config.getAimMode().getValue())) {
AutoRegressionContext context = AutoRegressionContext.getInstance();
context.updateLastAttackTime();
context.hitContentQueue();
}
}
private boolean isRightClickInteraction(ServerboundInteractPacket packet) {
final boolean[] interaction = {false};
packet.dispatch(new ServerboundInteractPacket.Handler() {
@Override
public void onInteraction(InteractionHand hand) {
interaction[0] = true;
}
@Override
public void onInteraction(InteractionHand hand, Vec3 pos) {
interaction[0] = true;
}
@Override
public void onAttack() {
interaction[0] = false;
}
});
return interaction[0];
}
private int findAxeInHotbar() {
for (int i = 0; i < 9; i++) {
ItemStack stack = mc.player.getInventory().getItem(i);
if (!stack.isEmpty() && stack.getItem() instanceof AxeItem) {
return i;
}
}
return -1;
}
private Slot findAxeInInventory() {
for (int i = 9; i <= 35; i++) {
Slot slot = mc.player.inventoryMenu.getSlot(i);
if (slot != null && !slot.getItem().isEmpty() && slot.getItem().getItem() instanceof AxeItem) {
return slot;
}
}
return null;
}
public boolean canAttack(StrikerConstructor.AttackPerpetratorConfigurable config, int ticks) {
for (int i = 0; i <= ticks; i++) {
if (canCrit(config, i)) {
return true;
}
}
return false;
}
public boolean canCrit(StrikerConstructor.AttackPerpetratorConfigurable config, int ticks) {
if (mc.player == null || mc.options == null || config == null) {
return false;
}
if (mc.player.isUsingItem()
&& mc.player.getUseItem().getItem() != Items.SHIELD
&& config.isEatAndAttack()) {
return false;
}
if (!clickScheduler.isCooldownComplete(config.isTpsSync(), ticks)) {
return false;
}
if (config.isOnlyCritical() && !hasCriticalAttackStrength(ticks)) {
return false;
}
PlayerSimulation simulated = PlayerSimulation.simulateLocalPlayer(ticks);
if (!config.isOnlyCritical()) {
return true;
}
if (isAirAttackMode(simulated)) {
return true;
}
if (hasMovementRestrictions(simulated)) {
return true;
}
boolean tightSpaceCritical = isInsideTightSpace(simulated);
boolean smartCritJumpRequired = isSmartCritJumpRequired();
boolean smartCritJumpIntent = smartCritJumpRequired && isSmartCritJumpIntent();
boolean debuffFallback = hasDebuffThatBreaksCrit(simulated);
if (shouldHoldCriticalOnStartup(simulated, smartCritJumpRequired, smartCritJumpIntent)) {
return false;
}
if (smartCritJumpRequired && !smartCritJumpIntent && !debuffFallback) {
return !tightSpaceCritical;
}
if (debuffFallback) {
return true;
}
if (tightSpaceCritical) {
return isTightSpaceCriticalWindow(simulated);
}
return isPlayerInCriticalState(simulated, ticks);
}
private boolean canAttackTrigger(StrikerConstructor.AttackPerpetratorConfigurable config, TriggerBot triggerBot,
int ticks) {
for (int i = 0; i <= ticks; i++) {
if (canCritTrigger(config, triggerBot, i)) {
return true;
}
}
return false;
}
private boolean canCritTrigger(StrikerConstructor.AttackPerpetratorConfigurable config, TriggerBot triggerBot, int ticks) {
if (mc.player.isUsingItem()
&& !mc.player.getUseItem().getItem().equals(Items.SHIELD)
&& config.isEatAndAttack()) {
return false;
}
if (!clickScheduler.isCooldownComplete(false, ticks)) {
return false;
}
if (triggerBot.isOnlyCrits() && !hasCriticalAttackStrength(ticks)) {
return false;
}
PlayerSimulation simulated = PlayerSimulation.simulateLocalPlayer(ticks);
if (isFreeCamMode()) {
if (triggerBot.isOnlyCrits()) {
return isFreeCamCritWindow(simulated);
}
return true;
}
if (isAirAttackMode(simulated)) {
return true;
}
if (triggerBot.isOnlyCrits()) {
if (hasMovementRestrictions(simulated)) {
return true;
}
boolean tightSpaceCritical = isInsideTightSpace(simulated);
boolean debuffFallback = hasDebuffThatBreaksCrit(simulated);
boolean smartCritJumpRequired = triggerBot.isSmartCritsEnabled();
boolean smartCritJumpIntent = smartCritJumpRequired && isSmartCritJumpIntent();
if (shouldHoldCriticalOnStartupTrigger(simulated, triggerBot, smartCritJumpRequired, smartCritJumpIntent)) {
return false;
}
if (smartCritJumpRequired && !smartCritJumpIntent && !debuffFallback) {
return !tightSpaceCritical;
}
if (debuffFallback) {
return true;
}
if (tightSpaceCritical) {
return isTightSpaceCriticalWindow(simulated);
}
return isPlayerInCriticalState(simulated);
}
return true;
}
private boolean hasMovementRestrictions(PlayerSimulation simulated) {
return simulated.hasStatusEffect(MobEffects.BLINDNESS)
|| simulated.hasStatusEffect(MobEffects.LEVITATION)
|| PlayerInteractionHelper.isBoxInBlock(simulated.boundingBox.inflate(-1e-3), Blocks.COBWEB)
|| simulated.isSubmergedInWater()
|| simulated.isInLava()
|| simulated.isClimbing()
|| simulated.player.getAbilities().flying;
}
private boolean isInsideTightSpace(PlayerSimulation simulated) {
return !PlayerInteractionHelper.canChangeIntoPose(Pose.STANDING, simulated.pos)
|| simulated.horizontalCollision
|| hasHorizontalBoxPressure(simulated)
|| countBlockingSides(simulated) >= 2;
}
private boolean isTightSpaceCriticalWindow(PlayerSimulation simulated) {
if (isPvpTradeCriticalWindow(simulated)) {
return true;
}
float requiredFallDistance = resolveCriticalFallDistance(simulated, true);
double requiredVelocity = resolveCriticalVelocity(simulated, true);
if (simulated.horizontalCollision || hasHorizontalBoxPressure(simulated)) {
requiredFallDistance = Math.min(requiredFallDistance, 0.004F);
requiredVelocity = Math.max(requiredVelocity, -0.010D);
}
return !simulated.onGround
&& simulated.fallDistance > requiredFallDistance
&& simulated.velocity.y < requiredVelocity;
}
private boolean hasHorizontalBoxPressure(PlayerSimulation simulated) {
if (mc.level == null || simulated == null) {
return false;
}
AABB expandedBox = simulated.boundingBox.inflate(0.22D, 0.0D, 0.22D).deflate(1.0E-7D);
return !mc.level.noCollision(simulated.player, expandedBox);
}
private int countBlockingSides(PlayerSimulation simulated) {
int blockingSides = 0;
if (isLateralSideBlocked(simulated, 0.72D, 0.0D)) {
blockingSides++;
}
if (isLateralSideBlocked(simulated, -0.72D, 0.0D)) {
blockingSides++;
}
if (isLateralSideBlocked(simulated, 0.0D, 0.72D)) {
blockingSides++;
}
if (isLateralSideBlocked(simulated, 0.0D, -0.72D)) {
blockingSides++;
}
return blockingSides;
}
private boolean isLateralSideBlocked(PlayerSimulation simulated, double offsetX, double offsetZ) {
if (mc.level == null || simulated == null) {
return false;
}
double footY = simulated.boundingBox.minY + 0.10D;
double bodyY = Math.min(simulated.boundingBox.maxY - 0.10D, simulated.boundingBox.minY + 0.95D);
return isSolidCollisionBlock(BlockPos.containing(simulated.pos.x + offsetX, footY, simulated.pos.z + offsetZ))
|| isSolidCollisionBlock(BlockPos.containing(simulated.pos.x + offsetX, bodyY, simulated.pos.z + offsetZ));
}
private boolean isSolidCollisionBlock(BlockPos pos) {
if (mc.level == null) {
return false;
}
BlockState state = mc.level.getBlockState(pos);
return !state.isAir() && !state.getCollisionShape(mc.level, pos).isEmpty();
}
private boolean shouldBypassSprintGateInTightSpace(StrikerConstructor.AttackPerpetratorConfigurable config,
PlayerSimulation simulated) {
if (mc.player == null || config == null || simulated == null || config.getTarget() == null) {
return false;
}
if (!isInsideTightSpace(simulated)) {
return false;
}
boolean wallPressure = simulated.horizontalCollision
|| hasHorizontalBoxPressure(simulated)
|| countBlockingSides(simulated) >= 1;
if (!wallPressure) {
return false;
}
double distance = mc.player.distanceTo(config.getTarget());
return distance <= Math.min(config.getMaximumRange() + 0.35F, 2.35F);
}
private boolean hasCriticalAttackStrength(float ticks) {
return mc.player != null && mc.player.getAttackStrengthScale(ticks) > 0.88F;
}
private boolean hasCriticalRestrictions(PlayerSimulation simulated) {
return simulated.hasStatusEffect(MobEffects.BLINDNESS)
|| simulated.hasStatusEffect(MobEffects.LEVITATION)
|| simulated.isSubmergedInWater()
|| simulated.isInLava()
|| simulated.isClimbing()
|| simulated.isSwimming
|| simulated.isFallFlying
|| simulated.player.getAbilities().flying;
}
private boolean hasDebuffThatBreaksCrit(PlayerSimulation simulated) {
return simulated.hasStatusEffect(MobEffects.BLINDNESS)
|| simulated.hasStatusEffect(MobEffects.LEVITATION);
}
private boolean isSmartCritJumpRequired() {
AuraModule aura = AuraModule.getInstance();
return aura != null
&& aura.isEnabled()
&& aura.getOnlyCriticals().getValue()
&& aura.getSmartCriticals().getValue();
}
private boolean isSmartCritJumpIntent() {
if (mc.player == null) {
return false;
}
if (mc.options.keyJump.isDown()) {
return true;
}
LivingEntityAccessor accessor = (LivingEntityAccessor) mc.player;
if (accessor.releon$isJumping()) {
return true;
}
if (accessor.releon$getJumpingCooldown() > 0 && !mc.player.onGround()) {
return true;
}
return !mc.player.onGround() && mc.player.getDeltaMovement().y > 0.08D;
}
private boolean isAirAttackMode(PlayerSimulation simulated) {
return simulated.isFallFlying
|| simulated.player.getAbilities().flying
|| mc.player.isFallFlying();
}
private boolean shouldHoldCriticalOnStartup(PlayerSimulation simulated, boolean smartCritJumpRequired, boolean smartCritJumpIntent) {
AuraModule aura = AuraModule.getInstance();
if (aura == null || !aura.isEnabled() || !aura.getOnlyCriticals().getValue()) {
return false;
}
if (smartCritJumpRequired && !smartCritJumpIntent) {
return false;
}
long activatedAt = aura.getActivationTimeMs();
if (activatedAt <= 0L || System.currentTimeMillis() - activatedAt > CRIT_STARTUP_HOLD_MS) {
return false;
}
if (simulated.onGround) {
return false;
}
if (simulated.fallDistance > 0.0F) {
return false;
}
return simulated.velocity.y > -0.03D;
}
private boolean shouldHoldCriticalOnStartupTrigger(PlayerSimulation simulated, TriggerBot triggerBot,
boolean smartCritJumpRequired, boolean smartCritJumpIntent) {
if (triggerBot == null || !triggerBot.isEnabled() || !triggerBot.isOnlyCrits()) {
return false;
}
if (smartCritJumpRequired && !smartCritJumpIntent) {
return false;
}
long activatedAt = triggerBot.getActivationTimeMs();
if (activatedAt <= 0L || System.currentTimeMillis() - activatedAt > CRIT_STARTUP_HOLD_MS) {
return false;
}
if (simulated.onGround) {
return false;
}
if (simulated.fallDistance > 0.0F) {
return false;
}
return simulated.velocity.y > -0.03D;
}
private boolean isFreeCamMode() {
FreeCam freeCam = FreeCam.getInstance();
return freeCam != null && freeCam.isEnabled();
}
private boolean isFreeCamCritWindow(PlayerSimulation simulated) {
return !simulated.onGround
&& simulated.velocity.y <= -0.01D
&& !hasCriticalRestrictions(simulated);
}
private boolean checkElytraMode(StrikerConstructor.AttackPerpetratorConfigurable config) {
return AuraModule.target != null
&& AuraModule.target.isFallFlying()
&& mc.player.isFallFlying()
&& ElytraTarget.getInstance() != null
&& ElytraTarget.getInstance().isEnabled();
}
private boolean checkElytraRaycast(StrikerConstructor.AttackPerpetratorConfigurable config) {
Vec3 targetVelocity = config.getTarget().getDeltaMovement();
float leadTicks = 0;
ElytraTarget elytraTarget = ElytraTarget.getInstance();
if (ElytraTarget.shouldElytraTarget && elytraTarget != null) {
leadTicks = elytraTarget.getForward();
}
Vec3 predictedPos = config.getTarget().position().add(targetVelocity.scale(leadTicks));
AABB predictedBox = new AABB(
predictedPos.x - config.getTarget().getBbWidth() / 2,
predictedPos.y,
predictedPos.z - config.getTarget().getBbWidth() / 2,
predictedPos.x + config.getTarget().getBbWidth() / 2,
predictedPos.y + config.getTarget().getBbHeight(),
predictedPos.z + config.getTarget().getBbWidth() / 2);
Vec3 eyePos = mc.player.getEyePosition();
Vec3 lookVec = AngleConnection.INSTANCE.getRotation().toVector();
return predictedBox.clip(eyePos, eyePos.add(lookVec.scale(config.getMaximumRange()))).isPresent();
}
private boolean isPlayerInCriticalState(PlayerSimulation simulated, int ticks) {
if (simulated.onGround || hasCriticalRestrictions(simulated)) {
return false;
}
if (isPvpTradeCriticalWindow(simulated)) {
return true;
}
boolean fallingByDistance = simulated.fallDistance > resolveCriticalFallDistance(simulated, false);
boolean fallingByVelocity = simulated.velocity.y < resolveCriticalVelocity(simulated, false);
boolean leavingGroundSoon = ticks > 0 ? !PlayerSimulation.simulateLocalPlayer(ticks).onGround : !simulated.onGround;
return fallingByDistance && fallingByVelocity && leavingGroundSoon;
}
private boolean isPlayerInCriticalState(PlayerSimulation simulated) {
boolean inCobweb = PlayerInteractionHelper.isBoxInBlock(simulated.boundingBox.inflate(-1e-3), Blocks.COBWEB);
Criticals criticals = Criticals.getInstance();
if (criticals != null && criticals.isEnabled() && inCobweb) {
return !simulated.onGround || inCobweb || simulated.fallDistance > 0.001F;
}
if (simulated.onGround || hasCriticalRestrictions(simulated)) {
return false;
}
if (isPvpTradeCriticalWindow(simulated)) {
return true;
}
boolean fallingByDistance = simulated.fallDistance > resolveCriticalFallDistance(simulated, false);
boolean fallingByVelocity = simulated.velocity.y < resolveCriticalVelocity(simulated, false);
return !simulated.onGround && fallingByDistance && fallingByVelocity;
}
private boolean isPvpTradeCriticalWindow(PlayerSimulation simulated) {
return isPvpPressureState(simulated)
&& !simulated.onGround
&& simulated.fallDistance > 0.0F
&& simulated.velocity.y < -0.01D;
}
private boolean isPvpPressureState(PlayerSimulation simulated) {
return (mc.player != null && mc.player.hurtTime > 0)
|| simulated.hasStatusEffect(MobEffects.SLOWNESS);
}
private float resolveCriticalFallDistance(PlayerSimulation simulated, boolean tightSpace) {
float required = tightSpace ? 0.01F : 0.03F;
if (isPvpPressureState(simulated)) {
required = Math.min(required, tightSpace ? 0.008F : 0.012F);
}
if (simulated.horizontalCollision) {
required = Math.min(required, 0.012F);
}
return required;
}
private double resolveCriticalVelocity(PlayerSimulation simulated, boolean tightSpace) {
double required = tightSpace ? -0.02D : -0.03D;
if (isPvpPressureState(simulated)) {
required = Math.max(required, tightSpace ? -0.012D : -0.018D);
}
if (simulated.horizontalCollision) {
required = Math.max(required, -0.015D);
}
return required;
}
public StopWatch getAttackTimer() {
return attackTimer;
}
public int getCount() {
return count;
}
}