Originally Posted by
Master674
GetUnitById basically takes the ID and does modulo 4091 or something like that.
Then uses that as an index in a unit array and compares if the IDs match. If they don't it checks the next place in the array. That way you can almost gurantee
O(1).
Code:
uint32 currIndex = unitId;
CUnit *currUnit = nullptr;
do {
currUnit = sGameMgr->m_unitArray[currIndex++ % 4091];
if (!currUnit)
return nullptr; // unit not present
} while (currUnit->unitId != unitId);
Something like that.
Ya I already reversed almost all of it. I think it is actually a hash table with linked lists at each bucket. I guess I could use this, but it would be much more efficient to find the start of the linked list.
Code:
signed int __cdecl GameLib_GetUnitById(int luastate)
{
int *UnitPointer; // eax@1
signed int result; // eax@3
int one; // [sp+8h] [bp-4h]@1
one = luaL_CheckNumber(luastate, 1);
UnitPointer = (int *)FindHash(manager + 23892, (int)&one);
if ( UnitPointer && *UnitPointer )
{
result = Apollo::GetUnit(luastate, *UnitPointer);
}
else
{
result = 1;
*(_DWORD *)(*(_DWORD *)(luastate + 8) + 8) = 0;
*(_DWORD *)(luastate + 8) += 16;
}
return result;
}
Code:
struct HashTable
{
int unknown1; // +0 is not a vtable pointer
int bucketSize; // +4
HashEntry* slots; // +8
int Hasher?(int slot); // +12
bool PointsToSameValue(void* a, void* b); // +16
}
struct HashEntry
{
int unknown1; // +0
HashEntry* next; // +4
int id?; // +8
void* value; // +12
}
Code:
int __thiscall FindHash(int hashtable, int id)
{
int hashtable2; // ebx@1
unsigned int hashed_index; // edi@1
int entry; // esi@1
int result; // eax@5
hashtable2 = hashtable;
hashed_index = (*(int (__cdecl **)(int))(hashtable + 12))(id);
entry = *(_DWORD *)(*(_DWORD *)(hashtable2 + 8) + 4 * hashed_index % *(_DWORD *)(hashtable2 + 4));
if ( entry )
{
while ( hashed_index != *(_DWORD *)entry || !(*(int (__cdecl **)(int, int))(hashtable2 + 16))(id, entry + 8) )// compare arg1 and arg2 dereferenced
{
entry = *(_DWORD *)(entry + 4);
if ( !entry )
goto LABEL_5;
}
result = entry + 12;
}
else
{
LABEL_5:
result = 0;
}
return result;
}