//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]; }