275 lines
11 KiB
C#
275 lines
11 KiB
C#
using RimWorld;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
using Verse;
|
|
|
|
namespace ArachnaeSwarm
|
|
{
|
|
[StaticConstructorOnStartup]
|
|
public class Gizmo_PawnResearchProgress : Gizmo
|
|
{
|
|
private readonly Comp_PawnResearchBlueprintReader researchComp;
|
|
|
|
// 尺寸常量
|
|
private const float Width = 180f;
|
|
private const float GizmoHeight = 75f;
|
|
private const float Padding = 6f;
|
|
private const float BarHeight = 18f;
|
|
|
|
// 材质颜色
|
|
private static readonly Texture2D ProgressBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.3f, 0.6f, 0.9f, 0.9f));
|
|
private static readonly Texture2D CompletedBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.8f, 0.3f, 0.9f));
|
|
private static readonly Texture2D PausedBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.7f, 0.7f, 0.3f, 0.9f));
|
|
private static readonly Texture2D NoPowerBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.5f, 0.5f, 0.5f, 0.9f));
|
|
private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.15f, 0.15f, 0.15f, 0.8f));
|
|
|
|
public Gizmo_PawnResearchProgress(Comp_PawnResearchBlueprintReader researchComp)
|
|
{
|
|
this.researchComp = researchComp;
|
|
Order = -130f;
|
|
}
|
|
|
|
public override float GetWidth(float maxWidth)
|
|
{
|
|
return Mathf.Min(Width, maxWidth);
|
|
}
|
|
|
|
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
|
|
{
|
|
Rect rect = new Rect(topLeft.x, topLeft.y, GetWidth(maxWidth), GizmoHeight);
|
|
Widgets.DrawWindowBackground(rect);
|
|
|
|
Rect innerRect = rect.ContractedBy(Padding);
|
|
float curY = innerRect.y;
|
|
|
|
var currentResearch = researchComp.CurrentResearch;
|
|
|
|
// === 第一行:标题(可点击选择研究) ===
|
|
Text.Font = GameFont.Small;
|
|
Text.Anchor = TextAnchor.MiddleLeft;
|
|
Rect titleRect = new Rect(innerRect.x, curY, innerRect.width, 18f);
|
|
|
|
string title;
|
|
if (currentResearch != null)
|
|
{
|
|
title = currentResearch.LabelCap.RawText ?? currentResearch.defName;
|
|
// 截断过长的标题
|
|
title = title.Truncate(innerRect.width - 20f);
|
|
}
|
|
else
|
|
{
|
|
title = "ARA_PawnResearch_NoProject".Translate();
|
|
}
|
|
|
|
// 标题可点击
|
|
if (Mouse.IsOver(titleRect))
|
|
{
|
|
Widgets.DrawHighlight(titleRect);
|
|
}
|
|
|
|
if (Widgets.ButtonInvisible(titleRect) && researchComp.CanResearch)
|
|
{
|
|
researchComp.ShowResearchMenu();
|
|
}
|
|
|
|
// 显示下拉箭头(如果可以选择研究)
|
|
if (researchComp.CanResearch)
|
|
{
|
|
GUI.color = new Color(0.7f, 0.9f, 1f);
|
|
Widgets.Label(titleRect, title + " ▼");
|
|
GUI.color = Color.white;
|
|
}
|
|
else
|
|
{
|
|
Widgets.Label(titleRect, title);
|
|
}
|
|
curY += 20f;
|
|
|
|
// === 第二行:状态信息 ===
|
|
Text.Font = GameFont.Tiny;
|
|
Text.Anchor = TextAnchor.MiddleLeft;
|
|
Rect statusRect = new Rect(innerRect.x, curY, innerRect.width, 14f);
|
|
|
|
if (currentResearch != null)
|
|
{
|
|
string statusText;
|
|
if (currentResearch.IsFinished)
|
|
{
|
|
GUI.color = new Color(0.3f, 0.9f, 0.3f);
|
|
statusText = "ARA_PawnResearch_Completed".Translate();
|
|
}
|
|
else if (researchComp.IsResearching && researchComp.CanResearch)
|
|
{
|
|
GUI.color = new Color(0.5f, 0.8f, 1f);
|
|
statusText = "ARA_PawnResearch_Researching".Translate();
|
|
}
|
|
else if (!researchComp.CanResearch)
|
|
{
|
|
GUI.color = new Color(0.8f, 0.2f, 0.2f);
|
|
statusText = "ARA_PawnResearch_CannotResearch".Translate();
|
|
}
|
|
else
|
|
{
|
|
GUI.color = new Color(0.9f, 0.7f, 0.2f);
|
|
statusText = "ARA_PawnResearch_Paused".Translate();
|
|
}
|
|
Widgets.Label(statusRect, statusText);
|
|
}
|
|
else
|
|
{
|
|
GUI.color = new Color(0.5f, 0.5f, 0.5f);
|
|
Widgets.Label(statusRect, "ARA_PawnResearch_SelectProject".Translate());
|
|
}
|
|
curY += 15f;
|
|
|
|
// === 第三行:进度条 ===
|
|
GUI.color = Color.white;
|
|
Rect barRect = new Rect(innerRect.x, curY, innerRect.width, BarHeight);
|
|
|
|
// 背景
|
|
GUI.DrawTexture(barRect, EmptyBarTex);
|
|
|
|
if (currentResearch != null)
|
|
{
|
|
float percentage = researchComp.ResearchProgressPercent;
|
|
|
|
// 根据状态选择颜色
|
|
Texture2D barTex;
|
|
if (currentResearch.IsFinished)
|
|
barTex = CompletedBarTex;
|
|
else if (researchComp.IsResearching && researchComp.CanResearch)
|
|
barTex = ProgressBarTex;
|
|
else if (!researchComp.CanResearch)
|
|
barTex = NoPowerBarTex;
|
|
else
|
|
barTex = PausedBarTex;
|
|
|
|
// 填充条
|
|
Rect fillRect = new Rect(barRect.x, barRect.y, barRect.width * percentage, barRect.height);
|
|
GUI.DrawTexture(fillRect, barTex);
|
|
|
|
// 百分比文字
|
|
Text.Font = GameFont.Tiny;
|
|
Text.Anchor = TextAnchor.MiddleCenter;
|
|
GUI.color = Color.white;
|
|
|
|
string progressText;
|
|
if (currentResearch.IsFinished)
|
|
{
|
|
progressText = "ARA_PawnResearch_CompletedShort".Translate();
|
|
}
|
|
else
|
|
{
|
|
progressText = $"{researchComp.CurrentProgress:F0} / {currentResearch.baseCost:F0}";
|
|
}
|
|
|
|
Widgets.Label(barRect, progressText);
|
|
}
|
|
else
|
|
{
|
|
// 无项目时显示空状态
|
|
Text.Font = GameFont.Tiny;
|
|
Text.Anchor = TextAnchor.MiddleCenter;
|
|
GUI.color = new Color(0.5f, 0.5f, 0.5f);
|
|
Widgets.Label(barRect, "---");
|
|
}
|
|
|
|
// === 工具提示 ===
|
|
if (Mouse.IsOver(rect))
|
|
{
|
|
Widgets.DrawHighlight(rect);
|
|
TooltipHandler.TipRegion(rect, GetTooltip());
|
|
}
|
|
|
|
GUI.color = Color.white;
|
|
Text.Anchor = TextAnchor.UpperLeft;
|
|
Text.Font = GameFont.Small;
|
|
|
|
return new GizmoResult(GizmoState.Clear);
|
|
}
|
|
|
|
private string GetTooltip()
|
|
{
|
|
var sb = new System.Text.StringBuilder();
|
|
var currentResearch = researchComp.CurrentResearch;
|
|
|
|
sb.AppendLine("ARA_PawnResearch_TooltipTitle".Translate());
|
|
sb.AppendLine();
|
|
|
|
if (currentResearch != null)
|
|
{
|
|
sb.AppendLine("ARA_PawnResearch_TooltipProject".Translate(currentResearch.LabelCap));
|
|
sb.AppendLine("ARA_PawnResearch_TooltipProgress".Translate(
|
|
researchComp.CurrentProgress.ToString("F0"),
|
|
currentResearch.baseCost.ToString("F0")));
|
|
|
|
sb.AppendLine("ARA_PawnResearch_TooltipPercentage".Translate(researchComp.ResearchProgressPercent.ToStringPercent()));
|
|
sb.AppendLine();
|
|
|
|
if (currentResearch.IsFinished)
|
|
{
|
|
sb.AppendLine("<color=green>" + "ARA_PawnResearch_TooltipCompleted".Translate() + "</color>");
|
|
}
|
|
else if (researchComp.IsResearching && researchComp.CanResearch)
|
|
{
|
|
// 显示研究速度
|
|
sb.AppendLine("ARA_PawnResearch_TooltipSpeed".Translate(researchComp.ResearchSpeedPerSecond.ToString("F1")));
|
|
|
|
// 显示灵能科研点消耗
|
|
if (researchComp.Props.usePsychicResearchPoints)
|
|
{
|
|
sb.AppendLine("ARA_PawnResearch_TooltipPointsConsumption".Translate(researchComp.PsychicResearchPointsPerSecond.ToString("F1")));
|
|
}
|
|
}
|
|
else if (!researchComp.CanResearch)
|
|
{
|
|
sb.AppendLine("<color=red>" + "ARA_PawnResearch_TooltipCannotResearch".Translate() + "</color>");
|
|
sb.AppendLine("ARA_PawnResearch_TooltipCannotResearchReason".Translate());
|
|
|
|
// 检查具体原因
|
|
if (researchComp.Pawn != null)
|
|
{
|
|
if (researchComp.Pawn.Dead)
|
|
sb.AppendLine(" • " + "Dead".Translate());
|
|
if (researchComp.Pawn.Downed)
|
|
sb.AppendLine(" • " + "Downed".Translate());
|
|
if (!researchComp.Pawn.Spawned)
|
|
sb.AppendLine(" • " + "NotSpawned".Translate());
|
|
}
|
|
|
|
if (researchComp.Props.usePsychicResearchPoints && researchComp.spellHolder != null)
|
|
{
|
|
if (researchComp.spellHolder.PsychicResearchPoints < researchComp.PsychicResearchPointsPerSecond)
|
|
{
|
|
sb.AppendLine(" • " + "ARA_PawnResearch_InsufficientPointsShort".Translate());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine("<color=yellow>" + "ARA_PawnResearch_TooltipPaused".Translate() + "</color>");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine("ARA_PawnResearch_TooltipNoProject".Translate());
|
|
}
|
|
|
|
// 显示Pawn信息
|
|
if (researchComp.Pawn != null)
|
|
{
|
|
sb.AppendLine();
|
|
sb.AppendLine("ARA_PawnResearch_TooltipPawnInfo".Translate());
|
|
sb.AppendLine($" • {"Intellectual".Translate()}: {researchComp.Pawn.skills.GetSkill(SkillDefOf.Intellectual).Level}");
|
|
|
|
if (researchComp.spellHolder != null)
|
|
{
|
|
sb.AppendLine($" • {"ARA_PawnResearch_PsychicPoints".Translate()}: {researchComp.spellHolder.PsychicResearchPoints:F0}");
|
|
}
|
|
}
|
|
|
|
return sb.ToString().TrimEndNewlines();
|
|
}
|
|
}
|
|
}
|