This commit is contained in:
2025-12-23 15:34:44 +08:00
parent 79b09af69f
commit c130329439
10 changed files with 777 additions and 152 deletions

View File

@@ -8,7 +8,7 @@ using System;
namespace ArachnaeSwarm
{
public class Building_EquipmentOotheca : Building
public class Building_EquipmentOotheca : Building, IFluxController
{
// 引用组件
public CompEquipmentIncubatorData EquipmentIncubatorData => this.TryGetComp<CompEquipmentIncubatorData>();
@@ -33,27 +33,75 @@ namespace ArachnaeSwarm
private float qualityProgress = 0f;
private float qualityTotal = 0f;
// === 简化后的营养液系统:只用于速度加成,不消耗 ===
private int totalNutrientCost = 0; // 总共需要的营养液地块数量(仅用于信息显示)
private int currentNutrientCount = 0; // 当前周围存在的营养液数量
// ======= 孵化活性系统 =======
private float neutronFlux = 0.5f; // 0-1, 默认50%
private FluxMode fluxMode = FluxMode.Balance; // 默认平衡模式
private CompRefuelableNutrition fuelComp; // 燃料组件缓存
private Comp_SwarmMaintenance maintenanceComp; // 维护组件缓存
// 缓存的ModExtension
private OothecaIncubatorExtension cachedExtension;
// 孵化活性公开属性
public float NeutronFlux => isIncubating ? neutronFlux : 0f;
public float RawFlux => neutronFlux;
public FluxMode CurrentFluxMode => fluxMode;
public bool IsAutoMode => fluxMode != FluxMode.Manual;
public bool IsIncubating => isIncubating;
// 获取ModExtension的辅助属性
public OothecaIncubatorExtension Ext
// 获取燃料组件
public CompRefuelableNutrition FuelComp => fuelComp ?? (fuelComp = this.TryGetComp<CompRefuelableNutrition>());
public Comp_SwarmMaintenance MaintenanceComp => maintenanceComp ?? (maintenanceComp = this.TryGetComp<Comp_SwarmMaintenance>());
// 孵化活性效率曲线非线性flux²
public float FluxEfficiency => NeutronFlux * NeutronFlux;
// 是否处于休眠状态
public bool IsDormant => NeutronFlux < 0.01f || (FuelComp != null && !FuelComp.HasFuel);
// 设置活性值
public void SetNeutronFlux(float value)
{
get
neutronFlux = Mathf.Clamp01(value);
}
// 切换模式
public void CycleFluxMode()
{
fluxMode = (FluxMode)(((int)fluxMode + 1) % 4);
}
public void SetFluxMode(FluxMode mode)
{
fluxMode = mode;
}
public string GetModeName()
{
switch (fluxMode)
{
if (cachedExtension == null)
{
cachedExtension = def.GetModExtension<OothecaIncubatorExtension>() ?? OothecaIncubatorExtension.Default;
}
return cachedExtension;
case FluxMode.Manual: return "手动";
case FluxMode.Quality: return "品质";
case FluxMode.Balance: return "平衡";
case FluxMode.Speed: return "速度";
default: return "?";
}
}
// 属性访问器
public string GetModeShort()
{
switch (fluxMode)
{
case FluxMode.Manual: return "M";
case FluxMode.Quality: return "Q";
case FluxMode.Balance: return "B";
case FluxMode.Speed: return "S";
default: return "?";
}
}
// 孵化进度百分比(给 Gizmo 用)
public float IncubationProgress => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
// 速度乘数
public float SpeedMultiplier
{
get
@@ -69,21 +117,27 @@ namespace ArachnaeSwarm
// 质量属性
public float QualityMultiplier => qualityMultiplier;
public float QualityProgress => qualityProgress;
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
// 营养液加成属性
public int CurrentNutrientCount => currentNutrientCount;
public float NutrientSpeedBonus => currentNutrientCount * Ext.nutrientSolutionBonusPerTile;
// 临时保留:营养液相关字段(后续清理)
private int totalNutrientCost = 0;
private int currentNutrientCount = 0;
private OothecaIncubatorExtension cachedExtension;
// 进度百分比
public float AdjustedProgressPercent
public OothecaIncubatorExtension Ext
{
get
{
if (incubationDuration <= 0) return 0f;
return incubationProgress / incubationDuration;
if (cachedExtension == null)
cachedExtension = def.GetModExtension<OothecaIncubatorExtension>() ?? OothecaIncubatorExtension.Default;
return cachedExtension;
}
}
// 营养液速度加成(临时保留)
public float NutrientSpeedBonus => currentNutrientCount * Ext.nutrientSolutionBonusPerTile;
// 进度百分比
public float AdjustedProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
// === 简化的初始化营养液方法 ===
private void InitializeNutrientInfo()
@@ -108,7 +162,7 @@ namespace ArachnaeSwarm
UpdateNutrientCount();
}
// === 简化的Tick方法 ===
// === Tick方法(带活性系统)===
protected override void Tick()
{
base.Tick();
@@ -126,12 +180,45 @@ namespace ArachnaeSwarm
UpdateSpeedMultiplier();
UpdateQualityMultiplier();
}
float currentSpeed = SpeedMultiplier;
// 始终增加进度(不再有营养液不足的暂停)
incubationProgress += currentSpeed;
qualityProgress += currentSpeed * QualityMultiplier;
// 自动模式计算
if (IsAutoMode && Find.TickManager.TicksGame % 250 == 0)
{
CalculateAutoFlux();
}
// 消耗虫蜜(基于孵化活性)
if (FuelComp != null && neutronFlux > 0.01f)
{
float fuelPerTick = (50f * FluxEfficiency) / 60000f;
FuelComp.ConsumeFuel(fuelPerTick);
}
// 休眠状态处理
if (IsDormant)
{
// 休眠时品质下降10%/天)
float qualityDecay = (qualityTotal * 0.1f) / 60000f;
qualityProgress = Mathf.Max(0f, qualityProgress - qualityDecay);
if (qualityProgress <= 0 && qualityTotal > 0)
{
Messages.Message("制造舱因品质归零而损坏!", this, MessageTypeDefOf.NegativeEvent);
Destroy(DestroyMode.KillFinalize);
return;
}
}
else
{
// 正常状态:应用活性效率
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
incubationProgress += fluxSpeed;
// 品质独立增长
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
}
if (incubationProgress >= incubationDuration)
{
@@ -139,6 +226,57 @@ namespace ArachnaeSwarm
}
}
}
// 自动模式算法
private void CalculateAutoFlux()
{
if (fluxMode == FluxMode.Manual) return;
float targetFlux = 0.5f;
float incubationPercent = incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
float qualityPercent = qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
float gap = qualityPercent - incubationPercent;
switch (fluxMode)
{
case FluxMode.Quality:
if (qualityPercent >= 0.98f) targetFlux = 1.0f;
else if (gap > 0.2f) targetFlux = 0.6f;
else if (gap > 0.1f) targetFlux = 0.45f;
else if (gap > 0f) targetFlux = 0.35f;
else targetFlux = 0.2f;
break;
case FluxMode.Speed:
if (qualityPercent >= 0.95f) targetFlux = 1.0f;
else if (qualityPercent < 0.3f && incubationPercent > 0.5f) targetFlux = 0.7f;
else if (qualityPercent < 0.2f && incubationPercent > 0.7f) targetFlux = 0.5f;
else targetFlux = 1.0f;
break;
case FluxMode.Balance:
default:
if (qualityPercent >= 0.95f) targetFlux = 1.0f;
else if (gap > 0.15f) targetFlux = 0.8f;
else if (gap > 0.05f) targetFlux = 0.6f;
else if (gap > -0.05f) targetFlux = 0.5f;
else if (gap > -0.15f) targetFlux = 0.35f;
else targetFlux = 0.2f;
break;
}
// 资源保护
if (FuelComp != null && FuelComp.Fuel < 2f)
targetFlux = Mathf.Min(targetFlux, 0.2f);
if (MaintenanceComp != null && MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance < 0.15f)
targetFlux = Mathf.Min(targetFlux, 0.15f);
// 平滑调节
float adjustSpeed = 0.03f;
if (neutronFlux < targetFlux) neutronFlux = Mathf.Min(neutronFlux + adjustSpeed, targetFlux);
else if (neutronFlux > targetFlux) neutronFlux = Mathf.Max(neutronFlux - adjustSpeed, targetFlux);
neutronFlux = Mathf.Clamp(neutronFlux, 0.1f, 1.0f);
}
// === 获取速度因子描述 ===
public string GetSpeedFactorsDescription()
@@ -565,18 +703,30 @@ namespace ArachnaeSwarm
// === Gizmos ===
public override IEnumerable<Gizmo> GetGizmos()
{
// 过滤掉拆除按钮和半径显示
foreach (var gizmo in base.GetGizmos())
{
// 跳过拆除和半径相关的 Gizmo
if (gizmo is Command_Action cmd && cmd.defaultLabel != null)
{
string label = cmd.defaultLabel.ToString();
if (label.Contains("拆除") || label.Contains("Deconstruct") ||
label.Contains("半径") || label.Contains("Radius"))
continue;
}
yield return gizmo;
}
// 只有玩家派系才显示Gizmo
if (Faction == Faction.OfPlayer)
{
if (!isIncubating && EquipmentIncubatorData?.IncubationConfigs?.Count > 0)
{
yield return CreateTargetSwitchGizmo();
}
// 始终显示双进度条Gizmo
yield return new Gizmo_EquipmentIncubationProgress(this);
// 始终显示活性 Gizmo
yield return new Gizmo_NeutronFlux(this);
// 不在孵化中且研究完成时才显示呼叫按钮
var config = EquipmentIncubatorData?.SelectedConfig;
if (!isIncubating && config != null && config.IsResearchComplete)
{
@@ -590,6 +740,7 @@ namespace ArachnaeSwarm
};
}
// 如果正在孵化,显示取消按钮
if (isIncubating)
{
yield return new Command_Action
@@ -978,6 +1129,10 @@ namespace ArachnaeSwarm
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
Scribe_Values.Look(ref totalNutrientCost, "totalNutrientCost", 0);
Scribe_Values.Look(ref currentNutrientCount, "currentNutrientCount", 0);
// 孵化活性系统
Scribe_Values.Look(ref neutronFlux, "neutronFlux", 0.5f);
Scribe_Values.Look(ref fluxMode, "fluxMode", FluxMode.Balance);
}
}
}