Example #1
0
        /// <summary>
        /// ステーションの設定を復元
        /// </summary>
        /// <param name="conn">DB接続情報</param>
        protected virtual void RestoreSettings(DBConnection conn, IStationSettings settings)
        {
            // 本部か
            const string sql1 = "SELECT Value FROM StationSettings WHERE Key = 'IsHeadquarters' UNION ALL SELECT 'False' LIMIT 1";

            settings.IsHeadquarters = conn.QuerySingle <string>(sql1) == bool.TrueString;

            // 日光
            const string sql2           = "SELECT Value FROM StationSettings WHERE Key = 'Sunlight' UNION ALL SELECT '100' LIMIT 1";
            var          sunLightString = conn.QuerySingle <string>(sql2);

            if (double.TryParse(sunLightString, out var sunLight))
            {
                settings.Sunlight = sunLight;
            }

            // 現在の労働者数
            const string sql3 = "SELECT Value FROM StationSettings WHERE Key = 'ActualWorkforce' UNION ALL SELECT '0' LIMIT 1";
            var          actualWorkforceString = conn.QuerySingle <string>(sql3);

            if (long.TryParse(actualWorkforceString, out var actualWorkforce))
            {
                settings.Workforce.Actual = actualWorkforce;
            }

            // (労働者数を)常に最大にするか
            const string sql4 = "SELECT Value FROM StationSettings WHERE key = 'AlwaysMaximumWorkforce' UNION ALL SELECT 'False' LIMIT 1";

            settings.Workforce.AlwaysMaximum = conn.QuerySingle <string>(sql4) == bool.TrueString;
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="modules">モジュール一覧情報</param>
        /// <param name="settings">ステーションの設定</param>
        public WorkForceModuleInfoModel(IModulesInfo modules, IStationSettings settings)
        {
            _Modules = modules;
            _Modules.Modules.CollectionChangedAsync         += OnModulesChanged;
            _Modules.Modules.CollectionPropertyChangedAsync += OnModulesPropertyChanged;

            _Settings = settings;
            _Settings.PropertyChanged += Settings_PropertyChanged;
            _HQ = new WorkForceModuleInfoDetailsItem("module_player_prod_hq_01_macro", 1, _Settings.HQWorkers, 0);
        }
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="modules">モジュール一覧</param>
        /// <param name="settings">ステーションの設定</param>
        public ProductsGridModel(IModulesInfo modules, IProductsInfo products, IStationSettings settings)
        {
            _Modules  = modules;
            _Products = products;

            _Modules.Modules.CollectionChangedAsync         += OnModulesChanged;
            _Modules.Modules.CollectionPropertyChangedAsync += OnModulePropertyChanged;

            _Modules  = modules;
            _Settings = settings;
            _Settings.PropertyChanged           += Settings_PropertyChanged;
            _Settings.Workforce.PropertyChanged += Workforce_PropertyChanged;
        }
        /// <summary>
        /// 必要モジュールを計算
        /// </summary>
        /// <param name="products">製品一覧</param>
        /// <param name="settings">ステーションの設定</param>
        /// <returns>必要モジュールと個数のタプル</returns>
        public IEnumerable <(IX4Module Module, long Count)> CalcNeedModules(IReadOnlyList <ProductsGridItem> products, IStationSettings settings)
        {
            var addModules        = new Dictionary <IX4Module, long>();                 // 追加予定モジュールと個数のディクショナリ
            var addModuleProducts = new List <(IWare Ware, long Count)>();              // 追加予定モジュールの製品一覧
            var excludeWares      = new HashSet <IWare>();                              // 計算除外製品一覧


            foreach (var prod in products.Where(x => 0 < x.Ware.WareGroup.Tier).OrderBy(x => x.Ware.WareGroup.Tier))
            {
                // 追加予定のモジュールも含めた製造ウェア数
                var totalCount = prod.Count + addModuleProducts
                                 .Where(x => x.Ware.Equals(prod.Ware))
                                 .Sum(x => x.Count);

                // 不足していない or 計算除外ウェアの場合、何もしない
                if (0 <= totalCount || excludeWares.Contains(prod.Ware))
                {
                    continue;
                }


                // 不足しているウェアを製造するモジュールを取得
                if (_Ware2ModuleDict.TryGetValue(prod.Ware, out var module))
                {
                    var modCount = 0L;

                    // モジュールが製造するウェアを取得
                    foreach (var addProduct in CalcProductAndResources(module, 1))
                    {
                        var addAmount = addProduct.WareAmount;

                        if (addProduct.Efficiency is not null && addProduct.Efficiency.TryGetValue("sunlight", out var wareEffect))
                        {
                            addAmount = (long)Math.Floor(addAmount * wareEffect.Product * settings.Sunlight);
                        }

                        // 生産数が0の場合、計算除外製品一覧に突っ込む
                        if (addAmount == 0)
                        {
                            excludeWares.Add(prod.Ware);
                            continue;
                        }

                        // 製造するウェア数からあと何モジュール必要か計算する
                        modCount = Math.Max(modCount, (long)Math.Ceiling(-(double)totalCount / addAmount));

                        // 追加予定モジュールの製品一覧を更新
                        addModuleProducts.Add((X4Database.Instance.Ware.Get(addProduct.WareID), addProduct.WareAmount * modCount));
                    }

                    // 追加予定モジュールにモジュールを追加
                    if (addModules.ContainsKey(module))
                    {
                        addModules[module] += modCount;
                    }
                    else
                    {
                        addModules.Add(module, modCount);
                    }
                }
            }

            return(addModules.Select(x => (x.Key, x.Value)));
        }