/// Funktion überprüft ob das in der Designansicht angeklickte Schiff in einem unserer Systeme gerade gebaut wird
/// Man benötigt diesen Check da man keine Schiffe ändern kann, welche gerade gebaut werden.
/// @param pShipInfo Zeiger des zu prüfenden Schiffes aus der Schiffsliste
/// @return CString mit dem Namen des Systems, wird das Schiff nirgends gebaut ist der String leer
CString CShipDesignMenuView::CheckIfShipIsBuilding(const CShipInfo* pShipInfo) const
{
	if (!pShipInfo)
		return "";

	CBotEDoc* pDoc = resources::pDoc;
	ASSERT(pDoc);

	CMajor* pMajor = m_pPlayersRace;
	ASSERT(pMajor);
	if (!pMajor)
		return "";

	USHORT ID = pShipInfo->GetID();
	// alle eigenen Systeme durchgehen und schauen, ob an erster Stelle in der Bauliste so ein Schiff steht
	for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++)
		for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++)
			if (pDoc->GetSystem(x,y).GetOwnerOfSystem() == pMajor->GetRaceID())
				for (int i = 0; i < ALE; i++)
					if (pDoc->GetSystem(x,y).GetAssemblyList()->GetAssemblyListEntry(i) == ID)
						return pDoc->GetSector(x,y).GetName();

	return "";
}
Пример #2
0
void CIntelBottomView::OnDraw(CDC* dc)
{
	CBotEDoc* pDoc = resources::pDoc;
	AssertBotE(pDoc);

	if (!pDoc->m_bDataReceived)
		return;

	CMajor* pMajor = m_pPlayersRace;
	AssertBotE(pMajor);
	if (!pMajor)
		return;
	// TODO: add draw code here

	// Doublebuffering wird initialisiert
	CMyMemDC pDC(dc);
	CRect client;
	GetClientRect(&client);

	// Graphicsobjekt, in welches gezeichnet wird anlegen
	Graphics g(pDC->GetSafeHdc());

	g.Clear(static_cast<Gdiplus::ARGB>(Color::Black));
	g.SetSmoothingMode(SmoothingModeHighSpeed);
	g.SetInterpolationMode(InterpolationModeLowQuality);
	g.SetPixelOffsetMode(PixelOffsetModeHighSpeed);
	g.SetCompositingQuality(CompositingQualityHighSpeed);
	g.ScaleTransform((REAL)client.Width() / (REAL)m_TotalSize.cx, (REAL)client.Height() / (REAL)m_TotalSize.cy);

	CString fontName = "";
	Gdiplus::REAL fontSize = 0.0;
	StringFormat fontFormat;
	SolidBrush fontBrush(static_cast<Gdiplus::ARGB>(Color::White));

	Color color;
	color.SetFromCOLORREF(pMajor->GetDesign()->m_clrGalaxySectorText);

	fontBrush.SetColor(color);
	Bitmap* graphic = pDoc->GetGraphicPool()->GetGDIGraphic("Backgrounds\\" + pMajor->GetPrefix() + "diplomacyV3.boj");

	// Grafik zeichnen
	if (graphic)
	{
		g.DrawImage(graphic, 0, 0, 1075, 249);
		graphic = NULL;
	}

	// Nur in bestimmten Submenüs werden in der View3 Berichte angezeigt
	BYTE curIntelSubMenu = resources::pMainFrame->GetSubMenu(RUNTIME_CLASS(CIntelMenuView));
	if (curIntelSubMenu == 4 || curIntelSubMenu == 5)
	{
		CRect r;
		r.SetRect(0,0,m_TotalSize.cx,m_TotalSize.cy);
		short n = pMajor->GetEmpire()->GetIntelligence()->GetIntelReports()->GetActiveReport();
		if (n != -1)
		{
			CFontLoader::CreateGDIFont(pMajor, 4, fontName, fontSize);
			fontFormat.SetAlignment(StringAlignmentNear);
			fontFormat.SetLineAlignment(StringAlignmentNear);
			fontFormat.SetFormatFlags(StringFormatFlagsNoWrap);
			CIntelObject* report = pMajor->GetEmpire()->GetIntelligence()->GetIntelReports()->GetReport(n);
			CString s;
			if (report->GetIsSpy())
				s = CLoc::GetString("SPY");
			else
				s = CLoc::GetString("SABOTAGE");
			g.DrawString(CComBSTR(s), -1, &Gdiplus::Font(CComBSTR(fontName), fontSize), RectF(40, 40, r.right-100, r.bottom-20), &fontFormat, &fontBrush);

			CFontLoader::CreateGDIFont(pMajor, 2, fontName, fontSize);
			fontBrush.SetColor(Color(200,200,250));
			fontFormat.SetFormatFlags(!StringFormatFlagsNoWrap);
			if (report->GetOwner() == pMajor->GetRaceID())
				s = *report->GetOwnerDesc();
			else
				s = *report->GetEnemyDesc();
			g.DrawString(CComBSTR(s), -1, &Gdiplus::Font(CComBSTR(fontName), fontSize), RectF(40, 100, r.right-250, r.bottom-20), &fontFormat, &fontBrush);
		}
	}
	g.ReleaseHDC(pDC->GetSafeHdc());
}
Пример #3
0
void CRandomEventCtrl::CalcShipEvents() const
{
	if (!IsActivated())
		return;

	CBotEDoc* pDoc = resources::pDoc;
	AssertBotE(pDoc);

	// Hüllenvirus
	for (int x = 0; x < STARMAP_SECTORS_HCOUNT; x++)
	{
		for (int y = 0; y < STARMAP_SECTORS_VCOUNT; y++)
		{
			// 0.1% Wahrscheinlichkeit für einen Hüllenvirus pro Sektor
			if (rand()%1000 != 0)
				continue;

			// gibt es keine Schiffe im Sektor, dann macht ein Hüllenvirus auch nichts
			CSector* pSector = &(pDoc->GetSystem(x, y));
			if (!pSector->GetIsShipInSector())
				continue;

			// allen Schiffe im Sektor die Hülle auf 1 reduzieren (außer Aliens)
			for (CShipMap::iterator i = pDoc->m_ShipMap.begin(); i != pDoc->m_ShipMap.end(); ++i)
			{
				if (i->second->IsAlien())
					continue;

				if (i->second->GetCo() != pSector->GetCo())
					continue;

				int nCurrentHull = i->second->GetHull()->GetCurrentHull();
				i->second->GetHull()->SetCurrentHull(-(nCurrentHull - 1), true);

				// allen Schiffen in der Flotte ebenfalls die Hülle auf 1 setzen
				for (CShips::iterator j = i->second->begin(); j != i->second->end(); ++j)
				{
					nCurrentHull = j->second->GetHull()->GetCurrentHull();
					j->second->GetHull()->SetCurrentHull(-(nCurrentHull - 1), true);
				}
			}

			// Nachrichten an alle Major welche Schiffe in diesem Sektor hatten
			const std::map<CString, CMajor*>* pmMajors = pDoc->GetRaceCtrl()->GetMajors();
			for (map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
			{
				if (!pSector->GetOwnerOfShip(it->first, true))
					continue;

				CMajor* pMajor = it->second;
				if (!pMajor)
					continue;

				const CString& sSectorName = pSector->CoordsName(true);

				CString sMessageText = CLoc::GetString("EVENTHULLVIRUS", false, sSectorName);
				CEmpireNews message;
				message.CreateNews(sMessageText,EMPIRE_NEWS_TYPE::MILITARY,pSector->GetName(),pSector->GetCo());
				pMajor->GetEmpire()->AddMsg(message);

				if (pMajor->IsHumanPlayer())
				{
					resources::pClientWorker->SetToEmpireViewFor(*pMajor);
					pMajor->GetEmpire()->PushEvent(boost::make_shared<CEventRandom>(pMajor->GetRaceID(), "HullVirus", sMessageText, ""));
				}
			}
		}
	}
}
Пример #4
0
//////////////////////////////////////////////////////////////////////
// sonstige Funktionen
//////////////////////////////////////////////////////////////////////
/// Funktion berechnet den Umgang mit dem Geheimdienst für die KI. Sie trifft Zuteilungen für die einzelnen Rassen.
void CIntelAI::CalcIntelligence(CBotEDoc* pDoc)
{
	AssertBotE(pDoc);

	// Struktur für eine Liste mit Rassen-ID und Geheimdienstpunkten
	struct INTELLIST {
		CString sRace;
		UINT points;

		bool operator< (const INTELLIST& elem2) const { return points < elem2.points;}
		bool operator> (const INTELLIST& elem2) const { return points > elem2.points;}
		INTELLIST() : sRace(""), points(0) {}
		INTELLIST(const CString& _sRace, UINT _points) : sRace(_sRace), points(_points) {}
	};

	// produzierte Geheimdienstpunkte und Punkte aus allen Geheimdienstlagern einer Rasse zusammenaddieren
	CArray<INTELLIST> intellist;
	std::map<CString, CMajor*>* pmMajors = pDoc->GetRaceCtrl()->GetMajors();
	for (std::map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
	{
		CIntelligence* pIntel = it->second->GetEmpire()->GetIntelligence();
		UINT points = pIntel->GetSecurityPoints() + pIntel->GetInnerSecurityStorage();
		for (map<CString, CMajor*>::const_iterator itt = pmMajors->begin(); itt != pmMajors->end(); ++itt)
			if (itt->first != it->first)
				points += pIntel->GetSPStorage(0, itt->first) + pIntel->GetSPStorage(1, itt->first);
		intellist.Add(INTELLIST(it->first, points));
	}
	// nun Feld nach den gesammten Geheimdienstpunkten absteigend sortiren lassen.
	c_arraysort<CArray<INTELLIST>, INTELLIST> (intellist, sort_desc);
	// unere Priorität ist der Index der Rasse im Feld.
	// wenn die Punkte sich nicht mehr als 10% bzw. 100SP unterscheiden, dann wird die Priorität des vorherigen
	// Indexes benutzt.
	m_byIntelPrio[intellist.GetAt(0).sRace] = rand()%2;
	for (int i = 1; i < intellist.GetSize(); i++)	// beim zweiten Index starten! Da das erste Element eine 0er Priorität hat
	{
		if (intellist.GetAt(i-1).points - intellist.GetAt(i).points > 100
			&& (intellist.GetAt(i).points * 100 / (intellist.GetAt(i-1).points+1) < 90))
			m_byIntelPrio[intellist.GetAt(i).sRace] = i;
		// ansonsten ist die Priorität der des Vorgängers
		else
			m_byIntelPrio[intellist.GetAt(i).sRace] = m_byIntelPrio[intellist.GetAt(i-1).sRace];
	}

	// jeder Geheimdienstbericht mit uns als Ziel aus den letzten 5 Runden erhöht die Priorität nochmal um eins, sofern
	// es sich dabei um eine Sabotageaktion handelte
	std::map<CString, int> badReports;
	for (std::map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
		if (it->second->AHumanPlays() == false)
		{
			CIntelligence* pIntel = it->second->GetEmpire()->GetIntelligence();
			for (int l = 0; l < pIntel->GetIntelReports()->GetNumberOfReports(); l++)
			{
				CIntelObject* intelObj = pIntel->GetIntelReports()->GetReport(l);
				if (intelObj->GetEnemy() == it->first && pDoc->GetCurrentRound() - intelObj->GetRound() < 6 && intelObj->GetIsSabotage())
					badReports[it->first] += 1;
			}
			m_byIntelPrio[it->first] += badReports[it->first];
		}

	for (std::map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
		MYTRACE("intelai")(MT::LEVEL_INFO, "Intel-AI: Intel Prio of %s is %d\n", it->first, m_byIntelPrio[it->first]);

	// nun liegen die Prioritäten und die Listen mit den Punkten vor. Jetzt kann begonnen werde die Rassen zu
	// vergeheimdiensteln. Ab hier kommt die KI für den Geheimdienst richtig ins Spiel.
	for (std::map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
	{
		if (it->second->AHumanPlays() == false)
		{
			CIntelligence* pIntel = it->second->GetEmpire()->GetIntelligence();
			// wenn in den letzten 5 Runden Geheimdienstberichte mit uns als Ziel vorliegen, so wird die innere
			// Sicherheit maximiert
			if (badReports[it->first] > NULL)
			{
				// Es liegt mindst. ein Bericht mit uns als Ziel aus den letzten 5 Runden vor.
				// Dann wird die Innere Sicherheit auf 100% gesetzt
				pIntel->SetAssignment()->SetGlobalPercentage(2, 100, it->second, "", pmMajors);
				continue;
			}

			// wenn die innere Sicherheit nicht verändert werden musste, dann können wir vielleicht selbst aktiv werden
			// KI benutzt nur Sabotage

			// Wie wird ein mögliches Geheimdienstopfer ermittelt?
			// - haben die schlechteste Beziehung zum Opfer
			// - Beziehung unter 50% oder aktueller Vertrag kleiner Freundschaft und kein Verteidigungsbündnis
			USHORT worstRel = MAXBYTE;
			CMajor* pWorstRace = NULL;
			for (std::map<CString, CMajor*>::const_iterator jt = pmMajors->begin(); jt != pmMajors->end(); ++jt)
				if (jt->first != it->first && it->second->IsRaceContacted(jt->first) == true)
				{
					// zufällig wird hier eine bekannte andere Rasse als ResponsibleRace ausgewählt
					pIntel->SetResponsibleRace(it->first);	// erstmal uns wieder auf die ResponsibleRace setzen
					if (jt->second->GetEmpire()->CountSystems() > 0 && rand()%3 == NULL)
					{
						pIntel->SetResponsibleRace(jt->first);
						break;
					}

					// vertragliche Situation und Mindestbeziehung checken
					if ((it->second->GetAgreement(jt->first) < DIPLOMATIC_AGREEMENT::FRIENDSHIP && it->second->GetDefencePact(jt->first) == false)
						||	it->second->GetRelation(jt->first) < 50)
					{
						// schlechteste Beziehung ermitteln
						if (it->second->GetRelation(jt->first) < worstRel)
						{
							worstRel = it->second->GetRelation(jt->first);
							pWorstRace = jt->second;
						}
						// bei Gleichheit zu 50% die neue Rasse mit schlechtester Bezeihung
						else if (it->second->GetRelation(jt->first) == worstRel && rand()%2 == NULL)
						{
							worstRel = it->second->GetRelation(jt->first);
							pWorstRace = jt->second;
						}
					}
				}

			// jetzt der ausgesuchten Rasse Geheimdienstpunkte zuweisen
			if (pWorstRace != NULL)
			{
				CIntelligence* pWorstIntel = pWorstRace->GetEmpire()->GetIntelligence();
				MYTRACE("intelai")(MT::LEVEL_INFO, "Intel-AI: assigned intel victim of %s is %s\n", it->first, pWorstRace->GetRaceID());
				// jede Rasse läßt immer einen bestimmten prozentualen Anteil in der inneren Sicherheit.
				int innerSecPerc = 25;

				if (it->second->IsRaceProperty(RACE_PROPERTY::FINANCIAL))
					innerSecPerc += 15;
				if (it->second->IsRaceProperty(RACE_PROPERTY::WARLIKE))
					innerSecPerc += 25;
				if (it->second->IsRaceProperty(RACE_PROPERTY::AGRARIAN))
					innerSecPerc += 25;
				if (it->second->IsRaceProperty(RACE_PROPERTY::INDUSTRIAL))
					innerSecPerc += 10;
				if (it->second->IsRaceProperty(RACE_PROPERTY::SECRET))
					innerSecPerc -= 10;
				if (it->second->IsRaceProperty(RACE_PROPERTY::SCIENTIFIC))
					innerSecPerc += 0;
				if (it->second->IsRaceProperty(RACE_PROPERTY::PRODUCER))
					innerSecPerc += 5;
				if (it->second->IsRaceProperty(RACE_PROPERTY::PACIFIST))
					innerSecPerc += 35;
				if (it->second->IsRaceProperty(RACE_PROPERTY::SNEAKY))
					innerSecPerc -= 15;
				if (it->second->IsRaceProperty(RACE_PROPERTY::SOLOING))
					innerSecPerc += 40;
				if (it->second->IsRaceProperty(RACE_PROPERTY::HOSTILE))
					innerSecPerc += 0;

				if (innerSecPerc > 100)
					innerSecPerc = 100;
				else if (innerSecPerc < 0)
					innerSecPerc = 0;

				if (pIntel->GetAssignment()->GetGlobalSabotagePercentage(pWorstRace->GetRaceID()) != 100 - innerSecPerc)
					pIntel->SetAssignment()->SetGlobalPercentage(2, 100, it->second, "", pmMajors);
				pIntel->SetAssignment()->SetGlobalPercentage(1, 100 - innerSecPerc, it->second, pWorstRace->GetRaceID(), pmMajors);

				// Wann wird die Geheimdiensaktion gestartet
				// - wenn unsere Geheimdienstpunkte + Punkte aus Depot > gegnerische Innere Sicherheit + deren Inneres Depot

				int type = rand()%4;	// Typ der Aktion (Wirtschaft, Wissenschaft, Militär oder Diplomatie)
				UINT ourPoints = pIntel->GetSecurityPoints()
					* pIntel->GetAssignment()->GetGlobalSabotagePercentage(pWorstRace->GetRaceID()) / 100
					+ pIntel->GetSPStorage(1, pWorstRace->GetRaceID()) * pIntel->GetAssignment()->GetSabotagePercentages(pWorstRace->GetRaceID(), type) / 100;
				ourPoints += ourPoints * pIntel->GetBonus(type, 1) / 100;

				UINT enemyPoints = pWorstIntel->GetSecurityPoints()
					* pWorstIntel->GetAssignment()->GetInnerSecurityPercentage() / 100;
				// + Bonus auf innere Sicherheit
				enemyPoints += enemyPoints * pWorstIntel->GetInnerSecurityBoni() / 100;
				// + Punkte aus dem Lager (darin ist der Bonus schon vorhanden)
				enemyPoints += pWorstIntel->GetInnerSecurityStorage();
				if (ourPoints > enemyPoints + rand()%1500)
				{
					// zuerst komplette Zuteilung ins Lager übernehmen, damit man dann auch wirklich 100% einem einzelnen
					// Ressort zuweisen kann
					pIntel->SetAssignment()->SetSabotagePercentage(4, 100, pWorstRace->GetRaceID());
					pIntel->SetAssignment()->SetSabotagePercentage(type, 100, pWorstRace->GetRaceID());
				}
				else
					pIntel->SetAssignment()->SetSabotagePercentage(4, 100, pWorstRace->GetRaceID());
				MYTRACE("intelai")(MT::LEVEL_INFO, "Intel-AI: our SP: %d - enemies SP: %d\n", ourPoints, enemyPoints);

			}
			// finden wir keine Rasse zum vergeheimdiensteln, so die innere Sicherheit auf 100% stellen
			else
				pIntel->SetAssignment()->SetGlobalPercentage(2, 100, it->second, "", pmMajors);
		}
	}
}
Пример #5
0
void CResearchAI::Calc(CBotEDoc* pDoc)
{
	ASSERT(pDoc);

	// Forschungsdurchschnitt aller Rassen berechnen
	map<CString, CMajor*>* pmMajors = pDoc->GetRaceCtrl()->GetMajors();
	ASSERT(pmMajors);

	// Map mit zum Major zugehörigen Techlevel
	map<CMajor*, double> mTechLevels;
	list<double> lTechLevels;

	for (map<CString, CMajor*>::const_iterator it = pmMajors->begin(); it != pmMajors->end(); ++it)
	{
		CMajor* pMajor = it->second;
		// für menschliche Spieler wird die KI nichts tun
		if (!pMajor || pMajor->AHumanPlays())
			continue;

		double dTechLevel = pMajor->GetEmpire()->GetResearch()->GetBioTech() +
							pMajor->GetEmpire()->GetResearch()->GetEnergyTech() +
							pMajor->GetEmpire()->GetResearch()->GetCompTech() +
							pMajor->GetEmpire()->GetResearch()->GetPropulsionTech() +
							pMajor->GetEmpire()->GetResearch()->GetConstructionTech() +
							pMajor->GetEmpire()->GetResearch()->GetWeaponTech();
		dTechLevel /= 6.0;
		lTechLevels.push_back(dTechLevel);

		// Hat die Rasse überhaupt eine Spezialforschung zur Auswahl? (auf FALSE prüfen!)
		if (!pMajor->GetEmpire()->GetResearch()->GetUniqueReady())
			// Hat die Rasse noch keinen Bereich gewählt?
			if (pMajor->GetEmpire()->GetResearch()->GetResearchInfo()->GetChoiceTaken() == false)
				mTechLevels[pMajor] = dTechLevel;
	}

	// absteigend sortieren
	lTechLevels.sort();
	lTechLevels.reverse();
	// auf die besten zwei begrenzen
	lTechLevels.resize(2);

	// nur die Majors mit dem besten oder zweitbesten Techlevel versuchen eine Spezialforschung
	// zu beginnen. Dies machen sie aber nur, wenn sie mindestens eine Techstufe weiter sind, als
	// sie für die Spezialforschung benötigt haben
	for (list<double>::const_iterator it = lTechLevels.begin(); it != lTechLevels.end(); ++it)
	{
		// Major mit diesem Techlevel suchen
		for (map<CMajor*, double>::const_iterator it2 = mTechLevels.begin(); it2 != mTechLevels.end(); ++it2)
		{
			if (*it == it2->second)
			{
				CMajor* pMajor = it2->first;
				if (pMajor->GetEmpire()->GetResearch()->GetResearchInfo()->GetChoiceTaken())
					break;

				BYTE nUniqueTech = pMajor->GetEmpire()->GetResearch()->GetUniqueTech() + 1;
				// Prüfen ob die Rasse schon ein Level weiter ist, als das was sie für die Spezialforschung braucht
				if (nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetBioTech() &&
					nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetEnergyTech() &&
					nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetCompTech() &&
					nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetConstructionTech() &&
					nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetPropulsionTech() &&
					nUniqueTech < pMajor->GetEmpire()->GetResearch()->GetWeaponTech())
				{
					// zufällig einen Bereich wählen (1 bis 3)
					int nComplex = rand()%3 + 1;
					pMajor->GetEmpire()->GetResearch()->GetResearchInfo()->SetUniqueResearchChoosePossibility(nComplex);
					// 100% zuteilen
					pMajor->GetEmpire()->GetResearch()->SetPercentage(6, 100);
					CString sName = pMajor->GetEmpire()->GetResearch()->GetResearchInfo()->GetCurrentResearchComplex()->GetComplexName();
					MYTRACE("general")(MT::LEVEL_INFO, "CResearchAI::Calc(): %s choose in unique complex '%s' field %d and set level to 100%%\n", pMajor->GetRaceID(), sName, nComplex);
				}
			}
		}
	}
}