This commit is contained in:
2025-11-18 11:50:30 +08:00
parent 710eca55d4
commit 875edfcc41
14 changed files with 1275 additions and 89 deletions

View File

@@ -24,33 +24,110 @@ namespace WulaFallenEmpire
if (parent.pawn?.Map == null) return;
// 销毁有 FlyOver 物体
DestroyAllFlyOvers();
// 销毁CompFlyOverFacilities 的 FlyOver
DestroyFlyOversWithFacilities();
}
// 销毁所有 FlyOver
private void DestroyAllFlyOvers()
// 销毁带有设施的 FlyOver
private void DestroyFlyOversWithFacilities()
{
List<Thing> flyOvers = new List<Thing>();
List<FlyOver> flyOversWithFacilities = new List<FlyOver>();
// 获取地图上所有的 FlyOver
foreach (Thing thing in parent.pawn.Map.listerThings.AllThings)
// 使用 CompFlyOverFacilities 的静态方法来获取所有带有设施的 FlyOver
var allFlyOvers = CompFlyOverFacilities.GetAllFlyOversWithFacilities(parent.pawn.Map);
if (allFlyOvers.Count > 0)
{
if (thing is FlyOver flyOver)
foreach (var flyOver in allFlyOvers)
{
flyOvers.Add(flyOver);
if (flyOver != null && !flyOver.Destroyed)
{
flyOversWithFacilities.Add(flyOver);
}
}
}
// 销毁找到的 FlyOver
foreach (FlyOver flyOver in flyOvers)
// 销毁找到的带有设施的 FlyOver
foreach (FlyOver flyOver in flyOversWithFacilities)
{
flyOver.EmergencyDestroy();
Log.Message($"[DestroyFlyOverByFacilities] Destroyed FlyOver with facilities at {flyOver.Position}");
}
if (flyOvers.Count > 0)
if (flyOversWithFacilities.Count > 0)
{
Messages.Message($"WULA_DestroyFlyOver".Translate(), parent.pawn, MessageTypeDefOf.PositiveEvent);
Messages.Message($"WULA_DestroyFlyOver".Translate(flyOversWithFacilities.Count), parent.pawn, MessageTypeDefOf.PositiveEvent);
}
else
{
Messages.Message("WULA_NoFlyOverWithFacilities".Translate(), parent.pawn, MessageTypeDefOf.NeutralEvent);
}
}
// 添加验证方法,确保只在有相关 FlyOver 时可用
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
if (!base.Valid(target, throwMessages))
return false;
// 检查是否有带有设施的 FlyOver
if (parent.pawn?.Map == null)
return false;
var flyOversWithFacilities = CompFlyOverFacilities.GetAllFlyOversWithFacilities(parent.pawn.Map);
if (flyOversWithFacilities.Count == 0)
{
if (throwMessages)
{
Messages.Message("WULA_NoFlyOverWithFacilities".Translate(), parent.pawn, MessageTypeDefOf.RejectInput);
}
return false;
}
return true;
}
public override bool GizmoDisabled(out string reason)
{
if (parent.pawn?.Map == null)
{
reason = "Cannot use outside of map";
return true;
}
// 检查是否有带有设施的 FlyOver
var flyOversWithFacilities = CompFlyOverFacilities.GetAllFlyOversWithFacilities(parent.pawn.Map);
if (flyOversWithFacilities.Count == 0)
{
reason = "No FlyOver with facilities found";
return true;
}
return base.GizmoDisabled(out reason);
}
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
try
{
if (parent.pawn?.Map == null)
return "Cannot use outside of map";
var flyOversWithFacilities = CompFlyOverFacilities.GetAllFlyOversWithFacilities(parent.pawn.Map);
if (flyOversWithFacilities.Count > 0)
{
return $"Will destroy {flyOversWithFacilities.Count} FlyOver(s) with facilities";
}
return "No FlyOver with facilities found";
}
catch (System.Exception ex)
{
Log.Error($"[DestroyFlyOverByFacilities] Error in ExtraLabelMouseAttachment: {ex}");
return "Error checking FlyOver status";
}
}
}

View File

@@ -42,11 +42,16 @@ namespace WulaFallenEmpire
public bool avoidHittingFlyOver = true;
// 信件通知
public bool sendAttackLetter = true; // 是否发送攻击信件
public bool sendAttackLetter = false; // 是否发送攻击信件
public string customLetterLabel; // 自定义信件标题
public string customLetterText; // 自定义信件内容
public LetterDef letterDef = LetterDefOf.ThreatBig; // 信件类型
// 新增:派系甄别系统
public bool useFactionDiscrimination = false; // 是否使用派系甄别
public FactionDef targetFaction; // 目标派系(友军派系)
public bool useMicroTracking = false; // 是否启用微追踪
public CompProperties_ShipArtillery()
{
compClass = typeof(CompShipArtillery);

View File

@@ -24,6 +24,16 @@ namespace WulaFallenEmpire
// 目标跟踪
private List<IntVec3> previousTargets = new List<IntVec3>();
// 新增:微追踪目标列表
private List<LocalTargetInfo> microTrackingTargets = new List<LocalTargetInfo>();
private List<float> microTrackingWeights = new List<float>(); // 新增:权重列表
// 新增:目标类型权重配置
private const float PAWN_WEIGHT = 5.0f; // Pawn权重5倍
private const float OWNED_BUILDING_WEIGHT = 1.0f; // 有主建筑权重1倍
private const float UNOWNED_BUILDING_WEIGHT = 0.01f; // 无主建筑权重0.01倍
private const float OTHER_WEIGHT = 1.0f; // 其他目标权重1倍
public override void Initialize(CompProperties props)
{
base.Initialize(props);
@@ -31,6 +41,7 @@ namespace WulaFallenEmpire
ticksUntilNextAttack = Props.ticksBetweenAttacks;
Log.Message($"Ship Artillery initialized: {Props.ticksBetweenAttacks} ticks between attacks, {Props.attackRadius} radius");
Log.Message($"Faction Discrimination: {Props.useFactionDiscrimination}, Target Faction: {Props.targetFaction?.defName ?? "None"}, Micro Tracking: {Props.useMicroTracking}");
}
public override void CompTick()
@@ -40,6 +51,12 @@ namespace WulaFallenEmpire
if (parent is not FlyOver flyOver || !flyOver.Spawned || flyOver.Map == null)
return;
// 更新微追踪目标列表(如果需要)
if (Props.useMicroTracking && Props.useFactionDiscrimination)
{
UpdateMicroTrackingTargets(flyOver);
}
// 更新预热状态
if (isWarmingUp)
{
@@ -65,6 +82,173 @@ namespace WulaFallenEmpire
}
}
// 新增:更新微追踪目标列表
private void UpdateMicroTrackingTargets(FlyOver flyOver)
{
microTrackingTargets.Clear();
microTrackingWeights.Clear();
Faction targetFaction = GetTargetFaction(flyOver);
if (targetFaction == null) return;
// 获取飞越物体当前位置
IntVec3 center = GetFlyOverPosition(flyOver);
// 搜索范围内的所有潜在目标
foreach (IntVec3 cell in GenRadial.RadialCellsAround(center, Props.attackRadius, true))
{
if (!cell.InBounds(flyOver.Map)) continue;
// 检查建筑
Building building = cell.GetEdifice(flyOver.Map);
if (building != null && IsValidMicroTrackingTarget(building, targetFaction))
{
microTrackingTargets.Add(new LocalTargetInfo(building));
float weight = GetTargetWeight(building);
microTrackingWeights.Add(weight);
}
// 检查生物
List<Thing> thingList = cell.GetThingList(flyOver.Map);
foreach (Thing thing in thingList)
{
if (thing is Pawn pawn && IsValidMicroTrackingTarget(pawn, targetFaction))
{
microTrackingTargets.Add(new LocalTargetInfo(pawn));
float weight = GetTargetWeight(pawn);
microTrackingWeights.Add(weight);
}
}
}
// 移除重复目标(基于位置)
for (int i = microTrackingTargets.Count - 1; i >= 0; i--)
{
for (int j = 0; j < i; j++)
{
if (microTrackingTargets[i].Cell == microTrackingTargets[j].Cell)
{
microTrackingTargets.RemoveAt(i);
microTrackingWeights.RemoveAt(i);
break;
}
}
}
if (DebugSettings.godMode)
{
Log.Message($"MicroTracking: Found {microTrackingTargets.Count} targets for faction {targetFaction.def.defName}");
// 输出目标统计信息
var targetStats = GetTargetStatistics();
Log.Message($"Target Statistics - Pawns: {targetStats.pawnCount}, Owned Buildings: {targetStats.ownedBuildingCount}, Unowned Buildings: {targetStats.unownedBuildingCount}, Others: {targetStats.otherCount}");
}
}
// 新增:获取目标权重
private float GetTargetWeight(Thing thing)
{
if (thing is Pawn)
{
return PAWN_WEIGHT;
}
else if (thing is Building building)
{
if (building.Faction == null)
{
return UNOWNED_BUILDING_WEIGHT;
}
else
{
return OWNED_BUILDING_WEIGHT;
}
}
else
{
return OTHER_WEIGHT;
}
}
// 新增:获取目标统计信息
private (int pawnCount, int ownedBuildingCount, int unownedBuildingCount, int otherCount) GetTargetStatistics()
{
int pawnCount = 0;
int ownedBuildingCount = 0;
int unownedBuildingCount = 0;
int otherCount = 0;
for (int i = 0; i < microTrackingTargets.Count; i++)
{
Thing thing = microTrackingTargets[i].Thing;
if (thing == null) continue;
if (thing is Pawn)
{
pawnCount++;
}
else if (thing is Building building)
{
if (building.Faction == null)
{
unownedBuildingCount++;
}
else
{
ownedBuildingCount++;
}
}
else
{
otherCount++;
}
}
return (pawnCount, ownedBuildingCount, unownedBuildingCount, otherCount);
}
// 新增:检查是否为有效的微追踪目标
private bool IsValidMicroTrackingTarget(Thing thing, Faction targetFaction)
{
if (thing == null || thing.Destroyed) return false;
// 检查派系关系:目标派系的友军不应该被攻击
if (thing.Faction != null)
{
if (thing.Faction == targetFaction) return false;
if (thing.Faction.RelationKindWith(targetFaction) == FactionRelationKind.Ally) return false;
}
// 检查是否在保护范围内
if (Props.avoidPlayerAssets && IsNearPlayerAssets(thing.Position, thing.Map))
{
return false;
}
// 避免击中飞越物体本身
if (Props.avoidHittingFlyOver && thing.Position.DistanceTo(parent.Position) < 10f)
{
return false;
}
return true;
}
// 新增:获取目标派系
private Faction GetTargetFaction(FlyOver flyOver)
{
if (!Props.useFactionDiscrimination)
return null;
// 如果指定了目标派系,使用指定的派系
if (Props.targetFaction != null)
{
Faction faction = Find.FactionManager.FirstFactionOfDef(Props.targetFaction);
if (faction != null) return faction;
}
// 否则使用玩家当前派系
return Faction.OfPlayer;
}
private void StartAttack(FlyOver flyOver)
{
if (!CanAttack(flyOver))
@@ -195,8 +379,16 @@ namespace WulaFallenEmpire
return;
}
// 直接选择随机目标
IntVec3 shellTarget = SelectRandomTarget(flyOver);
// 选择目标
IntVec3 shellTarget;
if (Props.useMicroTracking && Props.useFactionDiscrimination && microTrackingTargets.Count > 0)
{
shellTarget = SelectMicroTrackingTarget(flyOver);
}
else
{
shellTarget = SelectRandomTarget(flyOver);
}
// 关键修复:使用 SkyfallerMaker 创建并立即生成 Skyfaller
SkyfallerMaker.SpawnSkyfaller(shellDef, shellTarget, flyOver.Map);
@@ -216,6 +408,79 @@ namespace WulaFallenEmpire
}
}
// 修改:微追踪目标选择 - 现在使用权重系统
private IntVec3 SelectMicroTrackingTarget(FlyOver flyOver)
{
if (microTrackingTargets.Count == 0)
{
Log.Warning("MicroTracking: No targets available, falling back to random target");
return SelectRandomTarget(flyOver);
}
// 使用权重系统选择目标
LocalTargetInfo selectedTarget = SelectTargetByWeight();
IntVec3 targetCell = selectedTarget.Cell;
// 在目标周围添加随机偏移,避免过于精确
float offsetDistance = Rand.Range(0f, 2f);
float angle = Rand.Range(0f, 360f);
IntVec3 offsetTarget = targetCell;
offsetTarget.x += Mathf.RoundToInt(Mathf.Cos(angle * Mathf.Deg2Rad) * offsetDistance);
offsetTarget.z += Mathf.RoundToInt(Mathf.Sin(angle * Mathf.Deg2Rad) * offsetDistance);
// 确保目标在地图内
if (!offsetTarget.InBounds(flyOver.Map))
{
offsetTarget = targetCell;
}
if (DebugSettings.godMode)
{
Thing selectedThing = selectedTarget.Thing;
string targetType = selectedThing is Pawn ? "Pawn" :
selectedThing is Building building ?
(building.Faction == null ? "Unowned Building" : "Owned Building") : "Other";
Log.Message($"MicroTracking: Targeting {selectedThing?.Label ?? "unknown"} ({targetType}) at {targetCell}, final target: {offsetTarget}");
}
return offsetTarget;
}
// 新增:基于权重的目标选择
private LocalTargetInfo SelectTargetByWeight()
{
if (microTrackingTargets.Count == 0)
return LocalTargetInfo.Invalid;
if (microTrackingTargets.Count == 1)
return microTrackingTargets[0];
// 计算总权重
float totalWeight = 0f;
foreach (float weight in microTrackingWeights)
{
totalWeight += weight;
}
// 随机选择
float randomValue = Rand.Range(0f, totalWeight);
float currentSum = 0f;
for (int i = 0; i < microTrackingTargets.Count; i++)
{
currentSum += microTrackingWeights[i];
if (randomValue <= currentSum)
{
return microTrackingTargets[i];
}
}
// 回退到最后一个目标
return microTrackingTargets[microTrackingTargets.Count - 1];
}
private ThingDef SelectShellDef()
{
if (Props.skyfallerDefs != null && Props.skyfallerDefs.Count > 0)
@@ -352,6 +617,45 @@ namespace WulaFallenEmpire
if (!Props.avoidPlayerAssets)
return false;
// 如果启用了派系甄别,检查目标派系
if (Props.useFactionDiscrimination)
{
Faction targetFaction = GetTargetFaction(parent as FlyOver);
if (targetFaction != null)
{
foreach (IntVec3 checkCell in GenRadial.RadialCellsAround(cell, Props.playerAssetAvoidanceRadius, true))
{
if (!checkCell.InBounds(map))
continue;
// 检查目标派系建筑
var building = checkCell.GetEdifice(map);
if (building != null && building.Faction == targetFaction)
return true;
// 检查目标派系殖民者
var pawn = map.thingGrid.ThingAt<Pawn>(checkCell);
if (pawn != null && pawn.Faction == targetFaction && pawn.RaceProps.Humanlike)
return true;
// 检查目标派系动物
var animal = map.thingGrid.ThingAt<Pawn>(checkCell);
if (animal != null && animal.Faction == targetFaction && animal.RaceProps.Animal)
return true;
// 检查目标派系物品
var items = checkCell.GetThingList(map);
foreach (var item in items)
{
if (item.Faction == targetFaction && item.def.category == ThingCategory.Item)
return true;
}
}
return false;
}
}
// 默认行为:检查玩家资产
foreach (IntVec3 checkCell in GenRadial.RadialCellsAround(cell, Props.playerAssetAvoidanceRadius, true))
{
if (!checkCell.InBounds(map))
@@ -470,6 +774,8 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref isWarmingUp, "isWarmingUp", false);
Scribe_Values.Look(ref currentTarget, "currentTarget");
Scribe_Collections.Look(ref previousTargets, "previousTargets", LookMode.Value);
Scribe_Collections.Look(ref microTrackingTargets, "microTrackingTargets", LookMode.LocalTargetInfo);
Scribe_Collections.Look(ref microTrackingWeights, "microTrackingWeights", LookMode.Value);
}
public override IEnumerable<Gizmo> CompGetGizmosExtra()
@@ -504,9 +810,44 @@ namespace WulaFallenEmpire
IntVec3 flyOverPos = GetFlyOverPosition(flyOver);
Log.Message($"FlyOver - DrawPos: {flyOver.DrawPos}, Position: {flyOver.Position}, Calculated: {flyOverPos}");
Log.Message($"Current Target: {currentTarget}, Distance: {flyOverPos.DistanceTo(currentTarget):F1}");
// 显示派系甄别信息
Faction targetFaction = GetTargetFaction(flyOver);
Log.Message($"Faction Discrimination: {Props.useFactionDiscrimination}, Target Faction: {targetFaction?.def.defName ?? "None"}");
Log.Message($"Micro Tracking: {Props.useMicroTracking}, Targets Found: {microTrackingTargets.Count}");
// 显示目标统计
var stats = GetTargetStatistics();
Log.Message($"Target Stats - Pawns: {stats.pawnCount}, Owned Buildings: {stats.ownedBuildingCount}, Unowned Buildings: {stats.unownedBuildingCount}, Others: {stats.otherCount}");
}
}
};
// 显示微追踪目标信息
if (Props.useMicroTracking && Props.useFactionDiscrimination)
{
yield return new Command_Action
{
defaultLabel = $"Dev: Show Micro Targets ({microTrackingTargets.Count})",
action = () =>
{
if (parent is FlyOver flyOver)
{
for (int i = 0; i < microTrackingTargets.Count; i++)
{
var target = microTrackingTargets[i];
float weight = microTrackingWeights[i];
Thing thing = target.Thing;
string type = thing is Pawn ? "Pawn" :
thing is Building building ?
(building.Faction == null ? "Unowned Building" : "Owned Building") : "Other";
Log.Message($"Micro Target: {thing?.Label ?? "Unknown"} ({type}) at {target.Cell}, Weight: {weight:F2}");
}
}
}
};
}
}
}

View File

@@ -0,0 +1,33 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace WulaFallenEmpire
{
public class StorytellerCompProperties_ImportantQuestWithFactionFilter : StorytellerCompProperties_ImportantQuest
{
// 派系类型白名单 - 只有这些派系类型的殖民地会触发任务
public List<FactionDef> factionTypeWhitelist;
// 派系类型黑名单 - 这些派系类型的殖民地不会触发任务
public List<FactionDef> factionTypeBlacklist;
// 是否启用派系过滤
public bool useFactionFilter = false;
// 默认行为(当派系不在白名单中时的处理方式)
public FactionFilterDefaultBehavior defaultBehavior = FactionFilterDefaultBehavior.Allow;
public StorytellerCompProperties_ImportantQuestWithFactionFilter()
{
compClass = typeof(StorytellerComp_ImportantQuestWithFactionFilter);
}
}
// 派系过滤的默认行为枚举
public enum FactionFilterDefaultBehavior
{
Allow, // 允许不在列表中的派系
Deny // 拒绝不在列表中的派系
}
}

View File

@@ -0,0 +1,175 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
using System.Text;
using System.Linq;
using RimWorld.Planet;
namespace WulaFallenEmpire
{
public class StorytellerComp_ImportantQuestWithFactionFilter : StorytellerComp
{
private StorytellerCompProperties_ImportantQuestWithFactionFilter FilterProps =>
(StorytellerCompProperties_ImportantQuestWithFactionFilter)props;
// 重新实现基类的私有属性
private static int IntervalsPassed => Find.TickManager.TicksGame / 1000;
private bool BeenGivenQuest => Find.QuestManager.QuestsListForReading.Any((Quest q) => q.root == FilterProps.questDef);
public override IEnumerable<FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
{
// 先检查基础条件(天数、是否已给任务等)
if (IntervalsPassed <= FilterProps.fireAfterDaysPassed * 60 || BeenGivenQuest)
yield break;
// 检查派系过滤条件
if (!PassesFactionFilter(target))
yield break;
IncidentDef questIncident = FilterProps.questIncident;
if (questIncident.TargetAllowed(target))
{
yield return new FiringIncident(questIncident, this, GenerateParms(questIncident.category, target));
}
}
/// <summary>
/// 检查目标是否符合派系过滤条件
/// </summary>
private bool PassesFactionFilter(IIncidentTarget target)
{
// 如果不启用派系过滤,直接通过
if (!FilterProps.useFactionFilter)
return true;
// 获取目标的派系
Faction faction = GetTargetFaction(target);
if (faction == null)
return false;
// 检查黑名单
if (FilterProps.factionTypeBlacklist != null &&
FilterProps.factionTypeBlacklist.Contains(faction.def))
{
Log.Message($"[FactionFilter] Quest blocked: {faction.def.defName} is in blacklist");
return false;
}
// 检查白名单
if (FilterProps.factionTypeWhitelist != null &&
FilterProps.factionTypeWhitelist.Count > 0)
{
bool inWhitelist = FilterProps.factionTypeWhitelist.Contains(faction.def);
switch (FilterProps.defaultBehavior)
{
case FactionFilterDefaultBehavior.Allow:
// 白名单模式:在白名单中或默认允许
if (!inWhitelist)
{
Log.Message($"[FactionFilter] Quest allowed: {faction.def.defName} not in whitelist, but default behavior is Allow");
}
return true;
case FactionFilterDefaultBehavior.Deny:
// 白名单模式:只有在白名单中才允许
if (inWhitelist)
{
Log.Message($"[FactionFilter] Quest allowed: {faction.def.defName} is in whitelist");
return true;
}
else
{
Log.Message($"[FactionFilter] Quest blocked: {faction.def.defName} not in whitelist and default behavior is Deny");
return false;
}
}
}
// 如果没有设置白名单,根据默认行为决定
switch (FilterProps.defaultBehavior)
{
case FactionFilterDefaultBehavior.Allow:
Log.Message($"[FactionFilter] Quest allowed: No whitelist, default behavior is Allow");
return true;
case FactionFilterDefaultBehavior.Deny:
Log.Message($"[FactionFilter] Quest blocked: No whitelist, default behavior is Deny");
return false;
default:
return true;
}
}
/// <summary>
/// 获取目标的派系
/// </summary>
private Faction GetTargetFaction(IIncidentTarget target)
{
if (target is Map map)
{
return map.ParentFaction ?? Faction.OfPlayer;
}
else if (target is World world)
{
return Faction.OfPlayer;
}
else if (target is Caravan caravan)
{
return caravan.Faction;
}
return Faction.OfPlayer;
}
/// <summary>
/// 调试方法:显示当前过滤状态
/// </summary>
public string GetFactionFilterStatus(IIncidentTarget target)
{
if (!FilterProps.useFactionFilter)
return "Faction filter: DISABLED";
Faction faction = GetTargetFaction(target);
if (faction == null)
return "Faction filter: NO FACTION";
StringBuilder status = new StringBuilder();
status.AppendLine($"Faction filter: {faction.def.defName}");
// 黑名单检查
if (FilterProps.factionTypeBlacklist != null &&
FilterProps.factionTypeBlacklist.Contains(faction.def))
{
status.AppendLine("❌ BLACKLISTED");
return status.ToString();
}
// 白名单检查
if (FilterProps.factionTypeWhitelist != null &&
FilterProps.factionTypeWhitelist.Count > 0)
{
bool inWhitelist = FilterProps.factionTypeWhitelist.Contains(faction.def);
if (inWhitelist)
{
status.AppendLine("✅ WHITELISTED");
}
else
{
status.AppendLine(FilterProps.defaultBehavior == FactionFilterDefaultBehavior.Allow ?
"⚠️ NOT IN WHITELIST (Allowed by default)" :
"❌ NOT IN WHITELIST (Denied by default)");
}
}
else
{
status.AppendLine(FilterProps.defaultBehavior == FactionFilterDefaultBehavior.Allow ?
"✅ NO WHITELIST (Allowed by default)" :
"❌ NO WHITELIST (Denied by default)");
}
return status.ToString();
}
}
}

View File

@@ -1,63 +0,0 @@
using System.Collections.Generic;
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class StorytellerComp_SingleOnceFixed_FactionFilter : StorytellerComp_SingleOnceFixed
{
private StorytellerCompProperties_SingleOnceFixed_FactionFilter PropsFilter => (StorytellerCompProperties_SingleOnceFixed_FactionFilter)props;
public override IEnumerable<FiringIncident> MakeIntervalIncidents(IIncidentTarget target)
{
// 检查派系过滤条件
if (!CheckFactionFilter())
{
yield break;
}
// 调用父类的逻辑
foreach (var incident in base.MakeIntervalIncidents(target))
{
yield return incident;
}
}
private bool CheckFactionFilter()
{
if (Faction.OfPlayer == null)
return false;
var playerFactionDef = Faction.OfPlayer.def;
// 优先检查白名单:如果白名单有内容,只有白名单内的派系才能触发
if (PropsFilter.allowedFactionTypes != null && PropsFilter.allowedFactionTypes.Count > 0)
{
return PropsFilter.allowedFactionTypes.Contains(playerFactionDef);
}
// 然后检查黑名单:如果黑名单有内容,黑名单内的派系不能触发
if (PropsFilter.excludedFactionTypes != null && PropsFilter.excludedFactionTypes.Count > 0)
{
return !PropsFilter.excludedFactionTypes.Contains(playerFactionDef);
}
// 如果既没有白名单也没有黑名单,所有派系都能触发
return true;
}
}
public class StorytellerCompProperties_SingleOnceFixed_FactionFilter : StorytellerCompProperties_SingleOnceFixed
{
// 黑名单:这些派系类型不会触发事件
public List<FactionDef> excludedFactionTypes;
// 白名单:只有这些派系类型会触发事件(优先级高于黑名单)
public List<FactionDef> allowedFactionTypes;
public StorytellerCompProperties_SingleOnceFixed_FactionFilter()
{
compClass = typeof(StorytellerComp_SingleOnceFixed_FactionFilter);
}
}
}

View File

@@ -208,7 +208,8 @@
<Compile Include="Stat\StatWorker_Energy.cs" />
<Compile Include="Stat\StatWorker_Maintenance.cs" />
<Compile Include="Stat\StatWorker_NanoRepair.cs" />
<Compile Include="Storyteller\StorytellerComp_SingleOnceFixed_FactionFilter.cs" />
<Compile Include="Storyteller\StorytellerCompProperties_ImportantQuestWithFactionFilter.cs" />
<Compile Include="Storyteller\StorytellerComp_ImportantQuestWithFactionFilter.cs" />
<Compile Include="ThingComp\CompAndPatch_GiveHediffOnShot.cs" />
<Compile Include="ThingComp\CompApparelInterceptor.cs" />
<Compile Include="ThingComp\CompPsychicScaling.cs" />