namespace {
constexpr int kGroundDelayTicks = 4;
double readVelY(const Bindings &b, JObject player) {
if (!b.entityVelocity || !b.vec3Y) return 0.0;
JObject vel = player.Obj(b.entityVelocity);
if (!vel) return 0.0;
return vel.Double(b.vec3Y);
}
bool readOnGround(const Bindings &b, JObject player) {
if (!b.entityOnGround) return true;
return player.Bool(b.entityOnGround) != 0;
}
}
bool Triggerbot::apply(
DWORD pid,
const Settings &settings,
const Bindings &b,
JObject instance,
JObject player,
JObject hit,
ExternalTriggerbotState &state
) {
if (!player) return false;
bool onGround = readOnGround(b, player);
if (onGround) {
state.groundTicks++;
} else {
state.groundTicks = 0;
}
if (!hit) return true;
std::string hitClass = Jvm::className(getobjectclass(hit.ptr));
bool isEntityHit = (hitClass == "net/minecraft/class_3966" || hitClass == "net/minecraft/util/hit/EntityHitResult");
if (!isEntityHit) return true;
JObject target = hit.Obj(b.ehrEntity);
if (!target) return true;
int targetId = target.Int(b.entityId);
JObject profile = b.playerGameProfile ? target.Obj(b.playerGameProfile) : JObject();
bool targetIsPlayer = profile;
if (!targetIsPlayer) return true;
if (!settings.triggerbot.load()) return true;
int lastAttackedTicks = player.Int(b.livingLastAttackedTicks);
bool cooldownReady = lastAttackedTicks >= 12;
if (!cooldownReady) return true;
double velY = readVelY(b, player);
if (settings.onlyCrits.load()) {
if (onGround || velY >= -0.1) return true;
} else {
if (!onGround) {
if (velY > 0.0) return true;
if (velY >= -0.15) return true;
} else {
if (state.groundTicks < kSmartGroundDelayTicks) return true;
}
}
if (!instance || !b.mcOptions || !b.optionsAttackKey || !b.keyTimesPressed) return true;
ULONGLONG now = GetTickCount64();
if (now - state.lastClickMs < 50) return true;
JObject options = instance.Obj(b.mcOptions);
if (!options) return true;
JObject attackKey = options.Obj(b.optionsAttackKey);
if (!attackKey) return true;
int cur = attackKey.Int(b.keyTimesPressed);
attackKey.Int(b.keyTimesPressed, cur + 1);
state.lastClickMs = now;
return true;
}