三大系统

This commit is contained in:
Tourswen
2025-12-16 02:13:18 +08:00
parent 15404222fd
commit b17407b53f
55 changed files with 4892 additions and 644 deletions

View File

@@ -0,0 +1,882 @@
// File: Buildings/Building_EquipmentOotheca.cs
using RimWorld;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
using Verse;
using Verse.AI;
using System;
namespace ArachnaeSwarm
{
public class Building_EquipmentOotheca : Building
{
// 引用组件
public CompEquipmentIncubatorData EquipmentIncubatorData => this.TryGetComp<CompEquipmentIncubatorData>();
// 孵化状态
public bool isIncubating = false;
public float incubationProgress = 0f;
public float incubationDuration = 0f;
public ThingDef incubatingThingDef = null;
// 幼虫交互相关
public Pawn assignedLarva = null;
public int larvaOperateTicksRemaining = 0;
// 速度乘数系统
private float speedMultiplier = 1.0f;
private int lastMultiplierUpdateTick = -1;
private const int MultiplierUpdateInterval = 250;
// 质量系统
private float qualityMultiplier = 1.0f;
private float qualityProgress = 0f;
private float qualityTotal = 0f;
// 缓存的ModExtension
private OothecaIncubatorExtension cachedExtension;
// 获取ModExtension的辅助属性
private OothecaIncubatorExtension Ext
{
get
{
if (cachedExtension == null)
{
cachedExtension = def.GetModExtension<OothecaIncubatorExtension>() ?? OothecaIncubatorExtension.Default;
}
return cachedExtension;
}
}
// 属性访问器
public float SpeedMultiplier
{
get
{
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
{
UpdateSpeedMultiplier();
}
return speedMultiplier;
}
}
// 质量属性
public float QualityMultiplier => qualityMultiplier;
public float QualityProgress => qualityProgress;
public float QualityPercent => qualityTotal > 0 ? qualityProgress / qualityTotal : 0f;
// 进度百分比
public float AdjustedProgressPercent
{
get
{
if (incubationDuration <= 0) return 0f;
return incubationProgress / incubationDuration;
}
}
// 获取速度因子描述
public string GetSpeedFactorsDescription()
{
var builder = new StringBuilder();
builder.AppendLine("ARA_EquipmentIncubator.SpeedFactors".Translate());
builder.AppendLine();
// 1. 检查是否在孵化间中
bool inIncubatorRoom = IsInIncubatorRoom();
if (Ext.requiresIncubatorRoom)
{
builder.AppendLine(inIncubatorRoom ?
"ARA_EquipmentIncubator.InIncubatorRoom".Translate() :
"ARA_EquipmentIncubator.NotInIncubatorRoom".Translate());
}
// 2. 检查营养液数量
int nutrientSolutionCount = CountNearbyNutrientSolutions();
if (nutrientSolutionCount > 0)
{
builder.AppendLine("ARA_EquipmentIncubator.NutrientSolutions".Translate(
nutrientSolutionCount,
nutrientSolutionCount * Ext.nutrientSolutionBonusPerTile * 100));
}
else
{
builder.AppendLine("ARA_EquipmentIncubator.NoNutrientSolutionsNearby".Translate());
}
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.NutrientDetectionRadius".Translate(Ext.nutrientSolutionRadius));
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.TotalSpeedMultiplier".Translate(SpeedMultiplier.ToStringPercent()));
return builder.ToString().TrimEndNewlines();
}
// 获取质量因子描述
public string GetQualityFactorsDescription()
{
var builder = new StringBuilder();
builder.AppendLine("ARA_EquipmentIncubator.QualityFactors".Translate());
builder.AppendLine();
// 1. 建筑血量损失百分比
if (Ext.healthAffectsQuality)
{
float healthPercent = (float)HitPoints / MaxHitPoints;
builder.AppendLine("ARA_EquipmentIncubator.BuildingHealth".Translate(healthPercent.ToStringPercent()));
}
// 2. 房间质量因子
if (Ext.useRoomQualityFactor)
{
float roomFactor = GetRoomQualityFactor();
builder.AppendLine(roomFactor == 1.0f ?
"ARA_EquipmentIncubator.RoomFactorNormal".Translate() :
$"{(roomFactor > 1.0f ? "" : "")} {"ARA_EquipmentIncubator.RoomFactorModified".Translate()}{roomFactor.ToStringPercent()}");
}
// 3. 附近其他卵
int nearbyOothecaCount = CountNearbyOtherOothecas();
if (nearbyOothecaCount > 0)
{
builder.AppendLine("ARA_EquipmentIncubator.NearbyOothecas".Translate(
nearbyOothecaCount,
Mathf.Min(nearbyOothecaCount * Ext.nearbyOothecaPenaltyPerUnit * 100, 100)));
}
else
{
builder.AppendLine("ARA_EquipmentIncubator.NoNearbyOothecas".Translate());
}
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.OothecaDetectionRadius".Translate(Ext.nearbyOothecaRadius));
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.TotalQualityMultiplier".Translate(QualityMultiplier.ToStringPercent()));
return builder.ToString().TrimEndNewlines();
}
// 构建呼叫幼虫描述
private string BuildCallLarvaDescription(EquipmentIncubationConfig config)
{
var builder = new StringBuilder();
builder.AppendLine("ARA_EquipmentIncubator.CallLarvaTitle".Translate());
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.LarvaWillCome".Translate());
builder.AppendLine(config.thingDef.LabelCap);
builder.AppendLine();
if (Ext.larvaSearchRadius < 999f)
{
builder.AppendLine("ARA_EquipmentIncubator.LarvaSearchRadius".Translate(Ext.larvaSearchRadius));
}
return builder.ToString().TrimEndNewlines();
}
// 呼叫幼虫
private void CallLarva()
{
if (isIncubating)
{
Messages.Message("ARA_EquipmentIncubator.AlreadyIncubating".Translate() + " " + "ARA_EquipmentIncubator.CancelFirst".Translate(),
MessageTypeDefOf.RejectInput);
return;
}
if (assignedLarva != null)
{
Messages.Message("ARA_EquipmentIncubator.LarvaAlreadyOnWay".Translate(),
MessageTypeDefOf.RejectInput);
return;
}
var larva = FindLarva();
if (larva == null)
{
Messages.Message("ARA_EquipmentIncubator.NoLarvaeFound".Translate() + " " + "ARA_EquipmentIncubator.LarvaMustBeRace".Translate(),
MessageTypeDefOf.RejectInput);
return;
}
var job = JobMaker.MakeJob(ARA_JobDefOf.ARA_OperateEquipmentIncubator, this);
job.count = 1;
larva.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
assignedLarva = larva;
Messages.Message("ARA_EquipmentIncubator.LarvaCalled".Translate() + " " + "ARA_EquipmentIncubator.ArriveShortly".Translate(),
MessageTypeDefOf.PositiveEvent);
}
// 幼虫到达
public void NotifyLarvaArrived(Pawn larva)
{
if (larva.def.defName != "ArachnaeBase_Race_Larva")
{
ArachnaeLog.Debug($"Invalid larva arrived: {larva.def.defName}");
return;
}
larvaOperateTicksRemaining = 180;
assignedLarva = larva;
Messages.Message("ARA_EquipmentIncubator.LarvaArrived".Translate() + " " + "ARA_EquipmentIncubator.ActivatingOotheca".Translate(),
MessageTypeDefOf.SilentInput);
}
// 幼虫完成操作
public void NotifyLarvaOperationComplete(Pawn larva)
{
if (larva != assignedLarva)
{
ArachnaeLog.Debug("Larva operation complete called with wrong larva.");
return;
}
var config = EquipmentIncubatorData?.SelectedConfig;
if (config == null)
{
ArachnaeLog.Debug("No incubation config selected when larva completed operation.");
return;
}
incubatingThingDef = config.thingDef;
incubationDuration = config.DaysRequired * 60000f;
incubationProgress = 0f;
isIncubating = true;
qualityTotal = incubationDuration;
qualityProgress = 0f;
UpdateQualityMultiplier();
UpdateSpeedMultiplier();
assignedLarva = null;
larvaOperateTicksRemaining = 0;
Messages.Message("ARA_EquipmentIncubator.IncubationStarted".Translate() + " " + incubatingThingDef.LabelCap + ". " +
"ARA_EquipmentIncubator.ProcessWillComplete".Translate() + " " + config.DaysRequired + " " + "ARA_EquipmentIncubator.DaysBaseTime".Translate(),
MessageTypeDefOf.PositiveEvent);
}
// 取消孵化
private void CancelIncubation()
{
if (!isIncubating) return;
isIncubating = false;
incubationProgress = 0f;
incubationDuration = 0f;
incubatingThingDef = null;
qualityProgress = 0f;
qualityTotal = 0f;
Messages.Message("ARA_EquipmentIncubator.IncubationCancelled".Translate() + " " + "ARA_EquipmentIncubator.ContentsLost".Translate(),
MessageTypeDefOf.NeutralEvent);
}
// 完成孵化
private void CompleteIncubation()
{
if (incubatingThingDef == null) return;
float finalQualityPercent = QualityPercent;
// 生成物品
Thing thing = ThingMaker.MakeThing(incubatingThingDef);
// 应用质量影响
ApplyQualityEffects(thing, finalQualityPercent);
// 放置物品
var spawnPos = Position;
GenPlace.TryPlaceThing(thing, spawnPos, Map, ThingPlaceMode.Near);
// 重置状态
isIncubating = false;
incubationProgress = 0f;
incubationDuration = 0f;
incubatingThingDef = null;
qualityProgress = 0f;
qualityTotal = 0f;
// 显示消息
string qualityText = finalQualityPercent >= 0.9f ? "ARA_EquipmentIncubator.QualityExcellent".Translate() :
finalQualityPercent >= 0.7f ? "ARA_EquipmentIncubator.QualityGood".Translate() :
finalQualityPercent >= 0.5f ? "ARA_EquipmentIncubator.QualityAverage".Translate() :
finalQualityPercent >= 0.3f ? "ARA_EquipmentIncubator.QualityPoor".Translate() : "ARA_EquipmentIncubator.QualityVeryPoor".Translate();
Messages.Message("ARA_EquipmentIncubator.IncubationComplete".Translate() + " " + thing.LabelCap + " " +
"ARA_EquipmentIncubator.HasEmergedWith".Translate() + " " + qualityText + " " +
"ARA_EquipmentIncubator.Quality".Translate() + " (" + finalQualityPercent.ToStringPercent() + ").",
MessageTypeDefOf.PositiveEvent);
Destroy();
}
// 应用质量效果
private void ApplyQualityEffects(Thing thing, float qualityPercent)
{
// 应用质量效果到装备
if (thing.TryGetComp<CompQuality>() is CompQuality compQuality)
{
// 根据质量百分比设置质量等级
QualityCategory qualityCategory = qualityPercent >= 0.99f ? QualityCategory.Legendary :
qualityPercent >= 0.75f ? QualityCategory.Masterwork :
qualityPercent >= 0.6f ? QualityCategory.Excellent :
qualityPercent >= 0.45f ? QualityCategory.Good :
qualityPercent >= 0.3f ? QualityCategory.Normal : QualityCategory.Poor;
compQuality.SetQuality(qualityCategory, ArtGenerationContext.Outsider);
}
// 设置生命值百分比
if (qualityPercent < 1.0f)
{
float healthFactor = Mathf.Lerp(0.5f, 1.0f, qualityPercent);
thing.HitPoints = Mathf.RoundToInt(thing.MaxHitPoints * healthFactor);
}
}
// 获取剩余时间
public float GetRemainingTicks()
{
if (!isIncubating || incubationDuration <= incubationProgress) return 0f;
float remainingProgress = incubationDuration - incubationProgress;
float currentSpeed = SpeedMultiplier;
if (currentSpeed <= 0) return float.MaxValue;
return remainingProgress / currentSpeed;
}
public float GetRemainingDays()
{
return GetRemainingTicks() / 60000f;
}
public float GetRemainingHours()
{
float remainingTicks = GetRemainingTicks();
return (remainingTicks % 60000f) / 2500f;
}
// 检查字符串
public override string GetInspectString()
{
var baseString = base.GetInspectString();
var builder = new StringBuilder();
if (!string.IsNullOrEmpty(baseString))
{
builder.Append(baseString);
}
if (isIncubating && incubatingThingDef != null)
{
float progressPercent = AdjustedProgressPercent;
float daysRemaining = GetRemainingDays();
float hoursRemaining = GetRemainingHours();
if (builder.Length > 0) builder.AppendLine();
builder.Append("ARA_EquipmentIncubator.Incubating".Translate() + ": " + incubatingThingDef.LabelCap);
builder.AppendLine();
builder.Append("ARA_EquipmentIncubator.Progress".Translate() + ": " + progressPercent.ToStringPercent());
builder.AppendLine();
string timeText = "ARA_EquipmentIncubator.TimeRemaining".Translate() + ": " + daysRemaining.ToString("F1") + " " + "ARA_EquipmentIncubator.Days".Translate();
if (hoursRemaining > 0.1f && daysRemaining < 1f)
{
timeText += " (" + hoursRemaining.ToString("F1") + " " + "ARA_EquipmentIncubator.Hours".Translate() + ")";
}
builder.Append(timeText);
builder.AppendLine();
builder.Append("ARA_EquipmentIncubator.Speed".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
"ARA_EquipmentIncubator.Quality".Translate() + ": " + QualityMultiplier.ToStringPercent());
}
else if (assignedLarva != null)
{
if (builder.Length > 0) builder.AppendLine();
if (larvaOperateTicksRemaining > 0)
{
float secondsRemaining = larvaOperateTicksRemaining / 60f;
builder.Append("ARA_EquipmentIncubator.LarvaOperating".Translate() + ": " + secondsRemaining.ToString("F1") + " " + "ARA_EquipmentIncubator.SRemaining".Translate());
}
else
{
builder.Append("ARA_EquipmentIncubator.LarvaOnWay".Translate());
}
}
else if (!isIncubating)
{
var config = EquipmentIncubatorData?.SelectedConfig;
if (config != null)
{
if (builder.Length > 0) builder.AppendLine();
builder.Append("ARA_EquipmentIncubator.Target".Translate() + ": " + config.thingDef.LabelCap);
builder.AppendLine();
builder.Append("ARA_EquipmentIncubator.SpeedMultiplier".Translate() + ": " + SpeedMultiplier.ToStringPercent() + ", " +
"ARA_EquipmentIncubator.QualityMultiplier".Translate() + ": " + QualityMultiplier.ToStringPercent());
}
}
return builder.ToString().TrimEndNewlines();
}
// Gizmos
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (var gizmo in base.GetGizmos())
{
yield return gizmo;
}
if (Faction == Faction.OfPlayer)
{
if (!isIncubating && EquipmentIncubatorData?.IncubationConfigs?.Count > 0)
{
yield return CreateTargetSwitchGizmo();
}
var config = EquipmentIncubatorData?.SelectedConfig;
if (!isIncubating && config != null && config.IsResearchComplete)
{
yield return new Command_Action
{
defaultLabel = "ARA_EquipmentIncubator.CallLarva".Translate(),
defaultDesc = BuildCallLarvaDescription(config),
icon = ContentFinder<Texture2D>.Get("ArachnaeSwarm/UI/Commands/ARA_CallLarva", false) ?? BaseContent.BadTex,
action = CallLarva,
hotKey = KeyBindingDefOf.Misc3
};
}
if (isIncubating)
{
yield return new Command_Action
{
defaultLabel = "ARA_EquipmentIncubator.CancelIncubation".Translate(),
defaultDesc = "ARA_EquipmentIncubator.CancelIncubationDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/Cancel", false) ?? TexCommand.ClearPrioritizedWork,
action = CancelIncubation
};
}
}
}
// 创建切换目标Gizmo - 现在使用装备的图标
private Gizmo CreateTargetSwitchGizmo()
{
var configs = EquipmentIncubatorData?.IncubationConfigs;
if (configs == null || configs.Count == 0) return null;
var props = EquipmentIncubatorData?.props as CompProperties_EquipmentIncubatorData;
var selectedConfig = EquipmentIncubatorData?.SelectedConfig;
var switchButton = new Command_Action
{
defaultLabel = BuildSwitchButtonLabel(selectedConfig, props),
defaultDesc = BuildSwitchButtonDescription(selectedConfig, props),
icon = GetConfigIcon(selectedConfig),
action = ShowSelectionMenu,
hotKey = KeyBindingDefOf.Misc2
};
if (selectedConfig != null && !selectedConfig.IsResearchComplete)
{
if (selectedConfig.requiredResearch != null)
{
switchButton.Disable($"Requires research: {selectedConfig.requiredResearch.LabelCap}");
}
}
return switchButton;
}
// 获取配置图标 - 现在直接从ThingDef获取
private Texture2D GetConfigIcon(EquipmentIncubationConfig config)
{
if (config == null)
return BaseContent.BadTex;
// 如果配置中没有缓存图标尝试直接获取ThingDef的uiIcon
if (config.thingDef?.uiIcon != null)
return config.thingDef.uiIcon;
// 回退到默认图标
return ContentFinder<Texture2D>.Get("UI/Commands/Default", false) ?? BaseContent.BadTex;
}
private string BuildSwitchButtonLabel(EquipmentIncubationConfig config, CompProperties_EquipmentIncubatorData props)
{
if (config != null && config.thingDef != null)
{
return (props?.buttonLabel ?? "ARA_EquipmentIncubator.IncubateLabel").Translate(config.thingDef.LabelCap);
}
return (props?.buttonLabel ?? "ARA_EquipmentIncubator.IncubateLabel").Translate("None");
}
private string BuildSwitchButtonDescription(EquipmentIncubationConfig config, CompProperties_EquipmentIncubatorData props)
{
var builder = new StringBuilder();
builder.AppendLine((props?.buttonDesc ?? "ARA_EquipmentIncubator.ButtonDesc").Translate());
builder.AppendLine();
if (config != null)
{
if (config.thingDef != null)
{
builder.AppendLine($"ARA_EquipmentIncubator.ButtonLabel".Translate(config.thingDef.LabelCap));
if (!string.IsNullOrEmpty(config.thingDef.description))
{
builder.AppendLine(config.thingDef.description);
}
}
builder.AppendLine($"ARA_EquipmentIncubator.IncubationTime".Translate(config.DaysRequired));
if (config.requiredResearch != null)
{
if (config.requiredResearch.IsFinished)
builder.AppendLine($"Research: {config.requiredResearch.LabelCap} (Completed)");
else
builder.AppendLine($"Research: {config.requiredResearch.LabelCap} (Required)");
}
}
builder.AppendLine();
builder.AppendLine("ARA_EquipmentIncubator.ButtonDesc".Translate());
return builder.ToString().TrimEndNewlines();
}
private void ShowSelectionMenu()
{
var configs = EquipmentIncubatorData?.IncubationConfigs;
var props = EquipmentIncubatorData?.props as CompProperties_EquipmentIncubatorData;
if (configs == null || configs.Count == 0) return;
var options = new List<FloatMenuOption>();
int currentIndex = EquipmentIncubatorData.GetSelectedIndex();
for (int i = 0; i < configs.Count; i++)
{
int index = i;
var config = configs[i];
if (config == null || config.thingDef == null) continue;
string label = config.thingDef.LabelCap;
string description = config.GetDescription();
string prefix = (i == currentIndex) ? "✓ " : " ";
// 使用原版FloatMenuOption的构造函数直接传入图标
FloatMenuOption option;
// 尝试获取ThingDef的图标
Texture2D icon = config.thingDef.uiIcon;
if (icon != null)
{
// 使用带有Texture2D图标的构造函数
option = new FloatMenuOption(
prefix + label,
() => SwitchToConfig(index),
icon,
Color.white,
MenuOptionPriority.Default,
null, // mouseoverGuiAction
null, // revalidateClickTarget
0f, // extraPartWidth
null, // extraPartOnGUI
null, // revalidateWorldClickTarget
true, // playSelectionSound
0, // orderInPriority
HorizontalJustification.Left, // iconJustification
false // extraPartRightJustified
);
}
else
{
// 如果没有图标,使用普通构造函数
option = new FloatMenuOption(
prefix + label,
() => SwitchToConfig(index)
);
}
// 设置工具提示
option.tooltip = description;
// 如果研究未完成,禁用选项
if (!config.IsResearchComplete)
{
option.Label = prefix + label;
option.Disabled = true;
option.tooltip = description + "\n\n " + "ARA_EquipmentIncubator.ResearchRequired".Translate() + " " + config.requiredResearch.LabelCap;
}
options.Add(option);
}
if (options.Count > 0)
{
Find.WindowStack.Add(new FloatMenu(options,
(props?.menuTitle ?? "ARA_EquipmentIncubator.MenuTitle").Translate()));
}
}
private void SwitchToConfig(int index)
{
if (EquipmentIncubatorData != null)
{
EquipmentIncubatorData.SwitchToConfig(index);
var config = EquipmentIncubatorData.SelectedConfig;
if (config != null && config.thingDef != null)
{
Messages.Message($"ARA_EquipmentIncubator.TargetSwitched".Translate(config.thingDef.LabelCap),
this, MessageTypeDefOf.SilentInput);
}
}
}
// 查找幼虫
private Pawn FindLarva()
{
var map = Map;
if (map == null) return null;
float searchRadius = Ext.larvaSearchRadius;
foreach (var pawn in map.mapPawns.SpawnedPawnsInFaction(Faction))
{
if (pawn.def.defName == "ArachnaeBase_Race_Larva")
{
if (searchRadius < 999f)
{
float distance = pawn.Position.DistanceTo(Position);
if (distance > searchRadius)
continue;
}
if (!pawn.Downed && !pawn.InMentalState &&
pawn.mindState != null &&
(pawn.CurJob == null || pawn.CurJob.def != ARA_JobDefOf.ARA_OperateEquipmentIncubator))
{
return pawn;
}
}
}
return null;
}
// 每tick更新
protected override void Tick()
{
base.Tick();
if (larvaOperateTicksRemaining > 0)
{
larvaOperateTicksRemaining--;
}
if (isIncubating)
{
if (lastMultiplierUpdateTick < 0 || Find.TickManager.TicksGame - lastMultiplierUpdateTick >= MultiplierUpdateInterval)
{
UpdateSpeedMultiplier();
UpdateQualityMultiplier();
}
float currentSpeed = SpeedMultiplier;
incubationProgress += currentSpeed;
qualityProgress += currentSpeed * QualityMultiplier;
if (incubationProgress >= incubationDuration)
{
CompleteIncubation();
}
}
}
// 检查是否在孵化间中
private bool IsInIncubatorRoom()
{
if (!Ext.requiresIncubatorRoom)
return true;
var room = this.GetRoom();
if (room == null) return false;
return room.Role != null && room.Role.defName == "ARA_Incubator_Room";
}
// 计算营养液数量
private int CountNearbyNutrientSolutions()
{
var map = Map;
if (map == null) return 0;
int count = 0;
int radius = Ext.NutrientSolutionRadiusInt;
for (int x = -radius; x <= radius; x++)
{
for (int y = -radius; y <= radius; y++)
{
IntVec3 cell = Position + new IntVec3(x, 0, y);
if (cell.InBounds(map))
{
TerrainDef terrain = map.terrainGrid.TerrainAt(cell);
if (terrain != null && terrain.defName == "ARA_Incubator_Nutrient_Solution")
{
count++;
}
}
}
}
return count;
}
// 计算房间质量因子
private float GetRoomQualityFactor()
{
if (!Ext.useRoomQualityFactor)
return 1.0f;
var room = this.GetRoom();
if (room == null) return 1.0f;
var statDef = DefDatabase<RoomStatDef>.GetNamedSilentFail("ARA_IncubatorQualityFactor");
if (statDef != null)
{
return room.GetStat(statDef);
}
return 1.0f;
}
// 计算附近其他卵的数量
private int CountNearbyOtherOothecas()
{
var map = Map;
if (map == null) return 0;
int count = 0;
var allBuildings = map.listerThings.ThingsOfDef(this.def);
foreach (var building in allBuildings)
{
if (building == this) continue;
if (building.def.defName == "ARA_Pawn_Ootheca" || building.def.defName == "ARA_Equipment_Ootheca")
{
bool isNearby = false;
if (Ext.checkSameRoomForOotheca)
{
var room = building.GetRoom();
if (room != null && room == this.GetRoom())
{
isNearby = true;
}
}
if (!isNearby)
{
float distance = building.Position.DistanceTo(this.Position);
if (distance <= Ext.nearbyOothecaRadius)
{
isNearby = true;
}
}
if (isNearby)
{
count++;
}
}
}
return count;
}
// 更新速度乘数
private void UpdateSpeedMultiplier()
{
float multiplier = 1.0f;
if (Ext.requiresIncubatorRoom && !IsInIncubatorRoom())
{
multiplier *= Ext.speedPenaltyOutsideIncubator;
}
int nutrientSolutionCount = CountNearbyNutrientSolutions();
float nutrientBonus = 1.0f + (nutrientSolutionCount * Ext.nutrientSolutionBonusPerTile);
multiplier *= nutrientBonus;
speedMultiplier = multiplier;
lastMultiplierUpdateTick = Find.TickManager.TicksGame;
}
// 更新质量乘数
private void UpdateQualityMultiplier()
{
float multiplier = 1.0f;
if (Ext.healthAffectsQuality)
{
float healthPercent = (float)HitPoints / MaxHitPoints;
multiplier *= healthPercent;
}
if (Ext.useRoomQualityFactor)
{
float roomFactor = GetRoomQualityFactor();
multiplier *= roomFactor;
}
int nearbyOothecaCount = CountNearbyOtherOothecas();
float oothecaPenalty = Mathf.Max(0f, 1.0f - (nearbyOothecaCount * Ext.nearbyOothecaPenaltyPerUnit));
multiplier *= oothecaPenalty;
qualityMultiplier = Mathf.Clamp(multiplier, 0f, 1.0f);
}
// 保存/加载
public override void ExposeData()
{
base.ExposeData();
Scribe_Values.Look(ref isIncubating, "isIncubating", false);
Scribe_Values.Look(ref incubationProgress, "incubationProgress", 0f);
Scribe_Values.Look(ref incubationDuration, "incubationDuration", 0f);
Scribe_Defs.Look(ref incubatingThingDef, "incubatingThingDef");
Scribe_References.Look(ref assignedLarva, "assignedLarva");
Scribe_Values.Look(ref larvaOperateTicksRemaining, "larvaOperateTicksRemaining", 0);
Scribe_Values.Look(ref speedMultiplier, "speedMultiplier", 1.0f);
Scribe_Values.Look(ref lastMultiplierUpdateTick, "lastMultiplierUpdateTick", -1);
Scribe_Values.Look(ref qualityMultiplier, "qualityMultiplier", 1.0f);
Scribe_Values.Look(ref qualityProgress, "qualityProgress", 0f);
Scribe_Values.Look(ref qualityTotal, "qualityTotal", 0f);
}
}
}