After a few hours of checking how the hell it works it wasnt that hard
Its nice how they did pretty much cancel out the use of out of game bots/radars as the game data changes location every frame. Though I can think of several idea's how (with a code-patch) you could cancel out this method.
Anyways lets get down to technical business
First the entity position list hasnt changed much itself except for 1 major difference, it doesnt contain a pointer itself anymore but rather a new ID. Unless this ID is -1, then it does actually contain a pointer.
The position list structure is as follows:
(note pseudo code, havent checked it syntax)
Code:
struct
{
int unk_0;
node **nodes;
int size;
} position_list;
struct
{
int guid;
int encID;
entity *ptr;
node *next;
} node;
Now treat each node in position_list->nodes as a linked list (using the next node) as long as next != 0. When encID == -1 then the entity ptr will be set, otherwise you'll have to look it up.
To get the entity pointer using the encID you do the following:
(note pseudo code, its kind of C# unsafe-syntax)
Code:
int enc1 = *(int*)(0xB9BD2C);
int enc2 = *(int*)(0xD0367C);
int enc3 = 0xB9C06C;
entity *ent = null;
if (encID != -1)
{
endID *= enc1;
endID += *(int*)(enc3 + enc2 * 4);
ent = (entity *)endID;
}
else
ent = node.entity;
From what I gather 0xB9BD2C always contains 0x3D8 and 0xD0367C changes each frame (number between 0 and 4) and enc3 is an array of 5 base-pointers.
So in short, 0x3D8 is the entity position structure size, 0xD0367C says which array to use and 0xB9C06C is a list of 5 pointers to the array of entity structures. And encID is the index within this array.
Good luck using this out of game, using this info in the game-thread itself isnt hard as the array-selector doesnt change.