[ZoneBuilder] Add interface for FxEffectDef

Soundaliases are missing, so the game will complain about missing sounds!
This commit is contained in:
momo5502 2016-11-28 21:18:14 +01:00
parent c360d62b40
commit d596cdc97b
5 changed files with 365 additions and 2 deletions

View File

@ -391,6 +391,7 @@ namespace Components
AssetHandler::RegisterInterface(new Assets::IMaterial());
AssetHandler::RegisterInterface(new Assets::IPhysPreset());
AssetHandler::RegisterInterface(new Assets::IXAnimParts());
AssetHandler::RegisterInterface(new Assets::IFxEffectDef());
AssetHandler::RegisterInterface(new Assets::IPhysCollmap());
AssetHandler::RegisterInterface(new Assets::IStringTable());
//AssetHandler::RegisterInterface(new Assets::IXModelSurfs());

View File

@ -75,6 +75,7 @@ namespace Components
#include "AssetInterfaces\IMaterial.hpp"
#include "AssetInterfaces\IPhysPreset.hpp"
#include "AssetInterfaces\IXAnimParts.hpp"
#include "AssetInterfaces\IFxEffectDef.hpp"
#include "AssetInterfaces\IPhysCollmap.hpp"
#include "AssetInterfaces\IStringTable.hpp"
#include "AssetInterfaces\IXModelSurfs.hpp"

View File

@ -0,0 +1,343 @@
#include <STDInclude.hpp>
namespace Assets
{
void IFxEffectDef::markFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder)
{
switch (elemType)
{
case 7:
{
if (visuals->xmodel)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel->name);
}
break;
}
case 8:
case 9:
break;
case 0xA:
{
// TODO: Load sound here as soon as soundaliases are supported!
break;
}
case 0xC:
{
if (visuals->effectDef)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, visuals->effectDef->name);
}
break;
}
default:
{
if (visuals->material)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material->name);
}
break;
}
}
}
void IFxEffectDef::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Game::FxEffectDef* asset = header.fx;
for (int i = 0; i < (asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); ++i)
{
Game::FxElemDef* elemDef = &asset->elemDefs[i];
{
if (elemDef->elemType == 11)
{
if (elemDef->visuals.markArray)
{
for (char j = 0; j < elemDef->visualCount; ++j)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[0]->name);
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[1]->name);
}
}
}
else if (elemDef->visualCount > 1)
{
if (elemDef->visuals.array)
{
for (char j = 0; j < elemDef->visualCount; ++j)
{
this->markFxElemVisuals(&elemDef->visuals.array[j], elemDef->elemType, builder);
}
}
}
else
{
this->markFxElemVisuals(&elemDef->visuals.instance, elemDef->elemType, builder);
}
}
if (elemDef->effectOnImpact)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnImpact->name);
}
if (elemDef->effectOnDeath)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectOnDeath->name);
}
if (elemDef->effectEmitted)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_FX, elemDef->effectEmitted->name);
}
}
}
void IFxEffectDef::saveFxElemVisuals(Game::FxElemVisuals* visuals, Game::FxElemVisuals* destVisuals, char elemType, Components::ZoneBuilder::Zone* builder)
{
Utils::Stream* buffer = builder->getBuffer();
switch (elemType)
{
case 7:
{
if (visuals->xmodel)
{
destVisuals->xmodel = builder->requireAsset(Game::XAssetType::ASSET_TYPE_XMODEL, visuals->xmodel->name).model;
}
break;
}
case 8:
case 9:
break;
case 0xA:
{
if (visuals->soundName)
{
buffer->saveString(visuals->soundName);
Utils::Stream::ClearPointer(&destVisuals->soundName);
}
break;
}
case 0xC:
{
if (visuals->effectDef)
{
buffer->saveString(visuals->effectDef->name);
Utils::Stream::ClearPointer(&destVisuals->effectDef);
}
break;
}
default:
{
if (visuals->material)
{
destVisuals->material = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, visuals->material->name).material;
}
break;
}
}
}
void IFxEffectDef::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
AssertSize(Game::FxEffectDef, 32);
Utils::Stream* buffer = builder->getBuffer();
Game::FxEffectDef* asset = header.fx;
Game::FxEffectDef* dest = buffer->dest<Game::FxEffectDef>();
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->elemDefs)
{
AssertSize(Game::FxElemDef, 252);
buffer->align(Utils::Stream::ALIGN_4);
Game::FxElemDef* destElemDefs = buffer->dest<Game::FxElemDef>();
buffer->saveArray(asset->elemDefs, asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot);
for (int i = 0; i < (asset->elemDefCountEmission + asset->elemDefCountLooping + asset->elemDefCountOneShot); ++i)
{
Game::FxElemDef* destElemDef = &destElemDefs[i];
Game::FxElemDef* elemDef = &asset->elemDefs[i];
if (elemDef->velSamples)
{
AssertSize(Game::FxElemVelStateSample, 96);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(elemDef->velSamples, elemDef->velIntervalCount + 1);
Utils::Stream::ClearPointer(&destElemDef->velSamples);
}
if (elemDef->visSamples)
{
AssertSize(Game::FxElemVisStateSample, 48);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(elemDef->visSamples, elemDef->visStateIntervalCount + 1);
Utils::Stream::ClearPointer(&destElemDef->visSamples);
}
// Save_FxElemDefVisuals
{
if (elemDef->elemType == 11)
{
if (elemDef->visuals.markArray)
{
AssertSize(Game::FxElemMarkVisuals, 8);
buffer->align(Utils::Stream::ALIGN_4);
Game::FxElemMarkVisuals* destMarkArray = buffer->dest<Game::FxElemMarkVisuals>();
buffer->saveArray(elemDef->visuals.markArray, elemDef->visualCount);
for (char j = 0; j < elemDef->visualCount; ++j)
{
if (elemDef->visuals.markArray[j].data[0])
{
destMarkArray[j].data[0] = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[0]->name).material;
}
if (elemDef->visuals.markArray[j].data[1])
{
destMarkArray[j].data[1] = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, elemDef->visuals.markArray[j].data[1]->name).material;
}
}
Utils::Stream::ClearPointer(&destElemDef->visuals.markArray);
}
}
else if(elemDef->visualCount > 1)
{
if (elemDef->visuals.array)
{
AssertSize(Game::FxElemVisuals, 4);
buffer->align(Utils::Stream::ALIGN_4);
Game::FxElemVisuals* destVisuals = buffer->dest<Game::FxElemVisuals>();
buffer->saveArray(elemDef->visuals.array, elemDef->visualCount);
for (char j = 0; j < elemDef->visualCount; ++j)
{
this->saveFxElemVisuals(&elemDef->visuals.array[j], &destVisuals[j], elemDef->elemType, builder);
}
Utils::Stream::ClearPointer(&destElemDef->visuals.array);
}
}
else
{
this->saveFxElemVisuals(&elemDef->visuals.instance, &destElemDef->visuals.instance, elemDef->elemType, builder);
}
}
if (elemDef->effectOnImpact)
{
buffer->saveString(elemDef->effectOnImpact->name);
Utils::Stream::ClearPointer(&destElemDef->effectOnImpact);
}
if (elemDef->effectOnDeath)
{
buffer->saveString(elemDef->effectOnDeath->name);
Utils::Stream::ClearPointer(&destElemDef->effectOnDeath);
}
if (elemDef->effectEmitted)
{
buffer->saveString(elemDef->effectEmitted->name);
Utils::Stream::ClearPointer(&destElemDef->effectEmitted);
}
// Save_FxElemExtendedDefPtr
{
AssertSize(Game::FxElemExtendedDef, 4);
if (elemDef->elemType == 3)
{
// Save_FxTrailDef
{
if (elemDef->extendedDef.trailDef)
{
AssertSize(Game::FxTrailDef, 36);
buffer->align(Utils::Stream::ALIGN_4);
Game::FxTrailDef* trailDef = elemDef->extendedDef.trailDef;
Game::FxTrailDef* destTrailDef = buffer->dest<Game::FxTrailDef>();
buffer->save(trailDef);
if (trailDef->verts)
{
AssertSize(Game::FxTrailVertex, 20);
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(trailDef->verts, trailDef->vertCount);
Utils::Stream::ClearPointer(&destTrailDef->verts);
}
if (trailDef->inds)
{
buffer->align(Utils::Stream::ALIGN_2);
buffer->saveArray(trailDef->inds, trailDef->indCount);
Utils::Stream::ClearPointer(&destTrailDef->inds);
}
Utils::Stream::ClearPointer(&destElemDef->extendedDef.trailDef);
}
}
}
else if (elemDef->elemType == 6)
{
if (elemDef->extendedDef.sparkFountain)
{
AssertSize(Game::FxSparkFountain, 52);
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(elemDef->extendedDef.sparkFountain);
Utils::Stream::ClearPointer(&destElemDef->extendedDef.sparkFountain);
}
}
else
{
if (elemDef->extendedDef.unknownBytes)
{
buffer->save(elemDef->extendedDef.unknownBytes);
Utils::Stream::ClearPointer(&destElemDef->extendedDef.unknownBytes);
}
}
}
}
Utils::Stream::ClearPointer(&dest->elemDefs);
}
buffer->popBlock();
}
}

View File

@ -0,0 +1,15 @@
namespace Assets
{
class IFxEffectDef : public Components::AssetHandler::IAsset
{
public:
virtual Game::XAssetType getType() override { return Game::XAssetType::ASSET_TYPE_FX; };
virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override;
private:
void markFxElemVisuals(Game::FxElemVisuals* visuals, char elemType, Components::ZoneBuilder::Zone* builder);
void saveFxElemVisuals(Game::FxElemVisuals* visuals, Game::FxElemVisuals* destVisuals, char elemType, Components::ZoneBuilder::Zone* builder);
};
}

View File

@ -1921,9 +1921,12 @@ namespace Game
struct FxTrailVertex
{
/*
float pos[2];
float normal[2];
float texCoord[2];
*/
char pad[20];
};
struct FxTrailDef
@ -1956,7 +1959,7 @@ namespace Game
float sparkFountainBoostFactor;
};
union unknownFxUnion
union FxElemExtendedDef
{
char *unknownBytes;
FxSparkFountain *sparkFountain;
@ -2037,7 +2040,7 @@ namespace Game
FxEffectDefRef *effectEmitted;
FxFloatRange emitDist;
FxFloatRange emitDistVariance;
unknownFxUnion *trailDef;
FxElemExtendedDef extendedDef;
//If elemType == 3, then use trailDef
//If elemType == 6, then use sparkFountain
//If elemType != 3 && elemType != 6 use unknownBytes (size = 1)