diff --git a/src/Common/Game/IGame.h b/src/Common/Game/IGame.h index b57c0e9b..065e2ff0 100644 --- a/src/Common/Game/IGame.h +++ b/src/Common/Game/IGame.h @@ -36,6 +36,7 @@ public: IGame& operator=(const IGame& other) = default; IGame& operator=(IGame&& other) noexcept = default; + virtual GameId GetId() = 0; virtual std::string GetFullName() = 0; virtual std::string GetShortName() = 0; virtual void AddZone(Zone* zone) = 0; diff --git a/src/Common/Game/IW3/GameIW3.cpp b/src/Common/Game/IW3/GameIW3.cpp index e3eb4549..788c9017 100644 --- a/src/Common/Game/IW3/GameIW3.cpp +++ b/src/Common/Game/IW3/GameIW3.cpp @@ -8,6 +8,11 @@ using namespace IW3; GameIW3 g_GameIW3; +GameId GameIW3::GetId() +{ + return GameId::IW3; +} + std::string GameIW3::GetFullName() { return "Call Of Duty 4: Modern Warfare"; diff --git a/src/Common/Game/IW3/GameIW3.h b/src/Common/Game/IW3/GameIW3.h index 025533b9..a4f10716 100644 --- a/src/Common/Game/IW3/GameIW3.h +++ b/src/Common/Game/IW3/GameIW3.h @@ -1,17 +1,19 @@ #pragma once #include "Game/IGame.h" -class GameIW3 : public IGame +class GameIW3 final : public IGame { - std::vector m_zones; - public: + GameId GetId() override; std::string GetFullName() override; std::string GetShortName() override; void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; std::vector GetLanguagePrefixes() override; + +private: + std::vector m_zones; }; extern GameIW3 g_GameIW3; diff --git a/src/Common/Game/IW4/GameIW4.cpp b/src/Common/Game/IW4/GameIW4.cpp index bc391d45..beb22d84 100644 --- a/src/Common/Game/IW4/GameIW4.cpp +++ b/src/Common/Game/IW4/GameIW4.cpp @@ -8,6 +8,11 @@ using namespace IW4; GameIW4 g_GameIW4; +GameId GameIW4::GetId() +{ + return GameId::IW4; +} + std::string GameIW4::GetFullName() { return "Call Of Duty: Modern Warfare 2"; diff --git a/src/Common/Game/IW4/GameIW4.h b/src/Common/Game/IW4/GameIW4.h index 5e70acd5..de9cb0b7 100644 --- a/src/Common/Game/IW4/GameIW4.h +++ b/src/Common/Game/IW4/GameIW4.h @@ -1,17 +1,19 @@ #pragma once #include "Game/IGame.h" -class GameIW4 : public IGame +class GameIW4 final : public IGame { - std::vector m_zones; - public: + GameId GetId() override; std::string GetFullName() override; std::string GetShortName() override; void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; std::vector GetLanguagePrefixes() override; + +private: + std::vector m_zones; }; extern GameIW4 g_GameIW4; diff --git a/src/Common/Game/IW5/GameIW5.cpp b/src/Common/Game/IW5/GameIW5.cpp index d11f93e9..d5c6141c 100644 --- a/src/Common/Game/IW5/GameIW5.cpp +++ b/src/Common/Game/IW5/GameIW5.cpp @@ -8,6 +8,11 @@ using namespace IW5; GameIW5 g_GameIW5; +GameId GameIW5::GetId() +{ + return GameId::IW5; +} + std::string GameIW5::GetFullName() { return "Call Of Duty: Modern Warfare 3"; diff --git a/src/Common/Game/IW5/GameIW5.h b/src/Common/Game/IW5/GameIW5.h index bebf3bbd..9632c657 100644 --- a/src/Common/Game/IW5/GameIW5.h +++ b/src/Common/Game/IW5/GameIW5.h @@ -1,17 +1,19 @@ #pragma once #include "Game/IGame.h" -class GameIW5 : public IGame +class GameIW5 final : public IGame { - std::vector m_zones; - public: + GameId GetId() override; std::string GetFullName() override; std::string GetShortName() override; void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; std::vector GetLanguagePrefixes() override; + +private: + std::vector m_zones; }; extern GameIW5 g_GameIW5; diff --git a/src/Common/Game/T5/GameT5.cpp b/src/Common/Game/T5/GameT5.cpp index 5f4f790b..28cd06e2 100644 --- a/src/Common/Game/T5/GameT5.cpp +++ b/src/Common/Game/T5/GameT5.cpp @@ -8,6 +8,11 @@ using namespace T5; GameT5 g_GameT5; +GameId GameT5::GetId() +{ + return GameId::T5; +} + std::string GameT5::GetFullName() { return "Call Of Duty: Black Ops"; diff --git a/src/Common/Game/T5/GameT5.h b/src/Common/Game/T5/GameT5.h index 890e7c81..df413e5c 100644 --- a/src/Common/Game/T5/GameT5.h +++ b/src/Common/Game/T5/GameT5.h @@ -1,17 +1,19 @@ #pragma once #include "Game/IGame.h" -class GameT5 : public IGame +class GameT5 final : public IGame { - std::vector m_zones; - public: + GameId GetId() override; std::string GetFullName() override; std::string GetShortName() override; void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; std::vector GetLanguagePrefixes() override; + +private: + std::vector m_zones; }; extern GameT5 g_GameT5; diff --git a/src/Common/Game/T6/GameT6.cpp b/src/Common/Game/T6/GameT6.cpp index 61149e03..15a9c590 100644 --- a/src/Common/Game/T6/GameT6.cpp +++ b/src/Common/Game/T6/GameT6.cpp @@ -8,6 +8,11 @@ using namespace T6; GameT6 g_GameT6; +GameId GameT6::GetId() +{ + return GameId::T6; +} + std::string GameT6::GetFullName() { return "Call Of Duty: Black Ops II"; diff --git a/src/Common/Game/T6/GameT6.h b/src/Common/Game/T6/GameT6.h index 56bdf23b..ad55f99d 100644 --- a/src/Common/Game/T6/GameT6.h +++ b/src/Common/Game/T6/GameT6.h @@ -1,17 +1,19 @@ #pragma once #include "Game/IGame.h" -class GameT6 : public IGame +class GameT6 final : public IGame { - std::vector m_zones; - public: + GameId GetId() override; std::string GetFullName() override; std::string GetShortName() override; void AddZone(Zone* zone) override; void RemoveZone(Zone* zone) override; std::vector GetZones() override; std::vector GetLanguagePrefixes() override; + +private: + std::vector m_zones; }; extern GameT6 g_GameT6; diff --git a/src/Unlinker/ContentLister/ContentPrinter.cpp b/src/Unlinker/ContentLister/ContentPrinter.cpp index 612940db..99e226d1 100644 --- a/src/Unlinker/ContentLister/ContentPrinter.cpp +++ b/src/Unlinker/ContentLister/ContentPrinter.cpp @@ -3,15 +3,15 @@ #include #include -ContentPrinter::ContentPrinter(Zone* zone) +ContentPrinter::ContentPrinter(const Zone& zone) + : m_zone(zone) { - m_zone = zone; } void ContentPrinter::PrintContent() const { - const auto* pools = m_zone->m_pools.get(); - std::cout << std::format("Zone '{}' ({})\n", m_zone->m_name, m_zone->m_game->GetShortName()); + const auto* pools = m_zone.m_pools.get(); + std::cout << std::format("Zone '{}' ({})\n", m_zone.m_name, m_zone.m_game->GetShortName()); std::cout << "Content:\n"; for (const auto& asset : *pools) diff --git a/src/Unlinker/ContentLister/ContentPrinter.h b/src/Unlinker/ContentLister/ContentPrinter.h index 9e13402a..a58c587e 100644 --- a/src/Unlinker/ContentLister/ContentPrinter.h +++ b/src/Unlinker/ContentLister/ContentPrinter.h @@ -4,10 +4,11 @@ class ContentPrinter { - Zone* m_zone; - public: - explicit ContentPrinter(Zone* zone); + explicit ContentPrinter(const Zone& zone); void PrintContent() const; + +private: + const Zone& m_zone; }; diff --git a/src/Unlinker/ContentLister/ZoneDefWriter.cpp b/src/Unlinker/ContentLister/ZoneDefWriter.cpp index 8ee121f1..51ec5539 100644 --- a/src/Unlinker/ContentLister/ZoneDefWriter.cpp +++ b/src/Unlinker/ContentLister/ZoneDefWriter.cpp @@ -1,17 +1,42 @@ #include "ZoneDefWriter.h" -void AbstractZoneDefWriter::WriteZoneDef(std::ostream& stream, const UnlinkerArgs* args, Zone* zone) const +#include "Game/IW3/ZoneDefWriterIW3.h" +#include "Game/IW4/ZoneDefWriterIW4.h" +#include "Game/IW5/ZoneDefWriterIW5.h" +#include "Game/T5/ZoneDefWriterT5.h" +#include "Game/T6/ZoneDefWriterT6.h" + +#include + +const IZoneDefWriter* IZoneDefWriter::GetZoneDefWriterForGame(GameId game) +{ + static const IZoneDefWriter* zoneDefWriters[static_cast(GameId::COUNT)]{ + new IW3::ZoneDefWriter(), + new IW4::ZoneDefWriter(), + new IW5::ZoneDefWriter(), + new T5::ZoneDefWriter(), + new T6::ZoneDefWriter(), + }; + + assert(static_cast(game) < static_cast(GameId::COUNT)); + const auto* result = zoneDefWriters[static_cast(game)]; + assert(result); + + return result; +} + +void AbstractZoneDefWriter::WriteZoneDef(std::ostream& stream, const UnlinkerArgs& args, const Zone& zone) const { ZoneDefinitionOutputStream out(stream); - out.WriteComment(zone->m_game->GetFullName()); - out.WriteMetaData(META_DATA_KEY_GAME, zone->m_game->GetShortName()); + out.WriteComment(zone.m_game->GetFullName()); + out.WriteMetaData(META_DATA_KEY_GAME, zone.m_game->GetShortName()); out.EmptyLine(); - if (args->m_use_gdt) + if (args.m_use_gdt) { out.WriteComment("Load asset gdt files"); - out.WriteMetaData(META_DATA_KEY_GDT, zone->m_name); + out.WriteMetaData(META_DATA_KEY_GDT, zone.m_name); out.EmptyLine(); } diff --git a/src/Unlinker/ContentLister/ZoneDefWriter.h b/src/Unlinker/ContentLister/ZoneDefWriter.h index 89370784..4cb7f6a4 100644 --- a/src/Unlinker/ContentLister/ZoneDefWriter.h +++ b/src/Unlinker/ContentLister/ZoneDefWriter.h @@ -2,7 +2,6 @@ #include "UnlinkerArgs.h" #include "Zone/Definition/ZoneDefinitionStream.h" -#include "Zone/Zone.h" class IZoneDefWriter { @@ -14,19 +13,20 @@ public: IZoneDefWriter& operator=(const IZoneDefWriter& other) = default; IZoneDefWriter& operator=(IZoneDefWriter&& other) noexcept = default; - virtual bool CanHandleZone(Zone* zone) const = 0; - virtual void WriteZoneDef(std::ostream& stream, const UnlinkerArgs* args, Zone* zone) const = 0; + virtual void WriteZoneDef(std::ostream& stream, const UnlinkerArgs& args, const Zone& zone) const = 0; + + static const IZoneDefWriter* GetZoneDefWriterForGame(GameId game); }; class AbstractZoneDefWriter : public IZoneDefWriter { protected: - static constexpr const char* META_DATA_KEY_GAME = "game"; - static constexpr const char* META_DATA_KEY_GDT = "gdt"; + static constexpr auto META_DATA_KEY_GAME = "game"; + static constexpr auto META_DATA_KEY_GDT = "gdt"; - virtual void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const = 0; - virtual void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const = 0; + virtual void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const = 0; + virtual void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const = 0; public: - void WriteZoneDef(std::ostream& stream, const UnlinkerArgs* args, Zone* zone) const override; + void WriteZoneDef(std::ostream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; diff --git a/src/Unlinker/Game/IW3/ZoneDefWriterIW3.cpp b/src/Unlinker/Game/IW3/ZoneDefWriterIW3.cpp index bde21a42..3850cba7 100644 --- a/src/Unlinker/Game/IW3/ZoneDefWriterIW3.cpp +++ b/src/Unlinker/Game/IW3/ZoneDefWriterIW3.cpp @@ -1,22 +1,16 @@ #include "ZoneDefWriterIW3.h" #include "Game/IW3/GameAssetPoolIW3.h" -#include "Game/IW3/GameIW3.h" #include using namespace IW3; -bool ZoneDefWriter::CanHandleZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW3; -} +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const {} -void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const {} - -void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - const auto* pools = dynamic_cast(zone->m_pools.get()); + const auto* pools = dynamic_cast(zone.m_pools.get()); assert(pools); if (!pools) @@ -24,9 +18,7 @@ void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Unlin // Localized strings are all collected in one string file. So only add this to the zone file. if (!pools->m_localize->m_asset_lookup.empty()) - { - stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name); - } + stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name); for (const auto& asset : *pools) { diff --git a/src/Unlinker/Game/IW3/ZoneDefWriterIW3.h b/src/Unlinker/Game/IW3/ZoneDefWriterIW3.h index 17aa5559..3f378d9d 100644 --- a/src/Unlinker/Game/IW3/ZoneDefWriterIW3.h +++ b/src/Unlinker/Game/IW3/ZoneDefWriterIW3.h @@ -7,10 +7,7 @@ namespace IW3 class ZoneDefWriter final : public AbstractZoneDefWriter { protected: - void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - - public: - bool CanHandleZone(Zone* zone) const override; + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; } // namespace IW3 diff --git a/src/Unlinker/Game/IW4/ZoneDefWriterIW4.cpp b/src/Unlinker/Game/IW4/ZoneDefWriterIW4.cpp index f9de09bb..7e100945 100644 --- a/src/Unlinker/Game/IW4/ZoneDefWriterIW4.cpp +++ b/src/Unlinker/Game/IW4/ZoneDefWriterIW4.cpp @@ -1,22 +1,16 @@ #include "ZoneDefWriterIW4.h" #include "Game/IW4/GameAssetPoolIW4.h" -#include "Game/IW4/GameIW4.h" #include using namespace IW4; -bool ZoneDefWriter::CanHandleZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW4; -} +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const {} -void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const {} - -void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - const auto* pools = dynamic_cast(zone->m_pools.get()); + const auto* pools = dynamic_cast(zone.m_pools.get()); assert(pools); if (!pools) @@ -24,9 +18,7 @@ void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Unlin // Localized strings are all collected in one string file. So only add this to the zone file. if (!pools->m_localize->m_asset_lookup.empty()) - { - stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name); - } + stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name); for (const auto& asset : *pools) { diff --git a/src/Unlinker/Game/IW4/ZoneDefWriterIW4.h b/src/Unlinker/Game/IW4/ZoneDefWriterIW4.h index 901800ba..83bf1642 100644 --- a/src/Unlinker/Game/IW4/ZoneDefWriterIW4.h +++ b/src/Unlinker/Game/IW4/ZoneDefWriterIW4.h @@ -7,10 +7,7 @@ namespace IW4 class ZoneDefWriter final : public AbstractZoneDefWriter { protected: - void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - - public: - bool CanHandleZone(Zone* zone) const override; + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; } // namespace IW4 diff --git a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp index 1de38c5e..ff54d622 100644 --- a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp +++ b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.cpp @@ -1,22 +1,16 @@ #include "ZoneDefWriterIW5.h" #include "Game/IW5/GameAssetPoolIW5.h" -#include "Game/IW5/GameIW5.h" #include using namespace IW5; -bool ZoneDefWriter::CanHandleZone(Zone* zone) const -{ - return zone->m_game == &g_GameIW5; -} +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const {} -void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const {} - -void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - const auto* pools = dynamic_cast(zone->m_pools.get()); + const auto* pools = dynamic_cast(zone.m_pools.get()); assert(pools); if (!pools) @@ -24,9 +18,7 @@ void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Unlin // Localized strings are all collected in one string file. So only add this to the zone file. if (!pools->m_localize->m_asset_lookup.empty()) - { - stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name); - } + stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name); for (const auto& asset : *pools) { diff --git a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h index 92402fbf..fac80d00 100644 --- a/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h +++ b/src/Unlinker/Game/IW5/ZoneDefWriterIW5.h @@ -7,10 +7,7 @@ namespace IW5 class ZoneDefWriter final : public AbstractZoneDefWriter { protected: - void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - - public: - bool CanHandleZone(Zone* zone) const override; + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; } // namespace IW5 diff --git a/src/Unlinker/Game/T5/ZoneDefWriterT5.cpp b/src/Unlinker/Game/T5/ZoneDefWriterT5.cpp index c875c6ba..5fa7774a 100644 --- a/src/Unlinker/Game/T5/ZoneDefWriterT5.cpp +++ b/src/Unlinker/Game/T5/ZoneDefWriterT5.cpp @@ -1,22 +1,16 @@ #include "ZoneDefWriterT5.h" #include "Game/T5/GameAssetPoolT5.h" -#include "Game/T5/GameT5.h" #include using namespace T5; -bool ZoneDefWriter::CanHandleZone(Zone* zone) const -{ - return zone->m_game == &g_GameT5; -} +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const {} -void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const {} - -void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - const auto* pools = dynamic_cast(zone->m_pools.get()); + const auto* pools = dynamic_cast(zone.m_pools.get()); assert(pools); if (!pools) @@ -24,9 +18,7 @@ void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Unlin // Localized strings are all collected in one string file. So only add this to the zone file. if (!pools->m_localize->m_asset_lookup.empty()) - { - stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name); - } + stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name); for (const auto& asset : *pools) { diff --git a/src/Unlinker/Game/T5/ZoneDefWriterT5.h b/src/Unlinker/Game/T5/ZoneDefWriterT5.h index a284dffd..8b206436 100644 --- a/src/Unlinker/Game/T5/ZoneDefWriterT5.h +++ b/src/Unlinker/Game/T5/ZoneDefWriterT5.h @@ -7,10 +7,7 @@ namespace T5 class ZoneDefWriter final : public AbstractZoneDefWriter { protected: - void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - - public: - bool CanHandleZone(Zone* zone) const override; + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; } // namespace T5 diff --git a/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp b/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp index cada1f6a..ad7b197d 100644 --- a/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp +++ b/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp @@ -2,7 +2,6 @@ #include "Game/T6/CommonT6.h" #include "Game/T6/GameAssetPoolT6.h" -#include "Game/T6/GameT6.h" #include #include @@ -10,7 +9,7 @@ using namespace T6; -namespace T6 +namespace { class KeyValuePairKnownKey { @@ -31,50 +30,43 @@ namespace T6 KeyValuePairKnownKey("initial_xmodels"), KeyValuePairKnownKey("initial_materials"), }; -} // namespace T6 -bool ZoneDefWriter::CanHandleZone(Zone* zone) const -{ - return zone->m_game == &g_GameT6; -} - -void ZoneDefWriter::WriteKeyValuePair(ZoneDefinitionOutputStream& stream, KeyValuePair* kvp) -{ - for (const auto& knownKey : KEY_VALUE_PAIR_KNOWN_KEYS) + void WriteKeyValuePair(ZoneDefinitionOutputStream& stream, const KeyValuePair& kvp) { - if (knownKey.m_hash == kvp->keyHash) + for (const auto& knownKey : KEY_VALUE_PAIR_KNOWN_KEYS) { - stream.WriteMetaData("level." + knownKey.m_key, kvp->value); - return; + if (knownKey.m_hash == kvp.keyHash) + { + stream.WriteMetaData("level." + knownKey.m_key, kvp.value); + return; + } } + + std::ostringstream str; + str << "level.@" << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << kvp.keyHash; + stream.WriteMetaData(str.str(), kvp.value); } +} // namespace - std::ostringstream str; - str << "level.@" << std::setfill('0') << std::setw(sizeof(int) * 2) << std::hex << kvp->keyHash; - stream.WriteMetaData(str.str(), kvp->value); -} - -void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - auto* assetPoolT6 = dynamic_cast(zone->m_pools.get()); + const auto* assetPoolT6 = dynamic_cast(zone.m_pools.get()); if (assetPoolT6 && !assetPoolT6->m_key_value_pairs->m_asset_lookup.empty()) { for (const auto* kvpAsset : *assetPoolT6->m_key_value_pairs) { const auto* keyValuePairs = kvpAsset->Asset(); for (auto varIndex = 0; varIndex < keyValuePairs->numVariables; varIndex++) - { - WriteKeyValuePair(stream, &keyValuePairs->keyValuePairs[varIndex]); - } + WriteKeyValuePair(stream, keyValuePairs->keyValuePairs[varIndex]); } stream.EmptyLine(); } } -void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const +void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const { - const auto* pools = dynamic_cast(zone->m_pools.get()); + const auto* pools = dynamic_cast(zone.m_pools.get()); assert(pools); if (!pools) @@ -82,9 +74,7 @@ void ZoneDefWriter::WriteContent(ZoneDefinitionOutputStream& stream, const Unlin // Localized strings are all collected in one string file. So only add this to the zone file. if (!pools->m_localize->m_asset_lookup.empty()) - { - stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone->m_name); - } + stream.WriteEntry(*pools->GetAssetTypeName(ASSET_TYPE_LOCALIZE_ENTRY), zone.m_name); for (const auto& asset : *pools) { diff --git a/src/Unlinker/Game/T6/ZoneDefWriterT6.h b/src/Unlinker/Game/T6/ZoneDefWriterT6.h index 3eb04ec8..5af9672c 100644 --- a/src/Unlinker/Game/T6/ZoneDefWriterT6.h +++ b/src/Unlinker/Game/T6/ZoneDefWriterT6.h @@ -1,19 +1,13 @@ #pragma once #include "ContentLister/ZoneDefWriter.h" -#include "Game/T6/T6.h" namespace T6 { class ZoneDefWriter final : public AbstractZoneDefWriter { - static void WriteKeyValuePair(ZoneDefinitionOutputStream& stream, KeyValuePair* kvp); - protected: - void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs* args, Zone* zone) const override; - - public: - bool CanHandleZone(Zone* zone) const override; + void WriteMetaData(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; + void WriteContent(ZoneDefinitionOutputStream& stream, const UnlinkerArgs& args, const Zone& zone) const override; }; } // namespace T6 diff --git a/src/Unlinker/Unlinker.cpp b/src/Unlinker/Unlinker.cpp index 8dae19b9..e16d3825 100644 --- a/src/Unlinker/Unlinker.cpp +++ b/src/Unlinker/Unlinker.cpp @@ -2,11 +2,6 @@ #include "ContentLister/ContentPrinter.h" #include "ContentLister/ZoneDefWriter.h" -#include "Game/IW3/ZoneDefWriterIW3.h" -#include "Game/IW4/ZoneDefWriterIW4.h" -#include "Game/IW5/ZoneDefWriterIW5.h" -#include "Game/T5/ZoneDefWriterT5.h" -#include "Game/T6/ZoneDefWriterT6.h" #include "ObjContainer/IWD/IWD.h" #include "ObjLoading.h" #include "ObjWriting.h" @@ -25,14 +20,6 @@ namespace fs = std::filesystem; -const IZoneDefWriter* const ZONE_DEF_WRITERS[]{ - new IW3::ZoneDefWriter(), - new IW4::ZoneDefWriter(), - new IW5::ZoneDefWriter(), - new T5::ZoneDefWriter(), - new T6::ZoneDefWriter(), -}; - class Unlinker::Impl { public: @@ -166,51 +153,41 @@ private: return true; } - bool WriteZoneDefinitionFile(Zone* zone, const fs::path& zoneDefinitionFileFolder) const + bool WriteZoneDefinitionFile(const Zone& zone, const fs::path& zoneDefinitionFileFolder) const { auto zoneDefinitionFilePath(zoneDefinitionFileFolder); - zoneDefinitionFilePath.append(zone->m_name); + zoneDefinitionFilePath.append(zone.m_name); zoneDefinitionFilePath.replace_extension(".zone"); std::ofstream zoneDefinitionFile(zoneDefinitionFilePath, std::fstream::out | std::fstream::binary); if (!zoneDefinitionFile.is_open()) { - std::cerr << std::format("Failed to open file for zone definition file of zone \"{}\".\n", zone->m_name); + std::cerr << std::format("Failed to open file for zone definition file of zone \"{}\".\n", zone.m_name); return false; } - auto result = false; - for (const auto* zoneDefWriter : ZONE_DEF_WRITERS) - { - if (zoneDefWriter->CanHandleZone(zone)) - { - zoneDefWriter->WriteZoneDef(zoneDefinitionFile, &m_args, zone); - result = true; - break; - } - } - - if (!result) - std::cerr << std::format("Failed to find writer for zone definition file of zone \"{}\".\n", zone->m_name); + const auto* zoneDefWriter = IZoneDefWriter::GetZoneDefWriterForGame(zone.m_game->GetId()); + zoneDefWriter->WriteZoneDef(zoneDefinitionFile, m_args, zone); zoneDefinitionFile.close(); - return result; + + return true; } - static bool OpenGdtFile(Zone* zone, const fs::path& outputFolder, std::ofstream& stream) + static bool OpenGdtFile(const Zone& zone, const fs::path& outputFolder, std::ofstream& stream) { auto gdtFilePath(outputFolder); gdtFilePath.append("source_data"); fs::create_directories(gdtFilePath); - gdtFilePath.append(zone->m_name); + gdtFilePath.append(zone.m_name); gdtFilePath.replace_extension(".gdt"); stream = std::ofstream(gdtFilePath, std::fstream::out | std::fstream::binary); if (!stream.is_open()) { - std::cerr << std::format("Failed to open file for zone definition file of zone \"{}\".\n", zone->m_name); + std::cerr << std::format("Failed to open file for zone definition file of zone \"{}\".\n", zone.m_name); return false; } @@ -274,7 +251,7 @@ private: * \param zone The zone to handle. * \return \c true if handling the zone was successful, otherwise \c false. */ - bool HandleZone(ISearchPath& searchPath, Zone* zone) const + bool HandleZone(ISearchPath& searchPath, Zone& zone) const { if (m_args.m_task == UnlinkerArgs::ProcessingTask::LIST) { @@ -295,7 +272,7 @@ private: std::ofstream gdtStream; AssetDumpingContext context; - context.m_zone = zone; + context.m_zone = &zone; context.m_base_path = outputFolderPath; context.m_obj_search_path = &searchPath; @@ -305,7 +282,7 @@ private: return false; auto gdt = std::make_unique(gdtStream); gdt->BeginStream(); - gdt->WriteVersion(GdtVersion(zone->m_game->GetShortName(), 1)); + gdt->WriteVersion(GdtVersion(zone.m_game->GetShortName(), 1)); context.m_gdt = std::move(gdt); } @@ -409,7 +386,7 @@ private: if (ShouldLoadObj()) ObjLoading::LoadReferencedContainersForZone(searchPathsForZone, *zone); - if (!HandleZone(searchPathsForZone, zone.get())) + if (!HandleZone(searchPathsForZone, *zone)) return false; if (ShouldLoadObj()) diff --git a/src/Unlinker/UnlinkerArgs.cpp b/src/Unlinker/UnlinkerArgs.cpp index ddefb61e..aa2102e6 100644 --- a/src/Unlinker/UnlinkerArgs.cpp +++ b/src/Unlinker/UnlinkerArgs.cpp @@ -377,7 +377,7 @@ bool UnlinkerArgs::ParseArgs(const int argc, const char** argv, bool& shouldCont return true; } -std::string UnlinkerArgs::GetOutputFolderPathForZone(const Zone* zone) const +std::string UnlinkerArgs::GetOutputFolderPathForZone(const Zone& zone) const { - return std::regex_replace(m_output_folder, m_zone_pattern, zone->m_name); + return std::regex_replace(m_output_folder, m_zone_pattern, zone.m_name); } diff --git a/src/Unlinker/UnlinkerArgs.h b/src/Unlinker/UnlinkerArgs.h index 9e2867e2..fea432b8 100644 --- a/src/Unlinker/UnlinkerArgs.h +++ b/src/Unlinker/UnlinkerArgs.h @@ -68,5 +68,5 @@ public: * \param zone The zone to resolve the path input for. * \return An output path for the zone based on the user input. */ - std::string GetOutputFolderPathForZone(const Zone* zone) const; + std::string GetOutputFolderPathForZone(const Zone& zone) const; };