//removes workers from factories until they are the minimum number to finish the current project //in still the same number of turns (as at the start of the function) int DecrementDueToWastedIndustry(bool max_industry) { m_pSystem->CalculateVariables(); const CAssemblyList& assembly_list = *m_pSystem->GetAssemblyList(); int unset = 0; if(assembly_list.IsEmpty() || assembly_list.GetWasBuildingBought()) return unset; const int min_rounds = m_pSystem->NeededRoundsToBuild(0, true); AssertBotE(min_rounds >= 1); if(max_industry && min_rounds > 1 || m_pSystem->GetWorker(WORKER::INDUSTRY_WORKER) == 0) return unset; while(true) { SetWorker(WORKER::INDUSTRY_WORKER, CSystem::SET_WORKER_MODE_DECREMENT); ++unset; m_pSystem->CalculateVariables(); const int current_rounds = m_pSystem->NeededRoundsToBuild(0, true, false); if(m_pSystem->GetWorker(WORKER::INDUSTRY_WORKER) == 0) { if(min_rounds < current_rounds) OnBestIndustryWorkerCountFound(unset); return unset; } if(min_rounds < current_rounds) { OnBestIndustryWorkerCountFound(unset); return unset; } } }
void Finish() const { AssertBotE(m_WorkersLeftToSet >= 0); #ifdef CONSISTENCY_CHECKS AssertBotE(m_pSystem->SanityCheckWorkers()); #endif m_pSystem->CalculateVariables(); }
//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; }
//Indreases workers in cathegories energy and food until we produce enough to suffice for the consumption we have bool IncreaseWorkersUntilSufficient(WORKER::Typ type, bool allow_insufficient) { AssertBotE(type == WORKER::ENERGY_WORKER || type == WORKER::FOOD_WORKER); if(m_pSystem->GetDisabledProductions()[type]) return true; while(true) { const int value = (type == WORKER::ENERGY_WORKER) ? m_pProd->GetEnergyProd() : m_pProd->GetFoodProd(); if(value >= 0) return true; if(m_WorkersLeftToSet <= 0) return allow_insufficient; const int number_of_buildings = m_pSystem->GetNumberOfWorkbuildings(type, 0); const int workers_set = m_pSystem->GetWorker(type); AssertBotE(workers_set <= number_of_buildings); if(workers_set == number_of_buildings) return allow_insufficient; SetWorker(type, CSystem::SET_WORKER_MODE_INCREMENT); m_pSystem->CalculateVariables(); } }
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; }
void Prepare() const { m_pSystem->FreeAllWorkers(); m_pSystem->CalculateVariables(); }