#pragma once

// -----------------------------------------------------------------------------
// aimbot.h
// -----------------------------------------------------------------------------
// Aimbot ported from the CS:GO version of the cheat. INSERT toggles the
// feature; the aim locks onto the enemy under the crosshair (m_iIDEntIndex)
// while MOUSE1 is held and firing (m_iShotsFired > 1, spray control) or
// while MOUSE3 is held (hard lock). The aim bone comes from the selected
// mode (Head / Chest / Stomach / Random, DELETE or NUMPAD 0/2/4/7/5; the
// "Off" mode falls back to the head bone). Recoil punch is subtracted from
// the aim angle and the view is smoothed by smoothAmount/100 of the
// remaining delta per pass.
// -----------------------------------------------------------------------------

#include "../core/memory.h"
#include "../core/offsets.h"
#include "../sdk/entitylist.h"
#include "../sdk/localplayer.h"

namespace features {

// Aimbot running on its own thread, toggled with INSERT.
class Aimbot
{
public:
	// Binds the memory reader, offsets, entity list and local player.
	void Initialize(const core::ProcessMemory* memory, const core::GameOffsets* offsets,
		const sdk::EntityList* entities, const sdk::LocalPlayer* player);

	// Starts the aimbot thread.
	void Start();

	// Thread entry point.
	static unsigned long __stdcall ThreadProc(void* param);

private:
	// Aims at the crosshair enemy while `virtualKey` is held. With
	// `requireShotsFired` the lock only runs while m_iShotsFired > 1
	// (spray control), mirroring the original cheat's two lock loops.
	void LockWhileHeld(int virtualKey, bool requireShotsFired);

	// One lock pass: re-aim the view at the given enemy slot.
	void AimLock(int slot);

	// Reads the recoil punch of the last shot into `outPunch`. Returns the
	// source tier used (0 = none, 1 = direct m_aimPunchCache vector,
	// 2-4 = CCSPlayer_AimPunchServices candidates, 5 = inverted
	// m_aimPunchAngle). Tiers 1-4 are raw punch (subtract), tier 5 is
	// inverted (add back).
	int ReadPunch(uintptr_t meBase, sdk::Vec3& outPunch);

	const core::ProcessMemory* m_memory = nullptr;
	const core::GameOffsets* m_offsets = nullptr;
	const sdk::EntityList* m_entities = nullptr;
	const sdk::LocalPlayer* m_player = nullptr;
};

} // namespace features