zc
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
// CompMechDefaultPilot.cs
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class CompMechDefaultPilot : ThingComp
|
||||
{
|
||||
public CompProperties_MechDefaultPilot Props => (CompProperties_MechDefaultPilot)props;
|
||||
private bool defaultPilotsSpawned = false;
|
||||
|
||||
public override void Initialize(CompProperties props)
|
||||
{
|
||||
base.Initialize(props);
|
||||
}
|
||||
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
if (respawningAfterLoad)
|
||||
return;
|
||||
|
||||
// 检查是否需要生成默认驾驶员
|
||||
TrySpawnDefaultPilots();
|
||||
}
|
||||
|
||||
// 尝试生成默认驾驶员
|
||||
public void TrySpawnDefaultPilots()
|
||||
{
|
||||
if (defaultPilotsSpawned)
|
||||
return;
|
||||
|
||||
var mech = parent as Pawn;
|
||||
if (mech == null)
|
||||
return;
|
||||
|
||||
var mechFaction = mech.Faction;
|
||||
if (mechFaction == null)
|
||||
return;
|
||||
|
||||
// 检查阵营条件
|
||||
bool isPlayerFaction = mechFaction == Faction.OfPlayer;
|
||||
if (isPlayerFaction && !Props.enableForPlayerFaction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isPlayerFaction && !Props.enableForNonPlayerFaction)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查生成几率
|
||||
if (Rand.Value > Props.defaultPilotChance)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取驾驶员容器
|
||||
var pilotHolder = mech.TryGetComp<CompMechPilotHolder>();
|
||||
if (pilotHolder == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否需要生成
|
||||
if (Props.spawnOnlyIfNoPilot && pilotHolder.HasPilots)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果需要替换现有驾驶员,先移除所有
|
||||
if (Props.replaceExistingPilots && pilotHolder.HasPilots)
|
||||
{
|
||||
pilotHolder.RemoveAllPilots();
|
||||
}
|
||||
|
||||
// 计算要生成的驾驶员数量
|
||||
int maxPilots = Props.maxDefaultPilots > 0 ?
|
||||
Props.maxDefaultPilots : pilotHolder.Props.maxPilots;
|
||||
int pilotsToSpawn = maxPilots - pilotHolder.CurrentPilotCount;
|
||||
|
||||
if (pilotsToSpawn <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成驾驶员
|
||||
int spawnedCount = 0;
|
||||
for (int i = 0; i < pilotsToSpawn; i++)
|
||||
{
|
||||
if (TrySpawnDefaultPilot(mech, pilotHolder))
|
||||
spawnedCount++;
|
||||
}
|
||||
|
||||
if (spawnedCount > 0)
|
||||
{
|
||||
defaultPilotsSpawned = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 尝试生成单个默认驾驶员
|
||||
private bool TrySpawnDefaultPilot(Pawn mech, CompMechPilotHolder pilotHolder)
|
||||
{
|
||||
// 选择驾驶员类型
|
||||
var pilotKind = Props.SelectRandomPilotKind();
|
||||
if (pilotKind == null)
|
||||
{
|
||||
Log.Warning($"[DD] No valid pilot kind found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 创建驾驶员生成请求
|
||||
PawnGenerationRequest request = new PawnGenerationRequest(
|
||||
kind: pilotKind,
|
||||
faction: mech.Faction,
|
||||
context: PawnGenerationContext.NonPlayer,
|
||||
tile: mech.Map?.Tile ?? -1,
|
||||
forceGenerateNewPawn: true,
|
||||
allowDead: false,
|
||||
allowDowned: false,
|
||||
canGeneratePawnRelations: false,
|
||||
mustBeCapableOfViolence: false,
|
||||
colonistRelationChanceFactor: 0f,
|
||||
forceAddFreeWarmLayerIfNeeded: false,
|
||||
allowGay: true,
|
||||
allowFood: true,
|
||||
allowAddictions: true
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
// 生成驾驶员
|
||||
Pawn pilot = PawnGenerator.GeneratePawn(request);
|
||||
|
||||
// 设置驾驶员名字
|
||||
if (pilot.Name == null || pilot.Name is NameSingle)
|
||||
{
|
||||
pilot.Name = PawnBioAndNameGenerator.GeneratePawnName(pilot, NameStyle.Numeric);
|
||||
}
|
||||
|
||||
// 添加到机甲
|
||||
if (pilotHolder.CanAddPilot(pilot))
|
||||
{
|
||||
pilotHolder.AddPilot(pilot);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning($"[DD] Cannot add pilot {pilot.LabelShortCap} to mech");
|
||||
// 清理生成的pawn
|
||||
pilot.Destroy();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Log.Error($"[DD] Error generating default pilot: {ex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 开发者命令:强制生成默认驾驶员
|
||||
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||
{
|
||||
foreach (Gizmo gizmo in base.CompGetGizmosExtra())
|
||||
{
|
||||
yield return gizmo;
|
||||
}
|
||||
|
||||
if (DebugSettings.ShowDevGizmos)
|
||||
{
|
||||
var mech = parent as Pawn;
|
||||
if (mech != null && mech.Faction == Faction.OfPlayer)
|
||||
{
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "DEV: Spawn Default Pilots",
|
||||
defaultDesc = "Force spawn default pilots for this mech",
|
||||
action = () =>
|
||||
{
|
||||
defaultPilotsSpawned = false;
|
||||
TrySpawnDefaultPilots();
|
||||
Messages.Message("Default pilots spawned", parent, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
};
|
||||
|
||||
yield return new Command_Action
|
||||
{
|
||||
defaultLabel = "DEV: Clear Default Pilots",
|
||||
defaultDesc = "Remove default pilots and allow respawning",
|
||||
action = () =>
|
||||
{
|
||||
defaultPilotsSpawned = false;
|
||||
var pilotHolder = mech.TryGetComp<CompMechPilotHolder>();
|
||||
if (pilotHolder != null)
|
||||
{
|
||||
pilotHolder.RemoveAllPilots();
|
||||
}
|
||||
Messages.Message("Default pilots cleared", parent, MessageTypeDefOf.NeutralEvent);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref defaultPilotsSpawned, "defaultPilotsSpawned", false);
|
||||
}
|
||||
|
||||
// 当机甲阵营改变时重新检查
|
||||
public void Notify_FactionChanged()
|
||||
{
|
||||
// 重置标记,允许在新阵营下生成驾驶员
|
||||
defaultPilotsSpawned = false;
|
||||
TrySpawnDefaultPilots();
|
||||
}
|
||||
|
||||
// 当驾驶员被移除时,如果全部移除,允许重新生成
|
||||
public void Notify_PilotRemoved()
|
||||
{
|
||||
var pilotHolder = parent.TryGetComp<CompMechPilotHolder>();
|
||||
if (pilotHolder != null && !pilotHolder.HasPilots)
|
||||
{
|
||||
// 如果所有驾驶员都被移除了,重置标记
|
||||
defaultPilotsSpawned = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// CompProperties_MechDefaultPilot.cs
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace WulaFallenEmpire
|
||||
{
|
||||
public class DefaultPilotEntry
|
||||
{
|
||||
public PawnKindDef pawnKind;
|
||||
public float weight = 1f; // 权重,用于随机选择
|
||||
public bool required = false; // 是否必选
|
||||
|
||||
public DefaultPilotEntry() { }
|
||||
|
||||
public DefaultPilotEntry(PawnKindDef pawnKind, float weight = 1f, bool required = false)
|
||||
{
|
||||
this.pawnKind = pawnKind;
|
||||
this.weight = weight;
|
||||
this.required = required;
|
||||
}
|
||||
}
|
||||
|
||||
public class CompProperties_MechDefaultPilot : CompProperties
|
||||
{
|
||||
// 基本配置
|
||||
public bool enableForNonPlayerFaction = true;
|
||||
public bool enableForPlayerFaction = false; // 玩家阵营是否也生成默认驾驶员
|
||||
public float defaultPilotChance = 1.0f; // 默认生成几率
|
||||
|
||||
// 驾驶员配置
|
||||
public List<DefaultPilotEntry> defaultPilots = new List<DefaultPilotEntry>();
|
||||
|
||||
// 高级配置
|
||||
public bool spawnOnlyIfNoPilot = true; // 只在没有驾驶员时生成
|
||||
public bool replaceExistingPilots = false; // 替换现有驾驶员
|
||||
public int maxDefaultPilots = -1; // -1表示使用CompMechPilotHolder的最大容量
|
||||
|
||||
public CompProperties_MechDefaultPilot()
|
||||
{
|
||||
this.compClass = typeof(CompMechDefaultPilot);
|
||||
}
|
||||
|
||||
public override IEnumerable<string> ConfigErrors(ThingDef parentDef)
|
||||
{
|
||||
foreach (string error in base.ConfigErrors(parentDef))
|
||||
{
|
||||
yield return error;
|
||||
}
|
||||
|
||||
if (defaultPilotChance < 0f || defaultPilotChance > 1f)
|
||||
{
|
||||
yield return $"defaultPilotChance must be between 0 and 1 for {parentDef.defName}";
|
||||
}
|
||||
|
||||
if (defaultPilots.Count == 0)
|
||||
{
|
||||
yield return $"No defaultPilots defined for {parentDef.defName}";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var entry in defaultPilots)
|
||||
{
|
||||
if (entry.pawnKind == null)
|
||||
{
|
||||
yield return $"Null pawnKind in defaultPilots for {parentDef.defName}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取有效的默认驾驶员列表
|
||||
public List<DefaultPilotEntry> GetValidDefaultPilots()
|
||||
{
|
||||
return defaultPilots.FindAll(p => p.pawnKind != null);
|
||||
}
|
||||
|
||||
// 计算总权重
|
||||
public float GetTotalWeight()
|
||||
{
|
||||
float total = 0f;
|
||||
foreach (var entry in defaultPilots)
|
||||
{
|
||||
if (entry.pawnKind != null && !entry.required)
|
||||
{
|
||||
total += entry.weight;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// 随机选择一个驾驶员类型
|
||||
public PawnKindDef SelectRandomPilotKind()
|
||||
{
|
||||
var validPilots = GetValidDefaultPilots();
|
||||
if (validPilots.Count == 0)
|
||||
return null;
|
||||
|
||||
// 先检查必选项
|
||||
foreach (var entry in validPilots)
|
||||
{
|
||||
if (entry.required)
|
||||
return entry.pawnKind;
|
||||
}
|
||||
|
||||
// 如果没有必选项,按权重随机选择
|
||||
float totalWeight = GetTotalWeight();
|
||||
if (totalWeight <= 0f)
|
||||
return validPilots[0].pawnKind; // 回退到第一个
|
||||
|
||||
float random = Rand.Range(0f, totalWeight);
|
||||
float current = 0f;
|
||||
|
||||
foreach (var entry in validPilots)
|
||||
{
|
||||
if (entry.required)
|
||||
continue;
|
||||
|
||||
current += entry.weight;
|
||||
if (random <= current)
|
||||
return entry.pawnKind;
|
||||
}
|
||||
|
||||
return validPilots[validPilots.Count - 1].pawnKind; // 回退到最后一个
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user