Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/Designator/Designator_CallSkyfallerInArea.cs
2025-12-02 11:15:13 +08:00

198 lines
6.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public class Designator_CallSkyfallerInArea : Designator
{
private readonly new Texture2D icon;
// 记录已经处理过的建筑(避免重复)
private HashSet<Thing> processedBuildings = new HashSet<Thing>();
public Designator_CallSkyfallerInArea()
{
defaultLabel = "WULA_Designator_CallSkyfallerInArea".Translate();
defaultDesc = "WULA_Designator_CallSkyfallerInAreaDesc".Translate();
icon = ContentFinder<Texture2D>.Get("Wula/UI/Designators/WULA_AreaSkyfaller");
soundDragSustain = SoundDefOf.Designate_DragStandard;
soundDragChanged = SoundDefOf.Designate_DragStandard_Changed;
useMouseIcon = true;
soundSucceeded = SoundDefOf.Designate_Claim;
hotKey = KeyBindingDefOf.Misc12;
tutorTag = "CallSkyfallerInArea";
}
public override AcceptanceReport CanDesignateCell(IntVec3 c)
{
if (!c.InBounds(Map))
return false;
// 允许在迷雾格上选择(就像拆除和索赔设计器一样)
if (c.Fogged(Map))
return false;
// 只要单元格内有玩家建筑,就允许选择
var things = Map.thingGrid.ThingsListAt(c);
foreach (var thing in things)
{
if (thing.def.category == ThingCategory.Building &&
thing.Faction == Faction.OfPlayer &&
thing.TryGetComp<CompSkyfallerCaller>() != null)
{
return true;
}
}
// 即使单元格内没有符合条件的建筑,也允许选择(这样用户可以拖动区域)
// 但返回一个友好的提示
return "WULA_NoCallableBuildingsInCell".Translate();
}
public override void DesignateSingleCell(IntVec3 c)
{
// 处理单个单元格内的所有建筑
ProcessCell(c);
}
public override void DesignateMultiCell(IEnumerable<IntVec3> cells)
{
// 清除已处理的建筑记录
processedBuildings.Clear();
int totalBuildings = 0;
// 处理所有选中的单元格
foreach (var cell in cells)
{
if (cell.InBounds(Map))
{
// 统计该单元格处理的建筑数量
int cellCount = processedBuildings.Count;
ProcessCell(cell);
int newBuildings = processedBuildings.Count - cellCount;
totalBuildings += newBuildings;
}
}
// 计算成功和失败的数量
// 这里需要跟踪每个建筑的调用结果
// 由于我们直接调用CallSkyfaller需要知道哪些失败了
// 简化处理在ProcessCell中统计
// 显示简单的结果消息
if (totalBuildings > 0)
{
Messages.Message("WULA_AreaCallInitiated".Translate(totalBuildings),
MessageTypeDefOf.PositiveEvent);
}
else
{
Messages.Message("WULA_NoCallableBuildingsInArea".Translate(),
MessageTypeDefOf.NeutralEvent);
}
}
private void ProcessCell(IntVec3 cell)
{
var things = Map.thingGrid.ThingsListAt(cell);
foreach (var thing in things)
{
// 跳过非建筑
if (thing.def.category != ThingCategory.Building)
continue;
// 跳过非玩家建筑
if (thing.Faction != Faction.OfPlayer)
continue;
// 检查是否已经处理过(避免重复处理同一个建筑)
if (processedBuildings.Contains(thing))
continue;
// 获取空投组件
var comp = thing.TryGetComp<CompSkyfallerCaller>();
if (comp == null)
continue;
// 尝试呼叫空投
if (comp.CanCallSkyfaller)
{
comp.CallSkyfaller(false);
processedBuildings.Add(thing);
}
// 即使不能呼叫,也添加到已处理列表,避免重复尝试
else
{
processedBuildings.Add(thing);
}
}
}
public override AcceptanceReport CanDesignateThing(Thing t)
{
// 这里提供单个建筑的反向设计器支持(右键菜单)
if (t.def.category != ThingCategory.Building)
return false;
if (t.Faction != Faction.OfPlayer)
return false;
var comp = t.TryGetComp<CompSkyfallerCaller>();
if (comp == null)
return false;
if (!comp.CanCallSkyfaller)
return GetFailureReason(t, comp);
return true;
}
private string GetFailureReason(Thing building, CompSkyfallerCaller comp)
{
if (!comp.HasRequiredFlyOver && comp.Props.requireFlyOver)
return "WULA_NoBuildingDropperFlyOver".Translate();
if (!comp.CheckRoofConditions)
{
var roof = building.Position.GetRoof(building.Map);
if (roof?.isThickRoof == true)
return "WULA_ThickRoofBlocking".Translate();
else
return "WULA_RoofBlocking".Translate();
}
if (!comp.HasEnoughMaterials())
return "WULA_InsufficientMaterials".Translate();
if (comp.used)
return "WULA_AlreadyUsed".Translate();
if (comp.calling)
return "WULA_AlreadyCalling".Translate();
return "WULA_CannotCallSkyfaller".Translate();
}
public override void DesignateThing(Thing t)
{
// 用于反向设计器(右键菜单)
var comp = t.TryGetComp<CompSkyfallerCaller>();
if (comp != null && comp.CanCallSkyfaller)
{
comp.CallSkyfaller(false);
}
}
public override void SelectedUpdate()
{
// 参考Designator_Deconstruct只绘制鼠标悬停方框
GenUI.RenderMouseoverBracket();
}
}
}