/// Helper function to read a single type (as a string) and find its ID in a database table. /// Assumes the type is in the table's field "Type" int ReadDBLookup(FDataStream& kStream, const char* szTable, bool* bValid /*= NULL*/) { FStringFixedBuffer(sTemp, 256); kStream >> sTemp; if (bValid) *bValid = true; if(sTemp.GetLength() > 0 && sTemp != "NO_TYPE") { Database::Connection* pDB = GC.GetGameDatabase(); if(pDB) { Database::Results kResults; CvString szCommand; szCommand.Format("SELECT ID from %s where Type = ? LIMIT 1", szTable); if(pDB->Execute(kResults, szCommand.c_str())) { kResults.Bind(1, sTemp.c_str()); if(kResults.Step()) { return kResults.GetInt(0); } else if (bValid) *bValid = false; } } else if (bValid) *bValid = false; } return -1; }
//------------------------------------------------------------------------------ void CvLuaEnums::RegisterDynamicEnums(lua_State* L, const char* szTableName, const char* szIdField, const char* szNameField, const char* szCountName) { Database::Connection& db = *GC.GetGameDatabase(); Database::Results kResults; char zSQL[256]; sprintf_s(zSQL, 255, "select %s, %s from %s", szIdField, szNameField, szTableName); if(db.Execute(kResults, zSQL)) { while(kResults.Step()) { const int value = kResults.GetInt(0); const char* name = kResults.GetText(1); lua_pushstring(L, name); lua_pushvalue(L, -1); lua_pushinteger(L, value); lua_rawset(L, -4); lua_rawseti(L, -2, value); } } if(szCountName != NULL) { lua_pushstring(L, szCountName); lua_pushinteger(L, db.Count(szTableName, false)); lua_rawset(L, -3); } }
//------------------------------------------------------------------------------ bool CvDatabaseUtility::PopulateArrayByExistence(int*& pArray, const char* szTypeTableName, const char* szDataTableName, const char* szTypeColumn, const char* szFilterColumn, const char* szFilterValue) { InitializeArray(pArray, MaxRows(szTypeTableName), -1); std::string strKey = "_PABE_"; strKey.append(szTypeTableName); strKey.append(szDataTableName); strKey.append(szFilterColumn); Database::Results* pResults = GetResults(strKey); if(pResults == NULL) { 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 == NULL) return false; } if(!pResults->Bind(1, szFilterValue, false)) { CvAssertMsg(false, GetErrorMessage()); return false; } int idx = 0; while(pResults->Step()) { pArray[idx++] = pResults->GetInt(0); } pResults->Reset(); return true; }
//------------------------------------------------------------------------------ int CvDatabaseUtility::MaxRows(const char* szTableName) { char szSQL[256] = {0}; sprintf_s(szSQL, "SELECT max(rowid) from %s", szTableName); Database::Results kResults; int maxValue = 0; if(DB.Execute(kResults, szSQL)) { if(kResults.Step()) { //Since some rowid's start at 0 in Civ, let's increase this # by 1. maxValue = kResults.GetInt(0) + 1; } } return maxValue; }
//------------------------------------------------------------------------------ bool CvDatabaseUtility::PopulateArrayByValue(int*& pArray, const char* szTypeTableName, const char* szDataTableName, const char* szTypeColumn, const char* szFilterColumn, const char* szFilterValue, const char* szValueColumn, int iDefaultValue /* = 0 */, int iMinArraySize /* = 0 */) { int iSize = MaxRows(szTypeTableName); InitializeArray(pArray, (iSize<iMinArraySize)?iMinArraySize:iSize, iDefaultValue); std::string strKey = "_PABV_"; strKey.append(szTypeTableName); strKey.append(szDataTableName); strKey.append(szFilterColumn); strKey.append(szValueColumn); Database::Results* pResults = GetResults(strKey); if(pResults == NULL) { char szSQL[512]; sprintf_s(szSQL, "select %s.ID, %s from %s inner join %s on %s = %s.Type where %s = ?", szTypeTableName, szValueColumn, szDataTableName, szTypeTableName, szTypeColumn, szTypeTableName, szFilterColumn); pResults = PrepareResults(strKey, szSQL); if(pResults == NULL) return false; } if(!pResults->Bind(1, szFilterValue, false)) { CvAssertMsg(false, GetErrorMessage()); return false; } while(pResults->Step()) { const int idx = pResults->GetInt(0); const int value = pResults->GetInt(1); pArray[idx] = value; } pResults->Reset(); return true; }
//------------------------------------------------------------------------------ bool CvProjectEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; m_iMaxGlobalInstances = kResults.GetInt("MaxGlobalInstances"); m_iMaxTeamInstances = kResults.GetInt("MaxTeamInstances"); m_iProductionCost = kResults.GetInt("Cost"); m_iNukeInterception = kResults.GetInt("NukeInterception"); m_iCultureBranchesRequired = kResults.GetInt("CultureBranchesRequired"); m_iTechShare = kResults.GetInt("TechShare"); m_iVictoryDelayPercent = kResults.GetInt("VictoryDelayPercent"); m_bSpaceship = kResults.GetBool("Spaceship"); m_bAllowsNukes = kResults.GetBool("AllowsNukes"); #if defined(MOD_BALANCE_CORE) const char* szFreeBuilding = kResults.GetText("FreeBuildingClassIfFirst"); if(szFreeBuilding) { m_eFreeBuilding = (BuildingClassTypes)GC.getInfoTypeForString(szFreeBuilding, true); } const char* szFreePolicy = kResults.GetText("FreePolicyIfFirst"); if(szFreePolicy) { m_eFreePolicy = (PolicyTypes)GC.getInfoTypeForString(szFreePolicy, true); } #endif m_strMovieArtDef = kResults.GetText("MovieDefineTag"); const char* szVictoryPrereq = kResults.GetText("VictoryPrereq"); m_iVictoryPrereq = GC.getInfoTypeForString(szVictoryPrereq, true); const char* szTechPrereq = kResults.GetText("TechPrereq"); m_iTechPrereq = GC.getInfoTypeForString(szTechPrereq, true); const char* szEveryoneSpecialUnit = kResults.GetText("EveryoneSpecialUnit"); m_iEveryoneSpecialUnit = GC.getInfoTypeForString(szEveryoneSpecialUnit, true); const char* szCreateSound = kResults.GetText("CreateSound"); SetCreateSound(szCreateSound); const char* szAnyonePrereqProject = kResults.GetText("AnyonePrereqProject"); m_iAnyoneProjectPrereq = GC.getInfoTypeForString(szAnyonePrereqProject, true); //Arrays const char* szProjectType = GetType(); kUtility.PopulateArrayByValue(m_piResourceQuantityRequirements, "Resources", "Project_ResourceQuantityRequirements", "ResourceType", "ProjectType", szProjectType, "Quantity"); //Victory Thresholds { const int iNumVictories = kUtility.MaxRows("Victories"); kUtility.InitializeArray(m_piVictoryThreshold, iNumVictories); kUtility.InitializeArray(m_piVictoryMinThreshold, iNumVictories); Database::Results kDBResults; char szQuery[512] = {0}; sprintf_s(szQuery, "select VictoryType, Threshold, MinThreshold from Project_VictoryThresholds where ProjectType = '%s';", szProjectType); if(DB.Execute(kDBResults, szQuery)) { while(kDBResults.Step()) { const char* szVictoryType = kDBResults.GetText("VictoryType"); const int idx = GC.getInfoTypeForString(szVictoryType, true); const int iThreshold = kDBResults.GetInt("Threshold"); const int iMinThreshold = kDBResults.GetInt("MinThreshold"); m_piVictoryThreshold[idx] = iThreshold; m_piVictoryMinThreshold[idx] = iMinThreshold; } } } kUtility.SetFlavors(m_piFlavorValue, "Project_Flavors", "ProjectType", szProjectType); kUtility.PopulateArrayByValue(m_piProjectsNeeded, "Projects", "Project_Prereqs", "PrereqProjectType", "ProjectType", szProjectType, "AmountNeeded"); return true; }
bool CvCorporationEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; m_iMaxFranchises = kResults.GetInt("MaxFranchises"); m_iNumFreeTradeRoutes = kResults.GetInt("NumFreeTradeRoutes"); m_iTradeRouteLandDistanceModifier = kResults.GetInt("TradeRouteLandDistanceModifier"); m_iTradeRouteSeaDistanceModifier = kResults.GetInt("TradeRouteSeaDistanceModifier"); m_iTradeRouteSpeedModifier = kResults.GetInt("TradeRouteSpeedModifier"); m_iTradeRouteVisionBoost = kResults.GetInt("TradeRouteVisionBoost"); m_bTradeRoutesInvulnerable = kResults.GetBool("TradeRoutesInvulnerable"); m_iTradeRouteRecipientBonus = kResults.GetInt("TradeRouteRecipientBonus"); m_iTradeRouteTargetBonus = kResults.GetInt("TradeRouteTargetBonus"); //References const char* szTextVal = NULL; szTextVal = kResults.GetText("HeadquartersBuildingClass"); m_eHeadquartersBuildingClass = (BuildingClassTypes) GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("OfficeBuildingClass"); m_eOfficeBuildingClass = (BuildingClassTypes) GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("FranchiseBuildingClass"); m_eFranchiseBuildingClass = (BuildingClassTypes) GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("OfficeBenefitHelper"); m_strOfficeBenefitHelper = szTextVal; // This is not ideal, but Corporations are loaded last, and I want an easy way to tell if a building class is owned by a Corporation // Note: Intellisense may lie here! This will compile (declared as friend) CvBuildingClassInfo* pkBuildingInfo = GC.getBuildingClassInfo(m_eHeadquartersBuildingClass); if (pkBuildingInfo) { pkBuildingInfo->m_eCorporationType = (CorporationTypes) GetID(); pkBuildingInfo->m_bIsHeadquarters = true; } pkBuildingInfo = GC.getBuildingClassInfo(m_eOfficeBuildingClass); if (pkBuildingInfo) { pkBuildingInfo->m_eCorporationType = (CorporationTypes) GetID(); pkBuildingInfo->m_bIsOffice = true; } pkBuildingInfo = GC.getBuildingClassInfo(m_eFranchiseBuildingClass); if (pkBuildingInfo) { pkBuildingInfo->m_eCorporationType = (CorporationTypes) GetID(); pkBuildingInfo->m_bIsFranchise = true; } const char* szCorporationType = GetType(); kUtility.PopulateArrayByExistence(m_piResourceMonopolyAnd, "Resources", "Corporation_ResourceMonopolyAnds", "ResourceType", "CorporationType", szCorporationType); kUtility.PopulateArrayByExistence(m_piResourceMonopolyOrs, "Resources", "Corporation_ResourceMonopolyOrs", "ResourceType", "CorporationType", szCorporationType); kUtility.PopulateArrayByValue(m_piNumFreeResource, "Resources", "Corporation_NumFreeResource", "ResourceType", "CorporationType", szCorporationType, "NumResource"); kUtility.PopulateArrayByValue(m_piUnitResourceProductionModifier, "Resources", "Corporation_UnitResourceProductionModifier", "ResourceType", "CorporationType", szCorporationType, "Modifier"); kUtility.SetYields(m_piTradeRouteCityMod, "Corporation_TradeRouteCityYield", "CorporationType", szCorporationType); kUtility.SetYields(m_piTradeRouteMod, "Corporation_TradeRouteMod", "CorporationType", szCorporationType); //BuildingClassYieldChanges { kUtility.Initialize2DArray(m_ppiBuildingClassYieldChanges, "BuildingClasses", "Yields"); std::string strKey("Corporation_BuildingClassYieldChanges"); Database::Results* pResults = kUtility.GetResults(strKey); if (pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select BuildingClasses.ID as BuildingClassID, Yields.ID as YieldID, YieldChange from Corporation_BuildingClassYieldChanges inner join BuildingClasses on BuildingClasses.Type = BuildingClassType inner join Yields on Yields.Type = YieldType where CorporationType = ?"); } pResults->Bind(1, szCorporationType); while (pResults->Step()) { const int BuildingClassID = pResults->GetInt(0); const int iYieldID = pResults->GetInt(1); const int iYieldChange = pResults->GetInt(2); m_ppiBuildingClassYieldChanges[BuildingClassID][iYieldID] = iYieldChange; } } //ResourceYieldChanges { kUtility.Initialize2DArray(m_ppaiResourceYieldChange, "Resources", "Yields"); std::string strKey("Corporation_ResourceYieldChanges"); Database::Results* pResults = kUtility.GetResults(strKey); if (pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Resources.ID as ResourceID, Yields.ID as YieldID, Yield from Corporation_ResourceYieldChanges inner join Resources on Resources.Type = ResourceType inner join Yields on Yields.Type = YieldType where CorporationType = ?"); } pResults->Bind(1, szCorporationType); while (pResults->Step()) { const int ResourceID = pResults->GetInt(0); const int YieldID = pResults->GetInt(1); const int yield = pResults->GetInt(2); m_ppaiResourceYieldChange[ResourceID][YieldID] = yield; } } //SpecialistYieldChanges { kUtility.Initialize2DArray(m_ppaiSpecialistYieldChange, "Specialists", "Yields"); std::string strKey("Corporation_SpecialistYieldChanges"); Database::Results* pResults = kUtility.GetResults(strKey); if (pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Specialists.ID as SpecialistID, Yields.ID as YieldID, Yield from Corporation_SpecialistYieldChanges inner join Specialists on Specialists.Type = SpecialistType inner join Yields on Yields.Type = YieldType where CorporationType = ?"); } pResults->Bind(1, szCorporationType); while (pResults->Step()) { const int SpecialistID = pResults->GetInt(0); const int YieldID = pResults->GetInt(1); const int yield = pResults->GetInt(2); m_ppaiSpecialistYieldChange[SpecialistID][YieldID] = yield; } } return true; }
/// Read from XML file bool CvImprovementEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; //Basic properties const char* szArtDefineTag = kResults.GetText("ArtDefineTag"); SetArtDefineTag(szArtDefineTag); m_iGoldMaintenance = kResults.GetInt("GoldMaintenance"); m_iCultureBombRadius = kResults.GetInt("CultureBombRadius"); m_iRequiresXAdjacentLand = kResults.GetInt("RequiresXAdjacentLand"); #if defined(MOD_API_EXTENSIONS) m_iRequiresXAdjacentWater = kResults.GetInt("RequiresXAdjacentWater"); #endif #if defined(MOD_GLOBAL_STACKING_RULES) m_iAdditionalUnits = kResults.GetInt("AdditionalUnits"); #endif m_iCultureAdjacentSameType = kResults.GetInt("CultureAdjacentSameType"); m_bHillsMakesValid = kResults.GetBool("HillsMakesValid"); #if defined(MOD_GLOBAL_ALPINE_PASSES) m_bMountainsMakesValid = kResults.GetBool("MountainsMakesValid"); #endif #if defined(MOD_GLOBAL_PASSABLE_FORTS) m_bMakesPassable = kResults.GetBool("MakesPassable"); #endif m_bFreshWaterMakesValid = kResults.GetBool("FreshWaterMakesValid"); m_bRiverSideMakesValid = kResults.GetBool("RiverSideMakesValid"); m_bNoFreshWater = kResults.GetBool("NoFreshWater"); #if defined(MOD_API_EXTENSIONS) if (MOD_API_EXTENSIONS) { m_bAddsFreshWater = kResults.GetBool("AddsFreshWater"); } #endif m_bRequiresFlatlands = kResults.GetBool("RequiresFlatlands"); m_bRequiresFlatlandsOrFreshWater = kResults.GetBool("RequiresFlatlandsOrFreshWater"); m_bRequiresFeature = kResults.GetBool("RequiresFeature"); m_bRequiresImprovement = kResults.GetBool("RequiresImprovement"); m_bRemovesResource = kResults.GetBool("RemovesResource"); m_bPromptWhenComplete = kResults.GetBool("PromptWhenComplete"); m_bWater = kResults.GetBool("Water"); m_bCoastal = kResults.GetBool("Coastal"); m_bDestroyedWhenPillaged = kResults.GetBool("DestroyedWhenPillaged"); m_bDisplacePillager = kResults.GetBool("DisplacePillager"); m_bBuildableOnResources = kResults.GetBool("BuildableOnResources"); m_eImprovementUsageType = m_bBuildableOnResources ? IMPROVEMENTUSAGE_LANDMARK : IMPROVEMENTUSAGE_BASIC; m_bBarbarianCamp = kResults.GetBool("BarbarianCamp"); m_bGoody = kResults.GetBool("Goody"); m_bPermanent = kResults.GetBool("Permanent"); m_iTilesPerGoody = kResults.GetInt("TilesPerGoody"); m_iGoodyUniqueRange = kResults.GetInt("GoodyRange"); m_iFeatureGrowthProbability = kResults.GetInt("FeatureGrowth"); m_iUpgradeTime = kResults.GetInt("UpgradeTime"); m_iRiverSideUpgradeMod = kResults.GetInt("RiverSideUpgradeMod"); m_iCoastalLandUpgradeMod = kResults.GetInt("CoastalLandUpgradeMod"); m_iHillsUpgradeMod = kResults.GetInt("HillsUpgradeMod"); m_iFreshWaterUpgradeMod = kResults.GetInt("FreshWaterUpgradeMod"); m_iDefenseModifier = kResults.GetInt("DefenseModifier"); m_iNearbyEnemyDamage = kResults.GetInt("NearbyEnemyDamage"); m_iPillageGold = kResults.GetInt("PillageGold"); m_bOutsideBorders = kResults.GetBool("OutsideBorders"); m_bInAdjacentFriendly = kResults.GetBool("InAdjacentFriendly"); m_bIgnoreOwnership = kResults.GetBool("IgnoreOwnership"); m_bOnlyCityStateTerritory = kResults.GetBool("OnlyCityStateTerritory"); #if defined(MOD_DIPLOMACY_CITYSTATES) if (MOD_DIPLOMACY_CITYSTATES) { m_bIsEmbassy = kResults.GetBool("IsEmbassy"); } #endif #if defined(MOD_BALANCE_CORE) const char* szObsoleteTech = kResults.GetText("ObsoleteTech"); m_iGetObsoleteTech = (CivilizationTypes)GC.getInfoTypeForString(szObsoleteTech, true); m_bAdjacentLake = kResults.GetBool("Lakeside"); m_bAdjacentCity = kResults.GetBool("Cityside"); m_iGrantsVision = kResults.GetInt("GrantsVisionXTiles"); #endif m_bNoTwoAdjacent = kResults.GetBool("NoTwoAdjacent"); m_bAdjacentLuxury = kResults.GetBool("AdjacentLuxury"); m_bAllowsWalkWater = kResults.GetBool("AllowsWalkWater"); m_bCreatedByGreatPerson = kResults.GetBool("CreatedByGreatPerson"); m_bSpecificCivRequired = kResults.GetBool("SpecificCivRequired"); m_iResourceExtractionMod = kResults.GetInt("ResourceExtractionMod"); m_iLuxuryCopiesSiphonedFromMinor = kResults.GetInt("LuxuryCopiesSiphonedFromMinor"); #if defined(MOD_DIPLOMACY_CITYSTATES) if (MOD_DIPLOMACY_CITYSTATES) { m_iImprovementLeagueVotes = kResults.GetInt("ImprovementLeagueVotes"); } #endif const char* szCivilizationType = kResults.GetText("CivilizationType"); m_eRequiredCivilization = (CivilizationTypes)GC.getInfoTypeForString(szCivilizationType, true); #if defined(MOD_BALANCE_CORE) const char* szImprovementResource = kResults.GetText("ImprovementResource"); m_iImprovementResource = (ResourceTypes)GC.getInfoTypeForString(szImprovementResource, true); m_iImprovementResourceQuantity = kResults.GetInt("ImprovementResourceQuantity"); const char* szTextVal; szTextVal = kResults.GetText("UnitFreePromotion"); if(szTextVal != NULL) { m_iUnitFreePromotionImprovement = GC.getInfoTypeForString(szTextVal, true); } #endif //References const char* szWorldsoundscapeAudioScript = kResults.GetText("WorldSoundscapeAudioScript"); if(szWorldsoundscapeAudioScript != NULL) { m_iWorldSoundscapeScriptId = gDLL->GetAudioTagIndex(szWorldsoundscapeAudioScript, AUDIOTAG_SOUNDSCAPE); } else { m_iWorldSoundscapeScriptId = -1; Remark(1, "Warning: Missing soundscape definition in XML for feature: '%s'", GetType()); } const char* szImprovementPillage = kResults.GetText("ImprovementPillage"); m_iImprovementPillage = GC.getInfoTypeForString(szImprovementPillage, true); const char* szImprovementUpgrade = kResults.GetText("ImprovementUpgrade"); m_iImprovementUpgrade = GC.getInfoTypeForString(szImprovementUpgrade, true); //Arrays const char* szImprovementType = GetType(); const size_t lenImprovementType = strlen(szImprovementType); kUtility.PopulateArrayByExistence(m_pbTerrainMakesValid, "Terrains", "Improvement_ValidTerrains", "TerrainType", "ImprovementType", szImprovementType); kUtility.PopulateArrayByExistence(m_pbFeatureMakesValid, "Features", "Improvement_ValidFeatures", "FeatureType", "ImprovementType", szImprovementType); kUtility.PopulateArrayByExistence(m_pbImprovementMakesValid, "Improvements", "Improvement_ValidImprovements", "PrereqImprovement", "ImprovementType", szImprovementType); #if defined(MOD_API_UNIFIED_YIELDS) kUtility.SetYields(m_piAdjacentSameTypeYield, "Improvement_YieldAdjacentSameType", "ImprovementType", szImprovementType); kUtility.SetYields(m_piAdjacentTwoSameTypeYield, "Improvement_YieldAdjacentTwoSameType", "ImprovementType", szImprovementType); #endif kUtility.SetYields(m_piYieldChange, "Improvement_Yields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piYieldPerEra, "Improvement_YieldPerEra", "ImprovementType", szImprovementType); kUtility.SetYields(m_piAdjacentCityYieldChange, "Improvement_AdjacentCityYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piAdjacentMountainYieldChange, "Improvement_AdjacentMountainYieldChanges", "ImprovementType", szImprovementType); kUtility.SetYields(m_piCoastalLandYieldChange, "Improvement_CoastalLandYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piFreshWaterChange, "Improvement_FreshWaterYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piHillsYieldChange, "Improvement_HillsYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piRiverSideYieldChange, "Improvement_RiverSideYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piPrereqNatureYield, "Improvement_PrereqNatureYields", "ImprovementType", szImprovementType); kUtility.SetFlavors(m_piFlavorValue, "Improvement_Flavors", "ImprovementType", szImprovementType); { //Initialize Improvement Resource Types to number of Resources const int iNumResources = kUtility.MaxRows("Resources"); m_paImprovementResource = FNEW(CvImprovementResourceInfo[iNumResources], c_eCiv5GameplayDLL, 0); kUtility.InitializeArray(m_piResourceQuantityRequirements, iNumResources); std::string strResourceTypesKey = "Improvements - ResourceTypes"; Database::Results* pResourceTypes = kUtility.GetResults(strResourceTypesKey); if(pResourceTypes == NULL) { pResourceTypes = kUtility.PrepareResults(strResourceTypesKey, "select Resources.ID, ResourceType, ResourceMakesValid, ResourceTrade, DiscoveryRand from Improvement_ResourceTypes inner join Resources on ResourceType = Resources.Type where ImprovementType = ?"); } std::string strYieldResultsKey = "Improvements - YieldResults"; Database::Results* pYieldResults = kUtility.GetResults(strYieldResultsKey); if(pYieldResults == NULL) { pYieldResults = kUtility.PrepareResults(strYieldResultsKey, "select Yields.ID, Yield from Improvement_ResourceType_Yields inner join Yields on YieldType = Yields.Type where ImprovementType = ? and ResourceType = ?"); } pResourceTypes->Bind(1, szImprovementType, lenImprovementType, false); while(pResourceTypes->Step()) { const int idx = pResourceTypes->GetInt("ID"); CvImprovementResourceInfo& pResourceInfo = m_paImprovementResource[idx]; const char* szResourceType = pResourceTypes->GetText("ResourceType"); pResourceInfo.m_bResourceMakesValid = pResourceTypes->GetBool("ResourceMakesValid"); pResourceInfo.m_bResourceTrade = pResourceTypes->GetBool("ResourceTrade"); pResourceInfo.m_iDiscoverRand = pResourceTypes->GetInt("DiscoveryRand"); m_piResourceQuantityRequirements[idx] = pResourceTypes->GetInt("QuantityRequirement"); //Populate Yields for structure kUtility.InitializeArray(pResourceInfo.m_piYieldChange, "Yields"); pYieldResults->Bind(1, szImprovementType, lenImprovementType, false); pYieldResults->Bind(2, szResourceType, -1, false); while(pYieldResults->Step()) { const int yieldIdx = pYieldResults->GetInt("ID"); const int yield = pYieldResults->GetInt("Yield"); pResourceInfo.m_piYieldChange[yieldIdx] = yield; } pYieldResults->Reset(); } pResourceTypes->Reset(); } const int iNumYields = kUtility.MaxRows("Yields"); #if defined(MOD_BALANCE_CORE) //AdjacentImprovementYieldChanges { const int iNumImprovements = kUtility.MaxRows("Improvements"); CvAssertMsg(iNumImprovements > 0, "Num Improvement Infos <= 0"); kUtility.Initialize2DArray(m_ppiAdjacentImprovementYieldChanges, iNumImprovements, iNumYields); std::string strKey = "Improvements - AdjacentImprovementYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Improvements.ID as ImprovementID, Yield from Improvement_AdjacentImprovementYieldChanges inner join Yields on YieldType = Yields.Type inner join Improvements on OtherImprovementType = Improvements.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int improvement_idx = pResults->GetInt(1); CvAssert(improvement_idx > -1); const int yield = pResults->GetInt(2); m_ppiAdjacentImprovementYieldChanges[improvement_idx][yield_idx] = yield; } pResults->Reset(); } #endif const int iNumTechs = GC.getNumTechInfos(); CvAssertMsg(iNumTechs > 0, "Num Tech Infos <= 0"); //TechYieldChanges { kUtility.Initialize2DArray(m_ppiTechYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechYieldChanges[tech_idx][yield_idx] = yield; } } //TechNoFreshWaterYieldChanges { kUtility.Initialize2DArray(m_ppiTechNoFreshWaterYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechNoFreshWaterYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechNoFreshWaterYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechNoFreshWaterYieldChanges[tech_idx][yield_idx] = yield; } pResults->Reset(); } //TechFreshWaterYieldChanges { kUtility.Initialize2DArray(m_ppiTechFreshWaterYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechFreshWaterYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechFreshWaterYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechFreshWaterYieldChanges[tech_idx][yield_idx] = yield; } pResults->Reset(); } //RouteYieldChanges { const int iNumRoutes = kUtility.MaxRows("Routes"); kUtility.Initialize2DArray(m_ppiRouteYieldChanges, iNumRoutes, iNumYields); std::string strKey = "Improvements - RouteYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Routes.ID as RouteID, Yield from Improvement_RouteYieldChanges inner join Yields on YieldType = Yields.Type inner join Routes on RouteType = Routes.Type where ImprovementType = ?;"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int route_idx = pResults->GetInt(1); CvAssert(route_idx > -1); const int yield = pResults->GetInt(2); m_ppiRouteYieldChanges[route_idx][yield_idx] = yield; } pResults->Reset(); } return true; }
/// Read from XML file bool CvImprovementEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; //Basic properties const char* szArtDefineTag = kResults.GetText("ArtDefineTag"); SetArtDefineTag(szArtDefineTag); m_iGoldMaintenance = kResults.GetInt("GoldMaintenance"); m_iCultureBombRadius = kResults.GetInt("CultureBombRadius"); m_iCultureAdjacentSameType = kResults.GetInt("CultureAdjacentSameType"); m_bHillsMakesValid = kResults.GetBool("HillsMakesValid"); m_bFreshWaterMakesValid = kResults.GetBool("FreshWaterMakesValid"); m_bRiverSideMakesValid = kResults.GetBool("RiverSideMakesValid"); m_bNoFreshWater = kResults.GetBool("NoFreshWater"); m_bRequiresFlatlands = kResults.GetBool("RequiresFlatlands"); m_bRequiresFlatlandsOrFreshWater = kResults.GetBool("RequiresFlatlandsOrFreshWater"); m_bRequiresFeature = kResults.GetBool("RequiresFeature"); m_bWater = kResults.GetBool("Water"); m_bCoastal = kResults.GetBool("Coastal"); m_bDestroyedWhenPillaged = kResults.GetBool("DestroyedWhenPillaged"); m_bBuildableOnResources = kResults.GetBool("BuildableOnResources"); m_eImprovementUsageType = m_bBuildableOnResources ? IMPROVEMENTUSAGE_LANDMARK : IMPROVEMENTUSAGE_BASIC; m_bBarbarianCamp = kResults.GetBool("BarbarianCamp"); m_bGoody = kResults.GetBool("Goody"); m_bPermanent = kResults.GetBool("Permanent"); m_iTilesPerGoody = kResults.GetInt("TilesPerGoody"); m_iGoodyUniqueRange = kResults.GetInt("GoodyRange"); m_iFeatureGrowthProbability = kResults.GetInt("FeatureGrowth"); m_iUpgradeTime = kResults.GetInt("UpgradeTime"); m_iRiverSideUpgradeMod = kResults.GetInt("RiverSideUpgradeMod"); m_iCoastalLandUpgradeMod = kResults.GetInt("CoastalLandUpgradeMod"); m_iHillsUpgradeMod = kResults.GetInt("HillsUpgradeMod"); m_iFreshWaterUpgradeMod = kResults.GetInt("FreshWaterUpgradeMod"); m_iDefenseModifier = kResults.GetInt("DefenseModifier"); m_iNearbyEnemyDamage = kResults.GetInt("NearbyEnemyDamage"); m_iPillageGold = kResults.GetInt("PillageGold"); m_bOutsideBorders = kResults.GetBool("OutsideBorders"); m_bInAdjacentFriendly = kResults.GetBool("InAdjacentFriendly"); m_bCreatedByGreatPerson = kResults.GetBool("CreatedByGreatPerson"); m_bSpecificCivRequired = kResults.GetBool("SpecificCivRequired"); m_iResourceExtractionMod = kResults.GetInt("ResourceExtractionMod"); const char* szCivilizationType = kResults.GetText("CivilizationType"); m_eRequiredCivilization = (CivilizationTypes)GC.getInfoTypeForString(szCivilizationType, true); //References const char* szWorldsoundscapeAudioScript = kResults.GetText("WorldSoundscapeAudioScript"); if(szWorldsoundscapeAudioScript != NULL) { m_iWorldSoundscapeScriptId = gDLL->GetAudioTagIndex(szWorldsoundscapeAudioScript, AUDIOTAG_SOUNDSCAPE); } else { m_iWorldSoundscapeScriptId = -1; Remark(1, "Warning: Missing soundscape definition in XML for feature: '%s'", GetType()); } const char* szImprovementPillage = kResults.GetText("ImprovementPillage"); m_iImprovementPillage = GC.getInfoTypeForString(szImprovementPillage, true); const char* szImprovementUpgrade = kResults.GetText("ImprovementUpgrade"); m_iImprovementUpgrade = GC.getInfoTypeForString(szImprovementUpgrade, true); //Arrays const char* szImprovementType = GetType(); const size_t lenImprovementType = strlen(szImprovementType); kUtility.PopulateArrayByExistence(m_pbTerrainMakesValid, "Terrains", "Improvement_ValidTerrains", "TerrainType", "ImprovementType", szImprovementType); kUtility.PopulateArrayByExistence(m_pbFeatureMakesValid, "Features", "Improvement_ValidFeatures", "FeatureType", "ImprovementType", szImprovementType); kUtility.SetYields(m_piYieldChange, "Improvement_Yields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piAdjacentCityYieldChange, "Improvement_AdjacentCityYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piAdjacentMountainYieldChange, "Improvement_AdjacentMountainYieldChanges", "ImprovementType", szImprovementType); kUtility.SetYields(m_piCoastalLandYieldChange, "Improvement_CoastalLandYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piFreshWaterChange, "Improvement_FreshWaterYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piHillsYieldChange, "Improvement_HillsYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piRiverSideYieldChange, "Improvement_RiverSideYields", "ImprovementType", szImprovementType); kUtility.SetYields(m_piPrereqNatureYield, "Improvement_PrereqNatureYields", "ImprovementType", szImprovementType); kUtility.SetFlavors(m_piFlavorValue, "Improvement_Flavors", "ImprovementType", szImprovementType); { //Initialize Improvement Resource Types to number of Resources const int iNumResources = kUtility.MaxRows("Resources"); m_paImprovementResource = FNEW(CvImprovementResourceInfo[iNumResources], c_eCiv5GameplayDLL, 0); kUtility.InitializeArray(m_piResourceQuantityRequirements, iNumResources); std::string strResourceTypesKey = "Improvements - ResourceTypes"; Database::Results* pResourceTypes = kUtility.GetResults(strResourceTypesKey); if(pResourceTypes == NULL) { pResourceTypes = kUtility.PrepareResults(strResourceTypesKey, "select Resources.ID, ResourceType, ResourceMakesValid, ResourceTrade, DiscoveryRand from Improvement_ResourceTypes inner join Resources on ResourceType = Resources.Type where ImprovementType = ?"); } std::string strYieldResultsKey = "Improvements - YieldResults"; Database::Results* pYieldResults = kUtility.GetResults(strYieldResultsKey); if(pYieldResults == NULL) { pYieldResults = kUtility.PrepareResults(strYieldResultsKey, "select Yields.ID, Yield from Improvement_ResourceType_Yields inner join Yields on YieldType = Yields.Type where ImprovementType = ? and ResourceType = ?"); } pResourceTypes->Bind(1, szImprovementType, lenImprovementType, false); while(pResourceTypes->Step()) { const int idx = pResourceTypes->GetInt("ID"); CvImprovementResourceInfo& pResourceInfo = m_paImprovementResource[idx]; const char* szResourceType = pResourceTypes->GetText("ResourceType"); pResourceInfo.m_bResourceMakesValid = pResourceTypes->GetBool("ResourceMakesValid"); pResourceInfo.m_bResourceTrade = pResourceTypes->GetBool("ResourceTrade"); pResourceInfo.m_iDiscoverRand = pResourceTypes->GetInt("DiscoveryRand"); m_piResourceQuantityRequirements[idx] = pResourceTypes->GetInt("QuantityRequirement"); //Populate Yields for structure kUtility.InitializeArray(pResourceInfo.m_piYieldChange, "Yields"); pYieldResults->Bind(1, szImprovementType, lenImprovementType, false); pYieldResults->Bind(2, szResourceType, -1, false); while(pYieldResults->Step()) { const int yieldIdx = pYieldResults->GetInt("ID"); const int yield = pYieldResults->GetInt("Yield"); pResourceInfo.m_piYieldChange[yieldIdx] = yield; } pYieldResults->Reset(); } pResourceTypes->Reset(); } const int iNumYields = kUtility.MaxRows("Yields"); const int iNumTechs = GC.getNumTechInfos(); CvAssertMsg(iNumTechs > 0, "Num Tech Infos <= 0"); //TechYieldChanges { kUtility.Initialize2DArray(m_ppiTechYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechYieldChanges[tech_idx][yield_idx] = yield; } } //TechNoFreshWaterYieldChanges { kUtility.Initialize2DArray(m_ppiTechNoFreshWaterYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechNoFreshWaterYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechNoFreshWaterYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechNoFreshWaterYieldChanges[tech_idx][yield_idx] = yield; } pResults->Reset(); } //TechFreshWaterYieldChanges { kUtility.Initialize2DArray(m_ppiTechFreshWaterYieldChanges, iNumTechs, iNumYields); std::string strKey = "Improvements - TechFreshWaterYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Technologies.ID as TechID, Yield from Improvement_TechFreshWaterYieldChanges inner join Yields on YieldType = Yields.Type inner join Technologies on TechType = Technologies.Type where ImprovementType = ?"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int tech_idx = pResults->GetInt(1); CvAssert(tech_idx > -1); const int yield = pResults->GetInt(2); m_ppiTechFreshWaterYieldChanges[tech_idx][yield_idx] = yield; } pResults->Reset(); } //RouteYieldChanges { const int iNumRoutes = kUtility.MaxRows("Routes"); kUtility.Initialize2DArray(m_ppiRouteYieldChanges, iNumRoutes, iNumYields); std::string strKey = "Improvements - RouteYieldChanges"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Yields.ID as YieldID, Routes.ID as RouteID, Yield from Improvement_RouteYieldChanges inner join Yields on YieldType = Yields.Type inner join Routes on RouteType = Routes.Type where ImprovementType = ?;"); } pResults->Bind(1, szImprovementType, lenImprovementType, false); while(pResults->Step()) { const int yield_idx = pResults->GetInt(0); CvAssert(yield_idx > -1); const int route_idx = pResults->GetInt(1); CvAssert(route_idx > -1); const int yield = pResults->GetInt(2); m_ppiRouteYieldChanges[route_idx][yield_idx] = yield; } pResults->Reset(); } return true; }
//------------------------------------------------------------------------------ bool CvDllDatabaseUtility::ValidateGameDatabase() { //This function contains a suite of useful game database unit tests that will //ensure the database conforms to certain unique rules of Civ5. cvStopWatch kPerfTest("Validating Game Database", "xml-perf.log"); bool bError = false; LogMsg("**** Validating Game Database *****"); //Test that all Tables w/ 'ID' column start at 0 and not 1. { Database::Results kTables("name"); if(DB.SelectAt(kTables, "sqlite_master", "type", "table")) { while(kTables.Step()) { const char* szTableName = kTables.GetText(0); if(DB.Count(szTableName) > 0) { //Test if table has 'ID' column bool bHasIDColumn = false; { //Execute "select ID from <table_name> limit 1; //If there's a SQL error, it's most likely due to a lack of an 'id' column. char szSQL[512]; sprintf_s(szSQL, "pragma table_info(%s)", szTableName); Database::Results kResults; DB.Execute(kResults, szSQL); while(kResults.Step()) { const char* szName = kResults.GetText("name"); if(strcmp(szTableName, szName) == 0) { bHasIDColumn = true; break; } } } if(bHasIDColumn) { Database::SingleResult kTest; if(!DB.SelectAt(kTest, szTableName, "ID", 0)) { //Table has 'ID' column and contains data but does not use ID 0. char szError[512]; sprintf_s(szError, "Table '%s' contains 'ID' column that starts at 1 instead of 0.", szTableName); LogMsg(szError); bError = true; } } } } } } //Validate FK constraints DB.ValidateFKConstraints(); LogMsg("Performing Localization Checks"); { LogMsg("Checking Tag Format..."); LogMsg("Note: Tags must only use [A-Z_] characters, start with 'TXT_KEY_', and be under 128 characters long."); Database::Results kLanguages; if(DB.SelectAll(kLanguages, "Languages")) { while(kLanguages.Step()) { const char* szTagColumnName = kLanguages.GetText("TagColumnName"); const char* szTableName = kLanguages.GetText("TableName"); Database::Results kResults; char szSQL[512]; sprintf_s(szSQL, "SELECT DISTINCT %s from %s", szTagColumnName, szTableName); if(DB.Execute(kResults, szSQL)) { bool bFirst = true; while(kResults.Step()) { const char* szTag = kResults.GetText(0); const size_t len = strlen(szTag); if(len > 128) { if(bFirst) { LogMsg("In table %s...", szTableName); bFirst = false; } bError = true; LogMsg("Tag (%s) has size greater than 127 characters.", szTag); } else { if(strncmp("TXT_KEY_", szTag, 8) != 0) { if(bFirst) { LogMsg("In table %s...", szTableName); bFirst = false; } bError = true; LogMsg("Tag (%s) does not start with 'TXT_KEY_'", szTag); } for(size_t i = 0; i < len; ++i) { char ch = szTag[i]; if(ch != '_' && !((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9'))) { if(bFirst) { LogMsg("In table %s...", szTableName); bFirst = false; } bError = true; LogMsg("Tag (%s) contains invalid character (%.1s)", szTag, &ch); } } } } } } } } LogMsg("Validating UnitGameplay"); { if(DB.Count("UnitGameplay2DScripts") != DB.Count("Units")) { LogMsg("Number of selection sounds doesn't match number of units."); bError = true; } } LogMsg("Validating Notifications"); { if(DB.Count("Notifications") != NUM_NOTIFICATION_TYPES) { LogMsg("Number of notification xml entries does not match enum size"); bError = true; } } if(bError) { LogMsg("**** VALIDATION FAILED *****"); } else { LogMsg("**** Validation Success *****"); } kPerfTest.EndPerfTest(); LogMsg("Validation Took %f seconds", kPerfTest.GetDeltaInSeconds()); return !bError; }
//------------------------------------------------------------------------------ bool CvDllDatabaseUtility::CacheGameDatabaseData() { //Do not cache everything if we don't need to. if(m_bGameDatabaseNeedsCaching == false) return true; //The following code depends on a valid initialized database. bool bSuccess = true; //TODO: Figure out how to handle cases where Validation has failed. /*bSuccess &= */ ValidateGameDatabase(); //bSuccess &= PerformDatabasePostProcessing(); //HACK Legacy 'FindInfoByType' support. //In order to support the legacy code still using the old infos system, //all of the id/type pairs must be added to gc.m_infosMap //I apologize for this horrendous code, please remove it in the near future. GC.infoTypeFromStringReset(); Database::Results kTables("name"); if(DB.SelectAt(kTables, "sqlite_master", "type", "table")) { while(kTables.Step()) { Database::Results kTypes; if(DB.SelectAll(kTypes, kTables.GetText(0))) { bool bFirstStep = true; while(kTypes.Step()) { if(bFirstStep) { if(!kTypes.HasColumn("ID") || !kTypes.HasColumn("Type")) { break; } bFirstStep = false; } const int rowid = kTypes.GetInt("ID"); const char* szType = kTypes.GetText("Type"); if(szType) GC.setInfoTypeFromString(szType, rowid); } } } } bSuccess &= LoadGlobalDefines(); bSuccess &= PrefetchGameData(); bSuccess &= UpdatePlayableCivilizationCounts(); CvTypes::AcquireTypes(DB); bSuccess &= SetGlobalActionInfo(); //Clear out database cache and tune for runtime use. DB.ClearCountCache(); //Log Database Memory statistics LogMsg(DB.CalculateMemoryStats()); CvAssertMsg(bSuccess, "Failed to load Gameplay Database Data! Not Good!"); if(bSuccess) m_bGameDatabaseNeedsCaching = false; #if defined(CUSTOM_MODS_H) // Load up the CustomModOptions configuration gCustomMods.preloadCache(); #endif return bSuccess; }
void CvTypes::AcquireTypes(Database::Connection& db) { //ArtifactType { typedef std::tr1::unordered_map<std::string, GreatWorkArtifactClass*> LookupTable; LookupTable kArtifactTypeLookupTable; kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_ANCIENT_RUIN"), &s_eARTIFACT_ANCIENT_RUIN)); kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_BARBARIAN_CAMP"), &s_eARTIFACT_BARBARIAN_CAMP)); kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_BATTLE_RANGED"), &s_eARTIFACT_BATTLE_RANGED)); kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_BATTLE_MELEE"), &s_eARTIFACT_BATTLE_MELEE)); kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_RAZED_CITY"), &s_eARTIFACT_RAZED_CITY)); kArtifactTypeLookupTable.insert(make_pair(std::string("ARTIFACT_WRITING"), &s_eARTIFACT_WRITING)); Database::Results kResults; if(db.Execute(kResults, "SELECT Type, ID from GreatWorkArtifactClasses")) { while(kResults.Step()) { std::string strArtifactType = kResults.GetText(0); LookupTable::iterator it = kArtifactTypeLookupTable.find(strArtifactType); if(it != kArtifactTypeLookupTable.end()) { (*it->second) = static_cast<GreatWorkArtifactClass>(kResults.GetInt(1)); } } } for(LookupTable::iterator it = kArtifactTypeLookupTable.begin(); it != kArtifactTypeLookupTable.end(); ++it) { if((*it->second) == NO_GREAT_WORK_ARTIFACT_CLASS) { char msg[256] = {0}; sprintf_s(msg, "ArtifactType - %s is used in the DLL but does not exist in the database.", it->first.c_str()); FILogFile* pLog = LOGFILEMGR.GetLog("Gamecore.log", FILogFile::kDontTimeStamp); pLog->WarningMsg(msg); CvAssertMsg(false, msg); } } } //GreatWorkSlots { typedef std::tr1::unordered_map<std::string, GreatWorkSlotType*> LookupTable; LookupTable kTypeLookupTable; kTypeLookupTable.insert(make_pair(std::string("GREAT_WORK_SLOT_ART_ARTIFACT"), &s_eGREAT_WORK_SLOT_ART_ARTIFACT)); kTypeLookupTable.insert(make_pair(std::string("GREAT_WORK_SLOT_LITERATURE"), &s_eGREAT_WORK_SLOT_LITERATURE)); kTypeLookupTable.insert(make_pair(std::string("GREAT_WORK_SLOT_MUSIC"), &s_eGREAT_WORK_SLOT_MUSIC)); Database::Results kResults; if(db.Execute(kResults, "SELECT Type, ID from GreatWorkSlots")) { while(kResults.Step()) { std::string strType = kResults.GetText(0); LookupTable::iterator it = kTypeLookupTable.find(strType); if(it != kTypeLookupTable.end()) { (*it->second) = static_cast<GreatWorkSlotType>(kResults.GetInt(1)); } } } for(LookupTable::iterator it = kTypeLookupTable.begin(); it != kTypeLookupTable.end(); ++it) { if((*it->second) == NO_GREAT_WORK_SLOT) { char msg[256] = {0}; sprintf_s(msg, "GreatWorkSlotType - %s is used in the DLL but does not exist in the database.", it->first.c_str()); FILogFile* pLog = LOGFILEMGR.GetLog("Gamecore.log", FILogFile::kDontTimeStamp); pLog->WarningMsg(msg); CvAssertMsg(false, msg); } } } //MissionTypes { typedef std::tr1::unordered_map<std::string, MissionTypes*> LookupTable; LookupTable kMissionTypesLookupTable; kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MOVE_TO"), &s_eMISSION_MOVE_TO)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ROUTE_TO"), &s_eMISSION_ROUTE_TO)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MOVE_TO_UNIT"), &s_eMISSION_MOVE_TO_UNIT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SWAP_UNITS"), &s_eMISSION_SWAP_UNITS)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SKIP"), &s_eMISSION_SKIP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SLEEP"), &s_eMISSION_SLEEP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ALERT"), &s_eMISSION_ALERT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FORTIFY"), &s_eMISSION_FORTIFY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GARRISON"), &s_eMISSION_GARRISON)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SET_UP_FOR_RANGED_ATTACK"), &s_eMISSION_SET_UP_FOR_RANGED_ATTACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_EMBARK"), &s_eMISSION_EMBARK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DISEMBARK"), &s_eMISSION_DISEMBARK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRPATROL"), &s_eMISSION_AIRPATROL)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_HEAL"), &s_eMISSION_HEAL)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRLIFT"), &s_eMISSION_AIRLIFT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_NUKE"), &s_eMISSION_NUKE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_PARADROP"), &s_eMISSION_PARADROP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIR_SWEEP"), &s_eMISSION_AIR_SWEEP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REBASE"), &s_eMISSION_REBASE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_RANGE_ATTACK"), &s_eMISSION_RANGE_ATTACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_PILLAGE"), &s_eMISSION_PILLAGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FOUND"), &s_eMISSION_FOUND)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_JOIN"), &s_eMISSION_JOIN)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CONSTRUCT"), &s_eMISSION_CONSTRUCT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DISCOVER"), &s_eMISSION_DISCOVER)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_HURRY"), &s_eMISSION_HURRY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_TRADE"), &s_eMISSION_TRADE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_BUY_CITY_STATE"), &s_eMISSION_BUY_CITY_STATE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REPAIR_FLEET"), &s_eMISSION_REPAIR_FLEET)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SPACESHIP"), &s_eMISSION_SPACESHIP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CULTURE_BOMB"), &s_eMISSION_CULTURE_BOMB)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FOUND_RELIGION"), &s_eMISSION_FOUND_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GOLDEN_AGE"), &s_eMISSION_GOLDEN_AGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_BUILD"), &s_eMISSION_BUILD)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_LEAD"), &s_eMISSION_LEAD)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DIE_ANIMATION"), &s_eMISSION_DIE_ANIMATION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_BEGIN_COMBAT"), &s_eMISSION_BEGIN_COMBAT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_END_COMBAT"), &s_eMISSION_END_COMBAT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRSTRIKE"), &s_eMISSION_AIRSTRIKE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SURRENDER"), &s_eMISSION_SURRENDER)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CAPTURED"), &s_eMISSION_CAPTURED)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_IDLE"), &s_eMISSION_IDLE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DIE"), &s_eMISSION_DIE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DAMAGE"), &s_eMISSION_DAMAGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MULTI_SELECT"), &s_eMISSION_MULTI_SELECT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MULTI_DESELECT"), &s_eMISSION_MULTI_DESELECT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_WAIT_FOR"), &s_eMISSION_WAIT_FOR)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SPREAD_RELIGION"), &s_eMISSION_SPREAD_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ENHANCE_RELIGION"), &s_eMISSION_ENHANCE_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REMOVE_HERESY"), &s_eMISSION_REMOVE_HERESY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ESTABLISH_TRADE_ROUTE"), &s_eMISSION_ESTABLISH_TRADE_ROUTE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_PLUNDER_TRADE_ROUTE"), &s_eMISSION_PLUNDER_TRADE_ROUTE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CREATE_GREAT_WORK"), &s_eMISSION_GREAT_WORK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CHANGE_TRADE_UNIT_HOME_CITY"), &s_eMISSION_CHANGE_TRADE_UNIT_HOME_CITY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SELL_EXOTIC_GOODS"), &s_eMISSION_SELL_EXOTIC_GOODS)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GIVE_POLICIES"), &s_eMISSION_GIVE_POLICIES)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ONE_SHOT_TOURISM"), &s_eMISSION_ONE_SHOT_TOURISM)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CHANGE_ADMIRAL_PORT"), &s_eMISSION_CHANGE_ADMIRAL_PORT)); #if defined (JRMOD_B5) kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GENERATE_UPRISING"), &s_eMISSION_GENERATE_UPRISING)); #endif #if defined (JRMOD_C18) kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_JOIN_ARMY_STACK"), &s_eMISSION_JOIN_ARMY_STACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DISJOIN_ARMY_STACK"), &s_eMISSION_DISJOIN_ARMY_STACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DEPLOY_ARMY_STACK"), &s_eMISSION_DEPLOY_ARMY_STACK)); #endif Database::Results kResults; if(db.Execute(kResults, "SELECT Type, ID from Missions")) { while(kResults.Step()) { std::string strMissionType = kResults.GetText(0); LookupTable::iterator it = kMissionTypesLookupTable.find(strMissionType); if(it != kMissionTypesLookupTable.end()) { (*it->second) = static_cast<MissionTypes>(kResults.GetInt(1)); } } } int iNumTypes = db.Count("Missions", false); if(iNumTypes >= 0) { s_uiNUM_MISSION_TYPES = static_cast<unsigned int>(iNumTypes); } for(LookupTable::iterator it = kMissionTypesLookupTable.begin(); it != kMissionTypesLookupTable.end(); ++it) { if((*it->second) == NO_MISSION) { char msg[256] = {0}; sprintf_s(msg, "MissionType - %s is used in the DLL but does not exist in the database.", it->first.c_str()); FILogFile* pLog = LOGFILEMGR.GetLog("Gamecore.log", FILogFile::kDontTimeStamp); pLog->WarningMsg(msg); CvAssertMsg(false, msg); } } } }
//------------------------------------------------------------------------------ bool CvDllDatabaseUtility::PrefetchGameData() { cvStopWatch kTest("PrefetchGameData", "xml-perf.log"); //Because Colors and PlayerColors are used everywhere during load //(by the translator) we load interface infos first. //Interface PrefetchCollection(GC.GetColorInfo(), "Colors"); PrefetchCollection(GC.GetPlayerColorInfo(), "PlayerColors"); PrefetchCollection(GC.getInterfaceModeInfo(), "InterfaceModes"); //AI PrefetchCollection(GC.getAICityStrategyInfo(), "AICityStrategies"); PrefetchCollection(GC.getEconomicAIStrategyInfo(), "AIEconomicStrategies"); PrefetchCollection(GC.getAIGrandStrategyInfo(), "AIGrandStrategies"); PrefetchCollection(GC.getMilitaryAIStrategyInfo(), "AIMilitaryStrategies"); PrefetchCollection(GC.getCitySpecializationInfo(), "CitySpecializations"); PrefetchCollection(GC.getTacticalMoveInfo(), "TacticalMoves"); //BasicInfos //AnimationOperators? //Attitudes? PrefetchCollection(GC.getUnitAIInfo(), "UnitAIInfos"); PrefetchCollection(GC.getUnitCombatClassInfo(), "UnitCombatInfos"); //Buildings PrefetchCollection(GC.getBuildingClassInfo(), "BuildingClasses"); PrefetchCollection(GC.getBuildingInfo(), "Buildings"); //GameInfo PrefetchCollection(GC.getEmphasisInfo(), "EmphasizeInfos"); PrefetchCollection(GC.getEraInfo(), "Eras"); PrefetchCollection(GC.getGameOptionInfo(), "GameOptions"); PrefetchCollection(GC.getGameSpeedInfo(), "GameSpeeds"); PrefetchCollection(GC.getHandicapInfo(), "HandicapInfos"); PrefetchCollection(GC.getHurryInfo(), "HurryInfos"); PrefetchCollection(GC.getMPOptionInfo(), "MultiplayerOptions"); PrefetchCollection(GC.getPlayerOptionInfo(), "PlayerOptions"); PrefetchCollection(GC.getPolicyInfo(), "Policies"); PrefetchCollection(GC.getPolicyBranchInfo(), "PolicyBranchTypes"); PrefetchCollection(GC.getProcessInfo(), "Processes"); PrefetchCollection(GC.getProjectInfo(), "Projects"); PrefetchCollection(GC.getSmallAwardInfo(), "SmallAwards"); PrefetchCollection(GC.getSpecialistInfo(), "Specialists"); PrefetchCollection(GC.getVictoryInfo(), "Victories"); PrefetchCollection(GC.getVoteInfo(), "Votes"); PrefetchCollection(GC.getVoteSourceInfo(), "VoteSources"); PrefetchCollection(GC.getUnitDomainInfo(), "Domains"); #if defined(MOD_EVENTS_DIPLO_MODIFIERS) PrefetchCollection(GC.getDiploModifierInfo(), "DiploModifiers"); #endif //Leaders PrefetchCollection(GC.getLeaderHeadInfo(), "Leaders"); //Misc PrefetchCollection(GC.getRouteInfo(), "Routes"); CvNotificationXMLEntries* pkNotificationEntries = GC.GetNotificationEntries(); if(pkNotificationEntries != NULL) { PrefetchCollection(pkNotificationEntries->GetNotificationEntries(), "Notifications"); } //Technologies PrefetchCollection(GC.getTechInfo(), "Technologies"); //Terrain PrefetchCollection(GC.getFeatureInfo(), "Features"); PrefetchCollection(GC.getImprovementInfo(), "Improvements"); PrefetchCollection(GC.getResourceClassInfo(), "ResourceClasses"); PrefetchCollection(GC.getResourceInfo(), "Resources"); #if defined(MOD_API_PLOT_YIELDS) if (MOD_API_PLOT_YIELDS) { PrefetchCollection(GC.getPlotInfo(), "Plots"); } #endif #if defined(MOD_API_UNIFIED_YIELDS) if (MOD_API_UNIFIED_YIELDS) { PrefetchCollection(GC.getGreatPersonInfo(), "GreatPersons"); } #endif PrefetchCollection(GC.getTerrainInfo(), "Terrains"); PrefetchCollection(GC.getYieldInfo(), "Yields"); //Units PrefetchCollection(GC.getAutomateInfo(), "Automates"); PrefetchCollection(GC.getBuildInfo(), "Builds"); PrefetchCollection(GC.getCommandInfo(), "Commands"); PrefetchCollection(GC.getControlInfo(), "Controls"); PrefetchCollection(GC.getEntityEventInfo(), "EntityEvents"); PrefetchCollection(GC.getMissionInfo(), "Missions"); PrefetchCollection(GC.getMultiUnitFormationInfo(), "MultiUnitFormations"); PrefetchCollection(GC.getSpecialUnitInfo(), "SpecialUnits"); PrefetchCollection(GC.getUnitClassInfo(), "UnitClasses"); PrefetchCollection(GC.getPromotionInfo(), "UnitPromotions"); PrefetchCollection(GC.getUnitInfo(), "Units"); //Civilizations - must be after buildings and units PrefetchCollection(GC.getCivilizationInfo(), "Civilizations"); PrefetchCollection(GC.getMinorCivInfo(), "MinorCivilizations"); PrefetchCollection(GC.getTraitInfo(), "Traits"); PrefetchCollection(GC.getReligionInfo(), "Religions"); PrefetchCollection(GC.getBeliefInfo(), "Beliefs"); PrefetchCollection(GC.getLeagueSpecialSessionInfo(), "LeagueSpecialSessions"); PrefetchCollection(GC.getLeagueNameInfo(), "LeagueNames"); PrefetchCollection(GC.getLeagueProjectInfo(), "LeagueProjects"); PrefetchCollection(GC.getLeagueProjectRewardInfo(), "LeagueProjectRewards"); PrefetchCollection(GC.getResolutionInfo(), "Resolutions"); #if defined(MOD_API_ACHIEVEMENTS) || defined(ACHIEVEMENT_HACKS) PrefetchCollection(GC.getAchievementInfo(), "Achievements"); #endif //Copy flavors into string array { CvDatabaseUtility kUtility; CvString*& paFlavors = GC.getFlavorTypes(); const int iNumFlavors = kUtility.MaxRows("Flavors"); //GC.getNumFlavorTypes() = iNumFlavors; GC.setNumFlavorTypes(iNumFlavors); paFlavors = FNEW(CvString[iNumFlavors], c_eCiv5GameplayDLL, 0); Database::Results kResults; if(DB.SelectWhere(kResults, "Flavors", "ID > -1")) { while(kResults.Step()) { const int iFlavor = kResults.GetInt("ID"); CvAssert(iFlavor >= 0 && iFlavor < iNumFlavors); if(iFlavor >= 0 && iFlavor < iNumFlavors) { paFlavors[iFlavor] = kResults.GetText("Type"); } } } else { CvAssertMsg(false, DB.ErrorMessage()); } } ValidatePrefetchProcess(); return true; }
//------------------------------------------------------------------------------ bool CvProjectEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; m_iMaxGlobalInstances = kResults.GetInt("MaxGlobalInstances"); m_iMaxTeamInstances = kResults.GetInt("MaxTeamInstances"); m_iProductionCost = kResults.GetInt("Cost"); m_iNukeInterception = kResults.GetInt("NukeInterception"); m_iCultureBranchesRequired = kResults.GetInt("CultureBranchesRequired"); m_iTechShare = kResults.GetInt("TechShare"); m_iVictoryDelayPercent = kResults.GetInt("VictoryDelayPercent"); m_bSpaceship = kResults.GetBool("Spaceship"); m_bAllowsNukes = kResults.GetBool("AllowsNukes"); m_strMovieArtDef = kResults.GetText("MovieDefineTag"); const char* szVictoryPrereq = kResults.GetText("VictoryPrereq"); m_iVictoryPrereq = GC.getInfoTypeForString(szVictoryPrereq, true); const char* szTechPrereq = kResults.GetText("TechPrereq"); m_iTechPrereq = GC.getInfoTypeForString(szTechPrereq, true); const char* szEveryoneSpecialUnit = kResults.GetText("EveryoneSpecialUnit"); m_iEveryoneSpecialUnit = GC.getInfoTypeForString(szEveryoneSpecialUnit, true); const char* szCreateSound = kResults.GetText("CreateSound"); SetCreateSound(szCreateSound); const char* szAnyonePrereqProject = kResults.GetText("AnyonePrereqProject"); m_iAnyoneProjectPrereq = GC.getInfoTypeForString(szAnyonePrereqProject, true); //Arrays const char* szProjectType = GetType(); kUtility.PopulateArrayByValue(m_piResourceQuantityRequirements, "Resources", "Project_ResourceQuantityRequirements", "ResourceType", "ProjectType", szProjectType, "Quantity"); //Victory Thresholds { const int iNumVictories = kUtility.MaxRows("Victories"); kUtility.InitializeArray(m_piVictoryThreshold, iNumVictories); kUtility.InitializeArray(m_piVictoryMinThreshold, iNumVictories); Database::Results kDBResults; char szQuery[512] = {0}; sprintf_s(szQuery, "select VictoryType, Threshold, MinThreshold from Project_VictoryThresholds where ProjectType = '%s';", szProjectType); if(DB.Execute(kDBResults, szQuery)) { while(kDBResults.Step()) { const char* szVictoryType = kDBResults.GetText("VictoryType"); const int idx = GC.getInfoTypeForString(szVictoryType, true); const int iThreshold = kDBResults.GetInt("Threshold"); const int iMinThreshold = kDBResults.GetInt("MinThreshold"); m_piVictoryThreshold[idx] = iThreshold; m_piVictoryMinThreshold[idx] = iMinThreshold; } } } kUtility.SetFlavors(m_piFlavorValue, "Project_Flavors", "ProjectType", szProjectType); kUtility.PopulateArrayByValue(m_piProjectsNeeded, "Projects", "Project_Prereqs", "PrereqProjectType", "ProjectType", szProjectType, "AmountNeeded"); // EventEngine - v0.1, Snarko { m_asziFlagPrereqs.clear(); std::string strKey("Project_PrereqFlags"); Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select * from Project_PrereqFlags where ProjectType = ?"); } pResults->Bind(1, szProjectType); while(pResults->Step()) { std::string szFlag = pResults->GetText("Flag"); int iMinimumValue = pResults->GetInt("MinimumValue"); m_asziFlagPrereqs.push_back(std::make_pair(szFlag, iMinimumValue)); } } // END EventEngine return true; }
bool CvUnitEntry::CacheResults(Database::Results& kResults, CvDatabaseUtility& kUtility) { if(!CvBaseInfo::CacheResults(kResults, kUtility)) return false; //Basic Properties m_iProductionCost = kResults.GetInt("Cost"); m_iFaithCost = kResults.GetInt("FaithCost"); m_bRequiresFaithPurchaseEnabled = kResults.GetBool("RequiresFaithPurchaseEnabled"); m_iHurryCostModifier = kResults.GetInt("HurryCostModifier"); m_iAdvancedStartCost = kResults.GetInt("AdvancedStartCost"); m_iMinAreaSize = kResults.GetInt("MinAreaSize"); m_iMoves = kResults.GetInt("Moves"); m_bMoves = kResults.GetInt("Immobile"); m_iBaseSightRange = kResults.GetInt("BaseSightRange"); m_iRange = kResults.GetInt("Range"); m_iAirInterceptRange = kResults.GetInt("AirInterceptRange"); m_iAirUnitCap = kResults.GetInt("AirUnitCap"); m_iNukeDamageLevel = kResults.GetInt("NukeDamageLevel"); m_iWorkRate = kResults.GetInt("WorkRate"); m_iNumFreeTechs = kResults.GetInt("NumFreeTechs"); m_iBaseBeakersTurnsToCount = kResults.GetInt("BaseBeakersTurnsToCount"); m_iBaseHurry = kResults.GetInt("BaseHurry"); m_iHurryMultiplier = kResults.GetInt("HurryMultiplier"); m_bRushBuilding= kResults.GetInt("RushBuilding"); m_iBaseGold = kResults.GetInt("BaseGold"); m_iNumGoldPerEra = kResults.GetInt("NumGoldPerEra"); m_bSpreadReligion = kResults.GetBool("SpreadReligion"); m_bRemoveHeresy = kResults.GetBool("RemoveHeresy"); m_iReligionSpreads = kResults.GetInt("ReligionSpreads"); m_iReligiousStrength = kResults.GetInt("ReligiousStrength"); m_bFoundReligion = kResults.GetBool("FoundReligion"); m_bRequiresEnhancedReligion = kResults.GetBool("RequiresEnhancedReligion"); m_bProhibitsSpread = kResults.GetBool("ProhibitsSpread"); m_iCombat = kResults.GetInt("Combat"); m_iCombatLimit = kResults.GetInt("CombatLimit"); m_iRangedCombat = kResults.GetInt("RangedCombat"); m_iRangedCombatLimit = kResults.GetInt("RangedCombatLimit"); m_iXPValueAttack = kResults.GetInt("XPValueAttack"); m_iXPValueDefense = kResults.GetInt("XPValueDefense"); m_iConscriptionValue = kResults.GetInt("Conscription"); m_iExtraMaintenanceCost = kResults.GetInt("ExtraMaintenanceCost"); m_bNoMaintenance = kResults.GetBool("NoMaintenance"); m_iUnhappiness = kResults.GetInt("Unhappiness"); m_iUnitFlagIconOffset = kResults.GetInt("UnitFlagIconOffset"); m_iUnitPortraitOffset = kResults.GetInt("PortraitIndex"); m_iLeaderExperience = kResults.GetInt("LeaderExperience"); m_bFoodProduction = kResults.GetBool("Food"); m_bNoBadGoodies = kResults.GetBool("NoBadGoodies"); m_bRivalTerritory = kResults.GetBool("RivalTerritory"); m_bMilitarySupport = kResults.GetBool("MilitarySupport"); m_bMilitaryProduction = kResults.GetBool("MilitaryProduction"); m_bPillage = kResults.GetBool("Pillage"); m_bFound = kResults.GetBool("Found"); m_bFoundAbroad = kResults.GetBool("FoundAbroad"); m_iCultureBombRadius = kResults.GetInt("CultureBombRadius"); m_iGoldenAgeTurns = kResults.GetInt("GoldenAgeTurns"); m_bIgnoreBuildingDefense = kResults.GetBool("IgnoreBuildingDefense"); m_bPrereqResources = kResults.GetBool("PrereqResources"); m_bMechanized = kResults.GetBool("Mechanized"); m_bSuicide = kResults.GetBool("Suicide"); m_bCaptureWhileEmbarked = kResults.GetBool("CaptureWhileEmbarked"); m_bRangeAttackOnlyInDomain = kResults.GetBool("RangeAttackOnlyInDomain"); m_strUnitArtInfoTag = kResults.GetText("UnitArtInfo"); m_bUnitArtInfoCulturalVariation = kResults.GetBool("UnitArtInfoCulturalVariation"); m_bUnitArtInfoEraVariation = kResults.GetBool("UnitArtInfoEraVariation"); //References const char* szTextVal = NULL; szTextVal = kResults.GetText("Class"); m_iUnitClassType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("Special"); m_iSpecialUnitType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("Capture"); m_iUnitCaptureClassType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("CombatClass"); m_iUnitCombatType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("Domain"); m_iDomainType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("CivilianAttackPriority"); m_iCivilianAttackPriority = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("DefaultUnitAI"); m_iDefaultUnitAIType = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("PillagePrereqTech"); m_iPrereqPillageTech = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("PrereqTech"); m_iPrereqAndTech = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("ObsoleteTech"); m_iObsoleteTech = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("GoodyHutUpgradeUnitClass"); m_iGoodyHutUpgradeUnitClass = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("SpecialCargo"); m_iSpecialCargo = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("DomainCargo"); m_iDomainCargo = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("ProjectPrereq"); m_iProjectPrereq = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("SpaceshipProject"); m_iSpaceshipProject = GC.getInfoTypeForString(szTextVal, true); szTextVal = kResults.GetText("LeaderPromotion"); m_iLeaderPromotion = GC.getInfoTypeForString(szTextVal, true); //Arrays const char* szUnitType = GetType(); kUtility.SetFlavors(m_piFlavorValue, "Unit_Flavors", "UnitType", szUnitType); kUtility.PopulateArrayByValue(m_piProductionTraits, "Traits", "Unit_ProductionTraits", "TraitType", "UnitType", szUnitType, "Trait"); kUtility.PopulateArrayByValue(m_piResourceQuantityRequirements, "Resources", "Unit_ResourceQuantityRequirements", "ResourceType", "UnitType", szUnitType, "Cost"); kUtility.PopulateArrayByValue(m_piProductionModifierBuildings, "Buildings", "Unit_ProductionModifierBuildings", "BuildingType", "UnitType", szUnitType, "ProductionModifier"); kUtility.PopulateArrayByValue(m_piYieldFromKills, "Yields", "Unit_YieldFromKills", "YieldType", "UnitType", szUnitType, "Yield"); kUtility.PopulateArrayByExistence(m_pbFreePromotions, "UnitPromotions", "Unit_FreePromotions", "PromotionType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbUpgradeUnitClass, "UnitClasses", "Unit_ClassUpgrades", "UnitClassType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbUnitAIType, "UnitAIInfos", "Unit_AITypes", "UnitAIType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbNotUnitAIType, "UnitAIInfos", "Unit_NotAITypes", "UnitAIType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbBuilds, "Builds", "Unit_Builds", "BuildType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbGreatPeoples, "Specialists", "Unit_GreatPersons", "GreatPersonType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbBuildings, "Buildings", "Unit_Buildings", "BuildingType", "UnitType", szUnitType); kUtility.PopulateArrayByExistence(m_pbBuildingClassRequireds, "BuildingClasses", "Unit_BuildingClassRequireds", "BuildingClassType", "UnitType", szUnitType); //TechTypes { //Initialize array to NO_TECH kUtility.InitializeArray(m_piPrereqAndTechs, "Technologies", (int)NO_TECH); std::string strKey = "Units - TechTypes"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select Technologies.ID from Unit_TechTypes inner join Technologies on TechType = Technologies.Type where UnitType = ?"); } pResults->Bind(1, szUnitType, -1, false); int i = 0; while(pResults->Step()) { m_piPrereqAndTechs[i++] = pResults->GetInt(0); } pResults->Reset(); } //Unit Unique Names Count { std::string strKey = "Units - UniqueNameCount"; Database::Results* pUnitNameCount = kUtility.GetResults(strKey); if(pUnitNameCount == NULL) { pUnitNameCount = kUtility.PrepareResults(strKey, "select count(*) from Unit_UniqueNames where UnitType = ?"); } pUnitNameCount->Bind(1, szUnitType, -1, false); pUnitNameCount->Step(); m_iNumUnitNames = pUnitNameCount->GetInt(0); pUnitNameCount->Reset(); } //Unit Unique Names { if(m_iNumUnitNames > 0) { m_paszUnitNames = FNEW(CvString[m_iNumUnitNames], c_eCiv5GameplayDLL, 0); std::string strKey = "Units - UniqueNames"; Database::Results* pResults = kUtility.GetResults(strKey); if(pResults == NULL) { pResults = kUtility.PrepareResults(strKey, "select UniqueName from Unit_UniqueNames where UnitType = ?"); } pResults->Bind(1, szUnitType, -1, false); int i = 0; while(pResults->Step()) { m_paszUnitNames[i++] = pResults->GetText(0); } pResults->Reset(); } } //MovementRates { std::string strKey = "Units - MovementRates"; Database::Results* pMovementRates = kUtility.GetResults(strKey); if(pMovementRates == NULL) { pMovementRates = kUtility.PrepareResults(strKey, "SELECT * FROM MovementRates where Type = ? ORDER BY NumHexes"); } const char* szMovementRate = kResults.GetText("MoveRate"); pMovementRates->Bind(1, szMovementRate, -1, false); while(pMovementRates->Step()) { int f0 = pMovementRates->GetInt("NumHexes") - 1; float f1 = pMovementRates->GetFloat("TotalTime"); float f2 = pMovementRates->GetFloat("EaseIn"); float f3 = pMovementRates->GetFloat("EaseOut"); float f4 = pMovementRates->GetFloat("IndividualOffset"); float f5 = pMovementRates->GetFloat("RowOffset"); float f6 = pMovementRates->GetFloat("CurveRoll"); int iPathSubdivision = pMovementRates->GetInt("PathSubdivision"); if(f0 >= 0 && f0 <= 11) { m_unitMoveRate[f0].m_fTotalMoveRate = f1; m_unitMoveRate[f0].m_fEaseIn = f2; m_unitMoveRate[f0].m_fEaseOut = f3; m_unitMoveRate[f0].m_fIndividualOffset = f4; m_unitMoveRate[f0].m_fRowOffset = f5; m_unitMoveRate[f0].m_fCurveRoll = f6; m_unitMoveRate[f0].m_iPathSubdivision = iPathSubdivision; } } pMovementRates->Reset(); } // Calculate military Power and cache it DoUpdatePower(); return true; }
//------------------------------------------------------------------------------ bool CvDllDatabaseUtility::PerformDatabasePostProcessing() { //Insert any database methods that you would like performed after the database //has been fully loaded. This method will execute every single time the game //is run. //Updates performed here are done AFTER the database has been built or read //from cache. Database::Connection* db = GC.GetGameDatabase(); //Update Defines table from references in PostDefines table db->BeginTransaction(); Database::Results kPostDefines; //Build insertion statement Database::Results kInsert; db->Execute(kInsert, "INSERT INTO Defines(Name, Value) VALUES(?, ?)"); db->SelectAll(kPostDefines, "PostDefines"); while(kPostDefines.Step()) { const char* szName = kPostDefines.GetText("Name"); const char* szKeyName = kPostDefines.GetText("Key"); const char* szTableName = kPostDefines.GetText("Table"); char szSQL[512]; sprintf_s(szSQL, "select ROWID from %s where Type = '%s' LIMIT 1", szTableName, szKeyName); Database::Results kLookup; //Compile the command. if(db->Execute(kLookup, szSQL)) { //Run the command. if(kLookup.Step()) { //Perform insertion kInsert.Bind(1, szName); kInsert.Bind(2, kLookup.GetInt(0)); kInsert.Step(); kInsert.Reset(); } } } // ** Modify ResourceUsage of Resources table ** // Set ResourceUsage to 1 if it's referenced in Unit_ResourceQuantityRequirements // NOTE: This query could be simplified using the IN operator but when analyzed this // statement generates faster operations. const char* szStrategicResource = "UPDATE Resources SET ResourceUsage = 1 WHERE EXISTS (SELECT * FROM Unit_ResourceQuantityRequirements WHERE ResourceType = Type)"; db->Execute(szStrategicResource); // Set ResourceUsage to 2 if the Resource has a happiness value greater than 0 const char* szLuxoryResource = "UPDATE Resources SET ResourceUsage = 2 where Happiness > 0"; db->Execute(szLuxoryResource); //These are hard-coded GameDefines enum values, let's share them with the database so that they //get the same amount of love as the DB. Database::Results kInsertDefine; if(db->Execute(kInsertDefine, "INSERT OR REPLACE INTO Defines(Name, Value) VALUES(?, ?);")) { InsertGameDefine(kInsertDefine, "MAX_CIV_PLAYERS", MAX_CIV_PLAYERS); InsertGameDefine(kInsertDefine, "MAX_CIV_TEAMS", MAX_CIV_TEAMS); InsertGameDefine(kInsertDefine, "MAX_MAJOR_CIVS", MAX_MAJOR_CIVS); InsertGameDefine(kInsertDefine, "MAX_MINOR_CIVS", MAX_MINOR_CIVS); InsertGameDefine(kInsertDefine, "MAX_PLAYERS", MAX_PLAYERS); InsertGameDefine(kInsertDefine, "MAX_TEAMS", MAX_TEAMS); InsertGameDefine(kInsertDefine, "BARBARIAN_PLAYER", BARBARIAN_PLAYER); InsertGameDefine(kInsertDefine, "BARBARIAN_TEAM", BARBARIAN_TEAM); #if defined(MOD_GLOBAL_CITY_WORKING) InsertGameDefine(kInsertDefine, "NUM_CITY_PLOTS", AVG_CITY_PLOTS); InsertGameDefine(kInsertDefine, "MIN_CITY_RADIUS", MIN_CITY_RADIUS); InsertGameDefine(kInsertDefine, "MAX_CITY_RADIUS", MAX_CITY_RADIUS); #else InsertGameDefine(kInsertDefine, "NUM_CITY_PLOTS", NUM_CITY_PLOTS); #endif InsertGameDefine(kInsertDefine, "CITY_HOME_PLOT", CITY_HOME_PLOT); #if defined(MOD_GLOBAL_CITY_WORKING) InsertGameDefine(kInsertDefine, "MAX_CITY_RADIUS", MAX_CITY_RADIUS); InsertGameDefine(kInsertDefine, "MAX_CITY_DIAMETER", (2*MAX_CITY_RADIUS+1)); #else InsertGameDefine(kInsertDefine, "CITY_PLOTS_RADIUS", CITY_PLOTS_RADIUS); InsertGameDefine(kInsertDefine, "CITY_PLOTS_DIAMETER", CITY_PLOTS_DIAMETER); #endif } db->EndTransaction(); return true; }
void CvTypes::AcquireTypes(Database::Connection& db) { //MissionTypes { typedef std::tr1::unordered_map<std::string, MissionTypes*> LookupTable; LookupTable kMissionTypesLookupTable; kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MOVE_TO"), &s_eMISSION_MOVE_TO)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ROUTE_TO"), &s_eMISSION_ROUTE_TO)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MOVE_TO_UNIT"), &s_eMISSION_MOVE_TO_UNIT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SWAP_UNITS"), &s_eMISSION_SWAP_UNITS)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SKIP"), &s_eMISSION_SKIP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SLEEP"), &s_eMISSION_SLEEP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ALERT"), &s_eMISSION_ALERT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FORTIFY"), &s_eMISSION_FORTIFY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GARRISON"), &s_eMISSION_GARRISON)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SET_UP_FOR_RANGED_ATTACK"), &s_eMISSION_SET_UP_FOR_RANGED_ATTACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_EMBARK"), &s_eMISSION_EMBARK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DISEMBARK"), &s_eMISSION_DISEMBARK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRPATROL"), &s_eMISSION_AIRPATROL)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_HEAL"), &s_eMISSION_HEAL)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRLIFT"), &s_eMISSION_AIRLIFT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_NUKE"), &s_eMISSION_NUKE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_PARADROP"), &s_eMISSION_PARADROP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIR_SWEEP"), &s_eMISSION_AIR_SWEEP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REBASE"), &s_eMISSION_REBASE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_RANGE_ATTACK"), &s_eMISSION_RANGE_ATTACK)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_PILLAGE"), &s_eMISSION_PILLAGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FOUND"), &s_eMISSION_FOUND)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_JOIN"), &s_eMISSION_JOIN)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CONSTRUCT"), &s_eMISSION_CONSTRUCT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DISCOVER"), &s_eMISSION_DISCOVER)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_HURRY"), &s_eMISSION_HURRY)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_TRADE"), &s_eMISSION_TRADE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REPAIR_FLEET"), &s_eMISSION_REPAIR_FLEET)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SPACESHIP"), &s_eMISSION_SPACESHIP)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CULTURE_BOMB"), &s_eMISSION_CULTURE_BOMB)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_FOUND_RELIGION"), &s_eMISSION_FOUND_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_GOLDEN_AGE"), &s_eMISSION_GOLDEN_AGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_BUILD"), &s_eMISSION_BUILD)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_LEAD"), &s_eMISSION_LEAD)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DIE_ANIMATION"), &s_eMISSION_DIE_ANIMATION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_BEGIN_COMBAT"), &s_eMISSION_BEGIN_COMBAT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_END_COMBAT"), &s_eMISSION_END_COMBAT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_AIRSTRIKE"), &s_eMISSION_AIRSTRIKE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SURRENDER"), &s_eMISSION_SURRENDER)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_CAPTURED"), &s_eMISSION_CAPTURED)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_IDLE"), &s_eMISSION_IDLE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DIE"), &s_eMISSION_DIE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_DAMAGE"), &s_eMISSION_DAMAGE)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MULTI_SELECT"), &s_eMISSION_MULTI_SELECT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_MULTI_DESELECT"), &s_eMISSION_MULTI_DESELECT)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_WAIT_FOR"), &s_eMISSION_WAIT_FOR)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_SPREAD_RELIGION"), &s_eMISSION_SPREAD_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_ENHANCE_RELIGION"), &s_eMISSION_ENHANCE_RELIGION)); kMissionTypesLookupTable.insert(make_pair(std::string("MISSION_REMOVE_HERESY"), &s_eMISSION_REMOVE_HERESY)); Database::Results kResults; if(db.Execute(kResults, "SELECT Type, ID from Missions")) { while(kResults.Step()) { std::string strMissionType = kResults.GetText(0); LookupTable::iterator it = kMissionTypesLookupTable.find(strMissionType); if(it != kMissionTypesLookupTable.end()) { (*it->second) = static_cast<MissionTypes>(kResults.GetInt(1)); } } } int iNumTypes = db.Count("Missions", false); if(iNumTypes >= 0) { s_uiNUM_MISSION_TYPES = static_cast<unsigned int>(iNumTypes); } for(LookupTable::iterator it = kMissionTypesLookupTable.begin(); it != kMissionTypesLookupTable.end(); ++it) { if((*it->second) == NO_MISSION) { char msg[256] = {0}; sprintf_s(msg, "MissionType - %s is used in the DLL but does not exist in the database.", it->first.c_str()); FILogFile* pLog = LOGFILEMGR.GetLog("Gamecore.log", FILogFile::kDontTimeStamp); pLog->WarningMsg(msg); CvAssertMsg(false, msg); } } } }