Init
This commit is contained in:
384
scripts/production/CraftingQueueManager.cs
Normal file
384
scripts/production/CraftingQueueManager.cs
Normal file
@ -0,0 +1,384 @@
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public partial class CraftingQueueManager : Panel
|
||||
{
|
||||
public class CraftingQueueItem
|
||||
{
|
||||
public string RecipeId { get; set; }
|
||||
public int Quantity { get; set; } = 1;
|
||||
public float RemainingTime { get; set; }
|
||||
public float TotalTime { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
}
|
||||
|
||||
private const int MAX_QUEUE_SIZE = 8;
|
||||
private List<CraftingQueueItem> craftingQueue = new List<CraftingQueueItem>();
|
||||
private List<Panel> slotPanels = new List<Panel>();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GD.Print("CraftingQueueManager _Ready 开始");
|
||||
|
||||
// 获取所有槽位面板
|
||||
var queueContainer = GetNode<HBoxContainer>("MarginContainer/VBoxContainer/QueueContainer");
|
||||
for (int i = 1; i <= MAX_QUEUE_SIZE; i++)
|
||||
{
|
||||
var slot = queueContainer.GetNode<Panel>($"Slot{i}");
|
||||
slotPanels.Add(slot);
|
||||
}
|
||||
|
||||
// 初始化队列显示
|
||||
UpdateQueueDisplay();
|
||||
|
||||
GD.Print("CraftingQueueManager 初始化完成");
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
ProcessCrafting((float)delta);
|
||||
}
|
||||
|
||||
private void ProcessCrafting(float deltaTime)
|
||||
{
|
||||
if (craftingQueue.Count == 0) return;
|
||||
|
||||
// 处理第一个(当前正在制作的)物品
|
||||
var currentItem = craftingQueue[0];
|
||||
if (!currentItem.IsActive)
|
||||
{
|
||||
// 开始制作
|
||||
currentItem.IsActive = true;
|
||||
GD.Print($"开始制作: {currentItem.RecipeId}");
|
||||
// 重新更新显示以确保进度条正确初始化
|
||||
UpdateQueueDisplay();
|
||||
return; // 这一帧先不处理时间,让UI先更新
|
||||
}
|
||||
|
||||
currentItem.RemainingTime -= deltaTime;
|
||||
|
||||
if (currentItem.RemainingTime <= 0)
|
||||
{
|
||||
// 制作完成
|
||||
CompleteCrafting(currentItem);
|
||||
craftingQueue.RemoveAt(0);
|
||||
UpdateQueueDisplay();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更新进度显示
|
||||
float progress = 1.0f - (currentItem.RemainingTime / currentItem.TotalTime);
|
||||
UpdateSlotProgress(0, progress);
|
||||
}
|
||||
}
|
||||
|
||||
private void CompleteCrafting(CraftingQueueItem item)
|
||||
{
|
||||
var recipe = CraftingRecipeManager.Instance?.GetRecipe(item.RecipeId);
|
||||
if (recipe == null || InventoryManager.Instance == null)
|
||||
{
|
||||
GD.PrintErr($"无法完成制作: {item.RecipeId}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加产品到库存(数量 = 配方产出数量 × 批量数量)
|
||||
int totalOutputQuantity = recipe.OutputQuantity * item.Quantity;
|
||||
InventoryManager.Instance.AddItem(recipe.OutputItem, totalOutputQuantity);
|
||||
|
||||
GD.Print($"制作完成: {recipe.OutputItem} x{totalOutputQuantity} (批量: {item.Quantity})");
|
||||
}
|
||||
|
||||
public bool AddToQueue(string recipeId, int quantity = 1)
|
||||
{
|
||||
if (craftingQueue.Count >= MAX_QUEUE_SIZE)
|
||||
{
|
||||
GD.Print("合成队列已满");
|
||||
return false;
|
||||
}
|
||||
|
||||
var recipe = CraftingRecipeManager.Instance?.GetRecipe(recipeId);
|
||||
if (recipe == null)
|
||||
{
|
||||
GD.PrintErr($"找不到配方: {recipeId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否有足够的材料制作指定数量
|
||||
foreach (var ingredient in recipe.Ingredients)
|
||||
{
|
||||
int requiredQuantity = ingredient.Quantity * quantity;
|
||||
if (InventoryManager.Instance.GetItemQuantity(ingredient.ItemId) < requiredQuantity)
|
||||
{
|
||||
GD.Print($"材料不足,无法制作 {quantity} 个: {recipeId}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 扣除材料(数量 = 配方需求 × 批量数量)
|
||||
foreach (var ingredient in recipe.Ingredients)
|
||||
{
|
||||
int totalRequired = ingredient.Quantity * quantity;
|
||||
InventoryManager.Instance.RemoveItem(ingredient.ItemId, totalRequired);
|
||||
GD.Print($"扣除材料: {ingredient.ItemId} x{totalRequired} (批量: {quantity})");
|
||||
}
|
||||
|
||||
// 计算总制作时间(时间 = 基础时间 × 数量)
|
||||
float totalCraftingTime = recipe.CraftingTime * quantity;
|
||||
|
||||
var queueItem = new CraftingQueueItem
|
||||
{
|
||||
RecipeId = recipeId,
|
||||
Quantity = quantity,
|
||||
RemainingTime = totalCraftingTime,
|
||||
TotalTime = totalCraftingTime,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
craftingQueue.Add(queueItem);
|
||||
UpdateQueueDisplay();
|
||||
|
||||
GD.Print($"添加到合成队列: {recipeId} x{quantity},总时间: {totalCraftingTime}s,已扣除材料");
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateQueueDisplay()
|
||||
{
|
||||
// 清空所有槽位
|
||||
for (int i = 0; i < slotPanels.Count; i++)
|
||||
{
|
||||
ClearSlot(i);
|
||||
}
|
||||
|
||||
// 显示队列中的物品
|
||||
for (int i = 0; i < craftingQueue.Count && i < slotPanels.Count; i++)
|
||||
{
|
||||
var queueItem = craftingQueue[i];
|
||||
var recipe = CraftingRecipeManager.Instance?.GetRecipe(queueItem.RecipeId);
|
||||
if (recipe != null)
|
||||
{
|
||||
UpdateSlotDisplay(i, recipe, queueItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSlotDisplay(int slotIndex, CraftingRecipeManager.CraftingRecipe recipe, CraftingQueueItem queueItem)
|
||||
{
|
||||
var slot = slotPanels[slotIndex];
|
||||
|
||||
// 立即清除现有的子节点,而不是使用QueueFree
|
||||
var childrenToRemove = new List<Node>();
|
||||
foreach (Node child in slot.GetChildren())
|
||||
{
|
||||
childrenToRemove.Add(child);
|
||||
}
|
||||
foreach (Node child in childrenToRemove)
|
||||
{
|
||||
slot.RemoveChild(child);
|
||||
child.QueueFree();
|
||||
}
|
||||
|
||||
// 创建背景层(灰色)
|
||||
var backgroundRect = new ColorRect();
|
||||
backgroundRect.Name = "Background";
|
||||
backgroundRect.Color = new Color(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
backgroundRect.AnchorLeft = 0.0f;
|
||||
backgroundRect.AnchorTop = 0.0f;
|
||||
backgroundRect.AnchorRight = 1.0f;
|
||||
backgroundRect.AnchorBottom = 1.0f;
|
||||
slot.AddChild(backgroundRect);
|
||||
|
||||
// 创建图标显示层
|
||||
var iconTexture = new TextureRect();
|
||||
iconTexture.Name = "ProductIcon";
|
||||
iconTexture.ExpandMode = TextureRect.ExpandModeEnum.FitWidthProportional;
|
||||
iconTexture.StretchMode = TextureRect.StretchModeEnum.KeepAspectCentered;
|
||||
iconTexture.AnchorLeft = 0.1f;
|
||||
iconTexture.AnchorTop = 0.1f;
|
||||
iconTexture.AnchorRight = 0.9f;
|
||||
iconTexture.AnchorBottom = 0.9f;
|
||||
|
||||
// 获取产物的图标
|
||||
var outputItemData = GameData.Instance?.GetItem(recipe.OutputItem);
|
||||
if (outputItemData != null && !string.IsNullOrEmpty(outputItemData.IconPath))
|
||||
{
|
||||
// 尝试加载物品图标
|
||||
if (FileAccess.FileExists(outputItemData.IconPath))
|
||||
{
|
||||
var texture = GD.Load<Texture2D>(outputItemData.IconPath);
|
||||
if (texture != null)
|
||||
{
|
||||
iconTexture.Texture = texture;
|
||||
GD.Print($"槽位{slotIndex}加载产物图标: {outputItemData.IconPath}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认图标
|
||||
LoadDefaultIcon(iconTexture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认图标
|
||||
LoadDefaultIcon(iconTexture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 使用默认图标
|
||||
LoadDefaultIcon(iconTexture);
|
||||
}
|
||||
|
||||
slot.AddChild(iconTexture);
|
||||
|
||||
// 创建进度层(白色半透明,覆盖在图标上面)
|
||||
var progressRect = new ColorRect();
|
||||
progressRect.Name = "Progress";
|
||||
progressRect.AnchorLeft = 0.0f;
|
||||
progressRect.AnchorRight = 1.0f;
|
||||
progressRect.AnchorBottom = 1.0f;
|
||||
progressRect.Color = new Color(1.0f, 1.0f, 1.0f, 0.3f); // 白色,透明度0.3
|
||||
|
||||
// 根据是否激活设置初始进度
|
||||
if (queueItem.IsActive)
|
||||
{
|
||||
float progress = 1.0f - (queueItem.RemainingTime / queueItem.TotalTime);
|
||||
progressRect.AnchorTop = 1.0f - progress; // 从下往上填充
|
||||
GD.Print($"槽位{slotIndex}初始化进度条,进度: {progress:F2}");
|
||||
}
|
||||
else
|
||||
{
|
||||
progressRect.AnchorTop = 1.0f; // 等待状态,无进度显示
|
||||
}
|
||||
|
||||
slot.AddChild(progressRect);
|
||||
|
||||
// 添加数量标签(如果数量大于1)
|
||||
if (queueItem.Quantity > 1)
|
||||
{
|
||||
var quantityLabel = new Label();
|
||||
quantityLabel.Name = "QuantityLabel";
|
||||
quantityLabel.Text = queueItem.Quantity.ToString();
|
||||
quantityLabel.AnchorLeft = 0.6f;
|
||||
quantityLabel.AnchorTop = 0.6f;
|
||||
quantityLabel.AnchorRight = 1.0f;
|
||||
quantityLabel.AnchorBottom = 1.0f;
|
||||
quantityLabel.HorizontalAlignment = HorizontalAlignment.Center;
|
||||
quantityLabel.VerticalAlignment = VerticalAlignment.Center;
|
||||
quantityLabel.AddThemeStyleboxOverride("normal", new StyleBoxFlat());
|
||||
var styleBox = quantityLabel.GetThemeStylebox("normal") as StyleBoxFlat;
|
||||
if (styleBox != null)
|
||||
{
|
||||
styleBox.BgColor = new Color(0.2f, 0.2f, 0.2f, 0.8f); // 半透明黑色背景
|
||||
styleBox.CornerRadiusTopLeft = 3;
|
||||
styleBox.CornerRadiusTopRight = 3;
|
||||
styleBox.CornerRadiusBottomLeft = 3;
|
||||
styleBox.CornerRadiusBottomRight = 3;
|
||||
}
|
||||
quantityLabel.AddThemeColorOverride("font_color", new Color(1.0f, 1.0f, 1.0f, 1.0f)); // 白色文字
|
||||
quantityLabel.AddThemeFontSizeOverride("font_size", 8);
|
||||
|
||||
slot.AddChild(quantityLabel);
|
||||
}
|
||||
|
||||
// 重置槽位颜色为默认
|
||||
slot.Modulate = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
private void LoadDefaultIcon(TextureRect iconTexture)
|
||||
{
|
||||
var defaultIcon = GD.Load<Texture2D>("res://assets/textures/icon.svg");
|
||||
if (defaultIcon != null)
|
||||
{
|
||||
iconTexture.Texture = defaultIcon;
|
||||
GD.Print("使用默认图标 icon.svg");
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr("无法加载默认图标 icon.svg");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSlotProgress(int slotIndex, float progress)
|
||||
{
|
||||
if (slotIndex >= slotPanels.Count)
|
||||
{
|
||||
GD.PrintErr($"UpdateSlotProgress: 无效的槽位索引 {slotIndex}");
|
||||
return;
|
||||
}
|
||||
|
||||
var slot = slotPanels[slotIndex];
|
||||
if (slot == null || !IsInstanceValid(slot))
|
||||
{
|
||||
GD.PrintErr($"UpdateSlotProgress: 槽位{slotIndex}无效");
|
||||
return;
|
||||
}
|
||||
|
||||
// 安全获取Progress节点
|
||||
ColorRect progressRect = null;
|
||||
try
|
||||
{
|
||||
if (slot.HasNode("Progress"))
|
||||
{
|
||||
progressRect = slot.GetNode<ColorRect>("Progress");
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr($"UpdateSlotProgress: 槽位{slotIndex}没有Progress节点");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
GD.PrintErr($"UpdateSlotProgress: 获取Progress节点失败: {e.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
if (progressRect != null && IsInstanceValid(progressRect))
|
||||
{
|
||||
// 从下往上填充:progress为0时AnchorTop为1.0,progress为1时AnchorTop为0.0
|
||||
float anchorTop = 1.0f - progress;
|
||||
progressRect.AnchorTop = anchorTop;
|
||||
// GD.Print($"更新槽位{slotIndex}进度: {progress:F2}, AnchorTop: {anchorTop:F2}");
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr($"UpdateSlotProgress: 槽位{slotIndex}的Progress节点无效");
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearSlot(int slotIndex)
|
||||
{
|
||||
var slot = slotPanels[slotIndex];
|
||||
|
||||
// 立即清除子节点
|
||||
var childrenToRemove = new List<Node>();
|
||||
foreach (Node child in slot.GetChildren())
|
||||
{
|
||||
childrenToRemove.Add(child);
|
||||
}
|
||||
foreach (Node child in childrenToRemove)
|
||||
{
|
||||
slot.RemoveChild(child);
|
||||
child.QueueFree();
|
||||
}
|
||||
|
||||
// 为空槽位添加灰色背景
|
||||
var backgroundRect = new ColorRect();
|
||||
backgroundRect.Name = "Background";
|
||||
backgroundRect.Color = new Color(0.2f, 0.2f, 0.2f, 1.0f); // 更深的灰色表示空槽位
|
||||
backgroundRect.AnchorLeft = 0.0f;
|
||||
backgroundRect.AnchorTop = 0.0f;
|
||||
backgroundRect.AnchorRight = 1.0f;
|
||||
backgroundRect.AnchorBottom = 1.0f;
|
||||
slot.AddChild(backgroundRect);
|
||||
|
||||
// 重置槽位颜色
|
||||
slot.Modulate = new Color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
// 公共方法,供外部调用添加铁块制作
|
||||
public void StartIronIngotCrafting()
|
||||
{
|
||||
AddToQueue("iron_ingot_smelting");
|
||||
}
|
||||
}
|
||||
192
scripts/production/ManualCollectionPanel.cs
Normal file
192
scripts/production/ManualCollectionPanel.cs
Normal file
@ -0,0 +1,192 @@
|
||||
using Godot;
|
||||
|
||||
public partial class ManualCollectionPanel : Control
|
||||
{
|
||||
// 采集相关参数
|
||||
private const float COLLECTION_TIME = 1.0f; // 采集时间1秒
|
||||
|
||||
// 状态变量
|
||||
private bool isCollecting = false;
|
||||
private float collectionProgress = 0.0f;
|
||||
private string itemId;
|
||||
|
||||
// UI引用
|
||||
private ColorRect progressFill;
|
||||
private Color originalProgressColor;
|
||||
private Color collectingProgressColor = new Color(1.0f, 0.8f, 0.3f, 1.0f); // 采集时的橙色
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
GD.Print("ManualCollectionPanel _Ready 开始");
|
||||
|
||||
// 获取进度条引用 - 现在需要从父节点获取
|
||||
var parent = GetParent<Control>();
|
||||
if (parent != null)
|
||||
{
|
||||
progressFill = parent.GetNode<ColorRect>("MarginContainer/VBoxContainer/ProgressContainer/ProgressFill");
|
||||
if (progressFill != null)
|
||||
{
|
||||
originalProgressColor = progressFill.Color;
|
||||
GD.Print("成功获取进度条引用");
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr("无法获取进度条引用");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr("无法获取父节点");
|
||||
}
|
||||
|
||||
// 连接鼠标事件
|
||||
GuiInput += OnGuiInput;
|
||||
GD.Print("已连接鼠标事件");
|
||||
|
||||
GD.Print("ManualCollectionPanel _Ready 完成");
|
||||
}
|
||||
|
||||
// 设置物品ID
|
||||
public void SetItemId(string id)
|
||||
{
|
||||
itemId = id;
|
||||
GD.Print($"设置手动采集面板物品ID: {itemId}");
|
||||
}
|
||||
|
||||
// 处理输入事件
|
||||
private void OnGuiInput(InputEvent @event)
|
||||
{
|
||||
if (@event is InputEventMouseButton mouseEvent)
|
||||
{
|
||||
if (mouseEvent.ButtonIndex == MouseButton.Left)
|
||||
{
|
||||
//打印鼠标事件
|
||||
GD.Print($"鼠标事件: {mouseEvent}");
|
||||
|
||||
if (mouseEvent.Pressed)
|
||||
{
|
||||
// 开始采集
|
||||
StartCollection();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 停止采集
|
||||
StopCollection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 开始采集
|
||||
private void StartCollection()
|
||||
{
|
||||
if (string.IsNullOrEmpty(itemId)) return;
|
||||
|
||||
isCollecting = true;
|
||||
collectionProgress = 0.0f;
|
||||
|
||||
// 改变进度条颜色表示正在采集
|
||||
if (progressFill != null)
|
||||
{
|
||||
progressFill.Color = collectingProgressColor;
|
||||
}
|
||||
|
||||
GD.Print($"开始采集: {itemId}");
|
||||
}
|
||||
|
||||
// 停止采集
|
||||
private void StopCollection()
|
||||
{
|
||||
if (!isCollecting) return;
|
||||
|
||||
isCollecting = false;
|
||||
collectionProgress = 0.0f;
|
||||
|
||||
// 恢复进度条
|
||||
UpdateProgressBar();
|
||||
|
||||
// 恢复原始颜色
|
||||
if (progressFill != null)
|
||||
{
|
||||
progressFill.Color = originalProgressColor;
|
||||
}
|
||||
|
||||
GD.Print($"停止采集: {itemId}");
|
||||
}
|
||||
|
||||
// 完成采集
|
||||
private void CompleteCollection()
|
||||
{
|
||||
if (string.IsNullOrEmpty(itemId)) return;
|
||||
|
||||
// 添加物品到库存
|
||||
if (InventoryManager.Instance != null)
|
||||
{
|
||||
InventoryManager.Instance.AddItem(itemId, 1);
|
||||
GD.Print($"采集完成,获得: {itemId} x1");
|
||||
}
|
||||
|
||||
// 重置采集状态
|
||||
collectionProgress = 0.0f;
|
||||
|
||||
// 如果还在按住,继续下一轮采集
|
||||
if (isCollecting)
|
||||
{
|
||||
GD.Print($"继续采集: {itemId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 恢复进度条显示
|
||||
UpdateProgressBar();
|
||||
if (progressFill != null)
|
||||
{
|
||||
progressFill.Color = originalProgressColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新进度条显示
|
||||
private void UpdateProgressBar()
|
||||
{
|
||||
if (progressFill != null)
|
||||
{
|
||||
if (isCollecting)
|
||||
{
|
||||
// 采集中显示当前进度
|
||||
progressFill.AnchorRight = collectionProgress;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 非采集状态显示满进度(表示可采集)
|
||||
progressFill.AnchorRight = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (isCollecting)
|
||||
{
|
||||
// 更新采集进度
|
||||
collectionProgress += (float)delta / COLLECTION_TIME;
|
||||
|
||||
// 限制进度在0-1之间
|
||||
collectionProgress = Mathf.Clamp(collectionProgress, 0.0f, 1.0f);
|
||||
|
||||
// 更新进度条显示
|
||||
UpdateProgressBar();
|
||||
|
||||
// 检查是否完成采集
|
||||
if (collectionProgress >= 1.0f)
|
||||
{
|
||||
CompleteCollection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 清理
|
||||
public override void _ExitTree()
|
||||
{
|
||||
GuiInput -= OnGuiInput;
|
||||
}
|
||||
}
|
||||
33
scripts/production/ResourceGrid.cs
Normal file
33
scripts/production/ResourceGrid.cs
Normal file
@ -0,0 +1,33 @@
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public partial class ResourceGrid : GridContainer
|
||||
{
|
||||
[Export]
|
||||
public PackedScene ItemPanelScene;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// 获取基础资源分类的所有物品
|
||||
var items = ResourceCategoryManager.Instance.GetItemsByCategory("基础资源");
|
||||
|
||||
foreach (var item in items.Values)
|
||||
{
|
||||
var panel = (Panel)ItemPanelScene.Instantiate();
|
||||
|
||||
// 设置图标为白色底色
|
||||
var icon = panel.GetNode<TextureRect>("HBoxContainer/Icon");
|
||||
icon.Texture = null;
|
||||
icon.Modulate = new Color(1, 1, 1, 1); // 白色
|
||||
|
||||
// 设置名称
|
||||
var nameLabel = panel.GetNode<Label>("HBoxContainer/VBoxContainer/TopRow/NameLabel");
|
||||
nameLabel.Text = item.Name;
|
||||
|
||||
// 其余内容可根据需要设置
|
||||
// ...
|
||||
|
||||
AddChild(panel);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user