示例#1
0
 /// <summary>
 /// Calculates employment ratio for type of resident
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 public float Get_Employment_Ratio(Building.Resident type)
 {
     if (Required_Workers[type] == 0)
     {
         return(0.0f);
     }
     return((float)Residents[type][CURRENT] / (float)Required_Workers[type]);
 }
示例#2
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="delta_time">Seconds since last update</param>
    public void Process(float delta_time)
    {
        Resources.Clear();
        Cash_Flow = 0.0f;
        Dictionary <Building.Resident, float> resident_happiness_temp = new Dictionary <Building.Resident, float>();
        Dictionary <Building.Resident, int>   required_workers_temp   = new Dictionary <Building.Resident, int>();

        foreach (Building.Resident resident_type in Enum.GetValues(typeof(Building.Resident)))
        {
            Residents[resident_type][CURRENT]      = 0;
            Residents[resident_type][MAX]          = 0;
            resident_happiness_temp[resident_type] = 0.0f;
            required_workers_temp.Add(resident_type, 0);
        }
        Dictionary <string, float[]> resource_stats_temp = new Dictionary <string, float[]>();

        float      income               = 0.0f;
        float      expenditures         = 0.0f;
        float      food_current         = 0.0f;
        float      food_max             = 0.0f;
        float      food_produced        = 0.0f;
        float      food_consumed        = 0.0f;
        List <int> food_storage_cheched = new List <int>();

        List <string> food_types = new List <string>();

        foreach (KeyValuePair <string, Dictionary <string, float> > resource in resource_data)
        {
            if (resource.Value.ContainsKey("food"))
            {
                food_types.Add(resource.Key);
            }
        }

        System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew();
        Time += (Game.Instance.Speed * delta_time);
        foreach (Building building in buildings)
        {
            //Process
            if (Game.Instance.Is_Paused)
            {
                building.Render_Alerts();
            }
            else
            {
                building.Process(Game.Instance.Speed * (delta_time + (stopwatch.ElapsedMilliseconds / 1000.0f)));
            }
            //Storage
            if (building.Is_Built)
            {
                if (building.Attribute("storehouse") != 0.0f)
                {
                    foreach (KeyValuePair <string, float[]> resource in building.Storage)
                    {
                        if (!Resources.ContainsKey(resource.Key))
                        {
                            Resources.Add(resource.Key, resource.Value[CURRENT]);
                        }
                        else
                        {
                            Resources[resource.Key] += resource.Value[CURRENT];
                        }
                    }
                }
                //Resident count
                foreach (Building.Resident resident_type in Enum.GetValues(typeof(Building.Resident)))
                {
                    if (building.Population_Type == resident_type)
                    {
                        Residents[resident_type][CURRENT]      += building.Population;
                        Residents[resident_type][MAX]          += building.Population_Max;
                        resident_happiness_temp[resident_type] += (building.Population_Happiness * building.Population);
                        break;
                    }
                }
                //Worker count
                foreach (KeyValuePair <Building.Resident, int[]> worker_type in building.Workers)
                {
                    required_workers_temp[worker_type.Key] += worker_type.Value[MAX];
                }
                if (building.Changeable_Workers_PC.Count != 0)
                {
                    if (building.Changeable_Workers_PC[2] == 0)
                    {
                        required_workers_temp[Building.Resident.PEASANT] += building.Changeable_Workers_PC[MAX];
                    }
                    else
                    {
                        required_workers_temp[Building.Resident.CITIZEN] += building.Changeable_Workers_PC[MAX];
                    }
                }
                if (building.Changeable_Workers_CN.Count != 0)
                {
                    if (building.Changeable_Workers_CN[2] == 0)
                    {
                        required_workers_temp[Building.Resident.CITIZEN] += building.Changeable_Workers_CN[MAX];
                    }
                    else
                    {
                        required_workers_temp[Building.Resident.NOBLE] += building.Changeable_Workers_CN[MAX];
                    }
                }
            }
            //Cash flow
            Cash_Flow    -= building.Current_Upkeep;
            expenditures -= building.Current_Upkeep;
            Cash_Flow    += building.Get_Statistic("income");
            income       += building.Get_Statistic("income");
            //Food
            foreach (string food in food_types)
            {
                food_current += building.Resource_Amount(food);
                if (building.Storage.ContainsKey(food) && !food_storage_cheched.Contains(building.Id))
                {
                    food_max += building.Storage[food][MAX];
                    food_storage_cheched.Add(building.Id);
                }
            }
            food_produced += building.Get_Statistic("food_produced");
            food_consumed += building.Get_Statistic("food_consumed");
            //Resources
            foreach (KeyValuePair <string, float> stat in building.Statistics)
            {
                if (stat.Key.StartsWith("produced_"))
                {
                    string  resource_name = stat.Key.Substring(9);
                    float[] data          = new float[3] {
                        0.0f, 0.0f, stat.Value
                    };
                    if (!resource_stats_temp.ContainsKey(resource_name))
                    {
                        resource_stats_temp.Add(resource_name, data);
                    }
                    else
                    {
                        resource_stats_temp[resource_name][0] += data[0];
                        resource_stats_temp[resource_name][1] += data[1];
                        resource_stats_temp[resource_name][2] += data[2];
                    }
                }
                else if (stat.Key.StartsWith("consumed_"))
                {
                    string  resource_name = stat.Key.Substring(9);
                    float[] data          = new float[3] {
                        0, 0, -1.0f * stat.Value
                    };
                    if (!resource_stats_temp.ContainsKey(resource_name))
                    {
                        resource_stats_temp.Add(resource_name, data);
                    }
                    else
                    {
                        resource_stats_temp[resource_name][0] += data[0];
                        resource_stats_temp[resource_name][1] += data[1];
                        resource_stats_temp[resource_name][2] += data[2];
                    }
                }
            }
            foreach (KeyValuePair <string, float[]> resource in building.Storage)
            {
                float[] data = new float[3] {
                    resource.Value[CURRENT], resource.Value[MAX], 0.0f
                };
                if (!resource_stats_temp.ContainsKey(resource.Key))
                {
                    resource_stats_temp.Add(resource.Key, data);
                }
                else
                {
                    resource_stats_temp[resource.Key][0] += data[0];
                    resource_stats_temp[resource.Key][1] += data[1];
                    resource_stats_temp[resource.Key][2] += data[2];
                }
            }
        }
        //Redistribute workers
        foreach (KeyValuePair <Building.Resident, int> temp_data in required_workers_temp)
        {
            Required_Workers[temp_data.Key] = temp_data.Value;
        }
        Dictionary <Building.Resident, int>   available_workers = new Dictionary <Building.Resident, int>();
        Dictionary <Building.Resident, float> worker_ratios     = new Dictionary <Building.Resident, float>();

        foreach (KeyValuePair <Building.Resident, int[]> resident in Residents)
        {
            available_workers.Add(resident.Key, resident.Value[CURRENT]);
            if (Required_Workers[resident.Key] == 0)
            {
                worker_ratios.Add(resident.Key, 0.0f);
            }
            else
            {
                worker_ratios.Add(resident.Key, resident.Value[CURRENT] / (float)Required_Workers[resident.Key]);
                if (worker_ratios[resident.Key] > 1.0f)
                {
                    worker_ratios[resident.Key] = 1.0f;
                }
            }
        }

        foreach (Building building in buildings)
        {
            if (building.Is_Built && (building.Workers.Count != 0 || building.Changeable_Workers_PC.Count != 0 || building.Changeable_Workers_CN.Count != 0))
            {
                foreach (KeyValuePair <Building.Resident, int[]> worker_data in building.Workers)
                {
                    worker_data.Value[CURRENT]          = (int)(worker_ratios[worker_data.Key] * worker_data.Value[MAX]);
                    available_workers[worker_data.Key] -= worker_data.Value[CURRENT];
                }
                if (building.Changeable_Workers_PC.Count != 0)
                {
                    Building.Resident type = Building.Resident.PEASANT;
                    if (building.Changeable_Workers_PC[2] == 1)
                    {
                        type = Building.Resident.CITIZEN;
                    }
                    building.Changeable_Workers_PC[CURRENT] = (int)(worker_ratios[type] * building.Changeable_Workers_PC[MAX]);
                    available_workers[type] -= building.Changeable_Workers_PC[CURRENT];
                }
                if (building.Changeable_Workers_CN.Count != 0)
                {
                    Building.Resident type = Building.Resident.CITIZEN;
                    if (building.Changeable_Workers_CN[2] == 1)
                    {
                        type = Building.Resident.NOBLE;
                    }
                    building.Changeable_Workers_CN[CURRENT] = (int)(worker_ratios[type] * building.Changeable_Workers_CN[MAX]);
                    available_workers[type] -= building.Changeable_Workers_CN[CURRENT];
                }
            }
        }

        //Average happiness
        foreach (Building.Resident resident_type in Enum.GetValues(typeof(Building.Resident)))
        {
            if (Residents[resident_type][CURRENT] == 0)
            {
                resident_happiness_temp[resident_type] = 0;
            }
            else
            {
                resident_happiness_temp[resident_type] /= Residents[resident_type][CURRENT];
            }
        }

        //Try to store resources
        foreach (KeyValuePair <Building, Dictionary <string, float> > store_data in resources_on_queue)
        {
            foreach (KeyValuePair <string, float> resource_data in store_data.Value)
            {
                float over_flow = Store_Resources(resource_data.Key, resource_data.Value);
                store_data.Key.Add(resource_data.Key, over_flow);
            }
        }
        resources_on_queue.Clear();

        //Delete
        foreach (Building b in buildings_to_be_deleted)
        {
            buildings.Remove(b);
        }
        buildings_to_be_deleted.Clear();

        //Update menu
        foreach (KeyValuePair <Building.Resident, float> pair in resident_happiness_temp)
        {
            Resident_Happiness[pair.Key] = pair.Value;
        }
        MenuManager.Instance.Set_Time(Time);
        Update_Resource_Menu();
        MenuManager.Instance.Set_Resident_Info(
            Residents[Building.Resident.PEASANT][CURRENT], Residents[Building.Resident.PEASANT][MAX], Mathf.RoundToInt(Resident_Happiness[Building.Resident.PEASANT] * 100.0f),
            Required_Workers[Building.Resident.PEASANT], Mathf.RoundToInt(100.0f * Get_Employment_Ratio(Building.Resident.PEASANT)),
            Residents[Building.Resident.CITIZEN][CURRENT], Residents[Building.Resident.CITIZEN][MAX], Mathf.RoundToInt(Resident_Happiness[Building.Resident.CITIZEN] * 100.0f),
            Required_Workers[Building.Resident.CITIZEN], Mathf.RoundToInt(100.0f * Get_Employment_Ratio(Building.Resident.CITIZEN)),
            Residents[Building.Resident.NOBLE][CURRENT], Residents[Building.Resident.NOBLE][MAX], Mathf.RoundToInt(Resident_Happiness[Building.Resident.NOBLE] * 100.0f),
            Required_Workers[Building.Resident.NOBLE], Mathf.RoundToInt(100.0f * Get_Employment_Ratio(Building.Resident.NOBLE))
            );

        //Update statistics
        StatisticsManager.Instance.Cash          = Cash;
        StatisticsManager.Instance.Income        = income;
        StatisticsManager.Instance.Expenditures  = expenditures;
        StatisticsManager.Instance.Food_Current  = food_current;
        StatisticsManager.Instance.Food_Max      = food_max;
        StatisticsManager.Instance.Food_Produced = food_produced;
        StatisticsManager.Instance.Food_Consumed = food_consumed;

        Resource_Stats.Clear();
        foreach (KeyValuePair <string, float[]> resource_data_temp in resource_stats_temp)
        {
            Resource_Stats.Add(resource_data_temp.Key, resource_data_temp.Value);
        }
    }