This commit is contained in:
2025-12-09 12:02:39 +08:00
parent 720487805f
commit 142df124dd
22 changed files with 991 additions and 539 deletions

View File

@@ -0,0 +1,183 @@
using System.Collections.Generic;
using RimWorld;
using Verse;
using Verse.AI;
using Verse.Sound;
namespace WulaFallenEmpire
{
public class PawnsArrivalModeWorker_EdgeTeleport : PawnsArrivalModeWorker
{
public override void Arrive(List<Pawn> pawns, IncidentParms parms)
{
Map map = (Map)parms.target;
// 如果没有指定生成中心则使用EdgeDrop的查找方式
if (!parms.spawnCenter.IsValid)
{
parms.spawnCenter = DropCellFinder.FindRaidDropCenterDistant(map);
}
// 为每个Pawn分配一个传送位置在生成中心附近
foreach (Pawn pawn in pawns)
{
if (pawn == null || pawn.Dead || pawn.Destroyed)
continue;
// 找到可用的传送位置
IntVec3 teleportPos = FindTeleportPosition(map, parms.spawnCenter);
// 如果Pawn已经在其他地图需要先将其移到当前地图
if (pawn.Map != map)
{
// 确保Pawn不在任何地图中
if (pawn.Spawned)
{
pawn.DeSpawn();
}
// 将Pawn放入当前地图
GenSpawn.Spawn(pawn, teleportPos, map, parms.spawnRotation);
}
else
{
// 如果已经在当前地图,直接移动位置
pawn.Position = teleportPos;
pawn.Notify_Teleported(true, false);
}
// 播放传送效果
PlayTeleportEffect(pawn, teleportPos, map);
// 确保Pawn有适当的状态
EnsurePawnStateAfterTeleport(pawn);
}
}
public override bool TryResolveRaidSpawnCenter(IncidentParms parms)
{
Map map = (Map)parms.target;
// 与EdgeDrop相同的方式解析生成中心
if (!parms.spawnCenter.IsValid)
{
parms.spawnCenter = DropCellFinder.FindRaidDropCenterDistant(map);
}
parms.spawnRotation = Rot4.Random;
return true;
}
/// <summary>
/// 找到可用的传送位置
/// </summary>
private IntVec3 FindTeleportPosition(Map map, IntVec3 center)
{
// 在中心点附近寻找可用的单元格
// 我们使用与EdgeWalkInGroups类似的逻辑但立即传送
if (CellFinder.TryFindRandomCellNear(center, map, 10,
c => c.Standable(map) &&
!c.Fogged(map) &&
c.GetRoof(map) != RoofDefOf.RoofRockThick && // 排除厚岩顶
map.reachability.CanReachColony(c),
out IntVec3 result))
{
return result;
}
// 如果找不到合适的单元格,使用备选方案
if (RCellFinder.TryFindRandomPawnEntryCell(out result, map, CellFinder.EdgeRoadChance_Hostile))
{
return result;
}
// 最后的手段:使用中心点
return center;
}
/// <summary>
/// 播放传送效果
/// </summary>
private void PlayTeleportEffect(Pawn pawn, IntVec3 pos, Map map)
{
try
{
// 播放Skip_ExitNoDelay效果
EffecterDef teleportEffect = DefDatabase<EffecterDef>.GetNamed("Skip_ExitNoDelay");
if (teleportEffect != null)
{
Effecter effecter = teleportEffect.Spawn();
effecter.ticksLeft = 30; // 设置效果持续时间
effecter.Trigger(new TargetInfo(pos, map), new TargetInfo(pos, map));
effecter.Cleanup();
}
else
{
// 如果找不到指定的效果,使用跳跃效果
EffecterDef jumpEffect = EffecterDefOf.Skip_Exit;
if (jumpEffect != null)
{
Effecter effecter = jumpEffect.Spawn();
effecter.ticksLeft = 30;
effecter.Trigger(new TargetInfo(pos, map), new TargetInfo(pos, map));
effecter.Cleanup();
}
}
// 可选:播放声音效果
SoundDef sound = SoundDefOf.PsychicPulseGlobal;
if (sound != null)
{
sound.PlayOneShot(new TargetInfo(pos, map));
}
}
catch (System.Exception ex)
{
Log.Warning($"Failed to play teleport effect for {pawn?.LabelCap}: {ex}");
}
}
/// <summary>
/// 确保Pawn传送后的状态
/// </summary>
private void EnsurePawnStateAfterTeleport(Pawn pawn)
{
if (pawn == null)
return;
// 重置当前工作
if (pawn.CurJob != null)
{
pawn.jobs.StopAll();
}
// 如果是殖民者或友军,设置为等待战斗状态
if (pawn.Faction == Faction.OfPlayer || !pawn.HostileTo(Faction.OfPlayer))
{
pawn.jobs.StartJob(new Job(JobDefOf.Wait_Combat, 600, true),
JobCondition.InterruptForced, null, false, true, null, null, false);
}
// 重置心理状态
if (pawn.mindState != null)
{
pawn.mindState.enemyTarget = null;
pawn.mindState.mentalStateHandler?.Reset();
}
// 如果是机械族,可能需要特殊处理
if (pawn.RaceProps.IsMechanoid)
{
var comp = pawn.GetComp<CompAutonomousMech>();
if (comp != null)
{
// 如果是自主机械,确保进入适当状态
if (!pawn.Drafted && pawn.Faction == Faction.OfPlayer)
{
pawn.drafter.Drafted = false;
}
}
}
}
}
}