Files
WulaFallenEmpireRW/Source/WulaFallenEmpire/GlobalWorkTable/Building_ResourceSubmitter.cs
2025-11-03 18:23:41 +08:00

349 lines
12 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 RimWorld;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Verse;
namespace WulaFallenEmpire
{
public class Building_ResourceSubmitter : Building_Storage
{
private CompPowerTrader powerComp;
private CompRefuelable refuelableComp;
private CompFlickable flickableComp;
public override void SpawnSetup(Map map, bool respawningAfterLoad)
{
base.SpawnSetup(map, respawningAfterLoad);
powerComp = GetComp<CompPowerTrader>();
refuelableComp = GetComp<CompRefuelable>();
flickableComp = GetComp<CompFlickable>();
}
/// <summary>
/// 检查建筑是否可用(电力、燃料、开关等)
/// </summary>
public bool IsOperational
{
get
{
if (powerComp != null && !powerComp.PowerOn)
return false;
if (refuelableComp != null && !refuelableComp.HasFuel)
return false;
if (flickableComp != null && !flickableComp.SwitchIsOn)
return false;
return true;
}
}
/// <summary>
/// 获取建筑的中心位置(用于生成 Skyfaller
/// </summary>
public IntVec3 CenterPosition
{
get
{
// 对于偶数尺寸的建筑,返回中心附近的单元格
var center = Position + new IntVec3(def.Size.x / 2, 0, def.Size.z / 2);
// 确保在建筑范围内
return center;
}
}
public override IEnumerable<Gizmo> GetGizmos()
{
foreach (Gizmo g in base.GetGizmos())
{
yield return g;
}
// 添加提交到资源储存器的命令
yield return new Command_Action
{
action = SubmitContentsToStorage,
defaultLabel = "WULA_SubmitToStorage".Translate(),
defaultDesc = "WULA_SubmitToStorageDesc".Translate(),
icon = ContentFinder<Texture2D>.Get("UI/Commands/Upload"),
disabledReason = GetDisabledReason()
};
}
/// <summary>
/// 获取存储的物品列表 - 修复版本
/// </summary>
private List<Thing> GetStoredItems()
{
var items = new List<Thing>();
// 方法1通过直接持有的物品获取如果建筑本身是容器
if (this is IThingHolder thingHolder)
{
ThingOwner directlyHeldThings = thingHolder.GetDirectlyHeldThings();
if (directlyHeldThings != null)
{
items.AddRange(directlyHeldThings);
}
}
// 方法2通过存储设置获取地图上的物品
if (items.Count == 0)
{
// 获取建筑的存储设置
var storageSettings = GetStoreSettings();
if (storageSettings != null)
{
// 查找地图上被此建筑接受的物品
foreach (Thing thing in Map.listerThings.ThingsInGroup(ThingRequestGroup.HaulableAlways))
{
if (thing.Position.InHorDistOf(Position, 2f) && storageSettings.AllowedToAccept(thing))
{
items.Add(thing);
}
}
}
}
return items;
}
/// <summary>
/// 获取禁用原因
/// </summary>
private string GetDisabledReason()
{
if (!IsOperational)
{
if (powerComp != null && !powerComp.PowerOn)
return "WULA_NoPower".Translate();
if (refuelableComp != null && !refuelableComp.HasFuel)
return "WULA_NoFuel".Translate();
if (flickableComp != null && !flickableComp.SwitchIsOn)
return "WULA_SwitchOff".Translate();
}
if (GetStoredItems().Count == 0)
return "WULA_NoItemsToSubmit".Translate();
return string.Empty;
}
/// <summary>
/// 提交内容到资源储存器
/// </summary>
private void SubmitContentsToStorage()
{
if (!IsOperational)
{
Messages.Message("WULA_DeviceNotOperational".Translate(), MessageTypeDefOf.RejectInput);
return;
}
var storedItems = GetStoredItems();
if (storedItems.Count == 0)
{
Messages.Message("WULA_NoItemsToSubmit".Translate(), MessageTypeDefOf.RejectInput);
return;
}
// 执行提交逻辑
if (TrySubmitItems(storedItems))
{
// 生成 Skyfaller 演出效果
CreateSubmissionEffect();
Messages.Message("WULA_ItemsSubmitted".Translate(storedItems.Count), MessageTypeDefOf.PositiveEvent);
}
else
{
Messages.Message("WULA_SubmissionFailed".Translate(), MessageTypeDefOf.NegativeEvent);
}
}
/// <summary>
/// 尝试提交物品到资源储存器
/// </summary>
private bool TrySubmitItems(List<Thing> items)
{
try
{
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null)
{
Log.Error("GlobalStorageWorldComponent not found");
return false;
}
int submittedCount = 0;
var processedItems = new List<Thing>();
foreach (Thing item in items)
{
if (item == null || item.Destroyed)
continue;
// 检查是否为装备或武器
if (IsEquipment(item.def))
{
// 装备和武器直接添加到输出存储
globalStorage.AddToOutputStorage(item.def, item.stackCount);
processedItems.Add(item);
submittedCount += item.stackCount;
}
else
{
// 其他物品添加到输入存储
globalStorage.AddToInputStorage(item.def, item.stackCount);
processedItems.Add(item);
submittedCount += item.stackCount;
}
}
// 从世界中移除已提交的物品
foreach (Thing item in processedItems)
{
// 如果物品在建筑的直接容器中
if (this is IThingHolder thingHolder)
{
ThingOwner directlyHeldThings = thingHolder.GetDirectlyHeldThings();
if (directlyHeldThings != null && directlyHeldThings.Contains(item))
{
directlyHeldThings.Remove(item);
}
}
// 如果物品在地图上,直接销毁
if (item.Spawned)
{
item.Destroy();
}
}
Log.Message($"Successfully submitted {submittedCount} items to global storage");
return submittedCount > 0;
}
catch (System.Exception ex)
{
Log.Error($"Error submitting items to storage: {ex}");
return false;
}
}
/// <summary>
/// 检查是否为装备或武器
/// </summary>
private bool IsEquipment(ThingDef thingDef)
{
return thingDef.IsApparel || thingDef.IsWeapon || thingDef.category == ThingCategory.Building;
}
/// <summary>
/// 创建提交效果Skyfaller
/// </summary>
private void CreateSubmissionEffect()
{
try
{
// 获取 Skyfaller 定义
ThingDef skyfallerDef = DefDatabase<ThingDef>.GetNamedSilentFail("DropPodIncoming");
if (skyfallerDef == null)
{
// 备用方案:使用简单的效果
CreateFallbackEffect();
return;
}
// 创建空的 Skyfaller
Skyfaller skyfaller = (Skyfaller)ThingMaker.MakeThing(skyfallerDef);
// 设置位置(建筑中心)
IntVec3 dropPos = CenterPosition;
// 确保位置有效
if (!dropPos.IsValid || !dropPos.InBounds(Map))
{
dropPos = Position; // 回退到建筑位置
}
// 生成 Skyfaller
GenSpawn.Spawn(skyfaller, dropPos, Map);
// 可选:添加一些视觉效果
FleckMaker.ThrowLightningGlow(dropPos.ToVector3Shifted(), Map, 2f);
Log.Message("Created submission skyfaller effect");
}
catch (System.Exception ex)
{
Log.Error($"Error creating skyfaller effect: {ex}");
CreateFallbackEffect();
}
}
/// <summary>
/// 备用效果(如果 Skyfaller 失败)
/// </summary>
private void CreateFallbackEffect()
{
try
{
IntVec3 center = CenterPosition;
// 生成闪光效果
for (int i = 0; i < 3; i++)
{
FleckMaker.ThrowLightningGlow(center.ToVector3Shifted(), Map, 1.5f);
}
// 生成烟雾效果
FleckMaker.ThrowSmoke(center.ToVector3Shifted(), Map, 2f);
Log.Message("Created fallback submission effect");
}
catch (System.Exception ex)
{
Log.Error($"Error creating fallback effect: {ex}");
}
}
/// <summary>
/// 修复的检查字符串方法 - 避免空行问题
/// </summary>
public override string GetInspectString()
{
StringBuilder stringBuilder = new StringBuilder();
// 获取基础检查字符串
string baseString = base.GetInspectString();
if (!baseString.NullOrEmpty())
{
stringBuilder.Append(baseString);
}
// 获取存储信息
var storedItems = GetStoredItems();
int itemCount = storedItems.Count;
int totalStack = storedItems.Sum(item => item.stackCount);
// 添加存储信息
if (stringBuilder.Length > 0)
{
stringBuilder.AppendLine();
}
stringBuilder.Append($"{"WULA_StoredItems".Translate()}: {itemCount} ({totalStack} {"WULA_Items".Translate()})");
// 添加状态信息(如果不工作)
if (!IsOperational)
{
if (stringBuilder.Length > 0)
{
stringBuilder.AppendLine();
}
stringBuilder.Append($"{"WULA_Status".Translate()}: {"WULA_Inoperative".Translate()}");
}
return stringBuilder.ToString();
}
}
}