This commit is contained in:
2025-12-23 14:30:48 +08:00
parent c70e4daf38
commit 073e0fa1e8
5 changed files with 94 additions and 105 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -201,8 +201,9 @@ namespace ArachnaeSwarm
MaxMaintenance.ToString("F1"),
MaintenancePercentage.ToString("P1"));
// 添加维护度递减信息
text += "\n" + "ARA_SwarmMaintenance.DailyDecay".Translate(Props.maintenanceDecayPerDay.ToString("F1"));
// 计算实际每日消耗
float actualDecayPerDay = GetActualDecayPerDay();
text += "\n" + "ARA_SwarmMaintenance.DailyDecay".Translate(actualDecayPerDay.ToString("F1"));
// 显示维护状态
if (NeedsMaintenance)
@@ -219,6 +220,27 @@ 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;
}
// 获取Gizmos命令按钮- 只保留调试功能
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{

View File

@@ -736,13 +736,17 @@ protected override void Tick()
}
else
{
// 正常状态:应用中子通量效率100%通量时5倍速度
// 孵化进度:受活性效率影响100%活性时5倍速度
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
incubationProgress += fluxSpeed;
// 质量进度也受中子通量影响
float fluxQuality = QualityMultiplier * FluxEfficiency * 5f;
qualityProgress += fluxSpeed * fluxQuality;
// 品质进度:独立增长,低活性时有额外加速
// - 高活性 = 快速孵化,品质正常速度
// - 低活性 = 慢速孵化,品质加速累积
// 加速公式1 + (1 - flux) * 0.5即活性0%→1.5x活性100%→1x
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
}
if (incubationProgress >= incubationDuration)
@@ -752,108 +756,80 @@ protected override void Tick()
}
}
// 自动模式:智能计算最优中子通量
// 目标:在资源允许的情况下,尽可能快速完成孵化
// 自动模式:方案C - 资源优先 + 品质保底
// 目标:在资源允许的情况下追求最高品质
private void CalculateAutoFlux()
{
if (!autoFluxMode) return;
float targetFlux = 1.0f; // 默认100%
// 基础目标50%平衡点(孵化和品质同时完成)
float targetFlux = 0.5f;
// === 策略1根据孵化剩余时间优化 ===
if (isIncubating && incubationDuration > 0)
if (isIncubating && incubationDuration > 0 && qualityTotal > 0)
{
float remainingProgress = incubationDuration - incubationProgress;
float remainingDays = remainingProgress / (60000f * SpeedMultiplier);
// 计算当前进度百分比
float incubationPercent = incubationProgress / incubationDuration;
float qualityPercent = qualityProgress / qualityTotal;
// 计算虫蜜能维持多少天(按当前通量)
float fuelDays = float.MaxValue;
if (FuelComp != null && FuelComp.Fuel > 0)
// === 策略1品质已满时全速 ===
if (qualityPercent >= 0.95f)
{
// 消耗率 = 50 * flux² 每天
float currentConsumption = 50f * neutronFlux * neutronFlux;
fuelDays = currentConsumption > 0 ? FuelComp.Fuel / currentConsumption : float.MaxValue;
targetFlux = 1.0f;
}
// 计算维护能维持多少天
float maintenanceDays = float.MaxValue;
if (MaintenanceComp != null)
// === 策略2孵化快完成但品质不够时降速追品质 ===
else if (incubationPercent > 0.8f && qualityPercent < 0.6f)
{
float maintenance = MaintenanceComp.CurrentMaintenance;
float decayPerDay = MaintenanceComp.Props.maintenanceDecayPerDay;
maintenanceDays = decayPerDay > 0 ? maintenance / decayPerDay : float.MaxValue;
targetFlux = 0.25f;
}
// 找到瓶颈资源
float minResourceDays = Mathf.Min(fuelDays, maintenanceDays);
// 安全边际:资源至少要能维持 剩余孵化天数 + 0.5天
float requiredDays = remainingDays + 0.5f;
if (minResourceDays < requiredDays && minResourceDays > 0)
// === 策略3品质落后时降速 ===
else if (qualityPercent < incubationPercent - 0.15f)
{
// 资源不足,需要降低通量
// 用二分法找到刚好能完成孵化的通量
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; // 需要更低
// 品质落后超过15%,降低活性追品质
targetFlux = 0.35f;
}
targetFlux = lowFlux;
// === 策略4品质领先时可以加速 ===
else if (qualityPercent > incubationPercent + 0.1f)
{
targetFlux = 0.7f;
}
}
// === 策略2紧急保护 ===
// 虫蜜极低时紧急降速
if (FuelComp != null && FuelComp.Fuel < 5f)
// === 资源紧张保护 ===
// 虫蜜紧张
if (FuelComp != null && FuelComp.Fuel < 3f)
{
targetFlux = Mathf.Min(targetFlux, 0.3f);
targetFlux = Mathf.Min(targetFlux, 0.25f);
}
// 维护极低时紧急降速
// 维护紧张
if (MaintenanceComp != null)
{
float maintenancePercent = MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance;
if (maintenancePercent < 0.15f)
if (maintenancePercent < 0.2f)
{
targetFlux = Mathf.Min(targetFlux, 0.2f);
}
}
// === 策略3资源充足时全速 ===
bool fuelAbundant = FuelComp == null || FuelComp.Fuel > FuelComp.Props.fuelCapacity * 0.8f;
// === 资源充足时可以更激进 ===
bool fuelAbundant = FuelComp == null || FuelComp.Fuel > FuelComp.Props.fuelCapacity * 0.7f;
bool maintenanceAbundant = MaintenanceComp == null ||
MaintenanceComp.CurrentMaintenance > MaintenanceComp.Props.maxMaintenance * 0.7f;
MaintenanceComp.CurrentMaintenance > MaintenanceComp.Props.maxMaintenance * 0.6f;
if (fuelAbundant && maintenanceAbundant)
// 资源充足且品质已满,全速冲刺
if (fuelAbundant && maintenanceAbundant && qualityProgress >= qualityTotal * 0.95f)
{
targetFlux = 1.0f;
}
// 平滑调节(避免突变,每次最多调整5%
float adjustSpeed = 0.05f;
// 平滑调节(每次最多调整3%,更平滑
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.05f, 1.0f); // 最低5%防止完全停止
neutronFlux = Mathf.Clamp(neutronFlux, 0.1f, 1.0f); // 最低10%
}
// 应用质量效果到生成的pawn

View File

@@ -23,8 +23,6 @@ namespace ArachnaeSwarm
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;
@@ -68,7 +66,7 @@ namespace ArachnaeSwarm
// === 竖向滑动条 ===
float barWidth = 32f;
float barHeight = 90f; // 增加高度
float barHeight = 90f;
float barX = innerRect.x + 8f;
float barY = innerRect.y + 24f;
Rect barRect = new Rect(barX, barY, barWidth, barHeight);
@@ -100,45 +98,38 @@ namespace ArachnaeSwarm
// 绘制边框
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);
// === 使用 Unity 原生滑块实现拖动 ===
// 滑块放在进度条右侧
Rect sliderRect = new Rect(barRect.xMax + 2f, barRect.y, 16f, barRect.height);
// 绘制三角形光标(指向左边)
GUI.color = isDragging ? new Color(1f, 0.8f, 0.3f, 1f) : new Color(0.9f, 0.9f, 0.9f, 1f);
// 创建自定义的滑块样式
GUIStyle sliderStyle = new GUIStyle();
GUIStyle thumbStyle = new GUIStyle();
thumbStyle.fixedWidth = 14f;
thumbStyle.fixedHeight = 10f;
thumbStyle.normal.background = Texture2D.whiteTexture;
// 使用 VerticalSlider注意上=max, 下=min
float newFlux = GUI.VerticalSlider(sliderRect, displayFlux, 1f, 0f);
// 如果值改变了,更新
if (Mathf.Abs(newFlux - displayFlux) > 0.001f)
{
ootheca.SetNeutronFlux(newFlux);
}
// === 光标指示器 ===
float cursorY = barRect.yMax - fillHeight;
GUI.color = 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 w = 10f * (1f - Mathf.Abs(i - 3) / 4f);
float y = cursorY - 3.5f + i;
Rect lineRect = new Rect(cursorRect.x, y, w, 1f);
Rect lineRect = new Rect(barRect.xMax + 2f, 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;