feat: 新增带通量控制、队列孵化和品质系统的督虫生成组件及相关UI。
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -8,18 +8,22 @@ using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
// 带状态和品质的物品订单(通量品质系统)
|
||||
// 带状态和品质的物品订单(与 Building_Ootheca 统一的累计进度模式)
|
||||
public class QueuedItemOrder : IExposable
|
||||
{
|
||||
public ProcessDef process;
|
||||
public string tempThingDefName;
|
||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||
public int productionUntilTick = -1;
|
||||
|
||||
// 进度系统(累计模式,与 Building_Ootheca 统一)
|
||||
public float incubationProgress = 0f;
|
||||
public float incubationDuration = 0f;
|
||||
|
||||
// 通量品质系统
|
||||
public float qualityProgress = 0f;
|
||||
public float qualityTotal = 0f;
|
||||
|
||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
||||
|
||||
public void ExposeData()
|
||||
@@ -30,7 +34,8 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
Scribe_Values.Look(ref tempThingDefName, "thingDefName");
|
||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||
Scribe_Values.Look(ref productionUntilTick, "productionUntilTick", -1);
|
||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
||||
}
|
||||
@@ -159,10 +164,8 @@ namespace ArachnaeSwarm
|
||||
|
||||
private float GetProgress(QueuedItemOrder order)
|
||||
{
|
||||
if (order.status != OrderStatus.Incubating || order.process == null) return 0f;
|
||||
int totalTicks = order.process.productionTicks;
|
||||
int elapsed = totalTicks - order.productionUntilTick;
|
||||
return totalTicks > 0 ? Mathf.Clamp01((float)elapsed / totalTicks) : 0f;
|
||||
// 使用累计进度模式
|
||||
return order.ProgressPercent;
|
||||
}
|
||||
|
||||
private QualityCategory GetQualityCategory(QueuedItemOrder order)
|
||||
@@ -253,8 +256,10 @@ namespace ArachnaeSwarm
|
||||
if (waitingOrder != null)
|
||||
{
|
||||
waitingOrder.status = OrderStatus.Incubating;
|
||||
waitingOrder.productionUntilTick = waitingOrder.process.productionTicks;
|
||||
waitingOrder.qualityTotal = waitingOrder.process.productionTicks;
|
||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
||||
waitingOrder.incubationDuration = waitingOrder.process.productionTicks;
|
||||
waitingOrder.incubationProgress = 0f;
|
||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
||||
waitingOrder.qualityProgress = 0f;
|
||||
}
|
||||
assignedLarvae.Remove(larva);
|
||||
@@ -286,50 +291,43 @@ namespace ArachnaeSwarm
|
||||
CalculateAutoFlux();
|
||||
}
|
||||
|
||||
// 消耗燃料
|
||||
// 消耗燃料(只有活性>0时)
|
||||
if (IsIncubating && FuelComp != null && neutronFlux > 0.01f)
|
||||
{
|
||||
float fuelPerTick = (80f * FluxEfficiency * IncubatingCount) / 60000f;
|
||||
FuelComp.ConsumeFuel(fuelPerTick);
|
||||
}
|
||||
|
||||
// 处理正在生产的订单
|
||||
if (hasFuel && !IsDormant)
|
||||
// 进度和品质处理(与 Building_Ootheca 统一)
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
{
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating && o.productionUntilTick > 0))
|
||||
if (IsDormant)
|
||||
{
|
||||
// 进度推进
|
||||
float extraProgress = fluxSpeed - 1f;
|
||||
if (extraProgress > 0)
|
||||
{
|
||||
int extraTicks = Mathf.FloorToInt(extraProgress);
|
||||
if (Rand.Value < (extraProgress - extraTicks)) extraTicks++;
|
||||
order.productionUntilTick = Mathf.Max(0, order.productionUntilTick - extraTicks);
|
||||
}
|
||||
|
||||
// 通量品质系统:低通量时品质增长快
|
||||
// 休眠时:不推进进度,品质衰减
|
||||
float qualityDecay = (order.qualityTotal * 0.1f) / 60000f;
|
||||
order.qualityProgress = Mathf.Max(0f, order.qualityProgress - qualityDecay);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常工作:推进进度和品质
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||
|
||||
// 进度推进(累计模式)
|
||||
order.incubationProgress += fluxSpeed;
|
||||
|
||||
// 品质增长 - 低活性时品质增长更快
|
||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||
float qualityGain = speedFactor * qualityBonus;
|
||||
order.qualityProgress = Mathf.Min(order.qualityProgress + qualityGain, order.qualityTotal);
|
||||
}
|
||||
}
|
||||
else if (IsDormant)
|
||||
{
|
||||
// 休眠时品质下降
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
{
|
||||
float qualityDecay = (order.qualityTotal * 0.1f) / 60000f;
|
||||
order.qualityProgress = Mathf.Max(0f, order.qualityProgress - qualityDecay);
|
||||
}
|
||||
}
|
||||
|
||||
// 完成订单
|
||||
// 完成检查(进度达到持续时间时完成)
|
||||
orders.RemoveAll(order =>
|
||||
{
|
||||
if (order.status == OrderStatus.Incubating && order.productionUntilTick == 0)
|
||||
if (order.status == OrderStatus.Incubating &&
|
||||
order.incubationProgress >= order.incubationDuration)
|
||||
{
|
||||
FinishProduction(order);
|
||||
return true;
|
||||
@@ -447,17 +445,23 @@ namespace ArachnaeSwarm
|
||||
var options = new List<FloatMenuOption>();
|
||||
foreach (var process in Processes)
|
||||
{
|
||||
Texture2D icon = process.thingDef?.uiIcon;
|
||||
string label = process.thingDef.LabelCap;
|
||||
|
||||
if (process.requiredResearch != null && !process.requiredResearch.IsFinished)
|
||||
{
|
||||
options.Add(new FloatMenuOption(process.thingDef.LabelCap + " (需要研究: " + process.requiredResearch.LabelCap + ")", null));
|
||||
label += $" (需要研究: {process.requiredResearch.LabelCap})";
|
||||
options.Add(new FloatMenuOption(label, null, icon, Color.white));
|
||||
}
|
||||
else
|
||||
{
|
||||
var capturedProcess = process;
|
||||
options.Add(new FloatMenuOption(process.thingDef.LabelCap, () => {
|
||||
float days = capturedProcess.productionTicks / 60000f;
|
||||
label += $" ({days:F1}天)";
|
||||
options.Add(new FloatMenuOption(label, () => {
|
||||
AddOrder(capturedProcess);
|
||||
if (orders.Count < Props.productionQueueLimit) ShowOrderMenu();
|
||||
}));
|
||||
}, icon, Color.white));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,21 +28,26 @@ namespace ArachnaeSwarm
|
||||
// 带状态和品质的督虫订单
|
||||
public class QueuedPawnOrder : IExposable
|
||||
{
|
||||
public IncubationConfig config; // 使用 IncubationConfig 而不是 QueuedPawnSpawnEntry
|
||||
public IncubationConfig config;
|
||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||
public int spawnUntilTick = -1;
|
||||
|
||||
// 进度系统(与 Building_Ootheca 统一)
|
||||
public float incubationProgress = 0f;
|
||||
public float incubationDuration = 0f;
|
||||
|
||||
// 品质系统
|
||||
public float qualityProgress = 0f;
|
||||
public float qualityTotal = 0f;
|
||||
|
||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Deep.Look(ref config, "config");
|
||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||
Scribe_Values.Look(ref spawnUntilTick, "spawnUntilTick", -1);
|
||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
||||
}
|
||||
@@ -154,8 +159,8 @@ namespace ArachnaeSwarm
|
||||
status = order.status,
|
||||
progress = prodProgress,
|
||||
qualityProgress = order.QualityPercent,
|
||||
remainingTime = order.status == OrderStatus.Incubating && order.spawnUntilTick > 0
|
||||
? (order.spawnUntilTick - Find.TickManager.TicksGame).ToStringTicksToPeriod()
|
||||
remainingTime = order.status == OrderStatus.Incubating
|
||||
? ((int)GetRemainingTicks(order)).ToStringTicksToPeriod()
|
||||
: "等待中",
|
||||
estimatedQuality = GetEstimatedQuality(order.QualityPercent)
|
||||
});
|
||||
@@ -165,11 +170,17 @@ namespace ArachnaeSwarm
|
||||
|
||||
private float GetProgress(QueuedPawnOrder order)
|
||||
{
|
||||
if (order.status != OrderStatus.Incubating || order.spawnUntilTick <= 0 || order.config == null) return 0f;
|
||||
int totalTicks = Mathf.RoundToInt(order.config.daysRequired * 60000);
|
||||
int startTick = order.spawnUntilTick - totalTicks;
|
||||
int elapsed = Find.TickManager.TicksGame - startTick;
|
||||
return totalTicks > 0 ? Mathf.Clamp01((float)elapsed / totalTicks) : 0f;
|
||||
// 使用累计进度模式
|
||||
return order.ProgressPercent;
|
||||
}
|
||||
|
||||
private float GetRemainingTicks(QueuedPawnOrder order)
|
||||
{
|
||||
if (order.status != OrderStatus.Incubating || order.incubationDuration <= 0) return 0f;
|
||||
float remaining = order.incubationDuration - order.incubationProgress;
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||
return fluxSpeed > 0 ? remaining / fluxSpeed : remaining;
|
||||
}
|
||||
|
||||
private string GetEstimatedQuality(float qualityPercent)
|
||||
@@ -260,9 +271,10 @@ namespace ArachnaeSwarm
|
||||
if (waitingOrder != null && waitingOrder.config != null)
|
||||
{
|
||||
waitingOrder.status = OrderStatus.Incubating;
|
||||
int totalTicks = Mathf.RoundToInt(waitingOrder.config.daysRequired * 60000);
|
||||
waitingOrder.spawnUntilTick = Find.TickManager.TicksGame + totalTicks;
|
||||
waitingOrder.qualityTotal = totalTicks;
|
||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
||||
waitingOrder.incubationDuration = waitingOrder.config.daysRequired * 60000f;
|
||||
waitingOrder.incubationProgress = 0f;
|
||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
||||
waitingOrder.qualityProgress = 0f;
|
||||
}
|
||||
assignedLarvae.Remove(larva);
|
||||
@@ -293,38 +305,43 @@ namespace ArachnaeSwarm
|
||||
CalculateAutoFlux();
|
||||
}
|
||||
|
||||
// 消耗燃料(只有活性>0时)
|
||||
if (IsIncubating && FuelComp != null && neutronFlux > 0.01f)
|
||||
{
|
||||
float fuelPerTick = (50f * FluxEfficiency * IncubatingCount) / 60000f;
|
||||
FuelComp.ConsumeFuel(fuelPerTick);
|
||||
}
|
||||
|
||||
if (hasFuel && !IsDormant)
|
||||
// 进度和品质处理(与 Building_Ootheca 统一)
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
{
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
if (IsDormant)
|
||||
{
|
||||
float extraProgress = fluxSpeed - 1f;
|
||||
if (extraProgress > 0)
|
||||
{
|
||||
int extraTicks = Mathf.FloorToInt(extraProgress);
|
||||
if (Rand.Value < (extraProgress - extraTicks)) extraTicks++;
|
||||
order.spawnUntilTick -= extraTicks;
|
||||
}
|
||||
|
||||
// 休眠时:不推进进度,品质衰减
|
||||
float qualityDecay = (order.qualityTotal * 0.1f) / 60000f;
|
||||
order.qualityProgress = Mathf.Max(0f, order.qualityProgress - qualityDecay);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常工作:推进进度和品质
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||
|
||||
// 进度推进(累计模式)
|
||||
order.incubationProgress += fluxSpeed;
|
||||
|
||||
// 品质增长 - 低活性时品质增长更快
|
||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||
float qualityGain = speedFactor * qualityBonus;
|
||||
order.qualityProgress = Mathf.Min(order.qualityProgress + qualityGain, order.qualityTotal);
|
||||
}
|
||||
}
|
||||
|
||||
// 完成检查(进度达到持续时间时完成)
|
||||
orders.RemoveAll(order =>
|
||||
{
|
||||
if (order.status == OrderStatus.Incubating &&
|
||||
order.spawnUntilTick > 0 &&
|
||||
Find.TickManager.TicksGame >= order.spawnUntilTick)
|
||||
order.incubationProgress >= order.incubationDuration)
|
||||
{
|
||||
CompleteOrder(order);
|
||||
return true;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using Verse.Sound; // Ensure this is present
|
||||
using Verse.Sound;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
@@ -73,5 +74,35 @@ namespace ArachnaeSwarm
|
||||
!(gizmo is Designator_Build designator && designator.PlacingDef == ThingDefOf.Hopper)
|
||||
);
|
||||
}
|
||||
|
||||
// 覆盖 GetInspectString 以隐藏电力和进料口相关的提示
|
||||
public override string GetInspectString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
// 只显示燃料信息,不显示电力相关信息
|
||||
if (nutritionComp != null && dispenserProps != null)
|
||||
{
|
||||
float fuel = nutritionComp.Fuel;
|
||||
float cost = dispenserProps.nutritionCostPerDispense;
|
||||
int mealsAvailable = (int)(fuel / cost);
|
||||
sb.AppendLine($"可制作: {mealsAvailable} 份");
|
||||
}
|
||||
|
||||
// 添加其他 Comp 的信息,但排除 CompPower 类型
|
||||
foreach (var comp in AllComps)
|
||||
{
|
||||
// 跳过电力相关的组件
|
||||
if (comp is CompPower) continue;
|
||||
|
||||
string compString = comp.CompInspectStringExtra();
|
||||
if (!compString.NullOrEmpty())
|
||||
{
|
||||
sb.AppendLine(compString);
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEndNewlines();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
@@ -167,4 +168,20 @@ namespace ArachnaeSwarm
|
||||
return bestDispenser;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Patch to exclude our custom dispenser from the "needs hopper" alert.
|
||||
/// The Alert checks all ThingsInGroup(ThingRequestGroup.FoodDispenser) and warns if they don't have adjacent hoppers.
|
||||
/// We filter out our custom dispenser from the result.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(Alert_PasteDispenserNeedsHopper), "BadDispensers", MethodType.Getter)]
|
||||
public static class Patch_AlertPasteDispenserNeedsHopper
|
||||
{
|
||||
[HarmonyPostfix]
|
||||
public static void Postfix(ref List<Thing> __result)
|
||||
{
|
||||
// Remove all instances of our custom dispenser from the "bad" list
|
||||
__result.RemoveAll(t => t is Building_ARANutrientDispenser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ArachnaeSwarm
|
||||
else if (config != null)
|
||||
title = config.thingDef.LabelCap;
|
||||
else
|
||||
title = "选择孵化目标...";
|
||||
title = "选择生产目标...";
|
||||
|
||||
// 标题按钮(只有非孵化状态可点击)
|
||||
bool canSwitch = !isIncubating && !hasLarva && building.EquipmentIncubatorData?.IncubationConfigs?.Count > 0;
|
||||
@@ -225,12 +225,8 @@ namespace ArachnaeSwarm
|
||||
else
|
||||
{
|
||||
sb.AppendLine("【未选择目标】");
|
||||
sb.AppendLine("点击上方标题选择孵化目标");
|
||||
sb.AppendLine("点击上方标题选择生产目标");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("当前速度加成: " + building.SpeedMultiplier.ToStringPercent());
|
||||
sb.AppendLine("当前质量加成: " + building.QualityMultiplier.ToStringPercent());
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEndNewlines();
|
||||
|
||||
@@ -94,14 +94,26 @@ namespace ArachnaeSwarm
|
||||
// === 订单列表 ===
|
||||
if (orderCount > 0)
|
||||
{
|
||||
float listHeight = Mathf.Min(visibleCount, orderCount) * (BarHeight + Spacing + 14f);
|
||||
Rect listRect = new Rect(innerRect.x, curY, innerRect.width, listHeight);
|
||||
|
||||
if (orderCount > MaxVisibleOrders && Mouse.IsOver(listRect))
|
||||
float itemHeight = BarHeight + Spacing + 14f;
|
||||
float listHeight = Mathf.Min(visibleCount, orderCount) * itemHeight;
|
||||
float totalContentHeight = orderCount * itemHeight;
|
||||
bool needsScrollbar = orderCount > MaxVisibleOrders;
|
||||
|
||||
float scrollbarWidth = needsScrollbar ? 12f : 0f;
|
||||
Rect listRect = new Rect(innerRect.x, curY, innerRect.width - scrollbarWidth, listHeight);
|
||||
|
||||
// 滚动条
|
||||
if (needsScrollbar)
|
||||
{
|
||||
float scrollMax = (orderCount - MaxVisibleOrders) * (BarHeight + Spacing + 14f);
|
||||
scrollPosition -= Event.current.delta.y * 0.5f;
|
||||
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
|
||||
Rect scrollbarRect = new Rect(innerRect.xMax - scrollbarWidth, curY, scrollbarWidth, listHeight);
|
||||
float scrollMax = totalContentHeight - listHeight;
|
||||
scrollPosition = GUI.VerticalScrollbar(scrollbarRect, scrollPosition, listHeight, 0f, totalContentHeight);
|
||||
|
||||
if (Mouse.IsOver(listRect))
|
||||
{
|
||||
scrollPosition -= Event.current.delta.y * 1.5f;
|
||||
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.BeginClip(listRect);
|
||||
@@ -110,14 +122,13 @@ namespace ArachnaeSwarm
|
||||
for (int i = 0; i < orderCount; i++)
|
||||
{
|
||||
var order = orders[i];
|
||||
float itemHeight = BarHeight + 14f;
|
||||
Rect itemRect = new Rect(0, drawY, listRect.width, itemHeight);
|
||||
Rect itemRect = new Rect(0, drawY, listRect.width, itemHeight - Spacing);
|
||||
|
||||
if (itemRect.yMax > 0 && itemRect.y < listRect.height)
|
||||
{
|
||||
DrawOrderItem(itemRect, order, i);
|
||||
}
|
||||
drawY += itemHeight + Spacing;
|
||||
drawY += itemHeight;
|
||||
}
|
||||
|
||||
GUI.EndClip();
|
||||
|
||||
@@ -224,10 +224,6 @@ namespace ArachnaeSwarm
|
||||
sb.AppendLine("【未选择目标】");
|
||||
sb.AppendLine("点击上方标题选择孵化目标");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("当前速度加成: " + ootheca.SpeedMultiplier.ToStringPercent());
|
||||
sb.AppendLine("当前质量加成: " + ootheca.QualityMultiplier.ToStringPercent());
|
||||
}
|
||||
|
||||
return sb.ToString().TrimEndNewlines();
|
||||
|
||||
@@ -97,15 +97,28 @@ namespace ArachnaeSwarm
|
||||
// === 订单列表 ===
|
||||
if (orderCount > 0)
|
||||
{
|
||||
float listHeight = Mathf.Min(visibleCount, orderCount) * (BarHeight + Spacing + 14f);
|
||||
Rect listRect = new Rect(innerRect.x, curY, innerRect.width, listHeight);
|
||||
|
||||
// 滚动支持
|
||||
if (orderCount > MaxVisibleOrders && Mouse.IsOver(listRect))
|
||||
float itemHeight = BarHeight + Spacing + 14f;
|
||||
float listHeight = Mathf.Min(visibleCount, orderCount) * itemHeight;
|
||||
float totalContentHeight = orderCount * itemHeight;
|
||||
bool needsScrollbar = orderCount > MaxVisibleOrders;
|
||||
|
||||
float scrollbarWidth = needsScrollbar ? 12f : 0f;
|
||||
Rect listRect = new Rect(innerRect.x, curY, innerRect.width - scrollbarWidth, listHeight);
|
||||
Rect viewRect = new Rect(0, 0, listRect.width, totalContentHeight);
|
||||
|
||||
// 滚动条区域
|
||||
if (needsScrollbar)
|
||||
{
|
||||
float scrollMax = (orderCount - MaxVisibleOrders) * (BarHeight + Spacing + 14f);
|
||||
scrollPosition -= Event.current.delta.y * 0.5f;
|
||||
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
|
||||
Rect scrollbarRect = new Rect(innerRect.xMax - scrollbarWidth, curY, scrollbarWidth, listHeight);
|
||||
float scrollMax = totalContentHeight - listHeight;
|
||||
scrollPosition = GUI.VerticalScrollbar(scrollbarRect, scrollPosition, listHeight, 0f, totalContentHeight);
|
||||
|
||||
// 也支持滚轮
|
||||
if (Mouse.IsOver(listRect))
|
||||
{
|
||||
scrollPosition -= Event.current.delta.y * 1.5f;
|
||||
scrollPosition = Mathf.Clamp(scrollPosition, 0f, scrollMax);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.BeginClip(listRect);
|
||||
@@ -114,14 +127,13 @@ namespace ArachnaeSwarm
|
||||
for (int i = 0; i < orderCount; i++)
|
||||
{
|
||||
var order = orders[i];
|
||||
float itemHeight = BarHeight + 14f;
|
||||
Rect itemRect = new Rect(0, drawY, listRect.width, itemHeight);
|
||||
Rect itemRect = new Rect(0, drawY, listRect.width, itemHeight - Spacing);
|
||||
|
||||
if (itemRect.yMax > 0 && itemRect.y < listRect.height)
|
||||
{
|
||||
DrawOrderItem(itemRect, order, i);
|
||||
}
|
||||
drawY += itemHeight + Spacing;
|
||||
drawY += itemHeight;
|
||||
}
|
||||
|
||||
GUI.EndClip();
|
||||
|
||||
Reference in New Issue
Block a user