diff --git a/deps/json11 b/deps/json11 index df1fdbfd..a20878aa 160000 --- a/deps/json11 +++ b/deps/json11 @@ -1 +1 @@ -Subproject commit df1fdbfd7951a33ae376eade9ec67046cf50fb19 +Subproject commit a20878aaa5bd2546466585b18b6d09808a98233d diff --git a/deps/protobuf b/deps/protobuf index dc497068..cc5296b8 160000 --- a/deps/protobuf +++ b/deps/protobuf @@ -1 +1 @@ -Subproject commit dc4970684ab8b76795cfb2a1e6bdbf54b79848f2 +Subproject commit cc5296b8692beff00285505dd7062c7d5bcb325a diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 953a8c12..ced1744c 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -252,6 +252,7 @@ namespace Components // Register asset interfaces AssetHandler::RegisterInterface(new Assets::IXModel()); + AssetHandler::RegisterInterface(new Assets::IMapEnts()); AssetHandler::RegisterInterface(new Assets::IRawFile()); AssetHandler::RegisterInterface(new Assets::IGfxImage()); AssetHandler::RegisterInterface(new Assets::IMaterial()); diff --git a/src/Components/Modules/AssetHandler.hpp b/src/Components/Modules/AssetHandler.hpp index 3be2d78c..ca2ab82a 100644 --- a/src/Components/Modules/AssetHandler.hpp +++ b/src/Components/Modules/AssetHandler.hpp @@ -57,6 +57,7 @@ namespace Components } #include "AssetInterfaces\IXModel.hpp" +#include "AssetInterfaces\IMapEnts.hpp" #include "AssetInterfaces\IRawFile.hpp" #include "AssetInterfaces\IGfxImage.hpp" #include "AssetInterfaces\IMaterial.hpp" diff --git a/src/Components/Modules/AssetInterfaces/IMapEnts.cpp b/src/Components/Modules/AssetInterfaces/IMapEnts.cpp new file mode 100644 index 00000000..bf1f46fa --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/IMapEnts.cpp @@ -0,0 +1,99 @@ +#include + +namespace Assets +{ + void IMapEnts::Load(Game::XAssetHeader* header, std::string name, Components::ZoneBuilder::Zone* builder) + { + Components::FileSystem::File ents(name + ".ents"); + if (ents.Exists()) + { + Game::MapEnts* entites = builder->GetAllocator()->AllocateArray(); + Game::MapEnts* orgEnts = Components::AssetHandler::FindOriginalAsset(this->GetType(), name.data()).mapEnts; + + if (orgEnts) + { + memcpy(entites, orgEnts, sizeof Game::MapEnts); + } + else + { + entites->name = builder->GetAllocator()->DuplicateString(name); + } + + entites->entityString = builder->GetAllocator()->DuplicateString(ents.GetBuffer()); + entites->numEntityChars = ents.GetBuffer().size() + 1; + + header->mapEnts = entites; + } + } + + void IMapEnts::Save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder) + { + Assert_Size(Game::MapEnts, 44); + + Utils::Stream* buffer = builder->GetBuffer(); + Game::MapEnts* asset = header.mapEnts; + Game::MapEnts* dest = buffer->Dest(); + buffer->Save(asset, sizeof(Game::MapEnts)); + + buffer->PushBlock(Game::XFILE_BLOCK_VIRTUAL); + + if (asset->name) + { + buffer->SaveString(builder->GetAssetName(this->GetType(), asset->name)); + dest->name = reinterpret_cast(-1); + } + + if (asset->entityString) + { + buffer->Save(asset->entityString, asset->numEntityChars); + dest->entityString = reinterpret_cast(-1); + } + + if (asset->trigger.models) + { + Assert_Size(Game::TriggerModel, 8); + buffer->Align(Utils::Stream::ALIGN_4); + buffer->SaveArray(asset->trigger.models, asset->trigger.modelCount); + dest->trigger.models = reinterpret_cast(-1); + } + + if (asset->trigger.hulls) + { + Assert_Size(Game::TriggerHull, 32); + buffer->Align(Utils::Stream::ALIGN_4); + buffer->SaveArray(asset->trigger.hulls, asset->trigger.hullCount); + dest->trigger.hulls = reinterpret_cast(-1); + } + + if (asset->trigger.slabs) + { + Assert_Size(Game::TriggerSlab, 20); + buffer->Align(Utils::Stream::ALIGN_4); + buffer->SaveArray(asset->trigger.slabs, asset->trigger.slabCount); + dest->trigger.slabs = reinterpret_cast(-1); + } + + if (asset->stages) + { + Assert_Size(Game::Stage, 20); + + buffer->Align(Utils::Stream::ALIGN_4); + + Game::Stage* destStages = buffer->Dest(); + buffer->SaveArray(asset->stages, asset->stageCount); + + for (int i = 0; i < asset->stageCount; ++i) + { + Game::Stage* destStage = &destStages[i]; + Game::Stage* stage = &asset->stages[i]; + + buffer->SaveString(stage->stageName); + destStage->stageName = reinterpret_cast(-1); + } + + dest->stages = reinterpret_cast(-1); + } + + buffer->PopBlock(); + } +} diff --git a/src/Components/Modules/AssetInterfaces/IMapEnts.hpp b/src/Components/Modules/AssetInterfaces/IMapEnts.hpp new file mode 100644 index 00000000..1e580497 --- /dev/null +++ b/src/Components/Modules/AssetInterfaces/IMapEnts.hpp @@ -0,0 +1,11 @@ +namespace Assets +{ + class IMapEnts : public Components::AssetHandler::IAsset + { + public: + virtual Game::XAssetType GetType() override { return Game::XAssetType::ASSET_TYPE_MAP_ENTS; }; + + 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; + }; +} \ No newline at end of file diff --git a/src/Components/Modules/Maps.cpp b/src/Components/Modules/Maps.cpp index 8f9b3faa..2d34c81f 100644 --- a/src/Components/Modules/Maps.cpp +++ b/src/Components/Modules/Maps.cpp @@ -61,6 +61,12 @@ namespace Components } } + if (type == Game::XAssetType::ASSET_TYPE_ADDON_MAP_ENTS) + { + *restrict = true; + return; + } + if (type == Game::XAssetType::ASSET_TYPE_MAP_ENTS) { static std::string mapEntities; @@ -69,7 +75,7 @@ namespace Components { mapEntities = ents.GetBuffer(); asset.mapEnts->entityString = const_cast(mapEntities.data()); - asset.mapEnts->numEntityChars = mapEntities.size(); + asset.mapEnts->numEntityChars = mapEntities.size() + 1; } } }