Пример #1
0
//////////////////////////////////////////////////////////////////////
// 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);
		}
	}
}