/// <summary> /// 居住モジュールの必要ウェアを計算 /// </summary> /// <param name="module">計算対象モジュール</param> /// <param name="moduleCount">モジュール数</param> /// <returns>必要ウェアの列挙</returns> private IEnumerable <CalcResult> CalcHabitationModuleResources(IX4Module module, long moduleCount) { // 居住モジュールか? if (0 < module.WorkersCapacity) { // 居住モジュールの種族を取得 var ownerRace = module.Owners.FirstOrDefault()?.Race; if (ownerRace is not null) { var workUnit = X4Database.Instance.Ware.Get("workunit_busy"); var method = workUnit.Resources.ContainsKey(ownerRace.RaceID) ? ownerRace.RaceID : "default"; var prod = workUnit.TryGetProduction(method) ?? throw new InvalidOperationException(); if (workUnit.Resources.TryGetValue(method, out var resources)) { foreach (var resource in resources) { // ウェア消費量 var amount = (long)Math.Floor(-3600 / prod.Time * resource.Amount); yield return(new CalcResult(resource.NeedWareID, amount, method, module, moduleCount)); } } } } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="wareID">生産/消費ウェアID</param> /// <param name="wareAmount">ウェア生産/消費量</param> /// <param name="method">ウェア生産方式</param> /// <param name="module">生産/消費ウェアを生産/消費するモジュール</param> /// <param name="moduleCount">生産/消費ウェアを生産/消費するモジュールの数</param> /// <param name="efficiency">ウェア生産の追加効果</param> public CalcResult(string wareID, long wareAmount, string method, IX4Module module, long moduleCount, IReadOnlyDictionary <string, IWareEffect>?efficiency = null) { WareID = wareID; WareAmount = wareAmount; Method = method; Module = module; ModuleCount = moduleCount; Efficiency = efficiency; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="module">表示対象モジュール</param> public ModulesGridItem(IX4Module module) { _Module = module; // 所有派閥を設定(ある種族固有の場合のみ表示) var ownerRaces = _Module.Owners.Select(x => x.Race.Name).OrderBy(x => x).Distinct().ToArray(); Race = (ownerRaces.Length == 1) ? ownerRaces[0] : ""; // 製品がある場合、製品の情報を設定 if (_Module.Products.Any()) { var firstWare = _Module.Products.First(); _Product = X4Database.Instance.Ware.Get(firstWare.WareID); MaxEfficiency = (long)((_Product.WareEffects.TryGet(firstWare.Method, "work")?.Product ?? 0.0 + 1) * 100); } }
/// <summary> /// 製造モジュールの製品と必要ウェアを計算 /// </summary> /// <param name="module">計算対象のモジュール</param> /// <param name="moduleCount">モジュール数</param> /// <returns>製品と必要ウェアの列挙</returns> private IEnumerable <CalcResult> CalcProductAndResources(IX4Module module, long moduleCount) { // モジュールの生産品を取得 foreach (var product in module.Products) { // 生産品IDに対応するウェアを取得 var prodWare = X4Database.Instance.Ware.Get(product.WareID); // ウェア生産方式を取得 var method = prodWare.Resources.ContainsKey(product.Method) ? product.Method : "default"; // ウェア生産情報を取得 var wareProduction = prodWare.TryGetProduction(product.Method) ?? throw new ArgumentException(); { // ウェア生産時の追加効果一覧をウェア生産方式別に抽出 var effects = prodWare.WareEffects.TryGet(product.Method); // ウェア生産量 var amount = (long)Math.Floor(wareProduction.Amount * (3600 / wareProduction.Time)); yield return(new CalcResult(product.WareID, amount, method, module, moduleCount, effects)); } // 有効なウェア生産方式か? if (prodWare.Resources.TryGetValue(method, out var resources)) { foreach (var resource in resources) { // ウェア消費量 var amount = (long)Math.Floor(-3600 / wareProduction.Time * resource.Amount); yield return(new CalcResult(resource.NeedWareID, amount, method, module, moduleCount)); } } } }
/// <summary> /// 製品と必要ウェアを計算 /// </summary> /// <param name="module"></param> /// <param name="moduleCount">モジュール数</param> /// <returns></returns> public IEnumerable <CalcResult> Calc(IX4Module module, long moduleCount) { return(CalcProductAndResources(module, moduleCount) .Concat(CalcHabitationModuleResources(module, moduleCount))); }