diff --git a/src/Components/Modules/AssetInterfaces/IComWorld.cpp b/src/Components/Modules/AssetInterfaces/IComWorld.cpp index 044456b2..bf81b683 100644 --- a/src/Components/Modules/AssetInterfaces/IComWorld.cpp +++ b/src/Components/Modules/AssetInterfaces/IComWorld.cpp @@ -1,18 +1,69 @@ #include "STDInclude.hpp" +#define IW4X_COMMAP_VERSION 0 + namespace Assets { + void IComWorld::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) + { + Utils::String::Replace(name, "maps/mp/", ""); + Utils::String::Replace(name, ".d3dbsp", ""); + + Components::FileSystem::File mapFile(Utils::String::VA("comworld/%s.iw4xComWorld", name.data())); + + if (mapFile.exists()) + { + Utils::Stream::Reader reader(builder->getAllocator(), mapFile.getBuffer()); + + __int64 magic = reader.read<__int64>(); + if (std::memcmp(&magic, "IW4xComW", 8)) + { + Components::Logger::Error("Reading comworld '%s' failed, header is invalid!", name.data()); + } + + int version = reader.read(); + if (version != IW4X_COMMAP_VERSION) + { + Components::Logger::Error("Reading comworld '%s' failed, expected version is %d, but it was %d!", name.data(), IW4X_COMMAP_VERSION, version); + } + + Game::ComWorld* asset = reader.readObject(); + header->comWorld = asset; + + if (asset->name) + { + asset->name = reader.readCString(); + } + + if (asset->primaryLights) + { + asset->primaryLights = reader.readArray(asset->primaryLightCount); + + for (unsigned int i = 0; i < asset->primaryLightCount; ++i) + { + Game::ComPrimaryLight* light = &asset->primaryLights[i]; + + if (light->defName) + { + light->defName = reader.readCString(); + Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_LIGHT_DEF, light->defName, builder); + } + } + } + } + } + void IComWorld::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { Game::ComWorld* asset = header.comWorld; - if (asset->lights) + if (asset->primaryLights) { - for (int i = 0; i < asset->lightCount; ++i) + for (unsigned int i = 0; i < asset->primaryLightCount; ++i) { - if (asset->lights[i].name) + if (asset->primaryLights[i].defName) { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_LIGHT_DEF, std::string(asset->lights[i].name), false); + builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_LIGHT_DEF, asset->primaryLights[i].defName, false); } } } @@ -35,27 +86,27 @@ namespace Assets Utils::Stream::ClearPointer(&dest->name); } - if (asset->lights) + if (asset->primaryLights) { AssertSize(Game::ComPrimaryLight, 68); buffer->align(Utils::Stream::ALIGN_4); Game::ComPrimaryLight* destLights = buffer->dest(); - buffer->saveArray(asset->lights, asset->lightCount); + buffer->saveArray(asset->primaryLights, asset->primaryLightCount); - for (int i = 0; i < asset->lightCount; ++i) + for (unsigned int i = 0; i < asset->primaryLightCount; ++i) { Game::ComPrimaryLight* destLight = &destLights[i]; - Game::ComPrimaryLight* light = &asset->lights[i]; + Game::ComPrimaryLight* light = &asset->primaryLights[i]; - if (light->name) + if (light->defName) { - buffer->saveString(light->name); - Utils::Stream::ClearPointer(&destLight->name); + buffer->saveString(light->defName); + Utils::Stream::ClearPointer(&destLight->defName); } } - Utils::Stream::ClearPointer(&dest->lights); + Utils::Stream::ClearPointer(&dest->primaryLights); } buffer->popBlock(); diff --git a/src/Components/Modules/AssetInterfaces/IComWorld.hpp b/src/Components/Modules/AssetInterfaces/IComWorld.hpp index 10f67fb2..a1ad9ccc 100644 --- a/src/Components/Modules/AssetInterfaces/IComWorld.hpp +++ b/src/Components/Modules/AssetInterfaces/IComWorld.hpp @@ -9,5 +9,6 @@ namespace Assets 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, std::string name, Components::ZoneBuilder::Zone* builder) override; }; } diff --git a/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp b/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp index 4fb7c869..fc7aefdd 100644 --- a/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp +++ b/src/Components/Modules/AssetInterfaces/IFxEffectDef.cpp @@ -97,7 +97,7 @@ namespace Assets case 0xA: { - builder->loadAsset(Game::XAssetType::ASSET_TYPE_SOUND, std::string(visuals->soundName), false); + builder->loadAssetByName(Game::XAssetType::ASSET_TYPE_SOUND, visuals->soundName, false); break; } diff --git a/src/Components/Modules/AssetInterfaces/IGfxLightDef.cpp b/src/Components/Modules/AssetInterfaces/IGfxLightDef.cpp index 0bc88d30..5daec41d 100644 --- a/src/Components/Modules/AssetInterfaces/IGfxLightDef.cpp +++ b/src/Components/Modules/AssetInterfaces/IGfxLightDef.cpp @@ -1,7 +1,45 @@ #include "STDInclude.hpp" +#define IW4X_LIGHT_VERSION "0" + namespace Assets { + void IGfxLightDef::load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File mapFile(Utils::String::VA("lights/%s.iw4xLight", name.data())); + + if (mapFile.exists()) + { + Utils::Stream::Reader reader(builder->getAllocator(), mapFile.getBuffer()); + + char* magic = reader.readArray(7); + if (std::memcmp(magic, "IW4xLit", 7)) + { + Components::Logger::Error(0, "Reading light '%s' failed, header is invalid!", name.data()); + } + + std::string version; + version.push_back(reader.read()); + if (version != IW4X_LIGHT_VERSION) + { + Components::Logger::Error("Reading light '%s' failed, expected version is %d, but it was %d!", name.data(), atoi(IW4X_LIGHT_VERSION), atoi(version.data())); + } + + Game::GfxLightDef* asset = reader.readObject(); + header->lightDef = asset; + + if (asset->name) + { + asset->name = reader.readCString(); + } + + if (asset->attenuation.image) + { + asset->attenuation.image = Components::AssetHandler::FindAssetForZone(Game::XAssetType::ASSET_TYPE_IMAGE, reader.readString().data(), builder).image; + } + } + } + void IGfxLightDef::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) { Game::GfxLightDef* asset = header.lightDef; diff --git a/src/Components/Modules/AssetInterfaces/IGfxLightDef.hpp b/src/Components/Modules/AssetInterfaces/IGfxLightDef.hpp index dc197664..485333d7 100644 --- a/src/Components/Modules/AssetInterfaces/IGfxLightDef.hpp +++ b/src/Components/Modules/AssetInterfaces/IGfxLightDef.hpp @@ -9,5 +9,6 @@ namespace Assets virtual void mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; virtual void save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) override; + virtual void load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) override; }; } diff --git a/src/Components/Modules/ZoneBuilder.cpp b/src/Components/Modules/ZoneBuilder.cpp index af666b72..aeb0c60e 100644 --- a/src/Components/Modules/ZoneBuilder.cpp +++ b/src/Components/Modules/ZoneBuilder.cpp @@ -162,7 +162,7 @@ namespace Components } } - if (!this->loadAsset(this->dataMap.getElementAt(i, 0), this->dataMap.getElementAt(i, 1), false)) + if (!this->loadAssetByName(this->dataMap.getElementAt(i, 0), this->dataMap.getElementAt(i, 1), false)) { return false; } @@ -178,16 +178,16 @@ namespace Components const char* name = Game::DB_GetXAssetName(&asset); - if (name) return this->loadAsset(type, std::string(name), isSubAsset); + if (name) return this->loadAssetByName(type, std::string(name), isSubAsset); else return false; } - bool ZoneBuilder::Zone::loadAsset(Game::XAssetType type, std::string name, bool isSubAsset) + bool ZoneBuilder::Zone::loadAssetByName(Game::XAssetType type, std::string name, bool isSubAsset) { - return this->loadAsset(Game::DB_GetXAssetTypeName(type), name, isSubAsset); + return this->loadAssetByName(Game::DB_GetXAssetTypeName(type), name, isSubAsset); } - bool ZoneBuilder::Zone::loadAsset(std::string typeName, std::string name, bool isSubAsset) + bool ZoneBuilder::Zone::loadAssetByName(std::string typeName, std::string name, bool isSubAsset) { Game::XAssetType type = Game::DB_GetXAssetNameType(typeName.data()); diff --git a/src/Components/Modules/ZoneBuilder.hpp b/src/Components/Modules/ZoneBuilder.hpp index 3d83be85..a6197074 100644 --- a/src/Components/Modules/ZoneBuilder.hpp +++ b/src/Components/Modules/ZoneBuilder.hpp @@ -35,7 +35,7 @@ namespace Components bool hasAlias(Game::XAsset asset); Game::XAssetHeader saveSubAsset(Game::XAssetType type, void* ptr); - bool loadAsset(Game::XAssetType type, std::string name, bool isSubAsset = true); + bool loadAssetByName(Game::XAssetType type, std::string name, bool isSubAsset = true); bool loadAsset(Game::XAssetType type, void* data, bool isSubAsset = true); int addScriptString(unsigned short gameIndex); @@ -55,7 +55,7 @@ namespace Components void loadFastFiles(); bool loadAssets(); - bool loadAsset(std::string type, std::string name, bool isSubAsset = true); + bool loadAssetByName(std::string type, std::string name, bool isSubAsset = true); void saveData(); void writeZone(); diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp index 81d5eca8..0d7b2804 100644 --- a/src/Game/Structs.hpp +++ b/src/Game/Structs.hpp @@ -3367,15 +3367,15 @@ namespace Game float cosHalfFovExpanded; float rotationLimit; float translationLimit; - char* name; + const char *defName; }; struct ComWorld { - char *name; + const char *name; int isInUse; - int lightCount; - ComPrimaryLight* lights; + unsigned int primaryLightCount; + ComPrimaryLight *primaryLights; }; #pragma pack(push, 4)