Files
Godot-test/scripts/production/ProductionProcessor.cs
2025-06-22 20:39:47 +08:00

233 lines
8.2 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.

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;
}
}
}