Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/GlobalWorkTable/GlobalProductionOrder.cs
ProjectKoi-Kalo\Kalo 98a0400c78 WulaFallenEmpireSettings.cs - 添加了 public bool enableDebugLogs = false; 字段和保存配置
 WulaLog.cs - 修改了DebugEnabled属性,仅检查enableDebugLogs设置(不检查DevMode)
 WulaFallenEmpireMod.cs - 在DoSettingsWindowContents中添加了UI复选框,显示"Enable Debug Logs"选项
 替换了所有848个Log.Message/Error/Warning调用为WulaLog.Debug()
2025-12-15 13:05:50 +08:00

350 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// GlobalProductionOrder.cs (修复成本计算使用产物的costList)
using RimWorld;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public class GlobalProductionOrder : IExposable
{
public RecipeDef recipe;
public int targetCount = 1;
public int currentCount = 0;
public bool paused = false;
// 生产状态
public ProductionState state = ProductionState.Gathering;
public enum ProductionState
{
Gathering, // 准备材料(小人搬运中)
Producing, // 生产中(云端倒计时)
Completed // 完成
}
public string Label => recipe.LabelCap;
public string Description => $"{currentCount}/{targetCount} {recipe.products[0].thingDef.label}";
private float _progress = 0f;
public float progress
{
get => _progress;
set
{
_progress = Mathf.Clamp01(value);
if (value < 0f || value > 1f)
{
WulaLog.Debug($"Progress clamped from {value} to {_progress} for {recipe?.defName ?? "unknown"}");
}
}
}
// 修正获取产物的ThingDef
public ThingDef ProductDef => recipe?.products?.Count > 0 ? recipe.products[0].thingDef : null;
public void ExposeData()
{
Scribe_Defs.Look(ref recipe, "recipe");
Scribe_Values.Look(ref targetCount, "targetCount", 1);
Scribe_Values.Look(ref currentCount, "currentCount", 0);
Scribe_Values.Look(ref paused, "paused", false);
Scribe_Values.Look(ref _progress, "progress", 0f);
Scribe_Values.Look(ref state, "state", ProductionState.Gathering);
// 修复:加载后验证数据
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
progress = _progress;
UpdateState();
}
}
// 新增:获取产物的成本列表
public Dictionary<ThingDef, int> GetProductCostList()
{
var costDict = new Dictionary<ThingDef, int>();
if (ProductDef?.costList != null)
{
foreach (var cost in ProductDef.costList)
{
if (costDict.ContainsKey(cost.thingDef))
costDict[cost.thingDef] += cost.count;
else
costDict[cost.thingDef] = cost.count;
}
}
return costDict;
}
// 修复HasEnoughResources 方法使用产物的costList
public bool HasEnoughResources()
{
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null) return false;
// 首先检查产物的costList对于武器等物品
var productCostList = GetProductCostList();
if (productCostList.Count > 0)
{
foreach (var kvp in productCostList)
{
int requiredCount = kvp.Value;
int availableCount = globalStorage.GetInputStorageCount(kvp.Key);
if (availableCount < requiredCount)
return false;
}
return true;
}
// 如果没有costList则回退到配方的ingredients对于加工类配方
foreach (var ingredient in recipe.ingredients)
{
bool hasEnoughForThisIngredient = false;
foreach (var thingDef in ingredient.filter.AllowedThingDefs)
{
int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
int availableCount = globalStorage.GetInputStorageCount(thingDef);
if (availableCount >= requiredCount)
{
hasEnoughForThisIngredient = true;
break;
}
}
if (!hasEnoughForThisIngredient)
return false;
}
return true;
}
// 修复TryDeductResources 方法,尝试扣除资源
public bool TryDeductResources()
{
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null) return false;
// 扣除资源(需要处理扣除失败的情况,避免出现“扣料失败但仍返回 true”的无成本生产
var productCostList = GetProductCostList();
if (productCostList.Count > 0)
{
Dictionary<ThingDef, int> removed = new Dictionary<ThingDef, int>();
foreach (var kvp in productCostList)
{
if (kvp.Value <= 0) continue;
if (!globalStorage.RemoveFromInputStorage(kvp.Key, kvp.Value))
{
foreach (var r in removed)
{
globalStorage.AddToInputStorage(r.Key, r.Value);
}
return false;
}
removed[kvp.Key] = kvp.Value;
}
return removed.Count > 0;
}
List<KeyValuePair<ThingDef, int>> removedIngredients = new List<KeyValuePair<ThingDef, int>>();
foreach (var ingredient in recipe.ingredients)
{
bool removedForThisIngredient = false;
foreach (var thingDef in ingredient.filter.AllowedThingDefs)
{
int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
int availableCount = globalStorage.GetInputStorageCount(thingDef);
if (requiredCount > 0 && availableCount >= requiredCount)
{
if (globalStorage.RemoveFromInputStorage(thingDef, requiredCount))
{
removedIngredients.Add(new KeyValuePair<ThingDef, int>(thingDef, requiredCount));
removedForThisIngredient = true;
break; // 只扣除一种满足条件的材料
}
}
}
if (!removedForThisIngredient)
{
foreach (var r in removedIngredients)
{
globalStorage.AddToInputStorage(r.Key, r.Value);
}
return false;
}
}
return removedIngredients.Count > 0;
}
// 修复GetIngredientsTooltip 方法,显示正确的成本信息
public string GetIngredientsTooltip()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine(recipe.LabelCap);
sb.AppendLine();
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
// 首先显示产物的costList对于武器等物品
var productCostList = GetProductCostList();
if (productCostList.Count > 0)
{
sb.AppendLine("WULA_FixedIngredients".Translate() + ":");
foreach (var kvp in productCostList)
{
ThingDef thingDef = kvp.Key;
int requiredCount = kvp.Value;
int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0;
string itemDisplay = $"{requiredCount} {thingDef.LabelCap}";
if (availableCount >= requiredCount)
{
sb.AppendLine($" <color=green>{itemDisplay}</color>");
}
else
{
sb.AppendLine($" <color=red>{itemDisplay}</color>");
}
}
}
else
{
// 如果没有costList显示配方的ingredients对于加工类配方
sb.AppendLine("WULA_FixedIngredients".Translate() + ":");
foreach (var ingredient in recipe.ingredients)
{
foreach (var thingDef in ingredient.filter.AllowedThingDefs)
{
int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
int availableCount = globalStorage?.GetInputStorageCount(thingDef) ?? 0;
string itemDisplay = $"{requiredCount} {thingDef.LabelCap}";
if (availableCount >= requiredCount)
{
sb.AppendLine($" <color=green>{itemDisplay}</color>");
}
else
{
sb.AppendLine($" <color=red>{itemDisplay}</color>");
}
}
}
}
// 产品
sb.AppendLine();
sb.AppendLine("WULA_Products".Translate() + ":");
foreach (var product in recipe.products)
{
sb.AppendLine($" {product.count} {product.thingDef.LabelCap}");
}
// 工作量信息
sb.AppendLine();
sb.AppendLine("WULA_WorkAmount".Translate() + ": " + GetWorkAmount().ToStringWorkAmount());
return sb.ToString();
}
// 其余方法保持不变...
public void UpdateState()
{
if (state == ProductionState.Completed)
return;
if (currentCount >= targetCount)
{
state = ProductionState.Completed;
progress = 0f;
return;
}
// 自动状态切换逻辑仅用于从Gathering切换到Producing
// 注意:现在资源的扣除是显式的,所以这里只检查是否可以开始
if (state == ProductionState.Gathering && !paused)
{
if (HasEnoughResources())
{
// 尝试扣除资源并开始生产
if (TryDeductResources())
{
state = ProductionState.Producing;
progress = 0f;
}
}
}
}
public void Produce()
{
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null)
return;
foreach (var product in recipe.products)
{
if (product.thingDef.race != null)
{
globalStorage.AddToOutputStorage(product.thingDef, product.count);
}
else
{
globalStorage.AddToOutputStorage(product.thingDef, product.count);
}
}
currentCount++;
progress = 0f;
if (currentCount >= targetCount)
{
state = ProductionState.Completed;
}
}
public float GetWorkAmount()
{
if (recipe == null)
return 1000f;
if (recipe.workAmount > 0)
return recipe.workAmount;
if (recipe.products != null && recipe.products.Count > 0)
{
ThingDef productDef = recipe.products[0].thingDef;
if (productDef != null)
{
float workToMake = productDef.GetStatValueAbstract(StatDefOf.WorkToMake);
if (workToMake > 0)
return workToMake;
float marketValue = productDef.GetStatValueAbstract(StatDefOf.MarketValue);
if (marketValue > 0)
return marketValue * 10f;
}
}
return 1000f;
}
}
}