void MapAnalysis::UpdateBoundingRectangle(const Army & army) { const PLAYER_INDEX player = army.GetOwner(); MapPoint xy_pos(0, 0); MapPoint rc_pos; army.GetPos(rc_pos); xy_pos.rc2xy(rc_pos, * g_theWorld->GetSize()); MapPoint xy_map_size(g_theWorld->GetWidth() * 2, g_theWorld->GetHeight()); if (!m_empireBoundingRect[player].IsValid()) { m_empireBoundingRect[player].Initialize (xy_pos, 2, xy_map_size, g_theWorld->IsXwrap(), g_theWorld->IsYwrap()); } BoundingRect armyRect(xy_pos, 2, xy_map_size, g_theWorld->IsXwrap(), g_theWorld->IsYwrap()); bool added = m_empireBoundingRect[player].Add(armyRect); Assert(added); m_empireCenter[player].xy2rc(m_empireBoundingRect[player].GetCenter(), * g_theWorld->GetSize()); DPRINTF(k_DBG_SCHEDULER, ("Empire Center for player %d : rc(%3d,%3d) \n", player, m_empireCenter[player].x, m_empireCenter[player].y)); }
bool SettleMap::HasSettleTargets(const PLAYER_INDEX &playerId, bool isWater) const { BoundingRect rect = MapAnalysis::GetMapAnalysis().GetBoundingRectangle(playerId); if (!rect.IsValid()) return false; rect.Expand( 10 ); MapPoint xy_pos(0,0); MapPoint rc_pos(0,0); SettleTarget settle_target; sint16 rows = rect.GetMaxRows(); sint16 cols = rect.GetMaxCols(); sint32 settle_threshold = 0; (void) Diplomat::GetDiplomat(playerId).GetCurrentStrategy().GetMinSettleScore(settle_threshold); for(sint32 i = 0; rect.Get(i, xy_pos, rows, cols); i++) { #if defined(USE_WORLDSIZE_CLASS) rc_pos.xy2rc(xy_pos, g_theWorld->GetSize()); #else rc_pos.xy2rc(xy_pos, *g_theWorld->GetSize()); #endif if(!CanSettlePos(rc_pos)) continue; if(m_settleValues.GetGridValue(rc_pos) <= settle_threshold) { continue; } if(g_theWorld->IsWater(rc_pos) == isWater) { return true; } } return false; }
void SettleMap::GetSettleTargets(const PLAYER_INDEX &playerId, SettleMap::SettleTargetList & targets) const { BoundingRect rect = MapAnalysis::GetMapAnalysis().GetBoundingRectangle(playerId); if (!rect.IsValid()) return; rect.Expand( 10 ); MapPoint xy_pos(0,0); MapPoint rc_pos(0,0); SettleTarget settle_target; sint16 rows = rect.GetMaxRows(); sint16 cols = rect.GetMaxCols(); sint32 settle_threshold = 0; (void) Diplomat::GetDiplomat(playerId).GetCurrentStrategy().GetMinSettleScore(settle_threshold); Player *player_ptr = g_player[playerId]; Assert(player_ptr); if(!player_ptr) return; sint32 numTerrain = g_theTerrainDB->NumRecords(); bool* settleTerrainTypes = new bool[numTerrain]; std::fill(settleTerrainTypes, settleTerrainTypes + numTerrain, false); bool noSettleUnits = true; Unit unit; sint32 i; Assert(player_ptr->m_all_units); for(i = 0; i < player_ptr->m_all_units->Num(); ++i) { unit = player_ptr->m_all_units->Access(i); const UnitRecord* rec = player_ptr->m_all_units->Access(i).GetDBRec(); Assert(rec); if(!rec) continue; if(rec->GetNumCanSettleOn() > 0) { for(sint32 j = 0; j < rec->GetNumCanSettleOn(); ++j){ settleTerrainTypes[rec->GetCanSettleOnIndex(j)] = true; noSettleUnits = false; } } else { for(sint32 j = 0; j < numTerrain; ++j) { const TerrainRecord* trec = g_theTerrainDB->Get(j); if(trec->GetMovementTypeLand() && rec->GetSettleLand() || trec->GetMovementTypeMountain() && rec->GetSettleMountain() ||(trec->GetMovementTypeSea() || trec->GetMovementTypeShallowWater()) && rec->GetSettleWater() || trec->GetMovementTypeSpace() && rec->GetSettleSpace() ){ settleTerrainTypes[j] = true; noSettleUnits = false; } } } } if(noSettleUnits) { delete [] settleTerrainTypes; return; } for(i = 0; rect.Get(i, xy_pos, rows, cols); i++) { #if defined(USE_WORLDSIZE_CLASS) rc_pos.xy2rc(xy_pos, g_theWorld->GetSize()); #else rc_pos.xy2rc(xy_pos, *g_theWorld->GetSize()); #endif settle_target.m_value = m_settleValues.GetGridValue(rc_pos); settle_target.m_pos = rc_pos; if(g_graphicsOptions->IsCellTextOn()) { char buf[16]; sprintf(buf,"*%4.0f*",settle_target.m_value); g_graphicsOptions->AddTextToCell(rc_pos, buf, 255); } if(!CanSettlePos(rc_pos)) continue; if(settle_target.m_value <= settle_threshold) { if (g_graphicsOptions->IsCellTextOn()) { char buf[16]; sprintf(buf,"(%4.0f)",settle_target.m_value); g_graphicsOptions->AddTextToCell(rc_pos, buf, 255); } continue; } if(!settleTerrainTypes[g_theWorld->GetTerrainType(rc_pos)]) continue; if(g_graphicsOptions->IsCellTextOn()) { char buf[16]; sprintf(buf,"%4.0f",settle_target.m_value); g_graphicsOptions->AddTextToCell(rc_pos, buf, 255); } targets.push_back(settle_target); } delete [] settleTerrainTypes; if (targets.empty()) { return; } targets.sort(std::greater<SettleTarget>()); sint16 max_water_cont = g_theWorld->GetMaxWaterContinent() - g_theWorld->GetMinWaterContinent(); sint16 max_land_cont = g_theWorld->GetMaxLandContinent () - g_theWorld->GetMinLandContinent (); std::vector<sint16> water_continent_count(max_water_cont, 0); std::vector<sint16> land_continent_count(max_land_cont, 0); bool is_land; sint16 cont; const StrategyRecord & strategy = Diplomat::GetDiplomat(playerId).GetCurrentStrategy(); sint32 min_settle_distance = 0; (void) strategy.GetMinSettleDistance(min_settle_distance); SettleMap::SettleTargetList::iterator iter = targets.begin(); SettleMap::SettleTargetList::iterator tmp_iter; settle_target = *iter; // non-emptyness verified before ++iter; while (iter != targets.end()) { g_theWorld->GetContinent(iter->m_pos, cont, is_land); #ifdef _DEBUG if (is_land) {Assert(cont < max_land_cont);} else {Assert(cont < max_water_cont);} #endif _DEBUG Assert(cont >= 0); if ((is_land && (land_continent_count[cont] >= k_targets_per_continent)) || (!is_land && (water_continent_count[cont] >= k_targets_per_continent))) { iter = targets.erase(iter); } else { for (tmp_iter = targets.begin(); tmp_iter != iter; ++tmp_iter) { if(MapPoint::GetSquaredDistance(iter->m_pos, tmp_iter->m_pos) < (min_settle_distance * min_settle_distance) ) { break; } } if (tmp_iter == iter) { ++iter; } else { iter = targets.erase(iter); continue; } if (is_land) { if (land_continent_count[cont] == 0) { iter->m_value += 2; } land_continent_count[cont]++; } else { if (water_continent_count[cont] == 0) { iter->m_value += 2; } water_continent_count[cont]++; } } } targets.sort(std::greater<SettleTarget>()); }