233 lines
8.2 KiB
C#
233 lines
8.2 KiB
C#
using Godot;
|
||
using System.Collections.Generic;
|
||
|
||
public partial class ProductionProcessor : Node
|
||
{
|
||
public static ProductionProcessor Instance { get; private set; }
|
||
|
||
public override void _Ready()
|
||
{
|
||
if (Instance == null)
|
||
{
|
||
Instance = this;
|
||
GD.Print("ProductionProcessor 初始化完成");
|
||
}
|
||
else
|
||
{
|
||
QueueFree();
|
||
}
|
||
}
|
||
|
||
public override void _Process(double delta)
|
||
{
|
||
ProcessAllProductionLines((float)delta);
|
||
}
|
||
|
||
private void ProcessAllProductionLines(float deltaTime)
|
||
{
|
||
var productionLineManager = ProductionLineManager.Instance;
|
||
if (productionLineManager == null) return;
|
||
|
||
var activeLines = productionLineManager.GetAllActiveProductionLines();
|
||
|
||
foreach (var kvp in activeLines)
|
||
{
|
||
var activeLine = kvp.Value;
|
||
if (!activeLine.IsActive || activeLine.BuildingCount <= 0) continue;
|
||
|
||
ProcessProductionLine(activeLine, deltaTime);
|
||
}
|
||
}
|
||
|
||
private void ProcessProductionLine(ProductionLineManager.ActiveProductionLine activeLine, float deltaTime)
|
||
{
|
||
var productionLine = ProductionLineManager.Instance?.GetProductionLine(activeLine.ProductionLineId);
|
||
if (productionLine == null) return;
|
||
|
||
// 特殊处理:如果是发电设备(powerGeneration > 0 且 productionTime <= 0),跳过生产处理
|
||
if (productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0)
|
||
{
|
||
// 发电设备不需要生产周期,直接返回
|
||
// 发电量已经在添加建筑时注册到PowerManager了
|
||
return;
|
||
}
|
||
|
||
// 获取电力满足率
|
||
float powerRatio = 1.0f;
|
||
var powerManager = PowerManager.Instance;
|
||
if (powerManager != null)
|
||
{
|
||
powerRatio = powerManager.GetPowerRatio();
|
||
}
|
||
|
||
// 根据电力满足率调整生产速度
|
||
float adjustedDeltaTime = deltaTime * powerRatio;
|
||
|
||
// 如果电力不足,减慢生产速度
|
||
if (powerRatio < 1.0f)
|
||
{
|
||
GD.Print($"产线 {productionLine.Name} 电力不足,生产速度调整为 {powerRatio * 100:F1}%");
|
||
}
|
||
|
||
// 更新生产时间
|
||
activeLine.RemainingTime -= adjustedDeltaTime;
|
||
|
||
if (activeLine.RemainingTime <= 0)
|
||
{
|
||
// 检查是否有足够的原料
|
||
if (CheckInputMaterials(productionLine, activeLine.BuildingCount))
|
||
{
|
||
// 消耗原料
|
||
ConsumeInputMaterials(productionLine, activeLine.BuildingCount);
|
||
|
||
// 生产产品
|
||
ProduceOutputItems(productionLine, activeLine.BuildingCount);
|
||
|
||
// 重置生产时间
|
||
activeLine.RemainingTime = productionLine.ProductionTime;
|
||
|
||
GD.Print($"产线 {productionLine.Name} 完成一轮生产,{activeLine.BuildingCount} 个建筑同时运行");
|
||
|
||
// 如果是发电设备,通知PowerManager(发电机运行)
|
||
if (productionLine.PowerGeneration > 0)
|
||
{
|
||
if (powerManager != null)
|
||
{
|
||
string generatorId = $"{activeLine.ProductionLineId}_{activeLine.BuildingCount}";
|
||
powerManager.UpdateGeneratorStatus(generatorId, true);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 原料不足,暂停生产
|
||
activeLine.RemainingTime = 0.1f; // 短暂等待后再检查
|
||
GD.Print($"产线 {productionLine.Name} 原料不足,暂停生产");
|
||
|
||
// 如果是发电设备,通知PowerManager(发电机异常)
|
||
if (productionLine.PowerGeneration > 0)
|
||
{
|
||
if (powerManager != null)
|
||
{
|
||
string generatorId = $"{activeLine.ProductionLineId}_{activeLine.BuildingCount}";
|
||
powerManager.UpdateGeneratorStatus(generatorId, false);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private bool CheckInputMaterials(ProductionLineManager.ProductionLine productionLine, int buildingCount)
|
||
{
|
||
var inventoryManager = InventoryManager.Instance;
|
||
if (inventoryManager == null) return false;
|
||
|
||
// 如果没有输入材料需求(如发电设备),直接返回true
|
||
if (productionLine.Recipe.Inputs == null || productionLine.Recipe.Inputs.Count == 0)
|
||
{
|
||
return true;
|
||
}
|
||
|
||
// 检查所有输入材料
|
||
foreach (var input in productionLine.Recipe.Inputs)
|
||
{
|
||
int requiredQuantity = input.Quantity * buildingCount;
|
||
int availableQuantity = inventoryManager.GetItemQuantity(input.ItemId);
|
||
|
||
if (availableQuantity < requiredQuantity)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
private void ConsumeInputMaterials(ProductionLineManager.ProductionLine productionLine, int buildingCount)
|
||
{
|
||
var inventoryManager = InventoryManager.Instance;
|
||
if (inventoryManager == null) return;
|
||
|
||
foreach (var input in productionLine.Recipe.Inputs)
|
||
{
|
||
int consumeQuantity = input.Quantity * buildingCount;
|
||
inventoryManager.RemoveItem(input.ItemId, consumeQuantity);
|
||
|
||
var itemData = GameData.Instance?.GetItem(input.ItemId);
|
||
string itemName = itemData?.Name ?? input.ItemId;
|
||
GD.Print($"消耗材料: {itemName} x{consumeQuantity}");
|
||
}
|
||
}
|
||
|
||
private void ProduceOutputItems(ProductionLineManager.ProductionLine productionLine, int buildingCount)
|
||
{
|
||
var inventoryManager = InventoryManager.Instance;
|
||
if (inventoryManager == null) return;
|
||
|
||
foreach (var output in productionLine.Recipe.Outputs)
|
||
{
|
||
int produceQuantity = output.Quantity * buildingCount;
|
||
inventoryManager.AddItem(output.ItemId, produceQuantity);
|
||
|
||
var itemData = GameData.Instance?.GetItem(output.ItemId);
|
||
string itemName = itemData?.Name ?? output.ItemId;
|
||
GD.Print($"生产物品: {itemName} x{produceQuantity}");
|
||
}
|
||
}
|
||
|
||
// 公共方法:获取产线当前状态信息
|
||
public ProductionLineStatus GetProductionLineStatus(string productionLineId)
|
||
{
|
||
var activeLine = ProductionLineManager.Instance?.GetActiveProductionLine(productionLineId);
|
||
var productionLine = ProductionLineManager.Instance?.GetProductionLine(productionLineId);
|
||
|
||
if (activeLine == null || productionLine == null)
|
||
{
|
||
return new ProductionLineStatus
|
||
{
|
||
IsActive = false,
|
||
Progress = 0,
|
||
ProductionRate = 0,
|
||
PowerConsumption = 0,
|
||
BuildingCount = 0
|
||
};
|
||
}
|
||
|
||
float progress = 0;
|
||
// 发电设备的进度条始终显示100%
|
||
if (productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0)
|
||
{
|
||
progress = 1.0f; // 发电设备进度始终为100%
|
||
}
|
||
else if (activeLine.IsActive && productionLine.ProductionTime > 0)
|
||
{
|
||
progress = 1.0f - (activeLine.RemainingTime / productionLine.ProductionTime);
|
||
}
|
||
|
||
return new ProductionLineStatus
|
||
{
|
||
IsActive = activeLine.IsActive,
|
||
Progress = Mathf.Clamp(progress, 0.0f, 1.0f),
|
||
ProductionRate = activeLine.ProductionRate,
|
||
PowerConsumption = activeLine.TotalPowerConsumption,
|
||
BuildingCount = activeLine.BuildingCount
|
||
};
|
||
}
|
||
|
||
public class ProductionLineStatus
|
||
{
|
||
public bool IsActive { get; set; }
|
||
public float Progress { get; set; } // 0-1的进度
|
||
public float ProductionRate { get; set; } // 每秒产出率
|
||
public int PowerConsumption { get; set; } // 功耗
|
||
public int BuildingCount { get; set; } // 建筑数量
|
||
}
|
||
|
||
public override void _ExitTree()
|
||
{
|
||
if (Instance == this)
|
||
{
|
||
Instance = null;
|
||
}
|
||
}
|
||
} |