This commit is contained in:
2025-12-25 17:42:02 +08:00
parent fcd98c9bfc
commit efee26e83c
3 changed files with 64 additions and 91 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,5 @@
// File: Gizmo_NeutronFlux.cs
// 向滑动条样式的孵化活性调节 Gizmo(带刻度)
// 向滑动条样式的孵化活性调节 Gizmo
// 支持实现 IFluxController 接口的所有建筑
using UnityEngine;
using Verse;
@@ -10,22 +10,19 @@ namespace ArachnaeSwarm
public class Gizmo_NeutronFlux : Gizmo
{
private readonly IFluxController controller;
private readonly Thing parentThing; // 用于获取 Thing 属性
private readonly Thing parentThing;
// 尺寸常量
private const float Width = 100f;
private const float GizmoHeight = 140f;
private const float Width = 200f;
private const float GizmoHeight = 78f;
private const float Padding = 6f;
private const float BarHeight = 28f;
// 材质
private static readonly Texture2D FluxBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.9f, 0.5f, 0.1f, 0.9f));
private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.15f, 0.15f, 0.15f, 0.8f));
private static readonly Texture2D AutoOnTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.7f, 0.2f, 0.9f));
private static readonly Texture2D AutoOffTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.5f, 0.3f, 0.3f, 0.7f));
private static readonly Texture2D TickMarkTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.4f, 0.4f, 0.4f, 0.8f));
private static readonly Texture2D CursorTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.9f, 0.9f, 0.9f, 1f));
// 构造函数接受接口
public Gizmo_NeutronFlux(IFluxController controller)
{
this.controller = controller;
@@ -33,40 +30,33 @@ namespace ArachnaeSwarm
Order = -150f;
}
public override float GetWidth(float maxWidth)
{
return Mathf.Min(Width, maxWidth);
}
public override float GetWidth(float maxWidth) => Mathf.Min(Width, maxWidth);
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
{
// 主矩形区域(向上偏移使其更高)
Rect rect = new Rect(topLeft.x, topLeft.y - 65f, GetWidth(maxWidth), GizmoHeight);
Rect rect = new Rect(topLeft.x, topLeft.y - (GizmoHeight - 75f), GetWidth(maxWidth), GizmoHeight);
Widgets.DrawWindowBackground(rect);
Rect innerRect = rect.ContractedBy(Padding);
float curY = innerRect.y;
// === 标题行 ===
Text.Font = GameFont.Small;
Text.Anchor = TextAnchor.MiddleLeft;
Rect titleRect = new Rect(innerRect.x, innerRect.y, innerRect.width - 24f, 18f);
float buttonSize = 18f;
Rect titleRect = new Rect(innerRect.x, curY, innerRect.width - buttonSize - 4f, Text.LineHeight);
Widgets.Label(titleRect, "ARA_Gizmo_NeutronFlux_Title".Translate());
// === 右上角模式切换按钮 ===
float buttonSize = 20f;
Rect modeRect = new Rect(innerRect.xMax - buttonSize, innerRect.y, buttonSize, buttonSize);
// 根据模式显示不同颜色
Color modeColor;
switch (controller.CurrentFluxMode)
// 模式按钮 [B]
Rect modeRect = new Rect(innerRect.xMax - buttonSize, curY + 1f, buttonSize, buttonSize);
Color modeColor = controller.CurrentFluxMode switch
{
case FluxMode.Manual: modeColor = new Color(0.5f, 0.5f, 0.5f, 0.9f); break;
case FluxMode.Quality: modeColor = new Color(0.3f, 0.6f, 0.9f, 0.9f); break;
case FluxMode.Balance: modeColor = new Color(0.9f, 0.5f, 0.2f, 0.9f); break;
case FluxMode.Speed: modeColor = new Color(0.2f, 0.7f, 0.2f, 0.9f); break;
default: modeColor = Color.gray; break;
}
FluxMode.Manual => new Color(0.5f, 0.5f, 0.5f, 0.9f),
FluxMode.Quality => new Color(0.3f, 0.6f, 0.9f, 0.9f),
FluxMode.Balance => new Color(0.9f, 0.5f, 0.2f, 0.9f),
FluxMode.Speed => new Color(0.2f, 0.7f, 0.2f, 0.9f),
_ => Color.gray
};
GUI.DrawTexture(modeRect, SolidColorMaterials.NewSolidColorTexture(modeColor));
Widgets.DrawBox(modeRect, 1);
@@ -80,41 +70,65 @@ namespace ArachnaeSwarm
controller.CycleFluxMode();
}
// === 竖向计量条 ===
float barWidth = 32f;
float barHeight = 90f;
float barX = innerRect.x + 8f;
float barY = innerRect.y + 24f;
Rect barRect = new Rect(barX, barY, barWidth, barHeight);
curY += Text.LineHeight + 2f;
// === 信息行50% 速度 1.0x 品质 1.0x ===
Text.Font = GameFont.Tiny;
Text.Anchor = TextAnchor.MiddleLeft;
float infoY = curY;
float segment = innerRect.width / 3f;
// 百分比
GUI.color = controller.IsDormant ? Color.red : Color.white;
Rect percentRect = new Rect(innerRect.x, infoY, segment, 14f);
Widgets.Label(percentRect, (controller.NeutronFlux * 100f).ToString("0") + "%");
// 速度
float speedMult = controller.FluxEfficiency;
GUI.color = speedMult >= 1f ? new Color(0.5f, 1f, 0.5f) : new Color(1f, 0.7f, 0.5f);
Rect speedRect = new Rect(innerRect.x + segment, infoY, segment, 14f);
Widgets.Label(speedRect, "ARA_Status_Speed".Translate() + " " + speedMult.ToString("0.0") + "x");
// 品质
float qualCoeff = IncubatorUtils.GetQualityCoefficient(controller.NeutronFlux);
GUI.color = qualCoeff >= 1f ? new Color(0.5f, 0.7f, 1f) : new Color(1f, 0.7f, 0.5f);
Rect qualRect = new Rect(innerRect.x + segment * 2f, infoY, segment, 14f);
Widgets.Label(qualRect, "ARA_Status_Quality".Translate() + " " + qualCoeff.ToString("0.0") + "x");
GUI.color = Color.white;
curY += 16f;
// === 横向滑条 ===
Rect barRect = new Rect(innerRect.x, curY, innerRect.width, BarHeight);
// 非孵化时显示灰色锁定状态
bool isLocked = !controller.IsIncubating;
// 绘制背景
// 背景
GUI.color = isLocked ? new Color(0.3f, 0.3f, 0.3f, 0.5f) : Color.white;
GUI.DrawTexture(barRect, EmptyBarTex);
// 绘制填充(从底部向上)- 使用 RawFlux 显示预设值
// 填充(从左到右)
float displayFlux = controller.RawFlux;
float fillHeight = barRect.height * displayFlux;
Rect fillRect = new Rect(barRect.x, barRect.yMax - fillHeight, barRect.width, fillHeight);
float fillWidth = barRect.width * displayFlux;
Rect fillRect = new Rect(barRect.x, barRect.y, fillWidth, barRect.height);
GUI.color = isLocked ? new Color(0.5f, 0.35f, 0.1f, 0.5f) : Color.white;
GUI.DrawTexture(fillRect, FluxBarTex);
GUI.color = Color.white;
// 绘制刻度线10格
// 刻度线10格
for (int i = 1; i < 10; i++)
{
float tickY = barRect.y + barRect.height * (1f - i / 10f);
float tickWidth = (i == 5) ? barRect.width * 0.6f : barRect.width * 0.3f;
Rect tickRect = new Rect(barRect.x, tickY - 0.5f, tickWidth, 1f);
float tickX = barRect.x + barRect.width * (i / 10f);
float tickHeight = (i == 5) ? barRect.height * 0.6f : barRect.height * 0.3f;
Rect tickRect = new Rect(tickX - 0.5f, barRect.y, 1f, tickHeight);
GUI.DrawTexture(tickRect, TickMarkTex);
}
// 绘制边框
// 边框
Widgets.DrawBox(barRect, 1);
// === 直接在计量条上点击/拖动 ===
// === 拖动交互 ===
int controlId = GUIUtility.GetControlID(FocusType.Passive);
Event evt = Event.current;
@@ -124,7 +138,7 @@ namespace ArachnaeSwarm
if (barRect.Contains(evt.mousePosition) && evt.button == 0)
{
GUIUtility.hotControl = controlId;
UpdateFluxFromMouse(barRect, evt.mousePosition.y);
UpdateFluxFromMouse(barRect, evt.mousePosition.x);
evt.Use();
}
break;
@@ -132,7 +146,7 @@ namespace ArachnaeSwarm
case EventType.MouseDrag:
if (GUIUtility.hotControl == controlId)
{
UpdateFluxFromMouse(barRect, evt.mousePosition.y);
UpdateFluxFromMouse(barRect, evt.mousePosition.x);
evt.Use();
}
break;
@@ -146,39 +160,6 @@ namespace ArachnaeSwarm
break;
}
// === 右侧信息显示 ===
float infoX = barRect.xMax + 6f;
float infoWidth = innerRect.xMax - infoX;
Text.Font = GameFont.Small;
Text.Anchor = TextAnchor.MiddleLeft;
// 百分比(大字)
GUI.color = controller.IsDormant ? Color.red : Color.white;
Rect percentRect = new Rect(infoX, barRect.y, infoWidth, 20f);
Widgets.Label(percentRect, (controller.NeutronFlux * 100f).ToString("0") + "%");
Text.Font = GameFont.Tiny;
// 速度倍率
GUI.color = new Color(0.7f, 0.7f, 0.7f);
Rect speedLabelRect = new Rect(infoX, barRect.y + 22f, infoWidth, 14f);
Widgets.Label(speedLabelRect, "ARA_Status_Speed".Translate());
float speedMultiplier = controller.FluxEfficiency;
Rect speedValRect = new Rect(infoX, barRect.y + 36f, infoWidth, 14f);
GUI.color = speedMultiplier >= 1f ? new Color(0.5f, 1f, 0.5f) : new Color(1f, 0.7f, 0.5f);
Widgets.Label(speedValRect, speedMultiplier.ToString("0.0") + "x");
// 品质倍率
GUI.color = new Color(0.7f, 0.7f, 0.7f);
float qualityCoeff = IncubatorUtils.GetQualityCoefficient(controller.NeutronFlux);
Rect qualLabelRect = new Rect(infoX, barRect.y + 54f, infoWidth, 14f);
Widgets.Label(qualLabelRect, "ARA_Status_Quality".Translate());
Rect qualValRect = new Rect(infoX, barRect.y + 68f, infoWidth, 14f);
GUI.color = qualityCoeff >= 1f ? new Color(0.5f, 0.7f, 1f) : new Color(1f, 0.7f, 0.5f);
Widgets.Label(qualValRect, qualityCoeff.ToString("0.0") + "x");
GUI.color = Color.white;
Text.Anchor = TextAnchor.UpperLeft;
Text.Font = GameFont.Small;
@@ -192,9 +173,9 @@ namespace ArachnaeSwarm
return new GizmoResult(GizmoState.Clear);
}
private void UpdateFluxFromMouse(Rect barRect, float mouseY)
private void UpdateFluxFromMouse(Rect barRect, float mouseX)
{
float percent = 1f - (mouseY - barRect.y) / barRect.height;
float percent = (mouseX - barRect.x) / barRect.width;
controller.SetNeutronFlux(Mathf.Clamp01(percent));
}
@@ -204,17 +185,11 @@ namespace ArachnaeSwarm
sb.AppendLine("ARA_Gizmo_NeutronFlux_TooltipTitle".Translate());
sb.AppendLine();
// 核心机制
sb.AppendLine("ARA_Gizmo_NeutronFlux_CoreMechanic".Translate());
sb.AppendLine();
// 当前状态
sb.AppendLine("ARA_Status_CurrentFlux".Translate(controller.RawFlux.ToStringPercent("0")));
sb.AppendLine("ARA_Status_IncubationSpeed".Translate((controller.FluxEfficiency * 5f).ToString("0.0")));
sb.AppendLine();
// 模式说明
sb.AppendLine("ARA_Status_Mode".Translate(controller.GetModeName()));
string modeDescKey = controller.CurrentFluxMode switch
@@ -230,8 +205,6 @@ namespace ArachnaeSwarm
sb.AppendLine(" " + modeDescKey.Translate());
}
sb.AppendLine();
// 操作
sb.AppendLine("ARA_Gizmo_NeutronFlux_Operations".Translate());
if (controller.IsDormant)