//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; }
bool CSystemManager::CheckEnergyConsumers(CSystem& system) { if(!m_bOnOffline) return false; CEnergyConsumersChecker checker(system); CArray<CBuilding>* buildings = system.GetAllBuildings(); bool bomb_warning = false; bool defense_checked = false; const CSystemProd& prod = *system.GetProduction(); int additional_available_energy = prod.GetAvailableEnergy(); for(int i = 0; i < buildings->GetSize(); ++i) { CBuilding& building = buildings->GetAt(i); const CBuildingInfo& info = resources::BuildingInfo->GetAt(building.GetRunningNumber() - 1); const int needed = info.GetNeededEnergy(); if(needed == 0) continue; if(m_IgnoredBuildings.find(info.GetRunningNumber()) != m_IgnoredBuildings.end()) continue; bool should_be_online = building.GetIsBuildingOnline(); if(info.GetShipYard() || info.GetShipBuildSpeed() > 0) { AssertBotE(!info.IsDefenseBuilding()); should_be_online = checker.ShouldTakeShipyardOnline(); } if(info.IsDefenseBuilding()) { AssertBotE(!info.GetShipYard()); if(bomb_warning) should_be_online = true; else if(!defense_checked) { bomb_warning = checker.BomberInSector(); should_be_online = bomb_warning; defense_checked = true; } else should_be_online = false; } if(info.IsDeritiumRefinery()) should_be_online = checker.CheckStoreFull(RESOURCES::DERITIUM, info, building); if(info.GetResistance() > 0) should_be_online = !system.Taken(); if(info.GetShipTraining() > 0) should_be_online = system.GetOwnerOfShip(system.OwnerID(), true); if(info.GetTroopTraining() > 0) should_be_online = !system.GetTroops()->IsEmpty(); bool minus_moral = false; if(info.GetMoralProd() < 0) minus_moral = should_be_online = checker.CheckMoral(info, building, m_iMinMoral, m_iMinMoralProd); const WORKER::Typ type = info.ProducesWorkerfull(); if(type != WORKER::NONE) { should_be_online = system.HasStore(type) ? checker.CheckStoreFull(WorkerToResource(type), info, building) : true; } should_be_online = should_be_online || info.IsUsefulForProduction(); should_be_online = should_be_online && (info.OnlyImprovesProduction(minus_moral) || (info.GetShipBuildSpeed() > 0 && checker.ShouldTakeShipyardOnline())); should_be_online = should_be_online || info.IsUsefulMoral(); const bool is_online = building.GetIsBuildingOnline(); if(should_be_online && !is_online) { if(additional_available_energy >= needed) { building.SetIsBuildingOnline(true); additional_available_energy -= needed; system.CalculateVariables(); } } else if (!should_be_online && is_online) { const int needed = info.GetNeededEnergy(); building.SetIsBuildingOnline(false); additional_available_energy += needed; system.CalculateVariables(); } } AssertBotE(additional_available_energy >= 0); return m_bBombWarning && bomb_warning; }