zc
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -52,6 +52,54 @@
|
|||||||
<li>Insect</li>
|
<li>Insect</li>
|
||||||
</tags> -->
|
</tags> -->
|
||||||
</TerrainDef>
|
</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">
|
<TerrainDef ParentName="FloorBase">
|
||||||
<defName>ARA_InsectCreepTile</defName>
|
<defName>ARA_InsectCreepTile</defName>
|
||||||
<label>阿拉克涅菌毯砖</label>
|
<label>阿拉克涅菌毯砖</label>
|
||||||
|
|||||||
@@ -430,18 +430,24 @@
|
|||||||
<warningThreshold>0.2</warningThreshold>
|
<warningThreshold>0.2</warningThreshold>
|
||||||
<maintenanceThresholdForJob>0.5</maintenanceThresholdForJob>
|
<maintenanceThresholdForJob>0.5</maintenanceThresholdForJob>
|
||||||
</li>
|
</li>
|
||||||
<!-- 虫蜜燃料组件(孵化活性系统) -->
|
<!-- 虫蜜燃料系统 -->
|
||||||
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
<li Class="ArachnaeSwarm.CompProperties_RefuelableNutrition">
|
||||||
<fuelConsumptionRate>0</fuelConsumptionRate>
|
<fuelCapacity>25.0</fuelCapacity>
|
||||||
<fuelCapacity>10</fuelCapacity>
|
|
||||||
<initialFuelPercent>0</initialFuelPercent>
|
|
||||||
<initialConfigurableTargetFuelLevel>5</initialConfigurableTargetFuelLevel>
|
|
||||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
|
||||||
<fuelFilter>
|
<fuelFilter>
|
||||||
<thingDefs>
|
<thingDefs>
|
||||||
<li>ARA_InsectJelly</li>
|
<li>ARA_InsectJelly</li>
|
||||||
</thingDefs>
|
</thingDefs>
|
||||||
</fuelFilter>
|
</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>
|
||||||
<li Class="ArachnaeSwarm.CompProperties_EquipmentIncubatorData">
|
<li Class="ArachnaeSwarm.CompProperties_EquipmentIncubatorData">
|
||||||
<!-- autoScanThingDefs默认为true,会自动扫描所有ThingDef -->
|
<!-- autoScanThingDefs默认为true,会自动扫描所有ThingDef -->
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
<ARA_Gizmo_CallLarvaDesc>呼叫一只幼虫来激活下一个订单(还有{0}个等待中)</ARA_Gizmo_CallLarvaDesc>
|
<ARA_Gizmo_CallLarvaDesc>呼叫一只幼虫来激活下一个订单(还有{0}个等待中)</ARA_Gizmo_CallLarvaDesc>
|
||||||
<ARA_Gizmo_LarvaWorking>幼虫工作中</ARA_Gizmo_LarvaWorking>
|
<ARA_Gizmo_LarvaWorking>幼虫工作中</ARA_Gizmo_LarvaWorking>
|
||||||
<ARA_Gizmo_LarvaWorkingDesc>一只幼虫正在操作孵化器(还有{0}个订单等待)</ARA_Gizmo_LarvaWorkingDesc>
|
<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>
|
<ARA_Menu_SelectIncubationTarget>选择孵化目标</ARA_Menu_SelectIncubationTarget>
|
||||||
|
|||||||
@@ -8,23 +8,35 @@ using Verse.AI;
|
|||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
// 带状态和品质的物品订单(与 Building_Ootheca 统一的累计进度模式)
|
// 带状态和品质的物品订单(实现 IIncubationState 接口)
|
||||||
public class QueuedItemOrder : IExposable
|
public class QueuedItemOrder : IExposable, IIncubationState
|
||||||
{
|
{
|
||||||
public ProcessDef process;
|
public ProcessDef process;
|
||||||
public string tempThingDefName;
|
public string tempThingDefName;
|
||||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||||
|
|
||||||
// 进度系统(累计模式,与 Building_Ootheca 统一)
|
// 进度系统
|
||||||
public float incubationProgress = 0f;
|
private float _incubationProgress = 0f;
|
||||||
public float incubationDuration = 0f;
|
private float _incubationDuration = 0f;
|
||||||
|
|
||||||
// 通量品质系统
|
// 品质系统
|
||||||
public float qualityProgress = 0f;
|
private float _qualityProgress = 0f;
|
||||||
public float qualityTotal = 0f;
|
private float _qualityTotal = 0f;
|
||||||
|
|
||||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
// IIncubationState 接口实现
|
||||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
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()
|
public void ExposeData()
|
||||||
{
|
{
|
||||||
@@ -34,10 +46,10 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
Scribe_Values.Look(ref tempThingDefName, "thingDefName");
|
Scribe_Values.Look(ref tempThingDefName, "thingDefName");
|
||||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
Scribe_Values.Look(ref _incubationProgress, "incubationProgress", 0f);
|
||||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
Scribe_Values.Look(ref _incubationDuration, "incubationDuration", 0f);
|
||||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
Scribe_Values.Look(ref _qualityProgress, "qualityProgress", 0f);
|
||||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
Scribe_Values.Look(ref _qualityTotal, "qualityTotal", 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,11 +271,7 @@ namespace ArachnaeSwarm
|
|||||||
if (waitingOrder != null)
|
if (waitingOrder != null)
|
||||||
{
|
{
|
||||||
waitingOrder.status = OrderStatus.Incubating;
|
waitingOrder.status = OrderStatus.Incubating;
|
||||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
waitingOrder.SetDuration(waitingOrder.process.productionTicks);
|
||||||
waitingOrder.incubationDuration = waitingOrder.process.productionTicks;
|
|
||||||
waitingOrder.incubationProgress = 0f;
|
|
||||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
|
||||||
waitingOrder.qualityProgress = 0f;
|
|
||||||
}
|
}
|
||||||
assignedLarvae.Remove(larva);
|
assignedLarvae.Remove(larva);
|
||||||
|
|
||||||
@@ -301,36 +309,20 @@ namespace ArachnaeSwarm
|
|||||||
FuelComp.ConsumeFuel(fuelPerTick);
|
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))
|
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||||
{
|
{
|
||||||
if (IsDormant)
|
IncubatorUtils.TickIncubation(order, speedFactor, neutronFlux, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完成检查(进度达到持续时间时完成)
|
// 完成检查
|
||||||
orders.RemoveAll(order =>
|
orders.RemoveAll(order =>
|
||||||
{
|
{
|
||||||
if (order.status == OrderStatus.Incubating &&
|
if (order.status == OrderStatus.Incubating &&
|
||||||
order.incubationProgress >= order.incubationDuration)
|
IncubatorUtils.IsIncubationComplete(order))
|
||||||
{
|
{
|
||||||
FinishProduction(order);
|
FinishProduction(order);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -25,31 +25,43 @@ namespace ArachnaeSwarm
|
|||||||
public string estimatedQuality;
|
public string estimatedQuality;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 带状态和品质的督虫订单
|
// 带状态和品质的督虫订单(实现 IIncubationState 接口)
|
||||||
public class QueuedPawnOrder : IExposable
|
public class QueuedPawnOrder : IExposable, IIncubationState
|
||||||
{
|
{
|
||||||
public IncubationConfig config;
|
public IncubationConfig config;
|
||||||
public OrderStatus status = OrderStatus.WaitingForLarva;
|
public OrderStatus status = OrderStatus.WaitingForLarva;
|
||||||
|
|
||||||
// 进度系统(与 Building_Ootheca 统一)
|
// 进度系统(与 Building_Ootheca 统一)
|
||||||
public float incubationProgress = 0f;
|
private float _incubationProgress = 0f;
|
||||||
public float incubationDuration = 0f;
|
private float _incubationDuration = 0f;
|
||||||
|
|
||||||
// 品质系统
|
// 品质系统
|
||||||
public float qualityProgress = 0f;
|
private float _qualityProgress = 0f;
|
||||||
public float qualityTotal = 0f;
|
private float _qualityTotal = 0f;
|
||||||
|
|
||||||
public float ProgressPercent => incubationDuration > 0 ? incubationProgress / incubationDuration : 0f;
|
// IIncubationState 接口实现
|
||||||
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
|
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()
|
public void ExposeData()
|
||||||
{
|
{
|
||||||
Scribe_Deep.Look(ref config, "config");
|
Scribe_Deep.Look(ref config, "config");
|
||||||
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
Scribe_Values.Look(ref status, "status", OrderStatus.WaitingForLarva);
|
||||||
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
|
Scribe_Values.Look(ref _incubationProgress, "incubationProgress", 0f);
|
||||||
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
|
Scribe_Values.Look(ref _incubationDuration, "incubationDuration", 0f);
|
||||||
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
|
Scribe_Values.Look(ref _qualityProgress, "qualityProgress", 0f);
|
||||||
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
|
Scribe_Values.Look(ref _qualityTotal, "qualityTotal", 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,8 +192,8 @@ namespace ArachnaeSwarm
|
|||||||
|
|
||||||
private float GetRemainingTicks(QueuedPawnOrder order)
|
private float GetRemainingTicks(QueuedPawnOrder order)
|
||||||
{
|
{
|
||||||
if (order.status != OrderStatus.Incubating || order.incubationDuration <= 0) return 0f;
|
if (order.status != OrderStatus.Incubating || order.IncubationDuration <= 0) return 0f;
|
||||||
float remaining = order.incubationDuration - order.incubationProgress;
|
float remaining = order.IncubationDuration - order.IncubationProgress;
|
||||||
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
float speedFactor = 1f + (FacilitiesComp?.GetStatOffset(StatDef.Named("ARA_IncubationSpeedFactor")) ?? 0f);
|
||||||
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
float fluxSpeed = speedFactor * FluxEfficiency * 5f;
|
||||||
return fluxSpeed > 0 ? remaining / fluxSpeed : remaining;
|
return fluxSpeed > 0 ? remaining / fluxSpeed : remaining;
|
||||||
@@ -275,11 +287,7 @@ namespace ArachnaeSwarm
|
|||||||
if (waitingOrder != null && waitingOrder.config != null)
|
if (waitingOrder != null && waitingOrder.config != null)
|
||||||
{
|
{
|
||||||
waitingOrder.status = OrderStatus.Incubating;
|
waitingOrder.status = OrderStatus.Incubating;
|
||||||
// 使用累计进度模式(与 Building_Ootheca 统一)
|
waitingOrder.SetDuration(waitingOrder.config.daysRequired * 60000f);
|
||||||
waitingOrder.incubationDuration = waitingOrder.config.daysRequired * 60000f;
|
|
||||||
waitingOrder.incubationProgress = 0f;
|
|
||||||
waitingOrder.qualityTotal = waitingOrder.incubationDuration;
|
|
||||||
waitingOrder.qualityProgress = 0f;
|
|
||||||
}
|
}
|
||||||
assignedLarvae.Remove(larva);
|
assignedLarvae.Remove(larva);
|
||||||
|
|
||||||
@@ -316,36 +324,20 @@ namespace ArachnaeSwarm
|
|||||||
FuelComp.ConsumeFuel(fuelPerTick);
|
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))
|
foreach (var order in orders.Where(o => o.status == OrderStatus.Incubating))
|
||||||
{
|
{
|
||||||
if (IsDormant)
|
IncubatorUtils.TickIncubation(order, speedFactor, neutronFlux, 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 完成检查(进度达到持续时间时完成)
|
// 完成检查
|
||||||
orders.RemoveAll(order =>
|
orders.RemoveAll(order =>
|
||||||
{
|
{
|
||||||
if (order.status == OrderStatus.Incubating &&
|
if (order.status == OrderStatus.Incubating &&
|
||||||
order.incubationProgress >= order.incubationDuration)
|
IncubatorUtils.IsIncubationComplete(order))
|
||||||
{
|
{
|
||||||
CompleteOrder(order);
|
CompleteOrder(order);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -135,13 +135,12 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 正常状态:应用活性效率
|
// 进度增长
|
||||||
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
||||||
incubationProgress += fluxSpeed;
|
incubationProgress += fluxSpeed;
|
||||||
|
|
||||||
// 品质独立增长
|
// 品质增长(新公式:50%通量时与进度同步)
|
||||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
float qualityGain = IncubatorUtils.CalculateQualityGainNew(fluxSpeed, neutronFlux);
|
||||||
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
|
|
||||||
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,21 +403,53 @@ namespace ArachnaeSwarm
|
|||||||
yield return new Gizmo_EquipmentIncubationProgress(this);
|
yield return new Gizmo_EquipmentIncubationProgress(this);
|
||||||
yield return new Gizmo_NeutronFlux(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
|
yield return new Command_Action
|
||||||
{
|
{
|
||||||
defaultLabel = "呼叫幼虫",
|
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),
|
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||||
action = CallLarva
|
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)
|
if (isIncubating)
|
||||||
{
|
{
|
||||||
yield return new Command_Action
|
yield return new Command_Action
|
||||||
{
|
{
|
||||||
defaultLabel = "取消孵化",
|
defaultLabel = "ARA_OothecaIncubator.CancelIncubation".Translate(),
|
||||||
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false),
|
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false),
|
||||||
action = CancelIncubation
|
action = CancelIncubation
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -321,6 +321,36 @@ namespace ArachnaeSwarm
|
|||||||
return selectedIndex;
|
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()
|
public override void PostExposeData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -240,11 +240,12 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// 进度增长
|
||||||
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
float fluxSpeed = SpeedMultiplier * FluxEfficiency * 5f;
|
||||||
incubationProgress += fluxSpeed;
|
incubationProgress += fluxSpeed;
|
||||||
|
|
||||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
// 品质增长(新公式:50%通量时与进度同步)
|
||||||
float qualityGain = SpeedMultiplier * QualityMultiplier * qualityBonus;
|
float qualityGain = IncubatorUtils.CalculateQualityGainNew(fluxSpeed, neutronFlux);
|
||||||
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
qualityProgress = Mathf.Min(qualityProgress + qualityGain, qualityTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,16 +409,48 @@ namespace ArachnaeSwarm
|
|||||||
yield return new Gizmo_NeutronFlux(this);
|
yield return new Gizmo_NeutronFlux(this);
|
||||||
|
|
||||||
var config = IncubatorData?.SelectedConfig;
|
var config = IncubatorData?.SelectedConfig;
|
||||||
if (!isIncubating && config != null && config.IsResearchComplete)
|
|
||||||
|
// 添加订单按钮(未孵化且未选目标,或已选目标但支持切换)
|
||||||
|
if (!isIncubating && assignedLarva == null)
|
||||||
{
|
{
|
||||||
yield return new Command_Action
|
yield return new Command_Action
|
||||||
{
|
{
|
||||||
defaultLabel = "ARA_OothecaIncubator.CallLarva".Translate(),
|
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),
|
defaultDesc = BuildCallLarvaDescription(config),
|
||||||
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false),
|
||||||
action = CallLarva
|
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)
|
if (isIncubating)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -385,6 +385,36 @@ namespace ArachnaeSwarm
|
|||||||
return selectedIndex;
|
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()
|
public override void PostExposeData()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,12 +6,67 @@ using Verse;
|
|||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 孵化状态数据接口 - 所有孵化系统共用
|
||||||
|
/// </summary>
|
||||||
|
public interface IIncubationState
|
||||||
|
{
|
||||||
|
float IncubationProgress { get; set; }
|
||||||
|
float IncubationDuration { get; }
|
||||||
|
float QualityProgress { get; set; }
|
||||||
|
float QualityTotal { get; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 孵化器通用工具类
|
/// 孵化器通用工具类
|
||||||
/// 统一核心算法,保持各孵化器行为一致
|
/// 统一核心算法,保持各孵化器行为一致
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class IncubatorUtils
|
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>
|
||||||
/// 获取模式名称
|
/// 获取模式名称(使用翻译键)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string GetFluxModeName(FluxMode mode)
|
public static string GetFluxModeName(FluxMode mode)
|
||||||
{
|
{
|
||||||
return mode switch
|
return mode switch
|
||||||
{
|
{
|
||||||
FluxMode.Manual => "手动",
|
FluxMode.Manual => "ARA_FluxMode_Manual".Translate(),
|
||||||
FluxMode.Quality => "品质",
|
FluxMode.Quality => "ARA_FluxMode_Quality".Translate(),
|
||||||
FluxMode.Balance => "平衡",
|
FluxMode.Balance => "ARA_FluxMode_Balance".Translate(),
|
||||||
FluxMode.Speed => "速度",
|
FluxMode.Speed => "ARA_FluxMode_Speed".Translate(),
|
||||||
_ => "?"
|
_ => "?"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -64,13 +119,38 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// 品质系统
|
// 进度系统
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算品质增长(低通量时增长更快)
|
/// 计算单tick的进度增量
|
||||||
/// 公式:qualityGain = speedFactor * (1 + (1 - flux) * 0.5)
|
/// 公式:progressGain = speedMultiplier * fluxEfficiency * 5
|
||||||
/// </summary>
|
/// </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)
|
public static float CalculateQualityGain(float neutronFlux, float speedFactor)
|
||||||
{
|
{
|
||||||
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
float qualityBonus = 1f + (1f - neutronFlux) * 0.5f;
|
||||||
|
|||||||
Reference in New Issue
Block a user