zc
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -52,6 +52,54 @@
|
||||
<li>Insect</li>
|
||||
</tags> -->
|
||||
</TerrainDef>
|
||||
<TerrainDef ParentName="FloorBase" MayRequire="Ludeon.RimWorld.Odyssey">
|
||||
<defName>ARA_InsectCreepFloor</defName>
|
||||
<label>阿拉克涅强固菌毯</label>
|
||||
<description>由阿拉克涅虫族所铺设的由真菌、甲壳素分泌物混合得到的地面,性质类似于阿拉克涅菌毯,不过可以在支撑结构上蔓延,以作为虫群的逆重飞船地基。</description>
|
||||
<texturePath>ArachnaeSwarm/Terrain/Surfaces/ARA_InsectCreep</texturePath>
|
||||
<pollutionTintColor>(0.95, 0.95, 0.93, 1)</pollutionTintColor>
|
||||
<color>(209, 207, 184)</color>
|
||||
<fertility>0</fertility>
|
||||
<edgeType>FadeRough</edgeType>
|
||||
<renderPrecedence>399</renderPrecedence>
|
||||
<constructEffect>ConstructMetal</constructEffect>
|
||||
<isPaintable>true</isPaintable>
|
||||
<designationCategory>ARA_Buildings</designationCategory>
|
||||
<isFoundation>true</isFoundation>
|
||||
<preventCraters>true</preventCraters>
|
||||
<designationHotKey>Misc9</designationHotKey>
|
||||
<researchPrerequisites>
|
||||
<li>ARA_Base_Technology</li>
|
||||
</researchPrerequisites>
|
||||
<affordances>
|
||||
<li>ARA_Creep</li>
|
||||
<li>Substructure</li>
|
||||
</affordances>
|
||||
<statBases>
|
||||
<Beauty>0</Beauty>
|
||||
<CleaningTimeFactor>0.25</CleaningTimeFactor>
|
||||
<Cleanliness>0</Cleanliness>
|
||||
<Flammability>0</Flammability>
|
||||
<WorkToBuild>100</WorkToBuild>
|
||||
</statBases>
|
||||
<costList>
|
||||
<GravlitePanel>1</GravlitePanel>
|
||||
<Steel>2</Steel>
|
||||
<ARA_Carapace>2</ARA_Carapace>
|
||||
</costList>
|
||||
<uiOrder>1000</uiOrder>
|
||||
<requireInspectedGravEngine>true</requireInspectedGravEngine>
|
||||
<terrainAffordanceNeeded>Walkable</terrainAffordanceNeeded>
|
||||
<resourcesFractionWhenDeconstructed>1</resourcesFractionWhenDeconstructed>
|
||||
<tags>
|
||||
<li>ARA_Creep</li>
|
||||
<li>Substructure</li>
|
||||
</tags>
|
||||
<placeWorkers>
|
||||
<li>PlaceWorker_InSubstructureFootprint</li>
|
||||
<li>PlaceWorker_BuildingsValidOverSubstructure</li>
|
||||
</placeWorkers>
|
||||
</TerrainDef>
|
||||
<TerrainDef ParentName="FloorBase">
|
||||
<defName>ARA_InsectCreepTile</defName>
|
||||
<label>阿拉克涅菌毯砖</label>
|
||||
|
||||
@@ -430,18 +430,24 @@
|
||||
<warningThreshold>0.2</warningThreshold>
|
||||
<maintenanceThresholdForJob>0.5</maintenanceThresholdForJob>
|
||||
</li>
|
||||
<!-- 虫蜜燃料组件(孵化活性系统) -->
|
||||
<!-- 虫蜜燃料系统 -->
|
||||
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
||||
<fuelConsumptionRate>0</fuelConsumptionRate>
|
||||
<fuelCapacity>10</fuelCapacity>
|
||||
<initialFuelPercent>0</initialFuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>5</initialConfigurableTargetFuelLevel>
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<fuelCapacity>25.0</fuelCapacity>
|
||||
<fuelFilter>
|
||||
<thingDefs>
|
||||
<li>ARA_InsectJelly</li>
|
||||
</thingDefs>
|
||||
</fuelFilter>
|
||||
<fuelGizmoLabel>虫蜜</fuelGizmoLabel>
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<targetFuelLevelConfigurable>true</targetFuelLevelConfigurable>
|
||||
<initialConfigurableTargetFuelLevel>5</initialConfigurableTargetFuelLevel>
|
||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||
</li>
|
||||
<li Class="CompProperties_AffectedByFacilities">
|
||||
<linkableFacilities>
|
||||
<li>ARA_NutrientNetworkTower</li>
|
||||
</linkableFacilities>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_EquipmentIncubatorData">
|
||||
<!-- autoScanThingDefs默认为true,会自动扫描所有ThingDef -->
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
<ARA_Gizmo_CallLarvaDesc>呼叫一只幼虫来激活下一个订单(还有{0}个等待中)</ARA_Gizmo_CallLarvaDesc>
|
||||
<ARA_Gizmo_LarvaWorking>幼虫工作中</ARA_Gizmo_LarvaWorking>
|
||||
<ARA_Gizmo_LarvaWorkingDesc>一只幼虫正在操作孵化器(还有{0}个订单等待)</ARA_Gizmo_LarvaWorkingDesc>
|
||||
<ARA_Gizmo_LarvaActivating>幼虫激活中</ARA_Gizmo_LarvaActivating>
|
||||
<ARA_Gizmo_LarvaOnTheWay>幼虫赶路中</ARA_Gizmo_LarvaOnTheWay>
|
||||
|
||||
<!-- 菜单 -->
|
||||
<ARA_Menu_SelectIncubationTarget>选择孵化目标</ARA_Menu_SelectIncubationTarget>
|
||||
|
||||
@@ -8,23 +8,35 @@ using Verse.AI;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
// 带状态和品质的物品订单(与 Building_Ootheca 统一的累计进度模式)
|
||||
public class QueuedItemOrder : IExposable
|
||||
// 带状态和品质的物品订单(实现 IIncubationState 接口)
|
||||
public class QueuedItemOrder : IExposable, IIncubationState
|
||||
{
|
||||
public ProcessDef process;
|
||||
public string tempThingDefName;
|
||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||
|
||||
// 进度系统(累计模式,与 Building_Ootheca 统一)
|
||||
public float incubationProgress = 0f;
|
||||
public float incubationDuration = 0f;
|
||||
// 进度系统
|
||||
private float _incubationProgress = 0f;
|
||||
private float _incubationDuration = 0f;
|
||||
|
||||
// 通量品质系统
|
||||
public float qualityProgress = 0f;
|
||||
public float qualityTotal = 0f;
|
||||
// 品质系统
|
||||
private float _qualityProgress = 0f;
|
||||
private float _qualityTotal = 0f;
|
||||
|
||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
||||
// IIncubationState 接口实现
|
||||
public float IncubationProgress { get => _incubationProgress; set => _incubationProgress = value; }
|
||||
public float IncubationDuration => _incubationDuration;
|
||||
public float QualityProgress { get => _qualityProgress; set => _qualityProgress = value; }
|
||||
public float QualityTotal => _qualityTotal;
|
||||
|
||||
public float ProgressPercent => _incubationDuration > 0 ? _incubationProgress / _incubationDuration : 0f;
|
||||
public float QualityPercent => _qualityTotal > 0 ? _qualityProgress / _qualityTotal : 0f;
|
||||
|
||||
public void SetDuration(float duration)
|
||||
{
|
||||
_incubationDuration = duration;
|
||||
_qualityTotal = duration;
|
||||
}
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
@@ -34,10 +46,10 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
Scribe_Values.Look(ref tempThingDefName, "thingDefName");
|
||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,11 +271,7 @@ namespace ArachnaeSwarm
|
||||
if (waitingOrder != null)
|
||||
{
|
||||
waitingOrder.status = OrderStatus.Incubating;
|
||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
||||
waitingOrder.incubationDuration = waitingOrder.process.productionTicks;
|
||||
waitingOrder.incubationProgress = 0f;
|
||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
||||
waitingOrder.qualityProgress = 0f;
|
||||
waitingOrder.SetDuration(waitingOrder.process.productionTicks);
|
||||
}
|
||||
assignedLarvae.Remove(larva);
|
||||
|
||||
@@ -301,36 +309,20 @@ namespace ArachnaeSwarm
|
||||
FuelComp.ConsumeFuel(fuelPerTick);
|
||||
}
|
||||
|
||||
// 进度和品质处理(与 Building_Ootheca 统一)
|
||||
// 进度和品质处理(调用统一工具方法)
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
bool isDormant = IsDormant || !hasFuel;
|
||||
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
{
|
||||
if (IsDormant)
|
||||
{
|
||||
// 休眠时:不推进进度,品质衰减
|
||||
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);
|
||||
}
|
||||
IncubatorUtils.TickIncubation(order, speedFactor, neutronFlux, isDormant);
|
||||
}
|
||||
|
||||
// 完成检查(进度达到持续时间时完成)
|
||||
// 完成检查
|
||||
orders.RemoveAll(order =>
|
||||
{
|
||||
if (order.status == OrderStatus.Incubating &&
|
||||
order.incubationProgress >= order.incubationDuration)
|
||||
IncubatorUtils.IsIncubationComplete(order))
|
||||
{
|
||||
FinishProduction(order);
|
||||
return true;
|
||||
|
||||
@@ -25,31 +25,43 @@ namespace ArachnaeSwarm
|
||||
public string estimatedQuality;
|
||||
}
|
||||
|
||||
// 带状态和品质的督虫订单
|
||||
public class QueuedPawnOrder : IExposable
|
||||
// 带状态和品质的督虫订单(实现 IIncubationState 接口)
|
||||
public class QueuedPawnOrder : IExposable, IIncubationState
|
||||
{
|
||||
public IncubationConfig config;
|
||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||
|
||||
// 进度系统(与 Building_Ootheca 统一)
|
||||
public float incubationProgress = 0f;
|
||||
public float incubationDuration = 0f;
|
||||
private float _incubationProgress = 0f;
|
||||
private float _incubationDuration = 0f;
|
||||
|
||||
// 品质系统
|
||||
public float qualityProgress = 0f;
|
||||
public float qualityTotal = 0f;
|
||||
private float _qualityProgress = 0f;
|
||||
private float _qualityTotal = 0f;
|
||||
|
||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
||||
// IIncubationState 接口实现
|
||||
public float IncubationProgress { get => _incubationProgress; set => _incubationProgress = value; }
|
||||
public float IncubationDuration => _incubationDuration;
|
||||
public float QualityProgress { get => _qualityProgress; set => _qualityProgress = value; }
|
||||
public float QualityTotal => _qualityTotal;
|
||||
|
||||
public float ProgressPercent => _incubationDuration > 0 ? _incubationProgress / _incubationDuration : 0f;
|
||||
public float QualityPercent => _qualityTotal > 0 ? _qualityProgress / _qualityTotal : 0f;
|
||||
|
||||
public void SetDuration(float duration)
|
||||
{
|
||||
_incubationDuration = duration;
|
||||
_qualityTotal = duration; // 品质总量与孵化时间相同
|
||||
}
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Deep.Look(ref config, "config");
|
||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,8 +192,8 @@ namespace ArachnaeSwarm
|
||||
|
||||
private float GetRemainingTicks(QueuedPawnOrder order)
|
||||
{
|
||||
if (order.status != OrderStatus.Incubating || order.incubationDuration <= 0) return 0f;
|
||||
float remaining = order.incubationDuration - order.incubationProgress;
|
||||
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;
|
||||
@@ -275,11 +287,7 @@ namespace ArachnaeSwarm
|
||||
if (waitingOrder != null && waitingOrder.config != null)
|
||||
{
|
||||
waitingOrder.status = OrderStatus.Incubating;
|
||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
||||
waitingOrder.incubationDuration = waitingOrder.config.daysRequired * 60000f;
|
||||
waitingOrder.incubationProgress = 0f;
|
||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
||||
waitingOrder.qualityProgress = 0f;
|
||||
waitingOrder.SetDuration(waitingOrder.config.daysRequired * 60000f);
|
||||
}
|
||||
assignedLarvae.Remove(larva);
|
||||
|
||||
@@ -316,36 +324,20 @@ namespace ArachnaeSwarm
|
||||
FuelComp.ConsumeFuel(fuelPerTick);
|
||||
}
|
||||
|
||||
// 进度和品质处理(与 Building_Ootheca 统一)
|
||||
// 进度和品质处理(调用统一工具方法)
|
||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||
bool isDormant = IsDormant || !hasFuel;
|
||||
|
||||
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||
{
|
||||
if (IsDormant)
|
||||
{
|
||||
// 休眠时:不推进进度,品质衰减
|
||||
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);
|
||||
}
|
||||
IncubatorUtils.TickIncubation(order, speedFactor, neutronFlux, isDormant);
|
||||
}
|
||||
|
||||
// 完成检查(进度达到持续时间时完成)
|
||||
// 完成检查
|
||||
orders.RemoveAll(order =>
|
||||
{
|
||||
if (order.status == OrderStatus.Incubating &&
|
||||
order.incubationProgress >= order.incubationDuration)
|
||||
IncubatorUtils.IsIncubationComplete(order))
|
||||
{
|
||||
CompleteOrder(order);
|
||||
return true;
|
||||
|
||||
@@ -135,13 +135,12 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常状态:应用活性效率
|
||||
// 进度增长
|
||||
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
||||
incubationProgress += fluxSpeed;
|
||||
|
||||
// 品质独立增长
|
||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
|
||||
// 品质增长(新公式:50%通量时与进度同步)
|
||||
float qualityGain = IncubatorUtils.CalculateQualityGainNew(fluxSpeed, neutronFlux);
|
||||
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
||||
}
|
||||
|
||||
@@ -404,21 +403,53 @@ namespace ArachnaeSwarm
|
||||
yield return new Gizmo_EquipmentIncubationProgress(this);
|
||||
yield return new Gizmo_NeutronFlux(this);
|
||||
|
||||
if (!isIncubating && EquipmentIncubatorData?.SelectedConfig?.IsResearchComplete == true)
|
||||
var config = EquipmentIncubatorData?.SelectedConfig;
|
||||
|
||||
// 添加订单按钮
|
||||
if (!isIncubating && assignedLarva == null)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "呼叫幼虫",
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
action = CallLarva
|
||||
defaultLabel = "ARA_Gizmo_AddOrder".Translate(config != null ? 1 : 0, 1),
|
||||
defaultDesc = "ARA_Gizmo_AddOrderDesc_Item".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_NodeSwarmIcon", false),
|
||||
action = () => EquipmentIncubatorData?.ShowFloatMenu()
|
||||
};
|
||||
}
|
||||
|
||||
// 呼叫幼虫按钮逻辑
|
||||
if (!isIncubating && config != null && config.IsResearchComplete)
|
||||
{
|
||||
if (assignedLarva == null)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "ARA_Gizmo_CallLarva".Translate(),
|
||||
defaultDesc = BuildCallLarvaDescription(config),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
action = CallLarva
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
string statusText = larvaOperateTicksRemaining > 0
|
||||
? "ARA_Gizmo_LarvaActivating".Translate()
|
||||
: "ARA_Gizmo_LarvaOnTheWay".Translate();
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = statusText,
|
||||
defaultDesc = "ARA_Gizmo_LarvaWorkingDesc".Translate(0),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
Disabled = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (isIncubating)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "取消孵化",
|
||||
defaultLabel = "ARA_OothecaIncubator.CancelIncubation".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false),
|
||||
action = CancelIncubation
|
||||
};
|
||||
|
||||
@@ -320,6 +320,36 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
// 显示目标选择菜单
|
||||
public void ShowFloatMenu()
|
||||
{
|
||||
var configs = IncubationConfigs;
|
||||
if (configs == null || configs.Count == 0) return;
|
||||
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
||||
|
||||
for (int i = 0; i < configs.Count; i++)
|
||||
{
|
||||
var cfg = configs[i];
|
||||
int index = i;
|
||||
|
||||
string label = cfg.thingDef.LabelCap;
|
||||
if (cfg.requiredResearch != null && !cfg.requiredResearch.IsFinished)
|
||||
{
|
||||
label += " (" + "ARA_Menu_RequiresResearch".Translate(cfg.requiredResearch.LabelCap) + ")";
|
||||
options.Add(new FloatMenuOption(label, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
label += " (" + "ARA_Menu_Days".Translate(cfg.DaysRequired.ToString("F1")) + ")";
|
||||
options.Add(new FloatMenuOption(label, () => SwitchToConfig(index)));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.Count > 0)
|
||||
Find.WindowStack.Add(new FloatMenu(options, "ARA_Menu_SelectProductionTarget".Translate()));
|
||||
}
|
||||
|
||||
// 存档加载
|
||||
public override void PostExposeData()
|
||||
|
||||
@@ -240,11 +240,12 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
else
|
||||
{
|
||||
// 进度增长
|
||||
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
||||
incubationProgress += fluxSpeed;
|
||||
|
||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
|
||||
// 品质增长(新公式:50%通量时与进度同步)
|
||||
float qualityGain = IncubatorUtils.CalculateQualityGainNew(fluxSpeed, neutronFlux);
|
||||
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
||||
}
|
||||
|
||||
@@ -408,17 +409,49 @@ namespace ArachnaeSwarm
|
||||
yield return new Gizmo_NeutronFlux(this);
|
||||
|
||||
var config = IncubatorData?.SelectedConfig;
|
||||
if (!isIncubating && config != null && config.IsResearchComplete)
|
||||
|
||||
// 添加订单按钮(未孵化且未选目标,或已选目标但支持切换)
|
||||
if (!isIncubating && assignedLarva == null)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "ARA_OothecaIncubator.CallLarva".Translate(),
|
||||
defaultDesc = BuildCallLarvaDescription(config),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
action = CallLarva
|
||||
defaultLabel = "ARA_Gizmo_AddOrder".Translate(config != null ? 1 : 0, 1),
|
||||
defaultDesc = "ARA_Gizmo_AddOrderDesc_Pawn".Translate(),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_NodeSwarmIcon", false),
|
||||
action = () => IncubatorData?.ShowFloatMenu()
|
||||
};
|
||||
}
|
||||
|
||||
// 呼叫幼虫按钮逻辑
|
||||
if (!isIncubating && config != null && config.IsResearchComplete)
|
||||
{
|
||||
if (assignedLarva == null)
|
||||
{
|
||||
// 无幼虫,可以呼叫
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "ARA_Gizmo_CallLarva".Translate(),
|
||||
defaultDesc = BuildCallLarvaDescription(config),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
action = CallLarva
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// 幼虫在路上或工作中
|
||||
string statusText = larvaOperateTicksRemaining > 0
|
||||
? "ARA_Gizmo_LarvaActivating".Translate()
|
||||
: "ARA_Gizmo_LarvaOnTheWay".Translate();
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = statusText,
|
||||
defaultDesc = "ARA_Gizmo_LarvaWorkingDesc".Translate(0),
|
||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||
Disabled = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (isIncubating)
|
||||
{
|
||||
yield return new Command_Action
|
||||
|
||||
@@ -384,6 +384,36 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
return selectedIndex;
|
||||
}
|
||||
|
||||
// 显示目标选择菜单
|
||||
public void ShowFloatMenu()
|
||||
{
|
||||
var configs = IncubationConfigs;
|
||||
if (configs == null || configs.Count == 0) return;
|
||||
|
||||
List<FloatMenuOption> options = new List<FloatMenuOption>();
|
||||
|
||||
for (int i = 0; i < configs.Count; i++)
|
||||
{
|
||||
var cfg = configs[i];
|
||||
int index = i;
|
||||
|
||||
string label = cfg.pawnKind.LabelCap;
|
||||
if (cfg.requiredResearch != null && !cfg.requiredResearch.IsFinished)
|
||||
{
|
||||
label += " (" + "ARA_Menu_RequiresResearch".Translate(cfg.requiredResearch.LabelCap) + ")";
|
||||
options.Add(new FloatMenuOption(label, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
label += " (" + "ARA_Menu_Days".Translate(cfg.daysRequired.ToString("F1")) + ")";
|
||||
options.Add(new FloatMenuOption(label, () => SwitchToConfig(index)));
|
||||
}
|
||||
}
|
||||
|
||||
if (options.Count > 0)
|
||||
Find.WindowStack.Add(new FloatMenu(options, "ARA_Menu_SelectIncubationTarget".Translate()));
|
||||
}
|
||||
|
||||
// 存档加载
|
||||
public override void PostExposeData()
|
||||
|
||||
@@ -6,12 +6,67 @@ using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 孵化状态数据接口 - 所有孵化系统共用
|
||||
/// </summary>
|
||||
public interface IIncubationState
|
||||
{
|
||||
float IncubationProgress { get; set; }
|
||||
float IncubationDuration { get; }
|
||||
float QualityProgress { get; set; }
|
||||
float QualityTotal { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 孵化器通用工具类
|
||||
/// 统一核心算法,保持各孵化器行为一致
|
||||
/// </summary>
|
||||
public static class IncubatorUtils
|
||||
{
|
||||
// ============================================
|
||||
// 核心 Tick 方法(各孵化器调用此方法)
|
||||
// ============================================
|
||||
|
||||
/// <summary>
|
||||
/// 执行单tick的孵化进度和品质更新(核心方法)
|
||||
/// 所有孵化器应调用此方法以保持行为一致
|
||||
/// </summary>
|
||||
/// <param name="state">孵化状态(实现 IIncubationState 接口)</param>
|
||||
/// <param name="speedMultiplier">速度倍率(来自设施等)</param>
|
||||
/// <param name="neutronFlux">当前通量值 0-1</param>
|
||||
/// <param name="isDormant">是否休眠(通量过低或无燃料)</param>
|
||||
/// <returns>本tick的进度增量(用于判断完成)</returns>
|
||||
public static float TickIncubation(IIncubationState state, float speedMultiplier, float neutronFlux, bool isDormant)
|
||||
{
|
||||
if (isDormant)
|
||||
{
|
||||
// 休眠时:进度不增长,品质衰减
|
||||
float qualityDecay = CalculateQualityDecay(state.QualityTotal);
|
||||
state.QualityProgress = Mathf.Max(0f, state.QualityProgress - qualityDecay);
|
||||
return 0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 正常工作:进度和品质同步增长
|
||||
float fluxEfficiency = GetFluxEfficiency(neutronFlux);
|
||||
float progressGain = CalculateProgressGain(speedMultiplier, fluxEfficiency);
|
||||
float qualityGain = CalculateQualityGainNew(progressGain, neutronFlux);
|
||||
|
||||
state.IncubationProgress += progressGain;
|
||||
state.QualityProgress = Mathf.Min(state.QualityProgress + qualityGain, state.QualityTotal);
|
||||
|
||||
return progressGain;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查孵化是否完成
|
||||
/// </summary>
|
||||
public static bool IsIncubationComplete(IIncubationState state)
|
||||
{
|
||||
return state.IncubationProgress >= state.IncubationDuration;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 通量系统
|
||||
// ============================================
|
||||
@@ -34,16 +89,16 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取模式名称
|
||||
/// 获取模式名称(使用翻译键)
|
||||
/// </summary>
|
||||
public static string GetFluxModeName(FluxMode mode)
|
||||
{
|
||||
return mode switch
|
||||
{
|
||||
FluxMode.Manual => "手动",
|
||||
FluxMode.Quality => "品质",
|
||||
FluxMode.Balance => "平衡",
|
||||
FluxMode.Speed => "速度",
|
||||
FluxMode.Manual => "ARA_FluxMode_Manual".Translate(),
|
||||
FluxMode.Quality => "ARA_FluxMode_Quality".Translate(),
|
||||
FluxMode.Balance => "ARA_FluxMode_Balance".Translate(),
|
||||
FluxMode.Speed => "ARA_FluxMode_Speed".Translate(),
|
||||
_ => "?"
|
||||
};
|
||||
}
|
||||
@@ -64,13 +119,38 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 品质系统
|
||||
// 进度系统
|
||||
// ============================================
|
||||
|
||||
/// <summary>
|
||||
/// 计算品质增长(低通量时增长更快)
|
||||
/// 公式:qualityGain = speedFactor * (1 + (1 - flux) * 0.5)
|
||||
/// 计算单tick的进度增量
|
||||
/// 公式:progressGain = speedMultiplier * fluxEfficiency * 5
|
||||
/// </summary>
|
||||
public static float CalculateProgressGain(float speedMultiplier, float fluxEfficiency)
|
||||
{
|
||||
return speedMultiplier * fluxEfficiency * 5f;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 品质系统(新公式:50%通量时与进度同步)
|
||||
// ============================================
|
||||
|
||||
/// <summary>
|
||||
/// 计算单tick的品质增量(新公式)
|
||||
/// 核心:50%通量时品质增长 = 进度增长(1:1同步)
|
||||
/// 公式:qualityGain = progressGain × 2 × (1 - neutronFlux)
|
||||
/// </summary>
|
||||
public static float CalculateQualityGainNew(float progressGain, float neutronFlux)
|
||||
{
|
||||
// qualityCoeff: 0%通量=2.0, 25%通量=1.5, 50%通量=1.0, 75%通量=0.5, 100%通量=0
|
||||
float qualityCoeff = 2f * (1f - neutronFlux);
|
||||
return progressGain * qualityCoeff;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// [已废弃] 旧品质计算公式
|
||||
/// </summary>
|
||||
[System.Obsolete("Use CalculateQualityGainNew instead")]
|
||||
public static float CalculateQualityGain(float neutronFlux, float speedFactor)
|
||||
{
|
||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||
|
||||
Reference in New Issue
Block a user