Merge branch 'feature/assetinterface-weapon' into 'develop'
Add weapons to zonebuilder
This commit is contained in:
commit
c845572be5
1
.gitignore
vendored
1
.gitignore
vendored
@ -143,6 +143,7 @@ UpgradeLog*.htm
|
||||
*.til
|
||||
*.idb
|
||||
*.i64
|
||||
ida/*
|
||||
|
||||
### Custom user files
|
||||
# User scripts
|
||||
|
2
deps/json11
vendored
2
deps/json11
vendored
@ -1 +1 @@
|
||||
Subproject commit 8d33613ebde0e7756a026e3770330da11e741823
|
||||
Subproject commit ec4e45219af1d7cde3d58b49ed762376fccf1ace
|
2
deps/libtommath
vendored
2
deps/libtommath
vendored
@ -1 +1 @@
|
||||
Subproject commit 2d80a97a2b48aa1ac6d8f0df29cc4dd6297b1fba
|
||||
Subproject commit 13444a8af2d077eda8fd0be017cac2dad20465dc
|
2
deps/mongoose
vendored
2
deps/mongoose
vendored
@ -1 +1 @@
|
||||
Subproject commit c2a10601b9486f28b75307f003f5d9078acdce10
|
||||
Subproject commit e9a8e5468d9e6e37fd2813decfd49f0d5312e66e
|
2
deps/pdcurses
vendored
2
deps/pdcurses
vendored
@ -1 +1 @@
|
||||
Subproject commit 3f2336ad818b394110494ccb6d0dafed54a13950
|
||||
Subproject commit 2b9bb5d0c8fc563fec431cf24efb0f985e4b43b7
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
||||
Subproject commit 0d36ec47f310478549c0864f215ab5c0114c49ba
|
||||
Subproject commit 7c0c75e990ca5395139c148f120042048b0ce091
|
@ -3,6 +3,7 @@
|
||||
namespace Components
|
||||
{
|
||||
thread_local int AssetHandler::BypassState = 0;
|
||||
bool AssetHandler::ShouldSearchTempAssets = false;
|
||||
std::map<Game::XAssetType, AssetHandler::IAsset*> AssetHandler::AssetInterfaces;
|
||||
std::map<Game::XAssetType, Utils::Slot<AssetHandler::Callback>> AssetHandler::TypeCallbacks;
|
||||
Utils::Signal<AssetHandler::RestrictCallback> AssetHandler::RestrictSignal;
|
||||
@ -69,6 +70,21 @@ namespace Components
|
||||
return header;
|
||||
}
|
||||
|
||||
Game::XAssetHeader AssetHandler::FindTemporaryAsset(Game::XAssetType type, const char* filename)
|
||||
{
|
||||
Game::XAssetHeader header = { nullptr };
|
||||
if (type >= Game::XAssetType::ASSET_TYPE_COUNT) return header;
|
||||
|
||||
auto tempPool = &AssetHandler::TemporaryAssets[type];
|
||||
auto entry = tempPool->find(filename);
|
||||
if (entry != tempPool->end())
|
||||
{
|
||||
header = { entry->second };
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
int AssetHandler::HasThreadBypass()
|
||||
{
|
||||
return AssetHandler::BypassState > 0;
|
||||
@ -116,7 +132,7 @@ namespace Components
|
||||
|
||||
|
||||
test al, al
|
||||
jnz finishOriginal
|
||||
jnz checkTempAssets
|
||||
|
||||
mov ecx, [esp + 18h] // Asset type
|
||||
mov ebx, [esp + 1Ch] // Filename
|
||||
@ -140,8 +156,27 @@ namespace Components
|
||||
test eax, eax
|
||||
jnz finishFound
|
||||
|
||||
finishOriginal:
|
||||
// Asset not found using custom handlers, redirect to DB_FindXAssetHeader
|
||||
checkTempAssets:
|
||||
mov al, AssetHandler::ShouldSearchTempAssets // check to see if enabled
|
||||
test eax, eax
|
||||
jz finishOriginal
|
||||
|
||||
mov ecx, [esp + 18h] // Asset type
|
||||
mov ebx, [esp + 1Ch] // Filename
|
||||
|
||||
push ebx
|
||||
push ecx
|
||||
|
||||
call AssetHandler::FindTemporaryAsset
|
||||
|
||||
add esp, 8h
|
||||
|
||||
test eax, eax
|
||||
jnz finishFound
|
||||
|
||||
finishOriginal:
|
||||
// Asset not found using custom handlers or in temp assets or bypasses were enabled
|
||||
// redirect to DB_FindXAssetHeader
|
||||
mov ebx, ds:6D7190h // InterlockedDecrement
|
||||
mov eax, 40793Bh
|
||||
jmp eax
|
||||
@ -454,6 +489,11 @@ namespace Components
|
||||
Utils::Hook::Set<Game::XAssetEntry*>(0x5BAEA2, entryPool + 1);
|
||||
}
|
||||
|
||||
void AssetHandler::ExposeTemporaryAssets(bool expose)
|
||||
{
|
||||
AssetHandler::ShouldSearchTempAssets = expose;
|
||||
}
|
||||
|
||||
AssetHandler::AssetHandler()
|
||||
{
|
||||
this->reallocateEntryPool();
|
||||
@ -525,6 +565,7 @@ namespace Components
|
||||
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_RAWFILE, 2048);
|
||||
|
||||
AssetHandler::RegisterInterface(new Assets::IFont_s());
|
||||
AssetHandler::RegisterInterface(new Assets::IWeapon());
|
||||
AssetHandler::RegisterInterface(new Assets::IXModel());
|
||||
AssetHandler::RegisterInterface(new Assets::IFxWorld());
|
||||
AssetHandler::RegisterInterface(new Assets::IMapEnts());
|
||||
@ -535,8 +576,9 @@ namespace Components
|
||||
AssetHandler::RegisterInterface(new Assets::ISndCurve());
|
||||
AssetHandler::RegisterInterface(new Assets::IMaterial());
|
||||
AssetHandler::RegisterInterface(new Assets::IMenuList());
|
||||
AssetHandler::RegisterInterface(new Assets::IclipMap_t());
|
||||
AssetHandler::RegisterInterface(new Assets::ImenuDef_t());
|
||||
AssetHandler::RegisterInterface(new Assets::IclipMap_t());
|
||||
AssetHandler::RegisterInterface(new Assets::ITracerDef());
|
||||
AssetHandler::RegisterInterface(new Assets::IPhysPreset());
|
||||
AssetHandler::RegisterInterface(new Assets::IXAnimParts());
|
||||
AssetHandler::RegisterInterface(new Assets::IFxEffectDef());
|
||||
|
@ -39,8 +39,11 @@ namespace Components
|
||||
|
||||
static void ResetBypassState();
|
||||
|
||||
static void ExposeTemporaryAssets(bool expose);
|
||||
|
||||
private:
|
||||
static thread_local int BypassState;
|
||||
static bool ShouldSearchTempAssets;
|
||||
|
||||
static std::map<std::string, Game::XAssetHeader> TemporaryAssets[Game::XAssetType::ASSET_TYPE_COUNT];
|
||||
|
||||
@ -55,6 +58,7 @@ namespace Components
|
||||
static void RegisterInterface(IAsset* iAsset);
|
||||
|
||||
static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename);
|
||||
static Game::XAssetHeader FindTemporaryAsset(Game::XAssetType type, const char* filename);
|
||||
static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset);
|
||||
static void FindAssetStub();
|
||||
static void AddAssetStub();
|
||||
@ -76,6 +80,7 @@ namespace Components
|
||||
}
|
||||
|
||||
#include "AssetInterfaces/IFont_s.hpp"
|
||||
#include "AssetInterfaces/IWeapon.hpp"
|
||||
#include "AssetInterfaces/IXModel.hpp"
|
||||
#include "AssetInterfaces/IFxWorld.hpp"
|
||||
#include "AssetInterfaces/IMapEnts.hpp"
|
||||
@ -86,8 +91,9 @@ namespace Components
|
||||
#include "AssetInterfaces/IMaterial.hpp"
|
||||
#include "AssetInterfaces/ISndCurve.hpp"
|
||||
#include "AssetInterfaces/IMenuList.hpp"
|
||||
#include "AssetInterfaces/ImenuDef_t.hpp"
|
||||
#include "AssetInterfaces/IclipMap_t.hpp"
|
||||
#include "AssetInterfaces/ImenuDef_t.hpp"
|
||||
#include "AssetInterfaces/ITracerDef.hpp"
|
||||
#include "AssetInterfaces/IPhysPreset.hpp"
|
||||
#include "AssetInterfaces/IXAnimParts.hpp"
|
||||
#include "AssetInterfaces/IFxEffectDef.hpp"
|
||||
@ -105,3 +111,4 @@ namespace Components
|
||||
#include "AssetInterfaces/IMaterialVertexShader.hpp"
|
||||
#include "AssetInterfaces/IStructuredDataDefSet.hpp"
|
||||
#include "AssetInterfaces/IMaterialVertexDeclaration.hpp"
|
||||
|
||||
|
44
src/Components/Modules/AssetInterfaces/ITracerDef.cpp
Normal file
44
src/Components/Modules/AssetInterfaces/ITracerDef.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
void ITracerDef::load(Game::XAssetHeader* /*header*/, const std::string& /*name*/, Components::ZoneBuilder::Zone* /*builder*/)
|
||||
{
|
||||
return; // don't load from filesystem right now
|
||||
}
|
||||
|
||||
void ITracerDef::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Game::TracerDef* asset = header.tracerDef;
|
||||
|
||||
if (asset->material)
|
||||
{
|
||||
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->material);
|
||||
}
|
||||
}
|
||||
|
||||
void ITracerDef::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
AssertSize(Game::TracerDef, 0x70);
|
||||
|
||||
Utils::Stream* buffer = builder->getBuffer();
|
||||
Game::TracerDef* asset = header.tracerDef;
|
||||
Game::TracerDef* dest = buffer->dest<Game::TracerDef>();
|
||||
buffer->save(asset);
|
||||
|
||||
buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (asset->name)
|
||||
{
|
||||
buffer->saveString(builder->getAssetName(this->getType(), asset->name));
|
||||
Utils::Stream::ClearPointer(&dest->name);
|
||||
}
|
||||
|
||||
if (asset->material)
|
||||
{
|
||||
dest->material = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->material).material;
|
||||
}
|
||||
|
||||
buffer->popBlock();
|
||||
}
|
||||
}
|
14
src/Components/Modules/AssetInterfaces/ITracerDef.hpp
Normal file
14
src/Components/Modules/AssetInterfaces/ITracerDef.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
class ITracerDef : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_TRACER; };
|
||||
|
||||
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override;
|
||||
};
|
||||
}
|
702
src/Components/Modules/AssetInterfaces/IWeapon.cpp
Normal file
702
src/Components/Modules/AssetInterfaces/IWeapon.cpp
Normal file
@ -0,0 +1,702 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
void IWeapon::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/)
|
||||
{
|
||||
// Try loading raw weapon
|
||||
if (Components::FileSystem::File(Utils::String::VA("weapons/mp/%s", name.data())).exists())
|
||||
{
|
||||
// let the function see temporary assets when calling DB_FindXAssetHeader during the loading function
|
||||
// otherwise it fails to link things properly
|
||||
Components::AssetHandler::ExposeTemporaryAssets(true);
|
||||
header->data = Game::BG_LoadWeaponDef_LoadObj(name.data());
|
||||
Components::AssetHandler::ExposeTemporaryAssets(false);
|
||||
}
|
||||
}
|
||||
|
||||
void IWeapon::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
Game::WeaponCompleteDef* asset = header.weapon;
|
||||
|
||||
// convert all script strings
|
||||
if (asset->hideTags)
|
||||
{
|
||||
for (char i = 0; i < 32; ++i)
|
||||
{
|
||||
if (asset->hideTags[i] == NULL) break; // no more strings
|
||||
builder->addScriptString(asset->hideTags[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->notetrackSoundMapKeys)
|
||||
{
|
||||
for (char i = 0; i < 16; ++i)
|
||||
{
|
||||
if (asset->weapDef->notetrackSoundMapKeys[i] == NULL) break; // no more strings
|
||||
builder->addScriptString(asset->weapDef->notetrackSoundMapKeys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->notetrackSoundMapValues)
|
||||
{
|
||||
for (char i = 0; i < 16; ++i)
|
||||
{
|
||||
if (asset->weapDef->notetrackSoundMapValues[i] == NULL) break; // no more strings
|
||||
builder->addScriptString(asset->weapDef->notetrackSoundMapValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->notetrackRumbleMapKeys)
|
||||
{
|
||||
for (char i = 0; i < 16; ++i)
|
||||
{
|
||||
if (asset->weapDef->notetrackRumbleMapKeys[i] == NULL) break; // no more strings
|
||||
builder->addScriptString(asset->weapDef->notetrackRumbleMapKeys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->notetrackRumbleMapValues)
|
||||
{
|
||||
for (char i = 0; i < 16; ++i)
|
||||
{
|
||||
if (asset->weapDef->notetrackRumbleMapValues[i] == NULL) break; // no more strings
|
||||
builder->addScriptString(asset->weapDef->notetrackRumbleMapValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now load all sub-assets properly
|
||||
if (asset->killIcon) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->killIcon);
|
||||
if (asset->dpadIcon) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->dpadIcon);
|
||||
if (asset->weapDef->reticleCenter) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->reticleCenter);
|
||||
if (asset->weapDef->reticleSide) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->reticleSide);
|
||||
if (asset->weapDef->hudIcon) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->hudIcon);
|
||||
if (asset->weapDef->pickupIcon) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->pickupIcon);
|
||||
if (asset->weapDef->ammoCounterIcon) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->ammoCounterIcon);
|
||||
if (asset->weapDef->overlayMaterial) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->overlayMaterial);
|
||||
if (asset->weapDef->overlayMaterialLowRes) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->overlayMaterialLowRes);
|
||||
if (asset->weapDef->overlayMaterialEMP) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->overlayMaterialEMP);
|
||||
if (asset->weapDef->overlayMaterialEMPLowRes) builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->weapDef->overlayMaterialEMPLowRes);
|
||||
|
||||
if (asset->weapDef->gunXModel)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (asset->weapDef->gunXModel[i]) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->gunXModel[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->handXModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->handXModel);
|
||||
|
||||
if (asset->weapDef->worldModel)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (asset->weapDef->worldModel[i]) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->worldModel[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (asset->weapDef->worldClipModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->worldClipModel);
|
||||
if (asset->weapDef->rocketModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->rocketModel);
|
||||
if (asset->weapDef->knifeModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->knifeModel);
|
||||
if (asset->weapDef->worldKnifeModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->worldKnifeModel);
|
||||
if (asset->weapDef->projectileModel) builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, asset->weapDef->projectileModel);
|
||||
|
||||
if (asset->weapDef->physCollmap) builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSCOLLMAP, asset->weapDef->physCollmap);
|
||||
|
||||
if (asset->weapDef->tracerType) builder->loadAsset(Game::XAssetType::ASSET_TYPE_TRACER, asset->weapDef->tracerType);
|
||||
|
||||
if (asset->weapDef->viewFlashEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->viewFlashEffect);
|
||||
if (asset->weapDef->worldFlashEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->worldFlashEffect);
|
||||
if (asset->weapDef->viewShellEjectEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->viewShellEjectEffect);
|
||||
if (asset->weapDef->worldShellEjectEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->worldShellEjectEffect);
|
||||
if (asset->weapDef->viewLastShotEjectEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->viewLastShotEjectEffect);
|
||||
if (asset->weapDef->worldLastShotEjectEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->worldLastShotEjectEffect);
|
||||
if (asset->weapDef->projExplosionEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->projExplosionEffect);
|
||||
if (asset->weapDef->projDudEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->projDudEffect);
|
||||
if (asset->weapDef->projTrailEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->projTrailEffect);
|
||||
if (asset->weapDef->projBeaconEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->projBeaconEffect);
|
||||
if (asset->weapDef->projIgnitionEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->projIgnitionEffect);
|
||||
if (asset->weapDef->turretOverheatEffect) builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, asset->weapDef->turretOverheatEffect);
|
||||
}
|
||||
|
||||
void IWeapon::writeWeaponDef(Game::WeaponDef* def, Components::ZoneBuilder::Zone* builder, Utils::Stream* buffer)
|
||||
{
|
||||
AssertSize(Game::WeaponDef, 0x684);
|
||||
|
||||
Game::WeaponDef* dest = buffer->dest<Game::WeaponDef>();
|
||||
buffer->save(def);
|
||||
|
||||
if (def->szOverlayName)
|
||||
{
|
||||
buffer->saveString(def->szOverlayName);
|
||||
Utils::Stream::ClearPointer(&dest->szOverlayName);
|
||||
}
|
||||
|
||||
if (def->gunXModel)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
Game::XModel** pointerTable = buffer->dest<Game::XModel*>();
|
||||
buffer->saveMax(16 * sizeof(Game::XModel*));
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (!def->gunXModel[i])
|
||||
{
|
||||
pointerTable[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
pointerTable[i] = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->gunXModel[i]).model;
|
||||
}
|
||||
Utils::Stream::ClearPointer(&dest->gunXModel);
|
||||
}
|
||||
|
||||
if (def->handXModel)
|
||||
{
|
||||
dest->handXModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->handXModel).model;
|
||||
}
|
||||
|
||||
if (def->szXAnimsRightHanded)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
int* poinerTable = buffer->dest<int>();
|
||||
buffer->saveMax(37 * sizeof(char*)); // array of 37 string pointers
|
||||
for (int i = 0; i < 37; i++)
|
||||
{
|
||||
if (!def->szXAnimsRightHanded[i]) {
|
||||
poinerTable[i] = 0; // clear poiner if there isn't a string here
|
||||
continue;
|
||||
}
|
||||
|
||||
// save string if it is present
|
||||
buffer->saveString(def->szXAnimsRightHanded[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->szXAnimsRightHanded);
|
||||
}
|
||||
|
||||
if (def->szXAnimsLeftHanded)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
int* poinerTable = buffer->dest<int>();
|
||||
buffer->saveMax(37 * sizeof(char*)); // array of 37 string pointers
|
||||
for (int i = 0; i < 37; i++)
|
||||
{
|
||||
if (!def->szXAnimsLeftHanded[i]) {
|
||||
poinerTable[i] = 0; // clear poiner if there isn't a string here
|
||||
continue;
|
||||
}
|
||||
|
||||
// save string if it is present
|
||||
buffer->saveString(def->szXAnimsLeftHanded[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->szXAnimsLeftHanded);
|
||||
}
|
||||
|
||||
if (def->szModeName)
|
||||
{
|
||||
buffer->saveString(def->szModeName);
|
||||
Utils::Stream::ClearPointer(&dest->szModeName);
|
||||
}
|
||||
|
||||
if (def->notetrackSoundMapKeys)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
unsigned short* scriptStringTable = buffer->dest<unsigned short>();
|
||||
buffer->saveArray(def->notetrackSoundMapKeys, 16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
builder->mapScriptString(&scriptStringTable[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->notetrackSoundMapKeys);
|
||||
}
|
||||
|
||||
if (def->notetrackSoundMapValues)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
unsigned short* scriptStringTable = buffer->dest<unsigned short>();
|
||||
buffer->saveArray(def->notetrackSoundMapValues, 16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
builder->mapScriptString(&scriptStringTable[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->notetrackSoundMapValues);
|
||||
}
|
||||
|
||||
if (def->notetrackRumbleMapKeys)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
unsigned short* scriptStringTable = buffer->dest<unsigned short>();
|
||||
buffer->saveArray(def->notetrackRumbleMapKeys, 16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
builder->mapScriptString(&scriptStringTable[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->notetrackRumbleMapKeys);
|
||||
}
|
||||
|
||||
if (def->notetrackRumbleMapValues)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
unsigned short* scriptStringTable = buffer->dest<unsigned short>();
|
||||
buffer->saveArray(def->notetrackRumbleMapValues, 16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
builder->mapScriptString(&scriptStringTable[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->notetrackRumbleMapValues);
|
||||
}
|
||||
|
||||
if (def->viewFlashEffect)
|
||||
{
|
||||
dest->viewFlashEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->viewFlashEffect).fx;
|
||||
}
|
||||
|
||||
if (def->worldFlashEffect)
|
||||
{
|
||||
dest->worldFlashEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->worldFlashEffect).fx;
|
||||
}
|
||||
|
||||
// This is compressed because I don't want to write the same piece of code 47 times
|
||||
// TODO: verify that this is saving the aliases correctly because the old code looks wrong and this looks right but the old code worked so go figure
|
||||
Game::snd_alias_list_t ** allSounds = &def->pickupSound;
|
||||
Game::snd_alias_list_t ** allSoundsDest = &dest->pickupSound;
|
||||
for (int i = 0; i < 47; i++) {
|
||||
if (!allSounds[i]) continue;
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveMax(sizeof(Game::snd_alias_list_t*));
|
||||
buffer->saveString(allSounds[i]->aliasName);
|
||||
Utils::Stream::ClearPointer(&allSoundsDest[i]);
|
||||
}
|
||||
|
||||
if (def->bounceSound)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
int* ptrs = buffer->dest<int>();
|
||||
buffer->saveMax(37 * sizeof(Game::snd_alias_list_t*));
|
||||
|
||||
for (int i = 0; i < 37; i++)
|
||||
{
|
||||
if (!def->bounceSound[i])
|
||||
{
|
||||
ptrs[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer->saveMax(sizeof(Game::snd_alias_list_t*));
|
||||
buffer->saveString(def->bounceSound[i]->aliasName);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->bounceSound);
|
||||
}
|
||||
|
||||
if (def->viewShellEjectEffect)
|
||||
{
|
||||
dest->viewShellEjectEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->viewShellEjectEffect).fx;
|
||||
}
|
||||
|
||||
if (def->worldShellEjectEffect)
|
||||
{
|
||||
dest->worldShellEjectEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->worldShellEjectEffect).fx;
|
||||
}
|
||||
|
||||
if (def->viewLastShotEjectEffect)
|
||||
{
|
||||
dest->viewLastShotEjectEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->viewLastShotEjectEffect).fx;
|
||||
}
|
||||
|
||||
if (def->worldLastShotEjectEffect)
|
||||
{
|
||||
dest->worldLastShotEjectEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->worldLastShotEjectEffect).fx;
|
||||
}
|
||||
|
||||
if (def->reticleCenter)
|
||||
{
|
||||
dest->reticleCenter = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->reticleCenter).material;
|
||||
}
|
||||
|
||||
if (def->reticleSide)
|
||||
{
|
||||
dest->reticleSide = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->reticleSide).material;
|
||||
}
|
||||
|
||||
if (def->worldModel)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
Game::XModel** pointerTable = buffer->dest<Game::XModel*>();
|
||||
buffer->saveMax(16 * sizeof(Game::XModel*));
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
if (!def->worldModel[i])
|
||||
{
|
||||
pointerTable[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
pointerTable[i] = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->worldModel[i]).model;
|
||||
}
|
||||
Utils::Stream::ClearPointer(&dest->worldModel);
|
||||
}
|
||||
|
||||
if (def->worldClipModel)
|
||||
{
|
||||
dest->worldClipModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->worldClipModel).model;
|
||||
}
|
||||
|
||||
if (def->rocketModel)
|
||||
{
|
||||
dest->rocketModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->rocketModel).model;
|
||||
}
|
||||
|
||||
if (def->knifeModel)
|
||||
{
|
||||
dest->knifeModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->knifeModel).model;
|
||||
}
|
||||
|
||||
if (def->worldKnifeModel)
|
||||
{
|
||||
dest->worldKnifeModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->worldKnifeModel).model;
|
||||
}
|
||||
|
||||
if (def->hudIcon)
|
||||
{
|
||||
dest->hudIcon = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->hudIcon).material;
|
||||
}
|
||||
|
||||
if (def->pickupIcon)
|
||||
{
|
||||
dest->pickupIcon = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->pickupIcon).material;
|
||||
}
|
||||
|
||||
if (def->ammoCounterIcon)
|
||||
{
|
||||
dest->ammoCounterIcon = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->ammoCounterIcon).material;
|
||||
}
|
||||
|
||||
if (def->szAmmoName)
|
||||
{
|
||||
buffer->saveString(def->szAmmoName);
|
||||
Utils::Stream::ClearPointer(&dest->szAmmoName);
|
||||
}
|
||||
|
||||
if (def->szClipName)
|
||||
{
|
||||
buffer->saveString(def->szClipName);
|
||||
Utils::Stream::ClearPointer(&dest->szClipName);
|
||||
}
|
||||
|
||||
if (def->szSharedAmmoCapName)
|
||||
{
|
||||
buffer->saveString(def->szSharedAmmoCapName);
|
||||
Utils::Stream::ClearPointer(&dest->szSharedAmmoCapName);
|
||||
}
|
||||
|
||||
if (def->overlayMaterial)
|
||||
{
|
||||
dest->overlayMaterial = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->overlayMaterial).material;
|
||||
}
|
||||
|
||||
if (def->overlayMaterialLowRes)
|
||||
{
|
||||
dest->overlayMaterialLowRes = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->overlayMaterialLowRes).material;
|
||||
}
|
||||
|
||||
if (def->overlayMaterialEMP)
|
||||
{
|
||||
dest->overlayMaterialEMP = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->overlayMaterialEMP).material;
|
||||
}
|
||||
|
||||
if (def->overlayMaterialEMPLowRes)
|
||||
{
|
||||
dest->overlayMaterialEMPLowRes = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, def->overlayMaterialEMPLowRes).material;
|
||||
}
|
||||
|
||||
if (def->physCollmap)
|
||||
{
|
||||
dest->physCollmap = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_PHYSCOLLMAP, def->overlayMaterialEMPLowRes).physCollmap;
|
||||
}
|
||||
|
||||
if (def->projectileModel)
|
||||
{
|
||||
dest->projectileModel = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_XMODEL, def->projectileModel).model;
|
||||
}
|
||||
|
||||
if (def->projExplosionEffect)
|
||||
{
|
||||
dest->projExplosionEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->projExplosionEffect).fx;
|
||||
}
|
||||
|
||||
if (def->projDudEffect)
|
||||
{
|
||||
dest->projDudEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->projDudEffect).fx;
|
||||
}
|
||||
|
||||
if (def->projExplosionSound)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->projExplosionSound->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->projExplosionSound);
|
||||
}
|
||||
|
||||
if (def->projDudSound)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->projDudSound->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->projDudSound);
|
||||
}
|
||||
|
||||
if (def->parallelBounce)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(def->parallelBounce, 31);
|
||||
Utils::Stream::ClearPointer(&dest->parallelBounce);
|
||||
}
|
||||
|
||||
if (def->perpendicularBounce)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(def->perpendicularBounce, 31);
|
||||
Utils::Stream::ClearPointer(&dest->perpendicularBounce);
|
||||
}
|
||||
|
||||
if (def->projTrailEffect)
|
||||
{
|
||||
dest->projTrailEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->projTrailEffect).fx;
|
||||
}
|
||||
|
||||
if (def->projBeaconEffect)
|
||||
{
|
||||
dest->projBeaconEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->projBeaconEffect).fx;
|
||||
}
|
||||
|
||||
if (def->projIgnitionEffect)
|
||||
{
|
||||
dest->projIgnitionEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->projIgnitionEffect).fx;
|
||||
}
|
||||
|
||||
if (def->projIgnitionSound)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->projIgnitionSound->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->projIgnitionSound);
|
||||
}
|
||||
|
||||
if (def->accuracyGraphName[0])
|
||||
{
|
||||
buffer->saveString(def->accuracyGraphName[0]);
|
||||
Utils::Stream::ClearPointer(&dest->accuracyGraphName[0]);
|
||||
}
|
||||
|
||||
if (def->originalAccuracyGraphKnots[0])
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(def->originalAccuracyGraphKnots[0], def->originalAccuracyGraphKnotCount[0]);
|
||||
Utils::Stream::ClearPointer(&dest->originalAccuracyGraphKnots[0]);
|
||||
}
|
||||
|
||||
if (def->accuracyGraphName[1])
|
||||
{
|
||||
buffer->saveString(def->accuracyGraphName[1]);
|
||||
Utils::Stream::ClearPointer(&dest->accuracyGraphName[1]);
|
||||
}
|
||||
|
||||
if (def->originalAccuracyGraphKnots[1])
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(def->originalAccuracyGraphKnots[1], def->originalAccuracyGraphKnotCount[1]);
|
||||
Utils::Stream::ClearPointer(&dest->originalAccuracyGraphKnots[1]);
|
||||
}
|
||||
|
||||
if (def->szUseHintString)
|
||||
{
|
||||
buffer->saveString(def->szUseHintString);
|
||||
Utils::Stream::ClearPointer(&dest->szUseHintString);
|
||||
}
|
||||
|
||||
if (def->dropHintString)
|
||||
{
|
||||
buffer->saveString(def->dropHintString);
|
||||
Utils::Stream::ClearPointer(&dest->dropHintString);
|
||||
}
|
||||
|
||||
if (def->szScript)
|
||||
{
|
||||
buffer->saveString(def->szScript);
|
||||
Utils::Stream::ClearPointer(&dest->szScript);
|
||||
}
|
||||
|
||||
if (def->locationDamageMultipliers)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(def->locationDamageMultipliers, 20);
|
||||
Utils::Stream::ClearPointer(&dest->locationDamageMultipliers);
|
||||
}
|
||||
|
||||
if (def->fireRumble)
|
||||
{
|
||||
buffer->saveString(def->fireRumble);
|
||||
Utils::Stream::ClearPointer(&dest->fireRumble);
|
||||
}
|
||||
|
||||
if (def->meleeImpactRumble)
|
||||
{
|
||||
buffer->saveString(def->meleeImpactRumble);
|
||||
Utils::Stream::ClearPointer(&dest->meleeImpactRumble);
|
||||
}
|
||||
|
||||
if (def->tracerType)
|
||||
{
|
||||
dest->tracerType = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_TRACER, def->tracerType).tracerDef;
|
||||
}
|
||||
|
||||
if (def->turretOverheatSound)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->turretOverheatSound->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->turretOverheatSound);
|
||||
}
|
||||
|
||||
if (def->turretOverheatEffect)
|
||||
{
|
||||
dest->turretOverheatEffect = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_FX, def->turretOverheatEffect).fx;
|
||||
}
|
||||
|
||||
if (def->turretBarrelSpinRumble)
|
||||
{
|
||||
buffer->saveString(def->turretBarrelSpinRumble);
|
||||
Utils::Stream::ClearPointer(&dest->turretBarrelSpinRumble);
|
||||
}
|
||||
|
||||
if (def->turretBarrelSpinMaxSnd)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->turretBarrelSpinMaxSnd->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->turretBarrelSpinMaxSnd);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!def->turretBarrelSpinUpSnd[i]) continue;
|
||||
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->turretBarrelSpinUpSnd[i]->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->turretBarrelSpinUpSnd[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (!def->turretBarrelSpinDownSnd[i]) continue;
|
||||
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->turretBarrelSpinDownSnd[i]->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->turretBarrelSpinDownSnd[i]);
|
||||
}
|
||||
|
||||
if (def->missileConeSoundAlias)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->missileConeSoundAlias->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->missileConeSoundAlias);
|
||||
}
|
||||
|
||||
if (def->missileConeSoundAliasAtBase)
|
||||
{
|
||||
buffer->saveMax(4);
|
||||
buffer->saveString(def->missileConeSoundAliasAtBase->aliasName);
|
||||
Utils::Stream::ClearPointer(&dest->missileConeSoundAliasAtBase);
|
||||
}
|
||||
}
|
||||
|
||||
void IWeapon::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
|
||||
{
|
||||
AssertSize(Game::WeaponCompleteDef, 0x74);
|
||||
|
||||
Utils::Stream* buffer = builder->getBuffer();
|
||||
Game::WeaponCompleteDef* asset = header.weapon;
|
||||
Game::WeaponCompleteDef* dest = buffer->dest<Game::WeaponCompleteDef>();
|
||||
buffer->save(asset);
|
||||
|
||||
buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL);
|
||||
|
||||
if (asset->szInternalName)
|
||||
{
|
||||
buffer->saveString(builder->getAssetName(this->getType(), asset->szInternalName));
|
||||
Utils::Stream::ClearPointer(&dest->szInternalName);
|
||||
}
|
||||
|
||||
if (asset->weapDef)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
IWeapon::writeWeaponDef(asset->weapDef, builder, buffer);
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->weapDef);
|
||||
}
|
||||
|
||||
if (asset->szDisplayName)
|
||||
{
|
||||
buffer->saveString(asset->szDisplayName);
|
||||
Utils::Stream::ClearPointer(&dest->szDisplayName);
|
||||
}
|
||||
|
||||
if (asset->hideTags)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_2);
|
||||
unsigned short* scriptStringTable = buffer->dest<unsigned short>();
|
||||
buffer->saveArray(asset->hideTags, 32);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
builder->mapScriptString(&scriptStringTable[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->hideTags);
|
||||
}
|
||||
|
||||
if (asset->szXAnims)
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
int* poinerTable = buffer->dest<int>();
|
||||
buffer->saveMax(37 * sizeof(char*)); // array of 37 string pointers
|
||||
for (int i = 0; i < 37; i++)
|
||||
{
|
||||
if (!asset->szXAnims[i]) {
|
||||
poinerTable[i] = 0; // clear poiner if there isn't a string here
|
||||
continue;
|
||||
}
|
||||
|
||||
// save string if it is present
|
||||
buffer->saveString(asset->szXAnims[i]);
|
||||
}
|
||||
|
||||
Utils::Stream::ClearPointer(&dest->szXAnims);
|
||||
}
|
||||
|
||||
if (asset->szAltWeaponName)
|
||||
{
|
||||
buffer->saveString(asset->szAltWeaponName);
|
||||
Utils::Stream::ClearPointer(&dest->szAltWeaponName);
|
||||
}
|
||||
|
||||
if (asset->killIcon)
|
||||
{
|
||||
dest->killIcon = builder->saveSubAsset(Game::ASSET_TYPE_MATERIAL, asset->killIcon).material;
|
||||
}
|
||||
|
||||
if (asset->dpadIcon)
|
||||
{
|
||||
dest->dpadIcon = builder->saveSubAsset(Game::ASSET_TYPE_MATERIAL, asset->dpadIcon).material;
|
||||
}
|
||||
|
||||
if (asset->accuracyGraphKnots[0])
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(asset->accuracyGraphKnots[0], asset->accuracyGraphKnotCount[0]);
|
||||
Utils::Stream::ClearPointer(&dest->accuracyGraphKnots[0]);
|
||||
}
|
||||
|
||||
if (asset->accuracyGraphKnots[1])
|
||||
{
|
||||
buffer->align(Utils::Stream::ALIGN_4);
|
||||
buffer->saveArray(asset->accuracyGraphKnots[1], asset->accuracyGraphKnotCount[1]);
|
||||
Utils::Stream::ClearPointer(&dest->accuracyGraphKnots[1]);
|
||||
}
|
||||
|
||||
buffer->popBlock();
|
||||
}
|
||||
}
|
17
src/Components/Modules/AssetInterfaces/IWeapon.hpp
Normal file
17
src/Components/Modules/AssetInterfaces/IWeapon.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace Assets
|
||||
{
|
||||
class IWeapon : public Components::AssetHandler::IAsset
|
||||
{
|
||||
public:
|
||||
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_WEAPON; };
|
||||
|
||||
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
|
||||
virtual void load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder) override;
|
||||
|
||||
private:
|
||||
void writeWeaponDef(Game::WeaponDef* def, Components::ZoneBuilder::Zone* builder, Utils::Stream* buffer);
|
||||
};
|
||||
}
|
@ -18,6 +18,7 @@ namespace Components
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilterStub(LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
|
||||
static __declspec(noreturn) void ErrorLongJmp(jmp_buf _Buf, int _Value);
|
||||
static __declspec(noreturn) void LongJmp(jmp_buf _Buf, int _Value);
|
||||
static void DebugMinidumpCommand(Command::Params*);
|
||||
|
||||
static int MiniDumpType;
|
||||
static Utils::Hook SetFilterHook;
|
||||
|
@ -410,6 +410,8 @@ namespace Components
|
||||
}
|
||||
#endif
|
||||
|
||||
Utils::IO::WriteFile("uncompressed", zoneBuffer);
|
||||
|
||||
zoneBuffer = Utils::Compression::ZLib::Compress(zoneBuffer);
|
||||
outBuffer.append(zoneBuffer);
|
||||
|
||||
@ -704,21 +706,20 @@ namespace Components
|
||||
|
||||
if (zoneIndex > 0)
|
||||
{
|
||||
Game::DB_EnumXAssetEntries(type, [&](Game::XAssetEntry* entry)
|
||||
{
|
||||
if (!header.data && entry->zoneIndex == zoneIndex && Game::DB_GetXAssetName(&entry->asset) == name)
|
||||
{
|
||||
// Allocate an empty asset (filled with zeros)
|
||||
header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]());
|
||||
Game::XAssetEntry* entry = Game::DB_FindXAssetEntry(type, name.data());
|
||||
|
||||
// Set the name to the original name, so it can be stored
|
||||
Game::DB_SetXAssetNameHandlers[type](&header, name.data());
|
||||
AssetHandler::StoreTemporaryAsset(type, header);
|
||||
if (entry->zoneIndex == zoneIndex)
|
||||
{
|
||||
// Allocate an empty asset (filled with zeros)
|
||||
header.data = builder->getAllocator()->allocate(Game::DB_GetXAssetSizeHandlers[type]());
|
||||
|
||||
// Set the name to the empty name
|
||||
Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name));
|
||||
}
|
||||
}, true, true);
|
||||
// Set the name to the original name, so it can be stored
|
||||
Game::DB_SetXAssetNameHandlers[type](&header, name.data());
|
||||
AssetHandler::StoreTemporaryAsset(type, header);
|
||||
|
||||
// Set the name to the empty name
|
||||
Game::DB_SetXAssetNameHandlers[type](&header, builder->getAllocator()->duplicateString("," + name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1109,12 +1110,29 @@ namespace Components
|
||||
if (!ZoneBuilder::TraceZone.empty() && ZoneBuilder::TraceZone == FastFiles::Current())
|
||||
{
|
||||
ZoneBuilder::TraceAssets.push_back({ type, name });
|
||||
OutputDebugStringA((name + "\n").data());
|
||||
}
|
||||
});
|
||||
|
||||
Command::Add("verifyzone", [](Command::Params* params)
|
||||
{
|
||||
if (params->length() < 2) return;
|
||||
/*
|
||||
Utils::Hook(0x4AE9C2, [] {
|
||||
Game::WeaponCompleteDef** varPtr = (Game::WeaponCompleteDef**)0x112A9F4;
|
||||
Game::WeaponCompleteDef* var = *varPtr;
|
||||
OutputDebugStringA("");
|
||||
Utils::Hook::Call<void()>(0x4D1D60)(); // DB_PopStreamPos
|
||||
}, HOOK_JUMP).install()->quick();
|
||||
|
||||
|
||||
Utils::Hook(0x4AE9B4, [] {
|
||||
Game::WeaponCompleteDef** varPtr = (Game::WeaponCompleteDef**)0x112A9F4;
|
||||
Game::WeaponCompleteDef* var = *varPtr;
|
||||
OutputDebugStringA("");
|
||||
Utils::Hook::Call<void()>(0x4D1D60)(); // DB_PopStreamPos
|
||||
}, HOOK_JUMP).install()->quick();
|
||||
*/
|
||||
|
||||
std::string zone = params->get(1);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user