This commit is contained in:
2025-12-23 17:31:42 +08:00
parent eab0afb1a0
commit 1264f6009e
7 changed files with 137 additions and 62 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<LanguageData>
<!-- 通量模式 -->
<ARA_FluxMode_Manual>手动</ARA_FluxMode_Manual>
<ARA_FluxMode_Quality>品质</ARA_FluxMode_Quality>
<ARA_FluxMode_Balance>平衡</ARA_FluxMode_Balance>
<ARA_FluxMode_Speed>速度</ARA_FluxMode_Speed>
<!-- 消息 -->
<ARA_Msg_QueueFull>队列已满!</ARA_Msg_QueueFull>
<ARA_Msg_LarvaWorking>已有幼虫正在工作中,请等待完成</ARA_Msg_LarvaWorking>
<ARA_Msg_NoOrderToActivate>没有需要激活的订单</ARA_Msg_NoOrderToActivate>
<ARA_Msg_NoLarvaFound>未找到可用的幼虫!</ARA_Msg_NoLarvaFound>
<ARA_Msg_LarvaCalled>已呼叫幼虫</ARA_Msg_LarvaCalled>
<ARA_Msg_LarvaCannotAccept>幼虫无法接受任务</ARA_Msg_LarvaCannotAccept>
<ARA_Msg_NoIncubationOptions>没有可用的孵化选项(检查 CompIncubatorData 配置)</ARA_Msg_NoIncubationOptions>
<ARA_Msg_NoProducibleItems>没有可生产的物品(检查建筑是否正确配置)</ARA_Msg_NoProducibleItems>
<!-- 品质等级 -->
<ARA_Quality_Legendary>传奇</ARA_Quality_Legendary>
<ARA_Quality_Masterwork>杰作</ARA_Quality_Masterwork>
<ARA_Quality_Excellent>优秀</ARA_Quality_Excellent>
<ARA_Quality_Good>良好</ARA_Quality_Good>
<ARA_Quality_Normal>普通</ARA_Quality_Normal>
<ARA_Quality_Poor>较差</ARA_Quality_Poor>
<!-- 状态文本 -->
<ARA_Status_Waiting>等待中</ARA_Status_Waiting>
<ARA_Status_WaitingForLarva>等待幼虫</ARA_Status_WaitingForLarva>
<!-- 检查面板 -->
<ARA_Inspect_Orders>订单: {0} / {1}</ARA_Inspect_Orders>
<ARA_Inspect_WaitingAndIncubating>等待幼虫: {0} 正在孵化: {1}</ARA_Inspect_WaitingAndIncubating>
<ARA_Inspect_WaitingAndProducing>等待幼虫: {0} 正在生产: {1}</ARA_Inspect_WaitingAndProducing>
<!-- Gizmo 按钮 -->
<ARA_Gizmo_AddOrder>添加订单 ({0}/{1})</ARA_Gizmo_AddOrder>
<ARA_Gizmo_AddOrderDesc_Pawn>选择要孵化的单位类型(可多次点击)</ARA_Gizmo_AddOrderDesc_Pawn>
<ARA_Gizmo_AddOrderDesc_Item>选择要生产的物品(可多次点击)</ARA_Gizmo_AddOrderDesc_Item>
<ARA_Gizmo_CallLarva>呼叫幼虫</ARA_Gizmo_CallLarva>
<ARA_Gizmo_CallLarvaDesc>呼叫一只幼虫来激活下一个订单(还有{0}个等待中)</ARA_Gizmo_CallLarvaDesc>
<ARA_Gizmo_LarvaWorking>幼虫工作中</ARA_Gizmo_LarvaWorking>
<ARA_Gizmo_LarvaWorkingDesc>一只幼虫正在操作孵化器(还有{0}个订单等待)</ARA_Gizmo_LarvaWorkingDesc>
<!-- 菜单 -->
<ARA_Menu_SelectIncubationTarget>选择孵化目标</ARA_Menu_SelectIncubationTarget>
<ARA_Menu_SelectProductionTarget>选择生产目标</ARA_Menu_SelectProductionTarget>
<ARA_Menu_RequiresResearch>需要研究: {0}</ARA_Menu_RequiresResearch>
<ARA_Menu_Days>{0}天</ARA_Menu_Days>
<!-- Gizmo 进度条 -->
<ARA_Gizmo_SelectIncubationTarget>选择孵化目标...</ARA_Gizmo_SelectIncubationTarget>
<ARA_Gizmo_SelectProductionTarget>选择生产目标...</ARA_Gizmo_SelectProductionTarget>
<ARA_Gizmo_QueueFull>(满)</ARA_Gizmo_QueueFull>
<ARA_Gizmo_ReadyClickAbove>就绪 - 点击上方选择目标</ARA_Gizmo_ReadyClickAbove>
<ARA_Gizmo_WaitingForLarvaActivation>等待幼虫激活</ARA_Gizmo_WaitingForLarvaActivation>
<!-- Tooltip -->
<ARA_Tooltip_NotSelected>【未选择目标】</ARA_Tooltip_NotSelected>
<ARA_Tooltip_ClickToSelectIncubation>点击上方标题选择孵化目标</ARA_Tooltip_ClickToSelectIncubation>
<ARA_Tooltip_ClickToSelectProduction>点击上方标题选择生产目标</ARA_Tooltip_ClickToSelectProduction>
<ARA_Tooltip_Ready>【就绪】</ARA_Tooltip_Ready>
<ARA_Tooltip_Target>目标: </ARA_Tooltip_Target>
<ARA_Tooltip_IncubationTime>孵化时间: {0} 天</ARA_Tooltip_IncubationTime>
<!-- 营养分配器 -->
<ARA_NutrientDispenser_MealsAvailable>可制作: {0} 份</ARA_NutrientDispenser_MealsAvailable>
</LanguageData>

View File

@@ -67,6 +67,9 @@ namespace ArachnaeSwarm
// === 幼虫管理 ===
private List<Pawn> assignedLarvae = new List<Pawn>();
// === UI 状态(供 Gizmo 使用,不保存) ===
public float GizmoScrollPosition = 0f;
// === 组件引用 ===
private CompRefuelableNutrition _fuelComp;
private CompAffectedByFacilities _facilitiesComp;
@@ -98,10 +101,10 @@ namespace ArachnaeSwarm
public void CycleFluxMode() => fluxMode = (FluxMode)(((int)fluxMode + 1) % 4);
public string GetModeName() => fluxMode switch {
FluxMode.Manual => "手动",
FluxMode.Quality => "品质",
FluxMode.Balance => "平衡",
FluxMode.Speed => "速度",
FluxMode.Manual => "ARA_FluxMode_Manual".Translate(),
FluxMode.Quality => "ARA_FluxMode_Quality".Translate(),
FluxMode.Balance => "ARA_FluxMode_Balance".Translate(),
FluxMode.Speed => "ARA_FluxMode_Speed".Translate(),
_ => "?"
};
@@ -135,7 +138,7 @@ namespace ArachnaeSwarm
{
if (orders.Count >= Props.productionQueueLimit)
{
Messages.Message("队列已满!", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_QueueFull".Translate(), MessageTypeDefOf.RejectInput);
return;
}
orders.Add(new QueuedItemOrder { process = process, status = OrderStatus.WaitingForLarva });
@@ -187,13 +190,13 @@ namespace ArachnaeSwarm
{
if (assignedLarvae.Count > 0)
{
Messages.Message("已有幼虫正在工作中,请等待完成", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_LarvaWorking".Translate(), MessageTypeDefOf.RejectInput);
return;
}
if (WaitingForLarvaCount <= 0)
{
Messages.Message("没有需要激活的订单", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoOrderToActivate".Translate(), MessageTypeDefOf.RejectInput);
return;
}
@@ -206,7 +209,7 @@ namespace ArachnaeSwarm
if (larva == null)
{
if (showMessage)
Messages.Message("未找到可用的幼虫!", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoLarvaFound".Translate(), MessageTypeDefOf.RejectInput);
return false;
}
@@ -215,13 +218,13 @@ namespace ArachnaeSwarm
{
assignedLarvae.Add(larva);
if (showMessage)
Messages.Message("已呼叫幼虫", MessageTypeDefOf.PositiveEvent);
Messages.Message("ARA_Msg_LarvaCalled".Translate(), MessageTypeDefOf.PositiveEvent);
return true;
}
else
{
if (showMessage)
Messages.Message("幼虫无法接受任务", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_LarvaCannotAccept".Translate(), MessageTypeDefOf.RejectInput);
return false;
}
}
@@ -391,8 +394,8 @@ namespace ArachnaeSwarm
public override string CompInspectStringExtra()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"订单: {orders.Count} / {Props.productionQueueLimit}");
sb.AppendLine($"等待幼虫: {WaitingForLarvaCount} 正在生产: {IncubatingCount}");
sb.AppendLine("ARA_Inspect_Orders".Translate(orders.Count, Props.productionQueueLimit));
sb.AppendLine("ARA_Inspect_WaitingAndProducing".Translate(WaitingForLarvaCount, IncubatingCount));
return sb.ToString().TrimEnd();
}
@@ -408,8 +411,8 @@ namespace ArachnaeSwarm
{
yield return new Command_Action
{
defaultLabel = $"添加订单 ({orders.Count}/{Props.productionQueueLimit})",
defaultDesc = "选择要生产的物品(可多次点击)",
defaultLabel = "ARA_Gizmo_AddOrder".Translate(orders.Count, Props.productionQueueLimit),
defaultDesc = "ARA_Gizmo_AddOrderDesc_Item".Translate(),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_NodeSwarmIcon", false),
action = ShowOrderMenu
};
@@ -420,8 +423,8 @@ namespace ArachnaeSwarm
{
yield return new Command_Action
{
defaultLabel = "呼叫幼虫",
defaultDesc = $"呼叫一只幼虫来激活下一个订单(还有{WaitingForLarvaCount}个等待中)",
defaultLabel = "ARA_Gizmo_CallLarva".Translate(),
defaultDesc = "ARA_Gizmo_CallLarvaDesc".Translate(WaitingForLarvaCount),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
action = CallLarvae
};
@@ -430,8 +433,8 @@ namespace ArachnaeSwarm
{
yield return new Command_Action
{
defaultLabel = "幼虫工作中",
defaultDesc = $"一只幼虫正在操作孵化器(还有{WaitingForLarvaCount}个订单等待)",
defaultLabel = "ARA_Gizmo_LarvaWorking".Translate(),
defaultDesc = "ARA_Gizmo_LarvaWorkingDesc".Translate(WaitingForLarvaCount),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
Disabled = true
};
@@ -450,14 +453,14 @@ namespace ArachnaeSwarm
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
{
label += $" (需要研究: {process.requiredResearch.LabelCap})";
label += " (" + "ARA_Menu_RequiresResearch".Translate(process.requiredResearch.LabelCap) + ")";
options.Add(new FloatMenuOption(label, null, icon, Color.white));
}
else
{
var capturedProcess = process;
float days = capturedProcess.productionTicks / 60000f;
label += $" ({days:F1}天)";
label += " (" + "ARA_Menu_Days".Translate(days.ToString("F1")) + ")";
options.Add(new FloatMenuOption(label, () => {
AddOrder(capturedProcess);
if (orders.Count < Props.productionQueueLimit) ShowOrderMenu();
@@ -466,9 +469,9 @@ namespace ArachnaeSwarm
}
if (options.Count > 0)
Find.WindowStack.Add(new FloatMenu(options, "选择生产目标"));
Find.WindowStack.Add(new FloatMenu(options, "ARA_Menu_SelectProductionTarget".Translate()));
else
Messages.Message("没有可生产的物品(检查建筑是否正确配置)", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoProducibleItems".Translate(), MessageTypeDefOf.RejectInput);
}
private void BuildProcessList()

View File

@@ -80,6 +80,10 @@ namespace ArachnaeSwarm
// === 幼虫管理 ===
private List<Pawn> assignedLarvae = new List<Pawn>();
// === UI 状态(供 Gizmo 使用,不保存) ===
public float GizmoScrollPosition = 0f;
public string LarvaStatusText = null; // 幼虫状态文本
// === 组件引用 ===
private CompRefuelableNutrition _fuelComp;
private CompAffectedByFacilities _facilitiesComp;
@@ -106,10 +110,10 @@ namespace ArachnaeSwarm
public void CycleFluxMode() => fluxMode = (FluxMode)(((int)fluxMode + 1) % 4);
public string GetModeName() => fluxMode switch {
FluxMode.Manual => "手动",
FluxMode.Quality => "品质",
FluxMode.Balance => "平衡",
FluxMode.Speed => "速度",
FluxMode.Manual => "ARA_FluxMode_Manual".Translate(),
FluxMode.Quality => "ARA_FluxMode_Quality".Translate(),
FluxMode.Balance => "ARA_FluxMode_Balance".Translate(),
FluxMode.Speed => "ARA_FluxMode_Speed".Translate(),
_ => "?"
};
@@ -134,7 +138,7 @@ namespace ArachnaeSwarm
{
if (orders.Count >= Props.productionQueueLimit)
{
Messages.Message("队列已满!", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_QueueFull".Translate(), MessageTypeDefOf.RejectInput);
return;
}
orders.Add(new QueuedPawnOrder { config = config, status = OrderStatus.WaitingForLarva });
@@ -161,7 +165,7 @@ namespace ArachnaeSwarm
qualityProgress = order.QualityPercent,
remainingTime = order.status == OrderStatus.Incubating
? ((int)GetRemainingTicks(order)).ToStringTicksToPeriod()
: "等待中",
: "ARA_Status_Waiting".Translate(),
estimatedQuality = GetEstimatedQuality(order.QualityPercent)
});
}
@@ -185,12 +189,12 @@ namespace ArachnaeSwarm
private string GetEstimatedQuality(float qualityPercent)
{
if (qualityPercent >= 0.99f) return "传奇";
if (qualityPercent >= 0.90f) return "杰作";
if (qualityPercent >= 0.70f) return "优秀";
if (qualityPercent >= 0.50f) return "良好";
if (qualityPercent >= 0.20f) return "普通";
return "较差";
if (qualityPercent >= 0.99f) return "ARA_Quality_Legendary".Translate();
if (qualityPercent >= 0.90f) return "ARA_Quality_Masterwork".Translate();
if (qualityPercent >= 0.70f) return "ARA_Quality_Excellent".Translate();
if (qualityPercent >= 0.50f) return "ARA_Quality_Good".Translate();
if (qualityPercent >= 0.20f) return "ARA_Quality_Normal".Translate();
return "ARA_Quality_Poor".Translate();
}
// === 幼虫激活逻辑 ===
@@ -200,13 +204,13 @@ namespace ArachnaeSwarm
// 检查是否已有幼虫在工作/路上
if (assignedLarvae.Count > 0)
{
Messages.Message("已有幼虫正在工作中,请等待完成", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_LarvaWorking".Translate(), MessageTypeDefOf.RejectInput);
return;
}
if (WaitingForLarvaCount <= 0)
{
Messages.Message("没有需要激活的订单", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoOrderToActivate".Translate(), MessageTypeDefOf.RejectInput);
return;
}
@@ -221,7 +225,7 @@ namespace ArachnaeSwarm
if (larva == null)
{
if (showMessage)
Messages.Message("未找到可用的幼虫!", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoLarvaFound".Translate(), MessageTypeDefOf.RejectInput);
return false;
}
@@ -230,13 +234,13 @@ namespace ArachnaeSwarm
{
assignedLarvae.Add(larva);
if (showMessage)
Messages.Message("已呼叫幼虫", MessageTypeDefOf.PositiveEvent);
Messages.Message("ARA_Msg_LarvaCalled".Translate(), MessageTypeDefOf.PositiveEvent);
return true;
}
else
{
if (showMessage)
Messages.Message("幼虫无法接受任务", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_LarvaCannotAccept".Translate(), MessageTypeDefOf.RejectInput);
return false;
}
}
@@ -409,8 +413,8 @@ namespace ArachnaeSwarm
public override string CompInspectStringExtra()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine($"订单: {orders.Count} / {Props.productionQueueLimit}");
sb.AppendLine($"等待幼虫: {WaitingForLarvaCount} 正在孵化: {IncubatingCount}");
sb.AppendLine("ARA_Inspect_Orders".Translate(orders.Count, Props.productionQueueLimit));
sb.AppendLine("ARA_Inspect_WaitingAndIncubating".Translate(WaitingForLarvaCount, IncubatingCount));
return sb.ToString().TrimEnd();
}
@@ -426,8 +430,8 @@ namespace ArachnaeSwarm
{
yield return new Command_Action
{
defaultLabel = $"添加订单 ({orders.Count}/{Props.productionQueueLimit})",
defaultDesc = "选择要孵化的单位类型(可多次点击)",
defaultLabel = "ARA_Gizmo_AddOrder".Translate(orders.Count, Props.productionQueueLimit),
defaultDesc = "ARA_Gizmo_AddOrderDesc_Pawn".Translate(),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_NodeSwarmIcon", false),
action = ShowOrderMenu
};
@@ -438,8 +442,8 @@ namespace ArachnaeSwarm
{
yield return new Command_Action
{
defaultLabel = $"呼叫幼虫",
defaultDesc = $"呼叫一只幼虫来激活下一个订单(还有{WaitingForLarvaCount}个等待中)",
defaultLabel = "ARA_Gizmo_CallLarva".Translate(),
defaultDesc = "ARA_Gizmo_CallLarvaDesc".Translate(WaitingForLarvaCount),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
action = CallLarvae
};
@@ -449,8 +453,8 @@ namespace ArachnaeSwarm
// 显示幼虫正在工作的状态
yield return new Command_Action
{
defaultLabel = "幼虫工作中",
defaultDesc = $"一只幼虫正在操作孵化器(还有{WaitingForLarvaCount}个订单等待)",
defaultLabel = "ARA_Gizmo_LarvaWorking".Translate(),
defaultDesc = "ARA_Gizmo_LarvaWorkingDesc".Translate(WaitingForLarvaCount),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
Disabled = true
};
@@ -471,7 +475,7 @@ namespace ArachnaeSwarm
if (config.requiredResearch != null && !config.requiredResearch.IsFinished)
{
options.Add(new FloatMenuOption(
config.pawnKind.LabelCap + " (需要研究: " + config.requiredResearch.LabelCap + ")",
config.pawnKind.LabelCap + " (" + "ARA_Menu_RequiresResearch".Translate(config.requiredResearch.LabelCap) + ")",
null
));
}
@@ -490,9 +494,9 @@ namespace ArachnaeSwarm
}
if (options.Count > 0)
Find.WindowStack.Add(new FloatMenu(options, "选择孵化目标"));
Find.WindowStack.Add(new FloatMenu(options, "ARA_Menu_SelectIncubationTarget".Translate()));
else
Messages.Message("没有可用的孵化选项(检查 CompIncubatorData 配置)", MessageTypeDefOf.RejectInput);
Messages.Message("ARA_Msg_NoIncubationOptions".Translate(), MessageTypeDefOf.RejectInput);
}
public override void PostExposeData()

View File

@@ -23,7 +23,7 @@ namespace ArachnaeSwarm
private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.5f));
private readonly CompQueuedInteractiveProducerWithFlux comp;
private float scrollPosition = 0f;
// scrollPosition 现在存储在 comp 中以在刷新间保持
public Gizmo_DualProgressBar(CompQueuedInteractiveProducerWithFlux comp)
{
@@ -107,17 +107,17 @@ namespace ArachnaeSwarm
{
Rect scrollbarRect = new Rect(innerRect.xMax - scrollbarWidth, curY, scrollbarWidth, listHeight);
float scrollMax = totalContentHeight - listHeight;
scrollPosition = GUI.VerticalScrollbar(scrollbarRect, scrollPosition, listHeight, 0f, totalContentHeight);
comp.GizmoScrollPosition = GUI.VerticalScrollbar(scrollbarRect, comp.GizmoScrollPosition, listHeight, 0f, totalContentHeight);
if (Mouse.IsOver(listRect))
{
scrollPosition -= Event.current.delta.y * 1.5f;
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
comp.GizmoScrollPosition -= Event.current.delta.y * 1.5f;
comp.GizmoScrollPosition = Mathf.Clamp(comp.GizmoScrollPosition, 0f, scrollMax);
}
}
GUI.BeginClip(listRect);
float drawY = -scrollPosition;
float drawY = -comp.GizmoScrollPosition;
for (int i = 0; i < orderCount; i++)
{

View File

@@ -23,7 +23,7 @@ namespace ArachnaeSwarm
private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.1f, 0.1f, 0.1f, 0.5f));
private readonly CompQueuedPawnSpawnerWithFlux comp;
private float scrollPosition = 0f;
// scrollPosition 现在存储在 comp 中以在刷新间保持
public Gizmo_PawnProgressBar(CompQueuedPawnSpawnerWithFlux comp)
{
@@ -65,7 +65,7 @@ namespace ArachnaeSwarm
}
else
{
title = "选择孵化目标...";
title = "ARA_Gizmo_SelectIncubationTarget".Translate();
}
// 标题按钮
@@ -89,7 +89,7 @@ namespace ArachnaeSwarm
else
{
GUI.color = new Color(0.5f, 0.5f, 0.5f);
Widgets.Label(titleRect, title.Truncate(titleRect.width) + " (满)");
Widgets.Label(titleRect, title.Truncate(titleRect.width) + " " + "ARA_Gizmo_QueueFull".Translate());
GUI.color = Color.white;
}
curY += Text.LineHeight + Spacing;
@@ -111,18 +111,18 @@ namespace ArachnaeSwarm
{
Rect scrollbarRect = new Rect(innerRect.xMax - scrollbarWidth, curY, scrollbarWidth, listHeight);
float scrollMax = totalContentHeight - listHeight;
scrollPosition = GUI.VerticalScrollbar(scrollbarRect, scrollPosition, listHeight, 0f, totalContentHeight);
comp.GizmoScrollPosition = GUI.VerticalScrollbar(scrollbarRect, comp.GizmoScrollPosition, listHeight, 0f, totalContentHeight);
// 也支持滚轮
if (Mouse.IsOver(listRect))
{
scrollPosition -= Event.current.delta.y * 1.5f;
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
comp.GizmoScrollPosition -= Event.current.delta.y * 1.5f;
comp.GizmoScrollPosition = Mathf.Clamp(comp.GizmoScrollPosition, 0f, scrollMax);
}
}
GUI.BeginClip(listRect);
float drawY = -scrollPosition;
float drawY = -comp.GizmoScrollPosition;
for (int i = 0; i < orderCount; i++)
{