1
This commit is contained in:
@@ -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
|
||||
{
|
||||
// 可用的设施列表(简单的字符串列表)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ namespace WulaFallenEmpire
|
||||
BombingRun, // 轰炸飞越
|
||||
Reconnaissance, // 侦察飞越
|
||||
GroundStrafing, // 地面扫射
|
||||
SectorSurveillance // 扇形区域监视
|
||||
SectorSurveillance, // 扇形区域监视
|
||||
}
|
||||
|
||||
// 进场类型枚举
|
||||
|
||||
Reference in New Issue
Block a user