Facebook
From Torrid Moth, 5 Years ago, written in Plain Text.
This paste is a reply to src from Ivory Pheasant - go back
Embed
Viewing differences between src and Re: src
#include "Menu.h"
#include "Controls.h"
#include "Hooks.h" // for the unload meme
#include "Interfaces.h"

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

AimWareWindow Menu::Window;

void UnLoadCallbk()
{
    DoUnload = true;
}

void KnifeApplyCallbk()
{
    static ConVar* Meme = Interfaces::CVar->FindVar("cl_fullupdate");
    Meme->nFlags &= ~FCVAR_CHEAT;
    Interfaces::Engine->ClientCmd_Unrestricted("cl_fullupdate");
}

void AimWareWindow::Setup()
{
    SetPosition(50, 50);
    SetSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    SetTitle(" PatrickHook-BestPrivateCheats);

    RegisterTab(&RageBotTab);
    RegisterTab(&LegitBotTab);
    RegisterTab(&VisualsTab);
    RegisterTab(&MiscTab);

    RECT Client = GetClientArea();
    Client.bottom -= 29;

    RageBotTab.Setup();
    LegitBotTab.Setup();
    VisualsTab.Setup();
    MiscTab.Setup();

#pragma region Bottom Buttons
    UnloadButton.SetText("PANIC");
    UnloadButton.SetCallback(UnLoadCallbk);
    UnloadButton.SetPosition(16, Client.bottom - 42);

    RageBotTab.RegisterControl(&UnloadButton);
    LegitBotTab.RegisterControl(&UnloadButton);
    VisualsTab.RegisterControl(&UnloadButton);
    MiscTab.RegisterControl(&UnloadButton);

    //SaveButton.SetText("Save Settings");
    //SaveButton.SetCallback(Call);
    //SaveButton.SetPosition(112, Client.bottom - 42);

    //RageBotTab.RegisterControl(&SaveButton);
    //LegitBotTab.RegisterControl(&SaveButton);
    //VisualsTab.RegisterControl(&SaveButton);
    //MiscTab.RegisterControl(&SaveButton);


#pragma endregion Setting up the settings buttons
}

void CRageBotTab::Setup()
{
    SetTitle("Rage Aimbot");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Aimbot

    AimbotGroup.SetPosition(16, 48);
    AimbotGroup.SetText("Aimbot");
    AimbotGroup.SetSize(376, 280);
    RegisterControl(&AimbotGroup);

    AimbotEnable.SetFileId("aim_enable");
    AimbotGroup.PlaceLabledControl("Enable", this, &AimbotEnable);

    AimbotAutoFire.SetFileId("aim_autofire");
    AimbotGroup.PlaceLabledControl("Auto Fire", this, &AimbotAutoFire);

    AimbotFov.SetFileId("aim_fov");
    AimbotFov.SetBoundaries(0.f, 180.f);
    AimbotFov.SetValue(39.f);
    AimbotGroup.PlaceLabledControl("FOV Range", this, &AimbotFov);

    AimbotSilentAim.SetFileId("aim_silent");
    AimbotGroup.PlaceLabledControl("Silent Aim", this, &AimbotSilentAim);

    AimbotPSilent.SetFileId("aim_psilent");
    AimbotGroup.PlaceLabledControl("Perfect Silent", this, &AimbotPSilent);

    AimbotAutoPistol.SetFileId("aim_autopistol");
    AimbotGroup.PlaceLabledControl("Auto Pistol", this, &AimbotAutoPistol);

    AimbotAimStep.SetFileId("aim_aimstep");
    AimbotGroup.PlaceLabledControl("Aim Step", this, &AimbotAimStep);

    AimbotKeyPress.SetFileId("aim_usekey");
    AimbotGroup.PlaceLabledControl("On Key Press", this, &AimbotKeyPress);

    AimbotKeyBind.SetFileId("aim_key");
    AimbotGroup.PlaceLabledControl("Key", this, &AimbotKeyBind);

    AimbotChicken.SetFileId("aim_chicken");
    AimbotGroup.PlaceLabledControl("Chikens", this, &AimbotChicken);

#pragma endregion Aimbot Controls Get Setup in here

#pragma region Target
    TargetGroup.SetPosition(16, 344);
    TargetGroup.SetText("Target");
    TargetGroup.SetSize(376, 134);
    RegisterControl(&TargetGroup);

    TargetSelection.SetFileId("tgt_selection");
    TargetSelection.AddItem("Closest To Crosshair");
    TargetSelection.AddItem("Distance");
    TargetSelection.AddItem("Lowest Health");
    TargetGroup.PlaceLabledControl("Selection", this, &TargetSelection);

    TargetFriendlyFire.SetFileId("tgt_friendlyfire");
    TargetGroup.PlaceLabledControl("Friendly Fire", this, &TargetFriendlyFire);

    TargetHitbox.SetFileId("tgt_hitbox");
    TargetHitbox.AddItem("Head");
    TargetHitbox.AddItem("Neck");
    TargetHitbox.AddItem("Chest");
    TargetHitbox.AddItem("Stomach");
    TargetGroup.PlaceLabledControl("Hitbox", this, &TargetHitbox);

    TargetHitscan.SetFileId("tgt_hitscan");
    TargetHitscan.AddItem("Off"); //0
    TargetHitscan.AddItem("Head / Body"); // 1
    TargetHitscan.AddItem("All Basic"); // 2
    TargetHitscan.AddItem("All Fucking Heaps"); // 3
    TargetGroup.PlaceLabledControl("Hit Scan", this, &TargetHitscan);
#pragma endregion Targetting controls 

#pragma region Accuracy
    AccuracyGroup.SetPosition(408, 48);
    AccuracyGroup.SetText("Accuracy");
    AccuracyGroup.SetSize(360, 280);
    RegisterControl(&AccuracyGroup);

    AccuracySpread.SetFileId("acc_nospread");
    AccuracyGroup.PlaceLabledControl("Anti Spread", this, &AccuracySpread);

    AccuracyRecoil.SetFileId("acc_norecoil");
    AccuracyGroup.PlaceLabledControl("Anti Recoil", this, &AccuracyRecoil);

    AccuracyAutoWall.SetFileId("acc_awall");
    AccuracyGroup.PlaceLabledControl("Auto Wall", this, &AccuracyAutoWall);

    AccuracyMinimumDamage.SetFileId("acc_mindmg");
    AccuracyMinimumDamage.SetBoundaries(1.f, 100.f);
    AccuracyMinimumDamage.SetValue(1.f);
    AccuracyGroup.PlaceLabledControl("Min AWall Damage", this, &AccuracyMinimumDamage);

    AccuracyAutoStop.SetFileId("acc_stop");
    AccuracyGroup.PlaceLabledControl("Auto Stop", this, &AccuracyAutoStop);

    AccuracyAutoCrouch.SetFileId("acc_crouch");
    AccuracyGroup.PlaceLabledControl("Auto Crouch", this, &AccuracyAutoCrouch);

    AccuracyAutoScope.SetFileId("acc_scope");
    AccuracyGroup.PlaceLabledControl("Auto Scope", this, &AccuracyAutoScope);

    AccuracySpreadLimit.SetFileId("acc_spreadlimon");
    AccuracyGroup.PlaceLabledControl("Spread Limit", this, &AccuracySpreadLimit);

    AccuracyMinimumSpread.SetFileId("acc_spreadlim");
    AccuracyMinimumSpread.SetBoundaries(0.f, 5.0f);
    AccuracyMinimumSpread.SetValue(1.5f);
    AccuracyGroup.PlaceLabledControl("Spread Limit Value", this, &AccuracyMinimumSpread);

    AccuracyAngleFix.SetFileId("acc_aaa");
    AccuracyGroup.PlaceLabledControl("AngleFix", this, &AccuracyAngleFix);
#pragma endregion  Accuracy controls get Setup in here

#pragma region AntiAim
    AntiAimGroup.SetPosition(408, 344);
    AntiAimGroup.SetText("Anti-Aim");
    AntiAimGroup.SetSize(360, 134);
    RegisterControl(&AntiAimGroup);

    AntiAimEnable.SetFileId("aa_enable");
    AntiAimGroup.PlaceLabledControl("Enable", this, &AntiAimEnable);

    AntiAimPitch.SetFileId("aa_x");
    AntiAimPitch.AddItem("None");
    AntiAimPitch.AddItem("Up");
    AntiAimPitch.AddItem("Down");
    AntiAimPitch.AddItem("Jitter");
    AntiAimGroup.PlaceLabledControl("X", this, &AntiAimPitch);

    AntiAimYaw.SetFileId("aa_y");
    AntiAimYaw.AddItem("None");
    AntiAimYaw.AddItem("Spin Fast");
    AntiAimYaw.AddItem("Spin Slow");
    AntiAimYaw.AddItem("Inverse");
    AntiAimYaw.AddItem("Jitter");
    AntiAimYaw.AddItem("Flip");
    AntiAimGroup.PlaceLabledControl("Y", this, &AntiAimYaw);

#pragma endregion  AntiAim controls get setup in here
}

void CLegitBotTab::Setup()
{
    SetTitle("Legit Aimbot");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Aimbot
    AimbotGroup.SetPosition(16, 48);
    AimbotGroup.SetText("Aimbot");
    AimbotGroup.SetSize(240, 210);
    RegisterControl(&AimbotGroup);

    AimbotEnable.SetFileId("aim_enable");
    AimbotGroup.PlaceLabledControl("Enable", this, &AimbotEnable);

    AimbotAutoFire.SetFileId("aim_autofire");
    AimbotGroup.PlaceLabledControl("Auto Fire", this, &AimbotAutoFire);

    AimbotFriendlyFire.SetFileId("aim_friendfire");
    AimbotGroup.PlaceLabledControl("Friendly Fire", this, &AimbotFriendlyFire);

    AimbotKeyPress.SetFileId("aim_usekey");
    AimbotGroup.PlaceLabledControl("On Key Press", this, &AimbotKeyPress);

    AimbotKeyBind.SetFileId("aim_key");
    AimbotGroup.PlaceLabledControl("Key Bind", this, &AimbotKeyBind);

    AimbotAutoPistol.SetFileId("aim_apistol");
    AimbotGroup.PlaceLabledControl("Auto Pistol", this, &AimbotAutoPistol);

#pragma endregion Aimbot shit

#pragma region Triggerbot
    TriggerGroup.SetPosition(272, 48);
    TriggerGroup.SetText("Triggerbot");
    TriggerGroup.SetSize(240, 210);
    RegisterControl(&TriggerGroup);

    TriggerEnable.SetFileId("trig_enable");
    TriggerGroup.PlaceLabledControl("Enable", this, &TriggerEnable);

    TriggerKeyPress.SetFileId("trig_onkey");
    TriggerGroup.PlaceLabledControl("On Key Press", this, &TriggerKeyPress);

    TriggerKeyBind.SetFileId("trig_key");
    TriggerGroup.PlaceLabledControl("Key Bind", this, &TriggerKeyBind);

    TriggerDelay.SetFileId("trig_delay");
    TriggerDelay.SetBoundaries(1, 1000);
    TriggerDelay.SetValue(50);
    TriggerGroup.PlaceLabledControl("Delay", this, &TriggerDelay);
#pragma endregion Triggerbot stuff

#pragma region Main Weapon
    WeaponMainGroup.SetPosition(16, 274);
    WeaponMainGroup.SetText("Rifles/Other");
    WeaponMainGroup.SetSize(240, 210);
    RegisterControl(&WeaponMainGroup);

    WeaponMainSpeed.SetFileId("main_speed");
    WeaponMainSpeed.SetBoundaries(0.1f, 2.f);
    WeaponMainSpeed.SetValue(1.0f);
    WeaponMainGroup.PlaceLabledControl("Max Speed", this, &WeaponMainSpeed);

    WeaponMainFoV.SetFileId("main_fov");
    WeaponMainFoV.SetBoundaries(0.1f, 30.f);
    WeaponMainFoV.SetValue(5.f);
    WeaponMainGroup.PlaceLabledControl("FOV", this, &WeaponMainFoV);

    WeaponMainRecoil.SetFileId("main_recoil");
    WeaponMainGroup.PlaceLabledControl("Recoil", this, &WeaponMainRecoil);

    WeaponMainHitbox.SetFileId("main_hitbox");
    WeaponMainHitbox.AddItem("Head");
    WeaponMainHitbox.AddItem("Neck");
    WeaponMainHitbox.AddItem("Chest");
    WeaponMainHitbox.AddItem("Stomach");
    WeaponMainGroup.PlaceLabledControl("Hitbox", this, &WeaponMainHitbox);
#pragma endregion

#pragma region Pistols
    WeaponPistGroup.SetPosition(272, 274);
    WeaponPistGroup.SetText("Pistols");
    WeaponPistGroup.SetSize(240, 210);
    RegisterControl(&WeaponPistGroup);

    WeaponPistSpeed.SetFileId("pist_speed");
    WeaponPistSpeed.SetBoundaries(0.1f, 2.f);
    WeaponPistSpeed.SetValue(1.0f);
    WeaponPistGroup.PlaceLabledControl("Max Speed", this, &WeaponPistSpeed);

    WeaponPistFoV.SetFileId("pist_fov");
    WeaponPistFoV.SetBoundaries(0.1f, 30.f);
    WeaponPistFoV.SetValue(5.f);
    WeaponPistGroup.PlaceLabledControl("FOV", this, &WeaponPistFoV);

    WeaponPistRecoil.SetFileId("pist_recoil");
    WeaponPistGroup.PlaceLabledControl("Recoil", this, &WeaponPistRecoil);

    WeaponPistHitbox.SetFileId("pist_hitbox");
    WeaponPistHitbox.AddItem("Head");
    WeaponPistHitbox.AddItem("Neck");
    WeaponPistHitbox.AddItem("Chest");
    WeaponPistHitbox.AddItem("Stomach");
    WeaponPistGroup.PlaceLabledControl("Hitbox", this, &WeaponPistHitbox);
#pragma endregion

#pragma region Snipers
    WeaponSnipGroup.SetPosition(528, 274);
    WeaponSnipGroup.SetText("Snipers");
    WeaponSnipGroup.SetSize(240, 210);
    RegisterControl(&WeaponSnipGroup);

    WeaponSnipSpeed.SetFileId("snip_speed");
    WeaponSnipSpeed.SetBoundaries(0.1f, 2.f);
    WeaponSnipSpeed.SetValue(1.0f);
    WeaponSnipGroup.PlaceLabledControl("Max Speed", this, &WeaponSnipSpeed);

    WeaponSnipFoV.SetFileId("snip_fov");
    WeaponSnipFoV.SetBoundaries(0.1f, 30.f);
    WeaponSnipFoV.SetValue(5.f);
    WeaponSnipGroup.PlaceLabledControl("FOV", this, &WeaponSnipFoV);

    WeaponSnipRecoil.SetFileId("snip_recoil");
    WeaponSnipGroup.PlaceLabledControl("Recoil", this, &WeaponSnipRecoil);

    WeaponSnipHitbox.SetFileId("snip_hitbox");
    WeaponSnipHitbox.AddItem("Head");
    WeaponSnipHitbox.AddItem("Neck");
    WeaponSnipHitbox.AddItem("Chest");
    WeaponSnipHitbox.AddItem("Stomach");
    WeaponSnipGroup.PlaceLabledControl("Hitbox", this, &WeaponSnipHitbox);
#pragma endregion
}

void CVisualTab::Setup()
{
    SetTitle("Visuals & Misc");

    ActiveLabel.SetPosition(16, 16);
    ActiveLabel.SetText("Active");
    RegisterControl(&ActiveLabel);

    Active.SetFileId("active");
    Active.SetPosition(66, 16);
    RegisterControl(&Active);

#pragma region Options
    OptionsGroup.SetText("Options");
    OptionsGroup.SetPosition(16, 48);
    OptionsGroup.SetSize(193, 430);
    RegisterControl(&OptionsGroup);

    OptionsBox.SetFileId("opt_box");
    OptionsGroup.PlaceLabledControl("Box", this, &OptionsBox);

    OptionsName.SetFileId("opt_name");
    OptionsGroup.PlaceLabledControl("Name", this, &OptionsName);

    OptionsHealth.SetFileId("opt_hp");
    OptionsGroup.PlaceLabledControl("Health", this, &OptionsHealth);

    OptionsWeapon.SetFileId("opt_weapon");
    OptionsGroup.PlaceLabledControl("Weapon", this, &OptionsWeapon);

    OptionsInfo.SetFileId("opt_info");
    OptionsGroup.PlaceLabledControl("Info", this, &OptionsInfo);

    OptionsChams.SetFileId("opt_chams");
    OptionsChams.AddItem("Off");
    OptionsChams.AddItem("Normal");
    OptionsChams.AddItem("Flat");
    OptionsGroup.PlaceLabledControl("Chams", this, &OptionsChams);

    OptionsSkeleton.SetFileId("opt_bone");
    OptionsGroup.PlaceLabledControl("Skeleton", this, &OptionsSkeleton);

    OptionsAimSpot.SetFileId("opt_aimspot");
    OptionsGroup.PlaceLabledControl("Aim Spot", this, &OptionsAimSpot);

    OptionsCompRank.SetFileId("opt_comprank");
    OptionsGroup.PlaceLabledControl("Competitive Rank", this, &OptionsCompRank);

#pragma endregion Setting up the Options controls

#pragma region Filters
    FiltersGroup.SetText("Filters");
    FiltersGroup.SetPosition(225, 48);
    FiltersGroup.SetSize(193, 430);
    RegisterControl(&FiltersGroup);

    FiltersAll.SetFileId("ftr_all");
    FiltersGroup.PlaceLabledControl("All", this, &FiltersAll);

    FiltersPlayers.SetFileId("ftr_players");
    FiltersGroup.PlaceLabledControl("Players", this, &FiltersPlayers);

    FiltersEnemiesOnly.SetFileId("ftr_enemyonly");
    FiltersGroup.PlaceLabledControl("Enemies Only", this, &FiltersEnemiesOnly);

    FiltersWeapons.SetFileId("ftr_weaps");
    FiltersGroup.PlaceLabledControl("Weapons", this, &FiltersWeapons);

    FiltersChickens.SetFileId("ftr_chickens");
    FiltersGroup.PlaceLabledControl("Chickens", this, &FiltersChickens);

    FiltersC4.SetFileId("ftr_c4");
    FiltersGroup.PlaceLabledControl("C4", this, &FiltersC4);
#pragma endregion Setting up the Filters controls

#pragma region Other
    OtherGroup.SetText("Other");
    OtherGroup.SetPosition(434, 48);
    OtherGroup.SetSize(334, 430);
    RegisterControl(&OtherGroup);

    OtherCrosshair.SetFileId("otr_xhair");
    OtherGroup.PlaceLabledControl("Crosshair", this, &OtherCrosshair);

    OtherRecoilCrosshair.SetFileId("otr_recoilhair");
    OtherRecoilCrosshair.AddItem("Off");
    OtherRecoilCrosshair.AddItem("Recoil Position");
    OtherRecoilCrosshair.AddItem("Radius");
    OtherGroup.PlaceLabledControl("Recoil Crosshair", this, &OtherRecoilCrosshair);

    OtherRadar.SetFileId("otr_radar");
    OtherGroup.PlaceLabledControl("Radar", this, &OtherRadar);

    OtherNoVisualRecoil.SetFileId("otr_visrecoil");
    OtherGroup.PlaceLabledControl("No Visual Recoil", this, &OtherNoVisualRecoil);

    OtherNoSky.SetFileId("otr_nosky");
    OtherGroup.PlaceLabledControl("No Sky", this, &OtherNoSky);

    OtherNoFlash.SetFileId("otr_noflash");
    OtherGroup.PlaceLabledControl("No Flash", this, &OtherNoFlash);

    OtherNoSmoke.SetFileId("otr_nosmoke");
    OtherGroup.PlaceLabledControl("No Smoke", this, &OtherNoSmoke);

    OtherNoHands.SetFileId("otr_hands");
    OtherNoHands.AddItem("Off");
    OtherNoHands.AddItem("None");
    OtherNoHands.AddItem("Transparent");
    OtherNoHands.AddItem("Chams");
    OtherNoHands.AddItem("Rainbow");
    OtherGroup.PlaceLabledControl("Hands", this, &OtherNoHands);

    OtherAutoJump.SetFileId("otr_autojump");
    OtherGroup.PlaceLabledControl("Auto Jump", this, &OtherAutoJump);

    OtherAutoStrafe.SetFileId("otr_autostrafe");
    OtherGroup.PlaceLabledControl("Auto Strafe", this, &OtherAutoStrafe);

    OtherSafeMode.SetFileId("otr_safemode");
    OtherSafeMode.SetState(true);
    OtherGroup.PlaceLabledControl("Safe Mode", this, &OtherSafeMode);

    OtherChatSpam.SetFileId("otr_spam");
    OtherChatSpam.AddItem("Off");
    OtherChatSpam.AddItem("Round-Say");
    OtherChatSpam.AddItem("Regular");
    OtherChatSpam.AddItem("Report Text Spam");
    OtherGroup.PlaceLabledControl("Chat Spam", this, &OtherChatSpam);

    OtherAirStuck.SetFileId("otr_astuck");
    OtherGroup.PlaceLabledControl("Air Stuck", this, &OtherAirStuck);

    OtherSpectators.SetFileId("otr_speclist");
    OtherGroup.PlaceLabledControl("Spectators List", this, &OtherSpectators);
#pragma endregion Setting up the Other controls
}

void CMiscTab::Setup()
{
    SetTitle("Skins");

#pragma region Knife
    KnifeGroup.SetPosition(16, 16);
    KnifeGroup.SetSize(360, 400);
    KnifeGroup.SetText("Skin Changer");
    RegisterControl(&KnifeGroup);

    KnifeEnable.SetFileId("knife_enable");
    KnifeGroup.PlaceLabledControl("Enable", this, &KnifeEnable);

    KnifeModel.SetFileId("knife_model");
    KnifeModel.AddItem("Karambit");
    KnifeModel.AddItem("Bayonet");
    KnifeModel.AddItem("Huntsman Knife");
    KnifeModel.AddItem("Gut Knife");
    KnifeModel.AddItem("Walmart Knife");
    KnifeModel.AddItem("Shadow Daggers");
    KnifeModel.AddItem("Butterfly Knife");
    KnifeModel.AddItem("Flip Knife");
    KnifeGroup.PlaceLabledControl("Knife", this, &KnifeModel);

    KnifeSkin.SetFileId("knife_skin");
    KnifeSkin.AddItem("Fade");
    KnifeSkin.AddItem("Damascus Steel");
    KnifeSkin.AddItem("Doppler Phase 1");
    KnifeSkin.AddItem("Doppler Phase 2");
    KnifeSkin.AddItem("Doppler Phase 3");
    KnifeSkin.AddItem("Doppler Phase 4");
    KnifeSkin.AddItem("Doppler (Ruby)");
    KnifeSkin.AddItem("Doppler (Sapphire)");
    KnifeSkin.AddItem("Doppler (Blackpearl)");
    KnifeSkin.AddItem("Marble Fade");
    KnifeSkin.AddItem("Tiger Tooth");
    KnifeSkin.AddItem("Ultraviolet");
    KnifeSkin.AddItem("Crimson Web");
    KnifeSkin.AddItem("Slaughter");
    KnifeSkin.AddItem("Night");
    KnifeGroup.PlaceLabledControl("Skin", this, &KnifeSkin);

    M41SSkin.SetFileId("m4a1s_skin");
    M41SSkin.AddItem("Masterpiece");
    M41SSkin.AddItem("Hyper Beast");
    M41SSkin.AddItem("Cyrex");
    M41SSkin.AddItem("Hot Rod");
    KnifeGroup.PlaceLabledControl("M4A1-S", this, &M41SSkin);

    M4A4Skin.SetFileId("m4a4_skin");
    M4A4Skin.AddItem("Royal Paladin");
    M4A4Skin.AddItem("Howl");
    M4A4Skin.AddItem("Bullet Rain");
    M4A4Skin.AddItem("Dragon King");
    M4A4Skin.AddItem("Asiimov");
    KnifeGroup.PlaceLabledControl("M4A4", this, &M4A4Skin);

    AK47Skin.SetFileId("ak47_skin");
    AK47Skin.AddItem("Point Disarray");
    AK47Skin.AddItem("Aquamarine Revenge");
    AK47Skin.AddItem("Vulcan");
    AK47Skin.AddItem("Fire Serpent");
    AK47Skin.AddItem("Jaguar");
    KnifeGroup.PlaceLabledControl("AK-47", this, &AK47Skin);

    AWPSkin.SetFileId("awp_skin");
    AWPSkin.AddItem("Hyper Beast");
    AWPSkin.AddItem("Asiimov");
    AWPSkin.AddItem("Dragon Lore");
    AWPSkin.AddItem("Lightning Strike");
    KnifeGroup.PlaceLabledControl("AWP", this, &AWPSkin);

    GLOCKSkin.SetFileId("glock_skin");
    GLOCKSkin.AddItem("Water Elemental");
    GLOCKSkin.AddItem("Fade");
    GLOCKSkin.AddItem("Twilight Galaxy");
    GLOCKSkin.AddItem("Bunsen Burner");
    KnifeGroup.PlaceLabledControl("Glock", this, &GLOCKSkin);

    USPSSkin.SetFileId("m4a1s_skin");
    USPSSkin.AddItem("Kill Confirmed");
    USPSSkin.AddItem("Caiman");
    USPSSkin.AddItem("Orion");
    USPSSkin.AddItem("Guardian");
    KnifeGroup.PlaceLabledControl("USP-S", this, &USPSSkin);

    MAGNUMSkin.SetFileId("357_skin");
    MAGNUMSkin.AddItem("Crimson Web");
    MAGNUMSkin.AddItem("Fade");
    MAGNUMSkin.AddItem("Amber Fade");
    KnifeGroup.PlaceLabledControl("R8 Revolver", this, &MAGNUMSkin);

    KnifeApply.SetText("Apply Changes");
    KnifeApply.SetCallback(KnifeApplyCallbk);
    KnifeGroup.PlaceLabledControl("", this, &KnifeApply);






#pragma endregion

#pragma endregion other random options
}

void Menu::SetupMenu()
{
    Window.Setup();

    GUI.RegisterWindow(&Window);
    GUI.BindWindow(VK_INSERT, &Window);
}

void Menu::DoUIFrame()
{
    // General Processing

    // If the "all filter is selected tick all the others
    if (Window.VisualsTab.FiltersAll.GetState())
    {
        Window.VisualsTab.FiltersC4.SetState(true);
        Window.VisualsTab.FiltersChickens.SetState(true);
        Window.VisualsTab.FiltersPlayers.SetState(true);
        Window.VisualsTab.FiltersWeapons.SetState(true);
    }

    GUI.Update();
    GUI.Draw();


}


#include "GUI.h"

#include "RenderManager.h"

#include 
#include "tinyxml2.h"
#include "Controls.h"

CGUI GUI;

CGUI::CGUI()
{

}

// Draws all windows 
void CGUI::Draw()
{
    bool ShouldDrawCursor = false;

    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            ShouldDrawCursor = true;
            DrawWindow(window);
        }

    }

    if (ShouldDrawCursor)
    {
        static Vertex_t MouseVt[3];

        MouseVt[0].Init(Vector2D(Mouse.x, Mouse.y));
        MouseVt[1].Init(Vector2D(Mouse.x + 16, Mouse.y));
        MouseVt[2].Init(Vector2D(Mouse.x, Mouse.y + 16));

        Render::PolygonOutline(3, MouseVt, Color(150, 0, 0, 230), Color(0, 0, 0, 150));
    }
}

// Handle all input etc
void CGUI::Update()
{
    //Key Array
    std::copy(keys, keys + 255, oldKeys);
    for (int x = 0; x < 255; x++)
    {
        //oldKeys[x] = oldKeys[x] & keys[x];
        keys[x] = (GetAsyncKeyState(x));
    }

    // Mouse Location
    POINT mp; GetCursorPos(&mp);
    Mouse.x = mp.x; Mouse.y = mp.y;

    RECT Screen = Render::GetViewport();

    // Window Binds
    for (auto & bind : WindowBinds)
    {
        if (GetKeyPress(bind.first))
        {
            bind.second->Toggle();
        }
    }

    // Stop dragging
    if (IsDraggingWindow && !GetKeyState(VK_LBUTTON))
    {
        IsDraggingWindow = false;
        DraggingWindow = nullptr;
    }

    // If we are in the proccess of dragging a window
    if (IsDraggingWindow && GetKeyState(VK_LBUTTON) && !GetKeyPress(VK_LBUTTON))
    {
        if (DraggingWindow)
        {
            DraggingWindow->m_x = Mouse.x - DragOffsetX;
            DraggingWindow->m_y = Mouse.y - DragOffsetY;
        }
    }

    // Process some windows
    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            // Used to tell the widget processing that there could be a click
            bool bCheckWidgetClicks = false;

            // If the user clicks inside the window
            if (GetKeyPress(VK_LBUTTON))
            {
                if (IsMouseInRegion(window->m_x, window->m_y, window->m_x + window->m_iWidth, window->m_y + window->m_iHeight))
                {
                    // Is it inside the client area?
                    if (IsMouseInRegion(window->GetClientArea()))
                    {
                        // User is selecting a new tab
                        if (IsMouseInRegion(window->GetTabArea()))
                        {
                            // Loose focus on the control
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;

                            int iTab = 0;
                            int TabCount = window->Tabs.size();
                            if (TabCount) // If there are some tabs
                            {
                                int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
                                int Dist = Mouse.x - (window->m_x + 8);
                                while (Dist > TabSize)
                                {
                                    if (Dist > TabSize)
                                    {
                                        iTab++;
                                        Dist -= TabSize;
                                    }
                                }
                                window->SelectedTab = window->Tabs[iTab];
                            }

                        }
                        else
                            bCheckWidgetClicks = true;
                    }
                    else
                    {
                        // Must be in the around the title or side of the window
                        // So we assume the user is trying to drag the window
                        IsDraggingWindow = true;
                        DraggingWindow = window;
                        DragOffsetX = Mouse.x - window->m_x;
                        DragOffsetY = Mouse.y - window->m_y;

                        // Loose focus on the control
                        window->IsFocusingControl = false;
                        window->FocusedControl = nullptr;
                    }
                }
                else
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }


            // Controls 
            if (window->SelectedTab != nullptr)
            {
                // Focused widget
                bool SkipWidget = false;
                CControl* SkipMe = nullptr;

                // this window is focusing on a widget??
                if (window->IsFocusingControl)
                {
                    if (window->FocusedControl != nullptr)
                    {
                        // We've processed it once, skip it later
                        SkipWidget = true;
                        SkipMe = window->FocusedControl;

                        POINT cAbs = window->FocusedControl->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, window->FocusedControl->m_iWidth, window->FocusedControl->m_iHeight };
                        window->FocusedControl->OnUpdate();

                        if (window->FocusedControl->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            window->FocusedControl->OnClick();

                            // If it gets clicked we loose focus
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;
                            bCheckWidgetClicks = false;
                        }
                    }
                }

                // Itterate over the rest of the control
                for (auto control : window->SelectedTab->Controls)
                {
                    if (control != nullptr)
                    {
                        if (SkipWidget && SkipMe == control)
                            continue;

                        POINT cAbs = control->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                        control->OnUpdate();

                        if (control->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            control->OnClick();
                            bCheckWidgetClicks = false;

                            // Change of focus
                            if (control->Flag(UIFlags::UI_Focusable))
                            {
                                window->IsFocusingControl = true;
                                window->FocusedControl = control;
                            }
                            else
                            {
                                window->IsFocusingControl = false;
                                window->FocusedControl = nullptr;
                            }

                        }
                    }
                }

                // We must have clicked whitespace
                if (bCheckWidgetClicks)
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }
        }
    }
}

// Returns 
bool CGUI::GetKeyPress(unsigned int key)
{
    if (keys[key] == true && oldKeys[key] == false)
        return true;
    else
        return false;
}

bool CGUI::GetKeyState(unsigned int key)
{
    return keys[key];
}

bool CGUI::IsMouseInRegion(int x, int y, int x2, int y2)
{
    if (Mouse.x > x && Mouse.y > y && Mouse.x < x2 && Mouse.y < y2)
        return true;
    else
        return false;
}

bool CGUI::IsMouseInRegion(RECT region)
{
    return IsMouseInRegion(region.left, region.top, region.left + region.right, region.top + region.bottom);
}

POINT CGUI::GetMouse()
{
    return Mouse;
}

bool CGUI::DrawWindow(CWindow* window)
{
    // Main Window
    Render::Outline(window->m_x, window->m_y, window->m_iWidth, window->m_iHeight, Color(20, 20, 20, 80));
    Render::GradientV(window->m_x + 2, window->m_y + 2, window->m_iWidth - 4, 26, Color(0, 0, 0, 255), Color(0, 0, 0, 255));
    Render::Clear(window->m_x + 2, window->m_y + 2 + 26, window->m_iWidth - 4, window->m_iHeight - 4 - 26, Color(0, 0, 0, 255));
    Render::Outline(window->m_x + 1, window->m_y + 1, window->m_iWidth - 2, window->m_iHeight - 2, Color(255, 0, 0, 255));
    Render::Text(window->m_x + 8, window->m_y + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, window->Title.c_str());

    //Inner
    Render::Outline(window->m_x + 7, window->m_y + 1 + 26, window->m_iWidth - 4 - 10, window->m_iHeight - 2 - 6 - 26, Color(255, 0, 0, 255));
    Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, window->m_iHeight - 2 - 8 - 26, Color(255, 255, 255, 255));

    //Tab
    Render::GradientV(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 29, Color(52, 52, 52, 255), Color(6, 6, 6, 255));
    int TabCount = window->Tabs.size();
    if (TabCount) // If there are some tabs
    {
        int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
        for (int i = 0; i < TabCount; i++)
        {
            RECT TabArea = { window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29 };
            CTab* tab = window->Tabs[i];
            if (window->SelectedTab == tab)
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(52, 52, 52, 255), Color(106, 106, 106, 255));
            }
            else if (IsMouseInRegion(TabArea))
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(106, 106, 106, 255), Color(52, 52, 52, 255));
            }
            RECT TextSize = Render::GetTextSize(Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Text(TabArea.left + (TabSize / 2) - (TextSize.right / 2), TabArea.top + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 2, Color(66, 66, 66, 255));
        }
    }


    // Controls 
    if (window->SelectedTab != nullptr)
    {
        // Focused widget
        bool SkipWidget = false;
        CControl* SkipMe = nullptr;

        // this window is focusing on a widget??
        if (window->IsFocusingControl)
        {
            if (window->FocusedControl != nullptr)
            {
                // We need to draw it last, so skip it in the regular loop
                SkipWidget = true;
                SkipMe = window->FocusedControl;
            }
        }


        // Itterate over all the other controls
        for (auto control : window->SelectedTab->Controls)
        {
            if (SkipWidget && SkipMe == control)
                continue;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

        // Draw the skipped widget last
        if (SkipWidget)
        {
            auto control = window->FocusedControl;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

    }


    return true;
}

void CGUI::RegisterWindow(CWindow* window)
{
    Windows.push_back(window);

    // Resorting to put groupboxes at the start
    for (auto tab : window->Tabs)
    {
        for (auto control : tab->Controls)
        {
            if (control->Flag(UIFlags::UI_RenderFirst))
            {
                CControl* c = control;
                tab->Controls.erase(std::remove(tab->Controls.begin(), tab->Controls.end(), control), tab->Controls.end());
                tab->Controls.insert(tab->Controls.begin(), control);
            }
        }
    }
}

void CGUI::BindWindow(unsigned char Key, CWindow* window)
{
    if (window)
        WindowBinds[Key] = window;
    else
        WindowBinds.erase(Key);
}

void CGUI::SaveWindowState(CWindow* window, std::string Filename)
{
    // Create a whole new document and we'll just save over top of the old one
    tinyxml2::XMLDocument Doc;

    // Root Element is called "ayy"
    tinyxml2::XMLElement* Root = Doc.NewElement("ayy");
    Doc.LinkEndChild(Root);

    Utilities::Log("Saving Window %s", window->Title.c_str());

    // If the window has some tabs..
    if (Root && window->Tabs.size() > 0)
    {
        for (auto Tab : window->Tabs)
        {
            // Add a new section for this tab
            tinyxml2::XMLElement* TabElement = Doc.NewElement(Tab->Title.c_str());
            Root->LinkEndChild(TabElement);

            Utilities::Log("Saving Tab %s", Tab->Title.c_str());

            // Now we itterate the controls this tab contains
            if (TabElement && Tab->Controls.size() > 0)
            {
                for (auto Control : Tab->Controls)
                {
                    // If the control is ok to be saved
                    if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                    {
                        // Create an element for the control
                        tinyxml2::XMLElement* ControlElement = Doc.NewElement(Control->FileIdentifier.c_str());
                        TabElement->LinkEndChild(ControlElement);

                        Utilities::Log("Saving control %s", Control->FileIdentifier.c_str());

                        if (!ControlElement)
                        {
                            Utilities::Log("Errorino :(");
                            return;
                        }

                        CCheckBox* cbx = nullptr;
                        CComboBox* cbo = nullptr;
                        CKeyBind* key = nullptr;
                        CSlider* sld = nullptr;

                        // Figure out what kind of control and data this is
                        switch (Control->FileControlType)
                        {
                            case UIControlTypes::UIC_CheckBox:
                                cbx = (CCheckBox*)Control;
                                ControlElement->SetText(cbx->GetState());
                                break;
                            case UIControlTypes::UIC_ComboBox:
                                cbo = (CComboBox*)Control;
                                ControlElement->SetText(cbo->GetIndex());
                                break;
                            case UIControlTypes::UIC_KeyBind:
                                key = (CKeyBind*)Control;
                                ControlElement->SetText(key->GetKey());
                                break;
                            case UIControlTypes::UIC_Slider:
                                sld = (CSlider*)Control;
                                ControlElement->SetText(sld->GetValue());
                                break;
                        }
                    }
                }
            }
        }
    }

    //Save the file
    if (Doc.SaveFile(Filename.c_str()) != tinyxml2::XML_NO_ERROR)
    {
        MessageBox(NULL, "Failed To Save Config File!", "AyyWare", MB_OK);
    }

}

void CGUI::LoadWindowState(CWindow* window, std::string Filename)
{
    // Lets load our meme
    tinyxml2::XMLDocument Doc;
    if (Doc.LoadFile(Filename.c_str()) == tinyxml2::XML_NO_ERROR)
    {
        tinyxml2::XMLElement* Root = Doc.RootElement();

        // The root "ayy" element
        if (Root)
        {
            // If the window has some tabs..
            if (Root && window->Tabs.size() > 0)
            {
                for (auto Tab : window->Tabs)
                {
                    // We find the corresponding element for this tab
                    tinyxml2::XMLElement* TabElement = Root->FirstChildElement(Tab->Title.c_str());
                    if (TabElement)
                    {
                        // Now we itterate the controls this tab contains
                        if (TabElement && Tab->Controls.size() > 0)
                        {
                            for (auto Control : Tab->Controls)
                            {
                                // If the control is ok to be saved
                                if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                                {
                                    // Get the controls element
                                    tinyxml2::XMLElement* ControlElement = TabElement->FirstChildElement(Control->FileIdentifier.c_str());

                                    if (ControlElement)
                                    {
                                        Utilities::Log("We tryin to load fam");
                                        CCheckBox* cbx = nullptr;
                                        CComboBox* cbo = nullptr;
                                        CKeyBind* key = nullptr;
                                        CSlider* sld = nullptr;

                                        // Figure out what kind of control and data this is
                                        switch (Control->FileControlType)
                                        {
                                            case UIControlTypes::UIC_CheckBox:
                                                cbx = (CCheckBox*)Control;
                                                cbx->SetState(ControlElement->GetText()[0] == '1' ? true : false);
                                                break;
                                            case UIControlTypes::UIC_ComboBox:
                                                cbo = (CComboBox*)Control;
                                                cbo->SelectIndex(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_KeyBind:
                                                key = (CKeyBind*)Control;
                                                key->SetKey(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_Slider:
                                                sld = (CSlider*)Control;
                                                sld->SetValue(atof(ControlElement->GetText()));
                                                break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w
#include "Interfaces.h"
#include "Menu.h"

// Shad0ws Yaw fix
// (FIX ME UP LATER)
void FixY(const CRecvProxyData* pData, void* pStruct, void* pOut)
{
    static Vector vLast[65];
    static bool bShotLastTime[65];
    static bool bJitterFix[65];

    float* flPitch = (float*)((DWORD)pOut - 4);
    float flYaw = pData->m_Value.m_Float;
    bool bHasAA;
    bool bSpinbot;

    if (Menu::Window.RageBotTab.AccuracyAngleFix.GetState())
    {
        bHasAA = ((*flPitch == 90.0f) || (*flPitch == 270.0f));
        bSpinbot = false;

        if (!bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()]
            && (fabsf(flYaw - vLast[((IClientEntity*)(pStruct))->GetIndex()].y) > 15.0f) && !bHasAA)
        {
            flYaw = vLast[((IClientEntity*)(pStruct))->GetIndex()].y;
            bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = true;
        }
        else
        {
            if (bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()]
                && (fabsf(flYaw - vLast[((IClientEntity*)(pStruct))->GetIndex()].y) > 15.0f))
            {
                bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = true;
                bSpinbot = true;
            }
            else
            {
                bShotLastTime[((IClientEntity*)(pStruct))->GetIndex()] = false;
            }
        }

        vLast[((IClientEntity*)(pStruct))->GetIndex()].y = flYaw;


        bool bTmp = bJitterFix[((IClientEntity*)(pStruct))->GetIndex()];

        bJitterFix[((IClientEntity*)(pStruct))->GetIndex()] = (flYaw >= 180.0f && flYaw <= 360.0f);

        if (bTmp && (flYaw >= 0.0f && flYaw <= 180.0f))
        {
            flYaw += 359.0f;
        }

    }

    *(float*)(pOut) = flYaw;
}

// Simple fix for some Fake-Downs
void FixX(const CRecvProxyData* pData, void* pStruct, void* pOut)
{
    float* ang = (float*)pOut;
    *ang = pData->m_Value.m_Float;

    if (!Menu::Window.RageBotTab.AccuracyAngleFix.GetState()) return;

    if (pData->m_Value.m_Float > 180.0f)
        *ang -= 360.0f;
    else if (pData->m_Value.m_Float < -180.0f)
        *ang += 360.0f;
}


RecvVarProxyFn oRecvnModelIndex;

void Hooked_RecvProxy_Viewmodel(CRecvProxyData* pData, void* pStruct, void* pOut)
{
    // Get the knife view model id's
    static int default_t = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_default_t.mdl");
    static int default_ct = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_default_ct.mdl");
    int iBayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_bayonet.mdl");
    int iButterfly = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_butterfly.mdl");
    int iFlip = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_flip.mdl");
    int iGunGame = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gg.mdl");
    int iGut = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gut.mdl");
    int iKarambit = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_karam.mdl");
    int iM9Bayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_m9_bay.mdl");
    int iHuntsman = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_tactical.mdl");

    int iFalchion = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_falchion_advanced.mdl");
    int iDagger = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_push.mdl");

    // Get local player (just to stop replacing spectators knifes)
    IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (Menu::Window.MiscTab.KnifeEnable.GetState() && pLocal)
    {
        // If we are alive and holding a default knife(if we already have a knife don't worry about changing)
        if (pLocal->IsAlive() && (pData->m_Value.m_Int == default_t || pData->m_Value.m_Int == default_ct))
        {
            // Set whatever knife we want
            if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 0)
                pData->m_Value.m_Int = iKarambit;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 1)
                pData->m_Value.m_Int = iBayonet;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 2)
                pData->m_Value.m_Int = iHuntsman;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 3)
                pData->m_Value.m_Int = iGut;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 4)
                pData->m_Value.m_Int = iFalchion;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 5)
                pData->m_Value.m_Int = iDagger;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 6)
                pData->m_Value.m_Int = iButterfly;
            else if (Menu::Window.MiscTab.KnifeModel.GetIndex() == 7)
                pData->m_Value.m_Int = iFlip;
        }
    }

    // Carry on the to original proxy
    oRecvnModelIndex(pData, pStruct, pOut);
}

void ApplyAAAHooks()
{
    ClientClass* pClass = Interfaces::Client->GetAllClasses();
    while (pClass)
    {
        const char* pszName = pClass->m_pRecvTable->m_pNetTableName;
        if (!strcmp(pszName, "DT_CSPlayer"))
        {
            for (int i = 0; i < pClass->m_pRecvTable->m_nProps; i++)
            {
                RecvProp* pProp = &(pClass->m_pRecvTable->m_pProps[i]);
                const char* name = pProp->m_pVarName;

                // Pitch Fix
                if (!strcmp(name, "m_angEyeAngles[0]"))
                {
                    pProp->m_ProxyFn = FixX;
                }

                // Yaw Fix
                if (!strcmp(name, "m_angEyeAngles[1]"))
                {
                    //Utilities::Log("Yaw Fix Applied");
                    pProp->m_ProxyFn = FixY;
                }
            }
        }
        else if (!strcmp(pszName, "DT_BaseViewModel"))
        {
            for (int i = 0; i < pClass->m_pRecvTable->m_nProps; i++)
            {
                RecvProp* pProp = &(pClass->m_pRecvTable->m_pProps[i]);
                const char* name = pProp->m_pVarName;

                // Knives
                if (!strcmp(name, "m_nModelIndex"))
                {
                    oRecvnModelIndex = (RecvVarProxyFn)pProp->m_ProxyFn;
                    pProp->m_ProxyFn = Hooked_RecvProxy_Viewmodel;
                }
            }
        }
        pClass = pClass->m_pNext;
    }
}/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w
#pragma once

void ApplyAAAHooks();
#include "AutoWall.h"

#define    HITGROUP_GENERIC    0
#define    HITGROUP_HEAD        1
#define    HITGROUP_CHEST        2
#define    HITGROUP_STOMACH    3
#define HITGROUP_LEFTARM    4    
#define HITGROUP_RIGHTARM    5
#define HITGROUP_LEFTLEG    6
#define HITGROUP_RIGHTLEG    7
#define HITGROUP_GEAR        10

inline bool CGameTrace::DidHitWorld() const
{
        return m_pEnt->GetIndex() == 0;
}

inline bool CGameTrace::DidHitNonWorldEntity() const
{
        return m_pEnt != NULL && !DidHitWorld();
}

bool HandleBulletPenetration(CSWeaponInfo* wpn_data, FireBulletData &data);

float GetHitgroupDamageMult(int iHitGroup)
{
    switch (iHitGroup)
    {
        case HITGROUP_GENERIC:
            return 1.0f;

        case HITGROUP_HEAD:
            return 2.0f;

        case HITGROUP_CHEST:
            return 1.0f;

        case HITGROUP_STOMACH:
            return 1.0f;

        case HITGROUP_LEFTARM:
        case HITGROUP_RIGHTARM:
            return 1.0f;

        case HITGROUP_LEFTLEG:
        case HITGROUP_RIGHTLEG:
            return 1.0f;

        default:
            return 1.0f;
    }
}

void ScaleDamage(int hitgroup, IClientEntity* enemy, float weapon_armor_ratio, float ¤t_damage)
{
    current_damage *= GetHitgroupDamageMult(hitgroup);

    if (enemy->ArmorValue() > 0)
    {
        if (hitgroup == HITGROUP_HEAD)
        {
            if (enemy->HasHelmet())
                current_damage *= (weapon_armor_ratio * .5f);
        }
        else
        {
            current_damage *= (weapon_armor_ratio * .5f);
        }
    }
}

bool SimulateFireBullet(IClientEntity* local, CBaseCombatWeapon* weapon, FireBulletData &data)
{
    //Utils::ToLog("SimulateFireBullet");
    data.penetrate_count = 4;
    data.trace_length = 0.0f;
    auto* wpn_data = weapon->GetCSWpnData();

    data.current_damage = (float)wpn_data->m_iDamage;

    while ((data.penetrate_count > 0) && (data.current_damage >= 1.0f))
    {
        data.trace_length_remaining = wpn_data->m_flRange - data.trace_length;

        Vector end = data.src + data.direction * data.trace_length_remaining;

        UTIL_TraceLine(data.src, end, 0x4600400B, local, 0, &data.enter_trace);
        UTIL_ClipTraceToPlayers(data.src, end + data.direction * 40.f, 0x4600400B, &data.filter, &data.enter_trace);

        if (data.enter_trace.fraction == 1.0f)
            break;

        if ((data.enter_trace.hitgroup <= 7)
            && (data.enter_trace.hitgroup > 0)
            && (local->GetTeamNum() != data.enter_trace.m_pEnt->GetTeamNum())
            /*&& (DoesRayTouchHitbox(end, &data))*/)
        {
            data.trace_length += data.enter_trace.fraction * data.trace_length_remaining;
            data.current_damage *= pow(wpn_data->m_flRangeModifier, data.trace_length * 0.002);
            ScaleDamage(data.enter_trace.hitgroup, data.enter_trace.m_pEnt, wpn_data->m_flArmorRatio, data.current_damage);

            return true;
        }

        if (!HandleBulletPenetration(wpn_data, data))
            break;
    }

    return false;
}

bool HandleBulletPenetration(CSWeaponInfo* wpn_data, FireBulletData &data)
{
    surfacedata_t* enter_surface_data = Interfaces::PhysProps->GetSurfaceData(data.enter_trace.surface.surfaceProps);
    int enter_material = enter_surface_data->game.material;
    float enter_surf_penetration_mod = enter_surface_data->game.flPenetrationModifier;


    data.trace_length += data.enter_trace.fraction * data.trace_length_remaining;
    data.current_damage *= pow(wpn_data->m_flRangeModifier, (data.trace_length * 0.002));

    if ((data.trace_length > 3000.f) || (enter_surf_penetration_mod < 0.1f))
        data.penetrate_count = 0;

    if (data.penetrate_count <= 0)
        return false;

    Vector dummy;
    trace_t trace_exit;
    if (!TraceToExit(dummy, data.enter_trace, data.enter_trace.endpos, data.direction, &trace_exit))
        return false;

    surfacedata_t* exit_surface_data = Interfaces::PhysProps->GetSurfaceData(trace_exit.surface.surfaceProps);
    int exit_material = exit_surface_data->game.material;

    float exit_surf_penetration_mod = exit_surface_data->game.flPenetrationModifier;
    float final_damage_modifier = 0.16f;
    float combined_penetration_modifier = 0.0f;

    if (((data.enter_trace.contents & CONTENTS_GRATE) != 0) || (enter_material == 89) || (enter_material == 71))
    {
        combined_penetration_modifier = 3.0f;
        final_damage_modifier = 0.05f;
    }
    else
    {
        combined_penetration_modifier = (enter_surf_penetration_mod + exit_surf_penetration_mod) * 0.5f;
    }

    if (enter_material == exit_material)
    {
        if (exit_material == 87 || exit_material == 85)
            combined_penetration_modifier = 3.0f;
        else if (exit_material == 76)
            combined_penetration_modifier = 2.0f;
    }

    float v34 = fmaxf(0.f, 1.0f / combined_penetration_modifier);
    float v35 = (data.current_damage * final_damage_modifier) + v34 * 3.0f * fmaxf(0.0f, (3.0f / wpn_data->m_flPenetration) * 1.25f);
    float thickness = VectorLength(trace_exit.endpos - data.enter_trace.endpos);

    thickness *= thickness;
    thickness *= v34;
    thickness /= 24.0f;


    float lost_damage = fmaxf(0.0f, v35 + thickness);

    if (lost_damage > data.current_damage)
        return false;

    if (lost_damage >= 0.0f)
        data.current_damage -= lost_damage;

    if (data.current_damage < 1.0f)
        return false;

    data.src = trace_exit.endpos;
    data.penetrate_count--;

    return true;
}


/*
*    CanHit() - example of how to use the code
*     @in  point: target hitbox vector
*     @out damage_given: amount of damage the shot would do
*/
bool CanHit(const Vector &point, float* damage_given)
{
    auto* local = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    auto data = FireBulletData(local->GetOrigin() + local->GetViewOffset());
    data.filter = CTraceFilter();
    data.filter.pSkip = local;

    Vector angles;
    CalcAngle(data.src, point, angles);
    AngleVectors(angles, &data.direction);
    VectorNormalize(data.direction);

    if (SimulateFireBullet(local, (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle((HANDLE)local->GetActiveWeaponHandle()), data))
    {
        *damage_given = data.current_damage;
        return true;
    }

    return false;
}
#pragma once

# include "Hacks.h"

struct FireBulletData
{
    FireBulletData(const Vector &eye_pos):src(eye_pos)
    {
    }

    Vector src;
    trace_t enter_trace;
    Vector direction;
    CTraceFilter filter;
    float trace_length;
    float trace_length_remaining;
    float current_damage;
    int penetrate_count;
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"

class IBaseClientDLL
{
    public:

        ClientClass* GetAllClasses(void)
    {
        typedef ClientClass*(__thiscall * OriginalFn)(PVOID); //Anything inside a VTable is a __thiscall unless it completly disregards the thisptr. You can also call them as __stdcalls, but you won't have access to the __thisptr.
        return call_vfunc(this, Offsets::VMT::CHL_GetAllClasses)(this); //Return the pointer to the head CClientClass.
    }
};//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $Workfile:     $
// $Date:         $
// $NoKeywords: $
//=============================================================================//

#ifndef BSPFLAGS_H
#define BSPFLAGS_H

#ifdef _WIN32
#pragma once
#endif

// contents flags are seperate bits
// a given brush can contribute multiple content bits
// multiple brushes can be in a single leaf

// these definitions also need to be in q_shared.h!

// lower bits are stronger, and will eat weaker brushes completely
#define        CONTENTS_EMPTY                        0                // No contents

#define        CONTENTS_SOLID                        0x1                // an eye is never valid in a solid
#define        CONTENTS_WINDOW                        0x2                // translucent, but not watery (glass)
#define        CONTENTS_AUX                        0x4
#define        CONTENTS_GRATE                        0x8                // alpha-tested "grate" textures.  Bullets/sight pass through, but solids don't
#define        CONTENTS_SLIME                        0x10
#define        CONTENTS_WATER                        0x20
#define        CONTENTS_BLOCKLOS                0x40        // block AI line of sight
#define CONTENTS_OPAQUE                        0x80        // things that cannot be seen through (may be non-solid though)
#define        LAST_VISIBLE_CONTENTS        0x80

#define ALL_VISIBLE_CONTENTS (LAST_VISIBLE_CONTENTS | (LAST_VISIBLE_CONTENTS-1))

#define CONTENTS_TESTFOGVOLUME        0x100
#define CONTENTS_UNUSED                        0x200        

// unused 
// NOTE: If it's visible, grab from the top + update LAST_VISIBLE_CONTENTS
// if not visible, then grab from the bottom.
#define CONTENTS_UNUSED6                0x400

#define CONTENTS_TEAM1                        0x800        // per team contents used to differentiate collisions 
#define CONTENTS_TEAM2                        0x1000        // between players and objects on different teams

// ignore CONTENTS_OPAQUE on surfaces that have SURF_NODRAW
#define CONTENTS_IGNORE_NODRAW_OPAQUE        0x2000

// hits entities which are MOVETYPE_PUSH (doors, plats, etc.)
#define CONTENTS_MOVEABLE                0x4000

// remaining contents are non-visible, and don't eat brushes
#define        CONTENTS_AREAPORTAL                0x8000

#define        CONTENTS_PLAYERCLIP                0x10000
#define        CONTENTS_MONSTERCLIP        0x20000

// currents can be added to any other contents, and may be mixed
#define        CONTENTS_CURRENT_0                0x40000
#define        CONTENTS_CURRENT_90                0x80000
#define        CONTENTS_CURRENT_180        0x100000
#define        CONTENTS_CURRENT_270        0x200000
#define        CONTENTS_CURRENT_UP                0x400000
#define        CONTENTS_CURRENT_DOWN        0x800000

#define        CONTENTS_ORIGIN                        0x1000000        // removed before bsping an entity

#define        CONTENTS_MONSTER                0x2000000        // should never be on a brush, only in game
#define        CONTENTS_DEBRIS                        0x4000000
#define        CONTENTS_DETAIL                        0x8000000        // brushes to be added after vis leafs
#define        CONTENTS_TRANSLUCENT        0x10000000        // auto set if any surface has trans
#define        CONTENTS_LADDER                        0x20000000
#define CONTENTS_HITBOX                        0x40000000        // use accurate hitboxes on trace


// NOTE: These are stored in a short in the engine now.  Don't use more than 16 bits
#define        SURF_LIGHT                0x0001                // value will hold the light strength
#define        SURF_SKY2D                0x0002                // don't draw, indicates we should skylight + draw 2d sky but not draw the 3D skybox
#define        SURF_SKY                0x0004                // don't draw, but add to skybox
#define        SURF_WARP                0x0008                // turbulent water warp
#define        SURF_TRANS                0x0010
#define SURF_NOPORTAL        0x0020        // the surface can not have a portal placed on it
#define        SURF_TRIGGER        0x0040        // FIXME: This is an xbox hack to work around elimination of trigger surfaces, which breaks occluders
#define        SURF_NODRAW                0x0080        // don't bother referencing the texture

#define        SURF_HINT                0x0100        // make a primary bsp splitter

#define        SURF_SKIP                0x0200        // completely ignore, allowing non-closed brushes
#define SURF_NOLIGHT        0x0400        // Don't calculate light
#define SURF_BUMPLIGHT        0x0800        // calculate three lightmaps for the surface for bumpmapping
#define SURF_NOSHADOWS        0x1000        // Don't receive shadows
#define SURF_NODECALS        0x2000        // Don't receive decals
#define SURF_NOCHOP                0x4000        // Don't subdivide patches on this surface 
#define SURF_HITBOX                0x8000        // surface is part of a hitbox



// -----------------------------------------------------
// spatial content masks - used for spatial queries (traceline,etc.)
// -----------------------------------------------------
#define        MASK_ALL                                        (0xFFFFFFFF)
// everything that is normally solid
#define        MASK_SOLID                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// everything that blocks player movement
#define        MASK_PLAYERSOLID                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// blocks npc movement
#define        MASK_NPCSOLID                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTERCLIP|CONTENTS_WINDOW|CONTENTS_MONSTER|CONTENTS_GRATE)
// water physics in these contents
#define        MASK_WATER                                        (CONTENTS_WATER|CONTENTS_MOVEABLE|CONTENTS_SLIME)
// everything that blocks lighting
#define        MASK_OPAQUE                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_OPAQUE)
// everything that blocks lighting, but with monsters added.
#define MASK_OPAQUE_AND_NPCS                (MASK_OPAQUE|CONTENTS_MONSTER)
// everything that blocks line of sight for AI
#define MASK_BLOCKLOS                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_BLOCKLOS)
// everything that blocks line of sight for AI plus NPCs
#define MASK_BLOCKLOS_AND_NPCS                (MASK_BLOCKLOS|CONTENTS_MONSTER)
// everything that blocks line of sight for players
#define        MASK_VISIBLE                                        (MASK_OPAQUE|CONTENTS_IGNORE_NODRAW_OPAQUE)
// everything that blocks line of sight for players, but with monsters added.
#define MASK_VISIBLE_AND_NPCS                (MASK_OPAQUE_AND_NPCS|CONTENTS_IGNORE_NODRAW_OPAQUE)
// bullets see these as solid
#define        MASK_SHOT                                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_HITBOX)
// non-raycasted weapons see this as solid (includes grates)
#define MASK_SHOT_HULL                                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_MONSTER|CONTENTS_WINDOW|CONTENTS_DEBRIS|CONTENTS_GRATE)
// hits solids (not grates) and passes through everything else
#define MASK_SHOT_PORTAL                        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTER)
// everything normally solid, except monsters (world+brush only)
#define MASK_SOLID_BRUSHONLY                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_GRATE)
// everything normally solid for player movement, except monsters (world+brush only)
#define MASK_PLAYERSOLID_BRUSHONLY        (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_PLAYERCLIP|CONTENTS_GRATE)
// everything normally solid for npc movement, except monsters (world+brush only)
#define MASK_NPCSOLID_BRUSHONLY                (CONTENTS_SOLID|CONTENTS_MOVEABLE|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// just the world, used for route rebuilding
#define MASK_NPCWORLDSTATIC                        (CONTENTS_SOLID|CONTENTS_WINDOW|CONTENTS_MONSTERCLIP|CONTENTS_GRATE)
// These are things that can split areaportals
#define MASK_SPLITAREAPORTAL                (CONTENTS_WATER|CONTENTS_SLIME)

// UNDONE: This is untested, any moving water
#define MASK_CURRENT                                (CONTENTS_CURRENT_0|CONTENTS_CURRENT_90|CONTENTS_CURRENT_180|CONTENTS_CURRENT_270|CONTENTS_CURRENT_UP|CONTENTS_CURRENT_DOWN)

// everything that blocks corpse movement
// UNDONE: Not used yet / may be deleted
#define        MASK_DEADSOLID                                (CONTENTS_SOLID|CONTENTS_PLAYERCLIP|CONTENTS_WINDOW|CONTENTS_GRATE)

#endif // BSPFLAGS_H

bool CanHit(const Vector &point, float* damage_given);

#include "Chams.h"
#include "offsets.h"
#include "SDK.h"
#include "Interfaces.h"

void InitKeyValues(KeyValues* keyValues, char* name)
{
    DWORD dwFunction = (DWORD)Offsets::Functions::KeyValues_KeyValues;
    __asm

    {
        push name

            mov ecx, keyValues

            call dwFunction

    }
}

void LoadFromBuffer(KeyValues* keyValues, char const *resourceName, const char* pBuffer)
{
    DWORD dwFunction = (DWORD)Offsets::Functions::KeyValues_LoadFromBuffer;

    __asm

    {
        push 0

            push 0

            push 0

            push pBuffer

            push resourceName

            mov ecx, keyValues

            call dwFunction

    }
}

IMaterial* CreateMaterial(bool shouldIgnoreZ, bool isLit, bool isWireframe) //credits to ph0ne
{
    static int created = 0;

    static const char tmp[] =
    {
        "\"%s\"\
                \n{\
                \n\t\"$basetexture\" \"vgui/white_additive\"\
                \n\t\"$envmap\" \"\"\
                \n\t\"$model\" \"1\"\
                \n\t\"$flat\" \"1\"\
                \n\t\"$nocull\" \"0\"\
                \n\t\"$selfillum\" \"1\"\
                \n\t\"$halflambert\" \"1\"\
                \n\t\"$nofog\" \"0\"\
                \n\t\"$ignorez\" \"%i\"\
                \n\t\"$znearer\" \"0\"\
                \n\t\"$wireframe\" \"%i\"\
        \n}\n"
    };

    char* baseType = (isLit == true ? "VertexLitGeneric" : "UnlitGeneric");
    char material[512];
    sprintf_s(material, sizeof(material), tmp, baseType, (shouldIgnoreZ) ? 1 : 0, (isWireframe) ? 1 : 0);

    char name[512];
    sprintf_s(name, sizeof(name), "#ayy_meme_%i.vmt", created);
    ++created;

    KeyValues* keyValues = (KeyValues*)malloc(sizeof(KeyValues));
    InitKeyValues(keyValues, baseType);
    LoadFromBuffer(keyValues, name, material);

    IMaterial* createdMaterial = Interfaces::MaterialSystem->CreateMaterial(name, keyValues);
    createdMaterial->IncrementReferenceCount();

    return createdMaterial;
}

void ForceMaterial(Color color, IMaterial* material, bool useColor, bool forceMaterial)
{
    if (useColor)
    {
        float temp[3] =
        {
            color.r(),
            color.g(),
            color.b()
        };

        temp[0] /= 255.f;
        temp[1] /= 255.f;
        temp[2] /= 255.f;


        float alpha = color.a();

        Interfaces::RenderView->SetBlend(1.0f);
        Interfaces::RenderView->SetColorModulation(temp);
    }

    if (forceMaterial)
        Interfaces::ModelRender->ForcedMaterialOverride(material);
    else
        Interfaces::ModelRender->ForcedMaterialOverride(NULL);

}/*
Syn's AYYWAREFramework 2015
*/

#pragma once
#include "SDK.h"

void InitKeyValues(KeyValues* keyValues, char* name);

void LoadFromBuffer(KeyValues* keyValues, char const *resourceName, const char* pBuffer);

void ForceMaterial(Color color, IMaterial* material, bool useColor = true, bool forceMaterial = true);

IMaterial* CreateMaterial(bool shouldIgnoreZ, bool isLit = true, bool isWireframe = false);
/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w

#pragma once

struct RecvProp;

class DVariant
{
    public:
        union
        {
                float m_Float;
    long m_Int;
    char* m_pString;
    void* m_pData;
    float m_Vector[3];
};
};

class CRecvProxyData
{
    public:
        const RecvProp* m_pRecvProp;
    char _pad[4];//csgo ( for l4d keep it commented out :) )
    DVariant m_Value;
    int m_iElement;
    int m_ObjectID;
};

typedef void(* RecvVarProxyFn)(const CRecvProxyData* pData, void* pStruct, void* pOut);

struct RecvTable
{
    RecvProp* m_pProps;
    int m_nProps;
    void* m_pDecoder;
    char* m_pNetTableName;
    bool m_bInitialized;
    bool m_bInMainList;
};

struct RecvProp
{
    char* m_pVarName;
    int m_RecvType;
    int m_Flags;
    int m_StringBufferSize;
    bool m_bInsideArray;
    const void* m_pExtraData;
    RecvProp* m_pArrayProp;
    void* m_ArrayLengthProxy;
    void* m_ProxyFn;
    void* m_DataTableProxyFn;
    RecvTable* m_pDataTable;
    int m_Offset;
    int m_ElementStride;
    int m_nElements;
    const char* m_pParentArrayPropName;
};

class ClientClass
{
    public:
        void* m_pCreateFn;
    void* m_pCreateEventFn;
    char* m_pNetworkName;
    RecvTable* m_pRecvTable;
    ClientClass* m_pNext;
    int m_ClassID;
};
#pragma once
#define _WINSOCKAPI_

// Includes
# include 
# include 
# include 
# include 
# include 
# include 
# include 
#pragma once
#define _WINSOCKAPI_

// Includes
# include 
# include 
# include 
# include 
# include 
# include 
# include 
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

# include "GUI.h"

class CCheckBox : public CControl
{
public:

    CCheckBox();
void SetState(bool s);
bool GetState();
protected:
        bool Checked;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CLabel : public CControl
{
public:

    CLabel();
void SetText(std::string text);
protected:
        std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CGroupBox : public CControl
{
public:

    CGroupBox();
void SetText(std::string text);
void PlaceLabledControl(std::string Label, CTab* Tab, CControl* control);
protected:
        int Items;
std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CSlider : public CControl
{
public:

    CSlider();
float GetValue();
void SetValue(float v);
void SetBoundaries(float min, float max);
protected:
        float Value;
float Min;
float Max;
bool DoDrag;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CKeyBind : public CControl
{
public:

    CKeyBind();
int GetKey();
void SetKey(int key);
protected:
        int Key;
bool IsGettingKey;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CButton : public CControl
{
public:
        typedef void(* ButtonCallback_t)(void);

    CButton();
void SetCallback(ButtonCallback_t callback);
void SetText(std::string text);
protected:
        ButtonCallback_t CallBack;
std::string Text;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};

class CComboBox : public CControl
{
public:

    CComboBox();
void AddItem(std::string text);
void SelectIndex(int idx);
int GetIndex();
std::string GetItem();
protected:
        std::vector Items;
int SelectedIndex;
bool IsOpen;
void Draw(bool hover);
void OnUpdate();
void OnClick();
};/*
Syn's AYYWAREFramework 2015
*/

#include "CRC32.h"

unsigned int uiCRC32_Table[256] = {
    0x00000000L, 0x77073096L, 0xEE0E612CL,
    0x990951BAL, 0x076DC419L, 0x706AF48FL,
    0xE963A535L, 0x9E6495A3L, 0x0EDB8832L,
    0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
    0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L,
    0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L,
    0xF3B97148L, 0x84BE41DEL, 0x1ADAD47DL,
    0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,
    0x136C9856L, 0x646BA8C0L, 0xFD62F97AL,
    0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L,
    0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L,
    0x4C69105EL, 0xD56041E4L, 0xA2677172L,
    0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL,
    0xA50AB56BL, 0x35B5A8FAL, 0x42B2986CL,
    0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L,
    0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L,
    0x26D930ACL, 0x51DE003AL, 0xC8D75180L,
    0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L,
    0xCFBA9599L, 0xB8BDA50FL, 0x2802B89EL,
    0x5F058808L, 0xC60CD9B2L, 0xB10BE924L,
    0x2F6F7C87L, 0x58684C11L, 0xC1611DABL,
    0xB6662D3DL, 0x76DC4190L, 0x01DB7106L,
    0x98D220BCL, 0xEFD5102AL, 0x71B18589L,
    0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L,
    0x7807C9A2L, 0x0F00F934L, 0x9609A88EL,
    0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL,
    0x91646C97L, 0xE6635C01L, 0x6B6B51F4L,
    0x1C6C6162L, 0x856530D8L, 0xF262004EL,
    0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L,
    0xF50FC457L, 0x65B0D9C6L, 0x12B7E950L,
    0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL,
    0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L,
    0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L,
    0xD4BB30E2L, 0x4ADFA541L, 0x3DD895D7L,
    0xA4D1C46DL, 0xD3D6F4FBL, 0x4369E96AL,
    0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L,
    0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL,
    0xDD0D7CC9L, 0x5005713CL, 0x270241AAL,
    0xBE0B1010L, 0xC90C2086L, 0x5768B525L,
    0x206F85B3L, 0xB966D409L, 0xCE61E49FL,
    0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L,
    0xC7D7A8B4L, 0x59B33D17L, 0x2EB40D81L,
    0xB7BD5C3BL, 0xC0BA6CADL, 0xEDB88320L,
    0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL,
    0xEAD54739L, 0x9DD277AFL, 0x04DB2615L,
    0x73DC1683L, 0xE3630B12L, 0x94643B84L,
    0x0D6D6A3EL, 0x7A6A5AA8L, 0xE40ECF0BL,
    0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L,
    0xF00F9344L, 0x8708A3D2L, 0x1E01F268L,
    0x6906C2FEL, 0xF762575DL, 0x806567CBL,
    0x196C3671L, 0x6E6B06E7L, 0xFED41B76L,
    0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL,
    0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L,
    0x60B08ED5L, 0xD6D6A3E8L, 0xA1D1937EL,
    0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L,
    0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL,
    0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L,
    0x41047A60L, 0xDF60EFC3L, 0xA867DF55L,
    0x316E8EEFL, 0x4669BE79L, 0xCB61B38CL,
    0xBC66831AL, 0x256FD2A0L, 0x5268E236L,
    0xCC0C7795L, 0xBB0B4703L, 0x220216B9L,
    0x5505262FL, 0xC5BA3BBEL, 0xB2BD0B28L,
    0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L,
    0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL,
    0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL,
    0x026D930AL, 0x9C0906A9L, 0xEB0E363FL,
    0x72076785L, 0x05005713L, 0x95BF4A82L,
    0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L,
    0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L,
    0x0BDBDF21L, 0x86D3D2D4L, 0xF1D4E242L,
    0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL,
    0xF6B9265BL, 0x6FB077E1L, 0x18B74777L,
    0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL,
    0x11010B5CL, 0x8F659EFFL, 0xF862AE69L,
    0x616BFFD3L, 0x166CCF45L, 0xA00AE278L,
    0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L,
    0xA7672661L, 0xD06016F7L, 0x4969474DL,
    0x3E6E77DBL, 0xAED16A4AL, 0xD9D65ADCL,
    0x40DF0B66L, 0x37D83BF0L, 0xA9BCAE53L,
    0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L,
    0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L,
    0x24B4A3A6L, 0xBAD03605L, 0xCDD70693L,
    0x54DE5729L, 0x23D967BFL, 0xB3667A2EL,
    0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L,
    0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL,
    0x2D02EF8DL };

unsigned int CRC32(void* pData, size_t iLen)
{
    unsigned int uiCRC32 = 0xFFFFFFFF;
    unsigned char* pszData = (unsigned char*)pData;

    for (size_t i = 0; i < iLen; ++i)
        uiCRC32 = ((uiCRC32 >> 8) & 0x00FFFFFF) ^ uiCRC32_Table[(uiCRC32 ^ (unsigned int)*pszData++) &0xFF];

    return (uiCRC32 ^ 0xFFFFFFFF);
}/*
Syn's AYYWAREFramework 2015
*/

// Credits Valve / Shad0w

#pragma once

unsigned int CRC32(void* pData, size_t iLen);
/*
Syn's AYYWAREFramework 2015
*/

#include "Utilities.h"

// Stuff to initialise
#include "Offsets.h"
#include "Interfaces.h"
#include "Hooks.h"
#include "RenderManager.h"
#include "Hacks.h"
#include "Menu.h"
#include "AntiAntiAim.h"

#include "Dumping.h"

bool DoUnload;

HINSTANCE HThisModule;

// Our thread we use to setup everything we need
// Everything appart from code in hooks get's called from inside 
// here.

int InitialThread(LPVOID lpArguments)
{
    Utilities::OpenConsole("Cebula.dll");

    //---------------------------------------------------------
    // Initialise all our shit

    Offsets::Initialise(); // Set our VMT offsets and do any pattern scans
    Interfaces::Initialise(); // Get pointers to the valve classes
    NetVar.RetrieveClasses(); // Setup our NetVar manager (thanks shad0w bby)
    Render::Initialise();
    Hacks::SetupHacks();
    Menu::SetupMenu();
    Hooks::Initialise();
    ApplyAAAHooks();
    // Dumping
    //Dump::DumpClassIds();

    //---------------------------------------------------------
    Utilities::Log("Ready");

    // While our cheat is running
    while (DoUnload == false)
    {
        Sleep(1000);
    }

    Hooks::UndoHooks();
    Sleep(2000); // Make sure none of our hooks are running
    FreeLibraryAndExitThread(HThisModule, 0);

    return 0;
}

// DllMain
// Entry point for our module
bool _stdcall DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpReserved)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)InitialThread, NULL, NULL, NULL);
    }
    return true;
}
#include "Dumping.h"

#define DUMPIDTOFILE

void Dump::DumpClassIds()
{
# ifdef DUMPIDTOFILE
    Utilities::EnableLogFile("ClassID.txt");
#endif
    ClientClass* cClass = Interfaces::Client->GetAllClasses();
    while (cClass)
    {
        Utilities::Log("%s = %d,", cClass->m_pNetworkName, cClass->m_ClassID);
        cClass = cClass->m_pNext;
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Interfaces.h"
#include "Utilities.h"

namespace Dump
{
    void DumpClassIds();
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"

// EngineClient
class IVEngineClient
{
    public:
        void GetScreenSize(int& width, int& height)
    {
        typedef void(__thiscall * oGetScreenSize)(PVOID, int &, int &);
        return call_vfunc(this, Offsets::VMT::Engine_GetScreenSize)(this, width, height);
    }
    bool GetPlayerInfo(int ent_num, player_info_t* pinfo)
    {
        typedef bool(__thiscall * oGetPlayerInfo)(PVOID, int, player_info_t *);
        return call_vfunc(this, Offsets::VMT::Engine_GetPlayerInfo)(this, ent_num, pinfo);
    }
    int GetLocalPlayer()
    {
        typedef int(__thiscall * oLocal)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_GetLocalPlayer)(this);
    }
    float Time()
    {
        typedef float(__thiscall * oTime)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_Time)(this);
    }
    void GetViewAngles(Vector& vAngles)
    {
        typedef void(__thiscall * oSetViewAngles)(PVOID, Vector &);
        return call_vfunc(this, Offsets::VMT::Engine_GetViewAngles)(this, vAngles);
    }
    void SetViewAngles(Vector& vAngles)
    {
        typedef void(__thiscall * oSetViewAngles)(PVOID, Vector &);
        return call_vfunc(this, Offsets::VMT::Engine_SetViewAngles)(this, vAngles);
    }
    int GetMaxClients()
    {
        typedef bool(__thiscall * oGetMaxClients)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_GetMaxClients)(this);
    }
    bool IsConnected()
    {
        typedef bool(__thiscall * oGetScreenSize)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_IsConnected)(this);
    }
    bool IsInGame()
    {
        typedef bool(__thiscall * oLocal)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_IsInGame)(this);
    }
    const matrix3x4& WorldToScreenMatrix()
    {
        typedef const matrix3x4&(__thiscall * oWorldToScreenMatrix)(PVOID);
        return call_vfunc(this, Offsets::VMT::Engine_WorldToScreenMatrix)(this);
    }
    void ClientCmd_Unrestricted(char  const* cmd)
        {

        typedef void(__thiscall* oClientCmdUnres)(PVOID, const char*);
                return call_vfunc(this, Offsets::VMT::Engine_ClientCmd_Unrestricted)(this, cmd);
        }
};/*
Syn's AyyWare Framework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"

#define TEAM_CS_T 2
#define TEAM_CS_CT 3

#define BONE_USED_BY_HITBOX                        0x00000100

class IClientRenderable;
class IClientNetworkable;
class IClientUnknown;
class IClientThinkable;
class IClientEntity;
class CSWeaponInfo;

class CSWeaponInfo
{
    public:
        virtual void Function0(); //
    virtual void Function1(); //
    virtual void Parse(KeyValues* pKeyValuesData, const char* szWeaponName); //
    virtual void RefreshDynamicParameters(void); //
    virtual void Function4(); //
    virtual void Function5(); //
    virtual void Function6(); //
    virtual void Function7(); //
    virtual void Function8(); //

    char pad_0x0004[0x2]; //0x0004
    char m_pszName[32]; //0x0006 
    char pad_0x0026[0x7E]; //0x0026
    __int16 N0000002E; //0x00A4 
    char m_pszModelName[32]; //0x00A6 
    char pad_0x00C6[0x6DE]; //0x00C6
    BYTE m_IsFullAuto; //0x07A4 
    char pad_0x07A5[0x7]; //0x07A5
    __int32 m_iPrice; //0x07AC 
    float m_flArmorRatio; //0x07B0 
    char pad_0x07B4[0x10]; //0x07B4
    float m_flPenetration; //0x07C4 
    __int32 m_iDamage; //0x07C8 
    float m_flRange; //0x07CC 
    float m_flRangeModifier; //0x07D0 
    char pad_0x07D4[0x4]; //0x07D4
    float m_flCycleTime; //0x07D8 

};

enum class CSGOClassID
{
    CTestTraceline = 189,
        CTEWorldDecal = 190,
        CTESpriteSpray = 187,
        CTESprite = 186,
        CTESparks = 185,
        CTESmoke = 184,
        CTEShowLine = 182,
        CTEProjectedDecal = 179,
        CTEPlayerDecal = 178,
        CTEPhysicsProp = 175,
        CTEParticleSystem = 174,
        CTEMuzzleFlash = 173,
        CTELargeFunnel = 171,
        CTEKillPlayerAttachments = 170,
        CTEImpact = 169,
        CTEGlowSprite = 168,
        CTEShatterSurface = 181,
        CTEFootprintDecal = 165,
        CTEFizz = 164,
        CTEExplosion = 162,
        CTEEnergySplash = 161,
        CTEEffectDispatch = 160,
        CTEDynamicLight = 159,
        CTEDecal = 157,
        CTEClientProjectile = 156,
        CTEBubbleTrail = 155,
        CTEBubbles = 154,
        CTEBSPDecal = 153,
        CTEBreakModel = 152,
        CTEBloodStream = 151,
        CTEBloodSprite = 150,
        CTEBeamSpline = 149,
        CTEBeamRingPoint = 148,
        CTEBeamRing = 147,
        CTEBeamPoints = 146,
        CTEBeamLaser = 145,
        CTEBeamFollow = 144,
        CTEBeamEnts = 143,
        CTEBeamEntPoint = 142,
        CTEBaseBeam = 141,
        CTEArmorRicochet = 140,
        CTEMetalSparks = 172,
        CSteamJet = 135,
        CSmokeStack = 128,
        DustTrail = 238,
        CFireTrail = 62,
        SporeTrail = 244,
        SporeExplosion = 243,
        RocketTrail = 241,
        SmokeTrail = 242,
        CPropVehicleDriveable = 117,
        ParticleSmokeGrenade = 240,
        CParticleFire = 96,
        MovieExplosion = 239,
        CTEGaussExplosion = 167,
        CEnvQuadraticBeam = 55,
        CEmbers = 45,
        CEnvWind = 59,
        CPrecipitation = 111,
        CPrecipitationBlocker = 112,
        CBaseTempEntity = 18,
        NextBotCombatCharacter = 0,
        CBaseAttributableItem = 4,
        CEconEntity = 44,
        CWeaponXM1014 = 236,
        CWeaponTaser = 231,
        CSmokeGrenade = 126,
        CWeaponSG552 = 228,
        CWeaponSawedoff = 224,
        CWeaponNOVA = 220,
        CIncendiaryGrenade = 85,
        CMolotovGrenade = 93,
        CWeaponM3 = 212,
        CKnifeGG = 90,
        CKnife = 89,
        CHEGrenade = 82,
        CFlashbang = 64,
        CWeaponElite = 203,
        CDecoyGrenade = 40,
        CDEagle = 39,
        CWeaponUSP = 235,
        CWeaponM249 = 211,
        CWeaponUMP45 = 234,
        CWeaponTMP = 233,
        CWeaponTec9 = 232,
        CWeaponSSG08 = 230,
        CWeaponSG556 = 229,
        CWeaponSG550 = 227,
        CWeaponScout = 226,
        CWeaponSCAR20 = 225,
        CSCAR17 = 122,
        CWeaponP90 = 223,
        CWeaponP250 = 222,
        CWeaponP228 = 221,
        CWeaponNegev = 219,
        CWeaponMP9 = 218,
        CWeaponMP7 = 217,
        CWeaponMP5Navy = 216,
        CWeaponMag7 = 215,
        CWeaponMAC10 = 214,
        CWeaponM4A1 = 213,
        CWeaponHKP2000 = 210,
        CWeaponGlock = 209,
        CWeaponGalilAR = 208,
        CWeaponGalil = 207,
        CWeaponG3SG1 = 206,
        CWeaponFiveSeven = 205,
        CWeaponFamas = 204,
        CWeaponBizon = 199,
        CWeaponAWP = 198,
        CWeaponAug = 197,
        CAK47 = 1,
        CWeaponCSBaseGun = 201,
        CWeaponCSBase = 200,
        CC4 = 29,
        CBaseCSGrenade = 8,
        CSmokeGrenadeProjectile = 127,
        CMolotovProjectile = 94,
        CDecoyProjectile = 41,
        CFireCrackerBlast = 60,
        CInferno = 86,
        CChicken = 31,
        CFootstepControl = 66,
        CCSGameRulesProxy = 34,
        CWeaponCubemap = 0,
        CWeaponCycler = 202,
        CTEPlantBomb = 176,
        CTEFireBullets = 163,
        CTERadioIcon = 180,
        CPlantedC4 = 104,
        CCSTeam = 38,
        CCSPlayerResource = 36,
        CCSPlayer = 35,
        CCSRagdoll = 37,
        CTEPlayerAnimEvent = 177,
        CHostage = 83,
        CHostageCarriableProp = 84,
        CBaseCSGrenadeProjectile = 9,
        CHandleTest = 81,
        CTeamplayRoundBasedRulesProxy = 139,
        CSpriteTrail = 133,
        CSpriteOriented = 132,
        CSprite = 131,
        CRagdollPropAttached = 120,
        CRagdollProp = 119,
        CPredictedViewModel = 113,
        CPoseController = 109,
        CGameRulesProxy = 80,
        CInfoLadderDismount = 87,
        CFuncLadder = 72,
        CTEFoundryHelpers = 166,
        CEnvDetailController = 51,
        CWorld = 237,
        CWaterLODControl = 196,
        CWaterBullet = 195,
        CVoteController = 194,
        CVGuiScreen = 193,
        CPropJeep = 116,
        CPropVehicleChoreoGeneric = 0,
        CTriggerSoundOperator = 192,
        CBaseVPhysicsTrigger = 22,
        CTriggerPlayerMovement = 191,
        CBaseTrigger = 20,
        CTest_ProxyToggle_Networkable = 188,
        CTesla = 183,
        CBaseTeamObjectiveResource = 17,
        CTeam = 138,
        CSunlightShadowControl = 137,
        CSun = 136,
        CParticlePerformanceMonitor = 97,
        CSpotlightEnd = 130,
        CSpatialEntity = 129,
        CSlideshowDisplay = 125,
        CShadowControl = 124,
        CSceneEntity = 123,
        CRopeKeyframe = 121,
        CRagdollManager = 118,
        CPhysicsPropMultiplayer = 102,
        CPhysBoxMultiplayer = 100,
        CPropDoorRotating = 115,
        CBasePropDoor = 16,
        CDynamicProp = 43,
        CProp_Hallucination = 114,
        CPostProcessController = 110,
        CPointCommentaryNode = 108,
        CPointCamera = 107,
        CPlayerResource = 106,
        CPlasma = 105,
        CPhysMagnet = 103,
        CPhysicsProp = 101,
        CStatueProp = 134,
        CPhysBox = 99,
        CParticleSystem = 98,
        CMovieDisplay = 95,
        CMaterialModifyControl = 92,
        CLightGlow = 91,
        CInfoOverlayAccessor = 88,
        CFuncTrackTrain = 79,
        CFuncSmokeVolume = 78,
        CFuncRotating = 77,
        CFuncReflectiveGlass = 76,
        CFuncOccluder = 75,
        CFuncMoveLinear = 74,
        CFuncMonitor = 73,
        CFunc_LOD = 68,
        CTEDust = 158,
        CFunc_Dust = 67,
        CFuncConveyor = 71,
        CFuncBrush = 70,
        CBreakableSurface = 28,
        CFuncAreaPortalWindow = 69,
        CFish = 63,
        CFireSmoke = 61,
        CEnvTonemapController = 58,
        CEnvScreenEffect = 56,
        CEnvScreenOverlay = 57,
        CEnvProjectedTexture = 54,
        CEnvParticleScript = 53,
        CFogController = 65,
        CEnvDOFController = 52,
        CCascadeLight = 30,
        CEnvAmbientLight = 50,
        CEntityParticleTrail = 49,
        CEntityFreezing = 48,
        CEntityFlame = 47,
        CEntityDissolve = 46,
        CDynamicLight = 42,
        CColorCorrectionVolume = 33,
        CColorCorrection = 32,
        CBreakableProp = 27,
        CBeamSpotlight = 25,
        CBaseButton = 5,
        CBaseToggle = 19,
        CBasePlayer = 15,
        CBaseFlex = 12,
        CBaseEntity = 11,
        CBaseDoor = 10,
        CBaseCombatCharacter = 6,
        CBaseAnimatingOverlay = 3,
        CBoneFollower = 26,
        CBaseAnimating = 2,
        CAI_BaseNPC = 0,
        CBeam = 24,
        CBaseViewModel = 21,
        CBaseParticleEntity = 14,
        CBaseGrenade = 13,
        CBaseCombatWeapon = 7,
        CBaseWeaponWorldModel = 23
};

enum class CSGOHitboxID
{
    Head = 0,
        Neck,
        NeckLower,
        Pelvis,
        Stomach,
        LowerChest,
        Chest,
        UpperChest,
        RightThigh,
        LeftThigh,
        RightShin,
        LeftShin,
        RightFoot,
        LeftFoot,
        RightHand,
        LeftHand,
        RightUpperArm,
        RightLowerArm,
        LeftUpperArm,
        LeftLowerArm
};

class ScriptCreatedItem
{
    public:

    CPNETVAR_FUNC(int*, ItemDefinitionIndex, 0xE67AB3B8); //m_iItemDefinitionIndex

    CPNETVAR_FUNC(int*, ItemIDHigh, 0x714778A); //m_iItemIDHigh

    CPNETVAR_FUNC(int*, ItemIDLow, 0x3A3DFC74); //m_iItemIDLow
};

class AttributeContainer
{
    public:

    CPNETVAR_FUNC(ScriptCreatedItem*, m_Item, 0x7E029CE5);
};


class CBaseCombatWeapon
{
    public:

    CNETVAR_FUNC(float, GetNextPrimaryAttack, 0xDB7B106E); //m_flNextPrimaryAttack

    CNETVAR_FUNC(int, GetAmmoInClip, 0x97B6F70C); //m_iClip1

    CNETVAR_FUNC(HANDLE, GetOwnerHandle, 0xC32DF98D); //m_hOwner

    CNETVAR_FUNC(Vector, GetOrigin, 0x1231CE10); //m_vecOrigin


    CPNETVAR_FUNC(int*, FallbackPaintKit, 0xADE4C870); // m_nFallbackPaintKit

    CPNETVAR_FUNC(int*, FallbackSeed, 0xC2D0683D); // m_nFallbackSeed

    CPNETVAR_FUNC(float*, FallbackWear, 0xA263576C); //m_flFallbackWear

    CPNETVAR_FUNC(int*, FallbackStatTrak, 0x1ED78768); //m_nFallbackStatTrak

    CPNETVAR_FUNC(int*, OwnerXuidLow, 0xAD8D897F);

    CPNETVAR_FUNC(int*, OwnerXuidHigh, 0x90511E77);

    CPNETVAR_FUNC(int*, ViewModelIndex, 0x7F7C89C1);

    CPNETVAR_FUNC(int*, WorldModelIndex, 0x4D8AD9F3);


    CPNETVAR_FUNC(AttributeContainer*, m_AttributeManager, 0xCFFCE089);

    float GetInaccuracy()
    {
        typedef float(__thiscall * oGetSpread)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread)(this);
    }

    float GetSpread()
    {
        typedef float(__thiscall * oGetInac)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread + 1)(this);
    }

    void UpdateAccuracyPenalty()
    {
        typedef void(__thiscall * oUpdateAccuracyPenalty)(PVOID);
        return call_vfunc(this, Offsets::VMT::Weapon_GetSpread + 2)(this);
    }

    CSWeaponInfo* GetCSWpnData()
    {
        static DWORD GetCSWpnDataAddr = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x81\xEC\x00\x00\x00\x00\xB8\x00\x00\x00\x00\x57", "xxxxx????x????x");
        if (GetCSWpnDataAddr)
        {
            CSWeaponInfo* retData;
            __asm

            {
                mov ecx, this

                    call GetCSWpnDataAddr

                    mov retData, eax

            }
            return retData;
        }
        else
        {
            return nullptr;
        }
    }
};

class CCSBomb
{
    public:

    CNETVAR_FUNC(HANDLE, GetOwnerHandle, 0xC32DF98D); //m_hOwner

    CNETVAR_FUNC(float, GetC4BlowTime, 0xB5E0CA1C); //m_flC4Blow

    CNETVAR_FUNC(float, GetC4DefuseCountDown, 0xB959B4A6); //m_flDefuseCountDown
};

class CLocalPlayerExclusive
{
    public:

    CNETVAR_FUNC(Vector, GetViewPunchAngle, 0x68F014C0);//m_viewPunchAngle

    CNETVAR_FUNC(Vector, GetAimPunchAngle, 0xBF25C290);//m_aimPunchAngle

    CNETVAR_FUNC(Vector, GetAimPunchAngleVel, 0x8425E045);//m_aimPunchAngleVel
};

class CollisionProperty
{
    public:

    CNETVAR_FUNC(Vector, GetMins, 0xF6F78BAB);//m_vecMins

    CNETVAR_FUNC(Vector, GetMaxs, 0xE47C6FC4);//m_vecMaxs

    CNETVAR_FUNC(unsigned char, GetSolidType, 0xB86722A1);//m_nSolidType

    CNETVAR_FUNC(unsigned short, GetSolidFlags, 0x63BB24C1);//m_usSolidFlags

    CNETVAR_FUNC(int, GetSurroundsType, 0xB677A0BB); //m_nSurroundType

    bool IsSolid()
    {
        return (GetSolidType() != SOLID_NONE) && ((GetSolidFlags() & FSOLID_NOT_SOLID) == 0);
    }
};

class IClientRenderable
{
    public:
        //virtual void*                                        GetIClientUnknown() = 0;
        virtual Vector const&                        GetRenderOrigin(void) = 0;
        virtual Vector const&                        GetRenderAngles(void) = 0;
        virtual bool ShouldDraw(void) = 0;
        virtual bool IsTransparent(void) = 0;
        virtual bool UsesPowerOfTwoFrameBufferTexture() = 0;
        virtual bool UsesFullFrameBufferTexture() = 0;
        virtual void GetShadowHandle() const = 0;
    virtual void* RenderHandle() = 0;
        virtual const model_t* GetModel() const = 0;
    virtual int DrawModel(int flags) = 0;
        virtual int GetBody() = 0;
        virtual void ComputeFxBlend() = 0;

        bool SetupBones(matrix3x4* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime)
    {
        typedef bool(__thiscall * oSetupBones)(PVOID, matrix3x4 *, int, int, float);
        return call_vfunc(this, 13)(this, pBoneToWorldOut, nMaxBones, boneMask, currentTime);
    }
};

class IClientNetworkable
{
    public:
        virtual IClientUnknown* GetIClientUnknown() = 0;
        virtual void Release() = 0;
        virtual ClientClass* GetClientClass() = 0;// FOR NETVARS FIND YOURSELF ClientClass* stuffs
        virtual void NotifyShouldTransmit( /* ShouldTransmitState_t state*/) = 0;
        virtual void OnPreDataChanged( /*DataUpdateType_t updateType*/) = 0;
        virtual void OnDataChanged( /*DataUpdateType_t updateType*/) = 0;
        virtual void PreDataUpdate( /*DataUpdateType_t updateType*/) = 0;
        virtual void PostDataUpdate( /*DataUpdateType_t updateType*/) = 0;
        virtual void unknown();
    virtual bool IsDormant(void) = 0;
        virtual int GetIndex(void) const = 0;
    virtual void ReceiveMessage(int classID /*, bf_read &msg*/) = 0;
        virtual void* GetDataTableBasePtr() = 0;
        virtual void SetDestroyedOnRecreateEntities(void) = 0;
};

class IClientUnknown
{
    public:
        virtual void* GetCollideable() = 0;
        virtual IClientNetworkable* GetClientNetworkable() = 0;
        virtual IClientRenderable* GetClientRenderable() = 0;
        virtual IClientEntity* GetIClientEntity() = 0;
        virtual IClientEntity* GetBaseEntity() = 0;
        virtual IClientThinkable* GetClientThinkable() = 0;
};

class IClientThinkable
{
    public:
        virtual IClientUnknown* GetIClientUnknown() = 0;
        virtual void ClientThink() = 0;
        virtual void* GetThinkHandle() = 0;
        virtual void SetThinkHandle(void* hThink) = 0;
        virtual void Release() = 0;
};

class __declspec (novtable)IClientEntity : public IClientUnknown, public IClientRenderable, public IClientNetworkable, public IClientThinkable
{
public:
public:
        virtual void Release(void) = 0;
        virtual void blahblahpad(void) = 0;
        virtual Vector&        GetAbsOrigin(void) const = 0;//in broken place use GetOrigin Below
virtual const Vector&        GetAbsAngles(void) const = 0;

    //---                 NetVars                  ---//

    CPNETVAR_FUNC(CLocalPlayerExclusive*, localPlayerExclusive, 0x7177BC3E);// m_Local

    CPNETVAR_FUNC(CollisionProperty*, collisionProperty, 0xE477CBD0);//m_Collision


    CNETVAR_FUNC(int, GetFlags, 0xE456D580); //m_fFlags

    CNETVAR_FUNC(Vector, GetOrigin, 0x1231CE10); //m_vecOrigin

    CNETVAR_FUNC(Vector, GetRotation, 0x6BEA197A); //m_angRotation

    CNETVAR_FUNC(int, GetTeamNum, 0xC08B6C6E); //m_iTeamNum

    CNETVAR_FUNC(int, GetMaxHealth, 0xC52E1C28); //m_iMaxHealth

    CNETVAR_FUNC(int, GetHealth, 0xA93054E3); //m_iHealth

    CNETVAR_FUNC(unsigned char, GetLifeState, 0xD795CCFC); //m_lifeState

    CNETVAR_FUNC(HANDLE, GetActiveWeaponHandle, 0xB4FECDA3); //m_hActiveWeapon

    CNETVAR_FUNC(int, GetTickBase, 0xD472B079); //m_nTickBase

    CNETVAR_FUNC(Vector, GetViewOffset, 0xA9F74931); //m_vecViewOffset[0]

    CNETVAR_FUNC(Vector, GetVelocity, 0x40C1CA24); //m_vecVelocity[0]

    CNETVAR_FUNC(bool, HasGunGameImmunity, 0x6AD6FA0D); //m_bGunGameImmunity

    CNETVAR_FUNC(bool, IsDefusing, 0xA2C14106); //m_bIsDefusing

    CNETVAR_FUNC(int, ArmorValue, 0x3898634); //m_ArmorValue

    CNETVAR_FUNC(bool, HasHelmet, 0x7B97F18A); //m_bHasHelmet

    CNETVAR_FUNC(bool, IsScoped, 0x61B9C22C); //m_bIsScoped

    CNETVAR_FUNC(int, GetMoney, 0xF4B3E183); //m_iAccount

    CNETVAR_FUNC(HANDLE, GetObserverTargetHandle, 0x8660FD83); //m_hObserverTarget
                                                               // ----------------------------------------------//

bool IsAlive()
{
    return (GetLifeState() == LIFE_ALIVE && GetHealth() > 0);
}

Vector GetBonePos(int i)
{
    matrix3x4 boneMatrix[128];
    if (this->SetupBones(boneMatrix, 128, BONE_USED_BY_HITBOX, GetTickCount64()))
    {
        return Vector(boneMatrix[i][0][3], boneMatrix[i][1][3], boneMatrix[i][2][3]);
    }
    return Vector(0, 0, 0);
}

Vector GetHeadPos()
{
    return this->GetBonePos(6);
}

};/*
Syn's AYYWAREFramework 2015
*/

#include "ESP.h"
#include "Interfaces.h"
#include "RenderManager.h"

void CEsp::Init()
{
    BombCarrier = nullptr;
}

// Yeah dude we're defo gunna do some sick moves for the esp yeah
void CEsp::Move(CUserCmd* pCmd) { }

// Main ESP Drawing loop
void CEsp::Draw()
{
    IClientEntity* pLocal = hackManager.pLocal();

    // Loop through all active entitys
    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        player_info_t pinfo;

        // The entity isn't some laggy peice of shit or something
        if (pEntity && pEntity != pLocal && !pEntity->IsDormant())
        {
            // Is it a player?!
            if (Menu::Window.VisualsTab.FiltersPlayers.GetState() && Interfaces::Engine->GetPlayerInfo(i, &pinfo) && pEntity->IsAlive())
            {
                DrawPlayer(pEntity, pinfo);
            }

            // ~ Other ESP's here (items and shit) ~ //
            ClientClass* cClass = (ClientClass*)pEntity->GetClientClass();

            // Dropped weapons
            if (Menu::Window.VisualsTab.FiltersWeapons.GetState() && cClass->m_ClassID != (int)CSGOClassID::CBaseWeaponWorldModel && ((strstr(cClass->m_pNetworkName, "Weapon") || cClass->m_ClassID == (int)CSGOClassID::CDEagle || cClass->m_ClassID == (int)CSGOClassID::CAK47)))
            {
                DrawDrop(pEntity, cClass);
            }

            // If entity is the bomb
            if (Menu::Window.VisualsTab.FiltersC4.GetState())
            {
                if (cClass->m_ClassID == (int)CSGOClassID::CPlantedC4)
                    DrawBombPlanted(pEntity, cClass);

                if (cClass->m_ClassID == (int)CSGOClassID::CC4)
                    DrawBomb(pEntity, cClass);
            }

            // If entity is a chicken
            if (Menu::Window.VisualsTab.FiltersChickens.GetState())
            {
                if (cClass->m_ClassID == (int)CSGOClassID::CChicken)
                    DrawChicken(pEntity, cClass);
            }
        }
    }
}

//  Yeah m8
void CEsp::DrawPlayer(IClientEntity* pEntity, player_info_t pinfo)
{
    ESPBox Box;
    Color Color;

    // Show own team false? well gtfo teammate
    if (Menu::Window.VisualsTab.FiltersEnemiesOnly.GetState() && (pEntity->GetTeamNum() == hackManager.pLocal()->GetTeamNum()))
        return;

    if (GetBox(pEntity, Box))
    {
        Color = GetPlayerColor(pEntity);

        if (Menu::Window.VisualsTab.OptionsBox.GetState())
            DrawBox(Box, Color);

        if (Menu::Window.VisualsTab.OptionsName.GetState())
            DrawName(pinfo, Box);

        if (Menu::Window.VisualsTab.OptionsHealth.GetState())
            DrawHealth(pEntity, Box);

        if (Menu::Window.VisualsTab.OptionsInfo.GetState() || Menu::Window.VisualsTab.OptionsWeapon.GetState())
            DrawInfo(pEntity, Box);

        if (Menu::Window.VisualsTab.OptionsAimSpot.GetState())
            DrawCross(pEntity);

        if (Menu::Window.VisualsTab.OptionsSkeleton.GetState())
            DrawSkeleton(pEntity);
    }
}

// Gets the 2D bounding box for the entity
// Returns false on failure nigga don't fail me
bool CEsp::GetBox(IClientEntity* pEntity, CEsp::ESPBox &result)
{
    // Variables
    Vector vOrigin, min, max, sMin, sMax, sOrigin,
        flb, brt, blb, frt, frb, brb, blt, flt;
    float left, top, right, bottom;

    // Get the locations
    vOrigin = pEntity->GetOrigin();
    min = pEntity->collisionProperty()->GetMins() + vOrigin;
    max = pEntity->collisionProperty()->GetMaxs() + vOrigin;

    // Points of a 3d bounding box
    Vector points[] = { Vector(min.x, min.y, min.z),
        Vector(min.x, max.y, min.z),
        Vector(max.x, max.y, min.z),
        Vector(max.x, min.y, min.z),
        Vector(max.x, max.y, max.z),
        Vector(min.x, max.y, max.z),
        Vector(min.x, min.y, max.z),
        Vector(max.x, min.y, max.z) };

    // Get screen positions
    if (!Render::WorldToScreen(points[3], flb) || !Render::WorldToScreen(points[5], brt)
        || !Render::WorldToScreen(points[0], blb) || !Render::WorldToScreen(points[4], frt)
        || !Render::WorldToScreen(points[2], frb) || !Render::WorldToScreen(points[1], brb)
        || !Render::WorldToScreen(points[6], blt) || !Render::WorldToScreen(points[7], flt))
        return false;

    // Put them in an array (maybe start them off in one later for speed?)
    Vector arr[] = { flb, brt, blb, frt, frb, brb, blt, flt };

    // Init this shit
    left = flb.x;
    top = flb.y;
    right = flb.x;
    bottom = flb.y;

    // Find the bounding corners for our box
    for (int i = 1; i < 8; i++)
    {
        if (left > arr[i].x)
            left = arr[i].x;
        if (bottom < arr[i].y)
            bottom = arr[i].y;
        if (right < arr[i].x)
            right = arr[i].x;
        if (top > arr[i].y)
            top = arr[i].y;
    }

    // Width / height
    result.x = left;
    result.y = top;
    result.w = right - left;
    result.h = bottom - top;

    return true;
}

// Get an entities color depending on team and vis ect
Color CEsp::GetPlayerColor(IClientEntity* pEntity)
{
    int TeamNum = pEntity->GetTeamNum();
    bool IsVis = GameUtils::IsVisible(hackManager.pLocal(), pEntity, (int)CSGOHitboxID::Head);

    Color color;

    if (TeamNum == TEAM_CS_T)
    {
        if (IsVis)
            color = Color(235, 200, 0, 255);
        else
            color = Color(235, 50, 0, 255);
    }
    else
    {
        if (IsVis)
            color = Color(120, 210, 26, 255);
        else
            color = Color(15, 110, 220, 255);
    }


    return color;
}

// 2D  Esp box
void CEsp::DrawBox(CEsp::ESPBox size, Color color)
{
    //if (PlayerBoxes->GetStringIndex() == 1)
    //{
    //        // Full Box
    //        renderMan->Outline(size.x, size.y, size.w, size.h, color);
    //        renderMan->Outline(size.x - 1, size.y - 1, size.w + 2, size.h + 2, COLORCODE(10, 10, 10, 150));
    //        renderMan->Outline(size.x + 1, size.y + 1, size.w - 2, size.h - 2, COLORCODE(10, 10, 10, 150));
    //}
    //else
    //{
    // Corner Box
    int VertLine = (((float)size.w) * (0.20f));
    int HorzLine = (((float)size.h) * (0.20f));

    Render::Clear(size.x, size.y - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - VertLine, size.y - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x, size.y + size.h - 1, VertLine, 1, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - VertLine, size.y + size.h - 1, VertLine, 1, Color(10, 10, 10, 150));

    Render::Clear(size.x - 1, size.y, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x - 1, size.y + size.h - HorzLine, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - 1, size.y, 1, HorzLine, Color(10, 10, 10, 150));
    Render::Clear(size.x + size.w - 1, size.y + size.h - HorzLine, 1, HorzLine, Color(10, 10, 10, 150));

    Render::Clear(size.x, size.y, VertLine, 1, color);
    Render::Clear(size.x + size.w - VertLine, size.y, VertLine, 1, color);
    Render::Clear(size.x, size.y + size.h, VertLine, 1, color);
    Render::Clear(size.x + size.w - VertLine, size.y + size.h, VertLine, 1, color);

    Render::Clear(size.x, size.y, 1, HorzLine, color);
    Render::Clear(size.x, size.y + size.h - HorzLine, 1, HorzLine, color);
    Render::Clear(size.x + size.w, size.y, 1, HorzLine, color);
    Render::Clear(size.x + size.w, size.y + size.h - HorzLine, 1, HorzLine, color);
    //}
}

// Unicode Conversions
static wchar_t* CharToWideChar(const char* text)
{
    size_t size = strlen(text) + 1;
    wchar_t* wa = new wchar_t[size];
    mbstowcs_s(NULL, wa, size / 4, text, size);
    return wa;
}

// Player name
void CEsp::DrawName(player_info_t pinfo, CEsp::ESPBox size)
{
    RECT nameSize = Render::GetTextSize(Render::Fonts::ESP, pinfo.name);
    Render::Text(size.x + (size.w / 2) - (nameSize.right / 2), size.y - 16,
        Color(255, 255, 255, 255), Render::Fonts::ESP, pinfo.name);
}

// Draw a health bar. For Tf2 when a bar is bigger than max health a second bar is displayed
void CEsp::DrawHealth(IClientEntity* pEntity, CEsp::ESPBox size)
{
    ESPBox HealthBar = size;
    HealthBar.y += (HealthBar.h + 6);
    HealthBar.h = 4;

    float HealthValue = pEntity->GetHealth();
    float HealthPerc = HealthValue / 100.f;
    float Width = (size.w * HealthPerc);
    HealthBar.w = Width;

    // --  Main Bar -- //

    Vertex_t Verts[4];
    Verts[0].Init(Vector2D(HealthBar.x, HealthBar.y));
    Verts[1].Init(Vector2D(HealthBar.x + size.w + 5, HealthBar.y));
    Verts[2].Init(Vector2D(HealthBar.x + size.w, HealthBar.y + 5));
    Verts[3].Init(Vector2D(HealthBar.x - 5, HealthBar.y + 5));

    Render::PolygonOutline(4, Verts, Color(10, 10, 10, 255), Color(255, 255, 255, 170));

    Vertex_t Verts2[4];
    Verts2[0].Init(Vector2D(HealthBar.x + 1, HealthBar.y + 1));
    Verts2[1].Init(Vector2D(HealthBar.x + HealthBar.w + 4, HealthBar.y + 1));
    Verts2[2].Init(Vector2D(HealthBar.x + HealthBar.w, HealthBar.y + 5));
    Verts2[3].Init(Vector2D(HealthBar.x - 4, HealthBar.y + 5));

    Color c = GetPlayerColor(pEntity);
    Render::Polygon(4, Verts2, c);

    Verts2[0].Init(Vector2D(HealthBar.x + 1, HealthBar.y + 1));
    Verts2[1].Init(Vector2D(HealthBar.x + HealthBar.w + 2, HealthBar.y + 1));
    Verts2[2].Init(Vector2D(HealthBar.x + HealthBar.w, HealthBar.y + 2));
    Verts2[3].Init(Vector2D(HealthBar.x - 2, HealthBar.y + 2));

    Render::Polygon(4, Verts2, Color(255, 255, 255, 40));

}

// Cleans the internal class name up to something human readable and nice
std::string CleanItemName(std::string name)
{
    std::string Name = name;
    // Tidy up the weapon Name
    if (Name[0] == 'C')
        Name.erase(Name.begin());

    // Remove the word Weapon
    auto startOfWeap = Name.find("Weapon");
    if (startOfWeap != std::string::npos)
                Name.erase(Name.begin() + startOfWeap, Name.begin() + startOfWeap + 6);

    return Name;
}

// Anything else: weapons, class state? idk
void CEsp::DrawInfo(IClientEntity* pEntity, CEsp::ESPBox size)
{
    std::vector < std::string> Info;

    // Player Weapon ESP
    IClientEntity* pWeapon = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)pEntity->GetActiveWeaponHandle());
    if (Menu::Window.VisualsTab.OptionsWeapon.GetState() && pWeapon)
    {
        ClientClass* cClass = (ClientClass*)pWeapon->GetClientClass();
        if (cClass)
        {
            // Draw it
            Info.push_back(CleanItemName(cClass->m_pNetworkName));
        }
    }

    // Bomb Carrier
    if (Menu::Window.VisualsTab.OptionsInfo.GetState() && pEntity == BombCarrier)
    {
        Info.push_back("Bomb Carrier");
    }

    // Comp Rank
    if (Menu::Window.VisualsTab.OptionsInfo.GetState())
    {
        int CompRank = GameUtils::GetPlayerCompRank(pEntity);
        static const char* Ranks[] =
        {
            "",
            "Silver I",
            "Silver II",
            "Silver III",
            "Silver IV",
            "Silver Elite",
            "Silver Elite Master",

            "Gold Nova I",
            "Gold Nova II",
            "Gold Nova III",
            "Gold Nova Master",
            "Master Guardian I",
            "Master Guardian II",

            "Master Guardian Elite",
            "Distinguished Master Guardian",
            "Legendary Eagle",
            "Legendary Eagle Master",
            "Supreme Master First Class",
            "Global Elite"
        };
        if (CompRank >= 0 && CompRank <= 18)
            Info.push_back(Ranks[CompRank]);
    }

    static RECT Size = Render::GetTextSize(Render::Fonts::Default, "Hi");
    int i = 0;
    for (auto Text : Info)
    {
        Render::Text(size.x + size.w + 3, size.y + (i * (Size.bottom + 2)), Color(255, 255, 255, 255), Render::Fonts::ESP, Text.c_str());
        i++;
    }

}

// Little cross on their heads
void CEsp::DrawCross(IClientEntity* pEntity)
{
    Vector cross = pEntity->GetHeadPos(), screen;
    static int Scale = 2;
    if (Render::WorldToScreen(cross, screen))
    {
        Render::Clear(screen.x - Scale, screen.y - (Scale * 2), (Scale * 2), (Scale * 4), Color(20, 20, 20, 160));
        Render::Clear(screen.x - (Scale * 2), screen.y - Scale, (Scale * 4), (Scale * 2), Color(20, 20, 20, 160));
        Render::Clear(screen.x - Scale - 1, screen.y - (Scale * 2) - 1, (Scale * 2) - 2, (Scale * 4) - 2, Color(250, 250, 250, 160));
        Render::Clear(screen.x - (Scale * 2) - 1, screen.y - Scale - 1, (Scale * 4) - 2, (Scale * 2) - 2, Color(250, 250, 250, 160));
    }
}

// Draws a dropped CS:GO Item
void CEsp::DrawDrop(IClientEntity* pEntity, ClientClass* cClass)
{
    Vector Box;
    CBaseCombatWeapon* Weapon = (CBaseCombatWeapon*)pEntity;
    IClientEntity* plr = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)Weapon->GetOwnerHandle());
    if (!plr && Render::WorldToScreen(Weapon->GetOrigin(), Box))
    {
        if (Menu::Window.VisualsTab.OptionsBox.GetState())
        {
            Render::Outline(Box.x - 2, Box.y - 2, 4, 4, Color(255, 255, 255, 255));
            Render::Outline(Box.x - 3, Box.y - 3, 6, 6, Color(10, 10, 10, 150));
        }

        if (Menu::Window.VisualsTab.OptionsInfo.GetState())
        {
            std::string ItemName = CleanItemName(cClass->m_pNetworkName);
            RECT TextSize = Render::GetTextSize(Render::Fonts::ESP, ItemName.c_str());
            Render::Text(Box.x - (TextSize.right / 2), Box.y - 16, Color(255, 255, 255, 255), Render::Fonts::ESP, ItemName.c_str());
        }
    }
}

// Draws a chicken
void CEsp::DrawChicken(IClientEntity* pEntity, ClientClass* cClass)
{
    ESPBox Box;

    if (GetBox(pEntity, Box))
    {
        player_info_t pinfo; strcpy_s(pinfo.name, "Chicken");
        if (Menu::Window.VisualsTab.OptionsBox.GetState())
            DrawBox(Box, Color(255, 255, 255, 255));

        if (Menu::Window.VisualsTab.OptionsName.GetState())
            DrawName(pinfo, Box);
    }
}

// Draw the planted bomb and timer
void CEsp::DrawBombPlanted(IClientEntity* pEntity, ClientClass* cClass)
{
    // Null it out incase bomb has been dropped or planted
    BombCarrier = nullptr;

    Vector vOrig; Vector vScreen;
    vOrig = pEntity->GetOrigin();
    CCSBomb* Bomb = (CCSBomb*)pEntity;

    if (Render::WorldToScreen(vOrig, vScreen))
    {
        float flBlow = Bomb->GetC4BlowTime();
        float TimeRemaining = flBlow - (Interfaces::Globals->interval_per_tick * hackManager.pLocal()->GetTickBase());
        char buffer[64];
        sprintf_s(buffer, "Bomb: %.1f", TimeRemaining);
        Render::Text(vScreen.x, vScreen.y, Color(250, 42, 42, 255), Render::Fonts::ESP, buffer);
    }
}

// Draw the bomb if it's dropped, or store the player who's carrying 
void CEsp::DrawBomb(IClientEntity* pEntity, ClientClass* cClass)
{
    // Null it out incase bomb has been dropped or planted
    BombCarrier = nullptr;
    CBaseCombatWeapon* BombWeapon = (CBaseCombatWeapon*)pEntity;
    Vector vOrig; Vector vScreen;
    vOrig = pEntity->GetOrigin();
    bool adopted = true;
    HANDLE parent = BombWeapon->GetOwnerHandle();
    if (parent || (vOrig.x == 0 && vOrig.y == 0 && vOrig.z == 0))
    {
        IClientEntity* pParentEnt = (Interfaces::EntList->GetClientEntityFromHandle(parent));
        if (pParentEnt && pParentEnt->IsAlive())
        {
            BombCarrier = pParentEnt;
            adopted = false;
        }
    }

    if (adopted)
    {
        if (Render::WorldToScreen(vOrig, vScreen))
        {
            Render::Text(vScreen.x, vScreen.y, Color(112, 230, 20, 255), Render::Fonts::ESP, "Bomb");
        }
    }
}

void DrawBoneArray(int* boneNumbers, int amount, IClientEntity* pEntity, Color color)
{
    Vector LastBoneScreen;
    for (int i = 0; i < amount; i++)
    {
        Vector Bone = pEntity->GetBonePos(boneNumbers[i]);
        Vector BoneScreen;

        if (Render::WorldToScreen(Bone, BoneScreen))
        {
            if (i > 0)
            {
                Render::Line(LastBoneScreen.x, LastBoneScreen.y, BoneScreen.x, BoneScreen.y, color);
            }
        }
        LastBoneScreen = BoneScreen;
    }
}

void DrawBoneTest(IClientEntity* pEntity)
{
    for (int i = 0; i < 127; i++)
    {
        Vector BoneLoc = pEntity->GetBonePos(i);
        Vector BoneScreen;
        if (Render::WorldToScreen(BoneLoc, BoneScreen))
        {
            char buf[10];
            _itoa_s(i, buf, 10);
            Render::Text(BoneScreen.x, BoneScreen.y, Color(255, 255, 255, 180), Render::Fonts::ESP, buf);
        }
    }
}

void CEsp::DrawSkeleton(IClientEntity* pEntity)
{
    studiohdr_t* pStudioHdr = Interfaces::ModelInfo->GetStudiomodel(pEntity->GetModel());

    if (!pStudioHdr)
        return;

    Vector vParent, vChild, sParent, sChild;

    for (int j = 0; j < pStudioHdr->numbones; j++)
    {
        mstudiobone_t* pBone = pStudioHdr->GetBone(j);

        if (pBone && (pBone->flags & BONE_USED_BY_HITBOX) && (pBone->parent != -1))
        {
            vChild = pEntity->GetBonePos(j);
            vParent = pEntity->GetBonePos(pBone->parent);

            if (Render::WorldToScreen(vParent, sParent) && Render::WorldToScreen(vChild, sChild))
            {
                Render::Line(sParent[0], sParent[1], sChild[0], sChild[1], Color(255, 255, 255, 255));
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CEsp : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:

        // Other shit
        IClientEntity* BombCarrier;

struct ESPBox
{
    int x, y, w, h;
};

// Draw a player
void DrawPlayer(IClientEntity* pEntity, player_info_t pinfo);

// Get player info
Color GetPlayerColor(IClientEntity* pEntity);
bool GetBox(IClientEntity* pEntity, ESPBox &result);

// Draw shit about player
void DrawBox(ESPBox size, Color color);
void DrawName(player_info_t pinfo, ESPBox size);
void DrawHealth(IClientEntity* pEntity, ESPBox size);
void DrawInfo(IClientEntity* pEntity, ESPBox size);
void DrawCross(IClientEntity* pEntity);
void DrawSkeleton(IClientEntity* pEntity);

void DrawChicken(IClientEntity* pEntity, ClientClass* cClass);
void DrawDrop(IClientEntity* pEntity, ClientClass* cClass);
void DrawBombPlanted(IClientEntity* pEntity, ClientClass* cClass);
void DrawBomb(IClientEntity* pEntity, ClientClass* cClass);
};



#include "GUI.h"

#include "RenderManager.h"

#include 
#include "tinyxml2.h"
#include "Controls.h"

CGUI GUI;

CGUI::CGUI()
{

}

// Draws all windows 
void CGUI::Draw()
{
    bool ShouldDrawCursor = false;

    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            ShouldDrawCursor = true;
            DrawWindow(window);
        }

    }

    if (ShouldDrawCursor)
    {
        static Vertex_t MouseVt[3];

        MouseVt[0].Init(Vector2D(Mouse.x, Mouse.y));
        MouseVt[1].Init(Vector2D(Mouse.x + 16, Mouse.y));
        MouseVt[2].Init(Vector2D(Mouse.x, Mouse.y + 16));

        Render::PolygonOutline(3, MouseVt, Color(255, 0, 0, 230), Color(0, 0, 0, 240));
    }
}

// Handle all input etc
void CGUI::Update()
{
    //Key Array
    std::copy(keys, keys + 255, oldKeys);
    for (int x = 0; x < 255; x++)
    {
        //oldKeys[x] = oldKeys[x] & keys[x];
        keys[x] = (GetAsyncKeyState(x));
    }

    // Mouse Location
    POINT mp; GetCursorPos(&mp);
    Mouse.x = mp.x; Mouse.y = mp.y;

    RECT Screen = Render::GetViewport();

    // Window Binds
    for (auto & bind : WindowBinds)
    {
        if (GetKeyPress(bind.first))
        {
            bind.second->Toggle();
        }
    }

    // Stop dragging
    if (IsDraggingWindow && !GetKeyState(VK_LBUTTON))
    {
        IsDraggingWindow = false;
        DraggingWindow = nullptr;
    }

    // If we are in the proccess of dragging a window
    if (IsDraggingWindow && GetKeyState(VK_LBUTTON) && !GetKeyPress(VK_LBUTTON))
    {
        if (DraggingWindow)
        {
            DraggingWindow->m_x = Mouse.x - DragOffsetX;
            DraggingWindow->m_y = Mouse.y - DragOffsetY;
        }
    }

    // Process some windows
    for (auto window : Windows)
    {
        if (window->m_bIsOpen)
        {
            // Used to tell the widget processing that there could be a click
            bool bCheckWidgetClicks = false;

            // If the user clicks inside the window
            if (GetKeyPress(VK_LBUTTON))
            {
                if (IsMouseInRegion(window->m_x, window->m_y, window->m_x + window->m_iWidth, window->m_y + window->m_iHeight))
                {
                    // Is it inside the client area?
                    if (IsMouseInRegion(window->GetClientArea()))
                    {
                        // User is selecting a new tab
                        if (IsMouseInRegion(window->GetTabArea()))
                        {
                            // Loose focus on the control
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;

                            int iTab = 0;
                            int TabCount = window->Tabs.size();
                            if (TabCount) // If there are some tabs
                            {
                                int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
                                int Dist = Mouse.x - (window->m_x + 8);
                                while (Dist > TabSize)
                                {
                                    if (Dist > TabSize)
                                    {
                                        iTab++;
                                        Dist -= TabSize;
                                    }
                                }
                                window->SelectedTab = window->Tabs[iTab];
                            }

                        }
                        else
                            bCheckWidgetClicks = true;
                    }
                    else
                    {
                        // Must be in the around the title or side of the window
                        // So we assume the user is trying to drag the window
                        IsDraggingWindow = true;
                        DraggingWindow = window;
                        DragOffsetX = Mouse.x - window->m_x;
                        DragOffsetY = Mouse.y - window->m_y;

                        // Loose focus on the control
                        window->IsFocusingControl = false;
                        window->FocusedControl = nullptr;
                    }
                }
                else
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }


            // Controls 
            if (window->SelectedTab != nullptr)
            {
                // Focused widget
                bool SkipWidget = false;
                CControl* SkipMe = nullptr;

                // this window is focusing on a widget??
                if (window->IsFocusingControl)
                {
                    if (window->FocusedControl != nullptr)
                    {
                        // We've processed it once, skip it later
                        SkipWidget = true;
                        SkipMe = window->FocusedControl;

                        POINT cAbs = window->FocusedControl->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, window->FocusedControl->m_iWidth, window->FocusedControl->m_iHeight };
                        window->FocusedControl->OnUpdate();

                        if (window->FocusedControl->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            window->FocusedControl->OnClick();

                            // If it gets clicked we loose focus
                            window->IsFocusingControl = false;
                            window->FocusedControl = nullptr;
                            bCheckWidgetClicks = false;
                        }
                    }
                }

                // Itterate over the rest of the control
                for (auto control : window->SelectedTab->Controls)
                {
                    if (control != nullptr)
                    {
                        if (SkipWidget && SkipMe == control)
                            continue;

                        POINT cAbs = control->GetAbsolutePos();
                        RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                        control->OnUpdate();

                        if (control->Flag(UIFlags::UI_Clickable) && IsMouseInRegion(controlRect) && bCheckWidgetClicks)
                        {
                            control->OnClick();
                            bCheckWidgetClicks = false;

                            // Change of focus
                            if (control->Flag(UIFlags::UI_Focusable))
                            {
                                window->IsFocusingControl = true;
                                window->FocusedControl = control;
                            }
                            else
                            {
                                window->IsFocusingControl = false;
                                window->FocusedControl = nullptr;
                            }

                        }
                    }
                }

                // We must have clicked whitespace
                if (bCheckWidgetClicks)
                {
                    // Loose focus on the control
                    window->IsFocusingControl = false;
                    window->FocusedControl = nullptr;
                }
            }
        }
    }
}

// Returns 
bool CGUI::GetKeyPress(unsigned int key)
{
    if (keys[key] == true && oldKeys[key] == false)
        return true;
    else
        return false;
}

bool CGUI::GetKeyState(unsigned int key)
{
    return keys[key];
}

bool CGUI::IsMouseInRegion(int x, int y, int x2, int y2)
{
    if (Mouse.x > x && Mouse.y > y && Mouse.x < x2 && Mouse.y < y2)
        return true;
    else
        return false;
}

bool CGUI::IsMouseInRegion(RECT region)
{
    return IsMouseInRegion(region.left, region.top, region.left + region.right, region.top + region.bottom);
}

POINT CGUI::GetMouse()
{
    return Mouse;
}

bool CGUI::DrawWindow(CWindow* window)
{
    // Main Window
    Render::Outline(window->m_x, window->m_y, window->m_iWidth, window->m_iHeight, Color(20, 20, 20, 80));
    Render::GradientV(window->m_x + 2, window->m_y + 2, window->m_iWidth - 4, 26, Color(0, 0, 0, 255), Color(0, 0, 0, 255));
    Render::Clear(window->m_x + 2, window->m_y + 2 + 26, window->m_iWidth - 4, window->m_iHeight - 4 - 26, Color(0, 0, 0, 255));
    Render::Outline(window->m_x + 1, window->m_y + 1, window->m_iWidth - 2, window->m_iHeight - 2, Color(255, 0, 0, 255));
    Render::Text(window->m_x + 8, window->m_y + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, window->Title.c_str());

    //Inner
    Render::Outline(window->m_x + 7, window->m_y + 1 + 26, window->m_iWidth - 4 - 10, window->m_iHeight - 2 - 6 - 26, Color(255, 0, 0, 255));
    Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, window->m_iHeight - 2 - 8 - 26, Color(255, 255, 255, 255));

    //Tab
    Render::GradientV(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 29, Color(52, 52, 52, 255), Color(6, 6, 6, 255));
    int TabCount = window->Tabs.size();
    if (TabCount) // If there are some tabs
    {
        int TabSize = (window->m_iWidth - 4 - 12) / TabCount;
        for (int i = 0; i < TabCount; i++)
        {
            RECT TabArea = { window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29 };
            CTab* tab = window->Tabs[i];
            if (window->SelectedTab == tab)
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(52, 52, 52, 255), Color(106, 106, 106, 255));
            }
            else if (IsMouseInRegion(TabArea))
            {
                Render::GradientV(window->m_x + 8 + (i * TabSize), window->m_y + 1 + 27, TabSize, 29, Color(106, 106, 106, 255), Color(52, 52, 52, 255));
            }
            RECT TextSize = Render::GetTextSize(Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Text(TabArea.left + (TabSize / 2) - (TextSize.right / 2), TabArea.top + 8, Color(255, 255, 255, 255), Render::Fonts::MenuBold, tab->Title.c_str());
            Render::Clear(window->m_x + 8, window->m_y + 1 + 27, window->m_iWidth - 4 - 12, 2, Color(66, 66, 66, 255));
        }
    }


    // Controls 
    if (window->SelectedTab != nullptr)
    {
        // Focused widget
        bool SkipWidget = false;
        CControl* SkipMe = nullptr;

        // this window is focusing on a widget??
        if (window->IsFocusingControl)
        {
            if (window->FocusedControl != nullptr)
            {
                // We need to draw it last, so skip it in the regular loop
                SkipWidget = true;
                SkipMe = window->FocusedControl;
            }
        }


        // Itterate over all the other controls
        for (auto control : window->SelectedTab->Controls)
        {
            if (SkipWidget && SkipMe == control)
                continue;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

        // Draw the skipped widget last
        if (SkipWidget)
        {
            auto control = window->FocusedControl;

            if (control != nullptr && control->Flag(UIFlags::UI_Drawable))
            {
                POINT cAbs = control->GetAbsolutePos();
                RECT controlRect = { cAbs.x, cAbs.y, control->m_iWidth, control->m_iHeight };
                bool hover = false;
                if (IsMouseInRegion(controlRect))
                {
                    hover = true;
                }
                control->Draw(hover);
            }
        }

    }


    return true;
}

void CGUI::RegisterWindow(CWindow* window)
{
    Windows.push_back(window);

    // Resorting to put groupboxes at the start
    for (auto tab : window->Tabs)
    {
        for (auto control : tab->Controls)
        {
            if (control->Flag(UIFlags::UI_RenderFirst))
            {
                CControl* c = control;
                tab->Controls.erase(std::remove(tab->Controls.begin(), tab->Controls.end(), control), tab->Controls.end());
                tab->Controls.insert(tab->Controls.begin(), control);
            }
        }
    }
}

void CGUI::BindWindow(unsigned char Key, CWindow* window)
{
    if (window)
        WindowBinds[Key] = window;
    else
        WindowBinds.erase(Key);
}

void CGUI::SaveWindowState(CWindow* window, std::string Filename)
{
    // Create a whole new document and we'll just save over top of the old one
    tinyxml2::XMLDocument Doc;

    // Root Element is called "ayy"
    tinyxml2::XMLElement* Root = Doc.NewElement("ayy");
    Doc.LinkEndChild(Root);

    Utilities::Log("Saving Window %s", window->Title.c_str());

    // If the window has some tabs..
    if (Root && window->Tabs.size() > 0)
    {
        for (auto Tab : window->Tabs)
        {
            // Add a new section for this tab
            tinyxml2::XMLElement* TabElement = Doc.NewElement(Tab->Title.c_str());
            Root->LinkEndChild(TabElement);

            Utilities::Log("Saving Tab %s", Tab->Title.c_str());

            // Now we itterate the controls this tab contains
            if (TabElement && Tab->Controls.size() > 0)
            {
                for (auto Control : Tab->Controls)
                {
                    // If the control is ok to be saved
                    if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                    {
                        // Create an element for the control
                        tinyxml2::XMLElement* ControlElement = Doc.NewElement(Control->FileIdentifier.c_str());
                        TabElement->LinkEndChild(ControlElement);

                        Utilities::Log("Saving control %s", Control->FileIdentifier.c_str());

                        if (!ControlElement)
                        {
                            Utilities::Log("Errorino :(");
                            return;
                        }

                        CCheckBox* cbx = nullptr;
                        CComboBox* cbo = nullptr;
                        CKeyBind* key = nullptr;
                        CSlider* sld = nullptr;

                        // Figure out what kind of control and data this is
                        switch (Control->FileControlType)
                        {
                            case UIControlTypes::UIC_CheckBox:
                                cbx = (CCheckBox*)Control;
                                ControlElement->SetText(cbx->GetState());
                                break;
                            case UIControlTypes::UIC_ComboBox:
                                cbo = (CComboBox*)Control;
                                ControlElement->SetText(cbo->GetIndex());
                                break;
                            case UIControlTypes::UIC_KeyBind:
                                key = (CKeyBind*)Control;
                                ControlElement->SetText(key->GetKey());
                                break;
                            case UIControlTypes::UIC_Slider:
                                sld = (CSlider*)Control;
                                ControlElement->SetText(sld->GetValue());
                                break;
                        }
                    }
                }
            }
        }
    }

    //Save the file
    if (Doc.SaveFile(Filename.c_str()) != tinyxml2::XML_NO_ERROR)
    {
        MessageBox(NULL, "Failed To Save Config File!", "AyyWare", MB_OK);
    }

}

void CGUI::LoadWindowState(CWindow* window, std::string Filename)
{
    // Lets load our meme
    tinyxml2::XMLDocument Doc;
    if (Doc.LoadFile(Filename.c_str()) == tinyxml2::XML_NO_ERROR)
    {
        tinyxml2::XMLElement* Root = Doc.RootElement();

        // The root "ayy" element
        if (Root)
        {
            // If the window has some tabs..
            if (Root && window->Tabs.size() > 0)
            {
                for (auto Tab : window->Tabs)
                {
                    // We find the corresponding element for this tab
                    tinyxml2::XMLElement* TabElement = Root->FirstChildElement(Tab->Title.c_str());
                    if (TabElement)
                    {
                        // Now we itterate the controls this tab contains
                        if (TabElement && Tab->Controls.size() > 0)
                        {
                            for (auto Control : Tab->Controls)
                            {
                                // If the control is ok to be saved
                                if (Control && Control->Flag(UIFlags::UI_SaveFile) && Control->FileIdentifier.length() > 1 && Control->FileControlType)
                                {
                                    // Get the controls element
                                    tinyxml2::XMLElement* ControlElement = TabElement->FirstChildElement(Control->FileIdentifier.c_str());

                                    if (ControlElement)
                                    {
                                        Utilities::Log("We tryin to load fam");
                                        CCheckBox* cbx = nullptr;
                                        CComboBox* cbo = nullptr;
                                        CKeyBind* key = nullptr;
                                        CSlider* sld = nullptr;

                                        // Figure out what kind of control and data this is
                                        switch (Control->FileControlType)
                                        {
                                            case UIControlTypes::UIC_CheckBox:
                                                cbx = (CCheckBox*)Control;
                                                cbx->SetState(ControlElement->GetText()[0] == '1' ? true : false);
                                                break;
                                            case UIControlTypes::UIC_ComboBox:
                                                cbo = (CComboBox*)Control;
                                                cbo->SelectIndex(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_KeyBind:
                                                key = (CKeyBind*)Control;
                                                key->SetKey(atoi(ControlElement->GetText()));
                                                break;
                                            case UIControlTypes::UIC_Slider:
                                                sld = (CSlider*)Control;
                                                sld->SetValue(atof(ControlElement->GetText()));
                                                break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "CommonIncludes.h"

#include 

class CControl;
class CTab;
class CWindow;
class CGUI;

extern CGUI GUI;

enum UIFlags
{
    UI_None = 0x00,
    UI_Drawable = 0x01,
    UI_Clickable = 0x02,
    UI_Focusable = 0x04,
    UI_RenderFirst = 0x08,
    UI_SaveFile = 0x10
};

enum UIControlTypes
{
    UIC_CheckBox = 1,
    UIC_Slider,
    UIC_KeyBind,
    UIC_ComboBox
};

// Base class for GUI controls
class CControl
{
    friend class CGUI;
    friend class CTab;
    friend class CWindow;
    public:
        void SetPosition(int x, int y);
    void SetSize(int w, int h);
    void GetSize(int &w, int &h);
    void SetFileId(std::string fid);

    bool Flag(int f);
    protected:
        int m_x, m_y;
    int m_iWidth, m_iHeight;
    int m_Flags;
    CWindow* parent;

    std::string FileIdentifier;
    int FileControlType;

    virtual void Draw(bool) = 0;
        virtual void OnUpdate() = 0;
        virtual void OnClick() = 0;

        POINT GetAbsolutePos();
};

// A GUI Control Container
class CTab
{
    friend class CControl;
    friend class CGUI;
    friend class CWindow;
    public:
        void SetTitle(std::string name);
    void RegisterControl(CControl* control);
    private:
        std::string Title;
    std::vector Controls;
    CWindow* parent;
};

// Base class for a simple GUI window
class CWindow
{
    friend class CControl;
    friend class CGUI;
    public:
        void SetPosition(int x, int y);
    void SetSize(int w, int h);
    void SetTitle(std::string title);
    void Open();
    void Close();
    void Toggle();
    CControl* GetFocus();

    void RegisterTab(CTab* Tab);

    RECT GetClientArea();
    RECT GetTabArea();

    private:
        void DrawControls();

    bool m_bIsOpen;

    std::vector Tabs;
    CTab* SelectedTab;

    bool IsFocusingControl;
    CControl* FocusedControl;

    std::string Title;
    int m_x;
    int m_y;
    int m_iWidth;
    int m_iHeight;

};

// User interface manager
class CGUI
{
    public:
        CGUI();

    // Draws all windows 
    void Draw();

    // Handle all input etc
    void Update();

    // Draws a single window
    bool DrawWindow(CWindow* window);

    // Registers a window
    void RegisterWindow(CWindow* window);

    // Config saving/loading
    void SaveWindowState(CWindow* window, std::string Filename);
    void LoadWindowState(CWindow* window, std::string Filename);

    // Window Binds
    void BindWindow(unsigned char Key, CWindow* window);

    // Input
    bool GetKeyPress(unsigned int key);
    bool GetKeyState(unsigned int key);
    bool IsMouseInRegion(int x, int y, int x2, int y2);
    bool IsMouseInRegion(RECT region);
    POINT GetMouse();

    private:
        // Input
        // keyboard
        bool keys[256];
    bool oldKeys[256];
    // Mouse
    POINT Mouse;
    bool MenuOpen;

    // Window Dragging
    bool IsDraggingWindow;
    CWindow* DraggingWindow;
    int DragOffsetX; int DragOffsetY;

    // Windows
    std::vector Windows;

    // KeyBinds -> Windows Map
    std::map WindowBinds;

};/*
Syn's Payhake Framework for Insanity & Razor
*/

#include "Hacks.h"
#include "Interfaces.h"
#include "RenderManager.h"

#include "ESP.h"
#include "Visuals.h"
#include "RageBot.h"
#include "MiscHacks.h"
#include "LegitBot.h"

CEsp Esp;
CVisuals Visuals;
CMiscHacks MiscHacks;
CRageBot RageBot;
CLegitBot LegitBot;

// Initialise and register ALL hackmanager hacks in here nigga
void Hacks::SetupHacks()
{
    Esp.Init();
    Visuals.Init();
    MiscHacks.Init();
    RageBot.Init();
    LegitBot.Init();

    hackManager.RegisterHack(&Esp);
    hackManager.RegisterHack(&Visuals);
    hackManager.RegisterHack(&MiscHacks);
    hackManager.RegisterHack(&RageBot);
    hackManager.RegisterHack(&LegitBot);

    //--------------------------------
    hackManager.Ready();
}

void SpecList()
{
    IClientEntity* pLocal = hackManager.pLocal();

    RECT scrn = Render::GetViewport();
    int ayy = 0;

    // Loop through all active entitys
    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        player_info_t pinfo;

        // The entity isn't some laggy peice of shit or something
        if (pEntity && pEntity != pLocal)
        {
            if (Interfaces::Engine->GetPlayerInfo(i, &pinfo) && !pEntity->IsAlive() && !pEntity->IsDormant())
            {
                HANDLE obs = pEntity->GetObserverTargetHandle();

                if (obs)
                {
                    IClientEntity* pTarget = Interfaces::EntList->GetClientEntityFromHandle(obs);
                    player_info_t pinfo2;
                    if (pTarget)
                    {
                        if (Interfaces::Engine->GetPlayerInfo(pTarget->GetIndex(), &pinfo2))
                        {
                            char buf[255]; sprintf_s(buf, "%s => %s", pinfo.name, pinfo2.name);
                            RECT TextSize = Render::GetTextSize(Render::Fonts::ESP, buf);
                            Render::Clear(scrn.right - 260, (scrn.bottom / 2) + (16 * ayy), 260, 16, Color(0, 0, 0, 140));
                            Render::Text(scrn.right - TextSize.right - 4, (scrn.bottom / 2) + (16 * ayy), pTarget->GetIndex() == pLocal->GetIndex() ? Color(240, 70, 80, 255) : Color(255, 255, 255, 255), Render::Fonts::ESP, buf);
                            ayy++;
                        }
                    }
                }
            }
        }
    }

    Render::Outline(scrn.right - 261, (scrn.bottom / 2) - 1, 262, (16 * ayy) + 2, Color(23, 23, 23, 255));
    Render::Outline(scrn.right - 260, (scrn.bottom / 2), 260, (16 * ayy), Color(90, 90, 90, 255));
}

// Only gets called in game, use a seperate draw UI call for menus in the hook
void Hacks::DrawHacks()
{
    // Spectator List
    if (Menu::Window.VisualsTab.OtherSpectators.GetState())
        SpecList();

    // Check the master visuals switch, just to be sure
    if (!Menu::Window.VisualsTab.Active.GetState())
        return;

    hackManager.Draw();
    //--------------------------------

}

// Game Cmd Changes
void Hacks::MoveHacks(CUserCmd* pCmd)
{
    Vector origView = pCmd->viewangles;
    hackManager.Move(pCmd);
    // ------------------------------

    // Put it in here so it's applied AFTER the aimbot
    int AirStuckKey = Menu::Window.VisualsTab.OtherAirStuck.GetKey();
    if (AirStuckKey > 0 && GUI.GetKeyState(AirStuckKey))
    {
        if (!(pCmd->buttons & IN_ATTACK))
            pCmd->tick_count = 0xFFFFF;
    }
}

//---------------------------------------------------------------------//
HackManager hackManager;

// Register a new hack
void HackManager::RegisterHack(CHack* hake)
{
    Hacks.push_back(hake);
    hake->Init();
}

// Draw all the hakes
void HackManager::Draw()
{
    if (!IsReady)
        return;

    // Grab the local player for drawing related hacks
    pLocalInstance = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (!pLocalInstance) return;

    for (auto & hack : Hacks)
    {
        hack->Draw();
    }
}

// Handle all the move hakes
void HackManager::Move(CUserCmd* pCmd)
{
    if (!IsReady)
        return;

    // Grab the local player for move related hacks
    pLocalInstance = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (!pLocalInstance) return;

    for (auto & hack : Hacks)
    {
        hack->Move(pCmd);
    }
}

//---------------------------------------------------------------------//
// Other Utils and shit

// Saves hacks needing to call a bunch of virtuals to get the instance
// Saves on cycles and file size. Recycle your plastic kids
IClientEntity* HackManager::pLocal()
{
    return pLocalInstance;
}

// Makes sure none of the hacks are called in their 
// hooks until they are completely ready for use
void HackManager::Ready()
{
    IsReady = true;
}
#pragma once

#pragma once

# include "SDK.h"
# include "Menu.h"
# include 

namespace Hacks
{
    void SetupHacks();
    void DrawHacks();
    void MoveHacks(CUserCmd* pCmd);
}

class CHack
{
    public:
        virtual void Draw() = 0;
        virtual void Move(CUserCmd* pCmd) = 0;
        virtual void Init() = 0;
};

class HackManager
{
    public:
        void RegisterHack(CHack* hake);
    void Ready();

    void Draw();
    void Move(CUserCmd* pCmd);
    IClientEntity* pLocal();
    private:
        std::vector Hacks;
    IClientEntity* pLocalInstance;
    bool IsReady;
};

extern HackManager hackManager;
    /*
Syn's AYYWAREFramework 2015
*/

#include "Hooks.h"
#include "Hacks.h"
#include "Chams.h"
#include "Menu.h"

#include "Interfaces.h"
#include "RenderManager.h"
#include "MiscHacks.h"

// Funtion Typedefs
typedef void(__thiscall* DrawModelEx_)(void*, void*, void*, const ModelRenderInfo_t&, matrix3x4*);
typedef void(__thiscall* PaintTraverse_)(PVOID, unsigned int, bool, bool);
typedef bool(__thiscall* InPrediction_)(PVOID);
typedef void(__stdcall* FrameStageNotifyFn)(ClientFrameStage_t);

// Function Pointers to the originals
PaintTraverse_ oPaintTraverse;
DrawModelEx_ oDrawModelExecute;
FrameStageNotifyFn oFrameStageNotify;

// Hook function prototypes
void __fastcall PaintTraverse_Hooked(PVOID pPanels, int edx, unsigned int vguiPanel, bool forceRepaint, bool allowForce);
bool __stdcall Hooked_InPrediction();
void __fastcall Hooked_DrawModelExecute(void* thisptr, int edx, void* ctx, void* state, const ModelRenderInfo_t &pInfo, matrix3x4* pCustomBoneToWorld);
bool __fastcall CreateMoveClient_Hooked(void* self, int edx, float frametime, CUserCmd* pCmd);
void __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage);

// VMT Managers
namespace Hooks
{
    // VMT Managers
    Utilities::Memory::VMTManager VMTPanel; // Hooking drawing functions
    Utilities::Memory::VMTManager VMTClient; // Maybe CreateMove
    Utilities::Memory::VMTManager VMTClientMode; // CreateMove for functionality
    Utilities::Memory::VMTManager VMTModelRender; // DrawModelEx for chams
    Utilities::Memory::VMTManager VMTPrediction; // InPrediction for no vis recoil
};

// Initialise all our hooks
void Hooks::Initialise()
{
    // Panel hooks for drawing to the screen via surface functions
    VMTPanel.Initialise((DWORD*)Interfaces::Panels);
    oPaintTraverse = (PaintTraverse_)VMTPanel.HookMethod((DWORD) & PaintTraverse_Hooked, Offsets::VMT::Panel_PaintTraverse);
    Utilities::Log("Paint Traverse Hooked");

    // No Visual Recoil
    VMTPrediction.Initialise((DWORD*)Interfaces::Prediction);
    VMTPrediction.HookMethod((DWORD) & Hooked_InPrediction, 14);
    Utilities::Log("InPrediction Hooked");

    // Chams
    VMTModelRender.Initialise((DWORD*)Interfaces::ModelRender);
    oDrawModelExecute = (DrawModelEx_)VMTModelRender.HookMethod((DWORD) & Hooked_DrawModelExecute, Offsets::VMT::ModelRender_DrawModelExecute);
    Utilities::Log("DrawModelExecute Hooked");

    // Setup ClientMode Hooks
    VMTClientMode.Initialise((DWORD*)Interfaces::ClientMode);
    VMTClientMode.HookMethod((DWORD) & CreateMoveClient_Hooked, 24);
    //oFrameStageNotify = (FrameStageNotifyFn)VMTClientMode.HookMethod((DWORD)Hooked_FrameStageNotify, 36);
    Utilities::Log("CreateMove");

    // Setup client hooks
    VMTClient.Initialise((DWORD*)Interfaces::Client);
    oFrameStageNotify = (FrameStageNotifyFn)VMTClient.HookMethod((DWORD) & Hooked_FrameStageNotify, 36);
    Utilities::Log("FrameStage Hey whats up hello?");
}

// Undo our hooks
void Hooks::UndoHooks()
{
    VMTPanel.RestoreOriginal();
    VMTPrediction.RestoreOriginal();
    VMTModelRender.RestoreOriginal();
    VMTClientMode.RestoreOriginal();
    VMTClient.RestoreOriginal();
}

void MovementCorrection(CUserCmd* pCmd)
{

}

//---------------------------------------------------------------------------------------------------------
//                                         Hooked Functions
//---------------------------------------------------------------------------------------------------------

// Paint Traverse Hooked function
void __fastcall PaintTraverse_Hooked(PVOID pPanels, int edx, unsigned int vguiPanel, bool forceRepaint, bool allowForce)
{
    oPaintTraverse(pPanels, vguiPanel, forceRepaint, allowForce);

    static unsigned int FocusOverlayPanel = 0;
    static bool FoundPanel = false;

    if (!FoundPanel)
    {
        PCHAR szPanelName = (PCHAR)Interfaces::Panels->GetName(vguiPanel);
        if (strstr(szPanelName, "MatSystemTopPanel"))
        {
            FocusOverlayPanel = vguiPanel;
            FoundPanel = true;
        }
    }
    else if (FocusOverlayPanel == vguiPanel)
    {

        Render::Text(10, 10, Color(255, 255, 255, 220), Render::Fonts::Menu, "AYYWARE New Meme of 2015 Fixed By UnnAmE1337");
        if (Interfaces::Engine->IsConnected() && Interfaces::Engine->IsInGame())
            Hacks::DrawHacks();

        // Update and draw the menu
        Menu::DoUIFrame();
    }
}

// InPrediction Hooked Function
bool __stdcall Hooked_InPrediction()
{
    bool result;
    static InPrediction_ origFunc = (InPrediction_)Hooks::VMTPrediction.GetOriginalFunction(14);
    static DWORD* ecxVal = Interfaces::Prediction;
    result = origFunc(ecxVal);

    // If we are in the right place where the player view is calculated
    // Calculate the change in the view and get rid of it
    if (Menu::Window.VisualsTab.OtherNoVisualRecoil.GetState() && (DWORD)(_ReturnAddress()) == Offsets::Functions::dwCalcPlayerView)
    {
        IClientEntity* pLocalEntity = NULL;

        float* m_LocalViewAngles = NULL;

        __asm

        {
            MOV pLocalEntity, ESI

            MOV m_LocalViewAngles, EBX

        }

        Vector viewPunch = pLocalEntity->localPlayerExclusive()->GetViewPunchAngle();
        Vector aimPunch = pLocalEntity->localPlayerExclusive()->GetAimPunchAngle();

        m_LocalViewAngles[0] -= (viewPunch[0] + (aimPunch[0] * 2 * 0.4499999f));
        m_LocalViewAngles[1] -= (viewPunch[1] + (aimPunch[1] * 2 * 0.4499999f));
        m_LocalViewAngles[2] -= (viewPunch[2] + (aimPunch[2] * 2 * 0.4499999f));
        return true;
    }

    return result;
}

// DrawModelExec for chams and shit
void __fastcall Hooked_DrawModelExecute(void* thisptr, int edx, void* ctx, void* state, const ModelRenderInfo_t &pInfo, matrix3x4* pCustomBoneToWorld)
{
    Color color;
    float flColor[3] = { 0.f };
    static IMaterial* CoveredLit = CreateMaterial(true);
    static IMaterial* OpenLit = CreateMaterial(false);
    static IMaterial* CoveredFlat = CreateMaterial(true, false);
    static IMaterial* OpenFlat = CreateMaterial(false, false);
    bool DontDraw = false;

    const char* ModelName = Interfaces::ModelInfo->GetModelName((model_t*)pInfo.pModel);
    IClientEntity* pModelEntity = (IClientEntity*)Interfaces::EntList->GetClientEntity(pInfo.entity_index);
    IClientEntity* pLocal = (IClientEntity*)Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());

    if (Menu::Window.VisualsTab.Active.GetState())
    {
        // Player Chams
        int ChamsStyle = Menu::Window.VisualsTab.OptionsChams.GetIndex();
        int HandsStyle = Menu::Window.VisualsTab.OtherNoHands.GetIndex();
        if (ChamsStyle != 0 && Menu::Window.VisualsTab.FiltersPlayers.GetState() && strstr(ModelName, "models/player"))
        {
            if (pLocal && (!Menu::Window.VisualsTab.FiltersEnemiesOnly.GetState() ||
                pModelEntity->GetTeamNum() != pLocal->GetTeamNum()))
            {
                IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
                IMaterial* open = ChamsStyle == 1 ? OpenLit : OpenFlat;

                IClientEntity* pModelEntity = (IClientEntity*)Interfaces::EntList->GetClientEntity(pInfo.entity_index);
                if (pModelEntity)
                {
                    IClientEntity* local = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
                    if (local)
                    {
                        if (pModelEntity->IsAlive() && pModelEntity->GetHealth() > 0 /*&& pModelEntity->GetTeamNum() != local->GetTeamNum()*/)
                        {
                            float alpha = 1.f;

                            if (pModelEntity->HasGunGameImmunity())
                                alpha = 0.5f;

                            if (pModelEntity->GetTeamNum() == 2)
                            {
                                flColor[0] = 240.f / 255.f;
                                flColor[1] = 30.f / 255.f;
                                flColor[2] = 35.f / 255.f;
                            }
                            else
                            {
                                flColor[0] = 63.f / 255.f;
                                flColor[1] = 72.f / 255.f;
                                flColor[2] = 205.f / 255.f;
                            }

                            Interfaces::RenderView->SetColorModulation(flColor);
                            Interfaces::RenderView->SetBlend(alpha);
                            Interfaces::ModelRender->ForcedMaterialOverride(covered);
                            oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);

                            if (pModelEntity->GetTeamNum() == 2)
                            {
                                flColor[0] = 247.f / 255.f;
                                flColor[1] = 180.f / 255.f;
                                flColor[2] = 20.f / 255.f;
                            }
                            else
                            {
                                flColor[0] = 32.f / 255.f;
                                flColor[1] = 180.f / 255.f;
                                flColor[2] = 57.f / 255.f;
                            }

                            Interfaces::RenderView->SetColorModulation(flColor);
                            Interfaces::RenderView->SetBlend(alpha);
                            Interfaces::ModelRender->ForcedMaterialOverride(open);
                        }
                        else
                        {
                            color.SetColor(255, 255, 255, 255);
                            ForceMaterial(color, open);
                        }
                    }
                }
            }
        }
        else if (HandsStyle != 0 && strstr(ModelName, "arms"))
        {
            if (HandsStyle == 1)
            {
                DontDraw = true;
            }
            else if (HandsStyle == 2)
            {
                Interfaces::RenderView->SetBlend(0.3);
            }
            else if (HandsStyle == 3)
            {
                IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
                IMaterial* open = ChamsStyle == 1 ? OpenLit : OpenFlat;
                if (pLocal)
                {
                    if (pLocal->IsAlive())
                    {
                        int alpha = pLocal->HasGunGameImmunity() ? 150 : 255;

                        if (pLocal->GetTeamNum() == 2)
                            color.SetColor(240, 30, 35, alpha);
                        else
                            color.SetColor(63, 72, 205, alpha);

                        ForceMaterial(color, covered);
                        oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);

                        if (pLocal->GetTeamNum() == 2)
                            color.SetColor(247, 180, 20, alpha);
                        else
                            color.SetColor(32, 180, 57, alpha);
                    }
                    else
                    {
                        color.SetColor(255, 255, 255, 255);
                    }

                    ForceMaterial(color, open);
                }
            }
            else
            {
                static int counter = 0;
                static float colors[3] = { 1.f, 0.f, 0.f };

                if (colors[counter] >= 1.0f)
                {
                    colors[counter] = 1.0f;
                    counter += 1;
                    if (counter > 2)
                        counter = 0;
                }
                else
                {
                    int prev = counter - 1;
                    if (prev < 0) prev = 2;
                    colors[prev] -= 0.05f;
                    colors[counter] += 0.05f;
                }

                Interfaces::RenderView->SetColorModulation(colors);
                Interfaces::RenderView->SetBlend(0.3);
                Interfaces::ModelRender->ForcedMaterialOverride(OpenLit);
            }
        }
        else if (ChamsStyle != 0 && Menu::Window.VisualsTab.FiltersWeapons.GetState() && strstr(ModelName, "_dropped.mdl"))
        {
            IMaterial* covered = ChamsStyle == 1 ? CoveredLit : CoveredFlat;
            color.SetColor(255, 255, 255, 255);
            ForceMaterial(color, covered);
        }
    }

    if (!DontDraw)
        oDrawModelExecute(thisptr, ctx, state, pInfo, pCustomBoneToWorld);
    Interfaces::ModelRender->ForcedMaterialOverride(NULL);
}

// ClientMode CreateMove
bool __fastcall CreateMoveClient_Hooked(void* self, int edx, float frametime, CUserCmd* pCmd)
{
    // Backup for safety
    Vector origView = pCmd->viewangles;
    Vector viewforward, viewright, viewup, aimforward, aimright, aimup;
    Vector qAimAngles;
    qAimAngles.Init(0.0f, pCmd->viewangles.y, 0.0f);
    AngleVectors(qAimAngles, &viewforward, &viewright, &viewup);

    // Do da hacks
    IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
    if (Interfaces::Engine->IsConnected() && Interfaces::Engine->IsInGame() && pLocal && pLocal->IsAlive())
        Hacks::MoveHacks(pCmd);

    //Movement Fix
    //GameUtils::CL_FixMove(pCmd, origView);
    qAimAngles.Init(0.0f, GetAutostrafeView().y, 0.0f);
    AngleVectors(qAimAngles, &viewforward, &viewright, &viewup);
    qAimAngles.Init(0.0f, pCmd->viewangles.y, 0.0f);
    AngleVectors(qAimAngles, &aimforward, &aimright, &aimup);
    Vector vForwardNorm; Normalize(viewforward, vForwardNorm);
    Vector vRightNorm; Normalize(viewright, vRightNorm);
    Vector vUpNorm; Normalize(viewup, vUpNorm);

    // Original shit for movement correction
    float forward = pCmd->forwardmove;
    float right = pCmd->sidemove;
    float up = pCmd->upmove;
    if (forward > 450) forward = 450;
    if (right > 450) right = 450;
    if (up > 450) up = 450;
    if (forward < -450) forward = -450;
    if (right < -450) right = -450;
    if (up < -450) up = -450;
    pCmd->forwardmove = DotProduct(forward * vForwardNorm, aimforward) + DotProduct(right * vRightNorm, aimforward) + DotProduct(up * vUpNorm, aimforward);
    pCmd->sidemove = DotProduct(forward * vForwardNorm, aimright) + DotProduct(right * vRightNorm, aimright) + DotProduct(up * vUpNorm, aimright);
    pCmd->upmove = DotProduct(forward * vForwardNorm, aimup) + DotProduct(right * vRightNorm, aimup) + DotProduct(up * vUpNorm, aimup);

    // Angle normalisation
    if (Menu::Window.VisualsTab.OtherSafeMode.GetState())
    {
        GameUtils::NormaliseViewAngle(pCmd->viewangles);

        if (pCmd->viewangles.z != 0.0f)
        {
            pCmd->viewangles.z = 0.00;
        }

        if (pCmd->viewangles.x < -89 || pCmd->viewangles.x > 89 || pCmd->viewangles.y < -180 || pCmd->viewangles.y > 180)
        {
            Utilities::Log("Having to re-normalise!");
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
            Beep(750, 800);
            if (pCmd->viewangles.x < -89 || pCmd->viewangles.x > 89 || pCmd->viewangles.y < -180 || pCmd->viewangles.y > 180)
            {
                pCmd->viewangles = origView;
                pCmd->sidemove = right;
                pCmd->forwardmove = forward;
            }
        }
    }

    return false;
}

/*void  __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage)
{
        oFrameStageNotify(curStage);

        if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
        {
                IClientEntity *pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
                if (Menu::Window.MiscTab.KnifeEnable.GetState() && pLocal)
                {
                        IClientEntity* WeaponEnt = Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
                        CBaseCombatWeapon* Weapon = (CBaseCombatWeapon*)WeaponEnt;
                        if (Weapon)
                        {
                                //Utilities::Log("NIGGA WE CLOSE!");
                                static bool LastItemWasKnife = false;
                                if (WeaponEnt->GetClientClass()->m_ClassID == (int)CSGOClassID::CKnife)
                                {
                                        *Weapon->FallbackStatTrak() = 1337;
                                        int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();
                                        if (Skin == 0) *Weapon->FallbackPaintKit() = 416;
                                        if (Skin == 1) *Weapon->FallbackPaintKit() = 415;
                                        if (Skin == 3) *Weapon->FallbackPaintKit() = 409;
                                        if (Skin == 4) *Weapon->FallbackPaintKit() = 0;
                                        *Weapon->FallbackWear() = 0.0001;

                                        *Weapon->m_AttributeManager()->m_Item()->ItemIDLow() = 7;
                                        int Model = Menu::Window.MiscTab.KnifeModel.GetIndex();
                                        *Weapon->m_AttributeManager()->m_Item()->ItemIDHigh() = (Model == 0) ? 507 : 500;
                                        *Weapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = (Model == 0) ? 507 : 500;

                                        if (GUI.GetKeyState(VK_END))
                                                ForceUpdate();
                                }
                        }
                }
        }
}*/


void __stdcall Hooked_FrameStageNotify(ClientFrameStage_t curStage)
{
    oFrameStageNotify(curStage);

    //Utilities::Log("plsplspls");

    if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
    {
        //Utilities::Log("APPLY SKIN APPLY SKIN");
        IClientEntity* pLocal = Interfaces::EntList->GetClientEntity(Interfaces::Engine->GetLocalPlayer());
        int iBayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_bayonet.mdl");
        int iButterfly = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_butterfly.mdl");
        int iFlip = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_flip.mdl");
        int iGunGame = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gg.mdl");
        int iGut = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_gut.mdl");
        int iKarambit = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_karam.mdl");
        int iM9Bayonet = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_m9_bay.mdl");
        int iHuntsman = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_tactical.mdl");

        int iFalchion = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_falchion_advanced.mdl");
        int iDagger = Interfaces::ModelInfo->GetModelIndex("models/weapons/v_knife_push.mdl");

        for (int i = Interfaces::EntList->GetHighestEntityIndex(); i >= 0; --i)
        {
            IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);

            if (pEntity)
            {
                ULONG hOwnerEntity = *(PULONG)((DWORD)pEntity + 0x148);

                IClientEntity* pOwner = Interfaces::EntList->GetClientEntityFromHandle((HANDLE)hOwnerEntity);

                if (pOwner)
                {
                    if (pOwner == pLocal)
                    {
                        std::string sWeapon = Interfaces::ModelInfo->GetModelName(pEntity->GetModel());

                        if (!(sWeapon.find("models/weapons", 0) != std::string::npos))
                                                        continue;

        if (sWeapon.find("c4_planted", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("thrown", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("smokegrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("flashbang", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("fraggrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("molotov", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("decoy", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("incendiarygrenade", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("ied", 0) != std::string::npos)
                                                        continue;

        if (sWeapon.find("w_eq_", 0) != std::string::npos)
                                                        continue;

        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)pEntity;

        ClientClass* pClass = Interfaces::Client->GetAllClasses();

        if (Menu::Window.MiscTab.KnifeEnable.GetState())
        {
            int Model = Menu::Window.MiscTab.KnifeModel.GetIndex();

            int M41S = Menu::Window.MiscTab.M41SSkin.GetIndex();
            int M4A4 = Menu::Window.MiscTab.M4A4Skin.GetIndex();
            int AK47 = Menu::Window.MiscTab.AK47Skin.GetIndex();
            int AWP = Menu::Window.MiscTab.AWPSkin.GetIndex();
            int Glock = Menu::Window.MiscTab.GLOCKSkin.GetIndex();
            int USPS = Menu::Window.MiscTab.USPSSkin.GetIndex();
            int Deagle = Menu::Window.MiscTab.DEAGLESkin.GetIndex();
            int Magnum = Menu::Window.MiscTab.DEAGLESkin.GetIndex();

            if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 26) // M41S
            {
                if (M41S == 0)
                {
                    *pWeapon->FallbackPaintKit() = 321;
                }
                else if (M41S == 1)
                {
                    *pWeapon->FallbackPaintKit() = 430;
                }
                else if (M41S == 2)
                {
                    *pWeapon->FallbackPaintKit() = 360;
                }
                else if (M41S == 3)
                {
                    *pWeapon->FallbackPaintKit() = 445;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 60) // M4A4
            {
                if (M4A4 == 0)
                {
                    *pWeapon->FallbackPaintKit() = 512;
                }
                else if (M4A4 == 1)
                {
                    *pWeapon->FallbackPaintKit() = 309;
                }
                else if (M4A4 == 2)
                {
                    *pWeapon->FallbackPaintKit() = 155;
                }
                else if (M4A4 == 3)
                {
                    *pWeapon->FallbackPaintKit() = 400;
                }
                else if (M4A4 == 4)
                {
                    *pWeapon->FallbackPaintKit() = 255;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 7) // AK47
            {
                if (AK47 == 0)
                {
                    *pWeapon->FallbackPaintKit() = 506;
                }
                else if (AK47 == 1)
                {
                    *pWeapon->FallbackPaintKit() = 474;
                }
                else if (AK47 == 2)
                {
                    *pWeapon->FallbackPaintKit() = 302;
                }
                else if (AK47 == 3)
                {
                    *pWeapon->FallbackPaintKit() = 180;
                }
                else if (AK47 == 4)
                {
                    *pWeapon->FallbackPaintKit() = 316;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 9) // AWP
            {
                if (AWP == 0)
                {
                    *pWeapon->FallbackPaintKit() = 475;
                }
                else if (AWP == 1)
                {
                    *pWeapon->FallbackPaintKit() = 279;
                }
                else if (AWP == 2)
                {
                    *pWeapon->FallbackPaintKit() = 344;
                }
                else if (AWP == 3)
                {
                    *pWeapon->FallbackPaintKit() = 51;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 4) // GLOCK
            {
                if (Glock == 0)
                {
                    *pWeapon->FallbackPaintKit() = 353;
                }
                else if (Glock == 1)
                {
                    *pWeapon->FallbackPaintKit() = 38;
                }
                else if (Glock == 2)
                {
                    *pWeapon->FallbackPaintKit() = 437;
                }
                else if (Glock == 3)
                {
                    *pWeapon->FallbackPaintKit() = 479;
                }
            }
            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 61) // USPS
            {
                if (USPS == 0)
                {
                    *pWeapon->FallbackPaintKit() = 504;
                }
                else if (USPS == 1)
                {
                    *pWeapon->FallbackPaintKit() = 339;
                }
                else if (USPS == 2)
                {
                    *pWeapon->FallbackPaintKit() = 313;
                }
                else if (USPS == 3)
                {
                    *pWeapon->FallbackPaintKit() = 290;
                }
            }

            else if (*pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() == 64) // USPS
            {
                if (Magnum == 0)
                {
                    *pWeapon->FallbackPaintKit() = 12;
                }
                else if (Magnum == 1)
                {
                    *pWeapon->FallbackPaintKit() = 522;
                }
                else if (Magnum == 2)
                {
                    *pWeapon->FallbackPaintKit() = 523;
                }
            }

            if (pEntity->GetClientClass()->m_ClassID == (int)CSGOClassID::CKnife)
            {
                if (Model == 0) // Karambit
                {
                    *pWeapon->ViewModelIndex() = iKarambit;
                    *pWeapon->WorldModelIndex() = iKarambit + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 507;

                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 1) // Bayonet
                {

                    *pWeapon->ViewModelIndex() = iBayonet;
                    *pWeapon->WorldModelIndex() = iBayonet + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 500;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 2) // Huntsman Knife
                {

                    *pWeapon->ViewModelIndex() = iHuntsman;
                    *pWeapon->WorldModelIndex() = iHuntsman + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 509;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 3) // Gut Knife
                {

                    *pWeapon->ViewModelIndex() = iGut;
                    *pWeapon->WorldModelIndex() = iGut + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 506;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 4) // Walmart Knife
                {

                    *pWeapon->ViewModelIndex() = iFalchion;
                    *pWeapon->WorldModelIndex() = iFalchion + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 512;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 5) // Shadow Daggers Knife
                {

                    *pWeapon->ViewModelIndex() = iDagger;
                    *pWeapon->WorldModelIndex() = iDagger + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 516;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 6) // Butterfly Knife
                {

                    *pWeapon->ViewModelIndex() = iButterfly;
                    *pWeapon->WorldModelIndex() = iButterfly + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 515;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 7) // Flip Knife
                {

                    *pWeapon->ViewModelIndex() = iFlip;
                    *pWeapon->WorldModelIndex() = iFlip + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 505;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
                else if (Model == 8) // M9 Bayonet
                {

                    *pWeapon->ViewModelIndex() = iM9Bayonet;
                    *pWeapon->WorldModelIndex() = iM9Bayonet + 1;
                    *pWeapon->m_AttributeManager()->m_Item()->ItemDefinitionIndex() = 508;
                    int Skin = Menu::Window.MiscTab.KnifeSkin.GetIndex();

                    if (Skin == 0)
                    {
                        *pWeapon->FallbackPaintKit() = 38; // Fade
                    }
                    else if (Skin == 1)
                    {
                        *pWeapon->FallbackPaintKit() = 410; // Damascus Steel
                    }
                    else if (Skin == 2)
                    {
                        *pWeapon->FallbackPaintKit() = 418; // Doppler Phase 1
                    }
                    else if (Skin == 3)
                    {
                        *pWeapon->FallbackPaintKit() = 419; // Doppler Phase 2
                    }
                    else if (Skin == 4)
                    {
                        *pWeapon->FallbackPaintKit() = 420; // Doppler Phase 3
                    }
                    else if (Skin == 5)
                    {
                        *pWeapon->FallbackPaintKit() = 421; // Doppler Phase 4
                    }
                    else if (Skin == 6)
                    {
                        *pWeapon->FallbackPaintKit() = 415; // Doppler (Ruby)
                    }
                    else if (Skin == 7)
                    {
                        *pWeapon->FallbackPaintKit() = 416; // Doppler (Sapphire)
                    }
                    else if (Skin == 8)
                    {
                        *pWeapon->FallbackPaintKit() = 417; // Doppler (Blackpearl)
                    }
                    else if (Skin == 9)
                    {
                        *pWeapon->FallbackPaintKit() = 413; // Marble Fade
                    }
                    else if (Skin == 10)
                    {
                        *pWeapon->FallbackPaintKit() = 409; // Tiger Tooth
                    }
                    else if (Skin == 11)
                    {
                        *pWeapon->FallbackPaintKit() = 98; // Ultraviolet
                    }
                    else if (Skin == 12)
                    {
                        *pWeapon->FallbackPaintKit() = 12; // Crimson Web
                    }
                    else if (Skin == 13)
                    {
                        *pWeapon->FallbackPaintKit() = 59; // Slaughter
                    }
                    else if (Skin == 14)
                    {
                        *pWeapon->FallbackPaintKit() = 40; // Night
                    }
                }
            }
            *pWeapon->OwnerXuidLow() = 0;
            *pWeapon->OwnerXuidHigh() = 0;
            *pWeapon->FallbackWear() = 0.001f;
            *pWeapon->m_AttributeManager()->m_Item()->ItemIDHigh() = 1;
        }
    }
}

                        }
                }
        }
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

// It's actually in DLLMain but w/e
extern bool DoUnload;

#include "Utilities.h"

namespace Hooks
{
    void Initialise();
    void UndoHooks();

        // VMT Managers
        extern Utilities::Memory::VMTManager VMTPanel; // Hooking drawing functions
        extern Utilities::Memory::VMTManager VMTClient; // Maybe CreateMove
        extern Utilities::Memory::VMTManager VMTClientMode; // CreateMove for functionality
        extern Utilities::Memory::VMTManager VMTModelRender; // DrawModelEx for chams
        extern Utilities::Memory::VMTManager VMTPrediction; // InPrediction for no vis recoil
};/*
Syn's AYYWAREFramework 2015
*/

#include "Interfaces.h"
#include "Utilities.h"
#include "Menu.h"

//SDK Specific Definitions
typedef void* (__cdecl* CreateInterface_t)(const char*, int*);
typedef void* (* CreateInterfaceFn)(const char* pName, int* pReturnCode);

//Some globals for later
CreateInterface_t EngineFactory = NULL; // These are used to store the individual
CreateInterface_t ClientFactory = NULL; //  CreateInterface functions for each game
CreateInterface_t VGUISurfaceFactory = NULL; //  dll that we need access to. Can call
CreateInterface_t VGUI2Factory = NULL; //  them to recieve pointers to game classes.
CreateInterface_t MatFactory = NULL;
CreateInterface_t PhysFactory = NULL;
CreateInterface_t StdFactory = NULL;

void Interfaces::Initialise()
{

    //Get function pointers to the CreateInterface function of each module
    EngineFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Engine, "CreateInterface");
    ClientFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Client, "CreateInterface");
    VGUI2Factory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VGUI2, "CreateInterface");
    VGUISurfaceFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VGUISurface, "CreateInterface");
    MatFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Material, "CreateInterface");
    PhysFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::VPhysics, "CreateInterface");
    StdFactory = (CreateInterface_t)GetProcAddress((HMODULE)Offsets::Modules::Stdlib, "CreateInterface");

    //Get the interface names regardless of their version number by scanning for each string
    char* CHLClientInterfaceName = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClient0");
    char* VGUI2PanelsInterfaceName = (char*)Utilities::Memory::FindTextPattern("vgui2.dll", "VGUI_Panel0");
    char* VGUISurfaceInterfaceName = (char*)Utilities::Memory::FindTextPattern("vguimatsurface.dll", "VGUI_Surface0");
    char* EntityListInterfaceName = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClientEntityList0");
    char* EngineDebugThingInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VDebugOverlay0");
    char* EngineClientInterfaceName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineClient0");
    char* ClientPredictionInterface = (char*)Utilities::Memory::FindTextPattern("client.dll", "VClientPrediction0");
    char* MatSystemInterfaceName = (char*)Utilities::Memory::FindTextPattern("materialsystem.dll", "VMaterialSystem0");
    char* EngineRenderViewInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineRenderView0");
    char* EngineModelRenderInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineModel0");
    char* EngineModelInfoInterface = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VModelInfoClient0");
    char* EngineTraceInterfaceName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "EngineTraceClient0");
    char* PhysPropsInterfaces = (char*)Utilities::Memory::FindTextPattern("client.dll", "VPhysicsSurfaceProps0");
    char* VEngineCvarName = (char*)Utilities::Memory::FindTextPattern("engine.dll", "VEngineCvar00");

    // Use the factory function pointers along with the interface versions to grab
    //  pointers to the interfaces
    Client = (IBaseClientDLL*)ClientFactory(CHLClientInterfaceName, NULL);
    Engine = (IVEngineClient*)EngineFactory(EngineClientInterfaceName, NULL);
    Panels = (IPanel*)VGUI2Factory(VGUI2PanelsInterfaceName, NULL);
    Surface = (ISurface*)VGUISurfaceFactory(VGUISurfaceInterfaceName, NULL);
    EntList = (IClientEntityList*)ClientFactory(EntityListInterfaceName, NULL);
    DebugOverlay = (IVDebugOverlay*)EngineFactory(EngineDebugThingInterface, NULL);
    Prediction = (DWORD*)ClientFactory(ClientPredictionInterface, NULL);
    MaterialSystem = (CMaterialSystem*)MatFactory(MatSystemInterfaceName, NULL);
    RenderView = (CVRenderView*)EngineFactory(EngineRenderViewInterface, NULL);
    ModelRender = (IVModelRender*)EngineFactory(EngineModelRenderInterface, NULL);
    ModelInfo = (CModelInfo*)EngineFactory(EngineModelInfoInterface, NULL);
    Trace = (IEngineTrace*)EngineFactory(EngineTraceInterfaceName, NULL);
    PhysProps = (IPhysicsSurfaceProps*)PhysFactory(PhysPropsInterfaces, NULL);
    CVar = (ICVar*)StdFactory(VEngineCvarName, NULL);

    // Get ClientMode Pointer
    DWORD* ppClientMode;
    ppClientMode = nullptr; // before "scripts/vgui_screens.txt"
    DWORD p = Utilities::Memory::FindPattern("client.dll", (BYTE*)"\xC7\x05\x00\x00\x00\x00\x00\x00\x00\x00\xA8\x01\x75\x1A\x83\xC8\x01\xA3\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x68\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x83\xC4\x04\xA1\x00\x00\x00\x00\xB9\x00\x00\x00\x00\x56", "xx????????xxxxxxxx????x????x????x????xxxx????x????x");
    if (p)
    {
        ppClientMode = **(DWORD***)(p + 2);
        ClientMode = ppClientMode;
    }

    // Search through the first entry of the Client VTable
    // The initializer contains a pointer to the 'GlobalsVariables' Table
    PDWORD pdwClient = (PDWORD) * (PDWORD)Client;
    DWORD dwInitAddr = (DWORD)(pdwClient[0]);
    for (DWORD dwIter = 0; dwIter <= 0xFF; dwIter++)
    {
        if (*(PBYTE)(dwInitAddr + dwIter - 1) == 0x08 && *(PBYTE)(dwInitAddr + dwIter) == 0xA3)
        {
            Globals = (CGlobalVarsBase*)*(PDWORD) * (PDWORD)(dwInitAddr + dwIter + 1);
            break;
        }
    }
    Utilities::Log("Interfaces Readyz");
}

// Namespace to contain all the valve interfaces
namespace Interfaces
{
    IBaseClientDLL* Client;
    IVEngineClient* Engine;
    IPanel* Panels;
    IClientEntityList* EntList;
    ISurface* Surface;
    IVDebugOverlay* DebugOverlay;
    DWORD* ClientMode;
    CGlobalVarsBase* Globals;
    DWORD* Prediction;
    CMaterialSystem* MaterialSystem;
    CVRenderView* RenderView;
    IVModelRender* ModelRender;
    CModelInfo* ModelInfo;
    IEngineTrace* Trace;
    IPhysicsSurfaceProps* PhysProps;
    ICVar* CVar;
};/*
Syn's AYYWAREFramework
*/

#pragma once

// Includes
#include "SDK.h"

// Namespace to contain all the valve interfaces
namespace Interfaces
{
    // Gets handles to all the interfaces needed
    void Initialise();

        extern IBaseClientDLL* Client;
        extern IVEngineClient* Engine;
        extern IPanel* Panels;
        extern IClientEntityList* EntList;
        extern ISurface* Surface;
        extern IVDebugOverlay* DebugOverlay;
        extern DWORD * ClientMode;
        extern CGlobalVarsBase * Globals;
        extern DWORD * Prediction;
        extern CMaterialSystem* MaterialSystem;
        extern CVRenderView* RenderView;
        extern IVModelRender* ModelRender;
        extern CModelInfo* ModelInfo;
        extern IEngineTrace* Trace;
        extern IPhysicsSurfaceProps* PhysProps;
        exte
#include "LegitBot.h"
#include "RenderManager.h"

void CLegitBot::Init()
{
        IsLocked = false;
        TargetID = -1;
}

void CLegitBot::Draw()
{
        
}

void CLegitBot::Move(CUserCmd *pCmd)
{
        // Master switch
        if (!Menu::Window.LegitBotTab.Active.GetState())
                return;

        // Aimbot
        if (Menu::Window.LegitBotTab.AimbotEnable.GetState())
                DoAimbot(pCmd);

        // Triggerbot / Trigger Delay
        static size_t CustomDelay = 0;
        if (Menu::Window.LegitBotTab.TriggerEnable.GetState() && (!Menu::Window.LegitBotTab.TriggerKeyPress.GetState() || GUI.GetKeyState(Menu::Window.LegitBotTab.TriggerKeyBind.GetKey())))
        {

                if (Menu::Window.LegitBotTab.TriggerDelay.GetValue() > 1)
                {
                        if (GetTickCount() > CustomDelay)
                        {

                                DoTrigger(pCmd);
                                CustomDelay = GetTickCount() + Menu::Window.LegitBotTab.TriggerDelay.GetValue();
                        }
                }
                else
                        DoTrigger(pCmd);
        }
}

void CLegitBot::SyncWeaponSettings()
{
        IClientEntity* pLocal = hackManager.pLocal();
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());

        if (!pWeapon)
                return;

        if (GameUtils::IsPistol(pWeapon))
        {
                Speed = Menu::Window.LegitBotTab.WeaponPistSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponPistFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponPistRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponPistHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
        else if (GameUtils::IsSniper(pWeapon))
        {
                Speed = Menu::Window.LegitBotTab.WeaponSnipSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponSnipFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponSnipRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponSnipHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
        else
        {
                Speed = Menu::Window.LegitBotTab.WeaponMainSpeed.GetValue();
                FoV = Menu::Window.LegitBotTab.WeaponMainFoV.GetValue();
                RecoilControl = Menu::Window.LegitBotTab.WeaponMainRecoil.GetState();

                switch (Menu::Window.LegitBotTab.WeaponMainHitbox.GetIndex())
                {
                case 0:
                        HitBox = ((int)CSGOHitboxID::Head);
                        break;
                case 1:
                        HitBox = ((int)CSGOHitboxID::Neck);
                        break;
                case 2:
                        HitBox = ((int)CSGOHitboxID::Chest);
                        break;
                case 3:
                        HitBox = ((int)CSGOHitboxID::Stomach);
                        break;
                }
        }
}

// Functionality
void CLegitBot::DoAimbot(CUserCmd *pCmd)
{
        IClientEntity* pTarget = nullptr;
        IClientEntity* pLocal = hackManager.pLocal();
        bool FindNewTarget = true;
        //IsLocked = false;

        // Don't aimbot with the knife..
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
        if (pWeapon)
        {
                if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
                {
                        //TargetID = 0;
                        //pTarget = nullptr;
                        //HitBox = -1;
                        return;
                }
                SyncWeaponSettings();
                
        }
        else
                return;

        // Make sure we have a good target
        if (IsLocked && TargetID >= 0 && HitBox >= 0)
        {
                pTarget = Interfaces::EntList->GetClientEntity(TargetID);
                if (pTarget  && TargetMeetsRequirements(pTarget))
                {
                        SyncWeaponSettings();
                        if (HitBox >= 0)
                        {
                                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                                Vector View; Interfaces::Engine->GetViewAngles(View);
                                View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;
                                float nFoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                                if (nFoV < FoV)
                                        FindNewTarget = false;
                        }
                }
        }

        // Find a new target, apparently we need to
        if (FindNewTarget)
        {
                TargetID = 0;
                pTarget = nullptr;
                HitBox = -1;

                TargetID = GetTargetCrosshair();

                // Memes
                if (TargetID >= 0)
                {
                        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
                }
                else
                {
                        pTarget = nullptr;
                        HitBox = -1;
                }
        }

        SyncWeaponSettings();

        // If we finally have a good target
        if (TargetID >= 0 && pTarget)
        {
                //HitBox = (int)CSGOHitboxID::Head;//
                SyncWeaponSettings();

                // Key
                if (Menu::Window.LegitBotTab.AimbotKeyPress.GetState())
                {
                        int Key = Menu::Window.LegitBotTab.AimbotKeyBind.GetKey();
                        if (Key >= 0 && !GUI.GetKeyState(Key))
                        {
                                TargetID = -1;
                                pTarget = nullptr;
                                HitBox = -1;
                                return;
                        }
                }

                Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

                if (AimAtPoint(pLocal, AimPoint, pCmd))
                {
                        //IsLocked = true;
                        if (Menu::Window.LegitBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
                        {
                                pCmd->buttons |= IN_ATTACK;
                        }
                }
        }

        // Auto Pistol
        static bool WasFiring = false;
        CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
        if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
        {
                if (pCmd->buttons & IN_ATTACK)
                {
                        if (WasFiring)
                        {
                                pCmd->buttons &= ~IN_ATTACK;
                        }
                }

                WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
        }
}

bool TargetMeetsTriggerRequirements(IClientEntity* pEntity)
{
        // Is a valid player
        if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
        {
                // Entity Type checks
                ClientClass *pClientClass = pEntity->GetClientClass();
                player_info_t pinfo;
                if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
                {
                        // Team Check
                        if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
                        {
                                // Spawn Check
                                if (!pEntity->HasGunGameImmunity())
                                {
                                        return true;
                                }
                        }
                }
        }

        // They must have failed a requirement
        return false;
}

void CLegitBot::DoTrigger(CUserCmd *pCmd)
{
        IClientEntity* pLocal = hackManager.pLocal();

        // Don't triggerbot with the knife..
        CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
        if (pWeapon)
        {
                if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
                {
                        return;
                }
        }
        else
                return;

        // Triggerbot
        // Get the view with the recoil
        Vector ViewAngles;
        Interfaces::Engine->GetViewAngles(ViewAngles);
        ViewAngles += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

        // Build a ray going fowards at that angle
        Vector fowardVec;
        AngleVectors(ViewAngles, &fowardVec);
        fowardVec *= 10000;

        // Get ray start / end
        Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
        Vector end = start + fowardVec, endScreen;

        trace_t Trace;
        UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

        if (Trace.m_pEnt && 0 < Trace.hitgroup <= 7)
        {
                if (TargetMeetsTriggerRequirements(Trace.m_pEnt))
                {
                        pCmd->buttons |= IN_ATTACK;
                }
        }

        // Auto Pistol
        static bool WasFiring = false;
        CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
        if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
        {
                if (pCmd->buttons & IN_ATTACK)
                {
                        if (WasFiring)
                        {
                                pCmd->buttons &= ~IN_ATTACK;
                        }
                }

                WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
        }
}

bool CLegitBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
        // Is a valid player
        if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
        {
                // Entity Type checks
                ClientClass *pClientClass = pEntity->GetClientClass();
                player_info_t pinfo;
                if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
                {
                        // Team Check
                        if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
                        {
                                // Spawn Check
                                if (!pEntity->HasGunGameImmunity() && GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBox))
                                {
                                        return true;
                                }
                        }
                }
        }

        // They must have failed a requirement
        return false;
}

float CLegitBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
        // Anything past 180 degrees is just going to wrap around
        CONST FLOAT MaxDegrees = 180.0f;

        // Get local angles
        Vector Angles = View;

        // Get local view / eye position
        Vector Origin = ViewOffSet;

        // Create and intiialize vectors for calculations below
        Vector Delta(0, 0, 0);
        //Vector Origin(0, 0, 0);
        Vector Forward(0, 0, 0);

        // Convert angles to normalized directional forward vector
        AngleVectors(Angles, &Forward);
        Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
        // Get delta vector between our local eye position and passed vector
        VectorSubtract(AimPos, Origin, Delta);
        //Delta = AimPos - Origin;

        // Normalize our delta vector
        Normalize(Delta, Delta);

        // Get dot product between delta position and directional forward vectors
        FLOAT DotProduct = Forward.Dot(Delta);

        // Time to calculate the field of view
        return (acos(DotProduct) * (MaxDegrees / PI));
}

int CLegitBot::GetTargetCrosshair()
{
        // Target selection
        SyncWeaponSettings();
        int target = -1;
        float minFoV = FoV;

        IClientEntity* pLocal = hackManager.pLocal();
        Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
        Vector View; Interfaces::Engine->GetViewAngles(View);
        View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

        for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
        {
                IClientEntity *pEntity = Interfaces::EntList->GetClientEntity(i);
                if (TargetMeetsRequirements(pEntity))
                {
                        int NewHitBox = HitBox;
                        if (NewHitBox >= 0)
                        {
                                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                                if (fov < minFoV)
                                {
                                        minFoV = fov;
                                        target = i;
                                }
                        }
                }
        }

        return target;
}

bool CLegitBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd *pCmd)
{
        // Get the full angles
        if (point.Length() == 0) return false;

        Vector angles;
        Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

        CalcAngle(src, point, angles);
        GameUtils::NormaliseViewAngle(angles);

        if (angles[0] != angles[0] || angles[1] != angles[1])
        {
                return false;
        }

        if (RecoilControl)
        {
                Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
                if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
                {
                        angles -= AimPunch * 2;
                        GameUtils::NormaliseViewAngle(angles);
                }
        }

        IsLocked = true;
        //-----------------------------------------------

        Vector shit = angles - pCmd->viewangles;
        bool v = false;

        if (shit.Length() > Speed)
        {
                Normalize(shit, shit);
                shit *= Speed;
        }
        else
        {
                v = true;
        }

        pCmd->viewangles += shit;
        Interfaces::Engine->SetViewAngles(pCmd->viewangles);

        return v;
}
rn ICVar * CVar;
};
#include "LegitBot.h"
#include "RenderManager.h"

void CLegitBot::Init()
{
    IsLocked = false;
    TargetID = -1;
}

void CLegitBot::Draw()
{

}

void CLegitBot::Move(CUserCmd* pCmd)
{
    // Master switch
    if (!Menu::Window.LegitBotTab.Active.GetState())
        return;

    // Aimbot
    if (Menu::Window.LegitBotTab.AimbotEnable.GetState())
        DoAimbot(pCmd);

    // Triggerbot / Trigger Delay
    static size_t CustomDelay = 0;
    if (Menu::Window.LegitBotTab.TriggerEnable.GetState() && (!Menu::Window.LegitBotTab.TriggerKeyPress.GetState() || GUI.GetKeyState(Menu::Window.LegitBotTab.TriggerKeyBind.GetKey())))
    {

        if (Menu::Window.LegitBotTab.TriggerDelay.GetValue() > 1)
        {
            if (GetTickCount() > CustomDelay)
            {

                DoTrigger(pCmd);
                CustomDelay = GetTickCount() + Menu::Window.LegitBotTab.TriggerDelay.GetValue();
            }
        }
        else
            DoTrigger(pCmd);
    }
}

void CLegitBot::SyncWeaponSettings()
{
    IClientEntity* pLocal = hackManager.pLocal();
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());

    if (!pWeapon)
        return;

    if (GameUtils::IsPistol(pWeapon))
    {
        Speed = Menu::Window.LegitBotTab.WeaponPistSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponPistFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponPistRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponPistHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else if (GameUtils::IsSniper(pWeapon))
    {
        Speed = Menu::Window.LegitBotTab.WeaponSnipSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponSnipFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponSnipRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponSnipHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else
    {
        Speed = Menu::Window.LegitBotTab.WeaponMainSpeed.GetValue();
        FoV = Menu::Window.LegitBotTab.WeaponMainFoV.GetValue();
        RecoilControl = Menu::Window.LegitBotTab.WeaponMainRecoil.GetState();

        switch (Menu::Window.LegitBotTab.WeaponMainHitbox.GetIndex())
        {
            case 0:
                HitBox = ((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBox = ((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBox = ((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBox = ((int)CSGOHitboxID::Stomach);
                break;
        }
    }
}

// Functionality
void CLegitBot::DoAimbot(CUserCmd* pCmd)
{
    IClientEntity* pTarget = nullptr;
    IClientEntity* pLocal = hackManager.pLocal();
    bool FindNewTarget = true;
    //IsLocked = false;

    // Don't aimbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            //TargetID = 0;
            //pTarget = nullptr;
            //HitBox = -1;
            return;
        }
        SyncWeaponSettings();

    }
    else
        return;

    // Make sure we have a good target
    if (IsLocked && TargetID >= 0 && HitBox >= 0)
    {
        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        if (pTarget && TargetMeetsRequirements(pTarget))
        {
            SyncWeaponSettings();
            if (HitBox >= 0)
            {
                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                Vector View; Interfaces::Engine->GetViewAngles(View);
                View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;
                float nFoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                if (nFoV < FoV)
                    FindNewTarget = false;
            }
        }
    }

    // Find a new target, apparently we need to
    if (FindNewTarget)
    {
        TargetID = 0;
        pTarget = nullptr;
        HitBox = -1;

        TargetID = GetTargetCrosshair();

        // Memes
        if (TargetID >= 0)
        {
            pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        }
        else
        {
            pTarget = nullptr;
            HitBox = -1;
        }
    }

    SyncWeaponSettings();

    // If we finally have a good target
    if (TargetID >= 0 && pTarget)
    {
        //HitBox = (int)CSGOHitboxID::Head;//
        SyncWeaponSettings();

        // Key
        if (Menu::Window.LegitBotTab.AimbotKeyPress.GetState())
        {
            int Key = Menu::Window.LegitBotTab.AimbotKeyBind.GetKey();
            if (Key >= 0 && !GUI.GetKeyState(Key))
            {
                TargetID = -1;
                pTarget = nullptr;
                HitBox = -1;
                return;
            }
        }

        Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

        if (AimAtPoint(pLocal, AimPoint, pCmd))
        {
            //IsLocked = true;
            if (Menu::Window.LegitBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
            {
                pCmd->buttons |= IN_ATTACK;
            }
        }
    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }
}

bool TargetMeetsTriggerRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity())
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

void CLegitBot::DoTrigger(CUserCmd* pCmd)
{
    IClientEntity* pLocal = hackManager.pLocal();

    // Don't triggerbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            return;
        }
    }
    else
        return;

    // Triggerbot
    // Get the view with the recoil
    Vector ViewAngles;
    Interfaces::Engine->GetViewAngles(ViewAngles);
    ViewAngles += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

    // Build a ray going fowards at that angle
    Vector fowardVec;
    AngleVectors(ViewAngles, &fowardVec);
    fowardVec *= 10000;

    // Get ray start / end
    Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector end = start + fowardVec, endScreen;

    trace_t Trace;
    UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

    if (Trace.m_pEnt && 0 < Trace.hitgroup <= 7)
    {
        if (TargetMeetsTriggerRequirements(Trace.m_pEnt))
        {
            pCmd->buttons |= IN_ATTACK;
        }
    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.LegitBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }
}

bool CLegitBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.LegitBotTab.AimbotFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity() && GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBox))
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

float CLegitBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
    // Anything past 180 degrees is just going to wrap around
    CONST FLOAT MaxDegrees = 180.0f;

    // Get local angles
    Vector Angles = View;

    // Get local view / eye position
    Vector Origin = ViewOffSet;

    // Create and intiialize vectors for calculations below
    Vector Delta(0, 0, 0);
    //Vector Origin(0, 0, 0);
    Vector Forward(0, 0, 0);

    // Convert angles to normalized directional forward vector
    AngleVectors(Angles, &Forward);
    Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
    // Get delta vector between our local eye position and passed vector
    VectorSubtract(AimPos, Origin, Delta);
    //Delta = AimPos - Origin;

    // Normalize our delta vector
    Normalize(Delta, Delta);

    // Get dot product between delta position and directional forward vectors
    FLOAT DotProduct = Forward.Dot(Delta);

    // Time to calculate the field of view
    return (acos(DotProduct) * (MaxDegrees / PI));
}

int CLegitBot::GetTargetCrosshair()
{
    // Target selection
    SyncWeaponSettings();
    int target = -1;
    float minFoV = FoV;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);
    View += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitBox;
            if (NewHitBox >= 0)
            {
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (fov < minFoV)
                {
                    minFoV = fov;
                    target = i;
                }
            }
        }
    }

    return target;
}

bool CLegitBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd)
{
    // Get the full angles
    if (point.Length() == 0) return false;

    Vector angles;
    Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

    CalcAngle(src, point, angles);
    GameUtils::NormaliseViewAngle(angles);

    if (angles[0] != angles[0] || angles[1] != angles[1])
    {
        return false;
    }

    if (RecoilControl)
    {
        Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
        if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
        {
            angles -= AimPunch * 2;
            GameUtils::NormaliseViewAngle(angles);
        }
    }

    IsLocked = true;
    //-----------------------------------------------

    Vector shit = angles - pCmd->viewangles;
    bool v = false;

    if (shit.Length() > Speed)
    {
        Normalize(shit, shit);
        shit *= Speed;
    }
    else
    {
        v = true;
    }

    pCmd->viewangles += shit;
    Interfaces::Engine->SetViewAngles(pCmd->viewangles);

    return v;
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CLegitBot : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        // Targetting
        int GetTargetCrosshair();
bool TargetMeetsRequirements(IClientEntity* pEntity);
float FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int HitBox);
bool AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd);

void SyncWeaponSettings();

// Functionality
void DoAimbot(CUserCmd* pCmd);
void DoTrigger(CUserCmd* pCmd);

// Aimbot
bool IsLocked;
int TargetID;
int HitBox;
Vector AimPoint;

float Speed;
float FoV;
bool RecoilControl;

};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "MiscClasses.h"
#include "Vector2D.h"


class IMaterial
{
    public:
        const char* GetName()
        {

        typedef const char*(__thiscall * oGetName)(PVOID);
                return call_vfunc(this, Offsets::VMT::Material_GetName)(this);
        }

void SetMaterialVarFlag(MaterialVarFlags_t flag, bool value)
{
    typedef void(__thiscall * oSetMatFlag)(PVOID, MaterialVarFlags_t, bool);
    return call_vfunc(this, Offsets::VMT::Material_SetMaterialVarFlag)(this, flag, value);
}

bool GetMaterialVarFlag(MaterialVarFlags_t flag)
{
    typedef bool(__thiscall * oGetMatFlag)(PVOID, MaterialVarFlags_t);
    return call_vfunc(this, Offsets::VMT::Material_GetMaterialVarFlag)(this, flag);
}

void AlphaModulate(float a)
{
    typedef void(__thiscall * oAlphaModulate)(PVOID, float);
    return call_vfunc(this, Offsets::VMT::Material_AlphaModulate)(this, a);
}

void ColorModulate(float r, float g, float b)
{
    typedef void(__thiscall * oColorModulate)(PVOID, float, float, float);
    return call_vfunc(this, Offsets::VMT::Material_ColorModulate)(this, r, g, b);
}

void IncrementReferenceCount(void)
{
    typedef void(__thiscall * oIncrementReferenceCount)(PVOID);
    return call_vfunc(this, Offsets::VMT::Material_IncrementReferenceCount)(this);
}
};

class CMaterialSystem
{
    public:
        IMaterial* FindMaterial(char const* pMaterialName, const char* pTextureGroupName, bool complain = true, const char* pComplainPrefix = NULL)
        {

        typedef IMaterial*(__thiscall* oFindMaterial)(PVOID, char const*, char const*, bool, char const*);
                return call_vfunc(this, Offsets::VMT::MaterialSystem_FindMaterial)(this, pMaterialName, pTextureGroupName, complain, pComplainPrefix);
        }

IMaterial* CreateMaterial(const char* pMaterialName, KeyValues* pVMTKeyValues)
{
    typedef IMaterial*(__thiscall * oCreateMaterial)(PVOID, const char*, KeyValues*);
    return call_vfunc(this, Offsets::VMT::MaterialSystem_CreateMaterial)(this, pMaterialName, pVMTKeyValues);
}
};

class IVModelRender
{
    public:
        void ForcedMaterialOverride(IMaterial* material, OverrideType_t type = OVERRIDE_NORMAL, int idk = NULL)
    {
        typedef void(__thiscall * Fn)(void*, IMaterial*, OverrideType_t, int);
        return call_vfunc(this, Offsets::VMT::ModelRender_ForcedMaterialOverride)(this, material, type, idk);
    }

};

class CModelInfo
{
    public:
        int GetModelIndex(const char* name)
        {

        typedef int (__thiscall* oGetModelName)(PVOID, const char*);
                return call_vfunc(this, 2)(this, name);
        }
const char* GetModelName(const model_t * mod)
        {
                typedef const char*(__thiscall * oGetModelName)(PVOID, const model_t *);
                return call_vfunc(this, Offsets::VMT::ModelInfo_GetModelName)(this, mod);
}

studiohdr_t* GetStudiomodel(const model_t* mod)
{
    typedef studiohdr_t *(__stdcall * oGetStudiomodel)(const model_t*);
    return call_vfunc(this, Offsets::VMT::ModelInfo_GetStudiomodel)(mod);
}
};

class CVRenderView
{
    public:
        void SetBlend(float alpha)
    {
        typedef void(__thiscall * oDrawModelExecute)(PVOID, float);
        return call_vfunc(this, Offsets::VMT::RenderView_SetBlend)(this, alpha);
    }

    void SetColorModulation(float const* colors)
        {

        typedef void(__thiscall* oDrawModelExecute)(PVOID, float const*);
                return call_vfunc(this, Offsets::VMT::RenderView_SetColorModulation)(this, colors);
        }
};#include "MathFunctions.h"

void AngleVectors(const Vector &angles, Vector* forward)
{
    Assert(s_bMathlibInitialized);
    Assert(forward);

    float sp, sy, cp, cy;

    sy = sin(DEG2RAD(angles[1]));
    cy = cos(DEG2RAD(angles[1]));

    sp = sin(DEG2RAD(angles[0]));
    cp = cos(DEG2RAD(angles[0]));

    forward->x = cp * cy;
    forward->y = cp * sy;
    forward->z = -sp;
}

void VectorTransform(const Vector in1, float in2[3][4], Vector &out)
{
        out[0] = DotProduct(in1, Vector(in2[0][0], in2[0][1], in2[0][2])) + in2[0][3];
        out[1] = DotProduct(in1, Vector(in2[1][0], in2[1][1], in2[1][2])) + in2[1][3];
        out[2] = DotProduct(in1, Vector(in2[2][0], in2[2][1], in2[2][2])) + in2[2][3];
}

void SinCos(float a, float* s, float* c)
{
    *s = sin(a);
    *c = cos(a);
}

void VectorAngles(Vector forward, Vector &angles)
{
    float tmp, yaw, pitch;

    if (forward[2] == 0 && forward[0] == 0)
    {
        yaw = 0;

        if (forward[2] > 0)
            pitch = 90;
        else
            pitch = 270;
    }
    else
    {
        yaw = (atan2(forward[1], forward[0]) * 180 / PI);

        if (yaw < 0)
            yaw += 360;

        tmp = sqrt(forward[0] * forward[0] + forward[1] * forward[1]);
        pitch = (atan2(-forward[2], tmp) * 180 / PI);

        if (pitch < 0)
            pitch += 360;
    }

    if (pitch > 180)
        pitch -= 360;
    else if (pitch < -180)
        pitch += 360;

    if (yaw > 180)
        yaw -= 360;
    else if (yaw < -180)
        yaw += 360;

    if (pitch > 89)
        pitch = 89;
    else if (pitch < -89)
        pitch = -89;

    if (yaw > 180)
        yaw = 180;
    else if (yaw < -180)
        yaw = -180;

    angles[0] = pitch;
    angles[1] = yaw;
    angles[2] = 0;
}

void AngleVectors(const Vector &angles, Vector* forward, Vector* right, Vector* up)
{
    float sr, sp, sy, cr, cp, cy;

    SinCos(DEG2RAD(angles[1]), &sy, &cy);
    SinCos(DEG2RAD(angles[0]), &sp, &cp);
    SinCos(DEG2RAD(angles[2]), &sr, &cr);

    if (forward)
    {
        forward->x = cp * cy;
        forward->y = cp * sy;
        forward->z = -sp;
    }

    if (right)
    {
        right->x = (-1 * sr * sp * cy + -1 * cr * -sy);
        right->y = (-1 * sr * sp * sy + -1 * cr * cy);
        right->z = -1 * sr * cp;
    }

    if (up)
    {
        up->x = (cr * sp * cy + -sr * -sy);
        up->y = (cr * sp * sy + -sr * cy);
        up->z = cr * cp;
    }
}

void Normalize(Vector &vIn, Vector &vOut)
{
    float flLen = vIn.Length();
    if (flLen == 0)
    {
        vOut.Init(0, 0, 1);
        return;
    }
    flLen = 1 / flLen;
    vOut.Init(vIn.x * flLen, vIn.y * flLen, vIn.z * flLen);
}


void CalcAngle(Vector src, Vector dst, Vector &angles)
{
    Vector delta = src - dst;
    double hyp = delta.Length2D();
    angles.y = (atan(delta.y / delta.x) * 57.295779513082f);
    angles.x = (atan(delta.z / hyp) * 57.295779513082f);
    angles[2] = 0.00;

    if (delta.x >= 0.0)
        angles.y += 180.0f;
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Vector.h"

#include 

#define PI 3.14159265358979323846f
#define DEG2RAD( x ) ( ( float )( x ) * ( float )( ( float )( PI ) / 180.0f ) )
#define RAD2DEG( x ) ( ( float )( x ) * ( float )( 180.0f / ( float )( PI ) ) )
#define RADPI 57.295779513082f

void AngleVectors(const Vector &angles, Vector* forward);
void VectorTransform(const Vector in1, float in2[3][4], Vector &out);
void SinCos(float a, float* s, float* c);
void VectorAngles(Vector forward, Vector &angles);
void AngleVectors(const Vector &angles, Vector* forward, Vector* right, Vector* up);
void Normalize(Vector &vIn, Vector &vOut);
void CalcAngle(Vector src, Vector dst, Vector &angles);
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "GUI.h"
#include "Controls.h"

class CRageBotTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Aimbot Settings
CGroupBox AimbotGroup;
CCheckBox AimbotEnable;
CCheckBox AimbotAutoFire;
CSlider AimbotFov;
CCheckBox AimbotSilentAim;
CCheckBox AimbotPSilent;
CCheckBox AimbotAutoPistol;
CCheckBox AimbotAimStep;
CCheckBox AimbotKeyPress;
CKeyBind AimbotKeyBind;
CCheckBox AimbotChicken;

// Target Selection Settings
CGroupBox TargetGroup;
CComboBox TargetSelection;
CCheckBox TargetFriendlyFire;
CComboBox TargetHitbox;
CComboBox TargetHitscan;

// Accuracy Settings
CGroupBox AccuracyGroup;
CCheckBox AccuracySpread;
CCheckBox AccuracyRecoil;
CCheckBox AccuracyAutoWall;
CSlider AccuracyMinimumDamage;
CCheckBox AccuracyAutoStop;
CCheckBox AccuracyAutoCrouch;
CCheckBox AccuracyAutoScope;
CCheckBox AccuracySpreadLimit;
CSlider AccuracyMinimumSpread;
CCheckBox AccuracyAngleFix;


// Anti-Aim Settings
CGroupBox AntiAimGroup;
CCheckBox AntiAimEnable;
CComboBox AntiAimPitch;
CComboBox AntiAimYaw;
};

class CLegitBotTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Aimbot Settings
CGroupBox AimbotGroup;
CCheckBox AimbotEnable;
CCheckBox AimbotAutoFire;
CCheckBox AimbotFriendlyFire;
CCheckBox AimbotKeyPress;
CKeyBind AimbotKeyBind;
CCheckBox AimbotAutoPistol;

// Main
CGroupBox TriggerGroup;
CCheckBox TriggerEnable;
CCheckBox TriggerKeyPress;
CKeyBind TriggerKeyBind;
CSlider TriggerDelay;

// Main
CGroupBox WeaponMainGroup;
CSlider WeaponMainSpeed;
CSlider WeaponMainFoV;
CCheckBox WeaponMainRecoil;
CComboBox WeaponMainHitbox;

// Pistol
CGroupBox WeaponPistGroup;
CSlider WeaponPistSpeed;
CSlider WeaponPistFoV;
CCheckBox WeaponPistRecoil;
CComboBox WeaponPistHitbox;

// Sniper
CGroupBox WeaponSnipGroup;
CSlider WeaponSnipSpeed;
CSlider WeaponSnipFoV;
CCheckBox WeaponSnipRecoil;
CComboBox WeaponSnipHitbox;

};

class CVisualTab : public CTab
{
public:
        void Setup();

// Master Switch
CLabel ActiveLabel;
CCheckBox Active;

// Options Settings
CGroupBox OptionsGroup;
CCheckBox OptionsBox;
CCheckBox OptionsName;
CCheckBox OptionsHealth;
CCheckBox OptionsWeapon;
CCheckBox OptionsInfo;
CComboBox OptionsChams;
CCheckBox OptionsSkeleton;
CCheckBox OptionsAimSpot;
CCheckBox OptionsCompRank;

// Filters Settings
CGroupBox FiltersGroup;
CCheckBox FiltersAll;
CCheckBox FiltersPlayers;
CCheckBox FiltersEnemiesOnly;
CCheckBox FiltersWeapons;
CCheckBox FiltersChickens;
CCheckBox FiltersC4;

// Other Settings
CGroupBox OtherGroup;
CCheckBox OtherCrosshair;
CComboBox OtherRecoilCrosshair;
CCheckBox OtherRadar;
CCheckBox OtherNoVisualRecoil;
CCheckBox OtherNoSky;
CCheckBox OtherNoFlash;
CCheckBox OtherNoSmoke;
CComboBox OtherNoHands;
CCheckBox OtherAutoJump;
CCheckBox OtherAutoStrafe;
CCheckBox OtherSafeMode;
CComboBox OtherChatSpam;
CKeyBind OtherAirStuck;
CCheckBox OtherSpectators;
};

class CMiscTab : public CTab
{
public:
        void Setup();

// Fake Lag Settings
CGroupBox FakeLagGroup;
CCheckBox FakeLagEnable;
CSlider FakeLagAmount;
CCheckBox FakeLagWhileShooting;

// Knife Changer/Skin Changer
CGroupBox KnifeGroup;
CCheckBox KnifeEnable;
CComboBox KnifeModel;
CComboBox KnifeSkin;
CComboBox M41SSkin;
CComboBox M4A4Skin;
CComboBox AK47Skin;
CComboBox AWPSkin;
CComboBox GLOCKSkin;
CComboBox USPSSkin;
CComboBox DEAGLESkin;
CComboBox MAGNUMSkin;
CButton KnifeApply;
};

class AimWareWindow : public CWindow
{
public:
        void Setup();

CRageBotTab RageBotTab;
CLegitBotTab LegitBotTab;
CVisualTab VisualsTab;
CMiscTab MiscTab;

CButton SaveButton;
CButton LoadButton;
CButton UnloadButton;
};

namespace Menu
{
    void SetupMenu();
    void DoUIFrame();

        extern AimWareWindow Window;
};/*
Syn's AYYWAREFramework
*/
#include "Utilities.h"

#define AimWare_META_GAME "Counter-Strike: Global Offensive"

void PrintMetaHeader()
{
    printf("                                  Ayy");
    Utilities::SetConsoleColor(FOREGROUND_INTENSE_GREEN);
    printf("Ware\n");
    Utilities::SetConsoleColor(FOREGROUND_WHITE);
    Utilities::Log("Build %s", __DATE__);
    Utilities::Log("Setting Up AYYWAREfor %s", AimWare_META_GAME);
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "bspflags.h"

// Entity List
class IClientEntityList
{
    public:
        virtual void Function0();
    virtual void Function1();
    virtual void Function2();
    virtual IClientEntity* GetClientEntity(int entnum);
    virtual IClientEntity* GetClientEntityFromHandle(HANDLE hEnt) = 0;
        virtual int NumberOfEntities(bool bIncludeNonNetworkable) = 0;
        virtual int GetHighestEntityIndex(void);
    virtual void SetMaxEntities(int maxents);
    virtual int GetMaxEntities();
};

// Panels
class IPanel
{
    public:
        const char* GetName(unsigned int vguiPanel)
        {

        typedef const char* (__thiscall * OriginalFn)(PVOID, unsigned int);
                return call_vfunc(this, Offsets::VMT::Panel_GetName)(this, vguiPanel);
        }
};

// Colors
class Color
{
    public:
        // constructors
        Color()
    {
        *((int*)this) = 0;
    }
    Color(int r, int g, int b)
    {
        SetColor(r, g, b, 0);
    }
    Color(int r, int g, int b, int a)
    {
        SetColor(r, g, b, a);
    }
    void SetColor(int r, int g, int b, int a = 0)
    {
        _color[0] = (unsigned char)r;
        _color[1] = (unsigned char)g;
        _color[2] = (unsigned char)b;
        _color[3] = (unsigned char)a;
    }

    void GetColor(int &r, int &g, int &b, int &a) const
        {

        r = _color[0];
                g = _color[1];
                b = _color[2];
                a = _color[3];
        }

void SetRawColor(int color32)
{
    *((int*)this) = color32;
}

int GetRawColor() const
        {
                return *((int*)this);
}

inline int r() const    { return _color[0]; }
        inline int g() const    { return _color[1]; }
        inline int b() const    { return _color[2]; }
        inline int a() const    { return _color[3]; }

        void SetAlpha(int a) { _color[0] = (unsigned char)a; }
int GetAlpha() { return _color[0]; }


unsigned char &operator[] (int index)
{
    return _color[index];
}

const unsigned char &operator[] (int index) const
        {
                return _color[index];
        }

        bool operator ==(const Color &rhs) const
        {
                return (*((int*)this) == *((int *)&rhs));
}

bool operator !=(const Color &rhs) const
        {
                return !(operator ==(rhs));
        }

        Color &operator=(const Color &rhs)
{
    SetRawColor(rhs.GetRawColor());
    return *this;
}

private:
        unsigned char _color[4];
};

// Debug Overlay
class IVDebugOverlay
{
    public:
        virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;
    virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, int r, int g, int b, int a, float duration) = 0;
    virtual void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) = 0;
    virtual void AddTextOverlay(const Vector& origin, float duration, const char* format, ...) = 0;
    virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char* format, ...) = 0;
    virtual void AddScreenTextOverlay(float flXPos, float flYPos, float flDuration, int r, int g, int b, int a, const char* text) = 0;
    virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const Vector & angles, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddGridOverlay(const Vector& origin) = 0;
        virtual void AddCoordFrameOverlay(const matrix3x4& frame, float flScale, int vColorTable[3][3] = NULL) = 0;

        virtual int ScreenPosition(const Vector& point, Vector& screen) = 0;
        virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0;

        virtual void* GetFirst(void) = 0;
        virtual void* GetNext(void* current) = 0;
        virtual void ClearDeadOverlays(void) = 0;
        virtual void ClearAllOverlays() = 0;

        virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0;
    virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;

    virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddBoxOverlay2(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, const Color& faceColor, const Color& edgeColor, float duration) = 0;

    virtual void PurgeTextOverlays() = 0;
};

// User Cmd's
class CUserCmd
{
    public:
        virtual ~CUserCmd() { }; //Destructor 0
    CUserCmd()
    {
        Reset();
    }

    void Reset()
    {
        command_number = 0;
        tick_count = 0;
        viewangles.Init();
        forwardmove = 0.0f;
        sidemove = 0.0f;
        upmove = 0.0f;
        buttons = 0;
        impulse = 0;
        weaponselect = 0;
        weaponsubtype = 0;
        random_seed = 0;
        mousedx = 0;
        mousedy = 0;
        headangles.Init();
        headoffset.Init();

        hasbeenpredicted = false;
    }

    CUserCmd& operator =(const CUserCmd& src)
        {
                if (this == &src)
                        return *this;

                command_number = src.command_number;
                tick_count = src.tick_count;
                viewangles = src.viewangles;
                forwardmove = src.forwardmove;
                sidemove = src.sidemove;
                upmove = src.upmove;
                buttons = src.buttons;
                impulse = src.impulse;
                weaponselect = src.weaponselect;
                weaponsubtype = src.weaponsubtype;
                random_seed = src.random_seed;
                mousedx = src.mousedx;
                mousedy = src.mousedy;

                hasbeenpredicted = src.hasbeenpredicted;
                headangles = src.headangles;
                headoffset = src.headoffset;
                return *this;
        }


    CUserCmd(const CUserCmd& src)
{
    *this = src;
}


int command_number;
int tick_count;
Vector viewangles;
Vector aimdirection;
float forwardmove;
float sidemove;
float upmove;
int buttons;
BYTE impulse;
int weaponselect;
int weaponsubtype;
int random_seed;
short mousedx;
short mousedy;
bool hasbeenpredicted;
Vector headangles;
Vector headoffset;
};

class CGlobalVarsBase
{
    public:
        float realtime;
    int framecount;
    float absoluteframetime;
    float absoluteframestarttimestddev;
    float curtime;
    float frametime;
    int maxClients;
    int tickcount;
    float interval_per_tick;
    float interpolation_amount;
    int simTicksThisFrame;
    int network_protocol;
    void* pSaveData;
    bool m_bClient;
    int nTimestampNetworkingBase;
    int nTimestampRandomizeWindow;
};

struct Ray_t
{

    __declspec(align(16)) Vector m_Start;

    __declspec(align(16)) Vector m_Delta;

    __declspec(align(16)) Vector m_StartOffset;

    __declspec(align(16)) Vector m_Extents;
    //without your matrix3x4
    bool m_IsRay;
    bool m_IsSwept;

    void Init(Vector& vecStart, Vector& vecEnd)
    {
        m_Delta = vecEnd - vecStart;

        m_IsSwept = (m_Delta.LengthSqr() != 0);

        m_Extents.x = m_Extents.y = m_Extents.z = 0.0f;

        m_IsRay = true;

        m_StartOffset.x = m_StartOffset.y = m_StartOffset.z = 0.0f;

        m_Start = vecStart;
    }
};

struct cplane_t
{
    Vector normal;
    float dist;
    BYTE type;
    BYTE signbits;
    BYTE pad[2];
};

class CBaseTrace
{
    public:
        Vector startpos;
    Vector endpos;
    cplane_t plane;
    float fraction;
    int contents;
    unsigned short dispFlags;
    bool allsolid;
    bool startsolid;
};

struct csurface_t
{
    const char* name;
    short surfaceProps;
    unsigned short flags;
};

class CGameTrace : public CBaseTrace
{
public:
        bool DidHitWorld() const;
bool DidHitNonWorldEntity() const;
int GetEntityIndex() const;
bool DidHit() const;
public:
        float fractionleftsolid;
csurface_t surface;
int hitgroup;
short physicsbone;
unsigned short worldSurfaceIndex;
IClientEntity* m_pEnt;
int hitbox;
char shit[0x24];
};

inline bool CGameTrace::DidHit() const
{
        return fraction< 1.0f || allsolid || startsolid;
}

typedef CGameTrace trace_t;

enum TraceType_t
{
    TRACE_EVERYTHING = 0,
    TRACE_WORLD_ONLY,
    TRACE_ENTITIES_ONLY,
    TRACE_EVERYTHING_FILTER_PROPS,
};

class ITraceFilter
{
    public:
        virtual bool ShouldHitEntity(IClientEntity* pEntity, int contentsMask) = 0;
        virtual TraceType_t GetTraceType() const = 0;
};

class CTraceFilter : public ITraceFilter
{
public:
        bool ShouldHitEntity(IClientEntity* pEntityHandle, int contentsMask)
{
    return !(pEntityHandle == pSkip);
}

TraceType_t GetTraceType() const
        {
                return TRACE_EVERYTHING;
        }

        void* pSkip;
};

class IEngineTrace
{
    public:
        int GetPointContents(const Vector &vecAbsPosition, int contentsMask = MASK_ALL, IClientEntity** ppEntity = NULL)
        {
                typedef int(__thiscall* fnGetPointContents)(void*, const Vector&, int, IClientEntity**);
                return call_vfunc(this, 0)(this, vecAbsPosition, contentsMask, ppEntity);
        }

void TraceRay(const Ray_t &ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace)
{
    typedef void(__thiscall * fnTraceRay)(void*, const Ray_t&, unsigned int, ITraceFilter*, trace_t *);
    call_vfunc(this, 5)(this, ray, fMask, pTraceFilter, pTrace);
}
};

struct mstudiobbox_t
{
    int bone;
    int group;
    Vector bbmin;
    Vector bbmax;
    int szhitboxnameindex;
    int unused[8];

    char* GetHitboxName(void)
    {
        if (szhitboxnameindex == 0)
            return "";

        return ((char*)this) + szhitboxnameindex;
    }
};
struct mstudiohitboxset_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int numhitboxes;
int hitboxindex;
inline mstudiobbox_t* GetHitbox(int i) const { return (mstudiobbox_t*)(((byte*)this) + hitboxindex) + i; };
};
struct mstudiobone_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int parent;
int bonecontroller[6];

Vector pos;
float quat[4];
Vector rot;
Vector posscale;
Vector rotscale;

matrix3x4 poseToBone;
float qAlignment[4];
int flags;
int proctype;
int procindex;              // procedural rule
mutable int physicsbone;    // index into physically simulated bone
inline void* GetProcedure() const { if (procindex == 0) return NULL; else return  (void*)(((byte*)this) + procindex); };
int surfacepropidx; // index into string tablefor property name
inline char* const GetSurfaceProps(void) const { return ((char*)this) + surfacepropidx; }
        int contents;               // See BSPFlags.h for the contents flags

int unused[8];              // remove as appropriate
};
struct studiohdr_t
{
    int id;
    int version;

    int checksum;

    char name[64];
    int length;


    Vector eyeposition;

    Vector illumposition;

    Vector hull_min;
    Vector hull_max;

    Vector view_bbmin;
    Vector view_bbmax;

    int flags;

    int numbones;
    int boneindex;

    inline mstudiobone_t *GetBone(int i) const { return (mstudiobone_t*)(((byte*)this) + boneindex) + i; };
//        inline mstudiobone_t *pBone(int i) const { Assert(i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; };

int numbonecontrollers;
int bonecontrollerindex;

int numhitboxsets;
int hitboxsetindex;

mstudiohitboxset_t* GetHitboxSet(int i) const
        {
                return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i;
}

inline mstudiobbox_t* GetHitbox(int i, int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return NULL;

                return s->GetHitbox(i);
        }

        inline int GetHitboxCount(int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return 0;

                return s->numhitboxes;
        }

        int numlocalanim;
int localanimindex;

int numlocalseq;
int localseqindex;

mutable int activitylistversion;
mutable int eventsindexed;

int numtextures;
int textureindex;

int numcdtextures;
int cdtextureindex;

int numskinref;
int numskinfamilies;
int skinindex;

int numbodyparts;
int bodypartindex;

int numlocalattachments;
int localattachmentindex;

int numlocalnodes;
int localnodeindex;
int localnodenameindex;

int numflexdesc;
int flexdescindex;

int numflexcontrollers;
int flexcontrollerindex;

int numflexrules;
int flexruleindex;

int numikchains;
int ikchainindex;

int nummouths;
int mouthindex;

int numlocalposeparameters;
int localposeparamindex;

int surfacepropindex;

int keyvalueindex;
int keyvaluesize;


int numlocalikautoplaylocks;
int localikautoplaylockindex;

float mass;
int contents;

int numincludemodels;
int includemodelindex;

mutable void* virtualModel;

int szanimblocknameindex;
int numanimblocks;
int animblockindex;

mutable void* animblockModel;

int bonetablebynameindex;

void* pVertexBase;
void* pIndexBase;

byte constdirectionallightdot;

byte rootLOD;

byte numAllowedRootLODs;

byte unused[1];

int unused4;

int numflexcontrollerui;
int flexcontrolleruiindex;
float flVertAnimFixedPointScale;
int unused3[1];
int studiohdr2index;
int unused2[1];
};

struct surfacephysicsparams_t
{
    float friction;
    float elasticity; // collision elasticity - used to compute coefficient of restitution
    float density;    // physical density (in kg / m^3)
    float thickness;    // material thickness if not solid (sheet materials) in inches
    float dampening;
};

struct surfaceaudioparams_t
{
    float reflectivity;            // like elasticity, but how much sound should be reflected by this surface
    float hardnessFactor;            // like elasticity, but only affects impact sound choices
    float roughnessFactor;        // like friction, but only affects scrape sound choices   
    float roughThreshold;            // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes
    float hardThreshold;            // surface hardness > this causes "hard" impacts, < this causes "soft" impacts
    float hardVelocityThreshold;    // collision velocity > this causes "hard" impacts, < this causes "soft" impacts   
};

struct surfacesoundnames_t
{
    unsigned short stepleft;
    unsigned short stepright;
    unsigned short impactSoft;
    unsigned short impactHard;
    unsigned short scrapeSmooth;
    unsigned short scrapeRough;
    unsigned short bulletImpact;
    unsigned short rolling;
    unsigned short breakSound;
    unsigned short strainSound;
};

struct surfacegameprops_t
{
    public:
        float maxSpeedFactor; //0x0000
    float jumpFactor; //0x0004
    char pad00[0x4]; //0x0008
    float flPenetrationModifier; //0x000C
    float flDamageModifier; //0x0010
    unsigned short material; //0x0014
    char pad01[0x3];

};//Size=0x0019

struct surfacedata_t
{
    surfacephysicsparams_t physics;
    surfaceaudioparams_t audio;
    surfacesoundnames_t sounds;
    surfacegameprops_t game;
};

class IPhysicsSurfaceProps
{
    public:

        surfacedata_t* GetSurfaceData(int surfaceDataIndex)
    {
        typedef surfacedata_t*(__thiscall * fnGetSurfaceData)(void*, int);
        return call_vfunc(this, 5)(this, surfaceDataIndex);
    }
};

class ConVar
{
    public:
        //void SetString(const char *pValue)
        //{
        //        typedef void(__thiscall* SetStringFn)(void*, const char *);
        //        call_vfunc(this, 17)(this, pValue);
        //}

        void SetString(const char* str)
        {

        typedef void(__thiscall* SetStringFn)(void*, const char*);
                return call_vfunc(this, 13)(this, str);
        }

void InternalSetString(const char* str)
{
    typedef void(__thiscall * SetStringFn)(void*, const char*);
    return call_vfunc(this, 17)(this, str);
}

char* GetBaseName()
{
    typedef char*(__thiscall * SetStringFn)(void*);
    return call_vfunc(this, 6)(this);
}

char pad_0x0000[0x4]; //0x0000
ConVar* pNext; //0x0004 
__int32 bRegistered; //0x0008 
char* pszName; //0x000C 
char* pszHelpString; //0x0010 
__int32 nFlags; //0x0014 
char pad_0x0018[0x4]; //0x0018
ConVar* pParent; //0x001C 
char* pszDefaultValue; //0x0020 
char* strString; //0x0024 
__int32 StringLength; //0x0028 
float fValue; //0x002C 
__int32 nValue; //0x0030 
__int32 bHasMin; //0x0034 
float fMinVal; //0x0038 
__int32 bHasMax; //0x003C 
float fMaxVal; //0x0040 
void* fnChangeCallback; //0x0044 

};//Size=0x0048

class ICVar
{
    public:
        ConVar* FindVar(const char* var_name)
        {

        typedef ConVar*(__thiscall* FindVarFn)(void*, const char*);
                return call_vfunc(this, 15)(this, var_name);
        }
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "MiscDefinitions.h"
#include "ClientRecvProps.h"
#include "offsets.h"
#include "Vector.h"
#include "bspflags.h"

// Entity List
class IClientEntityList
{
    public:
        virtual void Function0();
    virtual void Function1();
    virtual void Function2();
    virtual IClientEntity* GetClientEntity(int entnum);
    virtual IClientEntity* GetClientEntityFromHandle(HANDLE hEnt) = 0;
        virtual int NumberOfEntities(bool bIncludeNonNetworkable) = 0;
        virtual int GetHighestEntityIndex(void);
    virtual void SetMaxEntities(int maxents);
    virtual int GetMaxEntities();
};

// Panels
class IPanel
{
    public:
        const char* GetName(unsigned int vguiPanel)
        {

        typedef const char* (__thiscall * OriginalFn)(PVOID, unsigned int);
                return call_vfunc(this, Offsets::VMT::Panel_GetName)(this, vguiPanel);
        }
};

// Colors
class Color
{
    public:
        // constructors
        Color()
    {
        *((int*)this) = 0;
    }
    Color(int r, int g, int b)
    {
        SetColor(r, g, b, 0);
    }
    Color(int r, int g, int b, int a)
    {
        SetColor(r, g, b, a);
    }
    void SetColor(int r, int g, int b, int a = 0)
    {
        _color[0] = (unsigned char)r;
        _color[1] = (unsigned char)g;
        _color[2] = (unsigned char)b;
        _color[3] = (unsigned char)a;
    }

    void GetColor(int &r, int &g, int &b, int &a) const
        {

        r = _color[0];
                g = _color[1];
                b = _color[2];
                a = _color[3];
        }

void SetRawColor(int color32)
{
    *((int*)this) = color32;
}

int GetRawColor() const
        {
                return *((int*)this);
}

inline int r() const    { return _color[0]; }
        inline int g() const    { return _color[1]; }
        inline int b() const    { return _color[2]; }
        inline int a() const    { return _color[3]; }

        void SetAlpha(int a) { _color[0] = (unsigned char)a; }
int GetAlpha() { return _color[0]; }


unsigned char &operator[] (int index)
{
    return _color[index];
}

const unsigned char &operator[] (int index) const
        {
                return _color[index];
        }

        bool operator ==(const Color &rhs) const
        {
                return (*((int*)this) == *((int *)&rhs));
}

bool operator !=(const Color &rhs) const
        {
                return !(operator ==(rhs));
        }

        Color &operator=(const Color &rhs)
{
    SetRawColor(rhs.GetRawColor());
    return *this;
}

private:
        unsigned char _color[4];
};

// Debug Overlay
class IVDebugOverlay
{
    public:
        virtual void AddEntityTextOverlay(int ent_index, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;
    virtual void AddBoxOverlay(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, int r, int g, int b, int a, float duration) = 0;
    virtual void AddSphereOverlay(const Vector& vOrigin, float flRadius, int nTheta, int nPhi, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddTriangleOverlay(const Vector& p1, const Vector& p2, const Vector& p3, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddLineOverlay(const Vector& origin, const Vector& dest, int r, int g, int b, bool noDepthTest, float duration) = 0;
    virtual void AddTextOverlay(const Vector& origin, float duration, const char* format, ...) = 0;
    virtual void AddTextOverlay(const Vector& origin, int line_offset, float duration, const char* format, ...) = 0;
    virtual void AddScreenTextOverlay(float flXPos, float flYPos, float flDuration, int r, int g, int b, int a, const char* text) = 0;
    virtual void AddSweptBoxOverlay(const Vector& start, const Vector& end, const Vector& mins, const Vector& max, const Vector & angles, int r, int g, int b, int a, float flDuration) = 0;
    virtual void AddGridOverlay(const Vector& origin) = 0;
        virtual void AddCoordFrameOverlay(const matrix3x4& frame, float flScale, int vColorTable[3][3] = NULL) = 0;

        virtual int ScreenPosition(const Vector& point, Vector& screen) = 0;
        virtual int ScreenPosition(float flXPos, float flYPos, Vector& screen) = 0;

        virtual void* GetFirst(void) = 0;
        virtual void* GetNext(void* current) = 0;
        virtual void ClearDeadOverlays(void) = 0;
        virtual void ClearAllOverlays() = 0;

        virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, float r, float g, float b, float alpha, const char* format, ...) = 0;
    virtual void AddTextOverlayRGB(const Vector& origin, int line_offset, float duration, int r, int g, int b, int a, const char* format, ...) = 0;

    virtual void AddLineOverlayAlpha(const Vector& origin, const Vector& dest, int r, int g, int b, int a, bool noDepthTest, float duration) = 0;
    virtual void AddBoxOverlay2(const Vector& origin, const Vector& mins, const Vector& max, Vector const& orientation, const Color& faceColor, const Color& edgeColor, float duration) = 0;

    virtual void PurgeTextOverlays() = 0;
};

// User Cmd's
class CUserCmd
{
    public:
        virtual ~CUserCmd() { }; //Destructor 0
    CUserCmd()
    {
        Reset();
    }

    void Reset()
    {
        command_number = 0;
        tick_count = 0;
        viewangles.Init();
        forwardmove = 0.0f;
        sidemove = 0.0f;
        upmove = 0.0f;
        buttons = 0;
        impulse = 0;
        weaponselect = 0;
        weaponsubtype = 0;
        random_seed = 0;
        mousedx = 0;
        mousedy = 0;
        headangles.Init();
        headoffset.Init();

        hasbeenpredicted = false;
    }

    CUserCmd& operator =(const CUserCmd& src)
        {
                if (this == &src)
                        return *this;

                command_number = src.command_number;
                tick_count = src.tick_count;
                viewangles = src.viewangles;
                forwardmove = src.forwardmove;
                sidemove = src.sidemove;
                upmove = src.upmove;
                buttons = src.buttons;
                impulse = src.impulse;
                weaponselect = src.weaponselect;
                weaponsubtype = src.weaponsubtype;
                random_seed = src.random_seed;
                mousedx = src.mousedx;
                mousedy = src.mousedy;

                hasbeenpredicted = src.hasbeenpredicted;
                headangles = src.headangles;
                headoffset = src.headoffset;
                return *this;
        }


    CUserCmd(const CUserCmd& src)
{
    *this = src;
}


int command_number;
int tick_count;
Vector viewangles;
Vector aimdirection;
float forwardmove;
float sidemove;
float upmove;
int buttons;
BYTE impulse;
int weaponselect;
int weaponsubtype;
int random_seed;
short mousedx;
short mousedy;
bool hasbeenpredicted;
Vector headangles;
Vector headoffset;
};

class CGlobalVarsBase
{
    public:
        float realtime;
    int framecount;
    float absoluteframetime;
    float absoluteframestarttimestddev;
    float curtime;
    float frametime;
    int maxClients;
    int tickcount;
    float interval_per_tick;
    float interpolation_amount;
    int simTicksThisFrame;
    int network_protocol;
    void* pSaveData;
    bool m_bClient;
    int nTimestampNetworkingBase;
    int nTimestampRandomizeWindow;
};

struct Ray_t
{

    __declspec(align(16)) Vector m_Start;

    __declspec(align(16)) Vector m_Delta;

    __declspec(align(16)) Vector m_StartOffset;

    __declspec(align(16)) Vector m_Extents;
    //without your matrix3x4
    bool m_IsRay;
    bool m_IsSwept;

    void Init(Vector& vecStart, Vector& vecEnd)
    {
        m_Delta = vecEnd - vecStart;

        m_IsSwept = (m_Delta.LengthSqr() != 0);

        m_Extents.x = m_Extents.y = m_Extents.z = 0.0f;

        m_IsRay = true;

        m_StartOffset.x = m_StartOffset.y = m_StartOffset.z = 0.0f;

        m_Start = vecStart;
    }
};

struct cplane_t
{
    Vector normal;
    float dist;
    BYTE type;
    BYTE signbits;
    BYTE pad[2];
};

class CBaseTrace
{
    public:
        Vector startpos;
    Vector endpos;
    cplane_t plane;
    float fraction;
    int contents;
    unsigned short dispFlags;
    bool allsolid;
    bool startsolid;
};

struct csurface_t
{
    const char* name;
    short surfaceProps;
    unsigned short flags;
};

class CGameTrace : public CBaseTrace
{
public:
        bool DidHitWorld() const;
bool DidHitNonWorldEntity() const;
int GetEntityIndex() const;
bool DidHit() const;
public:
        float fractionleftsolid;
csurface_t surface;
int hitgroup;
short physicsbone;
unsigned short worldSurfaceIndex;
IClientEntity* m_pEnt;
int hitbox;
char shit[0x24];
};

inline bool CGameTrace::DidHit() const
{
        return fraction< 1.0f || allsolid || startsolid;
}

typedef CGameTrace trace_t;

enum TraceType_t
{
    TRACE_EVERYTHING = 0,
    TRACE_WORLD_ONLY,
    TRACE_ENTITIES_ONLY,
    TRACE_EVERYTHING_FILTER_PROPS,
};

class ITraceFilter
{
    public:
        virtual bool ShouldHitEntity(IClientEntity* pEntity, int contentsMask) = 0;
        virtual TraceType_t GetTraceType() const = 0;
};

class CTraceFilter : public ITraceFilter
{
public:
        bool ShouldHitEntity(IClientEntity* pEntityHandle, int contentsMask)
{
    return !(pEntityHandle == pSkip);
}

TraceType_t GetTraceType() const
        {
                return TRACE_EVERYTHING;
        }

        void* pSkip;
};

class IEngineTrace
{
    public:
        int GetPointContents(const Vector &vecAbsPosition, int contentsMask = MASK_ALL, IClientEntity** ppEntity = NULL)
        {
                typedef int(__thiscall* fnGetPointContents)(void*, const Vector&, int, IClientEntity**);
                return call_vfunc(this, 0)(this, vecAbsPosition, contentsMask, ppEntity);
        }

void TraceRay(const Ray_t &ray, unsigned int fMask, ITraceFilter* pTraceFilter, trace_t* pTrace)
{
    typedef void(__thiscall * fnTraceRay)(void*, const Ray_t&, unsigned int, ITraceFilter*, trace_t *);
    call_vfunc(this, 5)(this, ray, fMask, pTraceFilter, pTrace);
}
};

struct mstudiobbox_t
{
    int bone;
    int group;
    Vector bbmin;
    Vector bbmax;
    int szhitboxnameindex;
    int unused[8];

    char* GetHitboxName(void)
    {
        if (szhitboxnameindex == 0)
            return "";

        return ((char*)this) + szhitboxnameindex;
    }
};
struct mstudiohitboxset_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int numhitboxes;
int hitboxindex;
inline mstudiobbox_t* GetHitbox(int i) const { return (mstudiobbox_t*)(((byte*)this) + hitboxindex) + i; };
};
struct mstudiobone_t
{
    int sznameindex;
    inline char* const GetName(void) const { return ((char*)this) + sznameindex; }
int parent;
int bonecontroller[6];

Vector pos;
float quat[4];
Vector rot;
Vector posscale;
Vector rotscale;

matrix3x4 poseToBone;
float qAlignment[4];
int flags;
int proctype;
int procindex;              // procedural rule
mutable int physicsbone;    // index into physically simulated bone
inline void* GetProcedure() const { if (procindex == 0) return NULL; else return  (void*)(((byte*)this) + procindex); };
int surfacepropidx; // index into string tablefor property name
inline char* const GetSurfaceProps(void) const { return ((char*)this) + surfacepropidx; }
        int contents;               // See BSPFlags.h for the contents flags

int unused[8];              // remove as appropriate
};
struct studiohdr_t
{
    int id;
    int version;

    int checksum;

    char name[64];
    int length;


    Vector eyeposition;

    Vector illumposition;

    Vector hull_min;
    Vector hull_max;

    Vector view_bbmin;
    Vector view_bbmax;

    int flags;

    int numbones;
    int boneindex;

    inline mstudiobone_t *GetBone(int i) const { return (mstudiobone_t*)(((byte*)this) + boneindex) + i; };
//        inline mstudiobone_t *pBone(int i) const { Assert(i >= 0 && i < numbones); return (mstudiobone_t *)(((byte *)this) + boneindex) + i; };

int numbonecontrollers;
int bonecontrollerindex;

int numhitboxsets;
int hitboxsetindex;

mstudiohitboxset_t* GetHitboxSet(int i) const
        {
                return (mstudiohitboxset_t*)(((byte*)this) + hitboxsetindex) + i;
}

inline mstudiobbox_t* GetHitbox(int i, int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return NULL;

                return s->GetHitbox(i);
        }

        inline int GetHitboxCount(int set) const
        {
                mstudiohitboxset_t const* s = GetHitboxSet(set);

                if (!s)
                        return 0;

                return s->numhitboxes;
        }

        int numlocalanim;
int localanimindex;

int numlocalseq;
int localseqindex;

mutable int activitylistversion;
mutable int eventsindexed;

int numtextures;
int textureindex;

int numcdtextures;
int cdtextureindex;

int numskinref;
int numskinfamilies;
int skinindex;

int numbodyparts;
int bodypartindex;

int numlocalattachments;
int localattachmentindex;

int numlocalnodes;
int localnodeindex;
int localnodenameindex;

int numflexdesc;
int flexdescindex;

int numflexcontrollers;
int flexcontrollerindex;

int numflexrules;
int flexruleindex;

int numikchains;
int ikchainindex;

int nummouths;
int mouthindex;

int numlocalposeparameters;
int localposeparamindex;

int surfacepropindex;

int keyvalueindex;
int keyvaluesize;


int numlocalikautoplaylocks;
int localikautoplaylockindex;

float mass;
int contents;

int numincludemodels;
int includemodelindex;

mutable void* virtualModel;

int szanimblocknameindex;
int numanimblocks;
int animblockindex;

mutable void* animblockModel;

int bonetablebynameindex;

void* pVertexBase;
void* pIndexBase;

byte constdirectionallightdot;

byte rootLOD;

byte numAllowedRootLODs;

byte unused[1];

int unused4;

int numflexcontrollerui;
int flexcontrolleruiindex;
float flVertAnimFixedPointScale;
int unused3[1];
int studiohdr2index;
int unused2[1];
};

struct surfacephysicsparams_t
{
    float friction;
    float elasticity; // collision elasticity - used to compute coefficient of restitution
    float density;    // physical density (in kg / m^3)
    float thickness;    // material thickness if not solid (sheet materials) in inches
    float dampening;
};

struct surfaceaudioparams_t
{
    float reflectivity;            // like elasticity, but how much sound should be reflected by this surface
    float hardnessFactor;            // like elasticity, but only affects impact sound choices
    float roughnessFactor;        // like friction, but only affects scrape sound choices   
    float roughThreshold;            // surface roughness > this causes "rough" scrapes, < this causes "smooth" scrapes
    float hardThreshold;            // surface hardness > this causes "hard" impacts, < this causes "soft" impacts
    float hardVelocityThreshold;    // collision velocity > this causes "hard" impacts, < this causes "soft" impacts   
};

struct surfacesoundnames_t
{
    unsigned short stepleft;
    unsigned short stepright;
    unsigned short impactSoft;
    unsigned short impactHard;
    unsigned short scrapeSmooth;
    unsigned short scrapeRough;
    unsigned short bulletImpact;
    unsigned short rolling;
    unsigned short breakSound;
    unsigned short strainSound;
};

struct surfacegameprops_t
{
    public:
        float maxSpeedFactor; //0x0000
    float jumpFactor; //0x0004
    char pad00[0x4]; //0x0008
    float flPenetrationModifier; //0x000C
    float flDamageModifier; //0x0010
    unsigned short material; //0x0014
    char pad01[0x3];

};//Size=0x0019

struct surfacedata_t
{
    surfacephysicsparams_t physics;
    surfaceaudioparams_t audio;
    surfacesoundnames_t sounds;
    surfacegameprops_t game;
};

class IPhysicsSurfaceProps
{
    public:

        surfacedata_t* GetSurfaceData(int surfaceDataIndex)
    {
        typedef surfacedata_t*(__thiscall * fnGetSurfaceData)(void*, int);
        return call_vfunc(this, 5)(this, surfaceDataIndex);
    }
};

class ConVar
{
    public:
        //void SetString(const char *pValue)
        //{
        //        typedef void(__thiscall* SetStringFn)(void*, const char *);
        //        call_vfunc(this, 17)(this, pValue);
        //}

        void SetString(const char* str)
        {

        typedef void(__thiscall* SetStringFn)(void*, const char*);
                return call_vfunc(this, 13)(this, str);
        }

void InternalSetString(const char* str)
{
    typedef void(__thiscall * SetStringFn)(void*, const char*);
    return call_vfunc(this, 17)(this, str);
}

char* GetBaseName()
{
    typedef char*(__thiscall * SetStringFn)(void*);
    return call_vfunc(this, 6)(this);
}

char pad_0x0000[0x4]; //0x0000
ConVar* pNext; //0x0004 
__int32 bRegistered; //0x0008 
char* pszName; //0x000C 
char* pszHelpString; //0x0010 
__int32 nFlags; //0x0014 
char pad_0x0018[0x4]; //0x0018
ConVar* pParent; //0x001C 
char* pszDefaultValue; //0x0020 
char* strString; //0x0024 
__int32 StringLength; //0x0028 
float fValue; //0x002C 
__int32 nValue; //0x0030 
__int32 bHasMin; //0x0034 
float fMinVal; //0x0038 
__int32 bHasMax; //0x003C 
float fMaxVal; //0x0040 
void* fnChangeCallback; //0x0044 

};//Size=0x0048

class ICVar
{
    public:
        ConVar* FindVar(const char* var_name)
        {

        typedef ConVar*(__thiscall* FindVarFn)(void*, const char*);
                return call_vfunc(this, 15)(this, var_name);
        }
};#pragma once

#include "NetVars.h"
#include "Vector.h"

//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------

// For calling VMT functions in our classes
template Function call_vfunc(PVOID Base, DWORD Index)
{
    PDWORD* VTablePointer = (PDWORD*)Base;
    PDWORD VTableFunctionBase = *VTablePointer;
    DWORD dwAddress = VTableFunctionBase[Index];
    return (Function)(dwAddress);
}

// Netvar shit
#define dwThis (DWORD)this
#define NETVAR(type,offset) *(type*)(dwThis + offset)
#define CNETVAR(type,offset) (type)(dwThis + offset)

//CNETVAR_FUNC - creates a netvar function in a class that returns value(s) [type=class type & return type] [name=function name] [netvar_crc=crc32 of netvar of choice]
#define CNETVAR_FUNC(type,name,netvar_crc) \
type name() \
        { \
                static DWORD dwObserverTarget = NetVar.GetNetVar(netvar_crc); \
                return NETVAR(type, dwObserverTarget); \
        }

//CPNETVAR_FUNC - creates a netvar function in a class that returns a pointer [type=class type & return type] [name=function name] [netvar_crc=crc32 of netvar of choice]
#define CPNETVAR_FUNC(type,name,netvar_crc) \
        type name() \
        { \
                static DWORD dwObserverTarget = NetVar.GetNetVar(netvar_crc); \
                return CNETVAR(type, dwObserverTarget); \
        }

// Lifestates
enum source_lifestates
{
    LIFE_ALIVE,
    LIFE_DYING,
    LIFE_DEAD,
    LIFE_RESPAWNABLE,
    LIFE_DISCARDBODY,
};

// Player Controls for CS:GO
enum playercontrols
{
    IN_ATTACK = (1 << 0),
    IN_JUMP = (1 << 1),
    IN_DUCK = (1 << 2),
    IN_FORWARD = (1 << 3),
    IN_BACK = (1 << 4),
    IN_USE = (1 << 5),
    IN_CANCEL = (1 << 6),
    IN_LEFT = (1 << 7),
    IN_RIGHT = (1 << 8),
    IN_MOVELEFT = (1 << 9),
    IN_MOVERIGHT = (1 << 10),
    IN_ATTACK2 = (1 << 11),
    IN_RUN = (1 << 12),
    IN_RELOAD = (1 << 13),
    IN_ALT1 = (1 << 14),
    IN_ALT2 = (1 << 15),
    IN_SCORE = (1 << 16),   // Used by client.dll for when scoreboard is held down
    IN_SPEED = (1 << 17),   // Player is holding the speed key
    IN_WALK = (1 << 18),    // Player holding walk key
    IN_ZOOM = (1 << 19),    // Zoom key for HUD zoom
    IN_WEAPON1 = (1 << 20), // weapon defines these bits
    IN_WEAPON2 = (1 << 21), // weapon defines these bits
    IN_BULLRUSH = (1 << 22),
};

typedef float matrix3x4[3][4];

class player_info_t
{
    public:
        char pad_0x0000[0x10]; //0x0000
    char name[64]; //0x0010 
    char pad_0x0050[0x40]; //0x0050
    __int32 userID; //0x0090 
    char guid[32]; //0x0094 
    char pad_0x00B4[0x180]; //0x00B4
};

enum SolidType_t
{
    SOLID_NONE = 0, // no solid model
    SOLID_BSP = 1,  // a BSP tree
    SOLID_BBOX = 2, // an AABB
    SOLID_OBB = 3,  // an OBB (not implemented yet)
    SOLID_OBB_YAW = 4,  // an OBB, constrained so that it can only yaw
    SOLID_CUSTOM = 5,   // Always call into the entity for tests
    SOLID_VPHYSICS = 6, // solid vphysics object, get vcollide from the model and collide with that
    SOLID_LAST,
};

enum SolidFlags_t
{
    FSOLID_CUSTOMRAYTEST = 0x0001,  // Ignore solid type + always call into the entity for ray tests
    FSOLID_CUSTOMBOXTEST = 0x0002,  // Ignore solid type + always call into the entity for swept box tests
    FSOLID_NOT_SOLID = 0x0004,  // Are we currently not solid?
    FSOLID_TRIGGER = 0x0008,    // This is something may be collideable but fires touch functions
                                // even when it's not collideable (when the FSOLID_NOT_SOLID flag is set)
    FSOLID_NOT_STANDABLE = 0x0010,  // You can't stand on this
    FSOLID_VOLUME_CONTENTS = 0x0020,    // Contains volumetric contents (like water)
    FSOLID_FORCE_WORLD_ALIGNED = 0x0040,    // Forces the collision rep to be world-aligned even if it's SOLID_BSP or SOLID_VPHYSICS
    FSOLID_USE_TRIGGER_BOUNDS = 0x0080, // Uses a special trigger bounds separate from the normal OBB
    FSOLID_ROOT_PARENT_ALIGNED = 0x0100,    // Collisions are defined in root parent's local coordinate space
    FSOLID_TRIGGER_TOUCH_DEBRIS = 0x0200,   // This trigger will touch debris objects

    FSOLID_MAX_BITS = 10
};

// KeyValues
class KeyValues
{
    public:
        char _pad[0x20];//csgo, for css its a diff size
};

// Memes
struct ModelRenderInfo_t
{
    Vector origin;
    Vector angles;
    void* pRenderable;
    const void* pModel;
    const matrix3x4* pModelToWorld;
    const matrix3x4* pLightingOffset;
    const Vector* pLightingOrigin;
    int flags;
    int entity_index;
    int skin;
    int body;
    int hitboxset;
    unsigned short instance;

    ModelRenderInfo_t()
    {
        pModelToWorld = NULL;
        pLightingOffset = NULL;
        pLightingOrigin = NULL;
    }
};

typedef float vec_t;

inline unsigned long& FloatBits(vec_t& f)
{
    return *reinterpret_cast < unsigned long*> (&f);
}

inline bool IsFinite(vec_t f)
{
    return ((FloatBits(f) & 0x7F800000) != 0x7F800000);
}

struct model_t;

enum OverrideType_t
{
    OVERRIDE_NORMAL = 0,
    OVERRIDE_BUILD_SHADOWS,
    OVERRIDE_DEPTH_WRITE,
};

enum MaterialVarFlags_t
{
    MATERIAL_VAR_DEBUG = (1 << 0),
    MATERIAL_VAR_NO_DEBUG_OVERRIDE = (1 << 1),
    MATERIAL_VAR_NO_DRAW = (1 << 2),
    MATERIAL_VAR_USE_IN_FILLRATE_MODE = (1 << 3),

    MATERIAL_VAR_VERTEXCOLOR = (1 << 4),
    MATERIAL_VAR_VERTEXALPHA = (1 << 5),
    MATERIAL_VAR_SELFILLUM = (1 << 6),
    MATERIAL_VAR_ADDITIVE = (1 << 7),
    MATERIAL_VAR_ALPHATEST = (1 << 8),
    MATERIAL_VAR_MULTIPASS = (1 << 9),
    MATERIAL_VAR_ZNEARER = (1 << 10),
    MATERIAL_VAR_MODEL = (1 << 11),
    MATERIAL_VAR_FLAT = (1 << 12),
    MATERIAL_VAR_NOCULL = (1 << 13),
    MATERIAL_VAR_NOFOG = (1 << 14),
    MATERIAL_VAR_IGNOREZ = (1 << 15),
    MATERIAL_VAR_DECAL = (1 << 16),
    MATERIAL_VAR_ENVMAPSPHERE = (1 << 17),
    MATERIAL_VAR_NOALPHAMOD = (1 << 18),
    MATERIAL_VAR_ENVMAPCAMERASPACE = (1 << 19),
    MATERIAL_VAR_BASEALPHAENVMAPMASK = (1 << 20),
    MATERIAL_VAR_TRANSLUCENT = (1 << 21),
    MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK = (1 << 22),
    MATERIAL_VAR_NEEDS_SOFTWARE_SKINNING = (1 << 23),
    MATERIAL_VAR_OPAQUETEXTURE = (1 << 24),
    MATERIAL_VAR_ENVMAPMODE = (1 << 25),
    MATERIAL_VAR_SUPPRESS_DECALS = (1 << 26),
    MATERIAL_VAR_HALFLAMBERT = (1 << 27),
    MATERIAL_VAR_WIREFRAME = (1 << 28),

    // NOTE: Only add flags here that either should be read from
    // .vmts or can be set directly from client code. Other, internal
    // flags should to into the flag enum in IMaterialInternal.h
};

#define        FL_ONGROUND                                (1<<0)        // At rest / on the ground
#define FL_DUCKING                                (1<<1)        // Player flag -- Player is fully crouched
#define        FL_WATERJUMP                        (1<<2)        // player jumping out of water
#define FL_ONTRAIN                                (1<<3) // Player is _controlling_ a train, so movement commands should be ignored on client during prediction.
#define FL_INRAIN                                (1<<4)        // Indicates the entity is standing in rain
#define FL_FROZEN                                (1<<5) // Player is frozen for 3rd person camera
#define FL_ATCONTROLS                        (1<<6) // Player can't move, but keeps key inputs for controlling another entity
#define        FL_CLIENT                                (1<<7)        // Is a player
#define FL_FAKECLIENT                        (1<<8)        // Fake client, simulated server side; don't send network messages to them
// NON-PLAYER SPECIFIC (i.e., not used by GameMovement or the client .dll ) -- Can still be applied to players, though
#define        FL_INWATER                                (1<<9)        // In water

// NOTE if you move things up, make sure to change this value
#define PLAYER_FLAG_BITS                10

#define        FL_FLY                                        (1<<10)        // Changes the SV_Movestep() behavior to not need to be on ground
#define        FL_SWIM                                        (1<<11)        // Changes the SV_Movestep() behavior to not need to be on ground (but stay in water)
#define        FL_CONVEYOR                                (1<<12)
#define        FL_NPC                                        (1<<13)
#define        FL_GODMODE                                (1<<14)
#define        FL_NOTARGET                                (1<<15)
#define        FL_AIMTARGET                        (1<<16)        // set if the crosshair needs to aim onto the entity
#define        FL_PARTIALGROUND                (1<<17)        // not all corners are valid
#define FL_STATICPROP                        (1<<18)        // Eetsa static prop!                
#define FL_GRAPHED                                (1<<19) // worldgraph has this ent listed as something that blocks a connection
#define FL_GRENADE                                (1<<20)
#define FL_STEPMOVEMENT                        (1<<21)        // Changes the SV_Movestep() behavior to not do any processing
#define FL_DONTTOUCH                        (1<<22)        // Doesn't generate touch functions, generates Untouch() for anything it was touching when this flag was set
#define FL_BASEVELOCITY                        (1<<23)        // Base velocity has been applied this frame (used to convert base velocity into momentum)
#define FL_WORLDBRUSH                        (1<<24)        // Not moveable/removeable brush entity (really part of the world, but represented as an entity for transparency or something)
#define FL_OBJECT                                (1<<25) // Terrible name. This is an object that NPCs should see. Missiles, for example.
#define FL_KILLME                                (1<<26)        // This entity is marked for death -- will be freed by game DLL
#define FL_ONFIRE                                (1<<27)        // You know...
#define FL_DISSOLVING                        (1<<28) // We're dissolving!
#define FL_TRANSRAGDOLL                        (1<<29) // In the process of turning into a client side ragdoll.
#define FL_UNBLOCKABLE_BY_PLAYER (1<<30) // pusher that can't be blocked by the player

enum ClientFrameStage_t
{
    FRAME_UNDEFINED = -1,           // (haven't run any frames yet)
    FRAME_START,

    // A network packet is being recieved
    FRAME_NET_UPDATE_START,
    // Data has been received and we're going to start calling PostDataUpdate
    FRAME_NET_UPDATE_POSTDATAUPDATE_START,
    // Data has been received and we've called PostDataUpdate on all data recipients
    FRAME_NET_UPDATE_POSTDATAUPDATE_END,
    // We've received all packets, we can now do interpolation, prediction, etc..
    FRAME_NET_UPDATE_END,

    // We're about to start rendering the scene
    FRAME_RENDER_START,
    // We've finished rendering the scene.
    FRAME_RENDER_END
};

// ConVar flags
#define FCVAR_NONE                                0 

#define FCVAR_UNREGISTERED                (1<<0)
#define FCVAR_DEVELOPMENTONLY        (1<<1)
#define FCVAR_GAMEDLL                        (1<<2)
#define FCVAR_CLIENTDLL                        (1<<3)
#define FCVAR_HIDDEN                        (1<<4)

#define FCVAR_PROTECTED                        (1<<5)
#define FCVAR_SPONLY                        (1<<6)
#define FCVAR_ARCHIVE                        (1<<7)
#define FCVAR_NOTIFY                        (1<<8)
#define FCVAR_USERINFO                        (1<<9)
#define FCVAR_CHEAT                                (1<<14)

#define FCVAR_PRINTABLEONLY                (1<<10)
#define FCVAR_UNLOGGED                        (1<<11)
#define FCVAR_NEVER_AS_STRING        (1<<12)
#define FCVAR_RELEASE                        (1<<19)

#define FCVAR_REPLICATED                (1<<13)
#define FCVAR_DEMO                                (1<<16)
#define FCVAR_DONTRECORD                (1<<17)

#define FCVAR_NOT_CONNECTED                (1<<22)
#define FCVAR_ARCHIVE_XBOX                (1<<24)
#define FCVAR_SERVER_CAN_EXECUTE        (1<<28)
#define FCVAR_SERVER_CANNOT_QUERY        (1<<29)
#define FCVAR_CLIENTCMD_CAN_EXECUTE        (1<<30)
/*
Syn's AYYWAREFramework 2015
*/

# include "MiscHacks.h"
# include "Interfaces.h"
# include "RenderManager.h"

# include 

Vector AutoStrafeView;

void CMiscHacks::Init()
{
    // Any init
}

void CMiscHacks::Draw()
{
    // Any drawing        
}

void CMiscHacks::Move(CUserCmd* pCmd)
{
    // Any Move Stuff

    // Bhop
    if (Menu::Window.VisualsTab.OtherAutoJump.GetState())
        AutoJump(pCmd);

    // Strafe
    Interfaces::Engine->GetViewAngles(AutoStrafeView);
    if (Menu::Window.VisualsTab.OtherAutoStrafe.GetState())
        AutoStrafe(pCmd);

    // Spams
    switch (Menu::Window.VisualsTab.OtherChatSpam.GetIndex())
    {
        case 0:
            // No Chat Spam
            break;
        case 1:
            // Round Say
            break;
        case 2:
            // Regular
            ChatSpamRegular();
            break;
        case 3:
            // Report Spam
            ChatSpamReports();
            break;
    }

}

void CMiscHacks::AutoJump(CUserCmd* pCmd)
{
    if (pCmd->buttons & IN_JUMP && GUI.GetKeyState(VK_SPACE))
    {
        int iFlags = hackManager.pLocal()->GetFlags();
        if (!(iFlags & FL_ONGROUND))
            pCmd->buttons &= ~IN_JUMP;

        if (hackManager.pLocal()->GetVelocity().Length() <= 50)
        {
            pCmd->forwardmove = 450.f;
        }
    }
}

void CMiscHacks::AutoStrafe(CUserCmd* pCmd)
{
    IClientEntity* pLocal = hackManager.pLocal();
    static bool bDirection = true;

    bool bKeysPressed = true;
    if (GUI.GetKeyState(0x41) || GUI.GetKeyState(0x57) || GUI.GetKeyState(0x53) || GUI.GetKeyState(0x44)) bKeysPressed = false;
    if (pCmd->buttons & IN_ATTACK) bKeysPressed = false;

    float flYawBhop = 0.f;
    if (pLocal->GetVelocity().Length() > 50.f)
    {
        float x = 30.f, y = pLocal->GetVelocity().Length(), z = 0.f, a = 0.f;

        z = x / y;
        z = fabsf(z);

        a = x * z;

        flYawBhop = a;
    }

    if ((GetAsyncKeyState(VK_SPACE) && !(pLocal->GetFlags() & FL_ONGROUND)) && bKeysPressed)
    {

        if (bDirection)
        {
            AutoStrafeView -= flYawBhop;
            GameUtils::NormaliseViewAngle(AutoStrafeView);
            pCmd->sidemove = -400.f;
            bDirection = false;
        }
        else
        {
            AutoStrafeView += flYawBhop;
            GameUtils::NormaliseViewAngle(AutoStrafeView);
            pCmd->sidemove = 400.f;
            bDirection = true;
        }

        if (pCmd->mousedx < 0)
        {
            pCmd->sidemove = -450.f;
        }

        if (pCmd->mousedx > 0)
        {
            pCmd->sidemove = 450.f;
        }
    }
}

Vector GetAutostrafeView()
{
    return AutoStrafeView;
}

void CMiscHacks::ChatSpamReports()
{
    // Don't spam it too fast so you can still do stuff
    static clock_t start_t = clock();
    double timeSoFar = (double)(clock() - start_t) / CLOCKS_PER_SEC;
    if (timeSoFar < 0.5)
        return;

    // Loop through all active entitys
    std::vector < std::string > Names;

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        // Get the entity
        IClientEntity* entity = Interfaces::EntList->GetClientEntity(i);

        player_info_t pInfo;
        // If it's a valid entity and isn't the player
        if (entity && hackManager.pLocal()->GetTeamNum() != entity->GetTeamNum())
        {
            ClientClass* cClass = (ClientClass*)entity->GetClientClass();

            // If entity is a player
            if (cClass->m_ClassID == (int)CSGOClassID::CCSPlayer)
            {
                if (Interfaces::Engine->GetPlayerInfo(i, &pInfo))
                {
                    if (!strstr(pInfo.name, "GOTV"))
                        Names.push_back(pInfo.name);
                }
            }
        }
    }

    int randomIndex = rand() % Names.size();
    char buffer[128];
    static unsigned long int meme = 3091961887844204720;
    sprintf_s(buffer, "Report for %s submitted, report id %lu.", Names[randomIndex].c_str(), meme);
    meme += 1;
    SayInChat(buffer);
    start_t = clock();
}

void CMiscHacks::ChatSpamRegular()
{
    // Don't spam it too fast so you can still do stuff
    static clock_t start_t = clock();
    double timeSoFar = (double)(clock() - start_t) / CLOCKS_PER_SEC;
    if (timeSoFar < 0.5)
        return;

    SayInChat("Aliens exist. #AliensInCSGOConfirmed");

    start_t = clock();
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

Vector GetAutostrafeView();

class CMiscHacks : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        void AutoJump(CUserCmd* pCmd);
void AutoStrafe(CUserCmd* pCmd);
void ChatSpamRegular();
void ChatSpamReports();
};/*
Syn's AYYWAREFramework 2015
*/

// Credits to Valve and Shad0w

#include "NetVars.h"
#include "ClientRecvProps.h"
#include "CRC32.h"
#include "Utilities.h"

#include "SDK.h"

CNetVar NetVar;

const char* AlignText(int align)
{
        static char buffer[256];
int i = 0;
        for (i = 0; i         {
                buffer[i] = ' ';
        }
        buffer[i + 1] = 0;
        return buffer;
}

void CNetVar::RetrieveClasses()
{
    Utilities::EnableLogFile(NETVAR_FILENAME);

    ClientClass* clientClass = Interfaces::Client->GetAllClasses();

    if (!clientClass)
        return;

    //Clear netvar vector incase of another call, not necesarry as it doesnt add duplicates

    vars.clear();

    while (clientClass != 0)
    {
        if (clientClass == 0)
            break;

        LogNetVar(clientClass->m_pRecvTable, 0);

        clientClass = clientClass->m_pNext;
    }
}

void CNetVar::LogNetVar(RecvTable* table, int align)
{
    if (table->m_nProps < 0)
        return;

    if (align)
        Utilities::Log("%s===%s===", AlignText(20 + align), table->m_pNetTableName);
    else
        Utilities::Log(table->m_pNetTableName);

    for (auto i = 0; i < table->m_nProps; ++i)
    {
        RecvProp* prop = &table->m_pProps[i];

        if (!prop)
            continue;

        char szCRC32[150];

        sprintf_s(szCRC32, "%s%s", table->m_pNetTableName, prop->m_pVarName);

        DWORD_PTR dwCRC32 = CRC32((void*)szCRC32, strlen(szCRC32));

        Utilities::Log("%s%s [0x%X] [CRC32::0x%X]", AlignText(15 + align), prop->m_pVarName, prop->m_Offset, dwCRC32);

        //Dont add duplicates

        bool bAddNetVar = true;

        for (auto netvar = 0; netvar < (int)vars.size(); ++netvar)
        {
            netvar_info_s* netvars = &vars[netvar];

            if (netvars->dwCRC32 == dwCRC32)
                bAddNetVar = false;


            if (netvars->dwCRC32 == dwCRC32 && netvars->dwOffset != prop->m_Offset) //just a test if any crc collide with another (didnt happen obviously)
            {
                Utilities::Log("^^^^ ERROR HASH %s%s::%s [0x%X] [CRC32::0x%X] ^^^^", AlignText(15 + align), table->m_pNetTableName, prop->m_pVarName, prop->m_Offset, dwCRC32);
                Utilities::Log("^^^^ CONFLICT %s%s::%s [0x%X] [CRC32::0x%X] ^^^^", AlignText(15 + align), netvars->szTableName, netvars->szPropName, netvars->dwOffset, netvars->dwCRC32);
            }
        }

        if (bAddNetVar) //avoid adding duplicates (faster lookup)
        {
            netvar_info_s tmp;
            strcpy_s(tmp.szTableName, table->m_pNetTableName);
            strcpy_s(tmp.szPropName, prop->m_pVarName);
            tmp.dwCRC32 = dwCRC32;

            tmp.dwOffset = prop->m_Offset;

            vars.push_back(tmp);
        }

        if (prop->m_pDataTable)
            LogNetVar(prop->m_pDataTable, 5);
    }
}

DWORD_PTR CNetVar::GetNetVar(DWORD_PTR dwCRC32) //returns 0xFFFFFFFF (-1) if not found (ex: if(GetNetVar(0xD34DB33F)==-1) return false;
{
    for (auto i = 0; i < (int)vars.size(); ++i)
    {
        if (vars[i].dwCRC32 == dwCRC32)
            return vars[i].dwOffset;
    }

    return 0xFFFFFFFF;
}/*
Syn's AYYWAREFramework 2015
*/

#include "Offsets.h"

void Offsets::Initialise()
{
    // Modules
    Modules::Client = Utilities::Memory::WaitOnModuleHandle("client.dll");
    Modules::Engine = Utilities::Memory::WaitOnModuleHandle("engine.dll");
    Modules::VGUI2 = Utilities::Memory::WaitOnModuleHandle("vgui2.dll");
    Modules::VGUISurface = Utilities::Memory::WaitOnModuleHandle("vguimatsurface.dll");
    Modules::Material = Utilities::Memory::WaitOnModuleHandle("materialsystem.dll");
    Modules::VPhysics = Utilities::Memory::WaitOnModuleHandle("vphysics.dll");
    Modules::Stdlib = Utilities::Memory::WaitOnModuleHandle("vstdlib.dll");

    //------------------------------------------------------------------------
    // VTables
#pragma region VTables
    VMT::CHL_GetAllClasses = 8;

    VMT::Engine_GetScreenSize = 5;
    VMT::Engine_GetPlayerInfo = 8;
    VMT::Engine_GetLocalPlayer = 12;
    VMT::Engine_Time = 14;
    VMT::Engine_GetViewAngles = 18;
    VMT::Engine_SetViewAngles = 19;
    VMT::Engine_GetMaxClients = 20;
    VMT::Engine_IsConnected = 27;
    VMT::Engine_IsInGame = 26;
    VMT::Engine_WorldToScreenMatrix = 37;
    VMT::Engine_ClientCmd_Unrestricted = 114;

    VMT::Panel_GetName = 36;
    VMT::Panel_PaintTraverse = 41;

    VMT::Surface_DrawSetColorA = 14;
    VMT::Surface_DrawSetColorB = 15;
    VMT::Surface_DrawFilledRect = 16;
    VMT::Surface_DrawOutlinedRect = 18;
    VMT::Surface_DrawLine = 19;
    VMT::Surface_DrawSetTextFont = 23;
    VMT::Surface_DrawSetTextColorA = 24;
    VMT::Surface_DrawSetTextColorB = 25;
    VMT::Surface_DrawSetTextPos = 26;
    VMT::Surface_DrawPrintText = 28;
    VMT::Surface_DrawSetTextureRGBA = 37;
    VMT::Surface_DrawSetTexture = 38;
    VMT::Surface_CreateNewTextureID = 43;
    VMT::Surface_FontCreate = 71;
    VMT::Surface_SetFontGlyphSet = 72;
    VMT::Surface_GetTextSize = 79;
    VMT::Surface_DrawOutlinedCircle = 103;
    VMT::Surface_SurfaceGetCursorPos = 66;
    VMT::Surface_DrawTexturedPolygon = 106;

    VMT::Material_GetName = 0;
    VMT::Material_SetMaterialVarFlag = 30;
    VMT::Material_GetMaterialVarFlag = 31;
    VMT::Material_AlphaModulate = 28;
    VMT::Material_ColorModulate = 29;
    VMT::Material_IncrementReferenceCount = 14;

    VMT::MaterialSystem_FindMaterial = 84;
    VMT::MaterialSystem_CreateMaterial = 83;

    VMT::ModelRender_ForcedMaterialOverride = 1;
    VMT::ModelRender_DrawModelExecute = 21;

    VMT::ModelInfo_GetModelName = 3;
    VMT::ModelInfo_GetStudiomodel = 30;

    VMT::RenderView_SetBlend = 4;
    VMT::RenderView_SetColorModulation = 6;

#pragma endregion Contains the VTable Indexs

    // An update changed the VTable offset for GetSpread.
    // Just incase ;)
    DWORD VMT_SpreadAddress = (DWORD)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x8B\x80\x00\x00\x00\x00\xFF\xD0\x51\xD9\x1C\x24\x0F\xB6\xC3\x8B\x5C\x24\x30", "xx????xxxxxxxxxxxxx");
    if (VMT_SpreadAddress)
    {
        VMT::Weapon_GetSpread = *(DWORD*)(VMT_SpreadAddress + 2);
        VMT::Weapon_GetSpread = (VMT::Weapon_GetSpread / 4);
    }

    // I cbf trying to get the KeyValues part of the SDK working solo, so we'll just
    // Do some dirty shit
    Functions::KeyValues_KeyValues = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x68\x00\x00\x00\x00\x8B\xC8\xE8\x00\x00\x00\x00\x89\x45\xFC\xEB\x07\xC7\x45\x00\x00\x00\x00\x00\x8B\x03\x56", "x????xxx????xxxxxxx?????xxx");
    Functions::KeyValues_KeyValues += 7;
    Functions::KeyValues_KeyValues = Functions::KeyValues_KeyValues + *reinterpret_cast(Functions::KeyValues_KeyValues + 1) + 5;

    Functions::KeyValues_LoadFromBuffer = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\xE8\x00\x00\x00\x00\x8A\xD8\xFF\x15\x00\x00\x00\x00\x84\xDB", "x????xxxx????xx");
    Functions::KeyValues_LoadFromBuffer = Functions::KeyValues_LoadFromBuffer + *reinterpret_cast(Functions::KeyValues_LoadFromBuffer + 1) + 5;

    Functions::dwCalcPlayerView = Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x84\xC0\x75\x08\x57\x8B\xCE\xE8\x00\x00\x00\x00\x8B\x06", "xxxxxxxx????xx");

    Utilities::Log("Offsets/Indexes Up to Date");
}

namespace Offsets
{
    // Addresses of loaded game modules
    namespace Modules
    {
        DWORD Client;
        DWORD Engine;
        DWORD VGUI2;
        DWORD VGUISurface;
        DWORD Material;
        DWORD VPhysics;
        DWORD Stdlib;
    };

    // Virtual Method Table Indexes
    namespace VMT
    {
        //CHL Client
        DWORD CHL_GetAllClasses;

        //Engine Client
        DWORD Engine_GetScreenSize;
        DWORD Engine_GetPlayerInfo;
        DWORD Engine_GetLocalPlayer;
        DWORD Engine_Time;
        DWORD Engine_GetViewAngles;
        DWORD Engine_SetViewAngles;
        DWORD Engine_GetMaxClients;
        DWORD Engine_IsConnected;
        DWORD Engine_IsInGame;
        DWORD Engine_WorldToScreenMatrix;
        DWORD Engine_ClientCmd_Unrestricted;

        // Panels
        DWORD Panel_GetName;
        DWORD Panel_PaintTraverse;

        // Surface
        DWORD Surface_DrawSetColorA;
        DWORD Surface_DrawSetColorB;
        DWORD Surface_DrawFilledRect;
        DWORD Surface_DrawOutlinedRect;
        DWORD Surface_DrawLine;
        DWORD Surface_DrawSetTextFont;
        DWORD Surface_DrawSetTextColorA;
        DWORD Surface_DrawSetTextColorB;
        DWORD Surface_DrawSetTextPos;
        DWORD Surface_DrawPrintText;
        DWORD Surface_DrawSetTextureRGBA;
        DWORD Surface_DrawSetTexture;
        DWORD Surface_CreateNewTextureID;
        DWORD Surface_FontCreate;
        DWORD Surface_SetFontGlyphSet;
        DWORD Surface_GetTextSize;
        DWORD Surface_DrawOutlinedCircle;
        DWORD Surface_SurfaceGetCursorPos;
        DWORD Surface_DrawTexturedPolygon;

        DWORD Material_GetName;
        DWORD Material_SetMaterialVarFlag;
        DWORD Material_GetMaterialVarFlag;
        DWORD Material_AlphaModulate;
        DWORD Material_ColorModulate;
        DWORD Material_IncrementReferenceCount;

        DWORD MaterialSystem_FindMaterial;
        DWORD MaterialSystem_CreateMaterial;

        DWORD ModelRender_ForcedMaterialOverride;
        DWORD ModelRender_DrawModelExecute;

        DWORD ModelInfo_GetModelName;
        DWORD ModelInfo_GetStudiomodel;

        DWORD RenderView_SetBlend;
        DWORD RenderView_SetColorModulation;

        // Weapon entities
        DWORD Weapon_GetSpread;
    };

    // Addresses of engine functions to call
    namespace Functions
    {
        DWORD KeyValues_KeyValues;
        DWORD KeyValues_LoadFromBuffer;
        DWORD dwCalcPlayerView;
    };

};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Utilities.h"

// Various offsets
namespace Offsets
{
    // Sets up all the shit we need
    void Initialise();

    // Addresses of loaded game modules
    namespace Modules
    {
        extern DWORD Client;
                extern DWORD Engine;
                extern DWORD VGUI2;
                extern DWORD VGUISurface;
                extern DWORD Material;
                extern DWORD VPhysics;
                extern DWORD Stdlib;
        };

    // Virtual Method Table Indexes
    namespace VMT
    {
        //CHL Client
        extern DWORD CHL_GetAllClasses;

                //Engine Client
                extern DWORD Engine_GetScreenSize;
                extern DWORD Engine_GetPlayerInfo;
                extern DWORD Engine_GetLocalPlayer;
                extern DWORD Engine_Time;
                extern DWORD Engine_GetViewAngles;
                extern DWORD Engine_SetViewAngles;
                extern DWORD Engine_GetMaxClients;
                extern DWORD Engine_IsConnected;
                extern DWORD Engine_IsInGame;
                extern DWORD Engine_WorldToScreenMatrix;
                extern DWORD Engine_ClientCmd_Unrestricted;

                // Panels
                extern DWORD Panel_GetName;
                extern DWORD Panel_PaintTraverse;

                // Surface
                extern DWORD Surface_DrawSetColorA;
                extern DWORD Surface_DrawSetColorB;
                extern DWORD Surface_DrawFilledRect;
                extern DWORD Surface_DrawOutlinedRect;
                extern DWORD Surface_DrawLine;
                extern DWORD Surface_DrawSetTextFont;
                extern DWORD Surface_DrawSetTextColorA;
                extern DWORD Surface_DrawSetTextColorB;
                extern DWORD Surface_DrawSetTextPos;
                extern DWORD Surface_DrawPrintText;
                extern DWORD Surface_DrawSetTextureRGBA;
                extern DWORD Surface_DrawSetTexture;
                extern DWORD Surface_CreateNewTextureID;
                extern DWORD Surface_FontCreate;
                extern DWORD Surface_SetFontGlyphSet;
                extern DWORD Surface_GetTextSize;
                extern DWORD Surface_DrawOutlinedCircle;
                extern DWORD Surface_SurfaceGetCursorPos;
                extern DWORD Surface_DrawTexturedPolygon;

                extern DWORD Material_GetName;
                extern DWORD Material_SetMaterialVarFlag;
                extern DWORD Material_GetMaterialVarFlag;
                extern DWORD Material_AlphaModulate;
                extern DWORD Material_ColorModulate;
                extern DWORD Material_IncrementReferenceCount;

                extern DWORD MaterialSystem_FindMaterial;
                extern DWORD MaterialSystem_CreateMaterial;

                extern DWORD ModelRender_ForcedMaterialOverride;
                extern DWORD ModelRender_DrawModelExecute;

                extern DWORD ModelInfo_GetModelName;
                extern DWORD ModelInfo_GetStudiomodel;
                
                extern DWORD RenderView_SetBlend;
                extern DWORD RenderView_SetColorModulation;

                // Weapon entities
                extern DWORD Weapon_GetSpread;
        };

    // Addresses of engine functions to call
    namespace Functions
    {
        extern DWORD KeyValues_KeyValues;
                extern DWORD KeyValues_LoadFromBuffer;
                extern DWORD dwCalcPlayerView;
        };

};#include "RageBot.h"
#include "RenderManager.h"
#include "Autowall.h"

void CRageBot::Init()
{
    IsAimStepping = false;
    IsLocked = false;
    TargetID = -1;
}

void CRageBot::Draw()
{

}

void CRageBot::Move(CUserCmd* pCmd)
{
    // Master switch
    if (!Menu::Window.RageBotTab.Active.GetState())
        return;

    // Aimbot
    if (Menu::Window.RageBotTab.AimbotEnable.GetState())
        DoAimbot(pCmd);

    // Recoil
    if (Menu::Window.RageBotTab.AccuracyRecoil.GetState())
        DoNoRecoil(pCmd);

    // No Spread
    if (Menu::Window.RageBotTab.AccuracySpread.GetState())
        DoNoSpread(pCmd);

    // Anti-Aim
    if (Menu::Window.RageBotTab.AntiAimEnable.GetState())
        DoAntiAim(pCmd);

    if (Menu::Window.RageBotTab.AimbotAimStep.GetState())
    {
        Vector AddAngs = pCmd->viewangles - LastAngle;
        if (AddAngs.Length2D() > 25.f)
        {
            Normalize(AddAngs, AddAngs);
            AddAngs *= 25;
            pCmd->viewangles = LastAngle + AddAngs;
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
        }
    }

    LastAngle = pCmd->viewangles;
}

// Functionality
void CRageBot::DoAimbot(CUserCmd* pCmd)
{
    IClientEntity* pTarget = nullptr;
    IClientEntity* pLocal = hackManager.pLocal();
    bool FindNewTarget = true;
    //IsLocked = false;

    // Don't aimbot with the knife..
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(pLocal->GetActiveWeaponHandle());
    if (pWeapon)
    {
        if (pWeapon->GetAmmoInClip() == 0 || !GameUtils::IsBallisticWeapon(pWeapon))
        {
            //TargetID = 0;
            //pTarget = nullptr;
            //HitBox = -1;
            return;
        }
    }
    else
        return;

    // Make sure we have a good target
    if (IsLocked && TargetID >= 0 && HitBox >= 0)
    {
        pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        if (pTarget && TargetMeetsRequirements(pTarget))
        {
            HitBox = HitScan(pTarget);
            if (HitBox >= 0)
            {
                Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
                Vector View; Interfaces::Engine->GetViewAngles(View);
                float FoV = FovToPlayer(ViewOffset, View, pTarget, HitBox);
                if (FoV < Menu::Window.RageBotTab.AimbotFov.GetValue())
                    FindNewTarget = false;
            }
        }
    }

    // Find a new target, apparently we need to
    if (FindNewTarget)
    {
        TargetID = 0;
        pTarget = nullptr;
        HitBox = -1;

        // Target selection type
        switch (Menu::Window.RageBotTab.TargetSelection.GetIndex())
        {
            case 0:
                TargetID = GetTargetCrosshair();
                break;
            case 1:
                TargetID = GetTargetDistance();
                break;
            case 2:
                TargetID = GetTargetHealth();
                break;
        }

        // Memes
        if (TargetID >= 0)
        {
            pTarget = Interfaces::EntList->GetClientEntity(TargetID);
        }
        else
        {
            pTarget = nullptr;
            HitBox = -1;
        }
    }

    // If we finally have a good target
    if (TargetID >= 0 && pTarget)
    {
        HitBox = HitScan(pTarget);

        // Key
        if (Menu::Window.RageBotTab.AimbotKeyPress.GetState())
        {
            int Key = Menu::Window.RageBotTab.AimbotKeyBind.GetKey();
            if (Key >= 0 && !GUI.GetKeyState(Key))
            {
                TargetID = -1;
                pTarget = nullptr;
                HitBox = -1;
                return;
            }
        }

        Vector AimPoint = GetHitboxPosition(pTarget, HitBox);

        float Spread = pWeapon->GetInaccuracy();

        if (!Menu::Window.RageBotTab.AccuracySpreadLimit.GetState() || Spread <= (Menu::Window.RageBotTab.AccuracyMinimumSpread.GetValue() / 100.f))
        {
            if (AimAtPoint(pLocal, AimPoint, pCmd))
            {
                //IsLocked = true;
                if (Menu::Window.RageBotTab.AimbotAutoFire.GetState() && !(pCmd->buttons & IN_ATTACK))
                {
                    pCmd->buttons |= IN_ATTACK;
                }
            }
        }

        if (Menu::Window.RageBotTab.AccuracyAutoStop.GetState())
        {
            pCmd->forwardmove = 0.f;
            pCmd->sidemove = 0.f;
        }

        if (Menu::Window.RageBotTab.AccuracyAutoCrouch.GetState())
        {
            pCmd->buttons |= IN_DUCK;
        }

    }

    // Auto Pistol
    static bool WasFiring = false;
    CSWeaponInfo* WeaponInfo = pWeapon->GetCSWpnData();
    if (!WeaponInfo->m_IsFullAuto && Menu::Window.RageBotTab.AimbotAutoPistol.GetState())
    {
        if (pCmd->buttons & IN_ATTACK)
        {
            if (WasFiring)
            {
                pCmd->buttons &= ~IN_ATTACK;
            }
        }

        WasFiring = pCmd->buttons & IN_ATTACK ? true : false;
    }


}

bool CRageBot::TargetMeetsRequirements(IClientEntity* pEntity)
{
    // Is a valid player
    if (pEntity && pEntity->IsDormant() == false && pEntity->IsAlive() && pEntity->GetIndex() != hackManager.pLocal()->GetIndex())
    {
        // Entity Type checks
        ClientClass* pClientClass = pEntity->GetClientClass();
        player_info_t pinfo;
        if (pClientClass->m_ClassID == (int)CSGOClassID::CCSPlayer && Interfaces::Engine->GetPlayerInfo(pEntity->GetIndex(), &pinfo))
        {
            // Team Check
            if (pEntity->GetTeamNum() != hackManager.pLocal()->GetTeamNum() || Menu::Window.RageBotTab.TargetFriendlyFire.GetState())
            {
                // Spawn Check
                if (!pEntity->HasGunGameImmunity())
                {
                    return true;
                }
            }
        }
    }

    // They must have failed a requirement
    return false;
}

float CRageBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int aHitBox)
{
    // Anything past 180 degrees is just going to wrap around
    CONST FLOAT MaxDegrees = 180.0f;

    // Get local angles
    Vector Angles = View;

    // Get local view / eye position
    Vector Origin = ViewOffSet;

    // Create and intiialize vectors for calculations below
    Vector Delta(0, 0, 0);
    //Vector Origin(0, 0, 0);
    Vector Forward(0, 0, 0);

    // Convert angles to normalized directional forward vector
    AngleVectors(Angles, &Forward);
    Vector AimPos = GetHitboxPosition(pEntity, aHitBox);
    // Get delta vector between our local eye position and passed vector
    VectorSubtract(AimPos, Origin, Delta);
    //Delta = AimPos - Origin;

    // Normalize our delta vector
    Normalize(Delta, Delta);

    // Get dot product between delta position and directional forward vectors
    FLOAT DotProduct = Forward.Dot(Delta);

    // Time to calculate the field of view
    return (acos(DotProduct) * (MaxDegrees / PI));
}

int CRageBot::GetTargetCrosshair()
{
    // Target selection
    int target = -1;
    float minFoV = Menu::Window.RageBotTab.AimbotFov.GetValue();

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (fov < minFoV)
                {
                    minFoV = fov;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::GetTargetDistance()
{
    // Target selection
    int target = -1;
    int minDist = 99999;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                Vector Difference = pLocal->GetOrigin() - pEntity->GetOrigin();
                int Distance = Difference.Length();
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (Distance < minDist && fov < Menu::Window.RageBotTab.AimbotFov.GetValue())
                {
                    minDist = Distance;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::GetTargetHealth()
{
    // Target selection
    int target = -1;
    int minHealth = 101;

    IClientEntity* pLocal = hackManager.pLocal();
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector View; Interfaces::Engine->GetViewAngles(View);

    for (int i = 0; i < Interfaces::EntList->GetHighestEntityIndex(); i++)
    {
        IClientEntity* pEntity = Interfaces::EntList->GetClientEntity(i);
        if (TargetMeetsRequirements(pEntity))
        {
            int NewHitBox = HitScan(pEntity);
            if (NewHitBox >= 0)
            {
                int Health = pEntity->GetHealth();
                float fov = FovToPlayer(ViewOffset, View, pEntity, 0);
                if (Health < minHealth && fov < Menu::Window.RageBotTab.AimbotFov.GetValue())
                {
                    minHealth = Health;
                    target = i;
                }
            }
        }
    }

    return target;
}

int CRageBot::HitScan(IClientEntity* pEntity)
{
    std::vector HitBoxesToScan;
    bool AWall = Menu::Window.RageBotTab.AccuracyAutoWall.GetState();

    // Get the hitboxes to scan
#pragma region GetHitboxesToScan
    int HitScanMode = Menu::Window.RageBotTab.TargetHitscan.GetIndex();
    if (HitScanMode == 0)
    {
        // No Hitscan, just a single hitbox
        switch (Menu::Window.RageBotTab.TargetHitbox.GetIndex())
        {
            case 0:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                break;
            case 1:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                break;
            case 2:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                break;
            case 3:
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                break;
        }
    }
    else
    {
        switch (HitScanMode)
        {
            case 1:
                // head/body
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                break;
            case 2:
                // basic +(arms, thighs)
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightThigh);
            case 3:
                // heaps ++(just all the random shit)
                HitBoxesToScan.push_back((int)CSGOHitboxID::Head);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Neck);
                HitBoxesToScan.push_back((int)CSGOHitboxID::UpperChest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Chest);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Stomach);
                HitBoxesToScan.push_back((int)CSGOHitboxID::Pelvis);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightUpperArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightThigh);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftHand);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightHand);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftFoot);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightFoot);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftShin);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightShin);
                HitBoxesToScan.push_back((int)CSGOHitboxID::LeftLowerArm);
                HitBoxesToScan.push_back((int)CSGOHitboxID::RightLowerArm);
        }
    }
#pragma endregion Get the list of shit to scan

    // check hits
    for (auto HitBoxID : HitBoxesToScan)
    {
        if (AWall)
        {
            Vector Point = GetHitboxPosition(pEntity, HitBoxID);
            float Damage = 0.f;
            Color c = Color(255, 255, 255, 255);
            if (CanHit(Point, &Damage))
            {
                c = Color(0, 255, 0, 255);
                if (Damage >= Menu::Window.RageBotTab.AccuracyMinimumDamage.GetValue())
                {
                    return HitBoxID;
                }
            }
        }
        else
        {
            if (GameUtils::IsVisible(hackManager.pLocal(), pEntity, HitBoxID))
                return HitBoxID;
        }
    }

    return -1;
}

void CRageBot::DoNoSpread(CUserCmd* pCmd)
{

}

void CRageBot::DoNoRecoil(CUserCmd* pCmd)
{
    // Ghetto rcs shit, implement properly later
    IClientEntity* pLocal = hackManager.pLocal();
    if (pLocal)
    {
        Vector AimPunch = pLocal->localPlayerExclusive()->GetAimPunchAngle();
        if (AimPunch.Length2D() > 0 && AimPunch.Length2D() < 150)
        {
            pCmd->viewangles -= AimPunch * 2;
            GameUtils::NormaliseViewAngle(pCmd->viewangles);
        }
    }
}

bool CRageBot::AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd)
{
    bool ReturnValue = false;
    // Get the full angles
    if (point.Length() == 0) return ReturnValue;

    Vector angles;
    Vector src = pLocal->GetOrigin() + pLocal->GetViewOffset();

    CalcAngle(src, point, angles);
    GameUtils::NormaliseViewAngle(angles);

    if (angles[0] != angles[0] || angles[1] != angles[1])
    {
        return ReturnValue;
    }


    IsLocked = true;
    //-----------------------------------------------

    // Aim Step Calcs
    Vector ViewOffset = pLocal->GetOrigin() + pLocal->GetViewOffset();
    if (!IsAimStepping)
        LastAimstepAngle = LastAngle; // Don't just use the viewangs because you need to consider aa

    float fovLeft = FovToPlayer(ViewOffset, LastAimstepAngle, Interfaces::EntList->GetClientEntity(TargetID), 0);

    if (fovLeft > 25.0f && Menu::Window.RageBotTab.AimbotAimStep.GetState())
    {
        Vector AddAngs = angles - LastAimstepAngle;
        Normalize(AddAngs, AddAngs);
        AddAngs *= 25;
        LastAimstepAngle += AddAngs;
        GameUtils::NormaliseViewAngle(LastAimstepAngle);
        angles = LastAimstepAngle;
    }
    else
    {
        ReturnValue = true;
    }

    pCmd->viewangles = angles;
    if (!Menu::Window.RageBotTab.AimbotSilentAim.GetState())
        Interfaces::Engine->SetViewAngles(angles);

    return ReturnValue;
}

namespace AntiAims
{
    // Pitches
    void StaticPitch(CUserCmd* pCmd, bool up)
    {
        if (up)
            // Up
            pCmd->viewangles.x = -88;
        else
            // Up
            pCmd->viewangles.x = 88;
    }

    void JitterPitch(CUserCmd* pCmd)
    {
        static bool up = true;
        if (up) pCmd->viewangles.x = -88;
        else pCmd->viewangles.x = 88;
        up = !up;
    }

    // Yaws
    void FastSpint(CUserCmd* pCmd)
    {
        int random = 160 + rand() % 40;
        static float current_y = pCmd->viewangles.y;
        current_y += random;
        pCmd->viewangles.y = current_y;
    }

    void SlowSpin(CUserCmd* pCmd)
    {
        int random = rand() % 100;
        int random2 = rand() % 1000;

        static bool dir;
        static float current_y = pCmd->viewangles.y;

        if (random == 1) dir = !dir;

        if (dir)
            current_y += 5;
        else
            current_y -= 5;

        pCmd->viewangles.y = current_y;

        if (random == random2)
            pCmd->viewangles.y += random;

    }

    void BackJitter(CUserCmd* pCmd)
    {
        int random = rand() % 100;

        // Small chance of starting fowards
        if (random < 98)
            // Look backwards
            pCmd->viewangles.y -= 180;

        // Some gitter
        if (random < 15)
        {
            float change = -70 + (rand() % (int)(140 + 1));
            pCmd->viewangles.y += change;
        }
        if (random == 69)
        {
            float change = -90 + (rand() % (int)(180 + 1));
            pCmd->viewangles.y += change;
        }

    }

    void Flip(CUserCmd* pCmd)
    {
        static bool back = false;
        back = !back;
        if (back)
            pCmd->viewangles.y -= 180;
    }
}

// AntiAim
void CRageBot::DoAntiAim(CUserCmd* pCmd)
{
    // If the aimbot is doing something don't do anything
    if (IsAimStepping || pCmd->buttons & IN_ATTACK)
        return;

    // Weapon shit
    CBaseCombatWeapon* pWeapon = (CBaseCombatWeapon*)Interfaces::EntList->GetClientEntityFromHandle(hackManager.pLocal()->GetActiveWeaponHandle());
    if (pWeapon)
    {
        CSWeaponInfo* pWeaponInfo = pWeapon->GetCSWpnData();
        // Knives or grenades
        if (!GameUtils::IsBallisticWeapon(pWeapon))
            return;
    }

    // Don't do antiaim
    // if (DoExit) return;

    // Anti-Aim Pitch
    switch (Menu::Window.RageBotTab.AntiAimPitch.GetIndex())
    {
        case 0:
            // No Pitch AA
            break;
        case 1:
            // up
            AntiAims::StaticPitch(pCmd, true);
            break;
        case 2:
            // Down
            AntiAims::StaticPitch(pCmd, false);
            break;
        case 3:
            // Jitter
            AntiAims::JitterPitch(pCmd);
            break;
    }

    //Anti-Aim Yaw
    switch (Menu::Window.RageBotTab.AntiAimYaw.GetIndex())
    {
        case 0:
            // No Yaw AA
            break;
        case 1:
            // Fast Spin
            AntiAims::FastSpint(pCmd);
            break;
        case 2:
            // Slow Spin
            AntiAims::SlowSpin(pCmd);
            break;
        case 3:
            // Inverse
            pCmd->viewangles.y -= 180;
            break;
        case 4:
            // Jitter
            AntiAims::BackJitter(pCmd);
            break;
        case 5:
            // Flip
            AntiAims::Flip(pCmd);
            break;
    }
}
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

class CRageBot : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        // Targetting
        int GetTargetCrosshair();
int GetTargetDistance();
int GetTargetHealth();
bool TargetMeetsRequirements(IClientEntity* pEntity);
float CRageBot::FovToPlayer(Vector ViewOffSet, Vector View, IClientEntity* pEntity, int HitBox);
int HitScan(IClientEntity* pEntity);
bool AimAtPoint(IClientEntity* pLocal, Vector point, CUserCmd* pCmd);

// Functionality
void DoAimbot(CUserCmd* pCmd);
void DoNoSpread(CUserCmd* pCmd);
void DoNoRecoil(CUserCmd* pCmd);

// AntiAim
void DoAntiAim(CUserCmd* pCmd);

// AimStep
bool IsAimStepping;
Vector LastAimstepAngle;
Vector LastAngle;

// Aimbot
bool IsLocked;
int TargetID;
int HitBox;
Vector AimPoint;
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "RenderManager.h"

#define _CRT_SECURE_NO_WARNINGS

// Font Instances
namespace Render
{
    // Text functions
    namespace Fonts
    {
        DWORD Default;
        DWORD Menu;
        DWORD MenuBold;
        DWORD ESP;
    };
};

// We don't use these anywhere else, no reason for them to be
// available anywhere else
enum EFontFlags
{
    FONTFLAG_NONE,
    FONTFLAG_ITALIC = 0x001,
    FONTFLAG_UNDERLINE = 0x002,
    FONTFLAG_STRIKEOUT = 0x004,
    FONTFLAG_SYMBOL = 0x008,
    FONTFLAG_ANTIALIAS = 0x010,
    FONTFLAG_GAUSSIANBLUR = 0x020,
    FONTFLAG_ROTARY = 0x040,
    FONTFLAG_DROPSHADOW = 0x080,
    FONTFLAG_ADDITIVE = 0x100,
    FONTFLAG_OUTLINE = 0x200,
    FONTFLAG_CUSTOM = 0x400,
    FONTFLAG_BITMAP = 0x800,
};

// Initialises the rendering system, setting up fonts etc
void Render::Initialise()
{
    Fonts::Default = 0x1D; // MainMenu Font from vgui_spew_fonts 
    Fonts::Menu = Interfaces::Surface->FontCreate();
    Fonts::MenuBold = Interfaces::Surface->FontCreate();
    Fonts::ESP = Interfaces::Surface->FontCreate();

    Interfaces::Surface->SetFontGlyphSet(Fonts::Menu, "Terminal", 14, 500, 0, 0, FONTFLAG_ANTIALIAS);
    Interfaces::Surface->SetFontGlyphSet(Fonts::MenuBold, "Terminal", 14, 900, 0, 0, FONTFLAG_ANTIALIAS);
    Interfaces::Surface->SetFontGlyphSet(Fonts::ESP, "Terminal", 14, 500, 0, 0, FONTFLAG_ANTIALIAS /*| FONTFLAG_DROPSHADOW*/);

    Utilities::Log("Render System Ready");
}

RECT Render::GetViewport()
{
    RECT Viewport = { 0, 0, 0, 0 };
    int w, h;
    Interfaces::Engine->GetScreenSize(w, h);
    Viewport.right = w; Viewport.bottom = h;
    return Viewport;
}

void Render::Clear(int x, int y, int w, int h, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawFilledRect(x, y, x + w, y + h);
}

void Render::Outline(int x, int y, int w, int h, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawOutlinedRect(x, y, x + w, y + h);
}

void Render::Line(int x, int y, int x2, int y2, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawLine(x, y, x2, y2);
}

void Render::PolyLine(int* x, int* y, int count, Color color)
{
    Interfaces::Surface->DrawSetColor(color);
    Interfaces::Surface->DrawPolyLine(x, y, count);
}

bool Render::WorldToScreen(Vector &in, Vector &out)
{
    const matrix3x4&worldToScreen = Interfaces::Engine->WorldToScreenMatrix(); //Grab the world to screen matrix from CEngineClient::WorldToScreenMatrix

    float w = worldToScreen[3][0] * in[0] + worldToScreen[3][1] * in[1] + worldToScreen[3][2] * in[2] + worldToScreen[3][3]; //Calculate the angle in compareson to the player's camera.
        out.z = 0; //Screen doesn't have a 3rd dimension.

        if (w > 0.001) //If the object is within view.
        {
                RECT ScreenSize = GetViewport();
float fl1DBw = 1 / w; //Divide 1 by the angle.
                out.x = (ScreenSize.right / 2) + (0.5f * ((worldToScreen[0][0] * in[0] + worldToScreen[0][1] * in[1] + worldToScreen[0][2] * in[2] + worldToScreen[0][3]) * fl1DBw) * ScreenSize.right + 0.5f); //Get the X dimension and push it in to the Vector.
                out.y = (ScreenSize.bottom / 2) - (0.5f * ((worldToScreen[1][0] * in[0] + worldToScreen[1][1] * in[1] + worldToScreen[1][2] * in[2] + worldToScreen[1][3]) * fl1DBw) * ScreenSize.bottom + 0.5f); //Get the Y dimension and push it in to the Vector.
                return true;
        }

        return false;
}

void Render::Text(int x, int y, Color color, DWORD font, const char* text)
{
    size_t origsize = strlen(text) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);

    Interfaces::Surface->DrawSetTextFont(font);

    Interfaces::Surface->DrawSetTextColor(color);
    Interfaces::Surface->DrawSetTextPos(x, y);
    Interfaces::Surface->DrawPrintText(wcstring, wcslen(wcstring));
    return;
}

void Render::Text(int x, int y, Color color, DWORD font, const wchar_t* text)
{
    Interfaces::Surface->DrawSetTextFont(font);
    Interfaces::Surface->DrawSetTextColor(color);
    Interfaces::Surface->DrawSetTextPos(x, y);
    Interfaces::Surface->DrawPrintText(text, wcslen(text));
}

void Render::Textf(int x, int y, Color color, DWORD font, const char* fmt, ...)
{
    if (!fmt) return; //if the passed string is null return
    if (strlen(fmt) < 2) return;

    //Set up va_list and buffer to hold the params 
    va_list va_alist;
    char logBuf[256] = { 0 };

    //Do sprintf with the parameters
    va_start(va_alist, fmt);
    _vsnprintf_s(logBuf + strlen(logBuf), 256 - strlen(logBuf), sizeof(logBuf) - strlen(logBuf), fmt, va_alist);
    va_end(va_alist);

    Text(x, y, color, font, logBuf);
}

RECT Render::GetTextSize(DWORD font, const char* text)
{
    size_t origsize = strlen(text) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, text, _TRUNCATE);

    RECT rect; int x, y;
    Interfaces::Surface->GetTextSize(font, wcstring, x, y);
    rect.left = x; rect.bottom = y;
    rect.right = x;
    return rect;
}

void Render::GradientV(int x, int y, int w, int h, Color c1, Color c2)
{
    Clear(x, y, w, h, c1);
    BYTE first = c2.r();
    BYTE second = c2.g();
    BYTE third = c2.b();
    for (int i = 0; i < h; i++)
    {
        float fi = i, fh = h;
        float a = fi / fh;
        DWORD ia = a * 255;
        Clear(x, y + i, w, 1, Color(first, second, third, ia));
    }
}

void Render::GradientH(int x, int y, int w, int h, Color c1, Color c2)
{
    Clear(x, y, w, h, c1);
    BYTE first = c2.r();
    BYTE second = c2.g();
    BYTE third = c2.b();
    for (int i = 0; i < w; i++)
    {
        float fi = i, fw = w;
        float a = fi / fw;
        DWORD ia = a * 255;
        Clear(x + i, y, 1, h, Color(first, second, third, ia));
    }
}

void Render::Polygon(int count, Vertex_t* Vertexs, Color color)
{
    static int Texture = Interfaces::Surface->CreateNewTextureID(true); //need to make a texture with procedural true
    unsigned char buffer[4] = { 255, 255, 255, 255 };//{ color.r(), color.g(), color.b(), color.a() };

    Interfaces::Surface->DrawSetTextureRGBA(Texture, buffer, 1, 1); //Texture, char array of texture, width, height
    Interfaces::Surface->DrawSetColor(color); // keep this full color and opacity use the RGBA @top to set values.
    Interfaces::Surface->DrawSetTexture(Texture); // bind texture

    Interfaces::Surface->DrawTexturedPolygon(count, Vertexs);
}

void Render::PolygonOutline(int count, Vertex_t* Vertexs, Color color, Color colorLine)
{
    static int x[128];
    static int y[128];

    Render::Polygon(count, Vertexs, color);

    for (int i = 0; i < count; i++)
    {
        x[i] = Vertexs[i].m_Position.x;
        y[i] = Vertexs[i].m_Position.y;
    }

    Render::PolyLine(x, y, count, colorLine);
}

void Render::PolyLine(int count, Vertex_t* Vertexs, Color colorLine)
{
    static int x[128];
    static int y[128];

    for (int i = 0; i < count; i++)
    {
        x[i] = Vertexs[i].m_Position.x;
        y[i] = Vertexs[i].m_Position.y;
    }

    Render::PolyLine(x, y, count, colorLine);
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Interfaces.h"

#include "Vector2D.h"

void Quad();


namespace Render
{
    void Initialise();

    // Normal Drawing functions
    void Clear(int x, int y, int w, int h, Color color);
    void Outline(int x, int y, int w, int h, Color color);
    void Line(int x, int y, int x2, int y2, Color color);
    void PolyLine(int* x, int* y, int count, Color color);
    void Polygon(int count, Vertex_t* Vertexs, Color color);
    void PolygonOutline(int count, Vertex_t* Vertexs, Color color, Color colorLine);
    void PolyLine(int count, Vertex_t* Vertexs, Color colorLine);

    // Gradient Functions
    void GradientV(int x, int y, int w, int h, Color c1, Color c2);
    void GradientH(int x, int y, int w, int h, Color c1, Color c2);

    // Text functions
    namespace Fonts
    {
        extern DWORD Default;
                extern DWORD Menu;
                extern DWORD MenuBold;
                extern DWORD ESP;

        };

    void Text(int x, int y, Color color, DWORD font, const char* text);
    void Textf(int x, int y, Color color, DWORD font, const char* fmt, ...);
    void Text(int x, int y, Color color, DWORD font, const wchar_t* text);
    RECT GetTextSize(DWORD font, const char* text);

    // Other rendering functions
    bool WorldToScreen(Vector &in, Vector &out);
    RECT GetViewport();
};

/*
Syn's AYYWAREFramework 2015
*/

#pragma once

// Our stuff
# include "Entities.h"
# include "offsets.h"
# include "ClientRecvProps.h"
# include "BaseClient.h"
# include "EngineClient.h"
# include "MiscClasses.h"
# include "Surface.h"
# include "Materials.h"


// Valve
# include "Vector.h"
# include "Vector2D.h"
# include "bspflags.h"

// Management Classes
# include "Interfaces.h"

// Functions
# include "UTIL Functions.h"
# include "MathFunctions.h"
/*
Syn's AYYWAREFramework 2015
*/

#pragma once

# include "MiscDefinitions.h"
# include "ClientRecvProps.h"
# include "offsets.h"
# include "Vector.h"
# include "MiscClasses.h"
# include "Vector2D.h"

struct Vertex_t
{
    Vector2D m_Position;
    Vector2D m_TexCoord;

    Vertex_t() { }
    Vertex_t(const Vector2D &pos, const Vector2D &coord = Vector2D(0, 0))
        {
                m_Position = pos;
                m_TexCoord = coord;
        }
void Init(const Vector2D &pos, const Vector2D &coord = Vector2D(0, 0))
{
    m_Position = pos;
    m_TexCoord = coord;
}
};

typedef Vertex_t FontVertex_t;

// Surface Drawing
class ISurface
{
    public:
        void DrawSetColor(Color col)
    {
        typedef void(__thiscall * oDrawSetColor)(PVOID, Color);
        return call_vfunc(this, Offsets::VMT::Surface_DrawSetColorA)(this, col);
    }

    void DrawSetColor(int r, int g, int b, int a)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetColorB)(this, r, g, b, a);
    }

    void DrawFilledRect(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawFilledRect)(this, x0, y0, x1, y1);
    }

    void DrawOutlinedRect(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawOutlinedRect)(this, x0, y0, x1, y1);
    }

    void DrawLine(int x0, int y0, int x1, int y1)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawLine)(this, x0, y0, x1, y1);
    }

    void DrawPolyLine(int* x, int* y, int count)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int *, int *, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawLine + 1)(this, x, y, count);
    }

    void DrawSetTextFont(unsigned long font)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, unsigned long);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextFont)(this, font);
    }

    void DrawSetTextColor(int r, int g, int b, int a)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextColorB)(this, r, g, b, a);
    }

    void DrawSetTextColor(Color col)
    {
        typedef void(__thiscall * oDrawSetTextColor)(PVOID, Color);
        return call_vfunc(this, Offsets::VMT::Surface_DrawSetTextColorA)(this, col);
    }

    void DrawSetTextPos(int x, int y)
    {
        typedef void(__thiscall * OriginalFn)(PVOID, int, int);
        call_vfunc(this, Offsets::VMT::Surface_DrawSetTextPos)(this, x, y);
    }

    void DrawPrintText(const wchar_t* text, int textLen)
        {

        typedef void(__thiscall* OriginalFn)(PVOID, const wchar_t*, int, int);
                call_vfunc(this, Offsets::VMT::Surface_DrawPrintText)(this, text, textLen, 0);
        }

void DrawSetTexture(int textureID)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawSetTexture)(this, textureID);
}

void DrawSetTextureRGBA(int textureID, unsigned char  const* colors, int w, int h)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int, unsigned char  const*, int, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawSetTextureRGBA)(this, textureID, colors, w, h);
}

int CreateNewTextureID(bool procedural)
{
    typedef int(__thiscall * oDrawSetTextColor)(PVOID, bool);
    return call_vfunc(this, Offsets::VMT::Surface_CreateNewTextureID)(this, procedural);
}

void DrawTexturedPolygon(int vtxCount, FontVertex_t* vtx, bool bClipVertices = true)
{
    typedef void(__thiscall * oDrawSetTextColor)(PVOID, int, FontVertex_t *, bool);
    return call_vfunc(this, Offsets::VMT::Surface_DrawTexturedPolygon)(this, vtxCount, vtx, bClipVertices);
}

unsigned long FontCreate()
{
    typedef unsigned int(__thiscall * OriginalFn)(PVOID);
    return call_vfunc(this, Offsets::VMT::Surface_FontCreate)(this);
}

void SetFontGlyphSet(unsigned long font, const char* windowsFontName, int tall, int weight, int blur, int scanlines, int flags)
{
    typedef void(__thiscall * OriginalFn)(PVOID, unsigned long, const char*, int, int, int, int, int, int, int);
    call_vfunc(this, Offsets::VMT::Surface_SetFontGlyphSet)(this, font, windowsFontName, tall, weight, blur, scanlines, flags, 0, 0);
}

void GetTextSize(unsigned long font, const wchar_t* text, int& wide, int& tall)
{
    typedef void(__thiscall * OriginalFn)(PVOID, unsigned long, const wchar_t*, int&, int&);
    call_vfunc(this, Offsets::VMT::Surface_GetTextSize)(this, font, text, wide, tall);
}

void DrawOutlinedCircle(int x, int y, int r, int seg)
{
    typedef void(__thiscall * oDrawOutlinedCircle)(PVOID, int, int, int, int);
    return call_vfunc(this, Offsets::VMT::Surface_DrawOutlinedCircle)(this, x, y, r, seg);
}

void SurfaceGetCursorPos(int &x, int &y)
{
    typedef void(__thiscall * oSurfaceGetCursorPos)(PVOID, int &, int &);
    return call_vfunc(this, Offsets::VMT::Surface_SurfaceGetCursorPos)(this, x, y);
}
};/*
Original code by Lee Thomason (www.grinninglizard.com)

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

#include "tinyxml2.h"

#include                 // yes, this one new style header, is in the Android SDK.
#if defined(ANDROID_NDK) || defined(__QNXNTO__)
#   include 
#   include 
#else
#   include 
#   include 
#endif

#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
        // Microsoft Visual Studio, version 2005 and higher. Not WinCE.
        /*int _snprintf_s(
           char *buffer,
           size_t sizeOfBuffer,
           size_t count,
           const char *format [,
                  argument] ...
        );*/
        static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... )
        {
                va_list va;
                va_start( va, format );
                int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
                va_end( va );
                return result;
        }

        static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va )
        {
                int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va );
                return result;
        }

        #define TIXML_VSCPRINTF        _vscprintf
        #define TIXML_SSCANF        sscanf_s
#elif defined _MSC_VER
        // Microsoft Visual Studio 2003 and earlier or WinCE
        #define TIXML_SNPRINTF        _snprintf
        #define TIXML_VSNPRINTF _vsnprintf
        #define TIXML_SSCANF        sscanf
        #if (_MSC_VER < 1400 ) && (!defined WINCE)
                // Microsoft Visual Studio 2003 and not WinCE.
                #define TIXML_VSCPRINTF   _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have.
        #else
                // Microsoft Visual Studio 2003 and earlier or WinCE.
                static inline int TIXML_VSCPRINTF( const char* format, va_list va )
                {
                        int len = 512;
                        for (;;) {
                                len = len*2;
                                char* str = new char[len]();
                                const int required = _vsnprintf(str, len, format, va);
                                delete[] str;
                                if ( required != -1 ) {
                                        TIXMLASSERT( required >= 0 );
                                        len = required;
                                        break;
                                }
                        }
                        TIXMLASSERT( len >= 0 );
                        return len;
                }
        #endif
#else
        // GCC version 3 and higher
        //#warning( "Using sn* functions." )
        #define TIXML_SNPRINTF        snprintf
        #define TIXML_VSNPRINTF        vsnprintf
        static inline int TIXML_VSCPRINTF( const char* format, va_list va)
{
    int len = vsnprintf(0, 0, format, va);
    TIXMLASSERT(len >= 0);
    return len;
}
#define TIXML_SSCANF   sscanf
#endif


static const char LINE_FEED = (char)0x0a;                        // all line endings are normalized to LF
static const char LF = LINE_FEED;
static const char CARRIAGE_RETURN = (char)0x0d;                        // CR gets filtered out
static const char CR = CARRIAGE_RETURN;
static const char SINGLE_QUOTE = '\'';
static const char DOUBLE_QUOTE = '\"';

// Bunch of unicode info at:
//                http://www.unicode.org/faq/utf_bom.html
//        ef bb bf (Microsoft "lead bytes") - designates UTF-8

static const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
static const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;

namespace tinyxml2
{

    struct Entity
    {
        const char* pattern;
        int length;
        char value;
    };

    static const int NUM_ENTITIES = 5;
    static const Entity entities[NUM_ENTITIES] = {
    { "quot", 4,    DOUBLE_QUOTE },
    { "amp", 3,     '&'  },
    { "apos", 4,    SINGLE_QUOTE },
    { "lt", 2,      '<'  },
    { "gt", 2,      '>'  }
};


    StrPair::~StrPair()
    {
        Reset();
    }


    void StrPair::TransferTo(StrPair* other)
    {
        if (this == other)
        {
            return;
        }
        // This in effect implements the assignment operator by "moving"
        // ownership (as in auto_ptr).

        TIXMLASSERT(other->_flags == 0);
        TIXMLASSERT(other->_start == 0);
        TIXMLASSERT(other->_end == 0);

        other->Reset();

        other->_flags = _flags;
        other->_start = _start;
        other->_end = _end;

        _flags = 0;
        _start = 0;
        _end = 0;
    }

    void StrPair::Reset()
    {
        if (_flags & NEEDS_DELETE)
        {
            delete[] _start;
        }
        _flags = 0;
        _start = 0;
        _end = 0;
    }


    void StrPair::SetStr( const char* str, int flags)
    {
        Reset();
        size_t len = strlen(str);
        TIXMLASSERT(_start == 0);
        _start = new char[len + 1];
        memcpy(_start, str, len + 1);
        _end = _start + len;
        _flags = flags | NEEDS_DELETE;
    }


    char* StrPair::ParseText(char* p, const char* endTag, int strFlags)
    {
        TIXMLASSERT(endTag && *endTag);

        char* start = p;
        char endChar = *endTag;
        size_t length = strlen(endTag);

        // Inner loop of text parsing.
        while (*p)
        {
            if (*p == endChar && strncmp(p, endTag, length) == 0)
            {
                Set(start, p, strFlags);
                return p + length;
            }
            ++p;
        }
        return 0;
    }


    char* StrPair::ParseName(char* p)
    {
        if (!p || !(*p))
        {
            return 0;
        }
        if (!XMLUtil::IsNameStartChar(*p))
        {
            return 0;
        }

        char* const start = p;
        ++p;
        while (*p && XMLUtil::IsNameChar(*p))
        {
            ++p;
        }

        Set(start, p, 0);
        return p;
    }


    void StrPair::CollapseWhitespace()
    {
        // Adjusting _start would cause undefined behavior on delete[]
        TIXMLASSERT((_flags & NEEDS_DELETE) == 0);
        // Trim leading space.
        _start = XMLUtil::SkipWhiteSpace(_start);

        if (*_start)
        {
            char* p = _start;   // the read pointer
            char* q = _start;   // the write pointer

            while (*p)
            {
                if (XMLUtil::IsWhiteSpace(*p))
                {
                    p = XMLUtil::SkipWhiteSpace(p);
                    if (*p == 0)
                    {
                        break;    // don't write to q; this trims the trailing space.
                    }
                    *q = ' ';
                    ++q;
                }
                *q = *p;
                ++q;
                ++p;
            }
            *q = 0;
        }
    }


    const char* StrPair::GetStr()
    {
        TIXMLASSERT(_start);
        TIXMLASSERT(_end);
        if (_flags & NEEDS_FLUSH)
        {
            *_end = 0;
            _flags ^= NEEDS_FLUSH;

            if (_flags)
            {
                char* p = _start;   // the read pointer
                char* q = _start;   // the write pointer

                while (p < _end)
                {
                    if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR)
                    {
                        // CR-LF pair becomes LF
                        // CR alone becomes LF
                        // LF-CR becomes LF
                        if (*(p + 1) == LF)
                        {
                            p += 2;
                        }
                        else
                        {
                            ++p;
                        }
                        *q++ = LF;
                    }
                    else if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF)
                    {
                        if (*(p + 1) == CR)
                        {
                            p += 2;
                        }
                        else
                        {
                            ++p;
                        }
                        *q++ = LF;
                    }
                    else if ((_flags & NEEDS_ENTITY_PROCESSING) && *p == '&')
                    {
                        // Entities handled by tinyXML2:
                        // - special entities in the entity table [in/out]
                        // - numeric character reference [in]
                        //   中 or 中

                        if (*(p + 1) == '#')
                        {
                            const int buflen = 10;
                            char buf[buflen] = { 0 };
                            int len = 0;
                            char* adjusted = const_cast(XMLUtil::GetCharacterRef(p, buf, &len));
                            if (adjusted == 0)
                            {
                                *q = *p;
                                ++p;
                                ++q;
                            }
                            else
                            {
                                TIXMLASSERT(0 <= len && len <= buflen);
                                TIXMLASSERT(q + len <= adjusted);
                                p = adjusted;
                                memcpy(q, buf, len);
                                q += len;
                            }
                        }
                        else
                        {
                            bool entityFound = false;
                            for (int i = 0; i < NUM_ENTITIES; ++i)
                            {
                                const Entity&entity = entities[i];
                                if (strncmp(p + 1, entity.pattern, entity.length) == 0
                                        && *(p + entity.length + 1) == ';')
                                {
                                    // Found an entity - convert.
                                    *q = entity.value;
                                    ++q;
                                    p += entity.length + 2;
                                    entityFound = true;
                                    break;
                                }
                            }
                            if (!entityFound)
                            {
                                // fixme: treat as error?
                                ++p;
                                ++q;
                            }
                        }
                    }
                    else
                    {
                        *q = *p;
                        ++p;
                        ++q;
                    }
                }
                *q = 0;
            }
            // The loop below has plenty going on, and this
            // is a less useful mode. Break it out.
            if (_flags & NEEDS_WHITESPACE_COLLAPSING)
            {
                CollapseWhitespace();
            }
            _flags = (_flags & NEEDS_DELETE);
        }
        TIXMLASSERT(_start);
        return _start;
    }




    // --------- XMLUtil ----------- //

    const char* XMLUtil::ReadBOM( const char* p, bool* bom)
    {
        TIXMLASSERT(p);
        TIXMLASSERT(bom);
        *bom = false;
        const unsigned char* pu = reinterpret_cast  (p);
        // Check for BOM:
        if (*(pu + 0) == TIXML_UTF_LEAD_0
                && *(pu + 1) == TIXML_UTF_LEAD_1
                && *(pu + 2) == TIXML_UTF_LEAD_2)
        {
            *bom = true;
            p += 3;
        }
        TIXMLASSERT(p);
        return p;
    }


    void XMLUtil::ConvertUTF32ToUTF8(unsigned long input, char* output, int* length)
    {
        const unsigned long BYTE_MASK = 0xBF;
        const unsigned long BYTE_MARK = 0x80;
        const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };

        if (input < 0x80)
        {
            *length = 1;
        }
        else if (input < 0x800)
        {
            *length = 2;
        }
        else if (input < 0x10000)
        {
            *length = 3;
        }
        else if (input < 0x200000)
        {
            *length = 4;
        }
        else
        {
            *length = 0;    // This code won't convert this correctly anyway.
            return;
        }

        output += *length;

        // Scary scary fall throughs.
        switch (*length)
        {
            case 4:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 3:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 2:
                --output;
                *output = (char)((input | BYTE_MARK) & BYTE_MASK);
                input >>= 6;
            case 1:
                --output;
                *output = (char)(input | FIRST_BYTE_MARK[*length]);
                break;
            default:
                TIXMLASSERT(false);
        }
    }


    const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length)
    {
        // Presume an entity, and pull it out.
        *length = 0;

        if (*(p + 1) == '#' && *(p + 2))
        {
            unsigned long ucs = 0;
            TIXMLASSERT(sizeof(ucs) >= 4);
            ptrdiff_t delta = 0;
            unsigned mult = 1;
            static const char SEMICOLON = ';';

            if (*(p + 2) == 'x')
            {
                // Hexadecimal.
                const char* q = p + 3;
                if (!(*q))
                {
                    return 0;
                }

                q = strchr(q, SEMICOLON);

                if (!q)
                {
                    return 0;
                }
                TIXMLASSERT(*q == SEMICOLON);

                delta = q - p;
                --q;

                while (*q != 'x')
                {
                    unsigned int digit = 0;

                    if (*q >= '0' && *q <= '9')
                    {
                        digit = *q - '0';
                    }
                    else if (*q >= 'a' && *q <= 'f')
                    {
                        digit = *q - 'a' + 10;
                    }
                    else if (*q >= 'A' && *q <= 'F')
                    {
                        digit = *q - 'A' + 10;
                    }
                    else
                    {
                        return 0;
                    }
                    TIXMLASSERT(digit >= 0 && digit < 16);
                    TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit);
                    const unsigned int digitScaled = mult * digit;
                    TIXMLASSERT(ucs <= ULONG_MAX - digitScaled);
                    ucs += digitScaled;
                    TIXMLASSERT(mult <= UINT_MAX / 16);
                    mult *= 16;
                    --q;
                }
            }
            else
            {
                // Decimal.
                const char* q = p + 2;
                if (!(*q))
                {
                    return 0;
                }

                q = strchr(q, SEMICOLON);

                if (!q)
                {
                    return 0;
                }
                TIXMLASSERT(*q == SEMICOLON);

                delta = q - p;
                --q;

                while (*q != '#')
                {
                    if (*q >= '0' && *q <= '9')
                    {
                        const unsigned int digit = *q - '0';
                        TIXMLASSERT(digit >= 0 && digit < 10);
                        TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit);
                        const unsigned int digitScaled = mult * digit;
                        TIXMLASSERT(ucs <= ULONG_MAX - digitScaled);
                        ucs += digitScaled;
                    }
                    else
                    {
                        return 0;
                    }
                    TIXMLASSERT(mult <= UINT_MAX / 10);
                    mult *= 10;
                    --q;
                }
            }
            // convert the UCS to UTF-8
            ConvertUTF32ToUTF8(ucs, value, length);
            return p + delta + 1;
        }
        return p + 1;
    }


    void XMLUtil::ToStr(int v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%d", v);
    }


    void XMLUtil::ToStr(unsigned v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%u", v);
    }


    void XMLUtil::ToStr(bool v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%d", v ? 1 : 0);
    }

    /*
        ToStr() of a number is a very tricky topic.
        https://github.com/leethomason/tinyxml2/issues/106
    */
    void XMLUtil::ToStr(float v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%.8g", v);
    }


    void XMLUtil::ToStr(double v, char* buffer, int bufferSize)
    {
        TIXML_SNPRINTF(buffer, bufferSize, "%.17g", v);
    }


    bool XMLUtil::ToInt( const char* str, int* value)
    {
        if (TIXML_SSCANF(str, "%d", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToUnsigned( const char* str, unsigned* value)
    {
        if (TIXML_SSCANF(str, "%u", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToBool( const char* str, bool* value)
    {
        int ival = 0;
        if (ToInt(str, &ival))
        {
            *value = (ival == 0) ? false : true;
            return true;
        }
        if (StringEqual(str, "true"))
        {
            *value = true;
            return true;
        }
        else if (StringEqual(str, "false"))
        {
            *value = false;
            return true;
        }
        return false;
    }


    bool XMLUtil::ToFloat( const char* str, float* value)
    {
        if (TIXML_SSCANF(str, "%f", value) == 1)
        {
            return true;
        }
        return false;
    }

    bool XMLUtil::ToDouble( const char* str, double* value)
    {
        if (TIXML_SSCANF(str, "%lf", value) == 1)
        {
            return true;
        }
        return false;
    }


    char* XMLDocument::Identify(char* p, XMLNode** node)
    {
        TIXMLASSERT(node);
        TIXMLASSERT(p);
        char* const start = p;
        p = XMLUtil::SkipWhiteSpace(p);
        if (!*p)
        {
            *node = 0;
            TIXMLASSERT(p);
            return p;
        }

        // These strings define the matching patterns:
        static const char* xmlHeader = { "         static const char* commentHeader = { "
    //
    // With a special case:
    //                
    //                

    //                
    //
    // Where the closing element (/foo) *must* be the next thing after the opening
    // element, and the names must match. BUT the tricky bit is that the closing
    // element will be read by the child.
    //
    // 'endTag' is the end tag for this node, it is returned by a call to a child.
    // 'parentEnd' is the end tag for the parent, which is filled in and returned.

    while (p && *p)
    {
        XMLNode* node = 0;

        p = _document->Identify(p, &node);
        if (node == 0)
        {
            break;
        }

        StrPair endTag;
        p = node->ParseDeep(p, &endTag);
        if (!p)
        {
            DeleteNode(node);
            if (!_document->Error())
            {
                _document->SetError(XML_ERROR_PARSING, 0, 0);
            }
            break;
        }

        XMLDeclaration* decl = node->ToDeclaration();
        if (decl)
        {
            // A declaration can only be the first child of a document.
            // Set error, if document already has children.
            if (!_document->NoChildren())
            {
                _document->SetError(XML_ERROR_PARSING_DECLARATION, decl->Value(), 0);
                DeleteNode(decl);
                break;
            }
        }

        XMLElement* ele = node->ToElement();
        if (ele)
        {
            // We read the end tag. Return it to the parent.
            if (ele->ClosingType() == XMLElement::CLOSING)
            {
                if (parentEnd)
                {
                    ele->_value.TransferTo(parentEnd);
                }
                node->_memPool->SetTracked();   // created and then immediately deleted.
                DeleteNode(node);
                return p;
            }

            // Handle an end tag returned to this level.
            // And handle a bunch of annoying errors.
            bool mismatch = false;
            if (endTag.Empty())
            {
                if (ele->ClosingType() == XMLElement::OPEN)
                {
                    mismatch = true;
                }
            }
            else
            {
                if (ele->ClosingType() != XMLElement::OPEN)
                {
                    mismatch = true;
                }
                else if (!XMLUtil::StringEqual(endTag.GetStr(), ele->Name()))
                {
                    mismatch = true;
                }
            }
            if (mismatch)
            {
                _document->SetError(XML_ERROR_MISMATCHED_ELEMENT, ele->Name(), 0);
                DeleteNode(node);
                break;
            }
        }
        InsertEndChild(node);
    }
    return 0;
}

void XMLNode::DeleteNode(XMLNode* node)
{
    if (node == 0)
    {
        return;
    }
    MemPool* pool = node->_memPool;
    node->~XMLNode();
    pool->Free(node);
}

void XMLNode::InsertChildPreamble(XMLNode* insertThis) const
{
    TIXMLASSERT(insertThis );
    TIXMLASSERT(insertThis->_document == _document );

    if ( insertThis->_parent )
        insertThis->_parent->Unlink(insertThis );
    else
        insertThis->_memPool->SetTracked();
}

// --------- XMLText ---------- //
char* XMLText::ParseDeep(char* p, StrPair* )
{
    const char* start = p;
    if (this->CData())
    {
        p = _value.ParseText(p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION);
        if (!p)
        {
            _document->SetError(XML_ERROR_PARSING_CDATA, start, 0);
        }
        return p;
    }
    else
    {
        int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES;
        if (_document->WhitespaceMode() == COLLAPSE_WHITESPACE)
        {
            flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING;
        }

        p = _value.ParseText(p, "<", flags);
        if (p && *p)
        {
            return p - 1;
        }
        if (!p)
        {
            _document->SetError(XML_ERROR_PARSING_TEXT, start, 0);
        }
    }
    return 0;
}


XMLNode* XMLText::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLText* text = doc->NewText(Value());  // fixme: this will always allocate memory. Intern?
text->SetCData(this->CData() );
    return text;
}


bool XMLText::ShallowEqual( const XMLNode* compare) const
{
    const XMLText* text = compare->ToText();
    return ( text && XMLUtil::StringEqual( text->Value(), Value() ) );
}


bool XMLText::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}


// --------- XMLComment ---------- //

XMLComment::XMLComment( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLComment::~XMLComment()
{
}


char* XMLComment::ParseDeep(char* p, StrPair* )
{
    // Comment parses as text.
    const char* start = p;
    p = _value.ParseText(p, "-->", StrPair::COMMENT);
    if (p == 0)
    {
        _document->SetError(XML_ERROR_PARSING_COMMENT, start, 0);
    }
    return p;
}


XMLNode* XMLComment::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLComment* comment = doc->NewComment(Value());        // fixme: this will always allocate memory. Intern?
    return comment;
}


bool XMLComment::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLComment* comment = compare->ToComment();
    return ( comment && XMLUtil::StringEqual( comment->Value(), Value() ));
}


bool XMLComment::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}


// --------- XMLDeclaration ---------- //

XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLDeclaration::~XMLDeclaration()
{
    //printf( "~XMLDeclaration\n" );
}


char* XMLDeclaration::ParseDeep(char* p, StrPair* )
{
    // Declaration parses as text.
    const char* start = p;
    p = _value.ParseText(p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION);
    if (p == 0)
    {
        _document->SetError(XML_ERROR_PARSING_DECLARATION, start, 0);
    }
    return p;
}


XMLNode* XMLDeclaration::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLDeclaration* dec = doc->NewDeclaration(Value());        // fixme: this will always allocate memory. Intern?
    return dec;
}


bool XMLDeclaration::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLDeclaration* declaration = compare->ToDeclaration();
    return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() ));
}



bool XMLDeclaration::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}

// --------- XMLUnknown ---------- //

XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode(doc )
{
}


XMLUnknown::~XMLUnknown()
{
}


char* XMLUnknown::ParseDeep(char* p, StrPair* )
{
    // Unknown parses as text.
    const char* start = p;

    p = _value.ParseText(p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION);
    if (!p)
    {
        _document->SetError(XML_ERROR_PARSING_UNKNOWN, start, 0);
    }
    return p;
}


XMLNode* XMLUnknown::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLUnknown* text = doc->NewUnknown(Value());        // fixme: this will always allocate memory. Intern?
    return text;
}


bool XMLUnknown::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLUnknown* unknown = compare->ToUnknown();
    return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() ));
}


bool XMLUnknown::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    return visitor->Visit( *this );
}

// --------- XMLAttribute ---------- //

const char* XMLAttribute::Name() const
{
    return _name.GetStr();
}

const char* XMLAttribute::Value() const
{
    return _value.GetStr();
}

char* XMLAttribute::ParseDeep(char* p, bool processEntities)
{
    // Parse using the name rules: bug fix, was using ParseText before
    p = _name.ParseName(p);
    if (!p || !*p)
    {
        return 0;
    }

    // Skip white space before =
    p = XMLUtil::SkipWhiteSpace(p);
    if (*p != '=')
    {
        return 0;
    }

    ++p;        // move up to opening quote
    p = XMLUtil::SkipWhiteSpace(p);
    if (*p != '\"' && *p != '\'')
    {
        return 0;
    }

    char endTag[2] = { *p, 0 };
    ++p;        // move past opening quote

    p = _value.ParseText(p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES);
    return p;
}


void XMLAttribute::SetName( const char* n)
{
    _name.SetStr(n);
}


XMLError XMLAttribute::QueryIntValue(int* value) const
{
    if ( XMLUtil::ToInt( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryUnsignedValue(unsigned int* value) const
{
    if ( XMLUtil::ToUnsigned( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryBoolValue(bool* value) const
{
    if ( XMLUtil::ToBool( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryFloatValue(float* value) const
{
    if ( XMLUtil::ToFloat( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


XMLError XMLAttribute::QueryDoubleValue(double* value) const
{
    if ( XMLUtil::ToDouble( Value(), value )) {
        return XML_NO_ERROR;
    }
    return XML_WRONG_ATTRIBUTE_TYPE;
}


void XMLAttribute::SetAttribute( const char* v)
{
    _value.SetStr(v);
}


void XMLAttribute::SetAttribute(int v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


void XMLAttribute::SetAttribute(unsigned v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


void XMLAttribute::SetAttribute(bool v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}

void XMLAttribute::SetAttribute(double v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}

void XMLAttribute::SetAttribute(float v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    _value.SetStr(buf);
}


// --------- XMLElement ---------- //
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode(doc ),
    _closingType( 0 ),
    _rootAttribute( 0 )
{
}


XMLElement::~XMLElement()
{
    while (_rootAttribute)
    {
        XMLAttribute* next = _rootAttribute->_next;
        DeleteAttribute(_rootAttribute);
        _rootAttribute = next;
    }
}


const XMLAttribute* XMLElement::FindAttribute( const char* name) const
{
    for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) {
        if ( XMLUtil::StringEqual( a->Name(), name ) ) {
            return a;
        }
    }
    return 0;
}


const char* XMLElement::Attribute( const char* name, const char* value) const
{
    const XMLAttribute* a = FindAttribute(name);
    if ( !a ) {
        return 0;
    }
    if ( !value || XMLUtil::StringEqual( a->Value(), value )) {
        return a->Value();
    }
    return 0;
}


const char* XMLElement::GetText() const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        return FirstChild()->Value();
    }
    return 0;
}


void XMLElement::SetText( const char* inText)
{
    if (FirstChild() && FirstChild()->ToText())
        FirstChild()->SetValue(inText);
    else
    {
        XMLText* theText = GetDocument()->NewText(inText);
        InsertFirstChild(theText);
    }
}


void XMLElement::SetText(int v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(unsigned v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(bool v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(float v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


void XMLElement::SetText(double v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    SetText(buf);
}


XMLError XMLElement::QueryIntText(int* ival) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToInt( t, ival ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryUnsignedText(unsigned* uval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToUnsigned( t, uval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryBoolText(bool* bval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToBool( t, bval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryDoubleText(double* dval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToDouble( t, dval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}


XMLError XMLElement::QueryFloatText(float* fval) const
{
    if ( FirstChild() && FirstChild()->ToText() ) {
        const char* t = FirstChild()->Value();
        if ( XMLUtil::ToFloat( t, fval ) ) {
            return XML_SUCCESS;
        }
        return XML_CAN_NOT_CONVERT_TEXT;
    }
    return XML_NO_TEXT_NODE;
}



XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name)
{
    XMLAttribute* last = 0;
    XMLAttribute* attrib = 0;
    for (attrib = _rootAttribute;
            attrib;
            last = attrib, attrib = attrib->_next)
    {
        if (XMLUtil::StringEqual(attrib->Name(), name))
        {
            break;
        }
    }
    if (!attrib)
    {
        TIXMLASSERT(sizeof(XMLAttribute) == _document->_attributePool.ItemSize());
        attrib = new (_document->_attributePool.Alloc()) XMLAttribute();
        attrib->_memPool = &_document->_attributePool;
        if (last)
        {
            last->_next = attrib;
        }
        else
        {
            _rootAttribute = attrib;
        }
        attrib->SetName(name);
        attrib->_memPool->SetTracked(); // always created and linked.
    }
    return attrib;
}


void XMLElement::DeleteAttribute( const char* name)
{
    XMLAttribute* prev = 0;
    for (XMLAttribute* a = _rootAttribute; a; a = a->_next)
    {
        if (XMLUtil::StringEqual(name, a->Name()))
        {
            if (prev)
            {
                prev->_next = a->_next;
            }
            else
            {
                _rootAttribute = a->_next;
            }
            DeleteAttribute(a);
            break;
        }
        prev = a;
    }
}


char* XMLElement::ParseAttributes(char* p)
{
    const char* start = p;
    XMLAttribute* prevAttribute = 0;

    // Read the attributes.
    while (p)
    {
        p = XMLUtil::SkipWhiteSpace(p);
        if (!(*p))
        {
            _document->SetError(XML_ERROR_PARSING_ELEMENT, start, Name());
            return 0;
        }

        // attribute.
        if (XMLUtil::IsNameStartChar(*p))
        {
            TIXMLASSERT(sizeof(XMLAttribute) == _document->_attributePool.ItemSize());
            XMLAttribute* attrib = new (_document->_attributePool.Alloc()) XMLAttribute();
            attrib->_memPool = &_document->_attributePool;
            attrib->_memPool->SetTracked();

            p = attrib->ParseDeep(p, _document->ProcessEntities());
            if (!p || Attribute(attrib->Name()))
            {
                DeleteAttribute(attrib);
                _document->SetError(XML_ERROR_PARSING_ATTRIBUTE, start, p);
                return 0;
            }
            // There is a minor bug here: if the attribute in the source xml
            // document is duplicated, it will not be detected and the
            // attribute will be doubly added. However, tracking the 'prevAttribute'
            // avoids re-scanning the attribute list. Preferring performance for
            // now, may reconsider in the future.
            if (prevAttribute)
            {
                prevAttribute->_next = attrib;
            }
            else
            {
                _rootAttribute = attrib;
            }
            prevAttribute = attrib;
        }
        // end of the tag
        else if (*p == '>')
        {
            ++p;
            break;
        }
        // end of the tag
        else if (*p == '/' && *(p + 1) == '>')
        {
            _closingType = CLOSED;
            return p + 2;        // done; sealed element.
        }
        else
        {
            _document->SetError(XML_ERROR_PARSING_ELEMENT, start, p);
            return 0;
        }
    }
    return p;
}

void XMLElement::DeleteAttribute(XMLAttribute* attribute)
{
    if (attribute == 0)
    {
        return;
    }
    MemPool* pool = attribute->_memPool;
    attribute->~XMLAttribute();
    pool->Free(attribute);
}

//
//        
//        foobar
//
char* XMLElement::ParseDeep(char* p, StrPair* strPair)
{
    // Read the element name.
    p = XMLUtil::SkipWhiteSpace(p);

    // The closing element is the  form. It is
    // parsed just like a regular element then deleted from
    // the DOM.
    if (*p == '/')
    {
        _closingType = CLOSING;
        ++p;
    }

    p = _value.ParseName(p);
    if (_value.Empty())
    {
        return 0;
    }

    p = ParseAttributes(p);
    if (!p || !*p || _closingType)
    {
        return p;
    }

    p = XMLNode::ParseDeep(p, strPair);
    return p;
}



XMLNode* XMLElement::ShallowClone(XMLDocument* doc) const
{
    if ( !doc ) {
        doc = _document;
    }
    XMLElement* element = doc->NewElement(Value());                                        // fixme: this will always allocate memory. Intern?
    for( const XMLAttribute* a = FirstAttribute(); a; a=a->Next() ) {
        element->SetAttribute(a->Name(), a->Value() );                                        // fixme: this will always allocate memory. Intern?
    }
    return element;
}


bool XMLElement::ShallowEqual( const XMLNode* compare) const
{
    TIXMLASSERT(compare );
const XMLElement* other = compare->ToElement();
    if ( other && XMLUtil::StringEqual( other->Name(), Name() )) {

        const XMLAttribute* a = FirstAttribute();
const XMLAttribute* b = other->FirstAttribute();

        while ( a && b ) {
            if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) {
                return false;
            }
            a = a->Next();
b = b->Next();
        }
        if ( a || b ) {
            // different count
            return false;
        }
        return true;
    }
    return false;
}


bool XMLElement::Accept(XMLVisitor* visitor) const
{
    TIXMLASSERT(visitor );
    if ( visitor->VisitEnter( *this, _rootAttribute ) ) {
        for ( const XMLNode* node = FirstChild(); node; node=node->NextSibling() ) {
            if ( !node->Accept(visitor ) ) {
                break;
            }
        }
    }
    return visitor->VisitExit( *this );
}


// --------- XMLDocument ----------- //

// Warning: List must match 'enum XMLError'
const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = {
    "XML_SUCCESS",
    "XML_NO_ATTRIBUTE",
    "XML_WRONG_ATTRIBUTE_TYPE",
    "XML_ERROR_FILE_NOT_FOUND",
    "XML_ERROR_FILE_COULD_NOT_BE_OPENED",
    "XML_ERROR_FILE_READ_ERROR",
    "XML_ERROR_ELEMENT_MISMATCH",
    "XML_ERROR_PARSING_ELEMENT",
    "XML_ERROR_PARSING_ATTRIBUTE",
    "XML_ERROR_IDENTIFYING_TAG",
    "XML_ERROR_PARSING_TEXT",
    "XML_ERROR_PARSING_CDATA",
    "XML_ERROR_PARSING_COMMENT",
    "XML_ERROR_PARSING_DECLARATION",
    "XML_ERROR_PARSING_UNKNOWN",
    "XML_ERROR_EMPTY_DOCUMENT",
    "XML_ERROR_MISMATCHED_ELEMENT",
    "XML_ERROR_PARSING",
    "XML_CAN_NOT_CONVERT_TEXT",
    "XML_NO_TEXT_NODE"
};


XMLDocument::XMLDocument( bool processEntities, Whitespace whitespace ) :
    XMLNode( 0 ),
    _writeBOM( false ),
    _processEntities(processEntities ),
    _errorID(XML_NO_ERROR ),
    _whitespace(whitespace ),
    _errorStr1( 0 ),
    _errorStr2( 0 ),
    _charBuffer( 0 )
{
    // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+)
    _document = this;
}


XMLDocument::~XMLDocument()
{
    Clear();
}


void XMLDocument::Clear()
{
    DeleteChildren();

#ifdef DEBUG
    const bool hadError = Error();
#endif
    _errorID = XML_NO_ERROR;
    _errorStr1 = 0;
    _errorStr2 = 0;

    delete[] _charBuffer;
    _charBuffer = 0;

#if 0
    _textPool.Trace( "text" );
    _elementPool.Trace( "element" );
    _commentPool.Trace( "comment" );
    _attributePool.Trace( "attribute" );
#endif

# ifdef DEBUG
    if (!hadError)
    {
        TIXMLASSERT(_elementPool.CurrentAllocs() == _elementPool.Untracked());
        TIXMLASSERT(_attributePool.CurrentAllocs() == _attributePool.Untracked());
        TIXMLASSERT(_textPool.CurrentAllocs() == _textPool.Untracked());
        TIXMLASSERT(_commentPool.CurrentAllocs() == _commentPool.Untracked());
    }
#endif
}


XMLElement* XMLDocument::NewElement( const char* name)
{
    TIXMLASSERT(sizeof(XMLElement) == _elementPool.ItemSize());
    XMLElement* ele = new (_elementPool.Alloc()) XMLElement(this);
    ele->_memPool = &_elementPool;
    ele->SetName(name);
    return ele;
}


XMLComment* XMLDocument::NewComment( const char* str)
{
    TIXMLASSERT(sizeof(XMLComment) == _commentPool.ItemSize());
    XMLComment* comment = new (_commentPool.Alloc()) XMLComment(this);
    comment->_memPool = &_commentPool;
    comment->SetValue(str);
    return comment;
}


XMLText* XMLDocument::NewText( const char* str)
{
    TIXMLASSERT(sizeof(XMLText) == _textPool.ItemSize());
    XMLText* text = new (_textPool.Alloc()) XMLText(this);
    text->_memPool = &_textPool;
    text->SetValue(str);
    return text;
}


XMLDeclaration* XMLDocument::NewDeclaration( const char* str)
{
    TIXMLASSERT(sizeof(XMLDeclaration) == _commentPool.ItemSize());
    XMLDeclaration* dec = new (_commentPool.Alloc()) XMLDeclaration(this);
    dec->_memPool = &_commentPool;
    dec->SetValue(str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"");
    return dec;
}


XMLUnknown* XMLDocument::NewUnknown( const char* str)
{
    TIXMLASSERT(sizeof(XMLUnknown) == _commentPool.ItemSize());
    XMLUnknown* unk = new (_commentPool.Alloc()) XMLUnknown(this);
    unk->_memPool = &_commentPool;
    unk->SetValue(str);
    return unk;
}

static FILE* callfopen( const char* filepath, const char* mode)
{
    TIXMLASSERT(filepath);
    TIXMLASSERT(mode);
#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE)
    FILE* fp = 0;
    errno_t err = fopen_s( &fp, filepath, mode );
    if ( err ) {
        return 0;
    }
#else
    FILE* fp = fopen(filepath, mode);
#endif
    return fp;
}

void XMLDocument::DeleteNode(XMLNode* node)
{
    TIXMLASSERT(node);
    TIXMLASSERT(node->_document == this);
    if (node->_parent)
    {
        node->_parent->DeleteChild(node);
    }
    else
    {
        // Isn't in the tree.
        // Use the parent delete.
        // Also, we need to mark it tracked: we 'know'
        // it was never used.
        node->_memPool->SetTracked();
        // Call the static XMLNode version:
        XMLNode::DeleteNode(node);
    }
}


XMLError XMLDocument::LoadFile( const char* filename)
{
    Clear();
    FILE* fp = callfopen(filename, "rb");
    if (!fp)
    {
        SetError(XML_ERROR_FILE_NOT_FOUND, filename, 0);
        return _errorID;
    }
    LoadFile(fp);
    fclose(fp);
    return _errorID;
}


XMLError XMLDocument::LoadFile(FILE* fp)
{
    Clear();

    fseek(fp, 0, SEEK_SET);
    if (fgetc(fp) == EOF && ferror(fp) != 0)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    fseek(fp, 0, SEEK_END);
    const long filelength = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    if (filelength == -1L)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    if ((unsigned long)filelength >= (size_t) - 1 ) {
        // Cannot handle files which won't fit in buffer together with null terminator
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    if (filelength == 0)
    {
        SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0);
        return _errorID;
    }

    const size_t size = filelength;
    TIXMLASSERT(_charBuffer == 0);
    _charBuffer = new char[size + 1];
    size_t read = fread(_charBuffer, 1, size, fp);
    if (read != size)
    {
        SetError(XML_ERROR_FILE_READ_ERROR, 0, 0);
        return _errorID;
    }

    _charBuffer[size] = 0;

    Parse();
    return _errorID;
}


XMLError XMLDocument::SaveFile( const char* filename, bool compact)
{
    FILE* fp = callfopen(filename, "w");
    if (!fp)
    {
        SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0);
        return _errorID;
    }
    SaveFile(fp, compact);
    fclose(fp);
    return _errorID;
}


XMLError XMLDocument::SaveFile(FILE* fp, bool compact)
{
    // Clear any error from the last save, otherwise it will get reported
    // for *this* call.
    SetError(XML_NO_ERROR, 0, 0);
    XMLPrinter stream(fp, compact);
    Print(&stream);
    return _errorID;
}


XMLError XMLDocument::Parse( const char* p, size_t len)
{
    Clear();

    if (len == 0 || !p || !*p)
    {
        SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0);
        return _errorID;
    }
    if (len == (size_t)(-1))
    {
        len = strlen(p);
    }
    TIXMLASSERT(_charBuffer == 0);
    _charBuffer = new char[len + 1];
    memcpy(_charBuffer, p, len);
    _charBuffer[len] = 0;

    Parse();
    if (Error())
    {
        // clean up now essentially dangling memory.
        // and the parse fail can put objects in the
        // pools that are dead and inaccessible.
        DeleteChildren();
        _elementPool.Clear();
        _attributePool.Clear();
        _textPool.Clear();
        _commentPool.Clear();
    }
    return _errorID;
}


void XMLDocument::Print(XMLPrinter* streamer) const
{
    if ( streamer ) {
        Accept(streamer );
    }
    else {
        XMLPrinter stdoutStreamer(stdout );
        Accept( &stdoutStreamer );
    }
}


void XMLDocument::SetError(XMLError error, const char* str1, const char* str2)
{
    TIXMLASSERT(error >= 0 && error < XML_ERROR_COUNT);
    _errorID = error;
    _errorStr1 = str1;
    _errorStr2 = str2;
}

const char* XMLDocument::ErrorName() const
{

    TIXMLASSERT(_errorID >= 0 && _errorID const char* errorName = _errorNames[_errorID];
    TIXMLASSERT(errorName && errorName[0] );
    return errorName;
}

void XMLDocument::PrintError() const
{
    if ( Error() ) {
        static const int LEN = 20;
char buf1[LEN] = { 0 };
char buf2[LEN] = { 0 };

        if ( _errorStr1 ) {
            TIXML_SNPRINTF(buf1, LEN, "%s", _errorStr1 );
        }
        if ( _errorStr2 ) {
            TIXML_SNPRINTF(buf2, LEN, "%s", _errorStr2 );
        }

        // Should check INT_MIN <= _errorID && _errorId <= INT_MAX, but that
        // causes a clang "always true" -Wtautological-constant-out-of-range-compare warning
        TIXMLASSERT( 0 <= _errorID && XML_ERROR_COUNT - 1 <= INT_MAX );
        printf( "XMLDocument error id=%d '%s' str1=%s str2=%s\n",
                static_cast( _errorID ), ErrorName(), buf1, buf2 );
    }
}

void XMLDocument::Parse()
{
    TIXMLASSERT(NoChildren()); // Clear() must have been called previously
    TIXMLASSERT(_charBuffer);
    char* p = _charBuffer;
    p = XMLUtil::SkipWhiteSpace(p);
    p = const_cast(XMLUtil::ReadBOM(p, &_writeBOM));
    if (!*p)
    {
        SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0);
        return;
    }
    ParseDeep(p, 0);
}

XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) :
    _elementJustOpened( false ),
    _firstElement( true ),
    _fp(file ),
    _depth(depth ),
    _textDepth( -1 ),
    _processEntities( true ),
    _compactMode(compact )
{
    for (int i = 0; i < ENTITY_RANGE; ++i)
    {
        _entityFlag[i] = false;
        _restrictedEntityFlag[i] = false;
    }
    for (int i = 0; i < NUM_ENTITIES; ++i)
    {
        const char entityValue = entities[i].value;
        TIXMLASSERT(0 <= entityValue && entityValue < ENTITY_RANGE);
        _entityFlag[(unsigned char)entityValue ] = true;
}
_restrictedEntityFlag[(unsigned char)'&'] = true;
    _restrictedEntityFlag[(unsigned char)'<'] = true;
    _restrictedEntityFlag[(unsigned char)'>'] = true;        // not required, but consistency is nice
    _buffer.Push( 0 );
}


void XMLPrinter::Print( const char* format, ... )
{
    va_list va;
    va_start(va, format);

    if (_fp)
    {
        vfprintf(_fp, format, va);
    }
    else
    {
        const int len = TIXML_VSCPRINTF(format, va);
        // Close out and re-start the va-args
        va_end(va);
        TIXMLASSERT(len >= 0);
        va_start(va, format);
        TIXMLASSERT(_buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0);
        char* p = _buffer.PushArr(len) - 1; // back up over the null terminator.
        TIXML_VSNPRINTF(p, len + 1, format, va);
    }
    va_end(va);
}


void XMLPrinter::PrintSpace(int depth)
{
    for (int i = 0; i < depth; ++i)
    {
        Print("    ");
    }
}


void XMLPrinter::PrintString( const char* p, bool restricted)
{
    // Look for runs of bytes between entities to print.
    const char* q = p;

    if (_processEntities)
    {
        const bool* flag = restricted ? _restrictedEntityFlag : _entityFlag;
        while (*q)
        {
            TIXMLASSERT(p <= q);
            // Remember, char is sometimes signed. (How many times has that bitten me?)
            if (*q > 0 && *q < ENTITY_RANGE)
            {
                // Check for entities. If one is found, flush
                // the stream up until the entity, write the
                // entity, and keep looking.
                if (flag[(unsigned char) (*q)] ) {
                    while (p < q)
                    {
                        const size_t delta = q - p;
                        // %.*s accepts type int as "precision"
                        const int toPrint = (INT_MAX < delta) ? INT_MAX : (int)delta;
                        Print("%.*s", toPrint, p);
                        p += toPrint;
                    }
                    bool entityPatternPrinted = false;
                    for (int i = 0; i < NUM_ENTITIES; ++i)
                    {
                        if (entities[i].value == *q)
                        {
                            Print("&%s;", entities[i].pattern);
                            entityPatternPrinted = true;
                            break;
                        }
                    }
                    if (!entityPatternPrinted)
                    {
                        // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release
                        TIXMLASSERT(false);
                    }
                    ++p;
                }
            }
            ++q;
            TIXMLASSERT(p <= q);
        }
    }
    // Flush the remaining string. This will be the entire
    // string if an entity wasn't found.
    TIXMLASSERT(p <= q);
    if (!_processEntities || (p < q))
    {
        Print("%s", p);
    }
}


void XMLPrinter::PushHeader(bool writeBOM, bool writeDec)
{
    if (writeBOM)
    {
        static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 };
        Print("%s", bom);
    }
    if (writeDec)
    {
        PushDeclaration("xml version=\"1.0\"");
    }
}


void XMLPrinter::OpenElement( const char* name, bool compactMode)
{
    SealElementIfJustOpened();
    _stack.Push(name);

    if (_textDepth < 0 && !_firstElement && !compactMode)
    {
        Print("\n");
    }
    if (!compactMode)
    {
        PrintSpace(_depth);
    }

    Print("<%s", name);
    _elementJustOpened = true;
    _firstElement = false;
    ++_depth;
}


void XMLPrinter::PushAttribute( const char* name, const char* value)
{
    TIXMLASSERT(_elementJustOpened);
    Print(" %s=\"", name);
    PrintString(value, false);
    Print("\"");
}


void XMLPrinter::PushAttribute( const char* name, int v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    PushAttribute(name, buf);
}


void XMLPrinter::PushAttribute( const char* name, unsigned v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    PushAttribute(name, buf);
}


void XMLPrinter::PushAttribute( const char* name, bool v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    PushAttribute(name, buf);
}


void XMLPrinter::PushAttribute( const char* name, double v)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(v, buf, BUF_SIZE);
    PushAttribute(name, buf);
}


void XMLPrinter::CloseElement(bool compactMode)
{
    --_depth;
    const char* name = _stack.Pop();

    if (_elementJustOpened)
    {
        Print("/>");
    }
    else
    {
        if (_textDepth < 0 && !compactMode)
        {
            Print("\n");
            PrintSpace(_depth);
        }
        Print("", name);
    }

    if (_textDepth == _depth)
    {
        _textDepth = -1;
    }
    if (_depth == 0 && !compactMode)
    {
        Print("\n");
    }
    _elementJustOpened = false;
}


void XMLPrinter::SealElementIfJustOpened()
{
    if (!_elementJustOpened)
    {
        return;
    }
    _elementJustOpened = false;
    Print(">");
}


void XMLPrinter::PushText( const char* text, bool cdata)
{
    _textDepth = _depth - 1;

    SealElementIfJustOpened();
    if (cdata)
    {
        Print("", text);
    }
    else
    {
        PrintString(text, true);
    }
}

void XMLPrinter::PushText(int value)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(value, buf, BUF_SIZE);
    PushText(buf, false);
}


void XMLPrinter::PushText(unsigned value)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(value, buf, BUF_SIZE);
    PushText(buf, false);
}


void XMLPrinter::PushText(bool value)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(value, buf, BUF_SIZE);
    PushText(buf, false);
}


void XMLPrinter::PushText(float value)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(value, buf, BUF_SIZE);
    PushText(buf, false);
}


void XMLPrinter::PushText(double value)
{
    char buf[BUF_SIZE];
    XMLUtil::ToStr(value, buf, BUF_SIZE);
    PushText(buf, false);
}


void XMLPrinter::PushComment( const char* comment)
{
    SealElementIfJustOpened();
    if (_textDepth < 0 && !_firstElement && !_compactMode)
    {
        Print("\n");
        PrintSpace(_depth);
    }
    _firstElement = false;
    Print("", comment);
}


void XMLPrinter::PushDeclaration( const char* value)
{
    SealElementIfJustOpened();
    if (_textDepth < 0 && !_firstElement && !_compactMode)
    {
        Print("\n");
        PrintSpace(_depth);
    }
    _firstElement = false;
    Print("", value);
}


void XMLPrinter::PushUnknown( const char* value)
{
    SealElementIfJustOpened();
    if (_textDepth < 0 && !_firstElement && !_compactMode)
    {
        Print("\n");
        PrintSpace(_depth);
    }
    _firstElement = false;
    Print("", value);
}


bool XMLPrinter::VisitEnter( const XMLDocument& doc )
{
    _processEntities = doc.ProcessEntities();
    if (doc.HasBOM())
    {
        PushHeader(true, false);
    }
    return true;
}


bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute)
{
    const XMLElement* parentElem = 0;
    if (element.Parent())
    {
        parentElem = element.Parent()->ToElement();
    }
    const bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode;
    OpenElement(element.Name(), compactMode);
    while (attribute)
    {
        PushAttribute(attribute->Name(), attribute->Value());
        attribute = attribute->Next();
    }
    return true;
}


bool XMLPrinter::VisitExit( const XMLElement& element )
{
    CloseElement(CompactMode(element));
    return true;
}


bool XMLPrinter::Visit( const XMLText& text )
{
    PushText(text.Value(), text.CData());
    return true;
}


bool XMLPrinter::Visit( const XMLComment& comment )
{
    PushComment(comment.Value());
    return true;
}

bool XMLPrinter::Visit( const XMLDeclaration& declaration )
{
    PushDeclaration(declaration.Value());
    return true;
}


bool XMLPrinter::Visit( const XMLUnknown& unknown )
{
    PushUnknown(unknown.Value());
    return true;
}

}   // namespace tinyxml2

/*
Original code by Lee Thomason (www.grinninglizard.com)

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.

Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

#ifndef TINYXML2_INCLUDED
#define TINYXML2_INCLUDED

#if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__)
#   include 
#   include 
#   include 
#   include 
#   include 
#else
#   include 
#   include 
#   include 
#   include 
#   include 
#endif

/*
   TODO: intern strings instead of allocation.
*/
/*
        gcc:
        g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe

    Formatting, Artistic Style:
        AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
*/

#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
#   ifndef DEBUG
#       define DEBUG
#   endif
#endif

#ifdef _MSC_VER
#   pragma warning(push)
#   pragma warning(disable: 4251)
#endif

#ifdef _WIN32
#   ifdef TINYXML2_EXPORT
#       define TINYXML2_LIB __declspec(dllexport)
#   elif defined(TINYXML2_IMPORT)
#       define TINYXML2_LIB __declspec(dllimport)
#   else
#       define TINYXML2_LIB
#   endif
#else
#   define TINYXML2_LIB
#endif


#if defined(DEBUG)
#   if defined(_MSC_VER)
#       // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
#       define TIXMLASSERT( x )           if ( !((void)0,(x))) { __debugbreak(); } //if ( !(x)) WinDebugBreak()
#   elif defined (ANDROID_NDK)
#       include 
#       define TIXMLASSERT( x )           if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); }
#   else
#       include 
#       define TIXMLASSERT                assert
#   endif
#   else
#       define TIXMLASSERT( x )           {}
#endif


/* Versioning, past 1.0.14:
        http://semver.org/
*/
static const int TIXML2_MAJOR_VERSION = 3;
static const int TIXML2_MINOR_VERSION = 0;
static const int TIXML2_PATCH_VERSION = 0;

namespace tinyxml2
{
    class XMLDocument;
    class XMLElement;
    class XMLAttribute;
    class XMLComment;
    class XMLText;
    class XMLDeclaration;
    class XMLUnknown;
    class XMLPrinter;

    /*
        A class that wraps strings. Normally stores the start and end
        pointers into the XML file itself, and will apply normalization
        and entity translation if actually read. Can also store (and memory
        manage) a traditional char[]
    */
    class StrPair
    {
        public:
    enum {
            NEEDS_ENTITY_PROCESSING = 0x01,
            NEEDS_NEWLINE_NORMALIZATION = 0x02,
            NEEDS_WHITESPACE_COLLAPSING = 0x04,

            TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
            TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
            ATTRIBUTE_NAME = 0,
            ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION,
            ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION,
            COMMENT = NEEDS_NEWLINE_NORMALIZATION
        };

        StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) { }
        ~StrPair();

        void Set(char* start, char* end, int flags)
        {
            Reset();
            _start = start;
            _end = end;
            _flags = flags | NEEDS_FLUSH;
        }

        const char* GetStr();

        bool Empty() const {
        return _start == _end;
    }

    void SetInternedStr( const char* str)
    {
        Reset();
        _start = const_cast(str);
    }

    void SetStr( const char* str, int flags = 0);

    char* ParseText(char* in, const char* endTag, int strFlags);
    char* ParseName(char* in );

    void TransferTo(StrPair* other);

    private:
    void Reset();
    void CollapseWhitespace();

    enum {
        NEEDS_FLUSH = 0x100,
        NEEDS_DELETE = 0x200
    };

    // After parsing, if *_end != 0, it can be set to zero.
    int _flags;
    char* _start;
    char* _end;

    StrPair( const StrPair& other );        // not supported
    void operator=(StrPair& other );        // not supported, use TransferTo()
};


/*
        A dynamic array of Plain Old Data. Doesn't support constructors, etc.
        Has a small initial memory pool, so that low or no usage will not
        cause a call to new/delete
*/
template
class DynArray
{
    public:
    DynArray()
    {
        _mem = _pool;
        _allocated = INITIAL_SIZE;
        _size = 0;
    }

    ~DynArray()
    {
        if (_mem != _pool)
        {
            delete[] _mem;
        }
    }

    void Clear()
    {
        _size = 0;
    }

    void Push(T t)
    {
        TIXMLASSERT(_size < INT_MAX);
        EnsureCapacity(_size + 1);
        _mem[_size++] = t;
    }

    T* PushArr(int count)
    {
        TIXMLASSERT(count >= 0);
        TIXMLASSERT(_size <= INT_MAX - count);
        EnsureCapacity(_size + count);
        T* ret = &_mem[_size];
        _size += count;
        return ret;
    }

    T Pop()
    {
        TIXMLASSERT(_size > 0);
        return _mem[--_size];
    }

    void PopArr(int count)
    {
        TIXMLASSERT(_size >= count);
        _size -= count;
    }

    bool Empty() const                  {
        return _size == 0;
    }

T& operator[] (int i)
{
    TIXMLASSERT(i >= 0 && i < _size);
    return _mem[i];
}

const T& operator[] (int i) const    {
        TIXMLASSERT(i>= 0 && i<_size );
        return _mem[i];
    }

    const T& PeekTop() const            {
        TIXMLASSERT(_size > 0 );
        return _mem[_size - 1];
    }

    int Size() const                    {
        TIXMLASSERT(_size >= 0 );
        return _size;
    }

    int Capacity() const                {
        TIXMLASSERT(_allocated >= INITIAL_SIZE );
        return _allocated;
    }

    const T* Mem() const                                {
        TIXMLASSERT(_mem);
        return _mem;
    }

    T* Mem()
{
    TIXMLASSERT(_mem);
    return _mem;
}

private:
    DynArray( const DynArray& ); // not supported
void operator=( const DynArray& ); // not supported

void EnsureCapacity(int cap)
{
    TIXMLASSERT(cap > 0);
    if (cap > _allocated)
    {
        TIXMLASSERT(cap <= INT_MAX / 2);
        int newAllocated = cap * 2;
        T* newMem = new T[newAllocated];
        memcpy(newMem, _mem, sizeof(T) * _size);    // warning: not using constructors, only works for PODs
        if (_mem != _pool)
        {
            delete[] _mem;
        }
        _mem = newMem;
        _allocated = newAllocated;
    }
}

T* _mem;
T _pool[INITIAL_SIZE];
int _allocated;     // objects allocated
int _size;                        // number objects in use
};


/*
        Parent virtual class of a pool for fast allocation
        and deallocation of objects.
*/
class MemPool
{
    public:
    MemPool() { }
    virtual ~MemPool() { }

    virtual int ItemSize() const = 0;
    virtual void* Alloc() = 0;
    virtual void Free(void* ) = 0;
    virtual void SetTracked() = 0;
    virtual void Clear() = 0;
};


/*
        Template child class to create pools of the correct type.
*/
template
class MemPoolT : public MemPool
{
public:
    MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) { }
~MemPoolT()
{
    Clear();
}

void Clear()
{
    // Delete the blocks.
    while (!_blockPtrs.Empty())
    {
        Block* b = _blockPtrs.Pop();
        delete b;
    }
    _root = 0;
    _currentAllocs = 0;
    _nAllocs = 0;
    _maxAllocs = 0;
    _nUntracked = 0;
}

virtual int ItemSize() const    {
        return SIZE;
    }
    int CurrentAllocs() const       {
        return _currentAllocs;
    }

    virtual void* Alloc()
{
    if (!_root)
    {
        // Need a new block.
        Block* block = new Block();
        _blockPtrs.Push(block);

        for (int i = 0; i < COUNT - 1; ++i)
        {
            block->chunk[i].next = &block->chunk[i + 1];
        }
        block->chunk[COUNT - 1].next = 0;
        _root = block->chunk;
    }
    void* result = _root;
    _root = _root->next;

    ++_currentAllocs;
    if (_currentAllocs > _maxAllocs)
    {
        _maxAllocs = _currentAllocs;
    }
    _nAllocs++;
    _nUntracked++;
    return result;
}

virtual void Free(void* mem)
{
    if (!mem)
    {
        return;
    }
    --_currentAllocs;
    Chunk* chunk = static_cast(mem);
# ifdef DEBUG
    memset(chunk, 0xfe, sizeof(Chunk));
#endif
    chunk->next = _root;
    _root = chunk;
}
void Trace( const char* name)
{
    printf("Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n",
            name, _maxAllocs, _maxAllocs * SIZE / 1024, _currentAllocs, SIZE, _nAllocs, _blockPtrs.Size());
}

void SetTracked()
{
    _nUntracked--;
}

int Untracked() const {
        return _nUntracked;
    }

        // This number is perf sensitive. 4k seems like a good tradeoff on my machine.
        // The test file is large, 170k.
        // Release:                VS2010 gcc(no opt)
        //                1k:                4000
        //                2k:                4000
        //                4k:                3900        21000
        //                16k:        5200
        //                32k:        4300
        //                64k:        4000        21000
    enum { COUNT = (4 * 1024) / SIZE }; // Some compilers do not accept to use COUNT in private part if COUNT is private

private:
    MemPoolT( const MemPoolT& ); // not supported
void operator=( const MemPoolT& ); // not supported

union Chunk
{
    Chunk*  next;
        char    mem [SIZE];
};
struct Block
{
    Chunk chunk[COUNT];
};
DynArray _blockPtrs;
Chunk* _root;

int _currentAllocs;
int _nAllocs;
int _maxAllocs;
int _nUntracked;
};



/**
        Implements the interface to the "Visitor pattern" (see the Accept() method.)
        If you call the Accept() method, it requires being passed a XMLVisitor
        class to handle callbacks. For nodes that contain other nodes (Document, Element)
        you will get called with a VisitEnter/VisitExit pair. Nodes that are always leafs
        are simply called with Visit().

        If you return 'true' from a Visit method, recursive parsing will continue. If you return
        false, no children of this node or its siblings will be visited.

        All flavors of Visit methods have a default implementation that returns 'true' (continue
        visiting). You need to only override methods that are interesting to you.

        Generally Accept() is called on the XMLDocument, although all nodes support visiting.

        You should never change the document from a callback.

        @sa XMLNode::Accept()
*/
class TINYXML2_LIB XMLVisitor
{
public:
    virtual ~XMLVisitor() { }

/// Visit a document.
virtual bool VisitEnter( const XMLDocument& /*doc*/ )
{
    return true;
}
/// Visit a document.
virtual bool VisitExit( const XMLDocument& /*doc*/ )
{
    return true;
}

/// Visit an element.
virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ )
{
    return true;
}
/// Visit an element.
virtual bool VisitExit( const XMLElement& /*element*/ )
{
    return true;
}

/// Visit a declaration.
virtual bool Visit( const XMLDeclaration& /*declaration*/ )
{
    return true;
}
/// Visit a text node.
virtual bool Visit( const XMLText& /*text*/ )
{
    return true;
}
/// Visit a comment node.
virtual bool Visit( const XMLComment& /*comment*/ )
{
    return true;
}
/// Visit an unknown node.
virtual bool Visit( const XMLUnknown& /*unknown*/ )
{
    return true;
}
};

// WARNING: must match XMLDocument::_errorNames[]
enum XMLError
{
    XML_SUCCESS = 0,
    XML_NO_ERROR = 0,
    XML_NO_ATTRIBUTE,
    XML_WRONG_ATTRIBUTE_TYPE,
    XML_ERROR_FILE_NOT_FOUND,
    XML_ERROR_FILE_COULD_NOT_BE_OPENED,
    XML_ERROR_FILE_READ_ERROR,
    XML_ERROR_ELEMENT_MISMATCH,
    XML_ERROR_PARSING_ELEMENT,
    XML_ERROR_PARSING_ATTRIBUTE,
    XML_ERROR_IDENTIFYING_TAG,
    XML_ERROR_PARSING_TEXT,
    XML_ERROR_PARSING_CDATA,
    XML_ERROR_PARSING_COMMENT,
    XML_ERROR_PARSING_DECLARATION,
    XML_ERROR_PARSING_UNKNOWN,
    XML_ERROR_EMPTY_DOCUMENT,
    XML_ERROR_MISMATCHED_ELEMENT,
    XML_ERROR_PARSING,
    XML_CAN_NOT_CONVERT_TEXT,
    XML_NO_TEXT_NODE,

    XML_ERROR_COUNT
};


/*
        Utility functionality.
*/
class XMLUtil
{
    public:
    static const char* SkipWhiteSpace( const char* p )        {
        TIXMLASSERT(p );
        while( IsWhiteSpace(*p) ) {
            ++p;
        }
        TIXMLASSERT(p );
        return p;
    }
    static char* SkipWhiteSpace(char* p)
{
    return const_cast(SkipWhiteSpace(const_cast  (p) ) );
}

// Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't
// correct, but simple, and usually works.
static bool IsWhiteSpace(char p)
{
    return !IsUTF8Continuation(p) && isspace(static_cast < unsigned char > (p));
}

inline static bool IsNameStartChar(unsigned char ch)
{
    if (ch >= 128)
    {
        // This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
        return true;
    }
    if (isalpha(ch))
    {
        return true;
    }
    return ch == ':' || ch == '_';
}

inline static bool IsNameChar(unsigned char ch)
{
    return IsNameStartChar(ch)
           || isdigit(ch)
           || ch == '.'
           || ch == '-';
}

inline static bool StringEqual( const char* p, const char* q, int nChar = INT_MAX)
{
    if (p == q)
    {
        return true;
    }
    int n = 0;
    while (*p && *q && *p == *q && n < nChar)
    {
        ++p;
        ++q;
        ++n;
    }
    if ((n == nChar) || (*p == 0 && *q == 0))
    {
        return true;
    }
    return false;
}

inline static bool IsUTF8Continuation(char p)
{
    return (p & 0x80) != 0;
}

static const char* ReadBOM( const char * p, bool * hasBOM );
    // p is the starting location,
    // the UTF-8 value of the entity will be placed in value, and length filled in.
    static const char* GetCharacterRef( const char * p, char * value, int * length );
    static void ConvertUTF32ToUTF8(unsigned long input, char* output, int* length);

// converts primitive types to strings
static void ToStr(int v, char* buffer, int bufferSize);
static void ToStr(unsigned v, char* buffer, int bufferSize);
static void ToStr(bool v, char* buffer, int bufferSize);
static void ToStr(float v, char* buffer, int bufferSize);
static void ToStr(double v, char* buffer, int bufferSize);

// converts strings to primitive types
static bool ToInt( const char* str, int* value);
static bool ToUnsigned( const char* str, unsigned* value);
static bool ToBool( const char* str, bool* value);
static bool ToFloat( const char* str, float* value);
static bool ToDouble( const char* str, double* value);
};


/** XMLNode is a base class for every object that is in the
        XML Document Object Model (DOM), except XMLAttributes.
        Nodes have siblings, a parent, and children which can
        be navigated. A node is always in a XMLDocument.
        The type of a XMLNode can be queried, and it can
        be cast to its more defined type.

        A XMLDocument allocates memory for all its Nodes.
        When the XMLDocument gets deleted, all its Nodes
        will also be deleted.

        @verbatim
        A Document can contain:        Element        (container or leaf)
                                                        Comment (leaf)
                                                        Unknown (leaf)
                                                        Declaration( leaf )

        An Element can contain:        Element (container or leaf)
                                                        Text        (leaf)
                                                        Attributes (not on tree)
                                                        Comment (leaf)
                                                        Unknown (leaf)

        @endverbatim
*/
class TINYXML2_LIB XMLNode
{
    friend class XMLDocument;
friend class XMLElement;
public:

    /// Get the XMLDocument that owns this XMLNode.
    const XMLDocument* GetDocument() const        {
        TIXMLASSERT(_document);
        return _document;
    }
    /// Get the XMLDocument that owns this XMLNode.
    XMLDocument* GetDocument()
{
    TIXMLASSERT(_document);
    return _document;
}

/// Safely cast to an Element, or null.
virtual XMLElement* ToElement()
{
    return 0;
}
/// Safely cast to Text, or null.
virtual XMLText* ToText()
{
    return 0;
}
/// Safely cast to a Comment, or null.
virtual XMLComment* ToComment()
{
    return 0;
}
/// Safely cast to a Document, or null.
virtual XMLDocument* ToDocument()
{
    return 0;
}
/// Safely cast to a Declaration, or null.
virtual XMLDeclaration* ToDeclaration()
{
    return 0;
}
/// Safely cast to an Unknown, or null.
virtual XMLUnknown* ToUnknown()
{
    return 0;
}

virtual const XMLElement* ToElement() const                {
        return 0;
    }
    virtual const XMLText* ToText() const                        {
        return 0;
    }
    virtual const XMLComment* ToComment() const                {
        return 0;
    }
    virtual const XMLDocument* ToDocument() const                {
        return 0;
    }
    virtual const XMLDeclaration* ToDeclaration() const        {
        return 0;
    }
    virtual const XMLUnknown* ToUnknown() const                {
        return 0;
    }

    /** The meaning of 'value' changes for the specific type.
            @verbatim
            Document:        empty (NULL is returned, not an empty string)
            Element:        name of the element
            Comment:        the comment text
            Unknown:        the tag contents
            Text:                the text string
            @endverbatim
    */
    const char* Value() const;

/** Set the Value of an XML node.
    @sa Value()
*/
void SetValue( const char* val, bool staticMem = false);

/// Get the parent of this node on the DOM.
const XMLNode* Parent() const                        {
        return _parent;
    }

    XMLNode* Parent()
{
    return _parent;
}

/// Returns true if this node has no children.
bool NoChildren() const                 {
        return !_firstChild;
    }

    /// Get the first child node, or null if none exists.
    const XMLNode* FirstChild() const                {
        return _firstChild;
    }

    XMLNode* FirstChild()
{
    return _firstChild;
}

/** Get the first child element, or optionally the first child
    element with the specified name.
*/
const XMLElement* FirstChildElement( const char * name = 0 ) const;

XMLElement* FirstChildElement( const char* name = 0)
{
    return const_cast(const_cast  (this)->FirstChildElement(name));
}

/// Get the last child node, or null if none exists.
const XMLNode* LastChild() const                                                {
        return _lastChild;
    }

    XMLNode* LastChild()
{
    return _lastChild;
}

/** Get the last child element or optionally the last child
    element with the specified name.
*/
const XMLElement* LastChildElement( const char * name = 0 ) const;

XMLElement* LastChildElement( const char* name = 0)
{
    return const_cast(const_cast  (this)->LastChildElement(name) );
}

/// Get the previous (left) sibling node of this node.
const XMLNode* PreviousSibling() const                                        {
        return _prev;
    }

    XMLNode* PreviousSibling()
{
    return _prev;
}

/// Get the previous (left) sibling element of this node, with an optionally supplied name.
const XMLElement* PreviousSiblingElement( const char * name = 0 ) const ;

XMLElement* PreviousSiblingElement( const char* name = 0)
{
    return const_cast(const_cast  (this)->PreviousSiblingElement(name) );
}

/// Get the next (right) sibling node of this node.
const XMLNode* NextSibling() const                                                {
        return _next;
    }

    XMLNode* NextSibling()
{
    return _next;
}

/// Get the next (right) sibling element of this node, with an optionally supplied name.
const XMLElement* NextSiblingElement( const char * name = 0 ) const;

XMLElement* NextSiblingElement( const char* name = 0)
{
    return const_cast(const_cast  (this)->NextSiblingElement(name) );
}

/**
    Add a child node as the last (right) child.
    If the child node is already part of the document,
    it is moved from its old location to the new location.
    Returns the addThis argument or 0 if the node does not
    belong to the same document.
*/
XMLNode* InsertEndChild(XMLNode* addThis);

XMLNode* LinkEndChild(XMLNode* addThis)
{
    return InsertEndChild(addThis);
}
/**
    Add a child node as the first (left) child.
    If the child node is already part of the document,
    it is moved from its old location to the new location.
    Returns the addThis argument or 0 if the node does not
    belong to the same document.
*/
XMLNode* InsertFirstChild(XMLNode* addThis);
/**
    Add a node after the specified child node.
    If the child node is already part of the document,
    it is moved from its old location to the new location.
    Returns the addThis argument or 0 if the afterThis node
    is not a child of this node, or if the node does not
    belong to the same document.
*/
XMLNode* InsertAfterChild(XMLNode* afterThis, XMLNode* addThis);

/**
    Delete all the children of this node.
*/
void DeleteChildren();

/**
    Delete a child of this node.
*/
void DeleteChild(XMLNode* node);

/**
    Make a copy of this node, but not its children.
    You may pass in a Document pointer that will be
    the owner of the new Node. If the 'document' is
    null, then the node returned will be allocated
    from the current Document. (this->GetDocument())

    Note: if called on a XMLDocument, this will return null.
*/
virtual XMLNode* ShallowClone(XMLDocument* document) const = 0;

/**
    Test if 2 nodes are the same, but don't test children.
    The 2 nodes do not need to be in the same Document.

    Note: if called on a XMLDocument, this will return false.
*/
virtual bool ShallowEqual( const XMLNode* compare) const = 0;

/** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the
    XML tree will be conditionally visited and the host will be called back
    via the XMLVisitor interface.

    This is essentially a SAX interface for TinyXML-2. (Note however it doesn't re-parse
    the XML for the callbacks, so the performance of TinyXML-2 is unchanged by using this
    interface versus any other.)

    The interface has been based on ideas from:

    - http://www.saxproject.org/
    - http://c2.com/cgi/wiki?HierarchicalVisitorPattern

    Which are both good references for "visiting".

    An example of using Accept():
    @verbatim
    XMLPrinter printer;
    tinyxmlDoc.Accept( &printer );
    const char* xmlcstr = printer.CStr();
    @endverbatim
*/
virtual bool Accept(XMLVisitor* visitor) const = 0;

protected:
    XMLNode(XMLDocument* );
virtual ~XMLNode();

virtual char* ParseDeep(char*, StrPair* );

XMLDocument* _document;
XMLNode* _parent;
mutable StrPair _value;

    XMLNode* _firstChild;
XMLNode* _lastChild;

XMLNode* _prev;
XMLNode* _next;

private:
    MemPool* _memPool;
void Unlink(XMLNode* child);
static void DeleteNode(XMLNode* node);
void InsertChildPreamble(XMLNode* insertThis) const;

    XMLNode( const XMLNode& );  // not supported
XMLNode& operator=( const XMLNode& );        // not supported
};


/** XML text.

        Note that a text node can have child element nodes, for example:
        @verbatim
        This is bold
        @endverbatim

        A text node can have 2 ways to output the next. "normal" output
        and CDATA. It will default to the mode it was parsed from the XML file and
        you generally want to leave it alone, but you can change the output mode with
        SetCData() and query it with CData().
*/
class TINYXML2_LIB XMLText : public XMLNode
{
    friend class XMLBase;
friend class XMLDocument;
public:
    virtual bool Accept(XMLVisitor* visitor) const;

virtual XMLText* ToText()
{
    return this;
}
virtual const XMLText* ToText() const        {
        return this;
    }

    /// Declare whether this should be CDATA or standard text.
    void SetCData(bool isCData)
{
    _isCData = isCData;
}
/// Returns true if this is a CDATA text element.
bool CData() const                      {
        return _isCData;
    }

    virtual XMLNode* ShallowClone(XMLDocument* document) const;
virtual bool ShallowEqual( const XMLNode* compare) const;

protected:
    XMLText(XMLDocument* doc)        : XMLNode(doc ), _isCData( false ) { }
virtual ~XMLText() { }

char* ParseDeep(char*, StrPair* endTag);

private:
    bool _isCData;

    XMLText( const XMLText& );  // not supported
XMLText& operator=( const XMLText& );        // not supported
};


/** An XML Comment. */
class TINYXML2_LIB XMLComment : public XMLNode
{
    friend class XMLDocument;
public:
    virtual XMLComment* ToComment()
{
    return this;
}
virtual const XMLComment* ToComment() const                {
        return this;
    }

    virtual bool Accept(XMLVisitor* visitor) const;

virtual XMLNode* ShallowClone(XMLDocument* document) const;
virtual bool ShallowEqual( const XMLNode* compare) const;

protected:
    XMLComment(XMLDocument* doc);
virtual ~XMLComment();

char* ParseDeep(char*, StrPair* endTag);

private:
    XMLComment( const XMLComment& );    // not supported
XMLComment& operator=( const XMLComment& );        // not supported
};


/** In correct XML the declaration is the first entry in the file.
        @verbatim
                
        @endverbatim

        TinyXML-2 will happily read or write files without a declaration,
        however.

        The text of the declaration isn't interpreted. It is parsed
        and written as a string.
*/
class TINYXML2_LIB XMLDeclaration : public XMLNode
{
    friend class XMLDocument;
public:
    virtual XMLDeclaration* ToDeclaration()
{
    return this;
}
virtual const XMLDeclaration* ToDeclaration() const                {
        return this;
    }

    virtual bool Accept(XMLVisitor* visitor) const;

virtual XMLNode* ShallowClone(XMLDocument* document) const;
virtual bool ShallowEqual( const XMLNode* compare) const;

protected:
    XMLDeclaration(XMLDocument* doc);
virtual ~XMLDeclaration();

char* ParseDeep(char*, StrPair* endTag);

private:
    XMLDeclaration( const XMLDeclaration& );    // not supported
XMLDeclaration& operator=( const XMLDeclaration& );        // not supported
};


/** Any tag that TinyXML-2 doesn't recognize is saved as an
        unknown. It is a tag of text, but should not be modified.
        It will be written back to the XML, unchanged, when the file
        is saved.

        DTD tags get thrown into XMLUnknowns.
*/
class TINYXML2_LIB XMLUnknown : public XMLNode
{
    friend class XMLDocument;
public:
    virtual XMLUnknown* ToUnknown()
{
    return this;
}
virtual const XMLUnknown* ToUnknown() const                {
        return this;
    }

    virtual bool Accept(XMLVisitor* visitor) const;

virtual XMLNode* ShallowClone(XMLDocument* document) const;
virtual bool ShallowEqual( const XMLNode* compare) const;

protected:
    XMLUnknown(XMLDocument* doc);
virtual ~XMLUnknown();

char* ParseDeep(char*, StrPair* endTag);

private:
    XMLUnknown( const XMLUnknown& );    // not supported
XMLUnknown& operator=( const XMLUnknown& );        // not supported
};



/** An attribute is a name-value pair. Elements have an arbitrary
        number of attributes, each with a unique name.

        @note The attributes are not XMLNodes. You may only query the
        Next() attribute in a list.
*/
class TINYXML2_LIB XMLAttribute
{
    friend class XMLElement;
public:
    /// The name of the attribute.
    const char* Name() const;

/// The value of the attribute.
const char* Value() const;

/// The next attribute in the list.
const XMLAttribute* Next() const {
        return _next;
    }

    /** IntValue interprets the attribute as an integer, and returns the value.
        If the value isn't an integer, 0 will be returned. There is no error checking;
            use QueryIntValue() if you need error checking.
    */
    int IntValue() const               {
        int i = 0;
        QueryIntValue( &i );
        return i;
    }
    /// Query as an unsigned integer. See IntValue()
    unsigned UnsignedValue() const          {
        unsigned i = 0;
        QueryUnsignedValue( &i );
        return i;
    }
    /// Query as a boolean. See IntValue()
    bool BoolValue() const              {
        bool b = false;
        QueryBoolValue( &b );
        return b;
    }
    /// Query as a double. See IntValue()
    double DoubleValue() const            {
        double d = 0;
        QueryDoubleValue( &d );
        return d;
    }
    /// Query as a float. See IntValue()
    float FloatValue() const             {
        float f = 0;
        QueryFloatValue( &f );
        return f;
    }

    /** QueryIntValue interprets the attribute as an integer, and returns the value
            in the provided parameter. The function will return XML_NO_ERROR on success,
            and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful.
    */
    XMLError QueryIntValue(int* value) const;
/// See QueryIntValue
XMLError QueryUnsignedValue(unsigned int* value) const;
/// See QueryIntValue
XMLError QueryBoolValue(bool* value) const;
/// See QueryIntValue
XMLError QueryDoubleValue(double* value) const;
/// See QueryIntValue
XMLError QueryFloatValue(float* value) const;

/// Set the attribute to a string value.
void SetAttribute( const char* value);
/// Set the attribute to value.
void SetAttribute(int value);
/// Set the attribute to value.
void SetAttribute(unsigned value);
/// Set the attribute to value.
void SetAttribute(bool value);
/// Set the attribute to value.
void SetAttribute(double value);
/// Set the attribute to value.
void SetAttribute(float value);

private:
    enum { BUF_SIZE = 200 };

    XMLAttribute() : _next( 0 ), _memPool( 0 ) { }
virtual ~XMLAttribute() { }

    XMLAttribute( const XMLAttribute& );    // not supported
void operator=( const XMLAttribute& );  // not supported
void SetName( const char* name);

char* ParseDeep(char* p, bool processEntities);

mutable StrPair _name;
    mutable StrPair _value;
    XMLAttribute* _next;
MemPool* _memPool;
};


/** The element is a container class. It has a value, the element name,
        and can contain other elements, text, comments, and unknowns.
        Elements also contain an arbitrary number of attributes.
*/
class TINYXML2_LIB XMLElement : public XMLNode
{
    friend class XMLBase;
friend class XMLDocument;
public:
    /// Get the name of an element (which is the Value() of the node.)
    const char* Name() const                {
        return Value();
    }
    /// Set the name of the element.
    void SetName( const char* str, bool staticMem = false)
{
    SetValue(str, staticMem);
}

virtual XMLElement* ToElement()
{
    return this;
}
virtual const XMLElement* ToElement() const {
        return this;
    }
    virtual bool Accept(XMLVisitor* visitor) const;

/** Given an attribute name, Attribute() returns the value
    for the attribute of that name, or null if none
    exists. For example:

    @verbatim
    const char* value = ele->Attribute( "foo" );
    @endverbatim

    The 'value' parameter is normally null. However, if specified,
    the attribute will only be returned if the 'name' and 'value'
    match. This allow you to write code:

    @verbatim
    if ( ele->Attribute( "foo", "bar" ) ) callFooIsBar();
    @endverbatim

    rather than:
    @verbatim
    if ( ele->Attribute( "foo" ) ) {
        if ( strcmp( ele->Attribute( "foo" ), "bar" ) == 0 ) callFooIsBar();
    }
    @endverbatim
*/
const char* Attribute( const char * name, const char * value = 0 ) const;

/** Given an attribute name, IntAttribute() returns the value
    of the attribute interpreted as an integer. 0 will be
    returned if there is an error. For a method with error
    checking, see QueryIntAttribute()
*/
int IntAttribute( const char* name) const     {
        int i = 0;
        QueryIntAttribute(name, &i );
        return i;
    }
    /// See IntAttribute()
    unsigned UnsignedAttribute( const char* name) const {
        unsigned i = 0;
        QueryUnsignedAttribute(name, &i );
        return i;
    }
    /// See IntAttribute()
    bool BoolAttribute( const char* name) const    {
        bool b = false;
        QueryBoolAttribute(name, &b );
        return b;
    }
    /// See IntAttribute()
    double DoubleAttribute( const char* name) const  {
        double d = 0;
        QueryDoubleAttribute(name, &d );
        return d;
    }
    /// See IntAttribute()
    float FloatAttribute( const char* name) const   {
        float f = 0;
        QueryFloatAttribute(name, &f );
        return f;
    }

    /** Given an attribute name, QueryIntAttribute() returns
            XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
            can't be performed, or XML_NO_ATTRIBUTE if the attribute
            doesn't exist. If successful, the result of the conversion
            will be written to 'value'. If not successful, nothing will
            be written to 'value'. This allows you to provide default
            value:

            @verbatim
            int value = 10;
            QueryIntAttribute( "foo", &value );                // if "foo" isn't found, value will still be 10
            @endverbatim
    */
    XMLError QueryIntAttribute( const char* name, int* value) const                {
        const XMLAttribute* a = FindAttribute(name);
        if ( !a ) {
            return XML_NO_ATTRIBUTE;
        }
        return a->QueryIntValue(value );
    }
    /// See QueryIntAttribute()
    XMLError QueryUnsignedAttribute( const char* name, unsigned int* value) const  {
        const XMLAttribute* a = FindAttribute(name);
        if ( !a ) {
            return XML_NO_ATTRIBUTE;
        }
        return a->QueryUnsignedValue(value );
    }
    /// See QueryIntAttribute()
    XMLError QueryBoolAttribute( const char* name, bool* value) const              {
        const XMLAttribute* a = FindAttribute(name);
        if ( !a ) {
            return XML_NO_ATTRIBUTE;
        }
        return a->QueryBoolValue(value );
    }
    /// See QueryIntAttribute()
    XMLError QueryDoubleAttribute( const char* name, double* value) const          {
        const XMLAttribute* a = FindAttribute(name);
        if ( !a ) {
            return XML_NO_ATTRIBUTE;
        }
        return a->QueryDoubleValue(value );
    }
    /// See QueryIntAttribute()
    XMLError QueryFloatAttribute( const char* name, float* value) const            {
        const XMLAttribute* a = FindAttribute(name);
        if ( !a ) {
            return XML_NO_ATTRIBUTE;
        }
        return a->QueryFloatValue(value );
    }

        
    /** Given an attribute name, QueryAttribute() returns
            XML_NO_ERROR, XML_WRONG_ATTRIBUTE_TYPE if the conversion
            can't be performed, or XML_NO_ATTRIBUTE if the attribute
            doesn't exist. It is overloaded for the primitive types,
                and is a generally more convenient replacement of
                QueryIntAttribute() and related functions.
                
                If successful, the result of the conversion
            will be written to 'value'. If not successful, nothing will
            be written to 'value'. This allows you to provide default
            value:

            @verbatim
            int value = 10;
            QueryAttribute( "foo", &value );                // if "foo" isn't found, value will still be 10
            @endverbatim
    */
        int QueryAttribute( const char* name, int* value) const {
                return QueryIntAttribute(name, value );
        }

        int QueryAttribute( const char* name, unsigned int* value) const {
                return QueryUnsignedAttribute(name, value );
        }

        int QueryAttribute( const char* name, bool* value) const {
                return QueryBoolAttribute(name, value );
        }

        int QueryAttribute( const char* name, double* value) const {
                return QueryDoubleAttribute(name, value );
        }

        int QueryAttribute( const char* name, float* value) const {
                return QueryFloatAttribute(name, value );
        }

        /// Sets the named attribute to value.
    void SetAttribute( const char* name, const char* value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}
/// Sets the named attribute to value.
void SetAttribute( const char* name, int value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}
/// Sets the named attribute to value.
void SetAttribute( const char* name, unsigned value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}
/// Sets the named attribute to value.
void SetAttribute( const char* name, bool value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}
/// Sets the named attribute to value.
void SetAttribute( const char* name, double value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}
/// Sets the named attribute to value.
void SetAttribute( const char* name, float value)
{
    XMLAttribute* a = FindOrCreateAttribute(name);
    a->SetAttribute(value);
}

/**
    Delete an attribute.
*/
void DeleteAttribute( const char* name);

/// Return the first attribute in the list.
const XMLAttribute* FirstAttribute() const {
        return _rootAttribute;
    }
    /// Query a specific attribute in the list.
    const XMLAttribute* FindAttribute( const char * name ) const;

/** Convenience function for easy access to the text inside an element. Although easy
    and concise, GetText() is limited compared to getting the XMLText child
    and accessing it directly.

    If the first child of 'this' is a XMLText, the GetText()
    returns the character string of the Text node, else null is returned.

    This is a convenient method for getting the text of simple contained text:
    @verbatim
    This is text
        const char* str = fooElement->GetText();
    @endverbatim

    'str' will be a pointer to "This is text".

    Note that this function can be misleading. If the element foo was created from
    this XML:
    @verbatim
        This is text
    @endverbatim

    then the value of str would be null. The first child node isn't a text node, it is
    another element. From this XML:
    @verbatim
        This is text
    @endverbatim
    GetText() will return "This is ".
*/
const char* GetText() const;

/** Convenience function for easy access to the text inside an element. Although easy
    and concise, SetText() is limited compared to creating an XMLText child
    and mutating it directly.

    If the first child of 'this' is a XMLText, SetText() sets its value to
    the given string, otherwise it will create a first child that is an XMLText.

    This is a convenient method for setting the text of simple contained text:
    @verbatim
    This is text
        fooElement->SetText( "Hullaballoo!" );
    Hullaballoo!
    @endverbatim

    Note that this function can be misleading. If the element foo was created from
    this XML:
    @verbatim
        This is text
    @endverbatim

    then it will not change "This is text", but rather prefix it with a text element:
    @verbatim
        Hullaballoo!This is text
    @endverbatim
    
    For this XML:
    @verbatim
        
    @endverbatim
    SetText() will generate
    @verbatim
        Hullaballoo!
    @endverbatim
*/
void SetText( const char* inText);
/// Convenience method for setting text inside and element. See SetText() for important limitations.
void SetText(int value);
/// Convenience method for setting text inside and element. See SetText() for important limitations.
void SetText(unsigned value);
/// Convenience method for setting text inside and element. See SetText() for important limitations.
void SetText(bool value);
/// Convenience method for setting text inside and element. See SetText() for important limitations.
void SetText(double value);
/// Convenience method for setting text inside and element. See SetText() for important limitations.
void SetText(float value);

/**
    Convenience method to query the value of a child text node. This is probably best
    shown by example. Given you have a document is this form:
    @verbatim
        
            1
            1.4
        

    @endverbatim

    The QueryIntText() and similar functions provide a safe and easier way to get to the
    "value" of x and y.

    @verbatim
        int x = 0;
        float y = 0;        // types of x and y are contrived for example
        const XMLElement* xElement = pointElement->FirstChildElement( "x" );
        const XMLElement* yElement = pointElement->FirstChildElement( "y" );
        xElement->QueryIntText( &x );
        yElement->QueryFloatText( &y );
    @endverbatim

    @returns XML_SUCCESS (0) on success, XML_CAN_NOT_CONVERT_TEXT if the text cannot be converted
             to the requested type, and XML_NO_TEXT_NODE if there is no child text to query.

*/
XMLError QueryIntText(int* ival) const;
/// See QueryIntText()
XMLError QueryUnsignedText(unsigned* uval) const;
/// See QueryIntText()
XMLError QueryBoolText(bool* bval) const;
/// See QueryIntText()
XMLError QueryDoubleText(double* dval) const;
/// See QueryIntText()
XMLError QueryFloatText(float* fval) const;

// internal:
enum {
    OPEN,       // 
    CLOSED,     // 
    CLOSING     // 

};
int ClosingType() const {
        return _closingType;
    }
    virtual XMLNode* ShallowClone(XMLDocument* document) const;
virtual bool ShallowEqual( const XMLNode* compare) const;

protected:
    char* ParseDeep(char* p, StrPair* endTag);

private:
    XMLElement(XMLDocument* doc);
virtual ~XMLElement();
    XMLElement( const XMLElement& );    // not supported
void operator=( const XMLElement& );    // not supported

XMLAttribute* FindAttribute( const char* name)
{
    return const_cast(const_cast  (this)->FindAttribute(name));
}
XMLAttribute* FindOrCreateAttribute( const char* name);
//void LinkAttribute( XMLAttribute* attrib );
char* ParseAttributes(char* p);
static void DeleteAttribute(XMLAttribute* attribute);

enum { BUF_SIZE = 200 };
int _closingType;
// The attribute list is ordered; there is no 'lastAttribute'
// because the list needs to be scanned for dupes before adding
// a new attribute.
XMLAttribute* _rootAttribute;
};


enum Whitespace
{
    PRESERVE_WHITESPACE,
    COLLAPSE_WHITESPACE
};


/** A Document binds together all the functionality.
        It can be saved, loaded, and printed to the screen.
        All Nodes are connected and allocated to a Document.
        If the Document is deleted, all its Nodes are also deleted.
*/
class TINYXML2_LIB XMLDocument : public XMLNode
{
    friend class XMLElement;
public:
    /// constructor
    XMLDocument(bool processEntities = true, Whitespace = PRESERVE_WHITESPACE);
~XMLDocument();

virtual XMLDocument* ToDocument()
{
    TIXMLASSERT(this == _document);
    return this;
}
virtual const XMLDocument* ToDocument() const        {

    TIXMLASSERT(this == _document);
        return this;
    }

/**
    Parse an XML file from a character string.
    Returns XML_NO_ERROR (0) on success, or
    an errorID.

    You may optionally pass in the 'nBytes', which is
    the number of bytes which will be parsed. If not
    specified, TinyXML-2 will assume 'xml' points to a
    null terminated string.
*/
XMLError Parse( const char* xml, size_t nBytes = (size_t)(-1));

/**
    Load an XML file from disk.
    Returns XML_NO_ERROR (0) on success, or
    an errorID.
*/
XMLError LoadFile( const char* filename);

/**
    Load an XML file from disk. You are responsible
    for providing and closing the FILE*. 
 
    NOTE: The file should be opened as binary ("rb")
    not text in order for TinyXML-2 to correctly
    do newline normalization.

    Returns XML_NO_ERROR (0) on success, or
    an errorID.
*/
XMLError LoadFile(FILE* );

/**
    Save the XML file to disk.
    Returns XML_NO_ERROR (0) on success, or
    an errorID.
*/
XMLError SaveFile( const char* filename, bool compact = false);

/**
    Save the XML file to disk. You are responsible
    for providing and closing the FILE*.

    Returns XML_NO_ERROR (0) on success, or
    an errorID.
*/
XMLError SaveFile(FILE* fp, bool compact = false);

bool ProcessEntities() const        {
        return _processEntities;
    }
    Whitespace WhitespaceMode() const   {
        return _whitespace;
    }

    /**
            Returns true if this document has a leading Byte Order Mark of UTF8.
    */
    bool HasBOM() const {
        return _writeBOM;
    }
    /** Sets whether to write the BOM when writing the file.
    */
    void SetBOM(bool useBOM)
{
    _writeBOM = useBOM;
}

/** Return the root element of DOM. Equivalent to FirstChildElement().
    To get the first node, use FirstChild().
*/
XMLElement* RootElement()
{
    return FirstChildElement();
}
const XMLElement* RootElement() const        {
        return FirstChildElement();
    }

    /** Print the Document. If the Printer is not provided, it will
        print to stdout. If you provide Printer, this can print to a file:
            @verbatim
            XMLPrinter printer( fp );
            doc.Print( &printer );
            @endverbatim

            Or you can use a printer to print to memory:
            @verbatim
            XMLPrinter printer;
            doc.Print( &printer );
            // printer.CStr() has a const char* to the XML
            @endverbatim
    */
    void Print(XMLPrinter* streamer = 0) const;
virtual bool Accept(XMLVisitor* visitor) const;

/**
    Create a new Element associated with
    this Document. The memory for the Element
    is managed by the Document.
*/
XMLElement* NewElement( const char* name);
/**
    Create a new Comment associated with
    this Document. The memory for the Comment
    is managed by the Document.
*/
XMLComment* NewComment( const char* comment);
/**
    Create a new Text associated with
    this Document. The memory for the Text
    is managed by the Document.
*/
XMLText* NewText( const char* text);
/**
    Create a new Declaration associated with
    this Document. The memory for the object
    is managed by the Document.

    If the 'text' param is null, the standard
    declaration is used.:
    @verbatim
        
    @endverbatim
*/
XMLDeclaration* NewDeclaration( const char* text = 0);
/**
    Create a new Unknown associated with
    this Document. The memory for the object
    is managed by the Document.
*/
XMLUnknown* NewUnknown( const char* text);

/**
    Delete a node associated with this document.
    It will be unlinked from the DOM.
*/
void DeleteNode(XMLNode* node);

void SetError(XMLError error, const char* str1, const char* str2);

/// Return true if there was an error parsing the document.
bool Error() const {
        return _errorID != XML_NO_ERROR;
    }
    /// Return the errorID.
    XMLError ErrorID() const {
        return _errorID;
    }
        const char* ErrorName() const;

/// Return a possibly helpful diagnostic location or string.
const char* GetErrorStr1() const {
        return _errorStr1;
    }
    /// Return a possibly helpful secondary diagnostic location or string.
    const char* GetErrorStr2() const {
        return _errorStr2;
    }
    /// If there is an error, print it to stdout.
    void PrintError() const;

/// Clear the document, resetting it to the initial state.
void Clear();

// internal
char* Identify(char* p, XMLNode** node);

virtual XMLNode* ShallowClone(XMLDocument* /*document*/ ) const    {
        return 0;
    }
    virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const   {
        return false;
    }

private:
    XMLDocument( const XMLDocument& );  // not supported
void operator=( const XMLDocument& );   // not supported

bool _writeBOM;
bool _processEntities;
XMLError _errorID;
Whitespace _whitespace;
const char* _errorStr1;
const char* _errorStr2;
char* _charBuffer;

MemPoolT< sizeof(XMLElement) >         _elementPool;
    MemPoolT< sizeof(XMLAttribute) > _attributePool;
    MemPoolT< sizeof(XMLText) >                 _textPool;
    MemPoolT< sizeof(XMLComment) >         _commentPool;

        static const char* _errorNames[XML_ERROR_COUNT];

void Parse();
};


/**
        A XMLHandle is a class that wraps a node pointer with null checks; this is
        an incredibly useful thing. Note that XMLHandle is not part of the TinyXML-2
        DOM structure. It is a separate utility class.

        Take an example:
        @verbatim
        
                
                        
                        
                
        

        @endverbatim

        Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
        easy to write a *lot* of code that looks like:

        @verbatim
        XMLElement* root = document.FirstChildElement( "Document" );
        if ( root )
        {
                XMLElement* element = root->FirstChildElement( "Element" );
                if ( element )
                {
                        XMLElement* child = element->FirstChildElement( "Child" );
                        if ( child )
                        {
                                XMLElement* child2 = child->NextSiblingElement( "Child" );
                                if ( child2 )
                                {
                                        // Finally do something useful.
        @endverbatim

        And that doesn't even cover "else" cases. XMLHandle addresses the verbosity
        of such code. A XMLHandle checks for null pointers so it is perfectly safe
        and correct to use:

        @verbatim
        XMLHandle docHandle( &document );
        XMLElement* child2 = docHandle.FirstChildElement( "Document" ).FirstChildElement( "Element" ).FirstChildElement().NextSiblingElement();
        if ( child2 )
        {
                // do something useful
        @endverbatim

        Which is MUCH more concise and useful.

        It is also safe to copy handles - internally they are nothing more than node pointers.
        @verbatim
        XMLHandle handleCopy = handle;
        @endverbatim

        See also XMLConstHandle, which is the same as XMLHandle, but operates on const objects.
*/
class TINYXML2_LIB XMLHandle
{
public:
    /// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
    XMLHandle(XMLNode* node)
{
    _node = node;
}
    /// Create a handle from a node.
    XMLHandle(XMLNode& node )
{
    _node = &node;
}
    /// Copy constructor
    XMLHandle( const XMLHandle& ref )
{
    _node = ref._node;
}
/// Assignment
XMLHandle& operator=( const XMLHandle& ref )
{
    _node = ref._node;
    return *this;
}

/// Get the first child of this handle.
XMLHandle FirstChild()
{
    return XMLHandle(_node ? _node->FirstChild() : 0);
}
/// Get the first child element of this handle.
XMLHandle FirstChildElement( const char* name = 0)
{
    return XMLHandle(_node ? _node->FirstChildElement(name) : 0);
}
/// Get the last child of this handle.
XMLHandle LastChild()
{
    return XMLHandle(_node ? _node->LastChild() : 0);
}
/// Get the last child element of this handle.
XMLHandle LastChildElement( const char* name = 0)
{
    return XMLHandle(_node ? _node->LastChildElement(name) : 0);
}
/// Get the previous sibling of this handle.
XMLHandle PreviousSibling()
{
    return XMLHandle(_node ? _node->PreviousSibling() : 0);
}
/// Get the previous sibling element of this handle.
XMLHandle PreviousSiblingElement( const char* name = 0)
{
    return XMLHandle(_node ? _node->PreviousSiblingElement(name) : 0);
}
/// Get the next sibling of this handle.
XMLHandle NextSibling()
{
    return XMLHandle(_node ? _node->NextSibling() : 0);
}
/// Get the next sibling element of this handle.
XMLHandle NextSiblingElement( const char* name = 0)
{
    return XMLHandle(_node ? _node->NextSiblingElement(name) : 0);
}

/// Safe cast to XMLNode. This can return null.
XMLNode* ToNode()
{
    return _node;
}
/// Safe cast to XMLElement. This can return null.
XMLElement* ToElement()
{
    return ((_node == 0) ? 0 : _node->ToElement());
}
/// Safe cast to XMLText. This can return null.
XMLText* ToText()
{
    return ((_node == 0) ? 0 : _node->ToText());
}
/// Safe cast to XMLUnknown. This can return null.
XMLUnknown* ToUnknown()
{
    return ((_node == 0) ? 0 : _node->ToUnknown());
}
/// Safe cast to XMLDeclaration. This can return null.
XMLDeclaration* ToDeclaration()
{
    return ((_node == 0) ? 0 : _node->ToDeclaration());
}

private:
    XMLNode* _node;
};


/**
        A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the
        same in all regards, except for the 'const' qualifiers. See XMLHandle for API.
*/
class TINYXML2_LIB XMLConstHandle
{
public:
    XMLConstHandle( const XMLNode* node)
{
    _node = node;
}
    XMLConstHandle( const XMLNode& node )
{
    _node = &node;
}
    XMLConstHandle( const XMLConstHandle& ref )
{
    _node = ref._node;
}

XMLConstHandle& operator=( const XMLConstHandle& ref )
{
    _node = ref._node;
    return *this;
}

const XMLConstHandle FirstChild() const                                                                                        {
        return XMLConstHandle(_node ? _node->FirstChild() : 0);
    }
    const XMLConstHandle FirstChildElement( const char * name = 0 ) const                {
        return XMLConstHandle(_node? _node->FirstChildElement( name ) : 0 );
    }
    const XMLConstHandle LastChild()        const                                                                                {
        return XMLConstHandle(_node ? _node->LastChild() : 0);
    }
    const XMLConstHandle LastChildElement( const char * name = 0 ) const             {
        return XMLConstHandle(_node? _node->LastChildElement( name ) : 0 );
    }
    const XMLConstHandle PreviousSibling() const                                                                        {
        return XMLConstHandle(_node ? _node->PreviousSibling() : 0);
    }
    const XMLConstHandle PreviousSiblingElement( const char * name = 0 ) const       {
        return XMLConstHandle(_node? _node->PreviousSiblingElement( name ) : 0 );
    }
    const XMLConstHandle NextSibling() const                                                                                {
        return XMLConstHandle(_node ? _node->NextSibling() : 0);
    }
    const XMLConstHandle NextSiblingElement( const char * name = 0 ) const           {
        return XMLConstHandle(_node? _node->NextSiblingElement( name ) : 0 );
    }


    const XMLNode* ToNode() const                                {
        return _node;
    }
    const XMLElement* ToElement() const                        {
        return ((_node == 0) ? 0 : _node->ToElement());
    }
    const XMLText* ToText() const                                {
        return ((_node == 0) ? 0 : _node->ToText());
    }
    const XMLUnknown* ToUnknown() const                        {
        return ((_node == 0) ? 0 : _node->ToUnknown());
    }
    const XMLDeclaration* ToDeclaration() const        {
        return ((_node == 0) ? 0 : _node->ToDeclaration());
    }

private:
    const XMLNode* _node;
};


/**
        Printing functionality. The XMLPrinter gives you more
        options than the XMLDocument::Print() method.

        It can:
        -# Print to memory.
        -# Print to a file you provide.
        -# Print XML without a XMLDocument.

        Print to Memory

        @verbatim
        XMLPrinter printer;
        doc.Print( &printer );
        SomeFunction( printer.CStr() );
        @endverbatim

        Print to a File

        You provide the file pointer.
        @verbatim
        XMLPrinter printer( fp );
        doc.Print( &printer );
        @endverbatim

        Print without a XMLDocument

        When loading, an XML parser is very useful. However, sometimes
        when saving, it just gets in the way. The code is often set up
        for streaming, and constructing the DOM is just overhead.

        The Printer supports the streaming case. The following code
        prints out a trivially simple XML file without ever creating
        an XML document.

        @verbatim
        XMLPrinter printer( fp );
        printer.OpenElement( "foo" );
        printer.PushAttribute( "foo", "bar" );
        printer.CloseElement();
        @endverbatim
*/
class TINYXML2_LIB XMLPrinter : public XMLVisitor
{
public:
    /** Construct the printer. If the FILE* is specified,
            this will print to the FILE. Else it will print
            to memory, and the result is available in CStr().
            If 'compact' is set to true, then output is created
            with only required whitespace and newlines.
    */
    XMLPrinter(FILE* file = 0, bool compact = false, int depth = 0);
virtual ~XMLPrinter() { }

/** If streaming, write the BOM and declaration. */
void PushHeader(bool writeBOM, bool writeDeclaration);
/** If streaming, start writing an element.
    The element must be closed with CloseElement()
*/
void OpenElement( const char* name, bool compactMode = false);
/// If streaming, add an attribute to an open element.
void PushAttribute( const char* name, const char* value);
void PushAttribute( const char* name, int value);
void PushAttribute( const char* name, unsigned value);
void PushAttribute( const char* name, bool value);
void PushAttribute( const char* name, double value);
/// If streaming, close the Element.
virtual void CloseElement(bool compactMode = false);

/// Add a text node.
void PushText( const char* text, bool cdata = false);
/// Add a text node from an integer.
void PushText(int value);
/// Add a text node from an unsigned.
void PushText(unsigned value);
/// Add a text node from a bool.
void PushText(bool value);
/// Add a text node from a float.
void PushText(float value);
/// Add a text node from a double.
void PushText(double value);

/// Add a comment
void PushComment( const char* comment);

void PushDeclaration( const char* value);
void PushUnknown( const char* value);

virtual bool VisitEnter( const XMLDocument& /*doc*/ );
virtual bool VisitExit( const XMLDocument& /*doc*/ )
{
    return true;
}

virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute);
virtual bool VisitExit( const XMLElement& element );

virtual bool Visit( const XMLText& text );
virtual bool Visit( const XMLComment& comment );
virtual bool Visit( const XMLDeclaration& declaration );
virtual bool Visit( const XMLUnknown& unknown );

/**
    If in print to memory mode, return a pointer to
    the XML file in memory.
*/
const char* CStr() const {
        return _buffer.Mem();
    }
    /**
            If in print to memory mode, return the size
            of the XML file in memory. (Note the size returned
            includes the terminating null.)
    */
    int CStrSize() const {
        return _buffer.Size();
    }
    /**
            If in print to memory mode, reset the buffer to the
            beginning.
    */
    void ClearBuffer()
{
    _buffer.Clear();
    _buffer.Push(0);
}

protected:
        virtual bool CompactMode( const XMLElement& ) { return _compactMode; }

/** Prints out the space before an element. You may override to change
    the space and tabs used. A PrintSpace() override should call Print().
*/
virtual void PrintSpace(int depth);
void Print( const char* format, ... );

void SealElementIfJustOpened();
bool _elementJustOpened;
DynArray< const char*, 10 > _stack;

private:
    void PrintString( const char*, bool restrictedEntitySet);   // prints out, after detecting entities.

bool _firstElement;
FILE* _fp;
int _depth;
int _textDepth;
bool _processEntities;
bool _compactMode;

enum {
    ENTITY_RANGE = 64,
    BUF_SIZE = 200
};
bool _entityFlag[ENTITY_RANGE];
bool _restrictedEntityFlag[ENTITY_RANGE];

DynArray _buffer;
};


}        // tinyxml2

#if defined(_MSC_VER)
#   pragma warning(pop)
#endif

#endif TINYXML2_INCLUDED
/*
Syn's AYYWAREFramework 2015
*/

#include "UTIL Functions.h"
#include "Utilities.h"

#include "RenderManager.h"

void UTIL_TraceLine(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
        const IClientEntity* ignore, int collisionGroup, trace_t* ptr)
{
    typedef int(__fastcall * UTIL_TraceLine_t)(const Vector&, const Vector&, unsigned int, const IClientEntity*, int, trace_t*);
    static UTIL_TraceLine_t TraceLine = (UTIL_TraceLine_t)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x83\xE4\xF0\x83\xEC\x7C\x56\x52", "xxxxxxxxxxx");
    TraceLine(vecAbsStart, vecAbsEnd, mask, ignore, collisionGroup, ptr);
}

void UTIL_ClipTraceToPlayers(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter* filter, trace_t* tr)
{
    static DWORD dwAddress = Utilities::Memory::FindPattern("client.dll", (BYTE*)"\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\x00\x00\x00\x00\x8B\x43\x10", "xxxxxxxxxxxxxxxxxxxxxxxx????xxx");

    if (!dwAddress)
        return;

    _asm

    {
        MOV EAX, filter

            LEA ECX, tr

            PUSH ECX

            PUSH EAX

            PUSH mask

            LEA EDX, vecAbsEnd

            LEA ECX, vecAbsStart

            CALL dwAddress

            ADD ESP, 0xC

    }
}

bool IsBreakableEntity(IClientEntity* ent)
{
    typedef bool(__thiscall * IsBreakbaleEntity_t)(IClientEntity *);
    IsBreakbaleEntity_t IsBreakbaleEntityFn = (IsBreakbaleEntity_t)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x51\x56\x8B\xF1\x85\xF6\x74\x68", "xxxxxxxxxxx");
    if (IsBreakbaleEntityFn)
        return IsBreakbaleEntityFn(ent);
    else
        return false;
}

bool TraceToExit(Vector& end, trace_t& tr, Vector start, Vector vEnd, trace_t* trace)
{
    typedef bool(__fastcall * TraceToExitFn)(Vector &, trace_t &, float, float, float, float, float, float, trace_t *);
    static TraceToExitFn TraceToExit = (TraceToExitFn)Utilities::Memory::FindPattern("client.dll", (BYTE*)"\x55\x8B\xEC\x83\xEC\x2C\xF3\x0F\x10\x75\x00\x33\xC0", "xxxxxxxxxx?xx");

    if (!TraceToExit)
        return false;

    return TraceToExit(end, tr, start.x, start.y, start.z, vEnd.x, vEnd.y, vEnd.z, trace);
}

void GameUtils::NormaliseViewAngle(Vector &angle)
{
    while (angle.y <= -180) angle.y += 360;
    while (angle.y > 180) angle.y -= 360;
    while (angle.x <= -180) angle.x += 360;
    while (angle.x > 180) angle.x -= 360;


    if (angle.x > 89.0) angle.x = 89;
    if (angle.x < -89.0) angle.x = -89;
    if (angle.y < -180) angle.y = -179.999;
    if (angle.y > 180) angle.y = 179.999;

    angle.z = 0;
}

void GameUtils::CL_FixMove(CUserCmd* pCmd, Vector viewangles)
{
    /*pCmd->forwardmove = DotProduct(forward * vForwardNorm, aimforward) + DotProduct(right * vRightNorm, aimforward) + DotProduct(up * vUpNorm, aimforward);
        pCmd->sidemove = DotProduct(forward * vForwardNorm, aimright) + DotProduct(right * vRightNorm, aimright) + DotProduct(up * vUpNorm, aimright);
        pCmd->upmove = DotProduct(forward * vForwardNorm, aimup) + DotProduct(right * vRightNorm, aimup) + DotProduct(up * vUpNorm, aimup);*/
}

char shit[16];
trace_t Trace;
char shit2[16];
IClientEntity* entCopy;

bool GameUtils::IsVisible(IClientEntity* pLocal, IClientEntity* pEntity, int BoneID)
{
    if (BoneID < 0) return false;

    entCopy = pEntity;
    Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector end = GetHitboxPosition(pEntity, BoneID);//pEntity->GetBonePos(BoneID);
    char shit3[32];

    //Interfaces::Trace->TraceRay(Ray,MASK_SOLID, NULL/*&filter*/, &Trace);
    UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

    if (Trace.m_pEnt == entCopy)
    {
        return true;
    }

    if (Trace.fraction == 1.0f)
    {
        return true;
    }

    return false;

}

bool GameUtils::IsBallisticWeapon(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CKnife || pWeaponClass->m_ClassID == (int)CSGOClassID::CHEGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CDecoyGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CIncendiaryGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CSmokeGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CC4)
        return false;
    else
        return true;
}

bool GameUtils::IsPistol(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CDEagle || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponElite || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponFiveSeven || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponGlock || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponHKP2000 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponP250 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponP228 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponTec9 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponUSP)
        return true;
    else
        return false;
}

bool GameUtils::IsSniper(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponAWP || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponSSG08 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponSCAR20 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponG3SG1)
        return true;
    else
        return false;
}

void SayInChat(const char* text)
{
    char buffer[250];
    sprintf_s(buffer, "say \"%s\"", text);
    Interfaces::Engine->ClientCmd_Unrestricted(buffer);
}

Vector GetHitboxPosition(IClientEntity* pEntity, int Hitbox)
{
    matrix3x4 matrix[128];

    if (!pEntity->SetupBones(matrix, 128, 0x00000100, GetTickCount64()))
        return Vector(0, 0, 0);

    studiohdr_t* hdr = Interfaces::ModelInfo->GetStudiomodel(pEntity->GetModel());
    mstudiohitboxset_t* set = hdr->GetHitboxSet(0);

    mstudiobbox_t* hitbox = set->GetHitbox(Hitbox);

    if (!hitbox)
        return Vector(0, 0, 0);

    Vector vMin, vMax, vCenter, sCenter;
    VectorTransform(hitbox->bbmin, matrix[hitbox->bone], vMin);
    VectorTransform(hitbox->bbmax, matrix[hitbox->bone], vMax);
    vCenter = (vMin + vMax) * 0.5f;
    return vCenter;
}

int GameUtils::GetPlayerCompRank(IClientEntity* pEntity)
{
    static DWORD m_iCompetitiveRanking = NetVar.GetNetVar(0x75671F7F);
    static DWORD GameResources = *(DWORD*)(Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x85\xFF\x0F\x84\x00\x00\x00\x00\x81\xC7", "xx????xxxx????xx") + 0x2);

    return *(int*)((DWORD)GameResources + m_iCompetitiveRanking + (int)pEntity->GetIndex() * 4);
}

void ForceUpdate()
{
    // Shh
    static DWORD clientstateaddr = Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x8A\xF9\xF3\x0F\x11\x45\xF8\x83\xBF\xE8\x00\x00\x00\x02", "xx????xxxxxxxxxxxxxx");
    static uintptr_t pEngineBase = (uintptr_t)GetModuleHandleA("engine.dll");

    static uintptr_t pClientState = **(uintptr_t**)(Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x8A\xF9", "xx????xx") + 2);

    static uintptr_t dwAddr1 = Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\xE8\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\xC7\x87\x00\x00\x00\x00\x00\x00\x00\x00", "x????x????x????xx????????");

    //E8 call is being used here
    static uintptr_t dwRelAddr = *(uintptr_t*)(dwAddr1 + 1);
    static uintptr_t sub_B5E60 = ((dwAddr1 + 5) + dwRelAddr);

    __asm

    {
        pushad
        mov edi, pClientState
        lea ecx, dword ptr[edi + 0x8]

        call sub_B5E60

        mov dword ptr[edi + 0x154], 0xFFFFFFFF

        popad

    }
}/*
Syn's AYYWAREFramework 2015
*/

#include "UTIL Functions.h"
#include "Utilities.h"

#include "RenderManager.h"

void UTIL_TraceLine(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,
        const IClientEntity* ignore, int collisionGroup, trace_t* ptr)
{
    typedef int(__fastcall * UTIL_TraceLine_t)(const Vector&, const Vector&, unsigned int, const IClientEntity*, int, trace_t*);
    static UTIL_TraceLine_t TraceLine = (UTIL_TraceLine_t)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x83\xE4\xF0\x83\xEC\x7C\x56\x52", "xxxxxxxxxxx");
    TraceLine(vecAbsStart, vecAbsEnd, mask, ignore, collisionGroup, ptr);
}

void UTIL_ClipTraceToPlayers(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter* filter, trace_t* tr)
{
    static DWORD dwAddress = Utilities::Memory::FindPattern("client.dll", (BYTE*)"\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x81\xEC\x00\x00\x00\x00\x8B\x43\x10", "xxxxxxxxxxxxxxxxxxxxxxxx????xxx");

    if (!dwAddress)
        return;

    _asm

    {
        MOV EAX, filter

            LEA ECX, tr

            PUSH ECX

            PUSH EAX

            PUSH mask

            LEA EDX, vecAbsEnd

            LEA ECX, vecAbsStart

            CALL dwAddress

            ADD ESP, 0xC

    }
}

bool IsBreakableEntity(IClientEntity* ent)
{
    typedef bool(__thiscall * IsBreakbaleEntity_t)(IClientEntity *);
    IsBreakbaleEntity_t IsBreakbaleEntityFn = (IsBreakbaleEntity_t)Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x55\x8B\xEC\x51\x56\x8B\xF1\x85\xF6\x74\x68", "xxxxxxxxxxx");
    if (IsBreakbaleEntityFn)
        return IsBreakbaleEntityFn(ent);
    else
        return false;
}

bool TraceToExit(Vector& end, trace_t& tr, Vector start, Vector vEnd, trace_t* trace)
{
    typedef bool(__fastcall * TraceToExitFn)(Vector &, trace_t &, float, float, float, float, float, float, trace_t *);
    static TraceToExitFn TraceToExit = (TraceToExitFn)Utilities::Memory::FindPattern("client.dll", (BYTE*)"\x55\x8B\xEC\x83\xEC\x2C\xF3\x0F\x10\x75\x00\x33\xC0", "xxxxxxxxxx?xx");

    if (!TraceToExit)
        return false;

    return TraceToExit(end, tr, start.x, start.y, start.z, vEnd.x, vEnd.y, vEnd.z, trace);
}

void GameUtils::NormaliseViewAngle(Vector &angle)
{
    while (angle.y <= -180) angle.y += 360;
    while (angle.y > 180) angle.y -= 360;
    while (angle.x <= -180) angle.x += 360;
    while (angle.x > 180) angle.x -= 360;


    if (angle.x > 89.0) angle.x = 89;
    if (angle.x < -89.0) angle.x = -89;
    if (angle.y < -180) angle.y = -179.999;
    if (angle.y > 180) angle.y = 179.999;

    angle.z = 0;
}

void GameUtils::CL_FixMove(CUserCmd* pCmd, Vector viewangles)
{
    /*pCmd->forwardmove = DotProduct(forward * vForwardNorm, aimforward) + DotProduct(right * vRightNorm, aimforward) + DotProduct(up * vUpNorm, aimforward);
        pCmd->sidemove = DotProduct(forward * vForwardNorm, aimright) + DotProduct(right * vRightNorm, aimright) + DotProduct(up * vUpNorm, aimright);
        pCmd->upmove = DotProduct(forward * vForwardNorm, aimup) + DotProduct(right * vRightNorm, aimup) + DotProduct(up * vUpNorm, aimup);*/
}

char shit[16];
trace_t Trace;
char shit2[16];
IClientEntity* entCopy;

bool GameUtils::IsVisible(IClientEntity* pLocal, IClientEntity* pEntity, int BoneID)
{
    if (BoneID < 0) return false;

    entCopy = pEntity;
    Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector end = GetHitboxPosition(pEntity, BoneID);//pEntity->GetBonePos(BoneID);
    char shit3[32];

    //Interfaces::Trace->TraceRay(Ray,MASK_SOLID, NULL/*&filter*/, &Trace);
    UTIL_TraceLine(start, end, MASK_SOLID, pLocal, 0, &Trace);

    if (Trace.m_pEnt == entCopy)
    {
        return true;
    }

    if (Trace.fraction == 1.0f)
    {
        return true;
    }

    return false;

}

bool GameUtils::IsBallisticWeapon(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CKnife || pWeaponClass->m_ClassID == (int)CSGOClassID::CHEGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CDecoyGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CIncendiaryGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CSmokeGrenade || pWeaponClass->m_ClassID == (int)CSGOClassID::CC4)
        return false;
    else
        return true;
}

bool GameUtils::IsPistol(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CDEagle || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponElite || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponFiveSeven || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponGlock || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponHKP2000 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponP250 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponP228 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponTec9 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponUSP)
        return true;
    else
        return false;
}

bool GameUtils::IsSniper(void* weapon)
{
    if (weapon == nullptr) return false;
    IClientEntity* weaponEnt = (IClientEntity*)weapon;
    ClientClass* pWeaponClass = weaponEnt->GetClientClass();

    if (pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponAWP || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponSSG08 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponSCAR20 || pWeaponClass->m_ClassID == (int)CSGOClassID::CWeaponG3SG1)
        return true;
    else
        return false;
}

void SayInChat(const char* text)
{
    char buffer[250];
    sprintf_s(buffer, "say \"%s\"", text);
    Interfaces::Engine->ClientCmd_Unrestricted(buffer);
}

Vector GetHitboxPosition(IClientEntity* pEntity, int Hitbox)
{
    matrix3x4 matrix[128];

    if (!pEntity->SetupBones(matrix, 128, 0x00000100, GetTickCount64()))
        return Vector(0, 0, 0);

    studiohdr_t* hdr = Interfaces::ModelInfo->GetStudiomodel(pEntity->GetModel());
    mstudiohitboxset_t* set = hdr->GetHitboxSet(0);

    mstudiobbox_t* hitbox = set->GetHitbox(Hitbox);

    if (!hitbox)
        return Vector(0, 0, 0);

    Vector vMin, vMax, vCenter, sCenter;
    VectorTransform(hitbox->bbmin, matrix[hitbox->bone], vMin);
    VectorTransform(hitbox->bbmax, matrix[hitbox->bone], vMax);
    vCenter = (vMin + vMax) * 0.5f;
    return vCenter;
}

int GameUtils::GetPlayerCompRank(IClientEntity* pEntity)
{
    static DWORD m_iCompetitiveRanking = NetVar.GetNetVar(0x75671F7F);
    static DWORD GameResources = *(DWORD*)(Utilities::Memory::FindPattern("client.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x85\xFF\x0F\x84\x00\x00\x00\x00\x81\xC7", "xx????xxxx????xx") + 0x2);

    return *(int*)((DWORD)GameResources + m_iCompetitiveRanking + (int)pEntity->GetIndex() * 4);
}

void ForceUpdate()
{
    // Shh
    static DWORD clientstateaddr = Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x8A\xF9\xF3\x0F\x11\x45\xF8\x83\xBF\xE8\x00\x00\x00\x02", "xx????xxxxxxxxxxxxxx");
    static uintptr_t pEngineBase = (uintptr_t)GetModuleHandleA("engine.dll");

    static uintptr_t pClientState = **(uintptr_t**)(Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\x8B\x3D\x00\x00\x00\x00\x8A\xF9", "xx????xx") + 2);

    static uintptr_t dwAddr1 = Utilities::Memory::FindPattern("engine.dll", (PBYTE)"\xE8\x00\x00\x00\x00\x68\x00\x00\x00\x00\x68\x00\x00\x00\x00\xC7\x87\x00\x00\x00\x00\x00\x00\x00\x00", "x????x????x????xx????????");

    //E8 call is being used here
    static uintptr_t dwRelAddr = *(uintptr_t*)(dwAddr1 + 1);
    static uintptr_t sub_B5E60 = ((dwAddr1 + 5) + dwRelAddr);

    __asm

    {
        pushad
        mov edi, pClientState
        lea ecx, dword ptr[edi + 0x8]

        call sub_B5E60

        mov dword ptr[edi + 0x154], 0xFFFFFFFF

        popad

    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "SDK.h"

namespace GameUtils
{
    void NormaliseViewAngle(Vector &angle);
    void CL_FixMove(CUserCmd* cmd, Vector viewangles);
    bool IsVisible(IClientEntity* pLocal, IClientEntity* pEntity, int BoneID);
    bool IsBallisticWeapon(void* weapon);
    bool IsPistol(void* weapon);
    bool IsSniper(void* weapon);
    int GetPlayerCompRank(IClientEntity* pEntity);
};

// Trace Line Memes
void UTIL_TraceLine(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask,

const IClientEntity* ignore, int collisionGroup, trace_t* ptr);

void UTIL_ClipTraceToPlayers(const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, ITraceFilter* filter, trace_t* tr);

bool IsBreakableEntity(IClientEntity* ent);

bool TraceToExit(Vector& end, trace_t& tr, Vector start, Vector vEnd, trace_t* trace);

void SayInChat(const char* text);

Vector GetHitboxPosition(IClientEntity* pEntity, int Hitbox);

void ForceUpdate();
/*
Syn's AYYWAREFramework
*/
#pragma once
#define _CRT_SECURE_NO_WARNINGS

// Includes
#include "Utilities.h"
#include 
#include 

bool FileLog = false;
std::ofstream logFile;

// --------         Utilities Core           ------------ //
// Opens a debug console
void Utilities::OpenConsole(std::string Title)
{
    AllocConsole();
    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);

    SetConsoleTitle(Title.c_str());
}

// Closes the debug console
void Utilities::CloseConsole()
{
    FreeConsole();
}

// Outputs text to the console
void Utilities::Log(const char* fmt, ...)
{
    if (!fmt) return; //if the passed string is null return
    if (strlen(fmt) < 2) return;

    //Set up va_list and buffer to hold the params 
    va_list va_alist;
    char logBuf[256] = { 0 };

    //Do sprintf with the parameters
    va_start(va_alist, fmt);
    _vsnprintf(logBuf + strlen(logBuf), sizeof(logBuf) - strlen(logBuf), fmt, va_alist);
    va_end(va_alist);

    //Output to console
    if (logBuf[0] != '\0')
    {
        SetConsoleColor(FOREGROUND_INTENSE_GREEN);
        printf("[%s]", GetTimeString().c_str());
        SetConsoleColor(FOREGROUND_WHITE);
        printf(": %s\n", logBuf);
    }

    if (FileLog)
    {
        logFile << logBuf << std::endl;
    }
}

// Gets the current time as a string
std::string Utilities::GetTimeString()
{
    //Time related variables
    time_t current_time;

    struct tm * time_info;
static char timeString[10];

    //Get current time
    time(¤t_time);
time_info = localtime(¤t_time);

    //Get current time as string
    strftime(timeString, sizeof(timeString), "%I:%M%p", time_info);
        return timeString;
}

// Sets the console color for upcoming text
void Utilities::SetConsoleColor(WORD color)
{
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}

// Enables writing all log calls to a file
void Utilities::EnableLogFile(std::string filename)
{
    logFile.open(filename.c_str());
    if (logFile.is_open())
        FileLog = true;
}


// --------         Utilities Memory           ------------ //

DWORD Utilities::Memory::WaitOnModuleHandle(std::string moduleName)
{
    DWORD ModuleHandle = NULL;
    while (!ModuleHandle)
    {
        ModuleHandle = (DWORD)GetModuleHandle(moduleName.c_str());
        if (!ModuleHandle)
            Sleep(50);
    }
    return ModuleHandle;
}

bool bCompare(const BYTE* Data, const BYTE* Mask, const char* szMask)
{
    for (; *szMask; ++szMask, ++Mask, ++Data)
    {
        if (*szMask == 'x' && *Mask != *Data)
        {
            return false;
        }
    }
    return (*szMask) == 0;
}

DWORD Utilities::Memory::FindPattern(std::string moduleName, BYTE* Mask, char* szMask)
{
    DWORD Address = WaitOnModuleHandle(moduleName.c_str());
    MODULEINFO ModInfo; GetModuleInformation(GetCurrentProcess(), (HMODULE)Address, &ModInfo, sizeof(MODULEINFO));
    DWORD Length = ModInfo.SizeOfImage;
    for (DWORD c = 0; c < Length; c += 1)
    {
        if (bCompare((BYTE*)(Address + c), Mask, szMask))
        {
            return (DWORD)(Address + c);
        }
    }
    return 0;
}

DWORD Utilities::Memory::FindTextPattern(std::string moduleName, char* string)
{
    DWORD Address = WaitOnModuleHandle(moduleName.c_str());
    MODULEINFO ModInfo; GetModuleInformation(GetCurrentProcess(), (HMODULE)Address, &ModInfo, sizeof(MODULEINFO));
    DWORD Length = ModInfo.SizeOfImage;

    int len = strlen(string);
    char* szMask = new char[len + 1];
    for (int i = 0; i < len; i++)
    {
        szMask[i] = 'x';
    }
    szMask[len] = '\0';

    for (DWORD c = 0; c < Length; c += 1)
    {
        if (bCompare((BYTE*)(Address + c), (BYTE*)string, szMask))
        {
            return (DWORD)(Address + c);
        }
    }
    return 0;
}

// --------         Utilities Memory VMT Manager       ------------ //

bool Utilities::Memory::VMTManager::Initialise(DWORD* InstancePointer)
{
    // Store the instance pointers and such, and work out how big the table is
    Instance = InstancePointer;
    OriginalTable = (DWORD*)*InstancePointer;
    int VMTSize = MethodCount(InstancePointer);
    size_t TableBytes = VMTSize * 4;

    // Allocate some memory and copy the table
    CustomTable = (DWORD*)malloc(TableBytes + 8);
    if (!CustomTable) return false;
    memcpy((void*)CustomTable, (void*)OriginalTable, VMTSize * 4);

    // Change the pointer
    *InstancePointer = (DWORD)CustomTable;

    initComplete = true;
    return true;
}

int Utilities::Memory::VMTManager::MethodCount(DWORD* InstancePointer)
{
    DWORD* VMT = (DWORD*)*InstancePointer;
    int Index = 0;
    int Amount = 0;
    while (!IsBadCodePtr((FARPROC)VMT[Index]))
    {
        if (!IsBadCodePtr((FARPROC)VMT[Index]))
        {
            Amount++;
            Index++;
        }
    }

    return Amount;
}

DWORD Utilities::Memory::VMTManager::HookMethod(DWORD NewFunction, int Index)
{
    if (initComplete)
    {
        CustomTable[Index] = NewFunction;
        return OriginalTable[Index];
    }
    else
        return NULL;
}

void Utilities::Memory::VMTManager::UnhookMethod(int Index)
{
    if (initComplete)
        CustomTable[Index] = OriginalTable[Index];
    return;
}

void Utilities::Memory::VMTManager::RestoreOriginal()
{
    if (initComplete)
    {
        *Instance = (DWORD)OriginalTable;
    }
    return;
}

void Utilities::Memory::VMTManager::RestoreCustom()
{
    if (initComplete)
    {
        *Instance = (DWORD)CustomTable;
    }
    return;
}

DWORD Utilities::Memory::VMTManager::GetOriginalFunction(int Index)
{
    return OriginalTable[Index];
}
/*
Syn's AYYWAREFramework
*/

#pragma once

// Includes
#include "CommonIncludes.h"
#include 

// Colors for the console
//Define extra colours
#define FOREGROUND_WHITE                    (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN)
#define FOREGROUND_YELLOW               (FOREGROUND_RED | FOREGROUND_GREEN)
#define FOREGROUND_CYAN                        (FOREGROUND_BLUE | FOREGROUND_GREEN)
#define FOREGROUND_MAGENTA                (FOREGROUND_RED | FOREGROUND_BLUE)
#define FOREGROUND_BLACK                    0

#define FOREGROUND_INTENSE_RED                (FOREGROUND_RED | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_GREEN        (FOREGROUND_GREEN | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_BLUE                (FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_WHITE        (FOREGROUND_WHITE | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_YELLOW        (FOREGROUND_YELLOW | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_CYAN                (FOREGROUND_CYAN | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_MAGENTA        (FOREGROUND_MAGENTA | FOREGROUND_INTENSITY)

// Utilities Namespace
// Purpose: Contains misc functionality for memory related functionality
namespace Utilities
{
    // Debug console controls
    void OpenConsole(std::string Title);
    void CloseConsole();
    void Log(const char* fmt, ...);

    void EnableLogFile(std::string filename);

    void SetConsoleColor(WORD color);

    // Misc Shizz
    std::string GetTimeString();

    // Memory utils
    // Purpose: Provides memeory related functionality (pattern scanning ect)
    namespace Memory
    {
        // Waits for a module to be available, before returning it's base address
        DWORD WaitOnModuleHandle(std::string moduleName);

        // Attempts to locate the given signature and mask in a memory range
        // Returns the address at which it has been found
        DWORD FindPattern(std::string moduleName, BYTE* Mask, char* szMask);

        // Attempts to locate the given text in a memory range
        // Returns the address at which it has been found
        DWORD FindTextPattern(std::string moduleName, char* string);

        class VMTManager
        {
            private:
                        DWORD* CustomTable;
            bool initComplete;
            DWORD* OriginalTable;
            DWORD* Instance;

            int MethodCount(DWORD* InstancePointer);

            public:
                        bool Initialise(DWORD* InstancePointer); // Pass a &class

            DWORD HookMethod(DWORD NewFunction, int Index);
            void UnhookMethod(int Index);

            void RestoreOriginal();
            void RestoreCustom();

            DWORD GetOriginalFunction(int Index);
        };
    };
};

/*
Syn's AYYWAREFramework
*/

#pragma once

// Includes
#include "CommonIncludes.h"
#include 

// Colors for the console
//Define extra colours
#define FOREGROUND_WHITE                    (FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN)
#define FOREGROUND_YELLOW               (FOREGROUND_RED | FOREGROUND_GREEN)
#define FOREGROUND_CYAN                        (FOREGROUND_BLUE | FOREGROUND_GREEN)
#define FOREGROUND_MAGENTA                (FOREGROUND_RED | FOREGROUND_BLUE)
#define FOREGROUND_BLACK                    0

#define FOREGROUND_INTENSE_RED                (FOREGROUND_RED | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_GREEN        (FOREGROUND_GREEN | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_BLUE                (FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_WHITE        (FOREGROUND_WHITE | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_YELLOW        (FOREGROUND_YELLOW | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_CYAN                (FOREGROUND_CYAN | FOREGROUND_INTENSITY)
#define FOREGROUND_INTENSE_MAGENTA        (FOREGROUND_MAGENTA | FOREGROUND_INTENSITY)

// Utilities Namespace
// Purpose: Contains misc functionality for memory related functionality
namespace Utilities
{
        // Debug console controls
        void OpenConsole(std::string Title);
        void CloseConsole();
        void Log(const char *fmt, ...);

        void EnableLogFile(std::string filename);

        void SetConsoleColor(WORD color);  

        // Misc Shizz
        std::string GetTimeString();
        
        // Memory utils
        // Purpose: Provides memeory related functionality (pattern scanning ect)
        namespace Memory
        {
                // Waits for a module to be available, before returning it's base address
                DWORD WaitOnModuleHandle(std::string moduleName);

                // Attempts to locate the given signature and mask in a memory range
                // Returns the address at which it has been found
                DWORD FindPattern(std::string moduleName, BYTE* Mask, char* szMask);

                // Attempts to locate the given text in a memory range
                // Returns the address at which it has been found
                DWORD FindTextPattern(std::string moduleName, char* string);

                class VMTManager
                {
                private:
                        DWORD        *CustomTable;
                        bool        initComplete;
                        DWORD        *OriginalTable;
                        DWORD        *Instance;

                        int                MethodCount(DWORD* InstancePointer);
                        
                public:
                        bool        Initialise(DWORD* InstancePointer); // Pass a &class

                        DWORD        HookMethod(DWORD NewFunction, int Index);
                        void        UnhookMethod(int Index);

                        void        RestoreOriginal();
                        void        RestoreCustom();

                        DWORD        GetOriginalFunction(int Index);
                };
        };
};

#ifndef _VECTORZ_H
#define _VECTORZ_H

#define CHECK_VALID( _v ) 0
#define Assert( _exp ) ((void)0)

#include 
#include 

// from the leaked sdk

#define  FORCEINLINE                        __forceinline

typedef float vec_t;

inline vec_t BitsToFloat(unsigned long i)
{
return *reinterpret_cast(&i);
}

#define FLOAT32_NAN_BITS     (unsigned long)0x7FC00000
#define FLOAT32_NAN          BitsToFloat( FLOAT32_NAN_BITS )

#define VEC_T_NAN FLOAT32_NAN

class Vector
{
    public:
        vec_t x, y, z;

    Vector(void);
    Vector(vec_t X, vec_t Y, vec_t Z);
    explicit Vector(vec_t XYZ);

    void Init(vec_t ix = 0.0f, vec_t iy = 0.0f, vec_t iz = 0.0f);

    bool IsValid() const;
    void Invalidate();

    vec_t operator[](int i) const;
    vec_t&  operator[](int i);

    vec_t* Base();
    vec_t const* Base() const;

    inline void Zero();

    bool operator ==(const Vector& v) const;
    bool operator !=(const Vector& v) const;

    FORCEINLINE Vector& operator+=(const Vector& v);
        FORCEINLINE Vector& operator-=(const Vector& v);
        FORCEINLINE Vector& operator*=(const Vector& v);
        FORCEINLINE Vector& operator*=(float s);
    FORCEINLINE Vector& operator/=(const Vector& v);
        FORCEINLINE Vector& operator/=(float s);
    FORCEINLINE Vector& operator+=(float fl);
    FORCEINLINE Vector& operator-=(float fl);

    void Negate();

    inline vec_t Length() const;

    FORCEINLINE vec_t LengthSqr(void) const
        {
                return (x* x + y* y + z* z);
}

bool IsZero(float tolerance = 0.01f) const
        {
                return (x > -tolerance && x
            y> -tolerance && y
           z> -tolerance && z         }

        vec_t NormalizeInPlace();
Vector Normalized() const;

bool IsLengthGreaterThan(float val) const;
bool IsLengthLessThan(float val) const;

FORCEINLINE bool WithinAABox(Vector const &boxmin, Vector const &boxmax);

vec_t DistTo(const Vector& vOther) const;

FORCEINLINE vec_t DistToSqr(const Vector& vOther) const
        {
                Vector delta;

delta.x = x - vOther.x;
                delta.y = y - vOther.y;
                delta.z = z - vOther.z;

                return delta.LengthSqr();
        }

        void CopyToArray(float* rgfl) const;
void MulAdd(const Vector& a, const Vector& b, float scalar);

vec_t Dot(const Vector& vOther) const;

Vector& operator=(const Vector& vOther);

vec_t Length2D(void) const;
vec_t Length2DSqr(void) const;

Vector operator -(void) const;
Vector operator +(const Vector& v) const;
Vector operator -(const Vector& v) const;
Vector operator *(const Vector& v) const;
Vector operator /(const Vector& v) const;
Vector operator *(float fl) const;
Vector operator /(float fl) const;

Vector Cross(const Vector& vOther) const;

Vector Min(const Vector& vOther) const;
Vector Max(const Vector& vOther) const;
};

FORCEINLINE Vector ReplicateToVector(float x)
{
    return Vector(x, x, x);
}

inline Vector::Vector(void)
{

}



inline Vector::Vector(vec_t X, vec_t Y, vec_t Z)
{
    x = X; y = Y; z = Z;
}

inline Vector::Vector(vec_t XYZ)
{
    x = y = z = XYZ;
}

inline void Vector::Init(vec_t ix, vec_t iy, vec_t iz)
{
    x = ix; y = iy; z = iz;
}

inline void Vector::Zero()
{
    x = y = z = 0.0f;
}

inline void VectorClear(Vector& a)
{
    a.x = a.y = a.z = 0.0f;
}

inline Vector& Vector::operator=(const Vector& vOther)
{
    x = vOther.x; y = vOther.y; z = vOther.z;
    return *this;
}

inline vec_t& Vector::operator[](int i)
{
        return ((vec_t*)this)[i];
}

inline vec_t Vector::operator[](int i) const
{
        return ((vec_t*)this)[i];
}



inline vec_t* Vector::Base()
{
    return (vec_t*)this;
}

inline vec_t const* Vector::Base() const
{
        return (vec_t const*)this;
}

inline bool Vector::IsValid() const
{
        return (x == x && y == y && z == z);
}

inline void Vector::Invalidate()
{
    x = y = z = VEC_T_NAN;
}

inline bool Vector::operator==(const Vector& src) const
{
        return (src.x == x) && (src.y == y) && (src.z == z);
}

inline bool Vector::operator!=(const Vector& src) const
{
        return (src.x != x) || (src.y != y) || (src.z != z);
}

FORCEINLINE void VectorCopy(const Vector& src, Vector& dst)
{
    dst.x = src.x;
    dst.y = src.y;
    dst.z = src.z;
}

inline void Vector::CopyToArray(float* rgfl) const
{
        rgfl[0] = x; rgfl[1] = y; rgfl[2] = z;
}

inline void Vector::Negate()
{
    x = -x; y = -y; z = -z;
}

FORCEINLINE Vector& Vector::operator+=(const Vector& v)
{
    x += v.x; y += v.y; z += v.z;
    return *this;
}

FORCEINLINE Vector& Vector::operator-=(const Vector& v)
{
    x -= v.x; y -= v.y; z -= v.z;
    return *this;
}

FORCEINLINE Vector& Vector::operator*=(float fl)
{
    x *= fl;
    y *= fl;
    z *= fl;
    return *this;
}

FORCEINLINE Vector& Vector::operator*=(const Vector& v)
{
    x *= v.x;
    y *= v.y;
    z *= v.z;
    return *this;
}

FORCEINLINE Vector& Vector::operator+=(float fl)
{
    x += fl;
    y += fl;
    z += fl;
    return *this;
}

FORCEINLINE Vector& Vector::operator-=(float fl)
{
    x -= fl;
    y -= fl;
    z -= fl;
    return *this;
}

FORCEINLINE Vector& Vector::operator/=(float fl)
{
    float oofl = 1.0f / fl;
    x *= oofl;
    y *= oofl;
    z *= oofl;
    return *this;
}

FORCEINLINE Vector& Vector::operator/=(const Vector& v)
{
    x /= v.x;
    y /= v.y;
    z /= v.z;
    return *this;
}

FORCEINLINE void VectorAdd(const Vector& a, const Vector& b, Vector& c)
{
    c.x = a.x + b.x;
    c.y = a.y + b.y;
    c.z = a.z + b.z;
}

FORCEINLINE void VectorSubtract(const Vector& a, const Vector& b, Vector& c)
{
    c.x = a.x - b.x;
    c.y = a.y - b.y;
    c.z = a.z - b.z;
}

FORCEINLINE void VectorMultiply(const Vector& a, vec_t b, Vector& c)
{
    c.x = a.x * b;
    c.y = a.y * b;
    c.z = a.z * b;
}

FORCEINLINE void VectorMultiply(const Vector& a, const Vector& b, Vector& c)
{
    c.x = a.x * b.x;
    c.y = a.y * b.y;
    c.z = a.z * b.z;
}

inline void VectorScale(const Vector& in, vec_t scale, Vector& result)
{
    VectorMultiply(in, scale, result);
}

FORCEINLINE void VectorDivide(const Vector& a, vec_t b, Vector& c)
{
    vec_t oob = 1.0f / b;
    c.x = a.x * oob;
    c.y = a.y * oob;
    c.z = a.z * oob;
}

FORCEINLINE void VectorDivide(const Vector& a, const Vector& b, Vector& c)
{
    c.x = a.x / b.x;
    c.y = a.y / b.y;
    c.z = a.z / b.z;
}

inline void Vector::MulAdd(const Vector& a, const Vector& b, float scalar)
{
    x = a.x + b.x * scalar;
    y = a.y + b.y * scalar;
    z = a.z + b.z * scalar;
}

inline void VectorLerp(const Vector& src1, const Vector& src2, vec_t t, Vector& dest)
{
    dest.x = src1.x + (src2.x - src1.x) * t;
    dest.y = src1.y + (src2.y - src1.y) * t;
    dest.z = src1.z + (src2.z - src1.z) * t;
}

FORCEINLINE vec_t DotProduct(const Vector& a, const Vector& b)
{
    return (a.x * b.x + a.y * b.y + a.z * b.z);
}

inline vec_t Vector::Dot(const Vector& vOther) const
{
        return DotProduct(*this, vOther);
}

inline void CrossProduct(const Vector& a, const Vector& b, Vector& result)
{
    result.x = a.y * b.z - a.z * b.y;
    result.y = a.z * b.x - a.x * b.z;
    result.z = a.x * b.y - a.y * b.x;
}

//inline vec_t DotProductAbs(const Vector& v0, const Vector& v1)
//{
//        return abs(v0.x * v1.x) + abs(v0.y * v1.y) + abs(v0.z * v1.z);
//}

inline vec_t VectorLength(const Vector& v)
{
    return (vec_t)sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}

inline vec_t Vector::Length(void) const
{
        return VectorLength(*this);
}

inline vec_t VectorNormalize(Vector& v)
{
    vec_t l = v.Length();

    if (l != 0.0f)
    {
        v /= l;
    }
    else
    {
        v.x = v.y = 0.0f; v.z = 1.0f;
    }

    return l;
}

FORCEINLINE float VectorNormalizer(float* v)
{
    return VectorNormalize(*(reinterpret_cast(v)));
}
inline vec_t Vector::NormalizeInPlace()
{
        return VectorNormalize(*this);
}

bool Vector::WithinAABox(Vector const &boxmin, Vector const &boxmax)
{
    return (
        (x >= boxmin.x) && (x <= boxmax.x) &&
        (y >= boxmin.y) && (y <= boxmax.y) &&
        (z >= boxmin.z) && (z <= boxmax.z)
        );
}

inline vec_t Vector::DistTo(const Vector& vOther) const
{
        Vector delta;

    VectorSubtract(*this, vOther, delta);
        return delta.Length();
}

inline Vector Vector::Min(const Vector& vOther) const
{
        return Vector(x         y         z }

inline Vector Vector::Max(const Vector& vOther) const
{
        return Vector(x > vOther.x? x : vOther.x,
        y > vOther.y? y : vOther.y,
        z > vOther.z? z : vOther.z);
}

inline Vector Vector::operator -(void) const
{
        return Vector(-x, -y, -z);
}

inline Vector Vector::operator +(const Vector& v) const
{
        Vector res;

    VectorAdd(*this, v, res);
        return res;
}

inline Vector Vector::operator -(const Vector& v) const
{
        Vector res;

    VectorSubtract(*this, v, res);
        return res;
}

inline Vector Vector::operator *(float fl) const
{
        Vector res;

    VectorMultiply(*this, fl, res);
        return res;
}

inline Vector Vector::operator *(const Vector& v) const
{
        Vector res;

    VectorMultiply(*this, v, res);
        return res;
}

inline Vector Vector::operator /(float fl) const
{
        Vector res;

    VectorDivide(*this, fl, res);
        return res;
}

inline Vector Vector::operator /(const Vector& v) const
{
        Vector res;

    VectorDivide(*this, v, res);
        return res;
}

inline Vector operator *(float fl, const Vector& v)
{
    return v * fl;
}

inline Vector Vector::Cross(const Vector& vOther) const
{
        Vector res;

    CrossProduct(*this, vOther, res);
        return res;
}

inline vec_t Vector::Length2D(void) const
{
        return (vec_t)::sqrtf(x* x + y* y);
}

inline vec_t Vector::Length2DSqr(void) const
{
        return (x* x + y* y);
}

inline Vector CrossProduct(const Vector& a, const Vector& b)
{
    return Vector(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}

inline void VectorMin(const Vector& a, const Vector& b, Vector& result)
{
    result.x = min(a.x, b.x);
    result.y = min(a.y, b.y);
    result.z = min(a.z, b.z);
}

inline void VectorMax(const Vector& a, const Vector& b, Vector& result)
{
    result.x = max(a.x, b.x);
    result.y = max(a.y, b.y);
    result.z = max(a.z, b.z);
}


class VectorAligned : public Vector
{
public:

    VectorAligned()
{
    x = y = z = 0.0f;
}


    VectorAligned(const Vector& v)
{
    x = v.x; y = v.y; z = v.z;
}

float w;
};



#endif // VECTOR_H
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//
//=============================================================================//

#ifndef VECTOR2D_H
#define VECTOR2D_H

#ifdef _WIN32
#pragma once
#endif

#include "MiscDefinitions.h"

#include 
#include 

// For rand(). We really need a library!
#include 

#define CHECK_VALID( _v ) 0
#define Assert( _exp ) ((void)0)

#define VALVE_RAND_MAX 0x7fff

//=========================================================
// 2D Vector2D
//=========================================================

class Vector2D
{
    public:
        // Members
        vec_t x, y;

    // Construction/destruction
    Vector2D(void);
    Vector2D(vec_t X, vec_t Y);
    Vector2D(const float* pFloat);

    // Initialization
    void Init(vec_t ix = 0.0f, vec_t iy = 0.0f);

    // Got any nasty NAN's?
    bool IsValid() const;

    // array access...
    vec_t operator[](int i) const;
    vec_t& operator[](int i);

    // Base address...
    vec_t* Base();
    vec_t const* Base() const;

    // Initialization methods
    void Random(float minVal, float maxVal);

    // equality
    bool operator ==(const Vector2D& v) const;
    bool operator !=(const Vector2D& v) const;

    // arithmetic operations
    Vector2D&        operator+=(const Vector2D &v);
        Vector2D&        operator-=(const Vector2D &v);
        Vector2D&        operator*=(const Vector2D &v);
        Vector2D&        operator*=(float s);
    Vector2D&        operator/=(const Vector2D &v);
        Vector2D&        operator/=(float s);

    // negate the Vector2D components
    void Negate();

    // Get the Vector2D's magnitude.
    vec_t Length() const;

    // Get the Vector2D's magnitude squared.
    vec_t LengthSqr(void) const;

    // return true if this vector is (0,0) within tolerance
    bool IsZero(float tolerance = 0.01f) const
        {
                return (x > -tolerance && x
            y> -tolerance && y         }

// Normalize in place and return the old length.
vec_t NormalizeInPlace();

// Compare length.
bool IsLengthGreaterThan(float val) const;
bool IsLengthLessThan(float val) const;

// Get the distance from this Vector2D to the other one.
vec_t DistTo(const Vector2D &vOther) const;

// Get the distance from this Vector2D to the other one squared.
vec_t DistToSqr(const Vector2D &vOther) const;

// Copy
void CopyToArray(float* rgfl) const;

// Multiply, add, and assign to this (ie: *this = a + b * scalar). This
// is about 12% faster than the actual Vector2D equation (because it's done per-component
// rather than per-Vector2D).
void MulAdd(const Vector2D& a, const Vector2D& b, float scalar);

// Dot product.
vec_t Dot(const Vector2D& vOther) const;

// assignment
Vector2D& operator=(const Vector2D &vOther);

# ifndef VECTOR_NO_SLOW_OPERATIONS
    // copy constructors
    Vector2D(const Vector2D &vOther);

// arithmetic operations
Vector2D operator -(void) const;

Vector2D operator +(const Vector2D& v) const;
Vector2D operator -(const Vector2D& v) const;
Vector2D operator *(const Vector2D& v) const;
Vector2D operator /(const Vector2D& v) const;
Vector2D operator *(float fl) const;
Vector2D operator /(float fl) const;

// Cross product between two vectors.
Vector2D Cross(const Vector2D &vOther) const;

// Returns a Vector2D with the min or max in X, Y, and Z.
Vector2D Min(const Vector2D &vOther) const;
Vector2D Max(const Vector2D &vOther) const;

#else

private:
    // No copy constructors allowed if we're in optimal mode
    Vector2D(const Vector2D& vOther);
#endif
};

//-----------------------------------------------------------------------------

const Vector2D vec2_origin(0, 0);
const Vector2D vec2_invalid(FLT_MAX, FLT_MAX);

//-----------------------------------------------------------------------------
// Vector2D related operations
//-----------------------------------------------------------------------------

// Vector2D clear
void Vector2DClear(Vector2D& a);

// Copy
void Vector2DCopy(const Vector2D& src, Vector2D& dst);

// Vector2D arithmetic
void Vector2DAdd(const Vector2D& a, const Vector2D& b, Vector2D& result);
void Vector2DSubtract(const Vector2D& a, const Vector2D& b, Vector2D& result);
void Vector2DMultiply(const Vector2D& a, vec_t b, Vector2D& result);
void Vector2DMultiply(const Vector2D& a, const Vector2D& b, Vector2D& result);
void Vector2DDivide(const Vector2D& a, vec_t b, Vector2D& result);
void Vector2DDivide(const Vector2D& a, const Vector2D& b, Vector2D& result);
void Vector2DMA(const Vector2D& start, float s, const Vector2D& dir, Vector2D& result);

// Store the min or max of each of x, y, and z into the result.
void Vector2DMin(const Vector2D &a, const Vector2D &b, Vector2D &result);
void Vector2DMax(const Vector2D &a, const Vector2D &b, Vector2D &result);

#define Vector2DExpand( v ) (v).x, (v).y

// Normalization
vec_t Vector2DNormalize(Vector2D& v);

// Length
vec_t Vector2DLength(const Vector2D& v);

// Dot Product
vec_t DotProduct2D(const Vector2D& a, const Vector2D& b);

// Linearly interpolate between two vectors
void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest);


//-----------------------------------------------------------------------------
//
// Inlined Vector2D methods
//
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// constructors
//-----------------------------------------------------------------------------

inline Vector2D::Vector2D(void)
{
# ifdef _DEBUG
    // Initialize to NAN to catch errors
    x = y = VEC_T_NAN;
#endif
}

inline Vector2D::Vector2D(vec_t X, vec_t Y)
{
    x = X; y = Y;
    Assert(IsValid());
}

inline Vector2D::Vector2D(const float* pFloat)
{
    Assert(pFloat);
    x = pFloat[0]; y = pFloat[1];
    Assert(IsValid());
}


//-----------------------------------------------------------------------------
// copy constructor
//-----------------------------------------------------------------------------

inline Vector2D::Vector2D(const Vector2D &vOther)
{
    Assert(vOther.IsValid());
    x = vOther.x; y = vOther.y;
}

//-----------------------------------------------------------------------------
// initialization
//-----------------------------------------------------------------------------

inline void Vector2D::Init(vec_t ix, vec_t iy)
{
    x = ix; y = iy;
    Assert(IsValid());
}

inline void Vector2D::Random(float minVal, float maxVal)
{
    x = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
    y = minVal + ((float)rand() / VALVE_RAND_MAX) * (maxVal - minVal);
}

inline void Vector2DClear(Vector2D& a)
{
    a.x = a.y = 0.0f;
}

//-----------------------------------------------------------------------------
// assignment
//-----------------------------------------------------------------------------

inline Vector2D& Vector2D::operator=(const Vector2D &vOther)
{
    Assert(vOther.IsValid());
    x = vOther.x; y = vOther.y;
    return *this;
}

//-----------------------------------------------------------------------------
// Array access
//-----------------------------------------------------------------------------

inline vec_t& Vector2D::operator[](int i)
{

    Assert((i >= 0) && (i< 2));
        return ((vec_t*)this)[i];
}

inline vec_t Vector2D::operator[](int i) const
{

    Assert((i >= 0) && (i< 2));
        return ((vec_t*)this)[i];
}

//-----------------------------------------------------------------------------
// Base address...
//-----------------------------------------------------------------------------

inline vec_t* Vector2D::Base()
{
    return (vec_t*)this;
}

inline vec_t const* Vector2D::Base() const
{
        return (vec_t const*)this;
}

//-----------------------------------------------------------------------------
// IsValid?
//-----------------------------------------------------------------------------

inline bool Vector2D::IsValid() const
{
        return IsFinite(x) && IsFinite(y);
}

//-----------------------------------------------------------------------------
// comparison
//-----------------------------------------------------------------------------

inline bool Vector2D::operator==(const Vector2D& src) const
{

    Assert(src.IsValid() && IsValid());
        return (src.x == x) && (src.y == y);
}

inline bool Vector2D::operator!=(const Vector2D& src) const
{

    Assert(src.IsValid() && IsValid());
        return (src.x != x) || (src.y != y);
}


//-----------------------------------------------------------------------------
// Copy
//-----------------------------------------------------------------------------

inline void Vector2DCopy(const Vector2D& src, Vector2D& dst)
{
    Assert(src.IsValid());
    dst.x = src.x;
    dst.y = src.y;
}

inline void Vector2D::CopyToArray(float* rgfl) const
{

    Assert(IsValid());

    Assert(rgfl);
rgfl[0] = x; rgfl[1] = y;
}

//-----------------------------------------------------------------------------
// standard math operations
//-----------------------------------------------------------------------------

inline void Vector2D::Negate()
{
    Assert(IsValid());
    x = -x; y = -y;
}

inline Vector2D& Vector2D::operator+=(const Vector2D& v)
{
    Assert(IsValid() && v.IsValid());
    x += v.x; y += v.y;
    return *this;
}

inline Vector2D& Vector2D::operator-=(const Vector2D& v)
{
    Assert(IsValid() && v.IsValid());
    x -= v.x; y -= v.y;
    return *this;
}

inline Vector2D& Vector2D::operator*=(float fl)
{
    x *= fl;
    y *= fl;
    Assert(IsValid());
    return *this;
}

inline Vector2D& Vector2D::operator*=(const Vector2D& v)
{
    x *= v.x;
    y *= v.y;
    Assert(IsValid());
    return *this;
}

inline Vector2D& Vector2D::operator/=(float fl)
{
    Assert(fl != 0.0f);
    float oofl = 1.0f / fl;
    x *= oofl;
    y *= oofl;
    Assert(IsValid());
    return *this;
}

inline Vector2D& Vector2D::operator/=(const Vector2D& v)
{
    Assert(v.x != 0.0f && v.y != 0.0f);
    x /= v.x;
    y /= v.y;
    Assert(IsValid());
    return *this;
}

inline void Vector2DAdd(const Vector2D& a, const Vector2D& b, Vector2D& c)
{
    Assert(a.IsValid() && b.IsValid());
    c.x = a.x + b.x;
    c.y = a.y + b.y;
}

inline void Vector2DSubtract(const Vector2D& a, const Vector2D& b, Vector2D& c)
{
    Assert(a.IsValid() && b.IsValid());
    c.x = a.x - b.x;
    c.y = a.y - b.y;
}

inline void Vector2DMultiply(const Vector2D& a, vec_t b, Vector2D& c)
{
    Assert(a.IsValid() && IsFinite(b));
    c.x = a.x * b;
    c.y = a.y * b;
}

inline void Vector2DMultiply(const Vector2D& a, const Vector2D& b, Vector2D& c)
{
    Assert(a.IsValid() && b.IsValid());
    c.x = a.x * b.x;
    c.y = a.y * b.y;
}


inline void Vector2DDivide(const Vector2D& a, vec_t b, Vector2D& c)
{
    Assert(a.IsValid());
    Assert(b != 0.0f);
    vec_t oob = 1.0f / b;
    c.x = a.x * oob;
    c.y = a.y * oob;
}

inline void Vector2DDivide(const Vector2D& a, const Vector2D& b, Vector2D& c)
{
    Assert(a.IsValid());
    Assert((b.x != 0.0f) && (b.y != 0.0f));
    c.x = a.x / b.x;
    c.y = a.y / b.y;
}

inline void Vector2DMA(const Vector2D& start, float s, const Vector2D& dir, Vector2D& result)
{
    Assert(start.IsValid() && IsFinite(s) && dir.IsValid());
    result.x = start.x + s * dir.x;
    result.y = start.y + s * dir.y;
}

// FIXME: Remove
// For backwards compatability
inline void Vector2D::MulAdd(const Vector2D& a, const Vector2D& b, float scalar)
{
    x = a.x + b.x * scalar;
    y = a.y + b.y * scalar;
}

inline void Vector2DLerp(const Vector2D& src1, const Vector2D& src2, vec_t t, Vector2D& dest)
{
    dest[0] = src1[0] + (src2[0] - src1[0]) * t;
    dest[1] = src1[1] + (src2[1] - src1[1]) * t;
}

//-----------------------------------------------------------------------------
// dot, cross
//-----------------------------------------------------------------------------
inline vec_t DotProduct2D(const Vector2D& a, const Vector2D& b)
{
    Assert(a.IsValid() && b.IsValid());
    return (a.x * b.x + a.y * b.y);
}

// for backwards compatability
inline vec_t Vector2D::Dot(const Vector2D& vOther) const
{
        return DotProduct2D(*this, vOther);
}


//-----------------------------------------------------------------------------
// length
//-----------------------------------------------------------------------------
inline vec_t Vector2DLength(const Vector2D& v)
{
    Assert(v.IsValid());
    return (vec_t)sqrt(v.x * v.x + v.y * v.y);
}

inline vec_t Vector2D::LengthSqr(void) const
{

    Assert(IsValid());
        return (x* x + y* y);
}

inline vec_t Vector2D::NormalizeInPlace()
{
        return Vector2DNormalize(*this);
}

inline bool Vector2D::IsLengthGreaterThan(float val) const
{
        return LengthSqr() > val* val;
}

inline bool Vector2D::IsLengthLessThan(float val) const
{
        return LengthSqr() < val* val;
}

inline vec_t Vector2D::Length(void) const
{
        return Vector2DLength(*this);
}


inline void Vector2DMin(const Vector2D &a, const Vector2D &b, Vector2D &result)
{
    result.x = (a.x < b.x) ? a.x : b.x;
    result.y = (a.y < b.y) ? a.y : b.y;
}


inline void Vector2DMax(const Vector2D &a, const Vector2D &b, Vector2D &result)
{
    result.x = (a.x > b.x) ? a.x : b.x;
    result.y = (a.y > b.y) ? a.y : b.y;
}


//-----------------------------------------------------------------------------
// Normalization
//-----------------------------------------------------------------------------
inline vec_t Vector2DNormalize(Vector2D& v)
{
    Assert(v.IsValid());
    vec_t l = v.Length();
    if (l != 0.0f)
    {
        v /= l;
    }
    else
    {
        v.x = v.y = 0.0f;
    }
    return l;
}


//-----------------------------------------------------------------------------
// Get the distance from this Vector2D to the other one 
//-----------------------------------------------------------------------------
inline vec_t Vector2D::DistTo(const Vector2D &vOther) const
{
        Vector2D delta;

    Vector2DSubtract(*this, vOther, delta);
        return delta.Length();
}

inline vec_t Vector2D::DistToSqr(const Vector2D &vOther) const
{
        Vector2D delta;

    Vector2DSubtract(*this, vOther, delta);
        return delta.LengthSqr();
}


//-----------------------------------------------------------------------------
// Computes the closest point to vecTarget no farther than flMaxDist from vecStart
//-----------------------------------------------------------------------------
inline void ComputeClosestPoint2D(const Vector2D& vecStart, float flMaxDist, const Vector2D& vecTarget, Vector2D* pResult)
{
    Vector2D vecDelta;
    Vector2DSubtract(vecTarget, vecStart, vecDelta);
    float flDistSqr = vecDelta.LengthSqr();
    if (flDistSqr <= flMaxDist * flMaxDist)
    {
        *pResult = vecTarget;
    }
    else
    {
        vecDelta /= sqrt(flDistSqr);
        Vector2DMA(vecStart, flMaxDist, vecDelta, *pResult);
    }
}



//-----------------------------------------------------------------------------
//
// Slow methods
//
//-----------------------------------------------------------------------------

#ifndef VECTOR_NO_SLOW_OPERATIONS

//-----------------------------------------------------------------------------
// Returns a Vector2D with the min or max in X, Y, and Z.
//-----------------------------------------------------------------------------

inline Vector2D Vector2D::Min(const Vector2D &vOther) const
{
        return Vector2D(x         y }

inline Vector2D Vector2D::Max(const Vector2D &vOther) const
{
        return Vector2D(x > vOther.x? x : vOther.x,
        y > vOther.y? y : vOther.y);
}


//-----------------------------------------------------------------------------
// arithmetic operations
//-----------------------------------------------------------------------------

inline Vector2D Vector2D::operator -(void) const
{
        return Vector2D(-x, -y);
}

inline Vector2D Vector2D::operator +(const Vector2D& v) const
{
        Vector2D res;

    Vector2DAdd(*this, v, res);
        return res;
}

inline Vector2D Vector2D::operator -(const Vector2D& v) const
{
        Vector2D res;

    Vector2DSubtract(*this, v, res);
        return res;
}

inline Vector2D Vector2D::operator *(float fl) const
{
        Vector2D res;

    Vector2DMultiply(*this, fl, res);
        return res;
}

inline Vector2D Vector2D::operator *(const Vector2D& v) const
{
        Vector2D res;

    Vector2DMultiply(*this, v, res);
        return res;
}

inline Vector2D Vector2D::operator /(float fl) const
{
        Vector2D res;

    Vector2DDivide(*this, fl, res);
        return res;
}

inline Vector2D Vector2D::operator /(const Vector2D& v) const
{
        Vector2D res;

    Vector2DDivide(*this, v, res);
        return res;
}

inline Vector2D operator *(float fl, const Vector2D& v)
{
    return v * fl;
}

#endif //slow

#endif // VECTOR2D_H
/*
Syn's AYYWAREFramework 2015
*/

#include "Visuals.h"
#include "Interfaces.h"
#include "RenderManager.h"

// Any init here
void CVisuals::Init()
{
    // Idk
}

// Don't really need to do anything in here
void CVisuals::Move(CUserCmd* pCmd) { }

// Main ESP Drawing loop
void CVisuals::Draw()
{
    // Crosshair
    if (Menu::Window.VisualsTab.OtherCrosshair.GetState())
        DrawCrosshair();

    // Recoil Crosshair
    if (Menu::Window.VisualsTab.OtherRecoilCrosshair.GetIndex())
        DrawRecoilCrosshair();


}

// Draw a basic crosshair
void CVisuals::DrawCrosshair()
{
    // Crosshair
    RECT View = Render::GetViewport();
    int MidX = View.right / 2;
    int MidY = View.bottom / 2;
    Render::Line(MidX - 8, MidY - 8, MidX + 8, MidY + 8, Color(0, 0, 0, 200));
    Render::Line(MidX + 8, MidY - 8, MidX - 8, MidY + 8, Color(0, 0, 0, 200));
    Render::Line(MidX - 4, MidY - 4, MidX + 4, MidY + 4, Color(0, 255, 0, 255));
    Render::Line(MidX + 4, MidY - 4, MidX - 4, MidY + 4, Color(0, 255, 0, 255));
}

// Recoil crosshair
void CVisuals::DrawRecoilCrosshair()
{
    if (Menu::Window.RageBotTab.AccuracyRecoil.GetState())
        return;

    IClientEntity* pLocal = hackManager.pLocal();

    // Get the view with the recoil
    Vector ViewAngles;
    Interfaces::Engine->GetViewAngles(ViewAngles);
    ViewAngles += pLocal->localPlayerExclusive()->GetAimPunchAngle() * 2.f;

    // Build a ray going fowards at that angle
    Vector fowardVec;
    AngleVectors(ViewAngles, &fowardVec);
    fowardVec *= 10000;

    // Get ray start / end
    Vector start = pLocal->GetOrigin() + pLocal->GetViewOffset();
    Vector end = start + fowardVec, endScreen;

    if (Render::WorldToScreen(end, endScreen) && pLocal->IsAlive())
    {
        Render::Line(endScreen.x - 4, endScreen.y - 4, endScreen.x + 4, endScreen.y + 4, Color(0, 255, 0, 255));
        Render::Line(endScreen.x + 4, endScreen.y - 4, endScreen.x - 4, endScreen.y + 4, Color(0, 255, 0, 255));
        Render::Line(endScreen.x - 2, endScreen.y - 2, endScreen.x + 2, endScreen.y + 2, Color(0, 0, 0, 200));
        Render::Line(endScreen.x + 2, endScreen.y - 2, endScreen.x - 2, endScreen.y + 2, Color(0, 0, 0, 200));
    }
}/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

// All misc visuals (Crosshairs etc) go in this class

class CVisuals : public CHack
{
public:
        void Init();
void Draw();
void Move(CUserCmd* pCmd);
private:
        void DrawCrosshair();
void DrawRecoilCrosshair();
void DrawCenterRadar();
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "Hacks.h"

// All misc visuals (Crosshairs etc) go in this class

class CVisuals : public CHack
{
public:
        void Init();
        void Draw();
        void Move(CUserCmd *pCmd);
private:
        void DrawCrosshair();
        void DrawRecoilCrosshair();
        void DrawCenterRadar();
};/*
Syn's AYYWAREFramework 2015
*/

#pragma once

#include "GUI.h"

#include "Interfaces.h"

void CWindow::SetPosition(int x, int y)
{
    m_x = x; m_y = y;
}

void CWindow::SetSize(int w, int h)
{
    m_iWidth = w;
    m_iHeight = h;
}

void CWindow::SetTitle(std::string title)
{
    Title = title;
}

void CWindow::RegisterTab(CTab* Tab)
{
    if (Tabs.size() == 0)
    {
        SelectedTab = Tab;
    }
    Tab->parent = this;
    Tabs.push_back(Tab);
}

RECT CWindow::GetClientArea()
{
    RECT client;
    client.left = m_x + 8;
    client.top = m_y + 1 + 27;
    client.right = m_iWidth - 4 - 12;
    client.bottom = m_iHeight - 2 - 8 - 26;
    return client;
}

RECT CWindow::GetTabArea()
{
    RECT client;
    client.left = m_x + 8;
    client.top = m_y + 1 + 27;
    client.right = m_iWidth - 4 - 12;
    client.bottom = 29;
    return client;
}

void CWindow::Open()
{
    m_bIsOpen = true;
}

void CWindow::Close()
{
    m_bIsOpen = false;
}

void CWindow::Toggle()
{
    m_bIsOpen = !m_bIsOpen;
    if (m_bIsOpen)
        Interfaces::Engine->ClientCmd_Unrestricted("cl_mouseenable 0");
    else
        Interfaces::Engine->ClientCmd_Unrestricted("cl_mouseenable 1");
}

CControl* CWindow::GetFocus()
{
    return FocusedControl;
}

// TABS ---------------------------------------------------------------------------------------------------

void CTab::SetTitle(std::string name)
{
    Title = name;
}

void CTab::RegisterControl(CControl* control)
{
    control->parent = parent;
    Controls.push_back(control);
}