Code
2052/// Determine how our recon efforts are going2053void CvEconomicAI::DoReconState()2054{2055 int iPlotLoop, iDirectionLoop, iUnitLoop;2056 CvPlot* pPlot;2057 CvPlot* pAdjacentPlot;2058 CvUnit* pLoopUnit;2059 bool bIsLand;2060 bool bIsCoastalWater;20612062 if(GetPlayer()->isMinorCiv())2063 {2064 m_eReconState = RECON_STATE_ENOUGH;2065 m_eNavalReconState = RECON_STATE_ENOUGH;2066 return;2067 }20682069 // Start at 1 so we don't get divide-by-0 errors2070 // Land recon counters2071 int iNumLandPlotsRevealed = 1;2072 int iNumLandPlotsWithAdjacentFog = 1;20732074 // Naval recon counters2075 int iNumCoastalTilesRevealed = 1;2076 int iNumCoastalTilesWithAdjacentFog = 1;20772078 bool bNeedToLookAtDeepWaterAlso = GET_TEAM(m_pPlayer->getTeam()).canEmbarkAllWaterPassage();20792080 // Look at map size and gauge how much of it we know about2081 for(iPlotLoop = 0; iPlotLoop < GC.getMap().numPlots(); iPlotLoop++)2082 {2083 pPlot = GC.getMap().plotByIndexUnchecked(iPlotLoop);20842085 if(pPlot->isRevealed(m_pPlayer->getTeam()))2086 {2087 bIsLand = false;2088 bIsCoastalWater = false;20892090 // Count Revealed Land Plots2091 if(!pPlot->isWater())2092 {2093 bIsLand = true;2094 iNumLandPlotsRevealed++;2095 }2096 else if(pPlot->isShallowWater() || bNeedToLookAtDeepWaterAlso)2097 {2098 bIsCoastalWater = true;2099 iNumCoastalTilesRevealed++;2100 }21012102 // Check adjacent Plots for THEIR visibility2103 for(iDirectionLoop = 0; iDirectionLoop < NUM_DIRECTION_TYPES; ++iDirectionLoop)2104 {2105 pAdjacentPlot = plotDirection(pPlot->getX(), pPlot->getY(), ((DirectionTypes)iDirectionLoop));21062107 if(pAdjacentPlot != NULL)2108 {2109 // Check to see if adjacent Tile is land or water...2110 if(pAdjacentPlot->isWater())2111 {2112 // This is a slight cheat (because the AI rules out water tiles) but helps prevents the AI from building too many Land explorers2113 if((bNeedToLookAtDeepWaterAlso || pAdjacentPlot->isShallowWater()) && !pAdjacentPlot->isRevealed(m_pPlayer->getTeam()))2114 {2115 iNumCoastalTilesWithAdjacentFog++;2116 break;2117 }2118 }2119 else2120 {2121 // This is a slight cheat (because the AI rules out water tiles) but helps prevents the AI from building too many Land explorers2122 if(!pAdjacentPlot->isRevealed(m_pPlayer->getTeam()))2123 {2124 iNumLandPlotsWithAdjacentFog++;2125 break;2126 }2127 }2128 }2129 }2130 }2131 }21322133 // RECON ON OUR HOME CONTINENT21342135 // How many Units do we have exploring or being trained to do this job? The more Units we have the less we want this Strategy2136 int iNumExploringUnits = m_pPlayer->GetNumUnitsWithUnitAI(UNITAI_EXPLORE, true, false) + m_iExplorersDisbanded;2137 int iStrategyWeight = /*100*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_STARTING_WEIGHT();2138 int iWeightThreshold = 110; // So result is a number from 10 to 1002139 iWeightThreshold -= m_pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_RECON")) *2140 /*10*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_WEIGHT_PER_FLAVOR();21412142 // Safety check even if personality flavor is higher than expected2143 if(iWeightThreshold > 100)2144 {2145 iWeightThreshold = 100;2146 }21472148 iStrategyWeight *= iNumLandPlotsWithAdjacentFog;2149 int iNumExplorerDivisor = iNumExploringUnits + /*1*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_EXPLORERS_WEIGHT_DIVISOR();2150 iStrategyWeight /= (iNumExplorerDivisor * iNumExplorerDivisor);2151 iStrategyWeight /= (int)sqrt((double)iNumLandPlotsRevealed);21522153 if(iStrategyWeight > iWeightThreshold)2154 {2155 m_eReconState = RECON_STATE_NEEDED;2156 }2157 else2158 {2159 if(iStrategyWeight > (iWeightThreshold / 4))2160 {2161 m_eReconState = RECON_STATE_NEUTRAL;2162 }2163 else2164 {2165 m_eReconState = RECON_STATE_ENOUGH;21662167 // Return all/most warriors/spears to normal unit AI since have enough recon. Keep at least 1 explorer through Turn 100.2168 bool bSkipFirst = GC.getGame().getGameTurn() < 100;2169 for(pLoopUnit = m_pPlayer->firstUnit(&iUnitLoop); pLoopUnit != NULL; pLoopUnit = m_pPlayer->nextUnit(&iUnitLoop))2170 {2171 if(pLoopUnit->AI_getUnitAIType() == UNITAI_EXPLORE && pLoopUnit->getUnitInfo().GetUnitAIType(UNITAI_ATTACK))2172 {2173 if(bSkipFirst)2174 {2175 bSkipFirst = false;2176 }2177 else2178 {2179 pLoopUnit->AI_setUnitAIType(UNITAI_ATTACK);2180 if(GC.getLogging() && GC.getAILogging())2181 {2182 CvString strLogString;2183 strLogString.Format("Assigning exploring %s back to attack AI, X: %d, Y: %d", pLoopUnit->getName().GetCString(), pLoopUnit->getX(), pLoopUnit->getY());2184 m_pPlayer->GetHomelandAI()->LogHomelandMessage(strLogString);2185 }2186 }2187 }2188 }2189 }2190 }21912192 // NAVAL RECON ACROSS THE ENTIRE MAP21932194 // No coastal cities? Moot point...2195 CvCity* pLoopCity;2196 int iCityLoop;2197 bool bFoundCoastalCity = false;2198 for(pLoopCity = m_pPlayer->firstCity(&iCityLoop); pLoopCity != NULL && !bFoundCoastalCity; pLoopCity = m_pPlayer->nextCity(&iCityLoop))2199 {2200 if(pLoopCity->isCoastal())2201 {2202 bFoundCoastalCity = true;2203 }2204 }22052206 if(!bFoundCoastalCity)2207 {2208 m_eNavalReconState = RECON_STATE_ENOUGH;2209 }22102211 else2212 {2213 // How many Units do we have exploring or being trained to do this job? The more Units we have the less we want this Strategy2214 iNumExploringUnits = m_pPlayer->GetNumUnitsWithUnitAI(UNITAI_EXPLORE_SEA, true, true);2215 iStrategyWeight = /*100*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_STARTING_WEIGHT();2216 iWeightThreshold = 110; // So result is a number from 10 to 1002217 iWeightThreshold -= m_pPlayer->GetGrandStrategyAI()->GetPersonalityAndGrandStrategy((FlavorTypes)GC.getInfoTypeForString("FLAVOR_NAVAL_RECON")) *2218 /*10*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_WEIGHT_PER_FLAVOR();22192220 // Safety check even if personality flavor is higher than expected2221 if(iWeightThreshold > 100)2222 {2223 iWeightThreshold = 100;2224 }22252226 iStrategyWeight *= iNumCoastalTilesWithAdjacentFog;2227 iNumExplorerDivisor = iNumExploringUnits + /*1*/ GC.getAI_STRATEGY_EARLY_EXPLORATION_EXPLORERS_WEIGHT_DIVISOR();2228 iStrategyWeight /= (iNumExplorerDivisor * iNumExplorerDivisor);2229 iStrategyWeight /= (int)sqrt((double)iNumCoastalTilesRevealed);22302231 if(iStrategyWeight > iWeightThreshold/* || iNumExploringUnits == 0 && iNumCoastalTilesWithAdjacentFog > 50*/)2232 {2233 m_eNavalReconState = RECON_STATE_NEEDED;2234 }2235 else2236 {2237 if(iStrategyWeight > (iWeightThreshold / 4))2238 {2239 m_eNavalReconState = RECON_STATE_NEUTRAL;2240 }2241 else2242 {2243 m_eNavalReconState = RECON_STATE_ENOUGH;22442245 // Return all/most boats to normal unit AI since have enough recon2246 bool bSkipFirst = (m_eNavalReconState == RECON_STATE_NEUTRAL);2247 for(pLoopUnit = m_pPlayer->firstUnit(&iUnitLoop); pLoopUnit != NULL; pLoopUnit = m_pPlayer->nextUnit(&iUnitLoop))2248 {2249 if(pLoopUnit->AI_getUnitAIType() == UNITAI_EXPLORE_SEA && pLoopUnit->getUnitInfo().GetUnitAIType(UNITAI_ATTACK_SEA))2250 {2251 if(bSkipFirst)2252 {2253 bSkipFirst = false;2254 }2255 else2256 {2257 pLoopUnit->AI_setUnitAIType(UNITAI_ATTACK_SEA);2258 if(GC.getLogging() && GC.getAILogging())2259 {2260 CvString strLogString;2261 strLogString.Format("Assigning naval explorer back to attack sea AI to %s, X: %d, Y: %d", pLoopUnit->getName().GetCString(), pLoopUnit->getX(), pLoopUnit->getY());2262 m_pPlayer->GetHomelandAI()->LogHomelandMessage(strLogString);2263 }2264 }2265 }2266 }2267 }2268 }2269 }2270}