zc
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -60,6 +60,7 @@
|
||||
<li>ARA_Acidling_AutoMortar</li>
|
||||
<li>CatastropheMissileSilo</li>
|
||||
<li>ARA_AutoSniperCannon</li>
|
||||
<li>ARA_Pawn_Ootheca</li>
|
||||
</linkableBuildings>
|
||||
<maxDistance>80</maxDistance> <!-- 供能范围 -->
|
||||
<maxSimultaneous>10</maxSimultaneous>
|
||||
|
||||
@@ -151,9 +151,7 @@
|
||||
<ARA_InsectJelly>25</ARA_InsectJelly>
|
||||
</costList>
|
||||
|
||||
<placeWorkers>
|
||||
<li>ArachnaeSwarm.PlaceWorker_CustomRadius</li>
|
||||
</placeWorkers>
|
||||
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_SwarmMaintenance">
|
||||
<maxMaintenance>100</maxMaintenance>
|
||||
@@ -162,15 +160,27 @@
|
||||
<warningThreshold>0.2</warningThreshold>
|
||||
<maintenanceThresholdForJob>0.5</maintenanceThresholdForJob>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_CustomRadius">
|
||||
<radius>5</radius> <!-- 半径大小 -->
|
||||
<color>(0.5, 1, 1)</color> <!-- 绿色圆圈 -->
|
||||
<radiusOffset>0</radiusOffset> <!-- 半径偏移 -->
|
||||
<showInGUI>true</showInGUI>
|
||||
<label>吸收半径</label>
|
||||
<description>这个卵在孵化过程中的吸收半径,确保这些地格中铺满阿拉克涅营养液,并且没有其他的卵,以获得最佳的孵化速度和孵化质量。</description>
|
||||
<defaultVisible>false</defaultVisible>
|
||||
|
||||
<!-- 虫蜜燃料系统 -->
|
||||
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
||||
<fuelCapacity>25.0</fuelCapacity>
|
||||
<fuelFilter>
|
||||
<thingDefs>
|
||||
<li>ARA_InsectJelly</li>
|
||||
</thingDefs>
|
||||
</fuelFilter>
|
||||
<fuelGizmoLabel>虫蜜</fuelGizmoLabel>
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
||||
<initialConfigurableTargetFuelLevel>5</initialConfigurableTargetFuelLevel>
|
||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||
</li>
|
||||
<li Class="CompProperties_AffectedByFacilities">
|
||||
<linkableFacilities>
|
||||
<li>ARA_NutrientNetworkTower</li>
|
||||
</linkableFacilities>
|
||||
</li>
|
||||
|
||||
<li Class="ArachnaeSwarm.CompProperties_IncubatorData">
|
||||
<!-- 按钮和菜单配置 -->
|
||||
<defaultIndex>0</defaultIndex>
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
<Compile Include="Buildings\Building_Ootheca\Building_Ootheca.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\CompProperties_IncubatorData.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\Gizmo_IncubationProgress.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\Gizmo_NeutronFlux.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\JobDriver_OperateIncubator.cs" />
|
||||
<Compile Include="Buildings\Building_Ootheca\OothecaIncubatorExtension.cs" />
|
||||
<Compile Include="Buildings\Building_ResearchBlueprintReader\Building_ResearchBlueprintReader.cs" />
|
||||
|
||||
@@ -89,8 +89,26 @@ namespace ArachnaeSwarm
|
||||
if (parent == null || parent.Map == null)
|
||||
return;
|
||||
|
||||
// 计算递减量:每天递减量转换为每2500tick(约0.347天)的递减量
|
||||
float decayAmount = Props.maintenanceDecayPerDay * (2500f / 60000f);
|
||||
// 计算基础递减量:每天递减量转换为每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;
|
||||
currentMaintenance -= decayAmount;
|
||||
|
||||
// 确保不低于0
|
||||
|
||||
@@ -33,6 +33,42 @@ namespace ArachnaeSwarm
|
||||
private float qualityProgress = 0f;
|
||||
private float qualityTotal = 0f;
|
||||
|
||||
// ======= 中子通量系统 =======
|
||||
private float neutronFlux = 0.5f; // 0-1, 默认50%
|
||||
private bool autoFluxMode = true; // 自动模式
|
||||
private CompRefuelableNutrition fuelComp; // 燃料组件缓存
|
||||
private Comp_SwarmMaintenance maintenanceComp; // 维护组件缓存
|
||||
|
||||
// 孵化活性公开属性(非孵化时锁定为0)
|
||||
public float NeutronFlux => isIncubating ? neutronFlux : 0f;
|
||||
public float RawFlux => neutronFlux; // 原始值用于 Gizmo 显示
|
||||
public bool AutoFluxMode => autoFluxMode;
|
||||
|
||||
// 获取燃料组件
|
||||
public CompRefuelableNutrition FuelComp => fuelComp ?? (fuelComp = this.TryGetComp<CompRefuelableNutrition>());
|
||||
public Comp_SwarmMaintenance MaintenanceComp => maintenanceComp ?? (maintenanceComp = this.TryGetComp<Comp_SwarmMaintenance>());
|
||||
|
||||
// 孵化活性效率曲线(非线性:flux² 使低活性效率极低)
|
||||
public float FluxEfficiency => NeutronFlux * NeutronFlux;
|
||||
|
||||
// 是否处于休眠状态(无燃料或活性为0)
|
||||
public bool IsDormant => NeutronFlux < 0.01f || (FuelComp != null && !FuelComp.HasFuel);
|
||||
|
||||
// 是否正在孵化(公开属性)
|
||||
public bool IsIncubating => isIncubating;
|
||||
|
||||
// 设置中子通量
|
||||
public void SetNeutronFlux(float value)
|
||||
{
|
||||
neutronFlux = Mathf.Clamp01(value);
|
||||
}
|
||||
|
||||
// 切换自动模式
|
||||
public void ToggleAutoMode()
|
||||
{
|
||||
autoFluxMode = !autoFluxMode;
|
||||
}
|
||||
|
||||
// 缓存的ModExtension
|
||||
private OothecaIncubatorExtension cachedExtension;
|
||||
|
||||
@@ -81,38 +117,18 @@ namespace ArachnaeSwarm
|
||||
public string GetSpeedFactorsDescription()
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.AppendLine("ARA_OothecaIncubator.SpeedFactors".Translate());
|
||||
builder.AppendLine("速度因子");
|
||||
builder.AppendLine();
|
||||
|
||||
// 1. 检查是否在孵化间中
|
||||
// 检查是否在孵化间中
|
||||
bool inIncubatorRoom = IsInIncubatorRoom();
|
||||
if (Ext.requiresIncubatorRoom)
|
||||
{
|
||||
builder.AppendLine(inIncubatorRoom ?
|
||||
"ARA_OothecaIncubator.InIncubatorRoom".Translate() :
|
||||
"ARA_OothecaIncubator.NotInIncubatorRoom".Translate());
|
||||
builder.AppendLine(inIncubatorRoom ? "✓ 在孵化间中" : "✗ 不在孵化间中");
|
||||
}
|
||||
|
||||
// 2. 检查营养液数量
|
||||
int nutrientSolutionCount = CountNearbyNutrientSolutions();
|
||||
if (nutrientSolutionCount > 0)
|
||||
{
|
||||
builder.AppendLine("ARA_OothecaIncubator.NutrientSolutions".Translate(
|
||||
nutrientSolutionCount,
|
||||
nutrientSolutionCount * Ext.nutrientSolutionBonusPerTile * 100));
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.AppendLine("ARA_OothecaIncubator.NoNutrientSolutionsNearby".Translate());
|
||||
}
|
||||
|
||||
// 显示检测半径
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("ARA_OothecaIncubator.NutrientDetectionRadius".Translate(Ext.nutrientSolutionRadius));
|
||||
|
||||
builder.AppendLine();
|
||||
builder.AppendLine("ARA_OothecaIncubator.TotalSpeedMultiplier".Translate(SpeedMultiplier.ToStringPercent()));
|
||||
builder.AppendLine("总速度倍率: " + SpeedMultiplier.ToStringPercent());
|
||||
|
||||
return builder.ToString().TrimEndNewlines();
|
||||
}
|
||||
@@ -422,22 +438,25 @@ public override string GetInspectString()
|
||||
// Gizmos
|
||||
public override IEnumerable<Gizmo> GetGizmos()
|
||||
{
|
||||
// 过滤掉拆除按钮
|
||||
foreach (var gizmo in base.GetGizmos())
|
||||
{
|
||||
// 跳过拆除相关的 Gizmo
|
||||
if (gizmo is Command_Action cmd && cmd.defaultLabel != null &&
|
||||
(cmd.defaultLabel.ToString().Contains("拆除") || cmd.defaultLabel.ToString().Contains("Deconstruct")))
|
||||
continue;
|
||||
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
// 只有玩家派系才显示Gizmo
|
||||
if (Faction == Faction.OfPlayer)
|
||||
{
|
||||
// 始终显示双进度条Gizmo(内部会自动处理非孵化状态的显示)
|
||||
// 始终显示双进度条Gizmo
|
||||
yield return new Gizmo_IncubationProgress(this);
|
||||
|
||||
// 不在孵化中时才显示切换目标按钮
|
||||
if (!isIncubating && IncubatorData?.IncubationConfigs?.Count > 0)
|
||||
{
|
||||
yield return CreateTargetSwitchGizmo();
|
||||
}
|
||||
// 中子通量控制 Gizmo
|
||||
yield return new Gizmo_NeutronFlux(this);
|
||||
|
||||
// 不在孵化中且研究完成时才显示呼叫按钮
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
@@ -669,25 +688,62 @@ public override string GetInspectString()
|
||||
if (larvaOperateTicksRemaining > 0)
|
||||
{
|
||||
larvaOperateTicksRemaining--;
|
||||
// 注意:孵化启动现在由JobDriver触发,这里只更新显示
|
||||
}
|
||||
|
||||
// 只有在孵化过程中才消耗资源和自动调节
|
||||
if (isIncubating)
|
||||
{
|
||||
// 自动模式计算(每250ticks更新一次)
|
||||
if (autoFluxMode && Find.TickManager.TicksGame % 250 == 0)
|
||||
{
|
||||
CalculateAutoFlux();
|
||||
}
|
||||
|
||||
// 消耗虫蜜(基于孵化活性)
|
||||
if (FuelComp != null && neutronFlux > 0.01f)
|
||||
{
|
||||
// 基础消耗:50虫蜜/天 在100%活性,非线性
|
||||
float baseConsumptionPerDay = 50f * FluxEfficiency;
|
||||
float consumptionPerTick = baseConsumptionPerDay / 60000f;
|
||||
FuelComp.ConsumeFuel(consumptionPerTick);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新孵化进度和质量进度
|
||||
if (isIncubating)
|
||||
{
|
||||
// 更新质量乘数(与速度乘数同步更新)
|
||||
// 更新乘数
|
||||
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
|
||||
{
|
||||
UpdateSpeedMultiplier();
|
||||
UpdateQualityMultiplier();
|
||||
}
|
||||
|
||||
// 应用速度乘数
|
||||
float currentSpeed = SpeedMultiplier;
|
||||
incubationProgress += currentSpeed;
|
||||
// 检查是否休眠
|
||||
if (IsDormant)
|
||||
{
|
||||
// 休眠状态:品质进度下降
|
||||
float qualityDecayPerTick = 0.1f / 60000f; // 每天下降10%
|
||||
qualityProgress = Mathf.Max(0, qualityProgress - qualityDecayPerTick * incubationDuration);
|
||||
|
||||
// 质量进度与速度同步增长,但乘以质量乘数
|
||||
qualityProgress += currentSpeed * QualityMultiplier;
|
||||
// 品质归零 → 破坏卵
|
||||
if (qualityProgress <= 0 && qualityTotal > 0)
|
||||
{
|
||||
Messages.Message("卵囊因品质归零而损坏!", this, MessageTypeDefOf.NegativeEvent);
|
||||
Destroy(DestroyMode.KillFinalize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常状态:应用中子通量效率(100%通量时5倍速度)
|
||||
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
||||
incubationProgress += fluxSpeed;
|
||||
|
||||
// 质量进度也受中子通量影响
|
||||
float fluxQuality = QualityMultiplier * FluxEfficiency * 5f;
|
||||
qualityProgress += fluxSpeed * fluxQuality;
|
||||
}
|
||||
|
||||
if (incubationProgress >= incubationDuration)
|
||||
{
|
||||
@@ -696,6 +752,110 @@ public override string GetInspectString()
|
||||
}
|
||||
}
|
||||
|
||||
// 自动模式:智能计算最优中子通量
|
||||
// 目标:在资源允许的情况下,尽可能快速完成孵化
|
||||
private void CalculateAutoFlux()
|
||||
{
|
||||
if (!autoFluxMode) return;
|
||||
|
||||
float targetFlux = 1.0f; // 默认100%
|
||||
|
||||
// === 策略1:根据孵化剩余时间优化 ===
|
||||
if (isIncubating && incubationDuration > 0)
|
||||
{
|
||||
float remainingProgress = incubationDuration - incubationProgress;
|
||||
float remainingDays = remainingProgress / (60000f * SpeedMultiplier);
|
||||
|
||||
// 计算虫蜜能维持多少天(按当前通量)
|
||||
float fuelDays = float.MaxValue;
|
||||
if (FuelComp != null && FuelComp.Fuel > 0)
|
||||
{
|
||||
// 消耗率 = 50 * flux² 每天
|
||||
float currentConsumption = 50f * neutronFlux * neutronFlux;
|
||||
fuelDays = currentConsumption > 0 ? FuelComp.Fuel / currentConsumption : float.MaxValue;
|
||||
}
|
||||
|
||||
// 计算维护能维持多少天
|
||||
float maintenanceDays = float.MaxValue;
|
||||
if (MaintenanceComp != null)
|
||||
{
|
||||
float maintenance = MaintenanceComp.CurrentMaintenance;
|
||||
float decayPerDay = MaintenanceComp.Props.maintenanceDecayPerDay;
|
||||
maintenanceDays = decayPerDay > 0 ? maintenance / decayPerDay : float.MaxValue;
|
||||
}
|
||||
|
||||
// 找到瓶颈资源
|
||||
float minResourceDays = Mathf.Min(fuelDays, maintenanceDays);
|
||||
|
||||
// 安全边际:资源至少要能维持 剩余孵化天数 + 0.5天
|
||||
float requiredDays = remainingDays + 0.5f;
|
||||
|
||||
if (minResourceDays < requiredDays && minResourceDays > 0)
|
||||
{
|
||||
// 资源不足,需要降低通量
|
||||
// 用二分法找到刚好能完成孵化的通量
|
||||
float lowFlux = 0.1f;
|
||||
float highFlux = neutronFlux;
|
||||
|
||||
for (int i = 0; i < 8; i++) // 8次迭代足够精确
|
||||
{
|
||||
float midFlux = (lowFlux + highFlux) / 2f;
|
||||
float testEfficiency = midFlux * midFlux;
|
||||
float testSpeed = SpeedMultiplier * testEfficiency * 5f;
|
||||
float testDays = testSpeed > 0 ? remainingProgress / (testSpeed * 60000f) : float.MaxValue;
|
||||
|
||||
// 计算该通量下资源能维持多久
|
||||
float testFuelDays = FuelComp != null && FuelComp.Fuel > 0
|
||||
? FuelComp.Fuel / (50f * testEfficiency + 0.01f)
|
||||
: float.MaxValue;
|
||||
|
||||
if (testFuelDays >= testDays + 0.5f)
|
||||
lowFlux = midFlux; // 可以更高
|
||||
else
|
||||
highFlux = midFlux; // 需要更低
|
||||
}
|
||||
|
||||
targetFlux = lowFlux;
|
||||
}
|
||||
}
|
||||
|
||||
// === 策略2:紧急保护 ===
|
||||
// 虫蜜极低时紧急降速
|
||||
if (FuelComp != null && FuelComp.Fuel < 5f)
|
||||
{
|
||||
targetFlux = Mathf.Min(targetFlux, 0.3f);
|
||||
}
|
||||
|
||||
// 维护极低时紧急降速
|
||||
if (MaintenanceComp != null)
|
||||
{
|
||||
float maintenancePercent = MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance;
|
||||
if (maintenancePercent < 0.15f)
|
||||
{
|
||||
targetFlux = Mathf.Min(targetFlux, 0.2f);
|
||||
}
|
||||
}
|
||||
|
||||
// === 策略3:资源充足时全速 ===
|
||||
bool fuelAbundant = FuelComp == null || FuelComp.Fuel > FuelComp.Props.fuelCapacity * 0.8f;
|
||||
bool maintenanceAbundant = MaintenanceComp == null ||
|
||||
MaintenanceComp.CurrentMaintenance > MaintenanceComp.Props.maxMaintenance * 0.7f;
|
||||
|
||||
if (fuelAbundant && maintenanceAbundant)
|
||||
{
|
||||
targetFlux = 1.0f;
|
||||
}
|
||||
|
||||
// 平滑调节(避免突变,每次最多调整5%)
|
||||
float adjustSpeed = 0.05f;
|
||||
if (neutronFlux < targetFlux)
|
||||
neutronFlux = Mathf.Min(neutronFlux + adjustSpeed, targetFlux);
|
||||
else if (neutronFlux > targetFlux)
|
||||
neutronFlux = Mathf.Max(neutronFlux - adjustSpeed, targetFlux);
|
||||
|
||||
neutronFlux = Mathf.Clamp(neutronFlux, 0.05f, 1.0f); // 最低5%防止完全停止
|
||||
}
|
||||
|
||||
// 应用质量效果到生成的pawn
|
||||
private void ApplyQualityEffects(Pawn pawn, float qualityPercent)
|
||||
{
|
||||
@@ -862,23 +1022,17 @@ public override string GetInspectString()
|
||||
return count;
|
||||
}
|
||||
|
||||
// 更新速度乘数
|
||||
// 更新速度乘数(已移除营养液逻辑,后续将使用 CompRefuelableNutrition)
|
||||
private void UpdateSpeedMultiplier()
|
||||
{
|
||||
float multiplier = 1.0f;
|
||||
|
||||
// 1. 检查是否在孵化间中(如果要求)
|
||||
// 检查是否在孵化间中(如果要求)
|
||||
if (Ext.requiresIncubatorRoom && !IsInIncubatorRoom())
|
||||
{
|
||||
multiplier *= Ext.speedPenaltyOutsideIncubator; // 应用惩罚
|
||||
multiplier *= Ext.speedPenaltyOutsideIncubator;
|
||||
}
|
||||
|
||||
// 2. 计算周围营养液的加成
|
||||
int nutrientSolutionCount = CountNearbyNutrientSolutions();
|
||||
float nutrientBonus = 1.0f + (nutrientSolutionCount * Ext.nutrientSolutionBonusPerTile);
|
||||
|
||||
multiplier *= nutrientBonus;
|
||||
|
||||
speedMultiplier = multiplier;
|
||||
lastMultiplierUpdateTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
@@ -927,6 +1081,10 @@ public override string GetInspectString()
|
||||
Scribe_Values.Look(ref qualityMultiplier, "qualityMultiplier", 1.0f);
|
||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
||||
|
||||
// 中子通量系统
|
||||
Scribe_Values.Look(ref neutronFlux, "neutronFlux", 0.5f);
|
||||
Scribe_Values.Look(ref autoFluxMode, "autoFluxMode", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace ArachnaeSwarm
|
||||
public Gizmo_IncubationProgress(Building_Ootheca ootheca)
|
||||
{
|
||||
this.ootheca = ootheca;
|
||||
Order = -100f; // 显示在左侧
|
||||
Order = -99f; // 在通量 Gizmo 之后显示
|
||||
}
|
||||
|
||||
public override float GetWidth(float maxWidth)
|
||||
@@ -37,8 +37,8 @@ namespace ArachnaeSwarm
|
||||
|
||||
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
|
||||
{
|
||||
// 主矩形区域(向上偏移以容纳更高的内容)
|
||||
Rect rect = new Rect(topLeft.x, topLeft.y - 55f, GetWidth(maxWidth), 130f);
|
||||
// 主矩形区域
|
||||
Rect rect = new Rect(topLeft.x, topLeft.y - 25f, GetWidth(maxWidth), 100f);
|
||||
Widgets.DrawWindowBackground(rect);
|
||||
|
||||
// 内部区域
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
// File: Gizmo_NeutronFlux.cs
|
||||
// 竖向滑动条样式的孵化活性调节 Gizmo(带刻度和可拖动光标)
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public class Gizmo_NeutronFlux : Gizmo
|
||||
{
|
||||
private readonly Building_Ootheca ootheca;
|
||||
|
||||
// 尺寸常量
|
||||
private const float Width = 100f;
|
||||
private const float GizmoHeight = 140f; // 增加高度与信息面板齐平
|
||||
private const float Padding = 6f;
|
||||
|
||||
// 材质
|
||||
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));
|
||||
|
||||
private bool isDragging = false;
|
||||
|
||||
public Gizmo_NeutronFlux(Building_Ootheca ootheca)
|
||||
{
|
||||
this.ootheca = ootheca;
|
||||
Order = -100f; // 最先显示
|
||||
}
|
||||
|
||||
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 - 65f, GetWidth(maxWidth), GizmoHeight);
|
||||
Widgets.DrawWindowBackground(rect);
|
||||
|
||||
Rect innerRect = rect.ContractedBy(Padding);
|
||||
|
||||
// === 标题行 ===
|
||||
Text.Font = GameFont.Small;
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
Rect titleRect = new Rect(innerRect.x, innerRect.y, innerRect.width - 24f, 18f);
|
||||
Widgets.Label(titleRect, "活性");
|
||||
|
||||
// === 右上角自动模式按钮 ===
|
||||
float buttonSize = 20f;
|
||||
Rect autoRect = new Rect(innerRect.xMax - buttonSize, innerRect.y, buttonSize, buttonSize);
|
||||
GUI.DrawTexture(autoRect, ootheca.AutoFluxMode ? AutoOnTex : AutoOffTex);
|
||||
Widgets.DrawBox(autoRect, 1);
|
||||
|
||||
Text.Font = GameFont.Tiny;
|
||||
Text.Anchor = TextAnchor.MiddleCenter;
|
||||
GUI.color = Color.white;
|
||||
Widgets.Label(autoRect, ootheca.AutoFluxMode ? "A" : "M");
|
||||
|
||||
if (Widgets.ButtonInvisible(autoRect))
|
||||
{
|
||||
ootheca.ToggleAutoMode();
|
||||
}
|
||||
|
||||
// === 竖向滑动条 ===
|
||||
float barWidth = 32f;
|
||||
float barHeight = 90f; // 增加高度
|
||||
float barX = innerRect.x + 8f;
|
||||
float barY = innerRect.y + 24f;
|
||||
Rect barRect = new Rect(barX, barY, barWidth, barHeight);
|
||||
|
||||
// 非孵化时显示灰色锁定状态
|
||||
bool isLocked = !ootheca.IsIncubating;
|
||||
|
||||
// 绘制背景
|
||||
GUI.color = isLocked ? new Color(0.3f, 0.3f, 0.3f, 0.5f) : Color.white;
|
||||
GUI.DrawTexture(barRect, EmptyBarTex);
|
||||
|
||||
// 绘制填充(从底部向上)- 使用 RawFlux 显示预设值
|
||||
float displayFlux = ootheca.RawFlux;
|
||||
float fillHeight = barRect.height * displayFlux;
|
||||
Rect fillRect = new Rect(barRect.x, barRect.yMax - fillHeight, barRect.width, fillHeight);
|
||||
GUI.color = isLocked ? new Color(0.5f, 0.35f, 0.1f, 0.5f) : Color.white;
|
||||
GUI.DrawTexture(fillRect, FluxBarTex);
|
||||
GUI.color = Color.white;
|
||||
|
||||
// 绘制刻度线(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);
|
||||
GUI.DrawTexture(tickRect, TickMarkTex);
|
||||
}
|
||||
|
||||
// 绘制边框
|
||||
Widgets.DrawBox(barRect, 1);
|
||||
|
||||
// === 可拖动光标(三角形指示器)===
|
||||
float cursorY = barRect.yMax - fillHeight;
|
||||
float cursorWidth = 12f;
|
||||
float cursorHeight = 14f;
|
||||
Rect cursorRect = new Rect(barRect.xMax + 2f, cursorY - cursorHeight / 2f, cursorWidth, cursorHeight);
|
||||
|
||||
// 绘制三角形光标(指向左边)
|
||||
GUI.color = isDragging ? new Color(1f, 0.8f, 0.3f, 1f) : new Color(0.9f, 0.9f, 0.9f, 1f);
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
float w = cursorWidth * (1f - Mathf.Abs(i - 3) / 4f);
|
||||
float y = cursorY - 3.5f + i;
|
||||
Rect lineRect = new Rect(cursorRect.x, y, w, 1f);
|
||||
GUI.DrawTexture(lineRect, CursorTex);
|
||||
}
|
||||
GUI.color = Color.white;
|
||||
|
||||
// === 拖动交互(包括光标区域)===
|
||||
Rect interactRect = new Rect(barRect.x - 5f, barRect.y - 5f, barRect.width + cursorWidth + 15f, barRect.height + 10f);
|
||||
|
||||
if (Event.current.type == EventType.MouseDown && interactRect.Contains(Event.current.mousePosition))
|
||||
{
|
||||
isDragging = true;
|
||||
UpdateFluxFromMouse(barRect);
|
||||
Event.current.Use();
|
||||
}
|
||||
if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
isDragging = false;
|
||||
}
|
||||
if (isDragging && (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.Repaint))
|
||||
{
|
||||
if (Event.current.type == EventType.MouseDrag)
|
||||
{
|
||||
UpdateFluxFromMouse(barRect);
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
|
||||
// === 右侧信息显示 ===
|
||||
float infoX = barRect.xMax + 18f;
|
||||
float infoWidth = innerRect.xMax - infoX;
|
||||
|
||||
Text.Font = GameFont.Small;
|
||||
Text.Anchor = TextAnchor.MiddleLeft;
|
||||
|
||||
// 百分比(大字)
|
||||
GUI.color = ootheca.IsDormant ? Color.red : Color.white;
|
||||
Rect percentRect = new Rect(infoX, barRect.y, infoWidth, 20f);
|
||||
Widgets.Label(percentRect, (ootheca.NeutronFlux * 100f).ToString("0") + "%");
|
||||
|
||||
Text.Font = GameFont.Tiny;
|
||||
|
||||
// 效率
|
||||
GUI.color = new Color(0.7f, 0.7f, 0.7f);
|
||||
Rect effRect = new Rect(infoX, barRect.y + 22f, infoWidth, 14f);
|
||||
Widgets.Label(effRect, "效率");
|
||||
Rect effValRect = new Rect(infoX, barRect.y + 36f, infoWidth, 14f);
|
||||
GUI.color = Color.white;
|
||||
Widgets.Label(effValRect, (ootheca.FluxEfficiency * 100f).ToString("0") + "%");
|
||||
|
||||
// 速度倍率
|
||||
GUI.color = new Color(0.7f, 0.7f, 0.7f);
|
||||
float speedMultiplier = ootheca.FluxEfficiency * 5f;
|
||||
Rect speedRect = new Rect(infoX, barRect.y + 54f, infoWidth, 14f);
|
||||
Widgets.Label(speedRect, "速度");
|
||||
Rect speedValRect = new Rect(infoX, barRect.y + 68f, 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 = Color.white;
|
||||
Text.Anchor = TextAnchor.UpperLeft;
|
||||
Text.Font = GameFont.Small;
|
||||
|
||||
// 工具提示
|
||||
if (Mouse.IsOver(rect))
|
||||
{
|
||||
Widgets.DrawHighlight(rect);
|
||||
TooltipHandler.TipRegion(rect, GetTooltip());
|
||||
}
|
||||
|
||||
return new GizmoResult(GizmoState.Clear);
|
||||
}
|
||||
|
||||
private void UpdateFluxFromMouse(Rect barRect)
|
||||
{
|
||||
float mouseY = Event.current.mousePosition.y;
|
||||
float percent = 1f - (mouseY - barRect.y) / barRect.height;
|
||||
ootheca.SetNeutronFlux(Mathf.Clamp01(percent));
|
||||
}
|
||||
|
||||
private string GetTooltip()
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
// 标题
|
||||
sb.AppendLine("【孵化活性控制器】");
|
||||
sb.AppendLine();
|
||||
|
||||
// 当前状态
|
||||
sb.AppendLine("═══ 当前状态 ═══");
|
||||
sb.AppendLine($"活性: {(ootheca.NeutronFlux * 100f):0}%");
|
||||
sb.AppendLine($"效率: {(ootheca.FluxEfficiency * 100f):0}% (活性²)");
|
||||
sb.AppendLine($"孵化速度: {(ootheca.FluxEfficiency * 5f):0.0}x");
|
||||
sb.AppendLine($"模式: {(ootheca.AutoFluxMode ? "自动" : "手动")}");
|
||||
sb.AppendLine();
|
||||
|
||||
// 效率说明
|
||||
sb.AppendLine("═══ 效率曲线 ═══");
|
||||
sb.AppendLine("活性与效率呈非线性关系:");
|
||||
sb.AppendLine(" 20% 活性 → 4% 效率 (0.2x速度)");
|
||||
sb.AppendLine(" 50% 活性 → 25% 效率 (1.25x速度)");
|
||||
sb.AppendLine(" 70% 活性 → 49% 效率 (2.45x速度)");
|
||||
sb.AppendLine(" 100% 活性 → 100% 效率 (5x速度)");
|
||||
sb.AppendLine();
|
||||
|
||||
// 消耗说明
|
||||
sb.AppendLine("═══ 资源消耗 ═══");
|
||||
float dailyFuelConsumption = 50f * ootheca.FluxEfficiency;
|
||||
sb.AppendLine($"虫蜜消耗: {dailyFuelConsumption:0.0}/天");
|
||||
sb.AppendLine("(基础50/天 × 效率)");
|
||||
sb.AppendLine();
|
||||
|
||||
// 操作说明
|
||||
sb.AppendLine("═══ 操作指南 ═══");
|
||||
sb.AppendLine("• 拖动滑块或光标调节通量");
|
||||
sb.AppendLine("• 右上角[A/M]切换模式");
|
||||
sb.AppendLine("• 自动模式智能平衡资源和速度");
|
||||
sb.AppendLine();
|
||||
|
||||
// 警告
|
||||
sb.AppendLine("═══ 注意事项 ═══");
|
||||
sb.AppendLine("• 通量为0时进入休眠状态");
|
||||
sb.AppendLine("• 休眠时品质持续下降");
|
||||
sb.AppendLine("• 品质归零卵囊将被破坏");
|
||||
sb.AppendLine("• 虫蜜耗尽也会进入休眠");
|
||||
|
||||
if (ootheca.IsDormant)
|
||||
{
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("<color=red>════════════════</color>");
|
||||
sb.AppendLine("<color=red>⚠ 当前处于休眠状态!</color>");
|
||||
sb.AppendLine("<color=red>品质正在下降!</color>");
|
||||
sb.AppendLine("<color=red>════════════════</color>");
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEndNewlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user