Created
May 10, 2020 23:50
-
-
Save donadigo/e8610a78edef379a8f1e3167959007bd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <cstdint> | |
#include <map> | |
#include <Windows.h> | |
#include <iostream> | |
#include <vector> | |
#define DllExport extern "C" __declspec(dllexport) | |
#pragma pack(1) | |
struct Vec3 { | |
float x; | |
float y; | |
float z; | |
}; | |
#pragma pack(1) | |
struct Iso4 { | |
float xx; | |
float xy; | |
float xz; | |
float yx; | |
float yy; | |
float yz; | |
float zx; | |
float zy; | |
float zz; | |
float tx; | |
float ty; | |
float tz; | |
bool operator<(const Iso4& iso) const | |
{ | |
return std::tie(tx, ty, tz) < std::tie(iso.tx, iso.ty, iso.tz); | |
} | |
}; | |
#pragma pack(1) | |
struct CollItem { | |
Iso4 matrix; | |
void* p; | |
void* blockRef; | |
}; | |
#pragma pack(1) | |
struct PhysItem { | |
void* p; | |
Iso4 matrix; | |
CollItem* collItem; | |
uint64_t unused; | |
}; | |
enum DataType : uint8_t { | |
BLOCK = 0, | |
ISO4 = 1 | |
}; | |
static std::map<void*, CollItem*> blockCacheMap; | |
static std::map<Iso4, CollItem*> itemCacheMap; | |
#if _DEBUG | |
void EnsureConsole() | |
{ | |
static bool consoleAllocated = false; | |
if (!consoleAllocated) { | |
AllocConsole(); | |
FILE* f; | |
freopen_s(&f, "CONOUT$", "w", stdout); | |
consoleAllocated = true; | |
} | |
} | |
#endif | |
PhysItem* GetPhysBuffer(const void* collMgr) | |
{ | |
uint64_t collMgrPtr = (uint64_t)collMgr; | |
uint64_t physZoneBufferPtr = *(uint64_t*)(collMgrPtr + 0xC8) - 0x48; | |
return (PhysItem*)(physZoneBufferPtr); | |
} | |
bool MoveCache(void* data, const uint8_t dataType, const Vec3* position) | |
{ | |
if (dataType == BLOCK) { | |
auto it = blockCacheMap.find(data); | |
if (it != blockCacheMap.end() && it->second->blockRef == data) { | |
auto collItem = it->second; | |
collItem->matrix.tx = position->x; | |
collItem->matrix.ty = position->y; | |
collItem->matrix.tz = position->z; | |
return true; | |
} else { | |
blockCacheMap.erase(data); | |
return false; | |
} | |
} else { | |
Iso4 location = *(Iso4*)data; | |
auto it = itemCacheMap.find(location); | |
if (it != itemCacheMap.end()) { | |
auto collItem = it->second; | |
if (collItem->matrix.tx == location.tx && | |
collItem->matrix.ty == location.ty && | |
collItem->matrix.tz == location.tz) { | |
collItem->matrix.tx = position->x; | |
collItem->matrix.ty = position->y; | |
collItem->matrix.tz = position->z; | |
return true; | |
} | |
} else { | |
itemCacheMap.erase(location); | |
return false; | |
} | |
} | |
return false; | |
} | |
DllExport void ClearPhysCache() | |
{ | |
blockCacheMap.clear(); | |
itemCacheMap.clear(); | |
} | |
bool MoveCorpusPhysBlock( | |
const void* collMgr, | |
const unsigned lastItem, | |
void* block, | |
const Vec3* position) | |
{ | |
if (!collMgr || !block) { | |
return false; | |
} | |
#if _DEBUG | |
EnsureConsole(); | |
#endif | |
PhysItem* buffer = GetPhysBuffer(collMgr); | |
for (int i = lastItem; i >= 0; i--) { | |
PhysItem& item = buffer[i]; | |
if (!item.collItem || (uint64_t)item.collItem->blockRef != (uint64_t)block) { | |
continue; | |
} | |
item.collItem->matrix.tx = position->x; | |
item.collItem->matrix.ty = position->y; | |
item.collItem->matrix.tz = position->z; | |
blockCacheMap[block] = item.collItem; | |
return true; | |
} | |
return false; | |
} | |
bool MoveCorpusPhysByPosition( | |
const void* collMgr, | |
const unsigned lastItem, | |
const Iso4* location, | |
const Vec3* position) | |
{ | |
if (!collMgr) { | |
return false; | |
} | |
#if _DEBUG | |
EnsureConsole(); | |
#endif | |
PhysItem* buffer = GetPhysBuffer(collMgr); | |
for (int i = lastItem; i >= 0; i--) { | |
PhysItem& item = buffer[i]; | |
if (!item.collItem || | |
item.collItem->matrix.tx != location->tx || | |
item.collItem->matrix.ty != location->ty || | |
item.collItem->matrix.tz != location->tz) { | |
continue; | |
} | |
item.collItem->matrix.tx = position->x; | |
item.collItem->matrix.ty = position->y; | |
item.collItem->matrix.tz = position->z; | |
Iso4 newLocation = *location; | |
newLocation.tx = position->x; | |
newLocation.ty = position->y; | |
newLocation.tz = position->z; | |
itemCacheMap[newLocation] = item.collItem; | |
return true; | |
} | |
return false; | |
} | |
DllExport bool MoveCorpusPhys( | |
const void* collMgr, | |
const unsigned lastItem, | |
const uint8_t dataType, | |
void* data, | |
const Vec3* position) | |
{ | |
if (MoveCache(data, dataType, position)) { | |
return true; | |
} | |
if (dataType == BLOCK) { | |
return MoveCorpusPhysBlock(collMgr, lastItem, data, position); | |
} else { | |
return MoveCorpusPhysByPosition(collMgr, lastItem, (const Iso4*)data, position); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment