feat: 新增虫群维护系统、营养网络塔及多种阿拉克涅建筑
This commit is contained in:
@@ -146,6 +146,7 @@
|
||||
<Compile Include="Pawn_Comps\ARA_DratfableAnimals\CompProperties_DratfableAnimals.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_SwarmMaintainer\CompProperties_SwarmMaintainer.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_SwarmMaintainer\Comp_SwarmMaintainer.cs" />
|
||||
<Compile Include="Building_Comps\ARA_SwarmMaintenance\Gizmo_SwarmMaintenance.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_DratfableAnimals\BeastUnit.cs" />
|
||||
<Compile Include="RoomRole\RoomRoleWorker_JellyVat.cs" />
|
||||
<Compile Include="RoomRole\RoomRoleWorker_Incubator.cs" />
|
||||
|
||||
@@ -90,25 +90,7 @@ namespace ArachnaeSwarm
|
||||
return;
|
||||
|
||||
// 计算基础递减量:每天递减量转换为每2500tick(约0.0417天)的递减量
|
||||
float baseDecayAmount = Props.maintenanceDecayPerDay * (2500f / 60000f);
|
||||
|
||||
// 检查是否为卵囊建筑,并根据孵化状态调整消耗
|
||||
float decayMultiplier = 1f;
|
||||
if (parent is Building_Ootheca ootheca)
|
||||
{
|
||||
if (!ootheca.IsIncubating)
|
||||
{
|
||||
// 未孵化时维护消耗减少80%
|
||||
decayMultiplier = 0.2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 孵化时根据活性调整(活性越高消耗越多)
|
||||
decayMultiplier = 0.5f + ootheca.FluxEfficiency * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
float decayAmount = baseDecayAmount * decayMultiplier;
|
||||
float decayAmount = Props.maintenanceDecayPerDay * (2500f / 60000f);
|
||||
currentMaintenance -= decayAmount;
|
||||
|
||||
// 确保不低于0
|
||||
@@ -185,6 +167,41 @@ namespace ArachnaeSwarm
|
||||
lastWarningState = false;
|
||||
}
|
||||
|
||||
// 手动呼叫最近的维护者
|
||||
public void CallMaintainer()
|
||||
{
|
||||
if (parent.Map == null) return;
|
||||
|
||||
Pawn bestPawn = null;
|
||||
float minDist = float.MaxValue;
|
||||
|
||||
foreach (Pawn pawn in parent.Map.mapPawns.FreeColonistsSpawned)
|
||||
{
|
||||
var maintainerComp = pawn.TryGetComp<Comp_SwarmMaintainer>();
|
||||
if (maintainerComp != null && !pawn.Downed && !pawn.Dead &&
|
||||
pawn.CanReserveAndReach(parent, PathEndMode.Touch, Danger.Some))
|
||||
{
|
||||
float dist = pawn.Position.DistanceToSquared(parent.Position);
|
||||
if (dist < minDist)
|
||||
{
|
||||
minDist = dist;
|
||||
bestPawn = pawn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bestPawn != null)
|
||||
{
|
||||
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_SwarmMaintain, parent);
|
||||
bestPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
||||
Messages.Message("ARA_Msg_MaintainerCalled".Translate(bestPawn.LabelShort), parent, MessageTypeDefOf.PositiveEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Messages.Message("ARA_Msg_NoMaintainerAvailable".Translate(), MessageTypeDefOf.RejectInput);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取可维护的优先级(用于WorkGiver排序)
|
||||
public float GetMaintenancePriority()
|
||||
{
|
||||
@@ -220,33 +237,21 @@ namespace ArachnaeSwarm
|
||||
return text;
|
||||
}
|
||||
|
||||
// 获取实际每日消耗(考虑孵化活性)
|
||||
// 获取实际每日消耗
|
||||
private float GetActualDecayPerDay()
|
||||
{
|
||||
float baseDecay = Props.maintenanceDecayPerDay;
|
||||
float multiplier = 1f;
|
||||
|
||||
if (parent is Building_Ootheca ootheca)
|
||||
{
|
||||
if (!ootheca.IsIncubating)
|
||||
{
|
||||
multiplier = 0.2f;
|
||||
}
|
||||
else
|
||||
{
|
||||
multiplier = 0.5f + ootheca.FluxEfficiency * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
return baseDecay * multiplier;
|
||||
return Props.maintenanceDecayPerDay;
|
||||
}
|
||||
|
||||
// 获取Gizmos(命令按钮)- 只保留调试功能
|
||||
// 获取Gizmos(命令按钮)
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
// 只在玩家控制下显示
|
||||
if (parent.Faction?.IsPlayer == true)
|
||||
{
|
||||
// 维护度计量条
|
||||
yield return new Gizmo_SwarmMaintenance(this);
|
||||
|
||||
// 调试按钮 - 仅在GodMode下显示
|
||||
if (DebugSettings.godMode)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
// File: Gizmo_SwarmMaintenance.cs
|
||||
// 虫群建筑维护度计量条 Gizmo
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public class Gizmo_SwarmMaintenance : Gizmo
|
||||
{
|
||||
private readonly Comp_SwarmMaintenance comp;
|
||||
private readonly Thing parentThing;
|
||||
|
||||
// 尺寸常量
|
||||
private const float Width = 140f;
|
||||
private const float GizmoHeight = 75f;
|
||||
private const float Padding = 6f;
|
||||
private const float BarHeight = 18f;
|
||||
|
||||
// 材质颜色
|
||||
private static readonly Texture2D FullBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.8f, 0.3f, 0.9f));
|
||||
private static readonly Texture2D MediumBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.9f, 0.7f, 0.2f, 0.9f));
|
||||
private static readonly Texture2D LowBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.9f, 0.3f, 0.2f, 0.9f));
|
||||
private static readonly Texture2D EmptyBarTex = SolidColorMaterials.NewSolidColorTexture(new Color(0.15f, 0.15f, 0.15f, 0.8f));
|
||||
|
||||
public Gizmo_SwarmMaintenance(Comp_SwarmMaintenance comp)
|
||||
{
|
||||
this.comp = comp;
|
||||
this.parentThing = comp.parent;
|
||||
Order = -120f; // 在活性和进度条之后,交互按钮之前
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// === 第一行:标题 + 按钮 ===
|
||||
Text.Font = GameFont.Small;
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
GUI.color = Color.white;
|
||||
Rect titleRect = new Rect(innerRect.x, curY, innerRect.width - 26f, 18f);
|
||||
Widgets.Label(titleRect, "ARA_SwarmMaintenance_Title".Translate());
|
||||
|
||||
// 右上角呼叫按钮
|
||||
Rect btnRect = new Rect(innerRect.xMax - 20f, curY - 1f, 20f, 20f);
|
||||
if (Widgets.ButtonImage(btnRect, ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false)))
|
||||
{
|
||||
comp.CallMaintainer();
|
||||
}
|
||||
TooltipHandler.TipRegion(btnRect, "ARA_Gizmo_CallMaintainer".Translate());
|
||||
|
||||
curY += 20f;
|
||||
|
||||
// === 第二行:消耗信息 ===
|
||||
Text.Font = GameFont.Tiny;
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
GUI.color = new Color(0.7f, 0.7f, 0.7f);
|
||||
Rect decayRect = new Rect(innerRect.x, curY, innerRect.width, 14f);
|
||||
string decayText = "ARA_SwarmMaintenance_DailyDecay_Short".Translate(comp.Props.maintenanceDecayPerDay.ToString("F1"));
|
||||
Widgets.Label(decayRect, decayText);
|
||||
curY += 15f;
|
||||
|
||||
// === 第三行:进度条 ===
|
||||
float percentage = comp.MaintenancePercentage;
|
||||
Rect barRect = new Rect(innerRect.x, curY, innerRect.width, BarHeight);
|
||||
|
||||
// 背景
|
||||
GUI.color = Color.white;
|
||||
GUI.DrawTexture(barRect, EmptyBarTex);
|
||||
|
||||
// 根据百分比选择颜色
|
||||
Texture2D barTex;
|
||||
if (percentage > 0.6f)
|
||||
barTex = FullBarTex;
|
||||
else if (percentage > 0.3f)
|
||||
barTex = MediumBarTex;
|
||||
else
|
||||
barTex = LowBarTex;
|
||||
|
||||
// 填充条
|
||||
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;
|
||||
Widgets.Label(barRect, percentage.ToStringPercent());
|
||||
|
||||
// === 工具提示 ===
|
||||
Rect tooltipRect = new Rect(rect.x, rect.y, rect.width, rect.height);
|
||||
tooltipRect.xMax -= 24f; // 排除按钮区域
|
||||
if (Mouse.IsOver(tooltipRect))
|
||||
{
|
||||
Widgets.DrawHighlight(rect);
|
||||
TooltipHandler.TipRegion(tooltipRect, 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();
|
||||
|
||||
sb.AppendLine("ARA_SwarmMaintenance_TooltipTitle".Translate());
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("ARA_SwarmMaintenance_TooltipCurrent".Translate(
|
||||
comp.CurrentMaintenance.ToString("F1"),
|
||||
comp.MaxMaintenance.ToString("F1")));
|
||||
sb.AppendLine("ARA_SwarmMaintenance_TooltipDecay".Translate(comp.Props.maintenanceDecayPerDay.ToString("F1")));
|
||||
sb.AppendLine();
|
||||
|
||||
if (comp.IsCritical)
|
||||
{
|
||||
sb.AppendLine("<color=orange>" + "ARA_SwarmMaintenance_TooltipCritical".Translate() + "</color>");
|
||||
}
|
||||
else if (comp.NeedsMaintenance)
|
||||
{
|
||||
sb.AppendLine("<color=yellow>" + "ARA_SwarmMaintenance_TooltipNeedsMaintenance".Translate() + "</color>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine("<color=green>" + "ARA_SwarmMaintenance_TooltipGood".Translate() + "</color>");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("ARA_SwarmMaintenance_TooltipHint".Translate());
|
||||
|
||||
return sb.ToString().TrimEndNewlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user