XModel stuff
This commit is contained in:
parent
19a4c62617
commit
9cd0624f88
@ -52,7 +52,7 @@ namespace Components
|
||||
{
|
||||
for (auto component : Loader::Components)
|
||||
{
|
||||
Logger::Print("Unregistering component: %s", component->GetName());
|
||||
Logger::Print("Unregistering component: %s\n", component->GetName());
|
||||
delete component;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ namespace Components
|
||||
{
|
||||
if (component)
|
||||
{
|
||||
Logger::Print("Component registered: %s", component->GetName());
|
||||
Logger::Print("Component registered: %s\n", component->GetName());
|
||||
Loader::Components.push_back(component);
|
||||
}
|
||||
}
|
||||
|
@ -40,30 +40,47 @@ namespace Assets
|
||||
image->dataLen1 = iwiHeader->fileSizeForPicmip[0] - 32;
|
||||
image->dataLen2 = iwiHeader->fileSizeForPicmip[0] - 32;
|
||||
|
||||
// TODO: Check tag
|
||||
image->texture->dimensions[0] = iwiHeader->dimensions[0]; // Width
|
||||
image->texture->dimensions[1] = iwiHeader->dimensions[1]; // Height
|
||||
image->texture->dimensions[2] = iwiHeader->dimensions[2]; // Depth
|
||||
image->texture->flags = 0;//iwiHeader->flags;
|
||||
if (std::memcmp(iwiHeader->tag, "IWi", 3))
|
||||
{
|
||||
Components::Logger::Error("Image is not a valid IWi!");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(image->texture->dimensions, iwiHeader->dimensions, 6);
|
||||
image->texture->flags = 0;
|
||||
image->texture->mipLevels = 0;
|
||||
|
||||
switch (iwiHeader->format)
|
||||
{
|
||||
case Game::IWI_COMPRESSION::IWI_ARGB:
|
||||
image->texture->format = 21;
|
||||
break;
|
||||
case Game::IWI_COMPRESSION::IWI_RGB8:
|
||||
image->texture->format = 20;
|
||||
break;
|
||||
case Game::IWI_COMPRESSION::IWI_DXT1:
|
||||
image->texture->format = 0x31545844;
|
||||
break;
|
||||
case Game::IWI_COMPRESSION::IWI_DXT3:
|
||||
image->texture->format = 0x33545844;
|
||||
break;
|
||||
case Game::IWI_COMPRESSION::IWI_DXT5:
|
||||
image->texture->format = 0x35545844;
|
||||
break;
|
||||
case Game::IWI_COMPRESSION::IWI_ARGB:
|
||||
{
|
||||
image->texture->format = 21;
|
||||
break;
|
||||
}
|
||||
|
||||
case Game::IWI_COMPRESSION::IWI_RGB8:
|
||||
{
|
||||
image->texture->format = 20;
|
||||
break;
|
||||
}
|
||||
|
||||
case Game::IWI_COMPRESSION::IWI_DXT1:
|
||||
{
|
||||
image->texture->format = 0x31545844;
|
||||
break;
|
||||
}
|
||||
|
||||
case Game::IWI_COMPRESSION::IWI_DXT3:
|
||||
{
|
||||
image->texture->format = 0x33545844;
|
||||
break;
|
||||
}
|
||||
|
||||
case Game::IWI_COMPRESSION::IWI_DXT5:
|
||||
{
|
||||
image->texture->format = 0x35545844;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
header->image = image;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IGfxImage : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_IMAGE; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class ILocalizedEntry : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_LOCALIZE; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IMaterial : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_MATERIAL; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IMaterialPixelShader : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_PIXELSHADER; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -105,17 +105,12 @@ namespace Assets
|
||||
}
|
||||
}
|
||||
|
||||
// We absolutely have to write something here!
|
||||
if (technique->name)
|
||||
{
|
||||
buffer->SaveString(technique->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer->SaveString("");
|
||||
destTechnique->name = reinterpret_cast<char*>(-1);
|
||||
}
|
||||
|
||||
destTechnique->name = reinterpret_cast<char*>(-1);
|
||||
dest->techniques[i] = reinterpret_cast<Game::MaterialTechnique*>(-1);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IMaterialTechniqueSet : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_TECHSET; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IMaterialVertexDeclaration : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_VERTEXDECL; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IMaterialVertexShader : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_VERTEXSHADER; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IPhysCollmap : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IPhysPreset : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_PHYSPRESET; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IRawFile : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_RAWFILE; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -14,11 +14,39 @@ namespace Assets
|
||||
}
|
||||
}
|
||||
|
||||
//asset->numBones = 0;
|
||||
//asset->numRootBones = 0;
|
||||
//asset->boneNames = 0;
|
||||
//asset->parentList = 0;
|
||||
//asset->tagAngles = 0;
|
||||
//asset->tagPositions = 0;
|
||||
//asset->animMatrix = 0;
|
||||
//asset->colSurf = 0;
|
||||
//asset->partClassification = 0;
|
||||
|
||||
if (asset->materials)
|
||||
{
|
||||
//asset->materials = 0;
|
||||
//asset->numSurfaces = 0;
|
||||
|
||||
for (char i = 0; i < asset->numSurfaces; ++i)
|
||||
{
|
||||
if (asset->materials[i])
|
||||
{
|
||||
//Components::Logger::Print("%s\n", asset->materials[i]->name);
|
||||
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->materials[i]->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
if (asset->lods[i].surfaces)
|
||||
{
|
||||
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name);
|
||||
// We're not supposed to include xmodelsurfs as standalone asset
|
||||
//builder->LoadAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name);
|
||||
|
||||
IXModelSurfs().Mark({ asset->lods[i].surfaces }, builder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +55,7 @@ namespace Assets
|
||||
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name);
|
||||
}
|
||||
|
||||
if (asset->physPreset)
|
||||
if (asset->physCollmap)
|
||||
{
|
||||
builder->LoadAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap->name);
|
||||
}
|
||||
@ -122,7 +150,7 @@ namespace Assets
|
||||
dest->materials = reinterpret_cast<Game::Material**>(-1);
|
||||
}
|
||||
|
||||
// Save_XModelLodInfoArray()
|
||||
// Save_XModelLodInfoArray
|
||||
{
|
||||
Assert_Size(Game::XModelLodInfo, 44);
|
||||
|
||||
@ -130,7 +158,11 @@ namespace Assets
|
||||
{
|
||||
if (asset->lods[i].surfaces)
|
||||
{
|
||||
dest->lods[i].surfaces = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name).surfaces;
|
||||
// Requiring this asset is not possible, as it has to be loaded after the model
|
||||
//dest->lods[i].surfaces = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_XMODELSURFS, asset->lods[i].surfaces->name).surfaces;
|
||||
|
||||
IXModelSurfs().Save({ asset->lods[i].surfaces }, builder);
|
||||
dest->lods[i].surfaces = reinterpret_cast<Game::XModelSurfs*>(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,7 +175,7 @@ namespace Assets
|
||||
buffer->Align(Utils::Stream::ALIGN_4);
|
||||
|
||||
Game::XModelCollSurf* destColSurfs = buffer->Dest<Game::XModelCollSurf>();
|
||||
buffer->Save(asset->colSurf, asset->numColSurfs);
|
||||
buffer->SaveArray(asset->colSurf, asset->numColSurfs);
|
||||
|
||||
for (int i = 0; i < asset->numColSurfs; ++i)
|
||||
{
|
||||
@ -174,9 +206,9 @@ namespace Assets
|
||||
dest->physPreset = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->physPreset->name).physPreset;
|
||||
}
|
||||
|
||||
if (asset->physPreset)
|
||||
if (asset->physCollmap)
|
||||
{
|
||||
dest->physPreset = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap->name).physPreset;
|
||||
dest->physCollmap = builder->RequireAsset(Game::XAssetType::ASSET_TYPE_PHYS_COLLMAP, asset->physCollmap->name).physCollmap;
|
||||
}
|
||||
|
||||
buffer->PopBlock();
|
||||
|
@ -2,6 +2,7 @@ namespace Assets
|
||||
{
|
||||
class IXModel : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_XMODEL; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
@ -2,6 +2,93 @@
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
void IXModelSurfs::Save_XSurfaceCollisionTree(Game::XSurfaceCollisionTree* entry, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Assert_Size(Game::XSurfaceCollisionTree, 40);
|
||||
|
||||
Utils::Stream* buffer = builder->GetBuffer();
|
||||
|
||||
Game::XSurfaceCollisionTree* destEntry = buffer->Dest<Game::XSurfaceCollisionTree>();
|
||||
buffer->Save(entry, sizeof(Game::XSurfaceCollisionTree));
|
||||
|
||||
if (entry->node)
|
||||
{
|
||||
buffer->Align(Utils::Stream::ALIGN_16);
|
||||
buffer->Save(entry->node, 16, entry->numNode);
|
||||
destEntry->node = reinterpret_cast<char*>(-1);
|
||||
}
|
||||
|
||||
if (entry->leaf)
|
||||
{
|
||||
buffer->Align(Utils::Stream::ALIGN_2);
|
||||
buffer->SaveArray(entry->leaf, entry->numLeaf);
|
||||
destEntry->leaf = reinterpret_cast<short*>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void IXModelSurfs::Save_XSurface(Game::XSurface* surf, Game::XSurface* destSurf, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Utils::Stream* buffer = builder->GetBuffer();
|
||||
|
||||
if (surf->blendInfo)
|
||||
{
|
||||
buffer->Align(Utils::Stream::ALIGN_2);
|
||||
|
||||
buffer->Save(surf->blendInfo, sizeof(short), surf->blendNum1 + (surf->blendNum2 * 3) + (surf->blendNum3 * 5) + (surf->blendNum4 * 7));
|
||||
destSurf->blendInfo = reinterpret_cast<char*>(-1);
|
||||
}
|
||||
|
||||
// Access vertex block
|
||||
buffer->PushBlock(Game::XFILE_BLOCK_VERTEX);
|
||||
if (surf->vertexBuffer)
|
||||
{
|
||||
Assert_Size(Game::GfxPackedVertex, 32);
|
||||
|
||||
buffer->Align(Utils::Stream::ALIGN_16);
|
||||
buffer->SaveArray(surf->vertexBuffer, surf->numVertices);
|
||||
destSurf->vertexBuffer = reinterpret_cast<Game::GfxPackedVertex*>(-1);
|
||||
}
|
||||
buffer->PopBlock();
|
||||
|
||||
// Save_XRigidVertListArray
|
||||
if (surf->ct)
|
||||
{
|
||||
Assert_Size(Game::XRigidVertList, 12);
|
||||
|
||||
buffer->Align(Utils::Stream::ALIGN_4);
|
||||
|
||||
Game::XRigidVertList* destCt = buffer->Dest<Game::XRigidVertList>();
|
||||
buffer->SaveArray(surf->ct, surf->numCT);
|
||||
|
||||
for (int i = 0; i < surf->numCT; ++i)
|
||||
{
|
||||
Game::XRigidVertList* destRigidVertList = &destCt[i];
|
||||
Game::XRigidVertList* rigidVertList = &surf->ct[i];
|
||||
|
||||
if (rigidVertList->entry)
|
||||
{
|
||||
buffer->Align(Utils::Stream::ALIGN_4);
|
||||
IXModelSurfs::Save_XSurfaceCollisionTree(rigidVertList->entry, builder);
|
||||
destRigidVertList->entry = reinterpret_cast<Game::XSurfaceCollisionTree*>(-1);
|
||||
}
|
||||
}
|
||||
|
||||
destSurf->ct = reinterpret_cast<Game::XRigidVertList*>(-1);
|
||||
}
|
||||
|
||||
// Access index block
|
||||
buffer->PushBlock(Game::XFILE_BLOCK_INDEX);
|
||||
if (surf->indexBuffer)
|
||||
{
|
||||
Assert_Size(Game::Face, 6);
|
||||
|
||||
buffer->Align(Utils::Stream::ALIGN_16);
|
||||
buffer->SaveArray(surf->indexBuffer, surf->numPrimitives);
|
||||
destSurf->indexBuffer = reinterpret_cast<Game::Face*>(-1);
|
||||
}
|
||||
buffer->PopBlock();
|
||||
}
|
||||
|
||||
void IXModelSurfs::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Assert_Size(Game::XModelSurfs, 36);
|
||||
@ -9,7 +96,7 @@ namespace Assets
|
||||
Utils::Stream* buffer = builder->GetBuffer();
|
||||
Game::XModelSurfs* asset = header.surfaces;
|
||||
Game::XModelSurfs* dest = buffer->Dest<Game::XModelSurfs>();
|
||||
buffer->Save(asset, sizeof(Game::PhysPreset));
|
||||
buffer->Save(asset, sizeof(Game::XModelSurfs));
|
||||
|
||||
buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
@ -24,11 +111,13 @@ namespace Assets
|
||||
Assert_Size(Game::XSurface, 64);
|
||||
|
||||
buffer->Align(Utils::Stream::ALIGN_4);
|
||||
|
||||
Game::XSurface* destSurfaces = buffer->Dest<Game::XSurface>();
|
||||
buffer->SaveArray(asset->surfaces, asset->numSurfaces);
|
||||
|
||||
for (int i = 0; i < asset->numSurfaces; ++i)
|
||||
{
|
||||
|
||||
IXModelSurfs::Save_XSurface(&asset->surfaces[i], &destSurfaces[i], builder);
|
||||
}
|
||||
|
||||
dest->surfaces = reinterpret_cast<Game::XSurface*>(-1);
|
||||
|
@ -2,8 +2,13 @@ namespace Assets
|
||||
{
|
||||
class IXModelSurfs : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_XMODELSURFS; };
|
||||
|
||||
virtual void Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
||||
private:
|
||||
void Save_XSurface(Game::XSurface* surf, Game::XSurface* destSurf, Components::ZoneBuilder::Zone* builder);
|
||||
void Save_XSurfaceCollisionTree(Game::XSurfaceCollisionTree* entry, Components::ZoneBuilder::Zone* builder);
|
||||
};
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ namespace Components
|
||||
data.push_back(info);
|
||||
|
||||
Game::DB_LoadXAssets(data.data(), data.size(), sync);
|
||||
|
||||
#ifdef DEBUG
|
||||
info = { "penis", 1, 0 };
|
||||
Game::DB_LoadXAssets(&info, 1, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* FastFiles::GetZoneLocation(const char* file)
|
||||
@ -112,7 +117,7 @@ namespace Components
|
||||
|
||||
Game::XZoneInfo info;
|
||||
info.name = params[1];
|
||||
info.allocFlags = 0x01000000;
|
||||
info.allocFlags = 1;//0x01000000;
|
||||
info.freeFlags = 0;
|
||||
|
||||
Game::DB_LoadXAssets(&info, 1, true);
|
||||
|
@ -37,15 +37,15 @@ namespace Components
|
||||
{
|
||||
ZoneBuilder::Zone::LoadFastFiles();
|
||||
|
||||
Logger::Print("link...");
|
||||
Logger::Print("Linking assets...\n");
|
||||
if (!ZoneBuilder::Zone::LoadAssets()) return;
|
||||
|
||||
ZoneBuilder::Zone::AddBranding();
|
||||
|
||||
Logger::Print("save...");
|
||||
Logger::Print("Saving...\n");
|
||||
ZoneBuilder::Zone::SaveData();
|
||||
|
||||
Logger::Print("compress...");
|
||||
Logger::Print("Compressing...\n");
|
||||
ZoneBuilder::Zone::WriteZone();
|
||||
}
|
||||
|
||||
@ -281,6 +281,11 @@ namespace Components
|
||||
ZoneBuilder::Zone::Buffer.PushBlock(Game::XFILE_BLOCK_TEMP);
|
||||
ZoneBuilder::Zone::Buffer.Align(Utils::Stream::ALIGN_4);
|
||||
|
||||
#ifdef DEBUG
|
||||
Components::Logger::Print("Saving (%s): %s\n", Game::DB_GetXAssetTypeName(asset.type), Game::DB_GetXAssetName(&asset));
|
||||
#endif
|
||||
|
||||
ZoneBuilder::Zone::Store(asset.header);
|
||||
AssetHandler::ZoneSave(asset, this);
|
||||
|
||||
ZoneBuilder::Zone::Buffer.PopBlock();
|
||||
@ -411,6 +416,14 @@ namespace Components
|
||||
return asset;
|
||||
}
|
||||
|
||||
void ZoneBuilder::Zone::Store(Game::XAssetHeader header)
|
||||
{
|
||||
if (!ZoneBuilder::Zone::HasPointer(header.data)) // We should never have to restore a pointer, so this expression should always resolve into false
|
||||
{
|
||||
ZoneBuilder::Zone::StorePointer(header.data);
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneBuilder::IsEnabled()
|
||||
{
|
||||
return (Flags::HasFlag("zonebuilder") && !Dedicated::IsDedicated());
|
||||
@ -457,7 +470,7 @@ namespace Components
|
||||
if (params.Length() < 2) return;
|
||||
|
||||
std::string zoneName = params[1];
|
||||
Logger::Print("Building zone '%s'...", zoneName.data());
|
||||
Logger::Print("Building zone '%s'...\n", zoneName.data());
|
||||
|
||||
Zone(zoneName).Build();
|
||||
});
|
||||
|
@ -38,6 +38,8 @@ namespace Components
|
||||
void RenameAsset(Game::XAssetType type, std::string asset, std::string newName);
|
||||
std::string GetAssetName(Game::XAssetType type, std::string asset);
|
||||
|
||||
void Store(Game::XAssetHeader header);
|
||||
|
||||
private:
|
||||
void LoadFastFiles();
|
||||
|
||||
|
@ -21,7 +21,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser
|
||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
// Ensure we're working with our desired binary
|
||||
if (Utils::Hook::Get<DWORD>(0x6BAC0F) != 0xF44EE8)
|
||||
if (Utils::Hook::Get<DWORD>(0x4C0FFF) != 0x6824748B)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user