コード例 #1
0
    public HousingSlots AvailableHousing()
    {
        HousingSlots availableHousing = new HousingSlots();

        availableHousing.low    = resources.totalHousingSlots.low - resources.occuppiedHousingSlots.low;
        availableHousing.middle = resources.totalHousingSlots.middle - resources.occuppiedHousingSlots.middle;
        availableHousing.high   = resources.totalHousingSlots.high - resources.occuppiedHousingSlots.high;

        return(availableHousing);
    }
コード例 #2
0
    static public HousingSlots operator+(HousingSlots slots1, HousingSlots slots2)
    {
        HousingSlots sum = new HousingSlots();

        sum.low    = slots1.low + slots2.low;
        sum.middle = slots1.middle + slots2.middle;
        sum.high   = slots1.high + slots2.high;

        return(sum);
    }
コード例 #3
0
    static public HousingSlots operator/(HousingSlots slots, float denominator)
    {
        HousingSlots sum = new HousingSlots();

        sum.low    = System.Convert.ToUInt32(System.Convert.ToDouble(slots.low) / denominator);
        sum.middle = System.Convert.ToUInt32(System.Convert.ToDouble(slots.middle) / denominator);
        sum.high   = System.Convert.ToUInt32(System.Convert.ToDouble(slots.high) / denominator);

        return(sum);
    }
コード例 #4
0
    void ProcessMigration() //called once per day.
    {
        //compute immigration rate based on happiness and empty housing.
        HousingSlots availableHousing      = GameManager.resourceMan.AvailableHousing();
        ulong        totalAvailableHousing = availableHousing.Sum();

        int minHappinessForImmigration = 35;
        int maxHappinessForImmigration = 75;

        //int _immigration = Mathf.RoundToInt(((float)populationHappiness.overall / 100.0f) * (0.8f * maxImmigrationRate));
        float happinesContirbution = Mathf.Clamp((float)(populationHappiness.overall - minHappinessForImmigration) / (float)(maxHappinessForImmigration - minHappinessForImmigration), 0.0f, 1.0f);
        int   _immigration         = Mathf.RoundToInt(happinesContirbution * (float)maxImmigrationRate);

        _immigration = Mathf.Max(Random.Range(Mathf.RoundToInt(_immigration - 0.2f * maxImmigrationRate), Mathf.RoundToInt(_immigration + 0.2f * maxImmigrationRate)), growthStats.minImmigrationRate);
        _immigration = (int)Mathf.Min(_immigration, maxImmigrationRate, totalAvailableHousing);

        int actualImmigration = 0; //pointless?

        if (_immigration > 0 && totalAvailableHousing > 0)
        {
            //Spawn new citizens here.
            //This is a test implementation
            float lowRatio    = availableHousing.low / totalAvailableHousing;
            float middleRatio = availableHousing.middle / totalAvailableHousing;
            float highRatio   = availableHousing.high / totalAvailableHousing;

            for (int i = 0; i < Mathf.FloorToInt(_immigration * lowRatio); i++)
            {
                GenerateImmigrationCase(CitizenClass.low);
                actualImmigration++;
            }
            for (int i = 0; i < Mathf.FloorToInt(_immigration * middleRatio); i++)
            {
                GenerateImmigrationCase(CitizenClass.middle);
                actualImmigration++;
            }
            for (int i = 0; i < Mathf.FloorToInt(_immigration * highRatio); i++)
            {
                GenerateImmigrationCase(CitizenClass.high);
                actualImmigration++;
            }
        }

        growthStats.immigrationRate          = actualImmigration;
        GameManager.resourceMan.Population() = PopulationCount();
        GameManager.uiMan.UpdatePopulation(PopulationCount());
    }
コード例 #5
0
    //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());
            }
        }
    }
コード例 #6
0
 public void UpdateOccupiedHousingSlots(HousingSlots slots)
 {
     resources.occuppiedHousingSlots.AssignNew(slots);
 }
コード例 #7
0
 public void UpdateTotalHousingSlots(HousingSlots slots)
 {
     resources.totalHousingSlots.AssignNew(slots);
 }
コード例 #8
0
 public void AssignNew(HousingSlots newSlots) //since we can't overload the assignment op and we sometimes want to deep copy an object
 {
     low    = newSlots.low;
     middle = newSlots.middle;
     high   = newSlots.high;
 }
コード例 #9
0
 public HousingSlots(HousingSlots newSlots)
 {
     AssignNew(newSlots);
 }