diff --git a/CvGameCoreDLL_Expansion2/CvDatabaseUtility.cpp b/CvGameCoreDLL_Expansion2/CvDatabaseUtility.cpp index 8c8a133f51..074cc9a6a0 100644 --- a/CvGameCoreDLL_Expansion2/CvDatabaseUtility.cpp +++ b/CvGameCoreDLL_Expansion2/CvDatabaseUtility.cpp @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------------------------------------- - © 1991-2012 Take-Two Interactive Software and its subsidiaries. Developed by Firaxis Games. + � 1991-2012 Take-Two Interactive Software and its subsidiaries. Developed by Firaxis Games. Sid Meier's Civilization V, Civ, Civilization, 2K Games, Firaxis Games, Take-Two Interactive Software and their respective logos are all trademarks of Take-Two interactive Software, Inc. All other marks and trademarks are the property of their respective owners. @@ -260,6 +260,42 @@ bool CvDatabaseUtility::PopulateArrayByValue(int*& pArray, const char* szTypeTab return true; } //------------------------------------------------------------------------------ +bool CvDatabaseUtility::PopulateSetByExistence(set& siData, const char* szTypeTableName, const char* szDataTableName, + const char* szTypeColumn, const char* szFilterColumn, const char* szFilterValue) +{ + siData.clear(); + + string strKey = "_PSBE_"; + strKey.append(szTypeTableName); + strKey.append(szDataTableName); + strKey.append(szFilterColumn); + + Database::Results* pResults = GetResults(strKey); + if (!pResults) + { + char szSQL[512]; + sprintf_s(szSQL, "select %s.ID from %s inner join %s on %s = %s.Type where %s = ?", szTypeTableName, szDataTableName, szTypeTableName, szTypeColumn, szTypeTableName, szFilterColumn); + pResults = PrepareResults(strKey, szSQL); + if (!pResults) + return false; + } + + if (!pResults->Bind(1, szFilterValue, false)) + { + CvAssertMsg(false, GetErrorMessage()); + return false; + } + + while (pResults->Step()) + { + siData.insert(pResults->GetInt(0)); + } + + pResults->Reset(); + + return true; +} +//------------------------------------------------------------------------------ bool CvDatabaseUtility::SetFlavors(int*& pFlavorsArray, const char* szTableName, const char* szFilterColumn, diff --git a/CvGameCoreDLL_Expansion2/CvDatabaseUtility.h b/CvGameCoreDLL_Expansion2/CvDatabaseUtility.h index 4dd315ff54..13c0193198 100644 --- a/CvGameCoreDLL_Expansion2/CvDatabaseUtility.h +++ b/CvGameCoreDLL_Expansion2/CvDatabaseUtility.h @@ -1,5 +1,5 @@ /* ------------------------------------------------------------------------------------------------------- - © 1991-2012 Take-Two Interactive Software and its subsidiaries. Developed by Firaxis Games. + � 1991-2012 Take-Two Interactive Software and its subsidiaries. Developed by Firaxis Games. Sid Meier's Civilization V, Civ, Civilization, 2K Games, Firaxis Games, Take-Two Interactive Software and their respective logos are all trademarks of Take-Two interactive Software, Inc. All other marks and trademarks are the property of their respective owners. @@ -73,6 +73,8 @@ void InitializeArray(T*& pArray, const char* szTableName, T default_ = (T)0); int iMinArraySize = 0, const char* szAdditionalCondition = ""); + // Populates a set of Type IDs that satisfies the filter and additional condition in the data table + bool PopulateSetByExistence(set& siData, const char* szTypeTableName, const char* szDataTableName, const char* szTypeColumn, const char* szFilterColumn, const char* szFilterValue); //------------------------------------------------------------------------------ // Tables in Civ5 commonly have a Flavors array. diff --git a/CvGameCoreDLL_Expansion2/CvPlayer.cpp b/CvGameCoreDLL_Expansion2/CvPlayer.cpp index c6e52453b2..d216b22d6f 100644 --- a/CvGameCoreDLL_Expansion2/CvPlayer.cpp +++ b/CvGameCoreDLL_Expansion2/CvPlayer.cpp @@ -1075,6 +1075,13 @@ void CvPlayer::init(PlayerTypes eID) } } + // Free promotions from traits + set seFreePromotions = GetPlayerTraits()->GetFreePromotions(); + for (set::iterator it = seFreePromotions.begin(); it != seFreePromotions.end(); ++it) + { + ChangeFreePromotionCount(*it, 1); + } + SetGreatGeneralCombatBonus(/*15*/ GD_INT_GET(GREAT_GENERAL_STRENGTH_MOD)); } GET_TEAM(getTeam()).DoUpdateBestRoute(); diff --git a/CvGameCoreDLL_Expansion2/CvTraitClasses.cpp b/CvGameCoreDLL_Expansion2/CvTraitClasses.cpp index d5b1155df2..45277f1afc 100644 --- a/CvGameCoreDLL_Expansion2/CvTraitClasses.cpp +++ b/CvGameCoreDLL_Expansion2/CvTraitClasses.cpp @@ -2657,6 +2657,10 @@ bool CvTraitEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility.PopulateArrayByValue(m_piDomainFreeExperienceModifier, "Domains", "Trait_DomainFreeExperienceModifier", "DomainType", "TraitType", szTraitType, "Modifier", 0, NUM_DOMAIN_TYPES); kUtility.PopulateArrayByValue(m_piFreeUnitClassesDOW, "UnitClasses", "Trait_FreeUnitClassesDOW", "UnitClassType", "TraitType", szTraitType, "Number"); #endif + + // Sets + kUtility.PopulateSetByExistence(m_siFreePromotions, "UnitPromotions", "Trait_FreePromotions", "PromotionType", "TraitType", szTraitType); + const int iNumTerrains = GC.getNumTerrainInfos(); //Trait_Terrains @@ -3912,6 +3916,8 @@ void CvPlayerTraits::SetIsWarmonger() } } + // Not optimal, since this assumes the free promotions are always combat-based. + // But there isn't a good way to classify promotions. for (int iNumPromos = 0; iNumPromos < GC.getNumPromotionInfos(); iNumPromos++) { for (int iNumUnits = 0; iNumUnits < GC.getNumUnitCombatClassInfos(); iNumUnits++) @@ -3934,6 +3940,11 @@ void CvPlayerTraits::SetIsWarmonger() } } + if (!GetFreePromotions().empty()) + { + m_bIsWarmonger = true; + return; + } for (int iDomain = 0; iDomain < NUM_DOMAIN_TYPES; iDomain++) { @@ -5161,6 +5172,14 @@ void CvPlayerTraits::InitPlayerTraits() } } #endif + + // Free promotions + set siFreePromotions = trait->GetFreePromotions(); + for (set::iterator it = siFreePromotions.begin(); it != siFreePromotions.end(); ++it) + { + PromotionTypes ePromotion = static_cast(*it); + m_seFreePromotions.insert(ePromotion); + } } } diff --git a/CvGameCoreDLL_Expansion2/CvTraitClasses.h b/CvGameCoreDLL_Expansion2/CvTraitClasses.h index 9e0a1739d9..c71db28f00 100644 --- a/CvGameCoreDLL_Expansion2/CvTraitClasses.h +++ b/CvGameCoreDLL_Expansion2/CvTraitClasses.h @@ -452,6 +452,10 @@ class CvTraitEntry: public CvBaseInfo bool UnitClassCanBuild(const int buildID, const int unitClassID) const; bool TerrainClaimBoost(TerrainTypes eTerrain); #endif + set GetFreePromotions() const + { + return m_siFreePromotions; + } #if defined(MOD_TRAITS_TRADE_ROUTE_PRODUCTION_SIPHON) TradeRouteProductionSiphon GetTradeRouteProductionSiphon(const bool bInternationalOnly) const; #endif @@ -821,6 +825,8 @@ class CvTraitEntry: public CvBaseInfo std::vector m_aFreeResourceXCities; std::vector m_abNoTrainUnitClass; + set m_siFreePromotions; + private: CvTraitEntry(const CvTraitEntry&); CvTraitEntry& operator=(const CvTraitEntry&); @@ -2099,6 +2105,11 @@ class CvPlayerTraits const std::vector GetPotentiallyActiveTraits() { return m_vPotentiallyActiveLeaderTraits; } + set GetFreePromotions() const + { + return m_seFreePromotions; + } + private: bool ConvertBarbarianCamp(CvUnit* pByUnit, CvPlot* pPlot); bool ConvertBarbarianNavalUnit(CvUnit* pByUnit, CvUnit* pUnit); @@ -2469,6 +2480,8 @@ class CvPlayerTraits std::vector< Firaxis::Array > m_ppaaiUnimprovedFeatureYieldChange; std::vector m_aFreeResourceXCities; + + set m_seFreePromotions; }; FDataStream& operator>>(FDataStream&, CvPlayerTraits&);