zc
This commit is contained in:
@@ -132,36 +132,62 @@ namespace WulaFallenEmpire
|
|||||||
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
|
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
|
||||||
if (globalStorage == null) return false;
|
if (globalStorage == null) return false;
|
||||||
|
|
||||||
// 检查资源是否足够
|
// 扣除资源(需要处理扣除失败的情况,避免出现“扣料失败但仍返回 true”的无成本生产)
|
||||||
if (!HasEnoughResources()) return false;
|
|
||||||
|
|
||||||
// 扣除资源
|
|
||||||
var productCostList = GetProductCostList();
|
var productCostList = GetProductCostList();
|
||||||
if (productCostList.Count > 0)
|
if (productCostList.Count > 0)
|
||||||
{
|
{
|
||||||
|
Dictionary<ThingDef, int> removed = new Dictionary<ThingDef, int>();
|
||||||
|
|
||||||
foreach (var kvp in productCostList)
|
foreach (var kvp in productCostList)
|
||||||
{
|
{
|
||||||
globalStorage.RemoveFromInputStorage(kvp.Key, kvp.Value);
|
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 true;
|
|
||||||
|
return removed.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<KeyValuePair<ThingDef, int>> removedIngredients = new List<KeyValuePair<ThingDef, int>>();
|
||||||
foreach (var ingredient in recipe.ingredients)
|
foreach (var ingredient in recipe.ingredients)
|
||||||
{
|
{
|
||||||
|
bool removedForThisIngredient = false;
|
||||||
foreach (var thingDef in ingredient.filter.AllowedThingDefs)
|
foreach (var thingDef in ingredient.filter.AllowedThingDefs)
|
||||||
{
|
{
|
||||||
int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
|
int requiredCount = ingredient.CountRequiredOfFor(thingDef, recipe);
|
||||||
int availableCount = globalStorage.GetInputStorageCount(thingDef);
|
int availableCount = globalStorage.GetInputStorageCount(thingDef);
|
||||||
|
|
||||||
if (availableCount >= requiredCount)
|
if (requiredCount > 0 && availableCount >= requiredCount)
|
||||||
{
|
{
|
||||||
globalStorage.RemoveFromInputStorage(thingDef, requiredCount);
|
if (globalStorage.RemoveFromInputStorage(thingDef, requiredCount))
|
||||||
break; // 只扣除一种满足条件的材料
|
{
|
||||||
|
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 true;
|
return removedIngredients.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修复:GetIngredientsTooltip 方法,显示正确的成本信息
|
// 修复:GetIngredientsTooltip 方法,显示正确的成本信息
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace WulaFallenEmpire
|
|||||||
// 修复:明确的工作量定义
|
// 修复:明确的工作量定义
|
||||||
private const float WorkPerSecond = 60f; // 每秒60工作量(标准RimWorld速度)
|
private const float WorkPerSecond = 60f; // 每秒60工作量(标准RimWorld速度)
|
||||||
private const float TicksPerSecond = 60f;
|
private const float TicksPerSecond = 60f;
|
||||||
private const float WorkPerTick = WorkPerSecond / TicksPerSecond; // 每tick 1工作量
|
private int lastProcessedTick = -1;
|
||||||
|
|
||||||
public GlobalProductionOrderStack(Building_GlobalWorkTable table)
|
public GlobalProductionOrderStack(Building_GlobalWorkTable table)
|
||||||
{
|
{
|
||||||
@@ -56,6 +56,13 @@ namespace WulaFallenEmpire
|
|||||||
|
|
||||||
public void ProcessOrders()
|
public void ProcessOrders()
|
||||||
{
|
{
|
||||||
|
int currentTick = Find.TickManager.TicksGame;
|
||||||
|
int deltaTicks = lastProcessedTick < 0 ? 1 : currentTick - lastProcessedTick;
|
||||||
|
if (deltaTicks <= 0) deltaTicks = 1;
|
||||||
|
lastProcessedTick = currentTick;
|
||||||
|
|
||||||
|
float workThisStep = WorkPerSecond * (deltaTicks / TicksPerSecond);
|
||||||
|
|
||||||
// 修复:使用倒序遍历避免修改集合问题
|
// 修复:使用倒序遍历避免修改集合问题
|
||||||
for (int i = orders.Count - 1; i >= 0; i--)
|
for (int i = orders.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
@@ -70,7 +77,7 @@ namespace WulaFallenEmpire
|
|||||||
// 生产中
|
// 生产中
|
||||||
if (order.state == GlobalProductionOrder.ProductionState.Producing)
|
if (order.state == GlobalProductionOrder.ProductionState.Producing)
|
||||||
{
|
{
|
||||||
ProcessProducingOrder(order, i);
|
ProcessProducingOrder(order, i, workThisStep);
|
||||||
}
|
}
|
||||||
else if (order.state == GlobalProductionOrder.ProductionState.Gathering && !order.paused)
|
else if (order.state == GlobalProductionOrder.ProductionState.Gathering && !order.paused)
|
||||||
{
|
{
|
||||||
@@ -79,7 +86,7 @@ namespace WulaFallenEmpire
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessProducingOrder(GlobalProductionOrder order, int index)
|
private void ProcessProducingOrder(GlobalProductionOrder order, int index, float workThisStep)
|
||||||
{
|
{
|
||||||
// 修复:使用正确的方法获取工作量
|
// 修复:使用正确的方法获取工作量
|
||||||
float workAmount = GetWorkAmountForOrder(order);
|
float workAmount = GetWorkAmountForOrder(order);
|
||||||
@@ -93,8 +100,8 @@ namespace WulaFallenEmpire
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修复:正确计算进度增量
|
// 修复:按两次 ProcessOrders 调用间隔的 tick 计算,避免调用频率变化导致生产速度偏差
|
||||||
float progressIncrement = WorkPerTick / workAmount;
|
float progressIncrement = workThisStep / workAmount;
|
||||||
|
|
||||||
// 修复:确保进度不会变成负数
|
// 修复:确保进度不会变成负数
|
||||||
float newProgress = Mathf.Max(0f, order.progress + progressIncrement);
|
float newProgress = Mathf.Max(0f, order.progress + progressIncrement);
|
||||||
@@ -152,15 +159,22 @@ namespace WulaFallenEmpire
|
|||||||
|
|
||||||
private void ProcessWaitingOrder(GlobalProductionOrder order)
|
private void ProcessWaitingOrder(GlobalProductionOrder order)
|
||||||
{
|
{
|
||||||
// 检查是否应该开始生产
|
// 注意:这里不能在不扣料的情况下把 Gathering 直接切到 Producing(会绕过 TryDeductResources)
|
||||||
if (order.HasEnoughResources())
|
if (order.HasEnoughResources())
|
||||||
{
|
{
|
||||||
order.state = GlobalProductionOrder.ProductionState.Producing;
|
if (order.TryDeductResources())
|
||||||
order.progress = 0f;
|
|
||||||
|
|
||||||
if (Find.TickManager.TicksGame % 600 == 0) // 每10秒记录一次
|
|
||||||
{
|
{
|
||||||
Log.Message($"[INFO] Order {order.recipe.defName} started producing");
|
order.state = GlobalProductionOrder.ProductionState.Producing;
|
||||||
|
order.progress = 0f;
|
||||||
|
|
||||||
|
if (Find.TickManager.TicksGame % 600 == 0) // 每10秒记录一次
|
||||||
|
{
|
||||||
|
Log.Message($"[INFO] Order {order.recipe.defName} started producing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning($"[WULA] Order {order.recipe.defName} had enough resources but failed to deduct them; staying in Gathering.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Find.TickManager.TicksGame % 1200 == 0) // 每20秒检查一次
|
else if (Find.TickManager.TicksGame % 1200 == 0) // 每20秒检查一次
|
||||||
@@ -185,7 +199,7 @@ namespace WulaFallenEmpire
|
|||||||
if (order.currentCount >= order.targetCount)
|
if (order.currentCount >= order.targetCount)
|
||||||
{
|
{
|
||||||
order.state = GlobalProductionOrder.ProductionState.Completed;
|
order.state = GlobalProductionOrder.ProductionState.Completed;
|
||||||
orders.RemoveAt(index);
|
Delete(order); // 同步 GlobalStorageWorldComponent.productionOrders
|
||||||
Log.Message($"[COMPLETE] Order {order.recipe.defName} completed and removed");
|
Log.Message($"[COMPLETE] Order {order.recipe.defName} completed and removed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -225,7 +239,7 @@ namespace WulaFallenEmpire
|
|||||||
if (order.recipe == null)
|
if (order.recipe == null)
|
||||||
{
|
{
|
||||||
Log.Warning($"Removing order with null recipe");
|
Log.Warning($"Removing order with null recipe");
|
||||||
orders.RemoveAt(i);
|
Delete(order); // 同步 GlobalStorageWorldComponent.productionOrders
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,6 +126,8 @@ namespace WulaFallenEmpire
|
|||||||
var totalRequired = order.GetProductCostList();
|
var totalRequired = order.GetProductCostList();
|
||||||
if (totalRequired.Count == 0)
|
if (totalRequired.Count == 0)
|
||||||
{
|
{
|
||||||
|
totalRequired = new Dictionary<ThingDef, int>();
|
||||||
|
|
||||||
// 处理配方原料 (Ingredients) - 简化处理,假设配方只使用固定材料
|
// 处理配方原料 (Ingredients) - 简化处理,假设配方只使用固定材料
|
||||||
// 实际情况可能更复杂,需要处理过滤器
|
// 实际情况可能更复杂,需要处理过滤器
|
||||||
foreach (var ingredient in order.recipe.ingredients)
|
foreach (var ingredient in order.recipe.ingredients)
|
||||||
@@ -133,19 +135,20 @@ namespace WulaFallenEmpire
|
|||||||
// 这里简化:只取第一个允许的物品作为需求
|
// 这里简化:只取第一个允许的物品作为需求
|
||||||
// 更好的做法是动态匹配,但这需要更复杂的逻辑
|
// 更好的做法是动态匹配,但这需要更复杂的逻辑
|
||||||
var def = ingredient.filter.AllowedThingDefs.FirstOrDefault();
|
var def = ingredient.filter.AllowedThingDefs.FirstOrDefault();
|
||||||
if (def != null)
|
if (def == null) continue;
|
||||||
{
|
|
||||||
int count = (int)ingredient.GetBaseCount();
|
int count = ingredient.CountRequiredOfFor(def, order.recipe);
|
||||||
if (needed.ContainsKey(def)) needed[def] += count;
|
if (count <= 0) continue;
|
||||||
else needed[def] = count;
|
|
||||||
}
|
if (totalRequired.ContainsKey(def)) totalRequired[def] += count;
|
||||||
|
else totalRequired[def] = count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 减去云端已有的
|
// 2. 减去云端已有的
|
||||||
foreach (var kvp in totalRequired)
|
foreach (var kvp in totalRequired)
|
||||||
{
|
{
|
||||||
int cloudCount = storage.GetInputStorageCount(kvp.Key);
|
int cloudCount = storage?.GetInputStorageCount(kvp.Key) ?? 0;
|
||||||
int remaining = kvp.Value - cloudCount;
|
int remaining = kvp.Value - cloudCount;
|
||||||
|
|
||||||
// 3. 减去工作台容器中已有的
|
// 3. 减去工作台容器中已有的
|
||||||
@@ -161,4 +164,4 @@ namespace WulaFallenEmpire
|
|||||||
return needed;
|
return needed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user