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

352 lines
13 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;
using System.Text.Json;
public partial class ProductionLineManager : Node
{
public static ProductionLineManager Instance { get; private set; }
public class ProductionRecipeItem
{
public string ItemId { get; set; }
public int Quantity { get; set; }
}
public class ProductionRecipe
{
public List<ProductionRecipeItem> Inputs { get; set; } = new List<ProductionRecipeItem>();
public List<ProductionRecipeItem> Outputs { get; set; } = new List<ProductionRecipeItem>();
}
public class ProductionLine
{
public string Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public string Description { get; set; }
public float ProductionTime { get; set; }
public int PowerConsumption { get; set; }
public int PowerGeneration { get; set; } = 0; // 新增:发电量
public List<ProductionRecipeItem> BuildingRequirements { get; set; } = new List<ProductionRecipeItem>();
public ProductionRecipe Recipe { get; set; } = new ProductionRecipe();
}
public class ProductionLineData
{
public List<ProductionLine> ProductionLines { get; set; } = new List<ProductionLine>();
}
// 活跃的产线实例
public class ActiveProductionLine
{
public string ProductionLineId { get; set; }
public int BuildingCount { get; set; } = 0; // 建筑数量
public float RemainingTime { get; set; } = 0; // 当前循环剩余时间
public bool IsActive { get; set; } = false; // 是否激活
public float ProductionRate { get; set; } = 0; // 每秒产出率
public int TotalPowerConsumption { get; set; } = 0; // 总功耗
public int TotalPowerGeneration { get; set; } = 0; // 总发电量
}
private ProductionLineData productionLineData;
private Dictionary<string, ProductionLine> productionLineMap = new Dictionary<string, ProductionLine>();
private Dictionary<string, List<ProductionLine>> categoryMap = new Dictionary<string, List<ProductionLine>>();
private Dictionary<string, ActiveProductionLine> activeProductionLines = new Dictionary<string, ActiveProductionLine>();
public override void _Ready()
{
if (Instance == null)
{
Instance = this;
LoadProductionLines();
}
else
{
QueueFree();
}
}
private void LoadProductionLines()
{
string configPath = "res://data/config/production_lines.json";
if (!FileAccess.FileExists(configPath))
{
GD.PrintErr($"自动产线配置文件不存在: {configPath}");
return;
}
using var file = FileAccess.Open(configPath, FileAccess.ModeFlags.Read);
if (file == null)
{
GD.PrintErr($"无法打开自动产线配置文件: {configPath}");
return;
}
string jsonContent = file.GetAsText();
try
{
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
productionLineData = JsonSerializer.Deserialize<ProductionLineData>(jsonContent, options);
if (productionLineData?.ProductionLines != null)
{
// 构建产线映射
foreach (var line in productionLineData.ProductionLines)
{
productionLineMap[line.Id] = line;
// 按分类分组
if (!categoryMap.ContainsKey(line.Category))
{
categoryMap[line.Category] = new List<ProductionLine>();
}
categoryMap[line.Category].Add(line);
GD.Print($"加载自动产线: {line.Id} - {line.Name} ({line.Category})");
}
GD.Print($"成功加载 {productionLineData.ProductionLines.Count} 个自动产线");
}
}
catch (JsonException e)
{
GD.PrintErr($"解析自动产线配置文件失败: {e.Message}");
}
}
public List<ProductionLine> GetAllProductionLines()
{
return productionLineData?.ProductionLines ?? new List<ProductionLine>();
}
public ProductionLine GetProductionLine(string lineId)
{
return productionLineMap.GetValueOrDefault(lineId);
}
public List<ProductionLine> GetProductionLinesByCategory(string category)
{
return categoryMap.GetValueOrDefault(category) ?? new List<ProductionLine>();
}
public List<string> GetAllCategories()
{
return new List<string>(categoryMap.Keys);
}
// 建筑管理
public void AddBuilding(string productionLineId, int count = 1)
{
var productionLine = GetProductionLine(productionLineId);
if (productionLine == null)
{
GD.PrintErr($"找不到产线: {productionLineId}");
return;
}
// 检查建筑需求
if (productionLine.BuildingRequirements == null || productionLine.BuildingRequirements.Count == 0)
{
GD.PrintErr($"产线 {productionLine.Name} 没有定义建筑需求");
return;
}
// 检查是否有足够的建筑材料
var inventoryManager = InventoryManager.Instance;
if (inventoryManager == null)
{
GD.PrintErr("InventoryManager实例为null");
return;
}
// 验证所有建筑需求
foreach (var requirement in productionLine.BuildingRequirements)
{
int available = inventoryManager.GetItemQuantity(requirement.ItemId);
int needed = requirement.Quantity * count;
if (available < needed)
{
var itemData = GameData.Instance?.GetItem(requirement.ItemId);
string itemName = itemData?.Name ?? requirement.ItemId;
GD.Print($"建筑材料不足,需要 {needed} 个 {itemName},当前只有 {available} 个");
return;
}
}
// 扣除建筑材料
foreach (var requirement in productionLine.BuildingRequirements)
{
int consumeAmount = requirement.Quantity * count;
inventoryManager.RemoveItem(requirement.ItemId, consumeAmount);
}
// 添加到活跃产线
if (!activeProductionLines.ContainsKey(productionLineId))
{
activeProductionLines[productionLineId] = new ActiveProductionLine
{
ProductionLineId = productionLineId,
RemainingTime = productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0
? 0 // 发电设备不需要生产时间
: productionLine.ProductionTime // 普通生产设备从完整的生产时间开始
};
if (productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0)
{
GD.Print($"创建新发电设备 {productionLine.Name},无需生产周期");
}
else
{
GD.Print($"创建新产线 {productionLine.Name},初始剩余时间: {productionLine.ProductionTime}s");
}
}
var activeLine = activeProductionLines[productionLineId];
activeLine.BuildingCount += count;
activeLine.IsActive = true;
// 重新计算产出率:发电设备特殊处理
if (productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0)
{
// 发电设备不产出物品产出率设为0
activeLine.ProductionRate = 0;
}
else if (productionLine.ProductionTime > 0)
{
activeLine.ProductionRate = activeLine.BuildingCount / productionLine.ProductionTime;
}
else
{
activeLine.ProductionRate = 0; // 避免除零
}
activeLine.TotalPowerConsumption = activeLine.BuildingCount * productionLine.PowerConsumption;
activeLine.TotalPowerGeneration = activeLine.BuildingCount * productionLine.PowerGeneration;
// 如果是发电设备通知PowerManager
if (productionLine.PowerGeneration > 0)
{
var powerManager = PowerManager.Instance;
if (powerManager != null)
{
// 使用更简单的generatorId避免重复问题
string generatorId = $"{productionLineId}";
float totalGeneration = productionLine.PowerGeneration * activeLine.BuildingCount;
powerManager.AddGenerator(generatorId, totalGeneration);
GD.Print($"发电设备 {productionLine.Name} 已添加到电网: +{totalGeneration}W");
}
}
GD.Print($"成功添加 {count} 个设备到产线 {productionLine.Name}");
GD.Print($"当前产线状态: {activeLine.BuildingCount} 个建筑, 产出率: {activeLine.ProductionRate:F2}/s, 功耗: {activeLine.TotalPowerConsumption}W, 发电: {activeLine.TotalPowerGeneration}W");
}
public void RemoveBuilding(string productionLineId, int count = 1)
{
if (!activeProductionLines.ContainsKey(productionLineId))
{
GD.Print($"产线 {productionLineId} 没有建筑可移除");
return;
}
var activeLine = activeProductionLines[productionLineId];
var productionLine = GetProductionLine(productionLineId);
count = Mathf.Min(count, activeLine.BuildingCount);
if (count <= 0) return;
// 如果是发电设备先通知PowerManager移除发电量
if (productionLine.PowerGeneration > 0)
{
var powerManager = PowerManager.Instance;
if (powerManager != null)
{
string generatorId = $"{productionLineId}";
float totalGeneration = productionLine.PowerGeneration * activeLine.BuildingCount;
powerManager.RemoveGenerator(generatorId);
}
}
activeLine.BuildingCount -= count;
if (activeLine.BuildingCount <= 0)
{
activeLine.IsActive = false;
activeLine.ProductionRate = 0;
activeLine.TotalPowerConsumption = 0;
activeLine.TotalPowerGeneration = 0;
}
else
{
// 重新计算产出率:发电设备特殊处理
if (productionLine.PowerGeneration > 0 && productionLine.ProductionTime <= 0)
{
// 发电设备不产出物品产出率设为0
activeLine.ProductionRate = 0;
}
else if (productionLine.ProductionTime > 0)
{
activeLine.ProductionRate = activeLine.BuildingCount / productionLine.ProductionTime;
}
else
{
activeLine.ProductionRate = 0; // 避免除零
}
activeLine.TotalPowerConsumption = activeLine.BuildingCount * productionLine.PowerConsumption;
activeLine.TotalPowerGeneration = activeLine.BuildingCount * productionLine.PowerGeneration;
// 如果是发电设备且还有剩余建筑重新添加到PowerManager
if (productionLine.PowerGeneration > 0)
{
var powerManager = PowerManager.Instance;
if (powerManager != null)
{
string newGeneratorId = $"{productionLineId}";
float totalGeneration = productionLine.PowerGeneration * activeLine.BuildingCount;
powerManager.AddGenerator(newGeneratorId, totalGeneration);
GD.Print($"发电设备 {productionLine.Name} 已添加到电网: +{totalGeneration}W");
}
}
}
// 归还建筑材料到库存
var inventoryManager = InventoryManager.Instance;
if (inventoryManager != null && productionLine.BuildingRequirements != null)
{
foreach (var requirement in productionLine.BuildingRequirements)
{
int returnAmount = requirement.Quantity * count;
inventoryManager.AddItem(requirement.ItemId, returnAmount);
}
}
GD.Print($"移除 {count} 个设备从产线 {productionLine.Name}");
GD.Print($"当前产线状态: {activeLine.BuildingCount} 个建筑, 产出率: {activeLine.ProductionRate:F2}/s, 功耗: {activeLine.TotalPowerConsumption}W, 发电: {activeLine.TotalPowerGeneration}W");
}
public ActiveProductionLine GetActiveProductionLine(string productionLineId)
{
return activeProductionLines.GetValueOrDefault(productionLineId);
}
public Dictionary<string, ActiveProductionLine> GetAllActiveProductionLines()
{
return activeProductionLines;
}
public override void _ExitTree()
{
if (Instance == this)
{
Instance = null;
}
}
}