Skip to content

Instantly share code, notes, and snippets.

@donadigo
Created May 10, 2020 23:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donadigo/e8610a78edef379a8f1e3167959007bd to your computer and use it in GitHub Desktop.
Save donadigo/e8610a78edef379a8f1e3167959007bd to your computer and use it in GitHub Desktop.
#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