public float CompareToBaseResource(BasicResources baseResources) //used mostly in calculating efficiency, called when this object is the ALLOCATED resources. Returns average of { //percentages of satisfaction for each resource. float percentage = 0.0f; int counter = 0; //The if statements are to make this method universal (useable in cases even when only part of the basic resources are set) if (baseResources.power > 0.001f) //not zero { percentage += power / baseResources.power; counter++; } if (baseResources.water > 0.001f) { percentage += water / baseResources.water; counter++; } if (counter > 0) { percentage = percentage / (float)counter; } else { percentage = 1.0f; } return(percentage); }
//Simulation runs coroutines. IEnumerator BuildingsSimRun() //the current logic assigns available resources prioritizing older buildings (those coming first in buildingsMan.constructedBuildings list) { //Current issue with this logic: It's expensive! Most buildings won't have their operational status and parameters changed each sim update cycle, yet we would still compute //productions and consumptions for all buildings at every sim update. A better approach would be to let each building process changes on its own by updating global values //or registering itself for processing by a central manager. Downside of this approach would be checking against race conditions, and a more complicated code. while (true) { if (isRunning) { //General Buildings float totalWaterDemand = 0.0f; float totalPowerDemand = 0.0f; HousingSlots totalHousingSlots = new HousingSlots(); HousingSlots occuppiedHousingSlots = new HousingSlots(); //To avoid having multiple loops, the loop bellow will cover several, building-specific calls depending on building types. Some exceptions will have their //own loops bellow, but in theory could also be merged with this loop. //TODO consider merging into a single loop with if-statements. foreach (Building building in GameManager.buildingsMan.constructedBuildings) { //Fill requirement resources //TODO consider moving this to a function that only updates when its state changes (e.g. new building constructed, stats changed, etc). Would complicate //the code elsewhere though. totalWaterDemand += building.GetStats().requiredResources.water; totalPowerDemand += building.GetStats().requiredResources.power; //update building effect on natural resources and environment building.UpdateEffectOnNature(dateUpdateRateHours); building.CheckAndShowResourceShortages(); //for residential buildings, if (building.GetStats().type == BuildingType.residential) { ResidentialBuilding residentialBuilding = building.gameObject.GetComponent <ResidentialBuilding>(); //update housing slots totalHousingSlots.IncrementSlotValue(residentialBuilding.HousingCapacity(), residentialBuilding.ResidentClass()); occuppiedHousingSlots.IncrementSlotValue(residentialBuilding.ResidentsCount(), residentialBuilding.ResidentClass()); residentialBuilding.UpdateHousingQuality(); } } //Update ResourceManager GameManager.resourceMan.UpdateWaterDemand(totalWaterDemand); GameManager.resourceMan.UpdatePowerDemand(totalPowerDemand); GameManager.resourceMan.UpdateTotalHousingSlots(totalHousingSlots); GameManager.resourceMan.UpdateOccupiedHousingSlots(occuppiedHousingSlots); //Computing production of infraStructure buildings float totalWaterProduction = 0.0f; float totalPowerProduction = 0.0f; //Compute production for all infra buildings foreach (InfrastructureBuilding building in GameManager.buildingsMan.powerProductionBuildings) { building.ComputeProduction(); totalPowerProduction += building.GetMaxProduction(); } foreach (InfrastructureBuilding building in GameManager.buildingsMan.waterProductionBuildings) { building.ComputeProduction(); totalWaterProduction += building.GetMaxProduction(); } //Update ResourcesManager GameManager.resourceMan.UpdateAvailableWater(totalWaterProduction); GameManager.resourceMan.UpdateAvailablePower(totalPowerProduction); //Allocate resources to buildings based on production and priority float totalWaterConsumption = 0.0f; float totalPowerConsumption = 0.0f; foreach (Building building in GameManager.buildingsMan.constructedBuildings) { BasicResources resources = new BasicResources(); resources.power = Mathf.Clamp(building.GetStats().requiredResources.power, 0.0f, totalPowerProduction - totalPowerConsumption); resources.water = Mathf.Clamp(building.GetStats().requiredResources.water, 0.0f, totalWaterProduction - totalWaterConsumption); totalPowerConsumption += resources.power; totalWaterConsumption += resources.water; building.AllocateResources(resources); } //update ResourceManager GameManager.resourceMan.UpdateWaterConsumption(totalWaterConsumption); GameManager.resourceMan.UpdatePowerConsumption(totalPowerConsumption); //Divide load on infrastructure buildings and assign it float powerDemandToMaxProductionRatio = Mathf.Min(totalPowerDemand / totalPowerProduction, 1.0f); float waterDemandToMaxProductionRatio = Mathf.Min(totalWaterDemand / totalWaterProduction, 1.0f); foreach (InfrastructureBuilding building in GameManager.buildingsMan.powerProductionBuildings) { building.SetLoad(powerDemandToMaxProductionRatio); } foreach (InfrastructureBuilding building in GameManager.buildingsMan.waterProductionBuildings) { building.SetLoad(waterDemandToMaxProductionRatio); } yield return(new WaitForSeconds(timeBetweenUpdates)); } else { yield return(new WaitForFixedUpdate()); } } }
public void AllocateResources(BasicResources resources) { allocatedResources = resources; }
public BasicResources(BasicResources source) //deep copy { power = source.power; water = source.water; }