This commit is contained in:
2025-12-23 14:47:31 +08:00
parent 073e0fa1e8
commit 9af5966135
4 changed files with 187 additions and 136 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -33,16 +33,26 @@ namespace ArachnaeSwarm
private float qualityProgress = 0f;
private float qualityTotal = 0f;
// ======= 中子通量系统 =======
// ======= 孵化活性系统 =======
private float neutronFlux = 0.5f; // 0-1, 默认50%
private bool autoFluxMode = true; // 自动模式
private FluxMode fluxMode = FluxMode.Balance; // 默认平衡模式
private CompRefuelableNutrition fuelComp; // 燃料组件缓存
private Comp_SwarmMaintenance maintenanceComp; // 维护组件缓存
// 活性模式枚举
public enum FluxMode
{
Manual, // 手动:完全手动控制
Quality, // 品质优先:低活性,追求高品质
Balance, // 平衡:自动平衡速度和品质
Speed // 速度优先:高活性,快速孵化
}
// 孵化活性公开属性非孵化时锁定为0
public float NeutronFlux => isIncubating ? neutronFlux : 0f;
public float RawFlux => neutronFlux; // 原始值用于 Gizmo 显示
public bool AutoFluxMode => autoFluxMode;
public FluxMode CurrentFluxMode => fluxMode;
public bool IsAutoMode => fluxMode != FluxMode.Manual;
// 获取燃料组件
public CompRefuelableNutrition FuelComp => fuelComp ?? (fuelComp = this.TryGetComp<CompRefuelableNutrition>());
@@ -57,16 +67,48 @@ namespace ArachnaeSwarm
// 是否正在孵化(公开属性)
public bool IsIncubating => isIncubating;
// 设置中子通量
// 设置活性值
public void SetNeutronFlux(float value)
{
neutronFlux = Mathf.Clamp01(value);
}
// 切换自动模式
public void ToggleAutoMode()
// 切换模式(循环切换)
public void CycleFluxMode()
{
autoFluxMode = !autoFluxMode;
fluxMode = (FluxMode)(((int)fluxMode + 1) % 4);
}
// 设置模式
public void SetFluxMode(FluxMode mode)
{
fluxMode = mode;
}
// 获取模式名称
public string GetModeName()
{
switch (fluxMode)
{
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 "?";
}
}
// 缓存的ModExtension
@@ -694,7 +736,7 @@ protected override void Tick()
if (isIncubating)
{
// 自动模式计算每250ticks更新一次
if (autoFluxMode && Find.TickManager.TicksGame % 250 == 0)
if (IsAutoMode && Find.TickManager.TicksGame % 250 == 0)
{
CalculateAutoFlux();
}
@@ -756,80 +798,88 @@ protected override void Tick()
}
}
// 自动模式:方案C - 资源优先 + 品质保底
// 目标:在资源允许的情况下追求最高品质
// 自动模式:根据选择的模式计算活性
private void CalculateAutoFlux()
{
if (!autoFluxMode) return;
// 手动模式不自动调节
if (fluxMode == FluxMode.Manual) return;
// 基础目标50%平衡点(孵化和品质同时完成)
float targetFlux = 0.5f;
if (isIncubating && incubationDuration > 0 && qualityTotal > 0)
// 计算进度百分比
float incubationPercent = incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
float qualityPercent = qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
switch (fluxMode)
{
// 计算当前进度百分比
float incubationPercent = incubationProgress / incubationDuration;
float qualityPercent = qualityProgress / qualityTotal;
// === 策略1品质已满时全速 ===
if (qualityPercent >= 0.95f)
{
targetFlux = 1.0f;
}
// === 策略2孵化快完成但品质不够时降速追品质 ===
else if (incubationPercent > 0.8f && qualityPercent < 0.6f)
{
targetFlux = 0.25f;
}
// === 策略3品质落后时降速 ===
else if (qualityPercent < incubationPercent - 0.15f)
{
// 品质落后超过15%,降低活性追品质
targetFlux = 0.35f;
}
// === 策略4品质领先时可以加速 ===
else if (qualityPercent > incubationPercent + 0.1f)
{
targetFlux = 0.7f;
}
case FluxMode.Quality:
// 品质优先低活性追求100%品质
targetFlux = 0.3f;
// 品质已满时加速
if (qualityPercent >= 0.95f) targetFlux = 0.8f;
break;
case FluxMode.Speed:
// 速度优先:高活性,快速完成
targetFlux = 0.9f;
// 资源紧张时稍微降低
if (FuelComp != null && FuelComp.Fuel < 5f) targetFlux = 0.6f;
break;
case FluxMode.Balance:
default:
// 平衡模式:动态调整,追求两者同时完成
targetFlux = 0.5f;
if (isIncubating)
{
// 品质已满时全速
if (qualityPercent >= 0.95f)
{
targetFlux = 1.0f;
}
// 孵化快完成但品质不够,降速追品质
else if (incubationPercent > 0.8f && qualityPercent < 0.6f)
{
targetFlux = 0.25f;
}
// 品质落后,降速
else if (qualityPercent < incubationPercent - 0.15f)
{
targetFlux = 0.35f;
}
// 品质领先,加速
else if (qualityPercent > incubationPercent + 0.1f)
{
targetFlux = 0.7f;
}
}
break;
}
// === 资源紧张保护 ===
// 虫蜜紧张
if (FuelComp != null && FuelComp.Fuel < 3f)
// === 资源紧张保护(所有自动模式通用)===
if (FuelComp != null && FuelComp.Fuel < 2f)
{
targetFlux = Mathf.Min(targetFlux, 0.25f);
targetFlux = Mathf.Min(targetFlux, 0.2f);
}
// 维护紧张
if (MaintenanceComp != null)
{
float maintenancePercent = MaintenanceComp.CurrentMaintenance / MaintenanceComp.Props.maxMaintenance;
if (maintenancePercent < 0.2f)
if (maintenancePercent < 0.15f)
{
targetFlux = Mathf.Min(targetFlux, 0.2f);
targetFlux = Mathf.Min(targetFlux, 0.15f);
}
}
// === 资源充足时可以更激进 ===
bool fuelAbundant = FuelComp == null || FuelComp.Fuel > FuelComp.Props.fuelCapacity * 0.7f;
bool maintenanceAbundant = MaintenanceComp == null ||
MaintenanceComp.CurrentMaintenance > MaintenanceComp.Props.maxMaintenance * 0.6f;
// 资源充足且品质已满,全速冲刺
if (fuelAbundant && maintenanceAbundant && qualityProgress >= qualityTotal * 0.95f)
{
targetFlux = 1.0f;
}
// 平滑调节每次最多调整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.1f, 1.0f); // 最低10%
neutronFlux = Mathf.Clamp(neutronFlux, 0.1f, 1.0f);
}
// 应用质量效果到生成的pawn
@@ -1058,9 +1108,9 @@ private void CalculateAutoFlux()
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);
Scribe_Values.Look(ref fluxMode, "fluxMode", FluxMode.Balance);
}
}
}

View File

@@ -48,23 +48,35 @@ namespace ArachnaeSwarm
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);
Rect modeRect = new Rect(innerRect.xMax - buttonSize, innerRect.y, buttonSize, buttonSize);
// 根据模式显示不同颜色
Color modeColor;
switch (ootheca.CurrentFluxMode)
{
case Building_Ootheca.FluxMode.Manual: modeColor = new Color(0.5f, 0.5f, 0.5f, 0.9f); break;
case Building_Ootheca.FluxMode.Quality: modeColor = new Color(0.3f, 0.6f, 0.9f, 0.9f); break;
case Building_Ootheca.FluxMode.Balance: modeColor = new Color(0.2f, 0.7f, 0.2f, 0.9f); break;
case Building_Ootheca.FluxMode.Speed: modeColor = new Color(0.9f, 0.5f, 0.2f, 0.9f); break;
default: modeColor = Color.gray; break;
}
GUI.DrawTexture(modeRect, SolidColorMaterials.NewSolidColorTexture(modeColor));
Widgets.DrawBox(modeRect, 1);
Text.Font = GameFont.Tiny;
Text.Anchor = TextAnchor.MiddleCenter;
GUI.color = Color.white;
Widgets.Label(autoRect, ootheca.AutoFluxMode ? "A" : "M");
Widgets.Label(modeRect, ootheca.GetModeShort());
if (Widgets.ButtonInvisible(autoRect))
if (Widgets.ButtonInvisible(modeRect))
{
ootheca.ToggleAutoMode();
ootheca.CycleFluxMode();
}
// === 竖向滑动条 ===
// === 竖向计量条 ===
float barWidth = 32f;
float barHeight = 90f;
float barX = innerRect.x + 8f;
@@ -98,40 +110,40 @@ namespace ArachnaeSwarm
// 绘制边框
Widgets.DrawBox(barRect, 1);
// === 使用 Unity 原生滑块实现拖动 ===
// 滑块放在进度条右侧
Rect sliderRect = new Rect(barRect.xMax + 2f, barRect.y, 16f, barRect.height);
// === 直接在计量条上点击/拖动 ===
int controlId = GUIUtility.GetControlID(FocusType.Passive);
Event evt = Event.current;
// 创建自定义的滑块样式
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)
switch (evt.GetTypeForControl(controlId))
{
ootheca.SetNeutronFlux(newFlux);
case EventType.MouseDown:
if (barRect.Contains(evt.mousePosition) && evt.button == 0)
{
GUIUtility.hotControl = controlId;
UpdateFluxFromMouse(barRect, evt.mousePosition.y);
evt.Use();
}
break;
case EventType.MouseDrag:
if (GUIUtility.hotControl == controlId)
{
UpdateFluxFromMouse(barRect, evt.mousePosition.y);
evt.Use();
}
break;
case EventType.MouseUp:
if (GUIUtility.hotControl == controlId)
{
GUIUtility.hotControl = 0;
evt.Use();
}
break;
}
// === 光标指示器 ===
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 = 10f * (1f - Mathf.Abs(i - 3) / 4f);
float y = cursorY - 3.5f + i;
Rect lineRect = new Rect(barRect.xMax + 2f, y, w, 1f);
GUI.DrawTexture(lineRect, CursorTex);
}
GUI.color = Color.white;
// === 右侧信息显示 ===
float infoX = barRect.xMax + 18f;
float infoX = barRect.xMax + 6f;
float infoWidth = innerRect.xMax - infoX;
Text.Font = GameFont.Small;
@@ -175,9 +187,8 @@ namespace ArachnaeSwarm
return new GizmoResult(GizmoState.Clear);
}
private void UpdateFluxFromMouse(Rect barRect)
private void UpdateFluxFromMouse(Rect barRect, float mouseY)
{
float mouseY = Event.current.mousePosition.y;
float percent = 1f - (mouseY - barRect.y) / barRect.height;
ootheca.SetNeutronFlux(Mathf.Clamp01(percent));
}
@@ -186,55 +197,45 @@ namespace ArachnaeSwarm
{
var sb = new System.Text.StringBuilder();
// 标题
sb.AppendLine("【孵化活性控制器】");
sb.AppendLine("【孵化活性】");
sb.AppendLine();
// 核心机制(简洁明了)
sb.AppendLine("▸ 活性越高 → 孵化越快");
sb.AppendLine("▸ 活性越低 → 品质越高");
sb.AppendLine();
// 当前状态
sb.AppendLine("═══ 当前状态 ═══");
sb.AppendLine($"活性: {(ootheca.NeutronFlux * 100f):0}%");
sb.AppendLine($"效率: {(ootheca.FluxEfficiency * 100f):0}% (活性²)");
sb.AppendLine($"当前活性: {(ootheca.RawFlux * 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($"模式: {ootheca.GetModeName()}");
switch (ootheca.CurrentFluxMode)
{
case Building_Ootheca.FluxMode.Manual:
sb.AppendLine(" 手动调节活性");
break;
case Building_Ootheca.FluxMode.Quality:
sb.AppendLine(" 低活性,追求品质");
break;
case Building_Ootheca.FluxMode.Balance:
sb.AppendLine(" 自动平衡速度和品质");
break;
case Building_Ootheca.FluxMode.Speed:
sb.AppendLine(" 高活性,快速孵化");
break;
}
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("• 虫蜜耗尽也会进入休眠");
// 操作
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>");
sb.AppendLine("<color=red>⚠ 休眠中,品质下降!</color>");
}
return sb.ToString().TrimEndNewlines();