传送器

This commit is contained in:
2025-11-25 17:31:19 +08:00
parent 79a02f99e0
commit e0b156f687
11 changed files with 794 additions and 18 deletions

View File

@@ -1031,9 +1031,9 @@
<!-- 支援 -->
<AbilityDef>
<defName>WULA_Support_Shield_Projection</defName>
<label>护盾投射</label>
<description>以启动拒止舰的止戈立场,在指定地点投射一面球形护盾,阻挡并反射所有的外来射弹</description>
<defName>WULA_Support_Holographic_Flag</defName>
<label>空投旗帜</label>
<description>从拒止舰队上扔一面全息旗帜到指定地点,激励附近的乌拉星人更英勇地战斗</description>
<iconPath>Wula/UI/Abilities/WULA_Firepower_Minigun_Strafe</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
@@ -1051,10 +1051,42 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_GlobalFlyOverCooldown">
<globalCooldownTicks>1000</globalCooldownTicks>
<requiredFacility>BombardmentFacility</requiredFacility>
<li Class="WulaFallenEmpire.CompProperties_AbilityCallSkyfaller">
<delayTicks>0</delayTicks>
<skyfallerDef>WULA_Holographic_Flag_Building_Skyfaller</skyfallerDef>
<previewRadius>15</previewRadius>
<previewColor>(1,1,1,0.5)</previewColor>
</li>
<li Class="WulaFallenEmpire.CompProperties_RequireFlyOverFacility">
<requiredFacility>FactoryFacility</requiredFacility>
<facilityNotFoundMessage>需要拥有&lt;color=#BD2F31>&lt;i>支援设施&lt;/i>&lt;/color>设施的战舰在地图上才能进行轨道炮击支援</facilityNotFoundMessage>
</li>
<!-- <li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Firepower_Minigun_Technology</requiredResearch>
</li> -->
</comps>
</AbilityDef>
<AbilityDef>
<defName>WULA_Support_Shield_Projection</defName>
<label>护盾投射</label>
<description>从拒止舰队上扔一面附拒止护盾的全息旗帜到指定地点,激励附近的乌拉星人更英勇地战斗。拒止护盾可以反射所有的敌方射弹,己方的开火不受影响。\n\n在工作一段时间后该系统将自行烧毁。</description>
<iconPath>Wula/UI/Abilities/WULA_Firepower_Minigun_Strafe</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<drawAimPie>false</drawAimPie>
<requireLineOfSight>false</requireLineOfSight>
<warmupTime>1</warmupTime>
<range>120</range>
<targetable>true</targetable>
<targetParams>
<canTargetSelf>false</canTargetSelf>
<canTargetLocations>true</canTargetLocations>
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityCallSkyfaller">
<delayTicks>0</delayTicks>
<skyfallerDef>WULA_Support_Shield_Projection_Skyfaller</skyfallerDef>
@@ -1071,4 +1103,41 @@
</li> -->
</comps>
</AbilityDef>
<AbilityDef>
<defName>WULA_Support_AreaTeleporter</defName>
<label>区域传送器</label>
<description>从拒止舰队上扔一面附拒止护盾的全息旗帜到指定地点,激励附近的乌拉星人更英勇地战斗。拒止护盾可以反射所有的敌方射弹,己方的开火不受影响。\n\n在工作一段时间后该系统将自行烧毁。</description>
<iconPath>Wula/UI/Abilities/WULA_Firepower_Minigun_Strafe</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<drawAimPie>false</drawAimPie>
<requireLineOfSight>false</requireLineOfSight>
<warmupTime>1</warmupTime>
<range>120</range>
<targetable>true</targetable>
<targetParams>
<canTargetSelf>false</canTargetSelf>
<canTargetLocations>true</canTargetLocations>
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityCallSkyfaller">
<delayTicks>0</delayTicks>
<skyfallerDef>WULA_Support_AreaTeleporter_Skyfaller</skyfallerDef>
<previewRadius>20</previewRadius>
<previewColor>(0.6,0.8,0.8,0.5)</previewColor>
</li>
<li Class="WulaFallenEmpire.CompProperties_RequireFlyOverFacility">
<!-- <flyOverDef></flyOverDef> -->
<requiredFacility>FactoryFacility</requiredFacility>
<facilityNotFoundMessage>需要拥有&lt;color=#BD2F31>&lt;i>支援设施&lt;/i>&lt;/color>设施的战舰在地图上才能进行轨道炮击支援</facilityNotFoundMessage>
</li>
<!-- <li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Firepower_Minigun_Technology</requiredResearch>
</li> -->
</comps>
</AbilityDef>
</Defs>

View File

@@ -167,7 +167,9 @@
<li>WULA_CallMotherShip</li>
<li>WULA_CallConstructionShip</li>
<li>WULA_ClearFlightPath</li>
<li>WULA_Support_Holographic_Flag</li>
<li>WULA_Support_Shield_Projection</li>
<li>WULA_Support_AreaTeleporter</li>
</abilityDefs>
</li>
</comps>

View File

@@ -300,7 +300,7 @@
<defaultLabelColor>(0.52, 1, 0.95)</defaultLabelColor>
<comps>
<li Class="HediffCompProperties_Disappears">
<disappearsAfterTicks>120</disappearsAfterTicks>
<disappearsAfterTicks>125</disappearsAfterTicks>
<showRemainingTime>false</showRemainingTime>
</li>
<li Class="HediffCompProperties_DisappearsOnDeath"/>
@@ -309,11 +309,12 @@
<li>
<minSeverity>0</minSeverity>
<statOffsets>
<MentalBreakThreshold>-0.01</MentalBreakThreshold>
<MentalBreakThreshold>-0.1</MentalBreakThreshold>
<MoveSpeed>0.5</MoveSpeed>
</statOffsets>
<statFactors>
<AimingDelayFactor>0.9</AimingDelayFactor>
<ShootingAccuracyPawn>1</ShootingAccuracyPawn>
<ShootingAccuracyPawn>1.25</ShootingAccuracyPawn>
<MeleeDamageFactor>1.1</MeleeDamageFactor>
<MeleeCooldownFactor>0.9</MeleeCooldownFactor>
</statFactors>

View File

@@ -2297,6 +2297,7 @@
<initialSeverity>0.5</initialSeverity>
<onlyPawnsInSameFaction>true</onlyPawnsInSameFaction>
<checkIntervalTicks>120</checkIntervalTicks>
<hediffDurationTicks>125</hediffDurationTicks>
<allowedRaces>
<li>WulaSpecies</li>
</allowedRaces>
@@ -2359,4 +2360,43 @@
</li>
</comps>
</ThingDef>
<ThingDef ParentName="WULA_Holographic_Flag_Skyfaller">
<defName>WULA_Support_AreaTeleporter_Skyfaller</defName>
<label>P.I.A全息旗帜附区域传送器落地中</label>
<skyfaller>
<spawnThing>WULA_Support_AreaTeleporter</spawnThing>
</skyfaller>
</ThingDef>
<ThingDef ParentName="WULA_Holographic_Flag_Building">
<defName>WULA_Support_AreaTeleporter</defName>
<label>P.I.A全息旗帜附区域传送器</label>
<description>乌拉帝国行星封锁机关的全息旗帜,除了宣誓主权外,也能激励附近的乌拉星人更加凶狠地战斗。这面旗帜的底座附带了一个区域传送器,可以使得机械乌拉在旗帜区域内传送。\n\n在工作一段时间后该系统将自行烧毁。</description>
<comps>
<li Class="WulaFallenEmpire.CompProperties_CustomRadius">
<radius>20</radius> <!-- 半径大小 -->
<color>(1, 1, 1)</color> <!-- 绿色圆圈 -->
<radiusOffset>0</radiusOffset> <!-- 半径偏移 -->
<showInGUI>true</showInGUI>
<label>传送范围</label>
<description>区域传送器提供的传送范围</description>
<defaultVisible>true</defaultVisible>
</li>
<li Class="CompProperties_Lifespan">
<lifespanTicks>3600</lifespanTicks>
</li>
<li Class="WulaFallenEmpire.CompProperties_AreaTeleporter">
<teleportRadius>20</teleportRadius>
<stunTicks>60</stunTicks>
<allowedRaces>
<li>WulaSpecies</li>
</allowedRaces>
<onlyPawnsInSameFaction>true</onlyPawnsInSameFaction>
<entryEffecter>Skip_Entry</entryEffecter>
<exitEffecter>Skip_Exit</exitEffecter>
<teleportSound>Psycast_Skip_Entry</teleportSound>
</li>
</comps>
</ThingDef>
</Defs>

View File

@@ -107,7 +107,6 @@ namespace WulaFallenEmpire
var facilitiesComp = flyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp == null)
{
Log.Warning($"[RequireFlyOverFacility] FlyOver at {flyOver.Position} has no CompFlyOverFacilities");
continue;
}

View File

@@ -0,0 +1,47 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
namespace WulaFallenEmpire
{
public class CompProperties_AreaTeleporter : CompProperties
{
public float teleportRadius = 15f;
// 种族筛选
public List<ThingDef> allowedRaces;
public List<ThingDef> excludedRaces;
public bool requireHumanlike = false;
public bool requireAnimal = false;
public bool requireMechanoid = false;
// 派系控制
public bool onlyPawnsInSameFaction = true;
public bool affectAllies = true;
public bool affectEnemies = true;
public bool affectNeutrals = true;
public bool affectPrisoners = false;
public bool affectSlaves = false;
// 传送设置 - 移除冷却时间
public int checkIntervalTicks = 30; // 检查间隔
public int stunTicks = 30; // 传送后眩晕时间
public int maxPositionAdjustRadius = 5; // 最大位置调整半径
// 效果设置
public EffecterDef entryEffecter;
public EffecterDef exitEffecter;
public EffecterDef enterRangeEffecter;
public EffecterDef leaveRangeEffecter;
public SoundDef teleportSound;
// 到达时的喧嚣效果
public ClamorDef destClamorType;
public float destClamorRadius = 2f;
public CompProperties_AreaTeleporter()
{
compClass = typeof(ThingComp_AreaTeleporter);
}
}
}

View File

@@ -0,0 +1,66 @@
using HarmonyLib;
using RimWorld;
using Verse;
using Verse.AI;
namespace WulaFallenEmpire
{
[HarmonyPatch(typeof(Pawn_JobTracker), "StartJob")]
public static class Patch_Pawn_JobTracker_StartJob
{
[HarmonyPostfix]
public static void Postfix(Pawn_JobTracker __instance, Pawn ___pawn)
{
// 检查是否是移动相关的任务
if (___pawn?.Map == null || ___pawn.Dead || ___pawn.Downed)
return;
if (__instance.curJob == null)
return;
// 只处理移动任务
if (__instance.curJob.def == JobDefOf.Goto ||
__instance.curJob.def == JobDefOf.GotoWander ||
__instance.curJob.def == JobDefOf.Follow)
{
// 通知区域传送器检查这个Pawn
NotifyAreaTeleporters(___pawn);
}
}
private static void NotifyAreaTeleporters(Pawn pawn)
{
if (pawn.Map == null)
return;
// 查找范围内的所有区域传送器
foreach (var thing in pawn.Map.listerThings.ThingsOfDef(ThingDef.Named("WULA_Support_AreaTeleporter")))
{
var comp = thing.TryGetComp<ThingComp_AreaTeleporter>();
if (comp != null && pawn.Position.DistanceTo(thing.Position) <= comp.Props.teleportRadius)
{
// 强制立即检查这个Pawn
comp.ForceCheckPawn(pawn);
}
}
}
}
// 为ThingComp_AreaTeleporter添加强制检查方法
public partial class ThingComp_AreaTeleporter
{
public void ForceCheckPawn(Pawn pawn)
{
if (parent == null || !parent.Spawned || parent.Map == null)
return;
if (pawn.Position.DistanceTo(parent.Position) > Props.teleportRadius)
return;
if (!ShouldAffectPawn(pawn))
return;
TryTeleportPawn(pawn);
}
}
}

View File

@@ -0,0 +1,548 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using UnityEngine;
using HarmonyLib;
using Verse.AI;
using Verse.Sound;
namespace WulaFallenEmpire
{
public partial class ThingComp_AreaTeleporter : ThingComp
{
public CompProperties_AreaTeleporter Props => (CompProperties_AreaTeleporter)props;
// 跟踪范围内的Pawn
private HashSet<Pawn> pawnsInRange = new HashSet<Pawn>();
// 效果器缓存
private Dictionary<Pawn, Effecter> effecters = new Dictionary<Pawn, Effecter>();
// 网络相关:存储同一地图上的所有传送器
private static Dictionary<Map, HashSet<ThingComp_AreaTeleporter>> teleporterNetworks =
new Dictionary<Map, HashSet<ThingComp_AreaTeleporter>>();
// 硬编码的工作排除表
private static readonly HashSet<JobDef> ExcludedJobs = new HashSet<JobDef>
{
JobDefOf.GotoWander // 排除闲逛工作
};
public override void Initialize(CompProperties props)
{
base.Initialize(props);
RegisterToNetwork();
}
public override void PostSpawnSetup(bool respawningAfterLoad)
{
base.PostSpawnSetup(respawningAfterLoad);
RegisterToNetwork();
}
public override void PostDeSpawn(Map map, DestroyMode mode = DestroyMode.Vanish)
{
base.PostDeSpawn(map);
UnregisterFromNetwork();
}
public override void PostDestroy(DestroyMode mode, Map previousMap)
{
base.PostDestroy(mode, previousMap);
UnregisterFromNetwork();
}
/// <summary>
/// 注册到网络
/// </summary>
private void RegisterToNetwork()
{
if (parent?.Map == null) return;
var map = parent.Map;
if (!teleporterNetworks.ContainsKey(map))
{
teleporterNetworks[map] = new HashSet<ThingComp_AreaTeleporter>();
}
teleporterNetworks[map].Add(this);
}
/// <summary>
/// 从网络注销
/// </summary>
private void UnregisterFromNetwork()
{
if (parent?.Map == null) return;
var map = parent.Map;
if (teleporterNetworks.ContainsKey(map))
{
teleporterNetworks[map].Remove(this);
if (teleporterNetworks[map].Count == 0)
{
teleporterNetworks.Remove(map);
}
}
}
/// <summary>
/// 获取同一地图上的所有传送器
/// </summary>
private HashSet<ThingComp_AreaTeleporter> GetNetworkTeleporters()
{
if (parent?.Map == null) return new HashSet<ThingComp_AreaTeleporter>();
if (teleporterNetworks.TryGetValue(parent.Map, out var network))
{
return network;
}
return new HashSet<ThingComp_AreaTeleporter>();
}
/// <summary>
/// 检查位置是否在传送网络的范围内
/// </summary>
private bool IsPositionInNetworkRange(IntVec3 position)
{
if (parent?.Map == null) return false;
foreach (var teleporter in GetNetworkTeleporters())
{
if (teleporter.parent?.Spawned == true &&
position.DistanceTo(teleporter.parent.Position) <= teleporter.Props.teleportRadius)
{
return true;
}
}
return false;
}
/// <summary>
/// 在传送网络范围内寻找安全的传送位置
/// </summary>
private IntVec3 FindSafePositionInNetwork(IntVec3 preferredPosition, Pawn pawn)
{
if (parent?.Map == null) return IntVec3.Invalid;
var map = parent.Map;
// 首先检查首选位置
if (preferredPosition.InBounds(map) && CanTeleportTo(preferredPosition, map))
return preferredPosition;
// 在首选位置周围搜索
for (int radius = 1; radius <= Props.maxPositionAdjustRadius; radius++)
{
foreach (var cell in GenRadial.RadialCellsAround(preferredPosition, radius, true))
{
if (cell.InBounds(map) && CanTeleportTo(cell, map) && IsPositionInNetworkRange(cell))
{
return cell;
}
}
}
// 在整个网络范围内搜索安全位置
foreach (var teleporter in GetNetworkTeleporters())
{
if (teleporter.parent?.Spawned != true) continue;
var teleporterPos = teleporter.parent.Position;
var searchRadius = teleporter.Props.teleportRadius;
// 在传送器周围搜索
for (int radius = 0; radius <= searchRadius; radius++)
{
foreach (var cell in GenRadial.RadialCellsAround(teleporterPos, radius, true))
{
if (cell.InBounds(map) && CanTeleportTo(cell, map))
{
return cell;
}
}
}
}
return IntVec3.Invalid;
}
public override void CompTick()
{
base.CompTick();
if (parent == null || !parent.Spawned || parent.Map == null)
return;
// 使用间隔检查优化性能
if (Find.TickManager.TicksGame % Props.checkIntervalTicks != 0)
return;
UpdatePawnsInRange();
ProcessPawnMovements();
}
private void UpdatePawnsInRange()
{
var newPawnsInRange = new HashSet<Pawn>();
// 获取范围内的所有pawn
foreach (var thing in parent.Map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn))
{
if (thing is Pawn pawn &&
pawn.Position.DistanceTo(parent.Position) <= Props.teleportRadius &&
pawn.Spawned && !pawn.Dead && !pawn.Downed)
{
newPawnsInRange.Add(pawn);
}
}
// 处理新进入范围的pawn
foreach (var pawn in newPawnsInRange)
{
if (!pawnsInRange.Contains(pawn) && ShouldAffectPawn(pawn))
{
OnPawnEnterRange(pawn);
}
}
// 处理离开范围的pawn
var pawnsToRemove = new List<Pawn>();
foreach (var pawn in pawnsInRange)
{
if (!newPawnsInRange.Contains(pawn))
{
pawnsToRemove.Add(pawn);
}
}
foreach (var pawn in pawnsToRemove)
{
OnPawnLeaveRange(pawn);
}
pawnsInRange = newPawnsInRange;
}
private void ProcessPawnMovements()
{
foreach (var pawn in pawnsInRange)
{
if (!ShouldAffectPawn(pawn))
continue;
if (IsPawnMoving(pawn))
{
TryTeleportPawn(pawn);
}
}
}
/// <summary>
/// 检查pawn是否应该受到传送效果影响
/// </summary>
private bool ShouldAffectPawn(Pawn pawn)
{
if (pawn == null || pawn.Dead || pawn.Destroyed)
return false;
// 种族类型检查 - 只允许人类和机械体
if (!pawn.RaceProps.Humanlike && !pawn.RaceProps.IsMechanoid)
return false;
// 特定种族检查
if (Props.allowedRaces != null && Props.allowedRaces.Count > 0)
{
if (!Props.allowedRaces.Contains(pawn.def))
return false;
}
// 排除种族检查
if (Props.excludedRaces != null && Props.excludedRaces.Count > 0)
{
if (Props.excludedRaces.Contains(pawn.def))
return false;
}
// 派系关系检查 - 简化版,只检查是否同派系
if (Props.onlyPawnsInSameFaction && parent.Faction != null && pawn.Faction != null)
{
if (parent.Faction != pawn.Faction)
return false;
}
// 囚犯和奴隶检查
if (!Props.affectPrisoners && pawn.IsPrisoner)
return false;
if (!Props.affectSlaves && pawn.IsSlave)
return false;
return true;
}
/// <summary>
/// 检查Pawn是否正在移动
/// </summary>
private bool IsPawnMoving(Pawn pawn)
{
if (pawn == null || pawn.jobs == null || pawn.jobs.curJob == null)
return false;
// 检查工作是否在排除表中
if (IsJobExcluded(pawn.jobs.curJob.def))
return false;
// 检查是否正在执行移动任务
if (pawn.jobs.curJob.def == JobDefOf.Goto ||
pawn.jobs.curJob.def == JobDefOf.GotoWander ||
pawn.jobs.curJob.def == JobDefOf.Follow)
{
return pawn.pather.Moving;
}
return false;
}
/// <summary>
/// 检查工作是否在排除表中
/// </summary>
private bool IsJobExcluded(JobDef jobDef)
{
return ExcludedJobs.Contains(jobDef);
}
/// <summary>
/// 尝试传送Pawn
/// </summary>
private void TryTeleportPawn(Pawn pawn)
{
try
{
if (pawn == null || pawn.Map == null || pawn.Destroyed)
return;
// 检查当前工作是否在排除表中
if (pawn.jobs?.curJob != null && IsJobExcluded(pawn.jobs.curJob.def))
return;
// 获取Pawn的目标位置
LocalTargetInfo target = GetPawnMoveTarget(pawn);
if (!target.IsValid)
return;
// 检查目标位置是否在传送网络范围内
if (!IsPositionInNetworkRange(target.Cell))
return;
// 在网络范围内寻找安全的传送位置
IntVec3 safeTarget = FindSafePositionInNetwork(target.Cell, pawn);
if (!safeTarget.IsValid)
return;
// 执行传送
PerformTeleport(pawn, safeTarget);
// 记录日志
Log.Message($"[AreaTeleporter] 传送 {pawn.LabelShort} 从 {pawn.Position} 到 {safeTarget} (网络传送)");
}
catch (System.Exception ex)
{
Log.Warning($"传送Pawn时出错: {ex.Message}");
}
}
/// <summary>
/// 获取Pawn的移动目标
/// </summary>
private LocalTargetInfo GetPawnMoveTarget(Pawn pawn)
{
if (pawn.jobs?.curJob == null)
return LocalTargetInfo.Invalid;
// 检查工作是否在排除表中
if (IsJobExcluded(pawn.jobs.curJob.def))
return LocalTargetInfo.Invalid;
// 尝试从当前工作中获取目标位置
var job = pawn.jobs.curJob;
// 对于Goto任务目标通常是targetA
if (job.targetA.IsValid)
return job.targetA;
// 对于其他移动任务,可能需要不同的逻辑
if (job.def == JobDefOf.Follow && job.targetB.IsValid)
return job.targetB;
return LocalTargetInfo.Invalid;
}
/// <summary>
/// 检查是否可以传送到指定位置
/// </summary>
private bool CanTeleportTo(IntVec3 cell, Map map)
{
if (!cell.InBounds(map))
return false;
// 检查是否可站立
if (!cell.Standable(map))
return false;
// 检查是否有建筑阻挡
Building edifice = cell.GetEdifice(map);
if (edifice != null && edifice.def.surfaceType != SurfaceType.Item &&
edifice.def.surfaceType != SurfaceType.Eat && !(edifice is Building_Door { Open: not false }))
{
return false;
}
// 检查是否有物品阻挡
List<Thing> thingList = cell.GetThingList(map);
for (int i = 0; i < thingList.Count; i++)
{
if (thingList[i].def.category == ThingCategory.Item)
{
return false;
}
}
return true;
}
/// <summary>
/// 执行传送
/// </summary>
private void PerformTeleport(Pawn pawn, IntVec3 targetCell)
{
Map map = pawn.Map;
// 创建入口特效
if (Props.entryEffecter != null)
{
Effecter entryEffect = Props.entryEffecter.Spawn();
entryEffect.Trigger(new TargetInfo(pawn.Position, map), new TargetInfo(pawn.Position, map));
entryEffect.Cleanup();
}
// 创建出口特效
if (Props.exitEffecter != null)
{
Effecter exitEffect = Props.exitEffecter.Spawn();
exitEffect.Trigger(new TargetInfo(targetCell, map), new TargetInfo(targetCell, map));
exitEffect.Cleanup();
}
// 播放音效
if (Props.teleportSound != null)
{
Props.teleportSound.PlayOneShot(new TargetInfo(targetCell, map));
}
// 执行传送
pawn.Position = targetCell;
pawn.Notify_Teleported();
pawn.jobs.StopAll();
// 如果是玩家阵营,解除战争迷雾
if ((pawn.Faction == Faction.OfPlayer || pawn.IsPlayerControlled) && pawn.Position.Fogged(map))
{
FloodFillerFog.FloodUnfog(pawn.Position, map);
}
// 传送后眩晕
if (Props.stunTicks > 0)
{
pawn.stances.stunner.StunFor(Props.stunTicks, pawn, addBattleLog: false, showMote: false);
}
// 播放到达时的喧嚣效果
if (Props.destClamorType != null)
{
GenClamor.DoClamor(pawn, targetCell, Props.destClamorRadius, Props.destClamorType);
}
}
private void OnPawnEnterRange(Pawn pawn)
{
// Pawn进入范围时的处理
if (Props.enterRangeEffecter != null)
{
Effecter effect = Props.enterRangeEffecter.Spawn();
effect.Trigger(new TargetInfo(pawn.Position, pawn.Map), new TargetInfo(pawn.Position, pawn.Map));
effect.Cleanup();
}
}
private void OnPawnLeaveRange(Pawn pawn)
{
// Pawn离开范围时的处理
if (Props.leaveRangeEffecter != null)
{
Effecter effect = Props.leaveRangeEffecter.Spawn();
effect.Trigger(new TargetInfo(pawn.Position, pawn.Map), new TargetInfo(pawn.Position, pawn.Map));
effect.Cleanup();
}
}
/// <summary>
/// 清理所有效果
/// </summary>
private void CleanupAllEffects()
{
pawnsInRange.Clear();
foreach (var effecter in effecters.Values)
{
effecter.Cleanup();
}
effecters.Clear();
}
// 调试方法:显示传送范围
public override void PostDraw()
{
base.PostDraw();
if (Find.Selector.IsSelected(parent))
{
try
{
// 绘制当前传送器范围
GenDraw.DrawRadiusRing(parent.Position, Props.teleportRadius, Color.blue);
// 绘制网络范围(所有传送器的范围)
foreach (var teleporter in GetNetworkTeleporters())
{
if (teleporter != this && teleporter.parent.Spawned)
{
GenDraw.DrawRadiusRing(teleporter.parent.Position, teleporter.Props.teleportRadius, new Color(0, 0, 1, 0.3f));
}
}
}
catch (System.Exception ex)
{
Log.Warning($"绘制传送范围环时出错: {ex.Message}");
}
}
}
// 获取当前范围内的pawn数量用于显示
public int GetPawnsInRangeCount()
{
return pawnsInRange.Count;
}
// 获取范围内的pawn列表用于调试
public IEnumerable<Pawn> GetPawnsInRange()
{
return pawnsInRange;
}
// 获取网络中的传送器数量
public int GetNetworkTeleporterCount()
{
return GetNetworkTeleporters().Count;
}
}
}

View File

@@ -197,13 +197,14 @@ namespace WulaFallenEmpire
Hediff newHediff = HediffMaker.MakeHediff(Props.hediff, pawn);
newHediff.Severity = Props.initialSeverity;
// 设置持续时间(如果有)
// 正确设置持续时间
if (Props.hediffDurationTicks > 0)
{
var comp = newHediff.TryGetComp<HediffComp_Disappears>();
if (comp != null)
var disappearComp = newHediff.TryGetComp<HediffComp_Disappears>();
if (disappearComp != null)
{
comp.ticksToDisappear = Props.hediffDurationTicks;
// 使用 SetDuration 方法正确设置持续时间
disappearComp.SetDuration(Props.hediffDurationTicks);
}
}
@@ -250,11 +251,11 @@ namespace WulaFallenEmpire
{
if (Props.hediffDurationTicks > 0)
{
var comp = hediff.TryGetComp<HediffComp_Disappears>();
if (comp != null)
var disappearComp = hediff.TryGetComp<HediffComp_Disappears>();
if (disappearComp != null)
{
// 重置持续时间,让效果持续
comp.ticksToDisappear = Props.hediffDurationTicks;
// 使用 SetDuration 方法重置持续时间,让效果持续
disappearComp.SetDuration(Props.hediffDurationTicks);
}
}
}

View File

@@ -259,6 +259,9 @@
<Compile Include="ThingComp\WULA_AreaShield\Gizmo_AreaShieldStatus.cs" />
<Compile Include="ThingComp\WULA_AreaShield\Harmony_AreaShieldInterceptor.cs" />
<Compile Include="ThingComp\WULA_AreaShield\ThingComp_AreaShield.cs" />
<Compile Include="ThingComp\WULA_AreaTeleporter\CompProperties_AreaTeleporter.cs" />
<Compile Include="ThingComp\WULA_AreaTeleporter\Patch_Pawn_JobTracker_StartJob.cs" />
<Compile Include="ThingComp\WULA_AreaTeleporter\ThingComp_AreaTeleporter.cs" />
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompCustomUniqueWeapon.cs" />
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompProperties_CustomUniqueWeapon.cs" />
<Compile Include="ThingComp\WULA_GiveHediffsInRange\CompGiveHediffsInRange.cs" />