Hooks
static bool BeforeCvBuilderTaskingAI_AddImprovingPlotsDirectives(CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);static void AfterCvBuilderTaskingAI_AddImprovingPlotsDirectives(CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);static void ReplaceCvBuilderTaskingAI_AddImprovingPlotsDirectives(void (*original)(CvBuilderTaskingAI*, CvUnit*, CvPlot*, int), CvBuilderTaskingAI* self, CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway);CivRegisterBefore<CivHooks::CvBuilderTaskingAI_AddImprovingPlotsDirectives>(host, &BeforeCvBuilderTaskingAI_AddImprovingPlotsDirectives);CivRegisterAfter<CivHooks::CvBuilderTaskingAI_AddImprovingPlotsDirectives>(host, &AfterCvBuilderTaskingAI_AddImprovingPlotsDirectives);CivRegisterReplace<CivHooks::CvBuilderTaskingAI_AddImprovingPlotsDirectives>(host, &ReplaceCvBuilderTaskingAI_AddImprovingPlotsDirectives);
Code
1039/// Evaluating a plot to determine what improvement could be best there1040void CvBuilderTaskingAI::AddImprovingPlotsDirectives(CvUnit* pUnit, CvPlot* pPlot, int iMoveTurnsAway)1041{1042 ImprovementTypes eExistingImprovement = pPlot->getImprovementType();10431044 // Do we have a special improvement here? (great person improvement, gifted improvement from major civ)1045 if(eExistingImprovement != NO_IMPROVEMENT && pPlot->HasSpecialImprovement() && !pPlot->IsImprovementPillaged())1046 {1047 return;1048 }10491050 // if it's not within a city radius1051 if(!pPlot->isWithinTeamCityRadius(pUnit->getTeam()))1052 {1053 return;1054 }10551056 // check to see if a non-bonus resource is here. if so, bail out!1057 ResourceTypes eResource = pPlot->getResourceType(m_pPlayer->getTeam());1058 if(eResource != NO_RESOURCE)1059 {1060 if(GC.getResourceInfo(eResource)->getResourceUsage() != RESOURCEUSAGE_BONUS)1061 {1062 return;1063 }1064 }10651066 // celtic rule: if this is a forest tile next to a city, do not improve this tile with a normal improvement1067 if (m_pPlayer->GetPlayerTraits()->IsFaithFromUnimprovedForest() && eExistingImprovement == NO_IMPROVEMENT)1068 {1069 CvCity* pNextCity = pPlot->GetAdjacentCity();1070 if (pNextCity && pNextCity->getOwner() == m_pPlayer->GetID())1071 {1072 if (pPlot->getFeatureType() == FEATURE_FOREST)1073 {1074 return;1075 }1076 }1077 }10781079 CvCity* pCity = GetWorkingCity(pPlot);1080 if(!pCity)1081 {1082 return;1083 }10841085 // loop through the build types to find one that we can use1086 BuildTypes eBuild;1087 BuildTypes eOriginalBuildType;1088 int iBuildIndex;1089 for(iBuildIndex = 0; iBuildIndex < GC.getNumBuildInfos(); iBuildIndex++)1090 {1091 eBuild = (BuildTypes)iBuildIndex;1092 eOriginalBuildType = eBuild;1093 CvBuildInfo* pkBuild = GC.getBuildInfo(eBuild);1094 if(pkBuild == NULL)1095 {1096 continue;1097 }10981099 ImprovementTypes eImprovement = (ImprovementTypes)pkBuild->getImprovement();1100 if(eImprovement == NO_IMPROVEMENT)1101 {1102 continue;1103 }11041105 CvImprovementEntry* pImprovement = GC.getImprovementInfo(eImprovement);11061107 // if this improvement has a defense modifier, ignore it for now1108 //if(pImprovement->GetDefenseModifier() > 0)1109 //{1110 // continue;1111 //}11121113 // for bonus resources, check to see if this is the improvement that connects it1114 if(eResource != NO_RESOURCE)1115 {1116 if(!pImprovement->IsImprovementResourceTrade(eResource))1117 {1118 if(m_bLogging){1119 CvString strTemp;1120 strTemp.Format("Weight,!pImprovement->IsImprovementResourceTrade(eResource),%s,%i,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), eResource, pPlot->getX(), pPlot->getY());1121 LogInfo(strTemp, m_pPlayer);1122 }1123 continue;1124 }1125 }11261127 if(eImprovement == pPlot->getImprovementType())1128 {1129 if(pPlot->IsImprovementPillaged())1130 {1131 eBuild = m_eRepairBuild;1132 }1133 else1134 {1135 if(m_bLogging){1136 CvString strTemp;1137 strTemp.Format("Weight,eImprovement == pPlot->getImprovementType(),%s,%i,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), eImprovement, pPlot->getX(), pPlot->getY());1138 LogInfo(strTemp, m_pPlayer);1139 }1140 continue;1141 }1142 }1143 else1144 {1145 // Do we have a special improvement here? (great person improvement, gifted improvement from major civ)1146 if (eExistingImprovement != NO_IMPROVEMENT)1147 {1148 if (pPlot->HasSpecialImprovement() || GET_PLAYER(pUnit->getOwner()).isOption(PLAYEROPTION_SAFE_AUTOMATION))1149 {1150 if(m_bLogging){1151 CvString strTemp;1152 strTemp.Format("Weight,Improvement Type Blocked by Special Improvement,%s,,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), pPlot->getX(), pPlot->getY());1153 LogInfo(strTemp, m_pPlayer);1154 }1155 continue;1156 }1157 }1158 }11591160 // Only check to make sure our unit can build this after possibly switching this to a repair build in the block of code above1161 if(!pUnit->canBuild(pPlot, eBuild))1162 {1163 if(m_bLogging){1164 CvString strTemp;1165 strTemp.Format("Weight,!pUnit->canBuild(),%s,,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), pPlot->getX(), pPlot->getY());1166 LogInfo(strTemp, m_pPlayer);1167 }1168 continue;1169 }11701171 bool bWillRemoveForestOrJungle = false;1172 FeatureTypes eFeature = pPlot->getFeatureType();1173 if(eFeature == FEATURE_FOREST || eFeature == FEATURE_JUNGLE)1174 {1175 if(pkBuild->isFeatureRemove(eFeature))1176 {1177 bWillRemoveForestOrJungle = true;1178 }1179 }11801181 // special case for Dutch1182 if (m_bKeepMarshes && eFeature == FEATURE_MARSH)1183 {1184 if (pkBuild->isFeatureRemove(FEATURE_MARSH))1185 {1186 if(m_bLogging){1187 CvString strTemp;1188 strTemp.Format("Weight,Marsh Remove,%s,,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), pPlot->getX(), pPlot->getY());1189 LogInfo(strTemp, m_pPlayer);1190 }1191 continue;1192 }1193 }11941195 // special case for Brazil1196 if (m_bKeepJungle && eFeature == FEATURE_JUNGLE)1197 {1198 if (pkBuild->isFeatureRemove(FEATURE_JUNGLE))1199 {1200 if(m_bLogging){1201 CvString strTemp;1202 strTemp.Format("Weight,Jungle Remove,%s,,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), pPlot->getX(), pPlot->getY());1203 LogInfo(strTemp, m_pPlayer);1204 }1205 if (pPlot->getResourceType(m_pPlayer->getTeam()) == NO_RESOURCE)1206 {1207 continue;1208 }1209 }1210 }12111212 if(GET_PLAYER(pUnit->getOwner()).isOption(PLAYEROPTION_LEAVE_FORESTS))1213 {1214 if(eFeature != NO_FEATURE)1215 {1216 if(pkBuild->isFeatureRemove(eFeature))1217 {1218 if(m_bLogging){1219 CvString strTemp;1220 strTemp.Format("Weight,Keep Forests,%s,,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), pPlot->getX(), pPlot->getY());1221 LogInfo(strTemp, m_pPlayer);1222 }1223 continue;1224 }1225 }1226 }12271228 UpdateProjectedPlotYields(pPlot, eBuild);1229 int iScore = ScorePlot();12301231 // if we're going backward, bail out!1232 if(iScore <= 0)1233 {1234 if(m_bLogging){1235 CvString strTemp;1236 strTemp.Format("Weight,Negative Score,%s,%i,,,%i, %i", GC.getBuildInfo(eBuild)->GetType(), iScore, pPlot->getX(), pPlot->getY());1237 LogInfo(strTemp, m_pPlayer);1238 }1239 continue;1240 }12411242 BuilderDirective::BuilderDirectiveType eDirectiveType = BuilderDirective::BUILD_IMPROVEMENT;1243 int iWeight = GC.getBUILDER_TASKING_BASELINE_BUILD_IMPROVEMENTS();1244 if(eBuild == m_eRepairBuild)1245 {1246 eDirectiveType = BuilderDirective::REPAIR;1247 iWeight = GC.getBUILDER_TASKING_BASELINE_REPAIR();1248 }1249#if defined(MOD_API_UNIFIED_YIELDS)1250 else1251 {1252 for(int iI = 0; iI < NUM_YIELD_TYPES; iI++)1253 {1254 YieldTypes eYield = (YieldTypes) iI;1255 if(pImprovement->GetYieldChange(iI) > 0)1256 {1257 iWeight = GC.getBUILDER_TASKING_BASELINE_ADDS_CULTURE() * GC.getImprovementInfo(eImprovement)->GetYieldChange(iI);1258 int iAdjacentCulture = pImprovement->GetYieldAdjacentSameType(eYield);12591260 if(iAdjacentCulture > 0)1261 {1262 iScore *= (1 + pPlot->ComputeYieldFromAdjacentImprovement(*pImprovement, eImprovement, eYield));1263 }1264 }1265 }1266 }1267#else1268 else if(pImprovement->GetYieldChange(YIELD_CULTURE) > 0)1269 {1270 iWeight = GC.getBUILDER_TASKING_BASELINE_ADDS_CULTURE() * GC.getImprovementInfo(eImprovement)->GetYieldChange(YIELD_CULTURE);1271 int iAdjacentCulture = pImprovement->GetCultureAdjacentSameType();12721273 if(iAdjacentCulture > 0)1274 {1275 iScore *= (1 + pPlot->ComputeCultureFromAdjacentImprovement(*pImprovement, eImprovement));1276 }1277 }1278#endif1279 iWeight = GetBuildCostWeight(iWeight, pPlot, eBuild);1280 int iBuildTimeWeight = GetBuildTimeWeight(pUnit, pPlot, eBuild, DoesBuildHelpRush(pUnit, pPlot, eBuild), iMoveTurnsAway);1281 iWeight += iBuildTimeWeight;1282 iWeight *= iScore;12831284 if(m_pPlayer->GetPlayerTraits()->IsMoveFriendlyWoodsAsRoad() && bWillRemoveForestOrJungle)1285 {1286 iWeight = iWeight / 4;1287 }12881289 iWeight = CorrectWeight(iWeight);12901291 BuilderDirective directive;12921293 directive.m_eDirective = eDirectiveType;1294 directive.m_eBuild = eBuild;1295 directive.m_eResource = NO_RESOURCE;1296 directive.m_sX = pPlot->getX();1297 directive.m_sY = pPlot->getY();1298 directive.m_sMoveTurnsAway = iMoveTurnsAway;12991300 if(m_bLogging)1301 {1302 CvString strTemp;1303 strTemp.Format("Weight,Directive Score Added,%s,,,,%i, %i, %i, %d", GC.getBuildInfo(eBuild)->GetType(), directive.m_sX, directive.m_sY, directive.m_sMoveTurnsAway, iWeight);1304 LogInfo(strTemp, m_pPlayer);1305 }13061307 m_aDirectives.push_back(directive, iWeight);1308 }1309}