diff --git a/README.md b/README.md index cc0fe08..5d6b0ce 100644 --- a/README.md +++ b/README.md @@ -180,11 +180,10 @@ if (pSC4App) This class allows other DLLS to query the style ids and names for the building styles that are present in the game's `Building Style Control` window. -It also provides a function to get a building occupant's supported styles as a string containing a comma-separated -list of style names, only styles that are present in the game's `Building Style Control` window will be included in -that list. +It also provides a function to get a building occupant's supported styles as a string containing a list of style names, +only styles that are present in the game's `Building Style Control` window will be included in that list. -See [cIBuildingStyleInfo.h](https://github.com/0xC0000054/sc4-more-building-styles/blob/main/src/public/include/cIBuildingStyleInfo.h) for details. +See [cIBuildingStyleInfo2.h](https://github.com/0xC0000054/sc4-more-building-styles/blob/main/src/public/include/cIBuildingStyleInfo2.h) for details. ### cIBuildingStyleWallToWall GZCOM Class diff --git a/src/BuildingStyleInfo.cpp b/src/BuildingStyleInfo.cpp index 0699eaf..144218f 100644 --- a/src/BuildingStyleInfo.cpp +++ b/src/BuildingStyleInfo.cpp @@ -28,12 +28,11 @@ namespace { - const std::string_view StyleNameListSeperator(", "); - void GetStyleNamesFromVariant( const cIGZVariant& variant, const BuildingStyleCollection& availableBuildingStyles, - cIGZString& destination) + cIGZString& destination, + const cIGZString& separator) { const uint32_t* pData = variant.RefUint32(); const uint32_t repCount = variant.GetCount(); @@ -58,7 +57,7 @@ namespace } else { - destination.Append(StyleNameListSeperator.data(), StyleNameListSeperator.size()); + destination.Append(separator); } destination.Append(item->styleName); @@ -94,6 +93,13 @@ bool BuildingStyleInfo::QueryInterface(uint32_t riid, void** ppvObj) return true; } + else if (riid == GZIID_cIBuildingStyleInfo2) + { + *ppvObj = static_cast(this); + AddRef(); + + return true; + } else if (riid == GZIID_cIGZUnknown) { *ppvObj = static_cast(this); @@ -173,13 +179,28 @@ bool BuildingStyleInfo::GetBuildingStyleName(uint32_t style, cIGZString& name) c return result; } -bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pOccupant, cIGZString& destination) const +bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pBuildingOccupant, cIGZString& destination) const +{ + return GetBuildingStyleNamesEx(pBuildingOccupant, destination, cRZBaseString(", ")); +} + +bool BuildingStyleInfo::IsBuildingStyleAvailable(uint32_t style) const +{ + const BuildingStyleCollection& availableBuildingStyles = buildingWinManager.GetAvailableBuildingStyles(); + + return availableBuildingStyles.find_style(style) != availableBuildingStyles.end(); +} + +bool BuildingStyleInfo::GetBuildingStyleNamesEx( + cISC4Occupant* pBuildingOccupant, + cIGZString& destination, + cIGZString const& separator) const { bool result = false; destination.Erase(0, destination.Strlen()); - const cISC4BuildingOccupant::PurposeType purpose = BuildingUtil::GetPurposeType(pOccupant); + const cISC4BuildingOccupant::PurposeType purpose = BuildingUtil::GetPurposeType(pBuildingOccupant); if (BuildingUtil::PurposeTypeSupportsBuildingStyles(purpose)) { @@ -187,7 +208,7 @@ bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pOccupant, cIGZStri if (availableBuildingStyles.size() > 0) { - const cISCPropertyHolder* pPropertyHolder = pOccupant->AsPropertyHolder(); + const cISCPropertyHolder* pPropertyHolder = pBuildingOccupant->AsPropertyHolder(); if (pPropertyHolder) { @@ -202,7 +223,8 @@ bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pOccupant, cIGZStri GetStyleNamesFromVariant( *pVariant, availableBuildingStyles, - destination); + destination, + separator); } } else @@ -239,7 +261,8 @@ bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pOccupant, cIGZStri GetStyleNamesFromVariant( *pVariant, availableBuildingStyles, - destination); + destination, + separator); } } } @@ -254,9 +277,7 @@ bool BuildingStyleInfo::GetBuildingStyleNames(cISC4Occupant* pOccupant, cIGZStri return result; } -bool BuildingStyleInfo::IsBuildingStyleAvailable(uint32_t style) const +bool BuildingStyleInfo::IsWallToWall(cISC4Occupant* pBuildingOccupant) const { - const BuildingStyleCollection& availableBuildingStyles = buildingWinManager.GetAvailableBuildingStyles(); - - return availableBuildingStyles.find_style(style) != availableBuildingStyles.end(); + return BuildingUtil::IsWallToWall(pBuildingOccupant); } diff --git a/src/BuildingStyleInfo.h b/src/BuildingStyleInfo.h index 76e2e5b..95461fa 100644 --- a/src/BuildingStyleInfo.h +++ b/src/BuildingStyleInfo.h @@ -11,25 +11,40 @@ //////////////////////////////////////////////////////////////////////////// #pragma once -#include "cIBuildingStyleInfo.h" +#include "cIBuildingStyleInfo2.h" class IBuildingSelectWinManager; -class BuildingStyleInfo : public cIBuildingStyleInfo +class BuildingStyleInfo final : public cIBuildingStyleInfo2 { public: BuildingStyleInfo(const IBuildingSelectWinManager& buildingWinManager); + // cIGZUnknown + bool QueryInterface(uint32_t riid, void** ppvObj) override; uint32_t AddRef() override; uint32_t Release() override; - uint32_t GetAvailableBuildingStyleIds(uint32_t* pStyles, uint32_t size) const; - bool GetBuildingStyleName(uint32_t style, cIGZString& name) const; - bool GetBuildingStyleNames(cISC4Occupant* pBuildingOccupant, cIGZString& destination) const; - bool IsBuildingStyleAvailable(uint32_t style) const; - private: + // cIBuildingStyleInfo + + uint32_t GetAvailableBuildingStyleIds(uint32_t* pStyles, uint32_t size) const override; + bool GetBuildingStyleName(uint32_t style, cIGZString& name) const override; + bool GetBuildingStyleNames(cISC4Occupant* pBuildingOccupant, cIGZString& destination) const override; + bool IsBuildingStyleAvailable(uint32_t style) const override; + + // cIBuildingStyleInfo2 + + bool GetBuildingStyleNamesEx( + cISC4Occupant* pBuildingOccupant, + cIGZString& destination, + const cIGZString& separator) const override; + + bool IsWallToWall(cISC4Occupant* pBuildingOccupant) const override; + + // Private members + uint32_t refCount; const IBuildingSelectWinManager& buildingWinManager; }; diff --git a/src/BuildingStyleWallToWall.cpp b/src/BuildingStyleWallToWall.cpp index 39bf7a9..21cf340 100644 --- a/src/BuildingStyleWallToWall.cpp +++ b/src/BuildingStyleWallToWall.cpp @@ -120,14 +120,7 @@ bool BuildingStyleWallToWall::GetWallToWallOccupantGroupName(uint32_t occupantGr bool BuildingStyleWallToWall::HasWallToWallOccupantGroup(cISC4Occupant* pBuildingOccupant) const { - bool result = false; - - if (pBuildingOccupant) - { - result = BuildingUtil::IsWallToWall(pBuildingOccupant->AsPropertyHolder()); - } - - return result; + return BuildingUtil::IsWallToWall(pBuildingOccupant); } bool BuildingStyleWallToWall::GetWallToWallOccupantGroupNames(cISC4Occupant* pBuildingOccupant, cIGZString& destination) const diff --git a/src/BuildingUtil.cpp b/src/BuildingUtil.cpp index 755474e..a884ea7 100644 --- a/src/BuildingUtil.cpp +++ b/src/BuildingUtil.cpp @@ -86,7 +86,6 @@ bool BuildingUtil::IsWallToWall(const cISCPropertyHolder* pPropertyHolder) if (pVariant) { - const uint16_t type = pVariant->GetType(); if (type == cIGZVariant::Bool) @@ -134,3 +133,15 @@ bool BuildingUtil::IsWallToWall(const cISCPropertyHolder* pPropertyHolder) return buildingIsWallToWall; } + +bool BuildingUtil::IsWallToWall(cISC4Occupant* pOccupant) +{ + bool result = false; + + if (pOccupant) + { + result = IsWallToWall(pOccupant->AsPropertyHolder()); + } + + return result; +} diff --git a/src/BuildingUtil.h b/src/BuildingUtil.h index 077dbd5..774409c 100644 --- a/src/BuildingUtil.h +++ b/src/BuildingUtil.h @@ -28,4 +28,5 @@ namespace BuildingUtil bool IsIndustrialBuilding(cISC4BuildingOccupant::PurposeType purposeType); bool IsWallToWall(const cISCPropertyHolder* pPropertyHolder); + bool IsWallToWall(cISC4Occupant* pOccupant); } \ No newline at end of file diff --git a/src/SC4MoreBuildingStyles.vcxproj b/src/SC4MoreBuildingStyles.vcxproj index 6d6e192..3a59739 100644 --- a/src/SC4MoreBuildingStyles.vcxproj +++ b/src/SC4MoreBuildingStyles.vcxproj @@ -89,6 +89,7 @@ + diff --git a/src/SC4MoreBuildingStyles.vcxproj.filters b/src/SC4MoreBuildingStyles.vcxproj.filters index b9f524b..09d5605 100644 --- a/src/SC4MoreBuildingStyles.vcxproj.filters +++ b/src/SC4MoreBuildingStyles.vcxproj.filters @@ -287,6 +287,9 @@ Header Files + + Header Files\Public Headers + diff --git a/src/public/include/cIBuildingStyleInfo2.h b/src/public/include/cIBuildingStyleInfo2.h new file mode 100644 index 0000000..2aa88a0 --- /dev/null +++ b/src/public/include/cIBuildingStyleInfo2.h @@ -0,0 +1,39 @@ +//////////////////////////////////////////////////////////////////////////// +// +// This file is part of sc4-more-building-styles, a DLL Plugin for +// SimCity 4 that adds support for more building styles. +// +// Copyright (c) 2024 Nicholas Hayes +// +// This file is licensed under terms of the MIT License. +// See LICENSE.txt for more information. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once +#include "cIBuildingStyleInfo.h" + +static const uint32_t GZIID_cIBuildingStyleInfo2 = 0xC6C058F1; + +class cIBuildingStyleInfo2 : public cIBuildingStyleInfo +{ +public: + /** + * @brief Gets a list of the style names for the specified building. + * @param pBuildingOccupant A pointer to the building occupant. + * @param destination The destination string. + * @param separator The separator between items in the list. + * @return true on success; otherwise, false. + */ + virtual bool GetBuildingStyleNamesEx( + cISC4Occupant* pBuildingOccupant, + cIGZString& destination, + cIGZString const& separator) const = 0; + + /** + * @brief Gets a value indicating whether the specified building is wall to wall. + * @param pBuildingOccupant A pointer to the building occupant. + * @return true if the specified building is wall to wall; otherwise, false. + */ + virtual bool IsWallToWall(cISC4Occupant* pBuildingOccupant) const = 0; +}; \ No newline at end of file