////////////////////////////////////////////////////////////////////// // sonstige Funktionen ////////////////////////////////////////////////////////////////////// /// Diese Funktion erteilt allen Schiffen aller computergesteuerten Rassen Befehle. void CShipAI::CalculateShipOrders(CSectorAI* SectorAI) { ASSERT(SectorAI); m_pSectorAI = SectorAI; // einen möglichen Angriffssektor berechnen lassen CalcAttackSector(); // danach einen möglichen Bombardierungssektor finden CalcBombardSector(); for(CShipMap::iterator i = m_pDoc->m_ShipMap.begin(); i != m_pDoc->m_ShipMap.end(); ++i) { if(i->second->IsAlien()) { CalculateAlienShipOrders(*i->second); continue; } const CString& sOwner = i->second->GetOwnerOfShip(); CMajor* pOwner = dynamic_cast<CMajor*>(m_pDoc->GetRaceCtrl()->GetRace(sOwner)); // gilt erstmal nur für Majors if (!pOwner || !pOwner->IsMajor()) continue; // gilt nicht für menschliche Spieler if (pOwner->AHumanPlays()) continue; // Flotte versuchen zu erstellen DoMakeFleet(i); // Vielleicht haben unsere Schiffe ein Ziel, welches sie angreifen müssen/können if (DoAttackMove(i->second, pOwner)) { DoCamouflage(i->second); continue; } // haben Kolonieschiffe einen Sektor zum Terraformen als Ziel, welcher kurz zuvor aber von einer // anderen Rasse weggeschnappt wurde, so wird ihr Kurs gelöscht if (i->second->GetShipType() == SHIP_TYPE::COLONYSHIP) { CPoint ptKO = i->second->GetKO(); // hat das Kolonieschiff den Befehl zum Terraformen, so wird dieser rückgängig gemacht, wenn der Sektor // schon einer anderen Rasse gehört if (i->second->GetCurrentOrder() == SHIP_ORDER::TERRAFORM) { if (m_pDoc->GetSector(ptKO.x, ptKO.y).GetOwnerOfSector() != "" && m_pDoc->GetSector(ptKO.x, ptKO.y).GetOwnerOfSector() != sOwner) { // Terraforming abbrechen i->second->UnsetCurrentOrder(); i->second->SetCombatTactic(COMBAT_TACTIC::CT_AVOID); } } CPoint ptTarget = i->second->GetTargetKO(); // nur wenn der Sektor noch niemandem gehört bzw. uns selbst ist, sollen Planeten terraformt werden if (ptTarget != CPoint(-1,-1) && m_pDoc->GetSector(ptTarget.x, ptTarget.y).GetOwnerOfSector() != "" && m_pDoc->GetSector(ptTarget.x, ptTarget.y).GetOwnerOfSector() != sOwner) { // nicht weiter fliegen und Kurs löschen i->second->SetTargetKO(CPoint(-1, -1)); i->second->GetPath()->RemoveAll(); } } // exisitiert kein aktueller Kurs, so wird dieser hier versucht dem Schiff zu erteilen if (i->second->GetPath()->GetSize() == 0) { // Scouts und Kriegsschiffe fliegen zuerst einmal zu den Minorracesystemen if (i->second->GetShipType() > SHIP_TYPE::COLONYSHIP) { // Zeiger auf Vektor mit Minorracessektoren holen vector<CPoint>* vMinorraceSectors = m_pSectorAI->GetMinorraceSectors(sOwner); bool bSet = false; int nCount = vMinorraceSectors->size() * 2; while (vMinorraceSectors->size() && nCount--) { int j = rand()%vMinorraceSectors->size(); CPoint ko = vMinorraceSectors->at(j); // Wenn Gefahr der anderen Rassen kleiner als die der meinen ist if (m_pSectorAI->GetCompleteDanger(sOwner, ko) == NULL || (m_pSectorAI->GetCompleteDanger(sOwner, ko) <= m_pSectorAI->GetDangerOnlyFromCombatShips(sOwner, i->second->GetKO()))) if (pOwner->GetStarmap()->GetRange(ko) <= i->second->GetRange(false)) { // Zielkoordinate für das Schiff setzen i->second->SetTargetKO(ko); MYTRACE("shipai")(MT::LEVEL_DEBUG, "Race %s: Ship to Minor: %s (%s) - Target: %d,%d\n",sOwner, i->second->GetShipName(), i->second->GetShipTypeAsString(), ko.x,ko.y); vMinorraceSectors->erase(vMinorraceSectors->begin() + j--); bSet = true; break; } } if (bSet) { DoCamouflage(i->second); continue; } } // Kolonieschiffe zum Terraformen schicken. Andere Schiffe fliegen manchmal auch dort hin, wenn // sie gerade keinen anderen Flugauftrag haben. if (i->second->GetShipType() >= SHIP_TYPE::COLONYSHIP && i->second->GetCurrentOrder() != SHIP_ORDER::TERRAFORM) { // Zeiger auf Vektor mit Terraformsektoren holen vector<CSectorAI::SectorToTerraform>* vSectorsToTerrform = m_pSectorAI->GetSectorsToTerraform(sOwner); for (UINT j = 0; j < vSectorsToTerrform->size(); j++) { CPoint ko = vSectorsToTerrform->at(j).p; // Wenn das Kolonieschiff schon auf einem Sektor für unser Terraforming steht, so fliegt es nicht weiter if (i->second->GetShipType() == SHIP_TYPE::COLONYSHIP && i->second->GetKO() == ko) break; // Wenn Gefahr der anderen Rassen kleiner als die der meinen ist if (m_pSectorAI->GetCompleteDanger(sOwner, ko) == NULL || (m_pSectorAI->GetCompleteDanger(sOwner, ko) < m_pSectorAI->GetDanger(sOwner, i->second->GetKO()))) { if (pOwner->GetStarmap()->GetRange(ko) <= i->second->GetRange(false)) { // Zielkoordinate für das Schiff setzen i->second->SetTargetKO(ko == i->second->GetKO() ? CPoint(-1, -1) : ko); MYTRACE("shipai")(MT::LEVEL_DEBUG, "Race %s: Ship %s (%s) has terraforming target: %d,%d\n",sOwner, i->second->GetShipName(), i->second->GetShipTypeAsString(), ko.x,ko.y); break; } } } } // Truppentransporter zu einem möglichen Sektor fliegen lassen um dort einen Außenposten bauen zu können if (m_pSectorAI->GetStationBuildSector(sOwner).points > MINBASEPOINTS && i->second->GetCurrentOrder() != SHIP_ORDER::BUILD_OUTPOST) { // nur Truppentransporter oder andere Schiffe ohne Ziel fliegen zu diesem Punkt, niemals aber // Kolonieschiffe if (i->second->GetShipType() == SHIP_TYPE::TRANSPORTER || (i->second->GetShipType() != SHIP_TYPE::COLONYSHIP && !i->second->HasTarget())) { CPoint ko(m_pSectorAI->GetStationBuildSector(sOwner).position.x, m_pSectorAI->GetStationBuildSector(sOwner).position.y); // Wenn Gefahr der anderen Rassen kleiner als die der meinen ist if (m_pSectorAI->GetCompleteDanger(sOwner, ko) == 0 || (m_pSectorAI->GetCompleteDanger(sOwner, ko) < m_pSectorAI->GetDanger(sOwner, i->second->GetKO()))) { if (pOwner->GetStarmap()->GetRange(ko) <= i->second->GetRange(false)) { // Zielkoordinate für das Schiff setzen i->second->SetTargetKO(ko == i->second->GetKO() ? CPoint(-1, -1) : ko); MYTRACE("shipai")(MT::LEVEL_DEBUG, "Race %s: Ship %s (%s) has stationbuild target: %d,%d\n",sOwner, i->second->GetShipName(), i->second->GetShipTypeAsString(), ko.x,ko.y); } } } } DoCamouflage(i->second); if (m_pDoc->GetSector(i->second->GetKO().x, i->second->GetKO().y).GetSunSystem()) { if (!DoTerraform(i->second)) DoColonize(i->second); } DoStationBuild(i->second); } else { DoCamouflage(i->second); } } }