This commit is contained in:
2026-02-28 11:50:54 +08:00
parent 60cde0317d
commit bd4843bc89
19 changed files with 1212 additions and 367 deletions

View File

@@ -1,6 +1,7 @@
// File: FloatMenuOptionProvider_EnterMech.cs
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using Verse;
using Verse.AI;
@@ -8,6 +9,7 @@ namespace WulaFallenEmpire
{
public class FloatMenuOptionProvider_EnterMech : FloatMenuOptionProvider
{
private static readonly List<Pawn> tmpPawns = new List<Pawn>();
// 检查Thing是否为机甲
private bool IsMech(Thing thing)
@@ -15,9 +17,9 @@ namespace WulaFallenEmpire
return thing is Wulamechunit || thing?.GetType()?.IsSubclassOf(typeof(Wulamechunit)) == true;
}
protected override bool Drafted => true; // 征召状态下不能进入机甲
protected override bool Drafted => false; // 征召状态下不能进入机甲
protected override bool Undrafted => true; // 非征召状态下可以进入
protected override bool Multiselect => true; // 支持多选
protected override bool Multiselect => true; // 支持多选
// 检查是否适用于当前上下文
protected override bool AppliesInt(FloatMenuContext context)
@@ -50,40 +52,97 @@ namespace WulaFallenEmpire
if (comp == null)
return false;
// 检查殖民者是否已经在机甲内
// 由于CompMechPilotHolder没有ContainsPilot方法我们需要通过其他方式检查
if (IsPawnInMech(context.FirstSelectedPawn, mech))
return false;
return true;
}
// 检查殖民者是否已经在机甲内替代ContainsPilot
private bool IsPawnInMech(Pawn pawn, Thing mech)
// 重写:获取选项
public override IEnumerable<FloatMenuOption> GetOptionsFor(Thing clickedThing, FloatMenuContext context)
{
var comp = mech.TryGetComp<CompMechPilotHolder>();
if (comp == null)
return false;
// 尝试通过内部容器检查
var holder = comp as IThingHolder;
if (holder != null)
if (!AppliesInt(context))
yield break;
if (context.IsMultiselect)
{
var things = holder.GetDirectlyHeldThings();
if (things != null && things.Contains(pawn))
return true;
var option = GetMultiselectEnterMechOption(clickedThing, context);
if (option != null)
yield return option;
yield break;
}
// 或者尝试通过其他属性检查
// 这里假设CompMechPilotHolder有HasPilots属性
if (comp.HasPilots)
var singleOption = GetSingleOptionFor(clickedThing, context);
if (singleOption != null)
yield return singleOption;
}
// 获取多选选项
private FloatMenuOption GetMultiselectEnterMechOption(Thing clickedThing, FloatMenuContext context)
{
tmpPawns.Clear();
var mech = clickedThing as Wulamechunit;
var comp = mech?.TryGetComp<CompMechPilotHolder>();
if (mech == null || comp == null)
return null;
// 收集所有可以进入机甲的Pawn
foreach (var pawn in context.ValidSelectedPawns)
{
// 如果有必要,可以通过反射或其他方式检查具体驾驶员
// 暂时返回false假设不在机甲内
return false;
if (CanPawnEnterMech(pawn, mech, comp))
{
tmpPawns.Add(pawn);
}
}
return false;
if (tmpPawns.Count == 0)
return null;
// 检查是否有机甲已满的情况
string failStr = null;
if (comp.IsFull)
{
failStr = "WULA_MechFull".Translate();
}
if (!failStr.NullOrEmpty())
{
return new FloatMenuOption(
"WULA_EnterMech".Translate(mech.LabelShort) + ": " + failStr,
null,
MenuOptionPriority.DisabledOption
);
}
// 计算可以进入的数量
int canEnterCount = 0;
foreach (var pawn in tmpPawns)
{
if (comp.HasRoom)
{
canEnterCount++;
}
else
{
break;
}
}
string label = "WULA_EnterMech".Translate(mech.LabelShort);
return new FloatMenuOption(label, () =>
{
FleckMaker.Static(mech.DrawPos, mech.MapHeld, FleckDefOf.FeedbackEquip);
// 为每个可以进入的Pawn创建Job
foreach (var pawn in tmpPawns)
{
if (comp.HasRoom && CanPawnEnterMech(pawn, mech, comp))
{
Job job = JobMaker.MakeJob(Wula_JobDefOf.WULA_EnterMech, mech);
pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
}
}
}, MenuOptionPriority.High);
}
// 获取单个选项
@@ -111,6 +170,25 @@ namespace WulaFallenEmpire
return CreateEnterMechOption(mech, context.FirstSelectedPawn, comp);
}
// 检查殖民者是否已经在机甲内
private bool IsPawnInMech(Pawn pawn, Thing mech)
{
var comp = mech.TryGetComp<CompMechPilotHolder>();
if (comp == null)
return false;
// 尝试通过内部容器检查
var holder = comp as IThingHolder;
if (holder != null)
{
var things = holder.GetDirectlyHeldThings();
if (things != null && things.Contains(pawn))
return true;
}
return false;
}
// 创建进入机甲的菜单选项
private FloatMenuOption CreateEnterMechOption(Wulamechunit mech, Pawn pawn, CompMechPilotHolder comp)
{
@@ -118,7 +196,7 @@ namespace WulaFallenEmpire
string disabledReason = "";
// 检查条件是否允许进入
bool canEnter = CanEnterMech(mech, pawn, comp, ref disabledReason);
bool canEnter = CanPawnEnterMech(pawn, mech, comp, ref disabledReason);
// 如果条件允许,创建可点击的选项
if (canEnter)
@@ -129,7 +207,7 @@ namespace WulaFallenEmpire
Job job = JobMaker.MakeJob(Wula_JobDefOf.WULA_EnterMech, mech);
pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
// 播放音效(如果有的话)
// 播放音效
FleckMaker.Static(mech.DrawPos, mech.MapHeld, FleckDefOf.FeedbackEquip);
}, MenuOptionPriority.High);
}
@@ -143,8 +221,8 @@ namespace WulaFallenEmpire
}
}
// 检查殖民者是否可以进入机甲
private bool CanEnterMech(Wulamechunit mech, Pawn pawn, CompMechPilotHolder comp, ref string disabledReason)
// 检查殖民者是否可以进入机甲(带原因)
private bool CanPawnEnterMech(Pawn pawn, Wulamechunit mech, CompMechPilotHolder comp, ref string disabledReason)
{
// 检查机甲是否已满
if (comp.IsFull)
@@ -160,6 +238,13 @@ namespace WulaFallenEmpire
return false;
}
// 检查殖民者是否已经在机甲内
if (IsPawnInMech(pawn, mech))
{
disabledReason = "AlreadyInMech".Translate();
return false;
}
// 检查距离
if (!pawn.CanReach(mech, PathEndMode.Touch, Danger.Deadly))
{
@@ -207,7 +292,21 @@ namespace WulaFallenEmpire
return false;
}
// 检查是否被征召(驾驶员不能是征召状态)
if (pawn.Drafted)
{
disabledReason = "Drafted".Translate();
return false;
}
return true;
}
// 检查殖民者是否可以进入机甲(简化版)
private bool CanPawnEnterMech(Pawn pawn, Wulamechunit mech, CompMechPilotHolder comp)
{
string disabledReason = "";
return CanPawnEnterMech(pawn, mech, comp, ref disabledReason);
}
}
}