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"), MaxMaintenance.ToString("F1"),
MaintenancePercentage.ToString("P1")); 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) if (NeedsMaintenance)
@@ -219,6 +220,27 @@ namespace ArachnaeSwarm
return text; 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命令按钮- 只保留调试功能 // 获取Gizmos命令按钮- 只保留调试功能
public override IEnumerable<Gizmo> CompGetGizmosExtra() public override IEnumerable<Gizmo> CompGetGizmosExtra()
{ {

View File

@@ -736,13 +736,17 @@ protected override void Tick()
} }
else else
{ {
// 正常状态:应用中子通量效率100%通量时5倍速度 // 孵化进度:受活性效率影响100%活性时5倍速度
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f; float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
incubationProgress += fluxSpeed; 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) if (incubationProgress >= incubationDuration)
@@ -752,108 +756,80 @@ protected override void Tick()
} }
} }
// 自动模式:智能计算最优中子通量 // 自动模式:方案C - 资源优先 + 品质保底
// 目标:在资源允许的情况下,尽可能快速完成孵化 // 目标:在资源允许的情况下追求最高品质
private void CalculateAutoFlux() private void CalculateAutoFlux()
{ {
if (!autoFluxMode) return; if (!autoFluxMode) return;
float targetFlux = 1.0f; // 默认100% // 基础目标50%平衡点(孵化和品质同时完成)
float targetFlux = 0.5f;
// === 策略1根据孵化剩余时间优化 === if (isIncubating && incubationDuration > 0 && qualityTotal > 0)
if (isIncubating && incubationDuration > 0)
{ {
float remainingProgress = incubationDuration - incubationProgress; // 计算当前进度百分比
float remainingDays = remainingProgress / (60000f * SpeedMultiplier); float incubationPercent = incubationProgress / incubationDuration;
float qualityPercent = qualityProgress / qualityTotal;
// 计算虫蜜能维持多少天(按当前通量) // === 策略1品质已满时全速 ===
float fuelDays = float.MaxValue; if (qualityPercent >= 0.95f)
if (FuelComp != null && FuelComp.Fuel > 0)
{ {
// 消耗率 = 50 * flux² 每天 targetFlux = 1.0f;
float currentConsumption = 50f * neutronFlux * neutronFlux;
fuelDays = currentConsumption > 0 ? FuelComp.Fuel / currentConsumption : float.MaxValue;
} }
// === 策略2孵化快完成但品质不够时降速追品质 ===
// 计算维护能维持多少天 else if (incubationPercent > 0.8f && qualityPercent < 0.6f)
float maintenanceDays = float.MaxValue;
if (MaintenanceComp != null)
{ {
float maintenance = MaintenanceComp.CurrentMaintenance; targetFlux = 0.25f;
float decayPerDay = MaintenanceComp.Props.maintenanceDecayPerDay;
maintenanceDays = decayPerDay > 0 ? maintenance / decayPerDay : float.MaxValue;
} }
// === 策略3品质落后时降速 ===
// 找到瓶颈资源 else if (qualityPercent < incubationPercent - 0.15f)
float minResourceDays = Mathf.Min(fuelDays, maintenanceDays);
// 安全边际:资源至少要能维持 剩余孵化天数 + 0.5天
float requiredDays = remainingDays + 0.5f;
if (minResourceDays < requiredDays && minResourceDays > 0)
{ {
// 资源不足,需要降低通量 // 品质落后超过15%,降低活性追品质
// 用二分法找到刚好能完成孵化的通量 targetFlux = 0.35f;
float lowFlux = 0.1f; }
float highFlux = neutronFlux; // === 策略4品质领先时可以加速 ===
else if (qualityPercent > incubationPercent + 0.1f)
for (int i = 0; i < 8; i++) // 8次迭代足够精确 {
{ targetFlux = 0.7f;
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) if (FuelComp != null && FuelComp.Fuel < 3f)
{ {
targetFlux = Mathf.Min(targetFlux, 0.3f); targetFlux = Mathf.Min(targetFlux, 0.25f);
} }
// 维护极低时紧急降速 // 维护紧张
if (MaintenanceComp != null) if (MaintenanceComp != null)
{ {
float maintenancePercent = MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance; float maintenancePercent = MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance;
if (maintenancePercent < 0.15f) if (maintenancePercent < 0.2f)
{ {
targetFlux = Mathf.Min(targetFlux, 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 || 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; targetFlux = 1.0f;
} }
// 平滑调节(避免突变,每次最多调整5% // 平滑调节(每次最多调整3%,更平滑
float adjustSpeed = 0.05f; float adjustSpeed = 0.03f;
if (neutronFlux < targetFlux) if (neutronFlux < targetFlux)
neutronFlux = Mathf.Min(neutronFlux + adjustSpeed, targetFlux); neutronFlux = Mathf.Min(neutronFlux + adjustSpeed, targetFlux);
else if (neutronFlux > targetFlux) else if (neutronFlux > targetFlux)
neutronFlux = Mathf.Max(neutronFlux - adjustSpeed, 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 // 应用质量效果到生成的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 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 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) public Gizmo_NeutronFlux(Building_Ootheca ootheca)
{ {
this.ootheca = ootheca; this.ootheca = ootheca;
@@ -68,7 +66,7 @@ namespace ArachnaeSwarm
// === 竖向滑动条 === // === 竖向滑动条 ===
float barWidth = 32f; float barWidth = 32f;
float barHeight = 90f; // 增加高度 float barHeight = 90f;
float barX = innerRect.x + 8f; float barX = innerRect.x + 8f;
float barY = innerRect.y + 24f; float barY = innerRect.y + 24f;
Rect barRect = new Rect(barX, barY, barWidth, barHeight); Rect barRect = new Rect(barX, barY, barWidth, barHeight);
@@ -100,45 +98,38 @@ namespace ArachnaeSwarm
// 绘制边框 // 绘制边框
Widgets.DrawBox(barRect, 1); Widgets.DrawBox(barRect, 1);
// === 可拖动光标(三角形指示器)=== // === 使用 Unity 原生滑块实现拖动 ===
float cursorY = barRect.yMax - fillHeight; // 滑块放在进度条右侧
float cursorWidth = 12f; Rect sliderRect = new Rect(barRect.xMax + 2f, barRect.y, 16f, barRect.height);
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); 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++) 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; 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.DrawTexture(lineRect, CursorTex);
} }
GUI.color = Color.white; 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 infoX = barRect.xMax + 18f;
float infoWidth = innerRect.xMax - infoX; float infoWidth = innerRect.xMax - infoX;