#pragma once #include "headers.h" #include "patcher.h" #include "defines.h" #include "accessors.h" BOOL(WINAPI* ____GetAsyncSpecialKeyState)(int Key); void (WINAPI* ____ApplySelectedUnitMenu)(); DWORD (WINAPI* ____WaitForSingleObject)(HANDLE hHandle, DWORD dwMilliseconds); HANDLE(WINAPI* ____CreateSemaphoreA)(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName); BOOL(WINAPI* ____ReleaseSemaphore)(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount); HMODULE(WINAPI* ____LoadLibraryA)(LPCSTR Path); FARPROC(WINAPI* ____GetProcAddress)(HMODULE Module, LPCSTR Name); HMODULE kernel32module; //char Buffer_Key; HANDLE NextIdleConstructionSemaphore; HANDLE UnitsWithWeaponsSemaphore; HANDLE SameUnitTypeSemaphore; void ____DeselectAllUnits() { // DWORD vars are pointers DWORD TAMainStructPtr = *(DWORD*)(0x00511DE8); char LocalHumanId = *(char*)(((DWORD)TAMainStructPtr + 0x2A42)); DWORD PlayerUnitsStart = *(DWORD*)(((DWORD)(((DWORD)TAMainStructPtr + 0x1B63 + (0x14B * LocalHumanId))) + 0x67)); DWORD PlayerUnitsEnd = *(DWORD*)(((DWORD)(((DWORD)TAMainStructPtr + 0x1B63 + (0x14B * LocalHumanId))) + 0x6B)); DWORD CurrentUnit = PlayerUnitsStart; while (CurrentUnit <= PlayerUnitsEnd) { if (*(short*)(CurrentUnit + 0xA6)) { if (((*(DWORD*)(CurrentUnit + 0x110)) & 0x20) != 0) { if (((*(float*)(CurrentUnit + 0x104)) == 0.f)) { (*(DWORD*)(CurrentUnit + 0x110)) &= 0xFFFFFFEF; } } } CurrentUnit += 0x118; } *(short*)((DWORD)TAMainStructPtr + 0x37E9C) = 0; } void ____UpdateSelectedUnitEffect() { DWORD TAMainStructPtr = *(DWORD*)(0x00511DE8); *(BYTE*)((DWORD)TAMainStructPtr + 0x37EBE) |= 0x10; // redundant? *(short*)((DWORD)TAMainStructPtr + 0x37E9C) = 0; } void ____UpdateSelectedtUnitMenu() { DWORD TAMainStructPtr = *(DWORD*)(0x00511DE8); BYTE PrepareOrderType_Save = *(BYTE*)(TAMainStructPtr+0x2CC3); ____ApplySelectedUnitMenu(); *(BYTE*)(TAMainStructPtr+0x2CC3) = PrepareOrderType_Save; } void ____ScrollToCenter(short xPos, short zPos) { int* TAMemPtr; int ScreenWidth; int ScreenHeight; int MaxScrollX; int MaxScrollZ; int* xPtr; int* zPtr; __asm { mov eax, ds: [0x511de8] mov TAMemPtr, eax lea eax, [eax + 0x14327] mov xPtr, eax mov eax, ds: [0x511de8] lea eax, [eax + 0x1432b] mov zPtr, eax mov edx, ds : [0x51fbd0] mov eax, [edx + 0xd4] mov ScreenWidth, eax mov eax, [edx + 0xd8] mov ScreenHeight, eax } xPos -= (ScreenWidth - 128) / 2; zPos -= (ScreenHeight - 64) / 2; if (xPos < 0) { xPos = 0; } if (zPos < 0) { zPos = 0; } MaxScrollX = ____GetMaxScrollX(); MaxScrollZ = ____GetMaxScrollZ(); if (xPos > MaxScrollX) { xPos = MaxScrollX; } if (zPos > MaxScrollZ) { zPos = MaxScrollZ; } *xPtr = xPos; *zPtr = zPos; } void ____NextIdleConstruction() { DWORD WaitCheck = ____WaitForSingleObject(NextIdleConstructionSemaphore, INFINITE); if (WaitCheck == WAIT_FAILED) return; if (WaitCheck == WAIT_TIMEOUT) { ____ReleaseSemaphore(NextIdleConstructionSemaphore, 1, NULL); return; } DWORD TAMainStructPtr = *(DWORD*)(0x00511DE8); char LocalHumanId = *(char*)(((DWORD)TAMainStructPtr + 0x2A42)); WORD LocalPlayerMaxUnitNumber = *(WORD*)(((DWORD)(((DWORD)TAMainStructPtr + 0x1B63 + (0x14B * LocalHumanId))) + 0x144)); DWORD UnitPtr; WORD Iterate = 0; BYTE IsDead; short XPos; short YPos; DWORD IsUnit; BYTE UnitSelected; DWORD UnitOrderPtr; DWORD IsBuilder; DWORD IsMobile; BYTE UnitState; static WORD LastUnitNumber = 0; if (LocalPlayerMaxUnitNumber < LastUnitNumber) LastUnitNumber = 0; Iterate = LastUnitNumber; while (Iterate <= LocalPlayerMaxUnitNumber) { UnitPtr = (*(DWORD*)(((DWORD)(((DWORD)TAMainStructPtr + 0x1B63 + (0x14B * LocalHumanId))) + 0x67))) + (0x118 * Iterate); IsDead = *(char*)(UnitPtr + 0xF7); XPos = *(short*)(UnitPtr + 0x6A + 2); YPos = *(short*)(UnitPtr + 0x6A + 10); IsUnit = *(DWORD*)(UnitPtr); UnitSelected = *(char*)(UnitPtr + 0x114); UnitOrderPtr = *(DWORD*)(UnitPtr + 0x5C); IsBuilder = *(DWORD*)(*(DWORD*)(UnitPtr + 0x92) + 0x241) & 0x40; IsMobile = *(BYTE*)(*(DWORD*)(UnitPtr + 0x92) + 0x22F); if (IsDead != 0 && IsDead != 1 && IsUnit) { if (IsBuilder != 0 && IsMobile != 0) { UnitState = *(char*)(*(DWORD*)(UnitPtr + 0x5C) + 4); if (UnitOrderPtr == NULL || UnitState == 0x29 || UnitState == 0x40) { if (LastUnitNumber < Iterate) { LastUnitNumber = Iterate; *(char*)(UnitPtr + 0x110) |= 0x10; ____ScrollToCenter(XPos, YPos); // scroll to unit //*(DWORD*)(TAMainStructPtr + 0x142f3) = Iterate; // unit focus like Ctrl+C ____ReleaseSemaphore(NextIdleConstructionSemaphore, 1, NULL); return; } } } } Iterate++; if (LocalPlayerMaxUnitNumber < Iterate) { if (LastUnitNumber == 0) { ____ReleaseSemaphore(NextIdleConstructionSemaphore, 1, NULL); return; } break; } } LastUnitNumber = 0; ____ReleaseSemaphore(NextIdleConstructionSemaphore, 1, NULL); ____NextIdleConstruction(); return; } void ____SelectUnitsWithWeaponsOnScreen() { TA_WaitForSingleObject(UnitsWithWeaponsSemaphore, INFINITE); int NumberHotUnits; void* UnitsArrayStart; short* HotUnitArrayPtr; void* CurrentUnitPtr; int Counter; unsigned int* UnitSelected; float* NanoFrame; void* PlayerPtr1; char LocalPlayerId; char PlayerArrayIndex; unsigned int UnitTypeMask0; unsigned int UnitTypeMask1; char* YardMap; void* NoWeaponPtr; void* Weapon1; void* Weapon2; void* Weapon3; unsigned int Weapon1Mask; unsigned int Weapon2Mask; unsigned int Weapon3Mask; Counter = 0; __asm { mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x1439B] mov NoWeaponPtr, eax } __asm { mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x14367] mov NumberHotUnits, eax } while (Counter < NumberHotUnits) { __asm { mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x14357] mov UnitsArrayStart, eax mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x1435F] mov HotUnitArrayPtr, eax // Set Current mov eax, Counter mov edx, 2 mul edx mov ecx, HotUnitArrayPtr add ecx, eax xor eax, eax mov ax, [ecx] // EDX = Index mov edx, 0x118 mul edx mov edx, UnitsArrayStart add eax, edx // EAX = UnitPtr mov CurrentUnitPtr, eax // Now we can start the normal checks mov eax, CurrentUnitPtr lea eax, [eax + 0x110] mov UnitSelected, eax mov eax, CurrentUnitPtr lea eax, [eax + 0x104] mov NanoFrame, eax mov eax, CurrentUnitPtr mov eax, [eax + 0xEC] mov PlayerPtr1, eax } if ((*UnitSelected & 0x20) != 0) { if (*NanoFrame == 0.0F) { if (PlayerPtr1 != NULL) { __asm { mov eax, dword ptr ds : [0x511DE8] mov al, [eax + 0x2A42] mov LocalPlayerId, al mov eax, CurrentUnitPtr mov eax, [eax + 0xEC] mov al, [eax + 0x146] mov PlayerArrayIndex, al } if (LocalPlayerId == PlayerArrayIndex) { __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x241] mov UnitTypeMask0, eax } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x245] mov UnitTypeMask1, eax } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x14E] mov YardMap, eax } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x1EE] mov Weapon1, eax mov eax, [eax + 0x111] mov Weapon1Mask, eax } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x1F2] mov Weapon2, eax mov eax, [eax + 0x111] mov Weapon2Mask, eax } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0x92] mov eax, [eax + 0x1F6] mov Weapon3, eax mov eax, [eax + 0x111] mov Weapon3Mask, eax } if ((NoWeaponPtr != Weapon1 && Weapon1 != NULL && (Weapon1Mask & 0x1000000) == 0) || (NoWeaponPtr != Weapon2 && Weapon2 != NULL && (Weapon2Mask & 0x1000000) == 0) || (NoWeaponPtr != Weapon3 && Weapon3 != NULL && (Weapon3Mask & 0x1000000) == 0)) { if (((UnitTypeMask1 & 0x20000) == 0) || ((UnitTypeMask0 & 0x4000) == 0)) { if ((UnitTypeMask0 & 0x40) == 0) { if (YardMap == NULL) { if ((UnitTypeMask0 & 0x800) != 0x800) { *UnitSelected |= 0x10; } } } } } } } } } Counter++; } ____ReleaseSemaphore(UnitsWithWeaponsSemaphore, 1, NULL); } void ____SelectAllOfDoubleClickedUnitOnScreen() { void* UnitsArrayStart; void* UnitsArrayEnd; void* PlayerUnitsArrayStart; void* PlayerUnitsArrayEnd; void* PlayersArray; void* CurrentUnitPtr; int NumberHotUnits; char LocalHumanPlayerIndex; char LocalHumanPlayerId; short* HotUnitsPtr; int Counter; int MouseOverUnit; short UnitInfoId; unsigned int* UnitSelected; float* NanoFrame; void* PlayerPtr1; short CurrentUnitInfoId; char CurrentUnitPlayerArrayIndex; TA_WaitForSingleObject(SameUnitTypeSemaphore, INFINITE); Counter = 0; __asm { mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x14357] mov UnitsArrayStart, eax mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x1435B] mov UnitsArrayEnd, eax mov eax, dword ptr ds : [0x511DE8] add eax, 0x1B63 mov PlayersArray, eax } LocalHumanPlayerIndex = ____GetLocalPlayerArrayIndex(); __asm { xor eax, eax mov al, LocalHumanPlayerId mov edx, 0x14B mul edx mov edx, PlayersArray add eax, edx add eax, 0x67 // Player Units Array mov PlayerUnitsArrayStart, eax add eax, 4 mov PlayerUnitsArrayEnd, eax } __asm { mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x14367] mov NumberHotUnits, eax mov eax, dword ptr ds : [0x511DE8] mov eax, [eax + 0x1435F] mov HotUnitsPtr, eax } MouseOverUnit = ____GetMouseOverUnit(); __asm { mov eax, MouseOverUnit mov edx, 0x118 mul edx add eax, UnitsArrayStart mov ax, [eax + 0xA6] mov UnitInfoId, ax } while (Counter < NumberHotUnits) { __asm { mov eax, 2 mov edx, Counter mul edx add eax, HotUnitsPtr xor edx, edx mov dx, [eax] // EDX = Unit Index mov eax, 0x118 mul edx // EAX = Offset From Beginning add eax, UnitsArrayStart mov CurrentUnitPtr, eax } __asm { mov eax, CurrentUnitPtr lea eax, [eax + 0x110] mov UnitSelected, eax mov eax, CurrentUnitPtr lea eax, [eax + 0x104] mov NanoFrame, eax mov eax, CurrentUnitPtr mov eax, [eax + 0xEC] mov PlayerPtr1, eax mov eax, CurrentUnitPtr mov ax, [eax + 0xA6] mov CurrentUnitInfoId, ax } if ((*UnitSelected & 0x20) != 0) { if (*NanoFrame == 0.0F) { if (CurrentUnitInfoId == UnitInfoId) { if (PlayerPtr1 != NULL) { __asm { mov eax, dword ptr ds : [0x511DE8] mov al, [eax + 0x2A42] mov LocalHumanPlayerId, al } __asm { mov eax, CurrentUnitPtr mov eax, [eax + 0xEC] mov al, [eax + 0x146] mov CurrentUnitPlayerArrayIndex, al } if (LocalHumanPlayerId == CurrentUnitPlayerArrayIndex) { *UnitSelected |= 0x10; } } } } } Counter++; } ____ReleaseSemaphore(SameUnitTypeSemaphore, 1, NULL); } void HotKeys() { ____LoadLibraryA = (HMODULE(WINAPI*)(LPCSTR))0x0049F77C; ____GetProcAddress = (FARPROC(WINAPI*)(HMODULE Module, LPCSTR Name))0x0049F776; kernel32module = ____LoadLibraryA("kernel32.dll"); ____ReleaseSemaphore = (BOOL(WINAPI*)(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount))____GetProcAddress(kernel32module, "ReleaseSemaphore"); ____GetAsyncSpecialKeyState = (BOOL(WINAPI*)(int Key))0x004C1B80; ____ApplySelectedUnitMenu = (void (WINAPI*)())0x00495860; ____WaitForSingleObject = (DWORD(WINAPI*)(HANDLE hHandle, DWORD dwMilliseconds))0x0049F770; ____CreateSemaphoreA = (HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName))0x0049F7B2; NextIdleConstructionSemaphore = ____CreateSemaphoreA(NULL, 1, 1, NULL); UnitsWithWeaponsSemaphore = ____CreateSemaphoreA(NULL, 1, 1, NULL); SameUnitTypeSemaphore = ____CreateSemaphoreA(NULL, 1, 1, NULL); }