Files
Godot-test/scripts/production/ProductionProcessor.cs

177 lines
5.9 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;
// 更新生产时间
activeLine.RemainingTime -= deltaTime;
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} 个建筑同时运行");
}
else
{
// 原料不足,暂停生产
activeLine.RemainingTime = 0.1f; // 短暂等待后再检查
GD.Print($"产线 {productionLine.Name} 原料不足,暂停生产");
}
}
}
private bool CheckInputMaterials(ProductionLineManager.ProductionLine productionLine, int buildingCount)
{
var inventoryManager = InventoryManager.Instance;
if (inventoryManager == null) return false;
// 检查所有输入材料
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;
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;
}
}
}