352 lines
13 KiB
C#
352 lines
13 KiB
C#
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;
|
||
}
|
||
}
|
||
} |