First the classes:
PHP Code
Code:
class BackpackSlot
{
public:
DWORD dwSlotID;
DWORD __PAD0001;
DWORD dwItemID; // 0x0008
int dwAmount; // 0x000C
DWORD __PAD0002[2];
}; // size: 0x0018
class CharacterLoadout
{
public:
DWORD __PAD0001[37];
bool globalInvAccess; // 0x0094
char __PAD0002[75];
signed int maxBackpackSlots; // 0x00E0
DWORD __PAD0003;
BackpackSlot backpack[32]; // 0x00E8
DWORD __PAD0004[256];
}; // size: 0x07E8
class UserProfile
{
public:
CharacterLoadout loadout[5];
DWORD activeCharacters; // 0x2788
DWORD usedSlotsInGI; // 0x278C
BackpackSlot globalInventory[2048]; // 0x2790
}; // size: 0xE790
Now the engine function that allows us to transfer as many items (of the same type) as we want to the current character's loadout at one time.
The first parameter specifies the desired target slot in the backpack. In most cases we don't care and simply can pass "-1" as the first parameter. This will result in the item occupying the first free slot (>7).
The second parameter, the slot ID, is a unique ID pointing into the global inventory that is organized as a simple array of backpack slots. More on the slot ID will follow after the engine function:
PHP Code:
Code:
signed int Engine::moveItemFromGlobalInventoryToBackpack(signed int toBackpackSlotIndex, DWORD slotID, int amount)
{
static DWORD dwCall = (DWORD)GetModuleHandle(NULL) + 0xD5EC0;
_asm
{
mov eax, amount
mov ecx, 0
mov edx, slotID
push eax
push ecx
mov ecx, toBackpackSlotIndex
push edx
call dwCall;
}
}
We now need a function to retrieve the slot ID of the item we want to move from global inventory.
The function will go through all slots in GI and will stop as soon as the first matching slot holding our desired item ID has been found:
PHP Code:
Code:
DWORD Engine::getSlotIDinGlobalInventoryForItemID(DWORD itemID)
{
// 05 ? ? ? ? 8B F0 83 3E 00 89
DWORD dwLoadoutAddress = FindPattern((DWORD)GetModuleHandle(NULL), (BYTE*)"\x05\x00\x00\x00\x00\x8B\xF0\x83\x3E\x00\x89", (CHAR*)"x????xxxxxx");
if (dwLoadoutAddress == NULL) return 0;
dwLoadoutAddress = *(DWORD*)(dwLoadoutAddress + 1);
UserProfile* profile = (UserProfile *)dwLoadoutAddress;
if (profile == NULL) return 0;
DWORD result = 0;
for (DWORD i = 0; i < profile->usedSlotsInGI; i++)
{
if (profile->globalInventory[i].dwItemID == itemID)
{
result = profile->globalInventory[i].dwSlotID;
break;
}
}
return result;
}
Finally, a simple example how to use it.
The function takes an item ID and the amount, retrieves the slot ID in GI and uses the engine function to transfer the items. In addition, you can of course use the info I gave you in the other thread to check, whether the currently selected character has enough free slots or whether he is in a safe zone... But who cares
To refresh the view, you again have to move any item or change your backpack...
PHP Code:
Code:
void Engine::TransferItemFromGlobalInventoryToBackpackLoadout(DWORD itemID, int amount)
{
// since we have to be disconnected, check for that
CGame *pGame = this->GetClientGame();
if (!pGame) return;
if (pGame->connected) return;
// search GI for the given item ID and retrieve a unique slot ID for our engine function
DWORD slotID = getSlotIDinGlobalInventoryForItemID( itemID );
if (slotID)
{
this->Log("\nMoving item %d from GI to backpack (%dx)", itemID, amount);
if (signed int e = moveItemFromGlobalInventoryToBackpack( -1, slotID, amount ))
this->Log(" -> failed (error code %d)", e);
else
this->Log(" -> done");
}
}
For a complete list of all item IDs see the itemsDB.xml in your (extracted) War Z directory under \data\weapons. You can make enums or whatever for the items you transfer the most. As a bonus here my 5 most favourite items
PHP Code:
Code:
enum MedsType
{
MEDS_Bandages = 0x18B8D,
MEDS_Painkillers = 0x18BB4,
MEDS_Antibiotics = 0x18B88,
MEDS_BandagesDX = 0x18B8E,
MEDS_MedKit = 0x18BB8
};
Have Fun
Credit: tester6663