This commit is contained in:
Tourswen
2025-11-10 01:19:43 +08:00
parent 2f20af64f3
commit b1fea9a600
16 changed files with 715 additions and 123 deletions

View File

@@ -7,6 +7,27 @@ namespace WulaFallenEmpire
{
public class CompFlyOverFacilities : ThingComp
{
// 在 CompFlyOverFacilities 类中添加以下方法
public bool IsFacilityReady(string facilityName)
{
if (!HasFacility(facilityName))
return false;
var cooldownComp = parent.GetComp<CompFlyOverCooldown>();
return cooldownComp == null || !cooldownComp.IsOnCooldown;
}
public string GetFacilityStatus(string facilityName)
{
if (!HasFacility(facilityName))
return "Not Available";
var cooldownComp = parent.GetComp<CompFlyOverCooldown>();
if (cooldownComp == null)
return "Ready (No Cooldown)";
return cooldownComp.IsOnCooldown ? $"Cooldown: {cooldownComp.CooldownTicksRemaining.ToStringTicksToPeriod()}" : "Ready";
}
public CompProperties_FlyOverFacilities Props => (CompProperties_FlyOverFacilities)props;
// 当前激活的设施列表
@@ -62,6 +83,8 @@ namespace WulaFallenEmpire
}
}
public class CompProperties_FlyOverFacilities : CompProperties
{
// 可用的设施列表(简单的字符串列表)

View File

@@ -0,0 +1,238 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
namespace WulaFallenEmpire
{
public class CompAbilityEffect_GlobalFlyOverCooldown : CompAbilityEffect
{
public new CompProperties_GlobalFlyOverCooldown Props => (CompProperties_GlobalFlyOverCooldown)props;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
if (parent.pawn == null || parent.pawn.Map == null)
return;
// 获取所有可用的轰炸设施FlyOver
var availableFlyOvers = GetAvailableFlyOvers();
if (availableFlyOvers.Count == 0)
{
Log.Error($"[GlobalFlyOverCooldown] No available FlyOver with BombardmentFacility found");
return;
}
// 随机选择一个FlyOver来执行任务
var selectedFlyOver = availableFlyOvers.RandomElement();
var facilitiesComp = selectedFlyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp == null)
{
Log.Error($"[GlobalFlyOverCooldown] Selected FlyOver has no CompFlyOverFacilities");
return;
}
// 设置冷却时间
SetCooldown(selectedFlyOver, Props.globalCooldownTicks);
Log.Message($"[GlobalFlyOverCooldown] Set cooldown on FlyOver at {selectedFlyOver.Position} for {Props.globalCooldownTicks} ticks");
}
public override bool GizmoDisabled(out string reason)
{
if (parent.pawn?.Map == null)
{
reason = "WULA_GlobalFlyOverCooldown.CannotUseOutsideMap".Translate();
return true;
}
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
if (availableFlyOvers.Count == 0)
{
reason = "WULA_GlobalFlyOverCooldown.NoAvailableFacilities".Translate(totalFlyOvers.Count);
return true;
}
return base.GizmoDisabled(out reason);
}
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
try
{
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
var cooldownFlyOvers = totalFlyOvers.Count - availableFlyOvers.Count;
return "WULA_GlobalFlyOverCooldown.FacilityStatus".Translate(availableFlyOvers.Count, cooldownFlyOvers);
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in ExtraLabelMouseAttachment: {ex}");
return "WULA_GlobalFlyOverCooldown.FacilityStatusError".Translate();
}
}
// 重写:添加额外的工具提示信息
public override string ExtraTooltipPart()
{
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
var cooldownFlyOvers = totalFlyOvers.Count - availableFlyOvers.Count;
var baseTooltip = base.ExtraTooltipPart() ?? "";
var facilityDesc = "\n" + "WULA_GlobalFlyOverCooldown.FacilityStatusDetailed".Translate(availableFlyOvers.Count, cooldownFlyOvers);
if (availableFlyOvers.Count > 0)
{
var cooldownComp = availableFlyOvers[0].GetComp<CompFlyOverCooldown>();
if (cooldownComp != null)
{
facilityDesc += "\n" + "WULA_GlobalFlyOverCooldown.CooldownTime".Translate(Props.globalCooldownTicks.ToStringTicksToPeriod());
}
}
return baseTooltip + facilityDesc;
}
// 重写:验证目标时检查设施可用性
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
if (!base.Valid(target, throwMessages))
return false;
var availableFlyOvers = GetAvailableFlyOvers();
if (availableFlyOvers.Count == 0)
{
if (throwMessages)
{
Messages.Message("WULA_GlobalFlyOverCooldown.NoAvailableFacilitiesSimple".Translate(), parent.pawn, MessageTypeDefOf.RejectInput);
}
return false;
}
return true;
}
// 获取可用的FlyOver不在冷却中的
private List<FlyOver> GetAvailableFlyOvers()
{
var availableFlyOvers = new List<FlyOver>();
if (parent.pawn?.Map == null)
return availableFlyOvers;
try
{
var allFlyOvers = GetTotalFlyOvers();
foreach (var flyOver in allFlyOvers)
{
if (!IsOnCooldown(flyOver))
{
availableFlyOvers.Add(flyOver);
}
}
return availableFlyOvers;
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in GetAvailableFlyOvers: {ex}");
return new List<FlyOver>();
}
}
// 获取所有具有轰炸设施的FlyOver
private List<FlyOver> GetTotalFlyOvers()
{
var totalFlyOvers = new List<FlyOver>();
if (parent.pawn?.Map == null)
return totalFlyOvers;
try
{
// 获取地图上所有FlyOver
var allFlyOvers = new List<Thing>();
var dynamicObjects = parent.pawn.Map.dynamicDrawManager.DrawThings;
foreach (var thing in dynamicObjects)
{
if (thing is FlyOver flyOver && !flyOver.Destroyed)
{
allFlyOvers.Add(thing);
}
}
// 筛选具有轰炸设施的FlyOver
foreach (var thing in allFlyOvers)
{
if (thing is FlyOver flyOver)
{
var facilitiesComp = flyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp != null && facilitiesComp.HasFacility("BombardmentFacility"))
{
totalFlyOvers.Add(flyOver);
}
}
}
return totalFlyOvers;
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in GetTotalFlyOvers: {ex}");
return new List<FlyOver>();
}
}
// 检查FlyOver是否在冷却中
private bool IsOnCooldown(FlyOver flyOver)
{
if (flyOver == null)
return true;
// 从FlyOver的comps中查找冷却组件
var cooldownComp = flyOver.GetComp<CompFlyOverCooldown>();
return cooldownComp?.IsOnCooldown ?? false;
}
// 设置FlyOver的冷却时间
private void SetCooldown(FlyOver flyOver, int cooldownTicks)
{
if (flyOver == null)
return;
// 获取或添加冷却组件
var cooldownComp = flyOver.GetComp<CompFlyOverCooldown>();
if (cooldownComp == null)
{
Log.Error($"[GlobalFlyOverCooldown] FlyOver at {flyOver.Position} has no CompFlyOverCooldown");
return;
}
cooldownComp.StartCooldown(cooldownTicks);
}
}
public class CompProperties_GlobalFlyOverCooldown : CompProperties_AbilityEffect
{
// 全局冷却时间ticks
public int globalCooldownTicks = 60000; // 默认1天
// 必需的设施名称
public string requiredFacility = "BombardmentFacility";
public CompProperties_GlobalFlyOverCooldown()
{
compClass = typeof(CompAbilityEffect_GlobalFlyOverCooldown);
}
}
}

View File

@@ -0,0 +1,96 @@
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompFlyOverCooldown : ThingComp
{
public CompProperties_FlyOverCooldown Props => (CompProperties_FlyOverCooldown)props;
// 冷却结束的tick
private int cooldownEndTick = -1;
// 是否在冷却中
public bool IsOnCooldown => Find.TickManager.TicksGame < cooldownEndTick;
// 剩余冷却时间ticks
public int CooldownTicksRemaining => IsOnCooldown ? cooldownEndTick - Find.TickManager.TicksGame : 0;
// 冷却进度0-1
public float CooldownProgress
{
get
{
if (!IsOnCooldown) return 0f;
int totalCooldown = cooldownEndTick - (cooldownEndTick - Props.baseCooldownTicks);
return 1f - ((float)CooldownTicksRemaining / Props.baseCooldownTicks);
}
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref cooldownEndTick, "cooldownEndTick", -1);
}
// 开始冷却
public void StartCooldown(int cooldownTicks = -1)
{
int actualCooldown = cooldownTicks > 0 ? cooldownTicks : Props.baseCooldownTicks;
cooldownEndTick = Find.TickManager.TicksGame + actualCooldown;
Log.Message($"[FlyOverCooldown] Cooldown started for {actualCooldown} ticks, ends at tick {cooldownEndTick}");
}
// 强制结束冷却
public void EndCooldown()
{
cooldownEndTick = -1;
}
// 获取冷却状态描述
public string GetCooldownStatus()
{
if (!IsOnCooldown)
return "WULA_FlyOverCooldown.Ready".Translate();
return "WULA_FlyOverCooldown.CooldownRemaining".Translate(CooldownTicksRemaining.ToStringTicksToPeriod());
}
public override void CompTick()
{
base.CompTick();
// 可以在这里添加冷却期间的视觉效果或逻辑
if (IsOnCooldown && Find.TickManager.TicksGame % 60 == 0) // 每60ticks检查一次
{
// 可选:在冷却期间添加一些视觉效果
if (Rand.MTBEventOccurs(10f, 1f, 1f))
{
FleckMaker.ThrowMetaIcon(parent.Position, parent.Map, FleckDefOf.SleepZ);
}
}
}
// 在检视面板中显示冷却信息
public override string CompInspectStringExtra()
{
if (IsOnCooldown)
{
return "WULA_FlyOverCooldown.BombardmentFacilityStatus".Translate(GetCooldownStatus());
}
return "WULA_FlyOverCooldown.BombardmentFacilityReady".Translate();
}
}
public class CompProperties_FlyOverCooldown : CompProperties
{
// 基础冷却时间ticks
public int baseCooldownTicks = 60000; // 默认1天
public CompProperties_FlyOverCooldown()
{
compClass = typeof(CompFlyOverCooldown);
}
}
}

View File

@@ -62,7 +62,7 @@ namespace WulaFallenEmpire
BombingRun, // 轰炸飞越
Reconnaissance, // 侦察飞越
GroundStrafing, // 地面扫射
SectorSurveillance // 扇形区域监视
SectorSurveillance, // 扇形区域监视
}
// 进场类型枚举