Example #1
0
	//removes workers from a cathegory which has a store until production + store <= store,
	//so that nothing will be wasted on next turn change
	int DecrementDueToFullStore(WORKER::Typ type)
	{
		int unset = 0;
		if(!m_pSystem->HasStore(type))
			return unset;
		const int store = m_pSystem->GetResourceStore(type);
		while(true)
		{
			const int workers = m_pSystem->GetWorker(type);
			if(workers == 0)
				break;
			m_pSystem->CalculateVariables();
			const int prod = m_pSystem->GetProduction()->GetXProd(type);
			if(store + prod <= m_pSystem->GetXStoreMax(type))
				break;
			SetWorker(type, CSystem::SET_WORKER_MODE_DECREMENT);
			++unset;
		}
		return unset;
	}
// Diese Funktion entfernt die benötigten Ressourcen aus dem lokalen Lager des Systems und falls Ressourcenrouten
// bestehen auch die Ressourcen in den Startsystemen der Route. Aber nur falls dies auch notwendig sein sollte.
void CAssemblyList::RemoveResourceFromStorage(BYTE res, const CPoint &ko, std::vector<CSystem>& systems, CArray<CPoint>* routesFrom)
{
	if (ko == CPoint(-1,-1))
		return;

	CSystem *system = &systems.at(ko.x+(ko.y)*STARMAP_SECTORS_HCOUNT);

	// für Deritium gibt es keine Ressourcenroute
	if (res != DERITIUM)
	{
		// zuerst wird immer versucht, die Ressourcen aus dem lokalen Lager zu nehmen
		long remainingRes = GetNeededResourceInAssemblyList(0, res) - system->GetResourceStore(res);
		// werden zusätzliche Ressourcen aus anderen Lagern benötigt, so kann das lokale Lager
		// auf NULL gesetzt werden
		if (remainingRes > 0)
		{
			*system->GetResourceStorages(res) = NULL;
			// zusätzliche Ressourcen müssen aus den Lagern der Systeme mit den Ressourcenrouten
			// bezogen werden. Dafür ein Feld anlegen, indem alle Startsysteme mit der zur Ressouce passenden
			// Ressourcenroute beinhaltet sind.
			struct ROUTELIST {
				CResourceRoute *route;
				CPoint fromSystem;

				ROUTELIST() : route(0), fromSystem(0) {}
				ROUTELIST(CResourceRoute *_route, CPoint _fromSystem) : route(_route), fromSystem(_fromSystem) {}
			};
			CArray<ROUTELIST> routes;
			for (int j = 0; j < routesFrom->GetSize(); j++)
			{
				CPoint p = routesFrom->GetAt(j);
				for (int k = 0; k < systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetSize(); k++)
				{
					// Stimmt die Ressource überein=
					if (systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k).GetResource() == res)
					{
						// Stimmt das Zielsystem mit unserem überein?
						if (systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k).GetKO() == ko)
						{
							// prüfen das die Route nicht schon verwendet wird
							bool bUsed = false;
							for (int l = 0; l < routes.GetSize(); l++)
								if (routes.GetAt(l).fromSystem == p)
								{
									bUsed = true;
									break;
								}
							if (!bUsed)
								routes.Add(ROUTELIST(&systems.at(p.x+(p.y)*STARMAP_SECTORS_HCOUNT).GetResourceRoutes()->GetAt(k), p));
						}
					}
				}
			}
			// in routes sind nun die Zeiger auf die richtigen Ressourcenrouten, also die Routen, welche auch den
			// passenden Rohstoff liefern könnten.
			while (routes.GetSize())
			{
				// zufällig eine Route aus den möglichen auswählen, damit nicht immer das gleiche System zuerst
				// die Rohstoffe liefern muss, falls mehrere Routen der selben Art ins System eingehen.
				int random = rand()%routes.GetSize();
				int percent = 0;
				CPoint start = routes.GetAt(random).fromSystem;
				// sind im jeweiligen Lager des Startsystem genügend Rohstoffe vorhanden
				if (systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res) >= (ULONG)remainingRes)
				{
					*systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStorages(res) -= remainingRes;
					if (GetNeededResourceInAssemblyList(0, res) > NULL)
						percent = 100 * remainingRes / GetNeededResourceInAssemblyList(0, res);
					CResourceRoute* pResRoute = routes.GetAt(random).route;
					pResRoute->SetPercent((BYTE)percent);
					remainingRes = 0;
				}
				else
				{
					remainingRes -= systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res);
					if (GetNeededResourceInAssemblyList(0, res) > NULL)
						percent = 100 * systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStore(res) / GetNeededResourceInAssemblyList(0, res);
					CResourceRoute* pResRoute = routes.GetAt(random).route;
					pResRoute->SetPercent((BYTE)percent);
					*systems.at(start.x+(start.y)*STARMAP_SECTORS_HCOUNT).GetResourceStorages(res) = NULL;
				}
				// ROUTELIST Eintrag entfernen, wenn dieser abgearbeitet wurde
				routes.RemoveAt(random);

				// werden keine Ressourcen mehr benötigt, so kann abgebrochen werden
				if (remainingRes == 0)
				{
					routes.RemoveAll();
					break;
				}
			}
			ASSERT(remainingRes == 0);
		}
		// anderenfalls werden nur die benötigten Ressourcen aus dem lokalen Lager abgezogen
		else
			*system->GetResourceStorages(res) -= GetNeededResourceInAssemblyList(0, res);
	}
	else
		*system->GetResourceStorages(res) -= m_iNeededDeritiumInAssemblyList[0];
}