#include namespace Assets { void IFxWorld::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { AssertSize(Game::FxWorld, 116); Utils::Stream* buffer = builder->getBuffer(); SAVE_LOG_ENTER("FxWorld"); Game::FxWorld* asset = header.fxWorld; Game::FxWorld* dest = buffer->dest(); 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); } // saveFxGlassSystem { AssertSize(Game::FxGlassSystem, 112); if(asset->glassSys.defs) { AssertSize(Game::FxGlassDef, 36); buffer->align(Utils::Stream::ALIGN_4); Game::FxGlassDef* glassDefTable = buffer->dest(); buffer->saveArray(asset->glassSys.defs, asset->glassSys.defCount); for (unsigned int i = 0; i < asset->glassSys.defCount; ++i) { Game::FxGlassDef* glassDef = &asset->glassSys.defs[i]; Game::FxGlassDef* destGlassDef = &glassDefTable[i]; if (glassDef->physPreset) { destGlassDef->physPreset = builder->requireAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, glassDef->physPreset->name).physPreset; } if (glassDef->material) { destGlassDef->material = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, glassDef->material->name).material; } if (glassDef->materialShattered) { destGlassDef->materialShattered = builder->requireAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, glassDef->materialShattered->name).material; } } } buffer->pushBlock(Game::XFILE_BLOCK_RUNTIME); if (asset->glassSys.piecePlaces) { AssertSize(Game::FxGlassPiecePlace, 32); buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.piecePlaces, asset->glassSys.pieceLimit); Utils::Stream::ClearPointer(&dest->glassSys.piecePlaces); } if (asset->glassSys.pieceStates) { AssertSize(Game::FxGlassPieceState, 32); buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.pieceStates, asset->glassSys.pieceLimit); Utils::Stream::ClearPointer(&dest->glassSys.pieceStates); } if (asset->glassSys.pieceDynamics) { AssertSize(Game::FxGlassPieceDynamics, 36); buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.pieceDynamics, asset->glassSys.pieceLimit); Utils::Stream::ClearPointer(&dest->glassSys.pieceDynamics); } if (asset->glassSys.geoData) { AssertSize(Game::FxGlassGeometryData, 4); buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.geoData, asset->glassSys.geoDataLimit); Utils::Stream::ClearPointer(&dest->glassSys.geoData); } if (asset->glassSys.isInUse) { buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.isInUse, asset->glassSys.pieceWordCount); Utils::Stream::ClearPointer(&dest->glassSys.isInUse); } if (asset->glassSys.cellBits) { buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.cellBits, asset->glassSys.pieceWordCount * asset->glassSys.cellCount); Utils::Stream::ClearPointer(&dest->glassSys.cellBits); } if (asset->glassSys.visData) { buffer->align(Utils::Stream::ALIGN_16); buffer->save(asset->glassSys.visData, 1, (asset->glassSys.pieceLimit + 15) & 0xFFFFFFF0); Utils::Stream::ClearPointer(&dest->glassSys.visData); } if (asset->glassSys.linkOrg) { buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.linkOrg, asset->glassSys.pieceLimit); Utils::Stream::ClearPointer(&dest->glassSys.linkOrg); } if (asset->glassSys.halfThickness) { buffer->align(Utils::Stream::ALIGN_16); buffer->save(asset->glassSys.halfThickness, 1, ((4 * asset->glassSys.pieceLimit) + 12) & 0xFFFFFFF0); Utils::Stream::ClearPointer(&dest->glassSys.halfThickness); } buffer->popBlock(); if (asset->glassSys.lightingHandles) { buffer->align(Utils::Stream::ALIGN_2); buffer->saveArray(asset->glassSys.lightingHandles, asset->glassSys.initPieceCount); Utils::Stream::ClearPointer(&dest->glassSys.lightingHandles); } if (asset->glassSys.initPieceStates) { AssertSize(Game::FxGlassInitPieceState, 52); buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.initPieceStates, asset->glassSys.initPieceCount); Utils::Stream::ClearPointer(&dest->glassSys.initPieceStates); } if (asset->glassSys.initGeoData) { buffer->align(Utils::Stream::ALIGN_4); buffer->saveArray(asset->glassSys.initGeoData, asset->glassSys.initGeoDataCount); Utils::Stream::ClearPointer(&dest->glassSys.initGeoData); } } } void IFxWorld::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { Game::FxWorld* asset = header.fxWorld; if (asset->glassSys.defs) { for (unsigned int i = 0; i < asset->glassSys.defCount; ++i) { builder->loadAsset(Game::XAssetType::ASSET_TYPE_PHYSPRESET, asset->glassSys.defs[i].physPreset->name); builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].material->name); builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->glassSys.defs[i].materialShattered->name); } } } void IFxWorld::load(Game::XAssetHeader* /*header*/, std::string name, Components::ZoneBuilder::Zone* /*builder*/) { Game::FxWorld* map = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_FX_MAP, name.data()).fxWorld; if (map) return; Components::Logger::Error("Missing fx_map %s... you can't make them yet you idiot.", name.data()); } }