This commit is contained in:
Oscar
2025-07-18 15:14:02 +03:00
parent 4d216b662b
commit d3c189f949
87 changed files with 945 additions and 175 deletions

View File

@@ -3,13 +3,93 @@
#include "../../../templeware/interfaces/interfaces.h"
#include "../../../templeware/hooks/hooks.h"
#include "../../../templeware/config/config.h"
#include "../../utils/memory/patternscan/patternscan.h"
#include <chrono>
#include <Windows.h>
#include "../../menu/hud.h"
#include "../../menu/menu.h"
#include <array>
#include <cmath>
// Индексы костей (актуально для CS2)
constexpr int BONE_INDEX_HEAD = 6; // Head
constexpr int BONE_INDEX_NECK = 5; // Neck
constexpr int BONE_INDEX_BODY = 4;//0; // Pelvis/Root
// --- lastBoneIdx теперь глобальный static ---
static int lastBoneIdx = -1;
inline QAngle_t CalcAngles(Vector_t viewPos, Vector_t aimPos)
{
QAngle_t angle = { 0, 0, 0 };
Vector_t delta = aimPos - viewPos;
angle.x = -asin(delta.z / delta.Length()) * (180.0f / 3.141592654f);
angle.y = atan2(delta.y, delta.x) * (180.0f / 3.141592654f);
return angle;
}
inline float GetFov(const QAngle_t& viewAngle, const QAngle_t& aimAngle)
{
QAngle_t delta = (aimAngle - viewAngle).Normalize();
return sqrtf(powf(delta.x, 2.0f) + powf(delta.y, 2.0f));
}
// // Сигнатура функции GetBonePosition (актуально для client.dll):
// // 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4D 8B F1
// using GetBonePositionFn = int64_t(__fastcall*)(void*, uint32_t, Vector_t*, Vector_t*);
// static GetBonePositionFn oGetBonePosition = nullptr;
// static void InitGetBonePositionSig() {
// if (!oGetBonePosition) {
// uintptr_t addr = M::patternScan("client.dll", "48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4D 8B F1");
// oGetBonePosition = reinterpret_cast<GetBonePositionFn>(addr);
// }
// }
Vector_t GetBonePosition(const C_CSPlayerPawn* Entity, int boneIdx) {
if (!Entity) return {};
// Внешний способ: читаем Vector3 по адресу boneMatrix + boneIdx * 0x20
uintptr_t pGameSceneNode = *reinterpret_cast<uintptr_t*>((uintptr_t)Entity + 0x328);
if (!pGameSceneNode) return {};
uintptr_t pBoneMatrix = *reinterpret_cast<uintptr_t*>(pGameSceneNode + 0x1F0);
if (!pBoneMatrix) return {};
return *reinterpret_cast<Vector_t*>(pBoneMatrix + boneIdx * 0x20);
}
// Получить позицию для аимбота в зависимости от выбора пользователя
Vector_t GetAimbotTargetPos(const C_CSPlayerPawn* Entity, const Vector_t& from, const QAngle_t& viewAngles) {
switch (Config::aimbot_bone) {
case Config::BONE_HEAD:
return GetBonePosition(Entity, BONE_INDEX_HEAD);
case Config::BONE_NECK:
return GetBonePosition(Entity, BONE_INDEX_NECK);
case Config::BONE_BODY:
return GetBonePosition(Entity, BONE_INDEX_BODY);
case Config::BONE_NEAREST:
default: {
// Каждый раз ищем ближайшую кость по FOV
std::array<int, 2> bones = {BONE_INDEX_HEAD, BONE_INDEX_BODY};
float bestFov = FLT_MAX;
int bestIdx = BONE_INDEX_HEAD;
for (int idx : bones) {
Vector_t pos = GetBonePosition(Entity, idx);
QAngle_t ang = CalcAngles(from, pos); // <-- Исправлено!
float fov = GetFov(viewAngles, ang);
if (fov < bestFov && std::isfinite(fov)) {
bestFov = fov;
bestIdx = idx;
}
}
return GetBonePosition(Entity, bestIdx);
}
}
}
// Literally the most autistic code ive ever written in my life
// Please dont ever make me do this again
Vector_t GetEntityEyePos(const C_CSPlayerPawn* Entity) {
if (!Entity)
@@ -27,110 +107,306 @@ Vector_t GetEntityEyePos(const C_CSPlayerPawn* Entity) {
return Result;
}
inline QAngle_t CalcAngles(Vector_t viewPos, Vector_t aimPos)
{
QAngle_t angle = { 0, 0, 0 };
Vector_t delta = aimPos - viewPos;
angle.x = -asin(delta.z / delta.Length()) * (180.0f / 3.141592654f);
angle.y = atan2(delta.y, delta.x) * (180.0f / 3.141592654f);
return angle;
}
inline float GetFov(const QAngle_t& viewAngle, const QAngle_t& aimAngle)
{
QAngle_t delta = (aimAngle - viewAngle).Normalize();
return sqrtf(powf(delta.x, 2.0f) + powf(delta.y, 2.0f));
}
void Aimbot() {
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevAimbotState = false;
static C_CSPlayerPawn* lockedTarget = nullptr;
static bool prevAimbotState = false;
static bool targetWasLost = false;
static QAngle_t last_punch_angle = {0,0,0};
static int shotCount = 0;
bool aimbotActive = Config::always_on_aimbot ? true : Config::aimbot;
// --- shooterAfterAim + triggerbot_key ---
if (Config::shooterAfterAim && (GetAsyncKeyState(Config::triggerbot_key) & 0x8000)) {
aimbotActive = true;
}
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
Vector_t lep = GetEntityEyePos(lp);
QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
bool isShooting = (GetAsyncKeyState(Config::triggerbot_key) & 0x8000) || (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
bool aimbotActive = Config::aimbot;
int shotsFired = lp ? lp->getShotsFired() : 0;
shotCount = shotsFired;
g_DebugString = "debug: " + std::to_string(shotsFired);
if (Config::aimbot_on_lmb && !Config::always_on_aimbot) {
aimbotActive = isShooting;
}
// Получаем локального игрока и viewangles всегда, чтобы не дублировать код
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
Vector_t lep = GetEntityEyePos(lp);
QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
// Получаем локального игрока и viewangles всегда, чтобы не дублировать код
// C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
// Vector_t lep = GetEntityEyePos(lp);
// QAngle_t* viewangles = (QAngle_t*)(modules.getModule("client") + 0x1A78650);
// Если кнопка только что нажата (переход с false на true) — ищем новую цель
if (aimbotActive && !prevAimbotState) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
// Проверка: стреляет ли игрок (LMB)
// bool isShooting = (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (!Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t eye_pos = GetEntityEyePos(pawn);
QAngle_t angle = CalcAngles(eye_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
}
// --- Новый режим: always_on_aimbot ---
if (Config::always_on_aimbot) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
// Если кнопка отпущена — сбрасываем захват
if (!aimbotActive)
lockedTarget = nullptr;
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
if (bestTarget) {
Vector_t target_pos = GetAimbotTargetPos(bestTarget, lep, *viewangles);
//Vector_t target_pos = GetEntityEyePos(bestTarget);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (isShooting) {
last_punch_angle = ang_punch_angle;
} else {
last_punch_angle = {0,0,0};
}
// --- RCS ---
bool rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > 1);
if (rcsActive)
angle -= last_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
// --- RCS ---
QAngle_t delta = (angle - *viewangles).Normalize();
if (rcsActive) {
float smooth_rcs = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth_rcs = Config::aimbot_smooth + (Config::aimbot_smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
smooth_rcs = std::fmax(smooth_rcs / 10.f, 1.0f);
angle -= last_punch_angle * 2.f * smooth_rcs;
}
// --- Smooth ---
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth = smooth + (smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
*viewangles = angle;
} else {
*viewangles = angle;
}
}
// В этом режиме не используем lockedTarget и не трогаем targetWasLost/prevAimbotState
return;
}
// Если есть захваченная цель и кнопка удерживается
if (aimbotActive && lockedTarget) {
// Проверяем, что цель всё ещё валидна
if (!lockedTarget->handle().valid() || lockedTarget->getHealth() <= 0) {
lockedTarget = nullptr;
}
else {
Vector_t eye_pos = GetEntityEyePos(lockedTarget);
QAngle_t angle = CalcAngles(eye_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (Config::rcs)
angle -= ang_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::aimbot_smooth;
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
*viewangles = angle;
}
else {
*viewangles = angle;
}
}
}
// Если кнопка только что нажата (переход с false на true) — ищем новую цель
if (aimbotActive && !prevAimbotState) {
lastBoneIdx = -1; // Сброс при новой активации
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
prevAimbotState = aimbotActive;
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
targetWasLost = false;
// Сброс punch_angle при смене цели
last_punch_angle = {0,0,0};
}
// Если кнопка отпущена — сбрасываем захват
if (!aimbotActive) {
lockedTarget = nullptr;
targetWasLost = false;
last_punch_angle = {0,0,0}; // сброс rcs
// Сброс lastBoneIdx при отпускании кнопки аимбота (например, в Aimbot()):
// if (!aimbotActive) lastBoneIdx = -1;
}
// Если есть захваченная цель и кнопка удерживается
if (aimbotActive && lockedTarget) {
// Проверяем, что цель всё ещё валидна
if (!lockedTarget->handle().valid() || lockedTarget->getHealth() <= 0) {
lockedTarget = nullptr;
targetWasLost = true;
// Не ищем новую цель до повторного нажатия!
last_punch_angle = {0,0,0}; // сброс rcs
}
else {
Vector_t target_pos = GetAimbotTargetPos(lockedTarget, lep, *viewangles);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
QAngle_t ang_punch_angle = *(QAngle_t*)((uintptr_t)lp + SchemaFinder::Get(hash_32_fnv1a_const("C_CSPlayerPawn->m_aimPunchAngle")));
if (isShooting) {
last_punch_angle = ang_punch_angle;
} else {
last_punch_angle = {0,0,0};
}
// --- RCS ---
bool rcsActive = (Config::rcs || Config::shooterAfterAim) && (shotCount > 1);
if (rcsActive)
angle -= last_punch_angle * 2.f;
angle.z = 0.f;
angle = angle.Normalize();
// --- RCS ---
QAngle_t delta = (angle - *viewangles).Normalize();
if (rcsActive) {
float smooth_rcs = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth_rcs = Config::aimbot_smooth + (Config::aimbot_smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
smooth_rcs = std::fmax(smooth_rcs / 10.f, 1.0f);
angle -= last_punch_angle * 2.f * smooth_rcs;
}
// --- Smooth ---
if (Config::aimbot_smooth > 0.f) {
QAngle_t cur = *viewangles;
QAngle_t delta = (angle - cur).Normalize();
float smooth = Config::aimbot_smooth;
if (Config::aimbot_dynamic_smooth) {
float fov = sqrtf(delta.x * delta.x + delta.y * delta.y);
float maxFov = Config::aimbot_fov;
float factor = (maxFov > 0.01f) ? (fov / maxFov) : 0.f;
smooth = smooth + (smooth * factor * Config::aimbot_dynamic_smooth_factor);
}
angle = cur + delta * (1.f / smooth);
angle = angle.Normalize();
*viewangles = angle;
} else {
*viewangles = angle;
}
}
}
//Если кнопка зажата, цели нет, и мы не теряли цель (т.е. только в начале или если цели не было вообще)
if (aimbotActive && !lockedTarget && !targetWasLost) {
int nMaxHighestEntity = I::GameEntity->Instance->GetHighestEntityIndex();
float bestFov = Config::aimbot_fov;
C_CSPlayerPawn* bestTarget = nullptr;
QAngle_t bestAngle = { 0, 0, 0 };
for (int i = 1; i <= nMaxHighestEntity; i++) {
auto Entity = I::GameEntity->Instance->Get(i);
if (!Entity)
continue;
if (!Entity->handle().valid())
continue;
SchemaClassInfoData_t* _class = nullptr;
Entity->dump_class_info(&_class);
if (!_class)
continue;
const uint32_t hash = HASH(_class->szName);
if (hash == HASH("C_CSPlayerPawn")) {
C_CSPlayerPawn* pawn = (C_CSPlayerPawn*)Entity;
if (pawn->get_entity_by_handle() == lp->get_entity_by_handle())
continue;
if (pawn->getHealth() <= 0)
continue;
if (Config::team_check && pawn->getTeam() == lp->getTeam())
continue;
Vector_t target_pos = GetEntityEyePos(pawn);//GetAimbotTargetPos(pawn, lep);
QAngle_t angle = CalcAngles(target_pos, lep);
angle.x *= -1.f;
angle.y += 180.f;
const float fov = GetFov(*viewangles, angle);
if (!std::isfinite(fov) || fov > bestFov)
continue;
bestFov = fov;
bestTarget = pawn;
bestAngle = angle;
}
}
lockedTarget = bestTarget;
// Сброс punch_angle при смене цели
last_punch_angle = {0,0,0};
}
prevAimbotState = aimbotActive;
//if (Config::shooterAfterAim) {
// if (g_ShowMenu) return;
// C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
// bool onEnemy = false;
// if (lp) {
// int crosshairIdx = *(int*)((uintptr_t)lp + 0x1458); // m_iIDEntIndex
// if (crosshairIdx > 0) {
// auto target = I::GameEntity->Instance->Get<C_CSPlayerPawn>(crosshairIdx);
// if (target && target->getHealth() > 0 && (!Config::team_check || target->getTeam() != lp->getTeam()))
// onEnemy = true;
// }
// }
// // Если врага нет под прицелом — всегда блокируем ЛКМ
// if (!onEnemy && (GetAsyncKeyState(VK_LBUTTON) & 0x8000)) {
// INPUT input = { 0 };
// input.type = INPUT_MOUSE;
// input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
// SendInput(1, &input, sizeof(INPUT));
// }
// // return; // Не делаем return, чтобы аимбот работал всегда
//}
}

View File

@@ -0,0 +1,116 @@
#include "../../../cs2/entity/C_CSPlayerPawn/C_CSPlayerPawn.h"
#include "../../../templeware/interfaces/CGameEntitySystem/CGameEntitySystem.h"
#include "../../../templeware/interfaces/interfaces.h"
#include "../../../templeware/hooks/hooks.h"
#include "../../../templeware/config/config.h"
#include "../../../templeware/features/aim/aim.h"
#include <Windows.h>
#include <cmath>
// Симуляция нажатия ЛКМ
void SimulateLMBClick() {
INPUT input = { 0 };
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(INPUT));
ZeroMemory(&input, sizeof(INPUT));
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(INPUT));
}
void SimulateLMBDown() {
INPUT input = { 0 };
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(INPUT));
}
void SimulateLMBUp() {
INPUT input = { 0 };
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(INPUT));
}
static DWORD lastShotTime = 0;
void Triggerbot() {
static DWORD lastShotTime = 0;
static bool lmbHeld = false;
static bool firstShot = true;
if (!Config::triggerbot)
return;
if (!Config::always_on_triggerbot && Config::triggerbot_key && !(GetAsyncKeyState(Config::triggerbot_key) & 0x8000))
return;
if (GetAsyncKeyState(VK_LBUTTON) & 0x8000) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
C_CSPlayerPawn* lp = H::oGetLocalPlayer(0);
if (!lp || lp->getHealth() <= 0) { firstShot = true; return; }
int crosshairIdx = *(int*)((uintptr_t)lp + 0x1458); // m_iIDEntIndex
//g_DebugString = "debug: " + std::to_string(crosshairIdx);
if (crosshairIdx <= 0) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
auto target = I::GameEntity->Instance->Get<C_CSPlayerPawn>(crosshairIdx);
if (!target) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
if (target->getHealth() <= 0) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
if (Config::team_check && target->getTeam() == lp->getTeam()) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
DWORD64 now = GetTickCount64();
if (!Config::triggerbot_hold_lmb) {
if (now - lastShotTime < static_cast<DWORD64>(Config::triggerbot_delay)) {
if (lmbHeld) {
SimulateLMBUp();
lmbHeld = false;
}
firstShot = true;
return;
}
}
if (Config::triggerbot_hold_lmb) {
if (firstShot) {
SimulateLMBClick();
firstShot = false;
lastShotTime = now;
return;
} else if (!lmbHeld) {
SimulateLMBDown();
lmbHeld = true;
}
lastShotTime = now;
return;
}
SimulateLMBClick();
lastShotTime = now;
firstShot = true;
}

View File

@@ -0,0 +1,3 @@
#pragma once
void Triggerbot();