#include "STDInclude.hpp" namespace Components { int Zones::ZoneVersion; int Zones::FxEffectIndex; char* Zones::FxEffectStrings[64]; Utils::Hook Zones::LoadFxElemDefHook; Utils::Hook Zones::LoadFxElemDefArrayHook; Utils::Hook Zones::LoadXModelLodInfoHook; Utils::Hook Zones::LoadXModelHook; Utils::Hook Zones::LoadXSurfaceArrayHook; Utils::Hook Zones::LoadGameWorldSpHook; Utils::Hook Zones::LoadPathDataHook; Utils::Hook Zones::LoadVehicleDefHook; Utils::Hook Zones::Loadsnd_alias_tArrayHook; Utils::Hook Zones::LoadLoadedSoundHook; Utils::Hook Zones::LoadmenuDef_tHook; Utils::Hook Zones::LoadFxEffectDefHook; Utils::Hook Zones::LoadMaterialShaderArgumentArrayHook; Utils::Hook Zones::LoadStructuredDataStructPropertyArrayHook; Utils::Hook Zones::LoadPathDataTailHook; Utils::Hook Zones::LoadWeaponAttachHook; Utils::Hook Zones::LoadWeaponCompleteDefHook; bool Zones::LoadFxEffectDef(bool atStreamStart, char* buffer, int size) { size /= 252; int count = size; size *= 260; bool result = Game::Load_Stream(atStreamStart, buffer, size); Zones::FxEffectIndex = 0; Utils::Memory::Allocator allocator; Game::FxElemDef* elems = allocator.AllocateArray(count); for (int i = 0; i < count; ++i) { AssetHandler::Relocate(buffer + (260 * i), buffer + (252 * i), 252); std::memcpy(&elems[i], buffer + (260 * i), 252); Zones::FxEffectStrings[i] = *reinterpret_cast(buffer + (260 * i) + 256); } std::memcpy(buffer, elems,sizeof(Game::FxElemDef) * count); return result; } bool Zones::LoadFxElemDefStub(bool atStreamStart, Game::FxElemDef* fxElem, int size) { if (fxElem->elemType == 3) { fxElem->elemType = 2; } else if (fxElem->elemType >= 5) { fxElem->elemType -= 2; } return Game::Load_Stream(atStreamStart, fxElem, size); } void Zones::LoadFxElemDefArrayStub(bool atStreamStart) { Game::Load_FxElemDef(atStreamStart); *Game::varXString = &Zones::FxEffectStrings[Zones::FxEffectIndex++]; Game::Load_XString(false); } bool Zones::LoadXModel(bool atStreamStart, char* xmodel, int size) { bool result = Game::Load_Stream(atStreamStart, xmodel, size); int elSize = (Zones::ZoneVersion == VERSION_ALPHA2) ? 364 : 360; Game::XModel model[2]; // Allocate 2 models, as we exceed the buffer std::memcpy(model, xmodel, 36); std::memcpy(&model->pad3[0x1C], &xmodel[44], 28); for (int i = 0; i < 4; ++i) { std::memcpy(&model->lods[i], &xmodel[72 + (i * 56)], 12); std::memcpy(&model->lods[i].pad3, &xmodel[72 + (i * 56) + 16], 32); std::memcpy(reinterpret_cast(&model) + (elSize - 4) - (i * 4), &xmodel[72 + (i * 56) + 12], 4); } std::memcpy(&model->lods[3].pad4[0], &xmodel[292], (elSize - 292 - 4)/*68*/); std::memcpy(&model->physPreset, &xmodel[(elSize - 8)], 8); model[1].name = reinterpret_cast(0xDEADC0DE); std::memcpy(xmodel, &model, elSize); return result; } void Zones::LoadXModelLodInfo(int i) { int elSize = (Zones::ZoneVersion == VERSION_ALPHA2) ? 364 : 360; *Game::varXString = reinterpret_cast(reinterpret_cast(*Game::varXModel) + (elSize - 4) - (4 * (4 - i))); Game::Load_XString(false); } __declspec(naked) void Zones::LoadXModelLodInfoStub() { __asm { push edi call Zones::LoadXModelLodInfo add esp, 4h mov eax, [esp + 8h] push eax add eax, 8 push eax call Game::Load_XModelSurfsFixup add esp, 8h retn } } bool Zones::LoadXSurfaceArray(bool atStreamStart, char* buffer, int size) { size >>= 6; int count = size; size *= 84; bool result = Game::Load_Stream(atStreamStart, buffer, size); Utils::Memory::Allocator allocator; Game::XSurface* tempSurfaces = allocator.AllocateArray(count); for (int i = 0; i < count; ++i) { char* source = &buffer[i * 84]; std::memcpy(&tempSurfaces[i], source, 12); std::memcpy(&tempSurfaces[i].indexBuffer, source + 16, 20); std::memcpy(&tempSurfaces[i].numCT, source + 40, 8); std::memcpy(&tempSurfaces[i].something, source + 52, 24); } std::memcpy(buffer, tempSurfaces, sizeof(Game::XSurface) * count); return result; } void Zones::LoadWeaponCompleteDef() { // setup structures we use char* varWeaponCompleteDef = *reinterpret_cast(0x112A9F4); // and do the stuff Game::Load_Stream(true, varWeaponCompleteDef, (Zones::ZoneVersion >= 318) ? 3156 : 3112); Game::DB_PushStreamPos(3); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 0); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 4); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 8); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 12); Game::Load_XString(false); *Game::varXModelPtr = reinterpret_cast(varWeaponCompleteDef + 16); Game::Load_XModelPtr(false); for (int i = 0, offset = 20; i < 32; ++i, offset += 4) { *Game::varXModelPtr = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_XModelPtr(false); } // 148 for (int offset = 148; offset <= 168; offset += 4) { *Game::varXModelPtr = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_XModelPtr(false); } // 172 // 32 scriptstrings, should not need to be loaded // 236 *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 236); Game::Load_XStringArray(false, 48); // 428 *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 428); Game::Load_XStringArray(false, 48); // 620 *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 620); Game::Load_XStringArray(false, 48); // 812 // 16 * 4 scriptstrings // 972 *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 972); Game::Load_FxEffectDefHandle(false); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 976); Game::Load_FxEffectDefHandle(false); // 980 // 50 soundalias name references; up to and including 1180 for (int i = 0, offset = 980; i < 50; ++i, offset += 4) { *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); } if (Zones::ZoneVersion >= 318) { for (int i = 0, offset = 1184; i < 2; ++i, offset += 4) { *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); } varWeaponCompleteDef += 8; // to compensate for the 2 in between here } if (*reinterpret_cast(varWeaponCompleteDef + 1184)) { if (*reinterpret_cast(varWeaponCompleteDef + 1184) == -1) { *reinterpret_cast(varWeaponCompleteDef + 1184) = Game::DB_AllocStreamPos(3); *Game::varsnd_alias_list_name = *reinterpret_cast(varWeaponCompleteDef + 1184); Game::Load_snd_alias_list_nameArray(true, 31); } else { // full usability requires ConvertOffsetToPointer here } } if (*reinterpret_cast(varWeaponCompleteDef + 1188)) { if (*reinterpret_cast(varWeaponCompleteDef + 1188) == -1) { *reinterpret_cast(varWeaponCompleteDef + 1188) = Game::DB_AllocStreamPos(3); *Game::varsnd_alias_list_name = *reinterpret_cast(varWeaponCompleteDef + 1188); Game::Load_snd_alias_list_nameArray(true, 31); } else { // full usability requires ConvertOffsetToPointer here } } // 1192 for (int offset = 1192; offset <= 1204; offset += 4) { *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_FxEffectDefHandle(false); } // 1208 static int matOffsets1[] = { 1208, 1212, 1428, 1432, 1436, 1440, 1444, 1448, 1456, 1464 }; for (int i = 0; i < ARRAYSIZE(matOffsets1); ++i) { *Game::varMaterialHandle = reinterpret_cast(varWeaponCompleteDef + matOffsets1[i]); Game::Load_MaterialHandle(false); } *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 1484); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 1492); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 1508); Game::Load_XString(false); for (int offset = 1764; offset <= 1776; offset += 4) { *Game::varMaterialHandle = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_MaterialHandle(false); } *Game::varPhysCollmapPtr = reinterpret_cast(varWeaponCompleteDef + 1964); Game::Load_PhysCollmapPtr(false); *Game::varXModelPtr = reinterpret_cast(varWeaponCompleteDef + 2052); Game::Load_XModelPtr(false); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2060); Game::Load_FxEffectDefHandle(false); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2064); Game::Load_FxEffectDefHandle(false); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2068); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2072); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2336); Game::Load_FxEffectDefHandle(false); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2340); Game::Load_FxEffectDefHandle(false); *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2368); // 2376 Game::Load_FxEffectDefHandle(false); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2372); // 2380 Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2548); // 2556 Game::Load_XString(false); if (*reinterpret_cast(varWeaponCompleteDef + 2556) == -1) // 2564 { void* vec2 = Game::DB_AllocStreamPos(3); *reinterpret_cast(varWeaponCompleteDef + 2556) = vec2; Game::Load_Stream(true, (void*)vec2, 8 * *reinterpret_cast(varWeaponCompleteDef + ((Zones::ZoneVersion >= 318) ? 3076 : 3040))); } *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2552); Game::Load_XString(false); if (*reinterpret_cast(varWeaponCompleteDef + 2560) == -1) { void* vec2 = Game::DB_AllocStreamPos(3); *reinterpret_cast(varWeaponCompleteDef + 2560) = vec2; Game::Load_Stream(true, (void*)vec2, 8 * *reinterpret_cast(varWeaponCompleteDef + ((Zones::ZoneVersion >= 318) ? 3078 : 3042))); } *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2640); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2644); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2676); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2680); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2804); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2808); Game::Load_XString(false); *Game::varTracerDefPtr = reinterpret_cast(varWeaponCompleteDef + 2812); Game::Load_TracerDefPtr(false); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2840); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); // 2848 *Game::varFxEffectDefHandle = reinterpret_cast(varWeaponCompleteDef + 2844); Game::Load_FxEffectDefHandle(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2848); Game::Load_XString(false); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2864); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2868); Game::Load_snd_alias_list_nameArray(false, 4); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2884); Game::Load_snd_alias_list_nameArray(false, 4); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2900); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + 2904); // 2912 Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); if (Zones::ZoneVersion >= 318) { for (int i = 0, offset = 2972; i < 6; ++i, offset += 4) { *Game::varsnd_alias_list_name = reinterpret_cast(varWeaponCompleteDef + offset); Game::Load_SndAliasCustom(*Game::varsnd_alias_list_name); } varWeaponCompleteDef += (6 * 4); varWeaponCompleteDef += 12; } else { } *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2984); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 2996); Game::Load_XString(false); *Game::varXString = reinterpret_cast(varWeaponCompleteDef + 3000); Game::Load_XString(false); *Game::varMaterialHandle = reinterpret_cast(varWeaponCompleteDef + 3008); Game::Load_MaterialHandle(false); *Game::varMaterialHandle = reinterpret_cast(varWeaponCompleteDef + 3012); Game::Load_MaterialHandle(false); *Game::varMaterialHandle = reinterpret_cast(varWeaponCompleteDef + 3016); Game::Load_MaterialHandle(false); if (*reinterpret_cast(varWeaponCompleteDef + 3044) == -1) { void* vec2 = Game::DB_AllocStreamPos(3); *reinterpret_cast(varWeaponCompleteDef + 3044) = vec2; Game::Load_Stream(true, (void*)vec2, 8 * *reinterpret_cast(varWeaponCompleteDef + 3040)); } if (*reinterpret_cast(varWeaponCompleteDef + 3048) == -1) { void* vec2 = Game::DB_AllocStreamPos(3); *reinterpret_cast(varWeaponCompleteDef + 3048) = vec2; Game::Load_Stream(true, (void*)vec2, 8 * *reinterpret_cast(varWeaponCompleteDef + 3042)); } Game::DB_PopStreamPos(); } bool Zones::LoadGameWorldSp(bool atStreamStart, char* buffer) { bool result = Game::Load_Stream(atStreamStart, buffer, 84); Game::GameWorldSp world[2]; std::memcpy(&world, buffer, 44); std::memcpy(&world[1], &buffer[44], 28); std::memcpy(&world->vehicleTrack, &buffer[72], 12); std::memcpy(buffer, world, 84); return result; } void Zones::LoadPathDataTail() { char* varPathData = reinterpret_cast(*Game::varPathData); if (*reinterpret_cast(varPathData + 56)) { *reinterpret_cast(varPathData + 56) = Game::DB_AllocStreamPos(0); Game::Load_Stream(true, *reinterpret_cast(varPathData + 56), *reinterpret_cast(varPathData + 52)); } if (*reinterpret_cast(varPathData + 64)) { *reinterpret_cast(varPathData + 64) = Game::DB_AllocStreamPos(0); Game::Load_Stream(true, *reinterpret_cast(varPathData + 64), *reinterpret_cast(varPathData + 60)); } if (*reinterpret_cast(varPathData + 76)) { *reinterpret_cast(varPathData + 76) = Game::DB_AllocStreamPos(0); Game::Load_Stream(true, *reinterpret_cast(varPathData + 76), *reinterpret_cast(varPathData + 72)); } } bool Zones::Loadsnd_alias_tArray(bool atStreamStart, char* buffer, int len) { len /= 100; int count = len; len *= 108; bool result = Game::Load_Stream(atStreamStart, buffer, len); Utils::Memory::Allocator allocator; Game::snd_alias_t* tempSounds = allocator.AllocateArray(count); for (int i = 0; i < count; ++i) { char* src = &buffer[i * 108]; std::memcpy(&tempSounds[i], src + 0, 60); std::memcpy(&tempSounds[i].pad2[36], src + 68, 20); std::memcpy(&tempSounds[i].pad2[56], src + 88, 20); AssetHandler::Relocate(src + 0, buffer + (i * 100) + 0, 60); AssetHandler::Relocate(src + 68, buffer + (i * 100) + 60, 20); AssetHandler::Relocate(src + 88, buffer + (i * 100) + 80, 20); } std::memcpy(buffer, tempSounds, sizeof(Game::snd_alias_t) * count); return result; } bool Zones::LoadLoadedSound(bool atStreamStart, char* buffer) { bool result = Game::Load_Stream(atStreamStart, buffer, 48); std::memmove(buffer + 28, buffer + 32, 16); AssetHandler::Relocate(buffer + 32, buffer + 28, 16); return result; } bool Zones::LoadVehicleDef(bool atStreamStart, char* buffer) { bool result = Game::Load_Stream(atStreamStart, buffer, 788); Game::VehicleDef vehicle[2]; std::memcpy(vehicle, &buffer[0], 400); std::memcpy(&vehicle->pad[404], &buffer[400], 388); AssetHandler::Relocate(buffer + 400, buffer + 408, 388); std::memcpy(buffer, vehicle, 788); return result; } void Zones::LoadWeaponAttachStuff(DWORD* varWeaponAttachStuff, int count) { Game::Load_Stream(true, varWeaponAttachStuff, 12 * count); for (int i = 0; i < count; ++i) { if (varWeaponAttachStuff[1] < 16 || varWeaponAttachStuff[1] == 39) { if (varWeaponAttachStuff[2] == -1) { varWeaponAttachStuff[2] = reinterpret_cast(Game::DB_AllocStreamPos(0)); *Game::varConstChar = reinterpret_cast(varWeaponAttachStuff[2]); Game::Load_XStringCustom(Game::varConstChar); } } varWeaponAttachStuff += 3; } } bool Zones::LoadmenuDef_t(bool atStreamStart, char* buffer, int size) { bool result = Game::Load_Stream(atStreamStart, buffer, size + 4); std::memmove(buffer + 168, buffer + 172, 232); AssetHandler::Relocate(buffer + 172, buffer + 168, 232); return result; } void Zones::LoadWeaponAttach() { // setup structures we use char* varWeaponAttach = *reinterpret_cast(0x112ADE0); // varAddonMapEnts // and do the stuff Game::Load_Stream(true, varWeaponAttach, 12); Game::DB_PushStreamPos(3); *Game::varXString = reinterpret_cast(varWeaponAttach); Game::Load_XString(false); *reinterpret_cast(varWeaponAttach + 8) = Game::DB_AllocStreamPos(3); Zones::LoadWeaponAttachStuff(*reinterpret_cast(varWeaponAttach + 8), *reinterpret_cast(varWeaponAttach + 4)); Game::DB_PopStreamPos(); } bool Zones::LoadMaterialShaderArgumentArray(bool atStreamStart, Game::MaterialShaderArgument* argument, int size) { bool result = Game::Load_Stream(atStreamStart, argument, size); Game::MaterialPass* curPass = *Game::varMaterialPass; int count = curPass->argCount1 + curPass->argCount2 + curPass->argCount3; for (int i = 0; i < count; ++i) { Game::MaterialShaderArgument* arg = &argument[i]; if (arg->type != 3 && arg->type != 5) { continue; } // should be min 68 currently // >= 58 fixes foliage without bad side effects // >= 53 still has broken shadow mapping // >= 23 is still broken somehow if (arg->paramID >= 58 && arg->paramID <= 135) // >= 34 would be 31 in iw4 terms { arg->paramID -= 3; } // >= 21 works fine for specular, but breaks trees // >= 4 is too low, breaks specular else if (arg->paramID >= 11 && arg->paramID < 58) { arg->paramID -= 2; } } return result; } bool Zones::LoadStructuredDataStructPropertyArray(bool atStreamStart, char* data, int size) { size /= 16; int count = size; size *= 24; bool result = Game::Load_Stream(atStreamStart, data, size); for (int i = 0; i < count; ++i) { std::memmove(data + (i * 16), data + (i * 24), 16); AssetHandler::Relocate(data + (i * 24), data + (i * 16), 16); } return result; } void Zones::InstallPatches(int version) { AssetHandler::ClearRelocations(); if (Zones::ZoneVersion == version) return; Zones::ZoneVersion = version; bool patch = (version >= VERSION_ALPHA2); if (Zones::ZoneVersion == VERSION_ALPHA2 || Zones::ZoneVersion == VERSION_ALPHA3 || Zones::ZoneVersion == VERSION_ALPHA3_DEC || Zones::ZoneVersion == XFILE_VERSION) { Utils::Hook::Set(0x4158F4, version); Utils::Hook::Set(0x4158FB, version); } // physpreset size Utils::Hook::Set(0x49CE0A, (patch) ? 68 : 44); // XModel size Utils::Hook::Set(0x410D8A, (patch) ? ((Zones::ZoneVersion == VERSION_ALPHA2) ? 0x16C : 0x168) : 0x130); // XSurface size Utils::Hook::Set(0x48E84A, (patch) ? 48 : 36); // impactfx internal size/count Utils::Hook::Set(0x4447B6, (patch) ? 0x8C0 : 0x834); Utils::Hook::Set(0x4447D1, (patch) ? 16 : 15); // GameWorldSp asset type Utils::Hook::Set(0x41899A, (patch) ? 18 : 17); // PathData internal struct size Utils::Hook::Set(0x4D6A04, (patch) ? 148 : 136); Utils::Hook::Set(0x4D6A49, (patch) ? 148 : 136); // PathData internal struct data size Utils::Hook::Set(0x463D63, (patch) ? 0x9090 : 0x048D); Utils::Hook::Set(0x463D65, (patch) ? 0x90 : 0x40); Utils::Hook::Set(0x463D66, (patch) ? 0x9004E0C1 : 0xC003C003); // shl eax, 4 instead of add eax, eax * 2 // addon_map_ents asset type (we reuse it for weaponattach) Utils::Hook::Set(0x418B30, (patch) ? 43 : Game::ASSET_TYPE_ADDON_MAP_ENTS); if (patch) { Zones::LoadFxElemDefArrayHook.Install(); Zones::LoadFxElemDefHook.Install(); Zones::LoadXModelLodInfoHook.Install(); Zones::LoadXModelHook.Install(); Zones::LoadXSurfaceArrayHook.Install(); Zones::LoadGameWorldSpHook.Install(); Zones::LoadPathDataTailHook.Install(); Zones::LoadWeaponCompleteDefHook.Install(); Zones::LoadVehicleDefHook.Install(); Zones::Loadsnd_alias_tArrayHook.Install(); Zones::LoadLoadedSoundHook.Install(); Zones::LoadmenuDef_tHook.Install(); Zones::LoadFxEffectDefHook.Install(); Zones::LoadWeaponAttachHook.Install(); if (Zones::ZoneVersion >= VERSION_ALPHA3) { Zones::LoadPathDataHook.Install(); } Zones::LoadMaterialShaderArgumentArrayHook.Install(); Zones::LoadStructuredDataStructPropertyArrayHook.Install(); } else { Zones::LoadFxElemDefArrayHook.Uninstall(); Zones::LoadFxElemDefHook.Uninstall(); Zones::LoadXModelLodInfoHook.Uninstall(); Zones::LoadXModelHook.Uninstall(); Zones::LoadXSurfaceArrayHook.Uninstall(); Zones::LoadGameWorldSpHook.Uninstall(); Zones::LoadPathDataTailHook.Uninstall(); Zones::LoadWeaponCompleteDefHook.Uninstall(); Zones::LoadVehicleDefHook.Uninstall(); Zones::Loadsnd_alias_tArrayHook.Uninstall(); Zones::LoadLoadedSoundHook.Uninstall(); Zones::LoadmenuDef_tHook.Uninstall(); Zones::LoadFxEffectDefHook.Uninstall(); Zones::LoadWeaponAttachHook.Uninstall(); Zones::LoadPathDataHook.Uninstall(); Zones::LoadMaterialShaderArgumentArrayHook.Uninstall(); Zones::LoadStructuredDataStructPropertyArrayHook.Uninstall(); } AntiCheat::EmptyHash(); } Zones::Zones() { Zones::ZoneVersion = 0; // Ignore missing soundaliases for now // TODO: Include them in the dependency zone! Utils::Hook::Nop(0x644207, 5); // Block Mark_pathnode_constant_t Utils::Hook::Set(0x4F74B0, 0xC3); Zones::LoadFxElemDefArrayHook.Initialize(0x495938, Zones::LoadFxElemDefArrayStub, HOOK_CALL); Zones::LoadFxElemDefHook.Initialize(0x45ADA0, Zones::LoadFxElemDefStub, HOOK_CALL); Zones::LoadXModelLodInfoHook.Initialize(0x4EA6FE, Zones::LoadXModelLodInfoStub, HOOK_CALL); Zones::LoadXModelHook.Initialize(0x410D90, Zones::LoadXModel, HOOK_CALL); Zones::LoadXSurfaceArrayHook.Initialize(0x4925C8, Zones::LoadXSurfaceArray, HOOK_CALL); Zones::LoadGameWorldSpHook.Initialize(0x4F4D0D, Zones::LoadGameWorldSp, HOOK_CALL); Zones::LoadWeaponCompleteDefHook.Initialize(0x47CCD2, Zones::LoadWeaponCompleteDef, HOOK_CALL); Zones::LoadVehicleDefHook.Initialize(0x483DA0, Zones::LoadVehicleDef, HOOK_CALL); Zones::Loadsnd_alias_tArrayHook.Initialize(0x4F0AC8, Zones::Loadsnd_alias_tArray, HOOK_CALL); Zones::LoadLoadedSoundHook.Initialize(0x403A5D, Zones::LoadLoadedSound, HOOK_CALL); Zones::LoadWeaponAttachHook.Initialize(0x463022, Zones::LoadWeaponAttach, HOOK_CALL); Zones::LoadmenuDef_tHook.Initialize(0x41A570, Zones::LoadmenuDef_t, HOOK_CALL); Zones::LoadFxEffectDefHook.Initialize(0x49591B, Zones::LoadFxEffectDef, HOOK_CALL); Zones::LoadMaterialShaderArgumentArrayHook.Initialize(0x428F0A, Zones::LoadMaterialShaderArgumentArray, HOOK_CALL); Zones::LoadStructuredDataStructPropertyArrayHook.Initialize(0x4B1EB8, Zones::LoadStructuredDataStructPropertyArray, HOOK_CALL); Zones::LoadPathDataTailHook.Initialize(0x427A1B, Zones::LoadPathDataTail, HOOK_JUMP); Zones::LoadPathDataHook.Initialize(0x4F4D3B, [] () { ZeroMemory(*Game::varPathData, sizeof(Game::PathData)); }, HOOK_CALL); } Zones::~Zones() { } }