This commit is contained in:
2025-11-29 12:01:47 +08:00
parent 14e018e312
commit 14a2cf542c
9 changed files with 355 additions and 3 deletions

View File

@@ -824,6 +824,12 @@
<garbageShieldEnabled>true</garbageShieldEnabled>
<garbageShieldUIEventDefName>Wula_UI_Legion_Reply_1</garbageShieldUIEventDefName>
</li>
<li Class="WulaFallenEmpire.CompProperties_ValueConverter">
<conversionRate>0.8</conversionRate>
<destroyAfterConversion>true</destroyAfterConversion>
<garbageShieldEnabled>true</garbageShieldEnabled>
<garbageShieldUIEventDefName>Wula_UI_Legion_Reply_1</garbageShieldUIEventDefName>
</li>
</comps>
<inspectorTabs>
<li>ITab_ContentsTransporter</li>

View File

@@ -351,4 +351,23 @@
<WULA_TeleporterEnableDesc>启用区域传送功能,允许机械乌拉在其覆盖范围内以传送代替常规移动。</WULA_TeleporterEnableDesc>
<WULA_TeleporterDisable>禁用传送器</WULA_TeleporterDisable>
<WULA_TeleporterDisableDesc>禁用区域传送功能,在其附近的机械乌拉使用常规移动而非传送。</WULA_TeleporterDisableDesc>
<!-- Value Converter Strings -->
<WULA_ConvertToSilver>向舰队贩卖物资</WULA_ConvertToSilver>
<WULA_ConvertToSilverDesc>将输送舱发射到乌拉帝国舰队,所有物品的价值按照 {0} 的比率转换为白银储存在舰队物资中</WULA_ConvertToSilverDesc>
<WULA_CannotConvert>无法贩卖:包含禁止物品或容器为空</WULA_CannotConvert>
<WULA_NoItemsToConvert>没有可贩卖的物品</WULA_NoItemsToConvert>
<WULA_NoValuableItems>没有有价值的物品</WULA_NoValuableItems>
<WULA_ConversionValueTooLow>贩卖价值过低</WULA_ConversionValueTooLow>
<WULA_ConversionCancelledDueToForbiddenItems>贩卖取消:包含禁止物品:{0}</WULA_ConversionCancelledDueToForbiddenItems>
<WULA_ValueConverted>成功将价值 {0} 的物品转换为 {1} 白银</WULA_ValueConverted>
<WULA_ValueConvertedWithLoss>成功将价值 {0} 的物品转换为 {1} 白银(转换率:{2}</WULA_ValueConvertedWithLoss>
<WULA_ValueConvertedWithBonus>成功将价值 {0} 的物品转换为 {1} 白银(奖励率:{2}</WULA_ValueConvertedWithBonus>
<WULA_CurrentValueInContainer>容器内物品总价值:{0}</WULA_CurrentValueInContainer>
<WULA_PotentialSilver>可转换白银:{0}</WULA_PotentialSilver>
<WULA_ConversionRate>转换率:{0}</WULA_ConversionRate>
<WULA_ConversionEfficiency>转换效率:{0}</WULA_ConversionEfficiency>
<WULA_ConversionEfficiencyLoss>(有损耗)</WULA_ConversionEfficiencyLoss>
<WULA_ConversionEfficiencyBonus>(有加成)</WULA_ConversionEfficiencyBonus>
<WULA_ConversionEfficiencyNormal>(等值转换)</WULA_ConversionEfficiencyNormal>
</LanguageData>

View File

@@ -0,0 +1,21 @@
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompProperties_ValueConverter : CompProperties
{
public float conversionRate = 1.0f; // 价值转换倍率
public ThingDef outputThingDef = null; // 输出物品定义,默认为白银
public bool destroyAfterConversion = true; // 转换后是否销毁建筑
// 垃圾屏蔽配置
public bool garbageShieldEnabled = false;
public string garbageShieldUIEventDefName = "Wula_UI_Legion_Reply_1";
public CompProperties_ValueConverter()
{
this.compClass = typeof(CompValueConverter);
}
}
}

View File

@@ -0,0 +1,304 @@
using RimWorld;
using System.Collections.Generic;
using UnityEngine;
using Verse;
using Verse.Sound;
using System.Text;
using System.Linq;
using RimWorld.Planet;
namespace WulaFallenEmpire
{
public class CompValueConverter : CompLaunchable_TransportPod
{
public new CompProperties_ValueConverter Props => (CompProperties_ValueConverter)this.props;
// 获取垃圾屏蔽组件
public CompGarbageShield GarbageShieldComp => this.parent.GetComp<CompGarbageShield>();
// 获取容器组件
public new CompTransporter Transporter => this.parent.GetComp<CompTransporter>();
public override IEnumerable<Gizmo> CompGetGizmosExtra()
{
// 首先处理基类的Gizmo但过滤掉原版的发射按钮
foreach (Gizmo gizmo in base.CompGetGizmosExtra())
{
// 跳过原版的发射按钮
if (gizmo is Command_Action launchCommand &&
(launchCommand.defaultDesc == "CommandLaunchGroupDesc".Translate() ||
launchCommand.defaultDesc == "CommandLaunchSingleDesc".Translate()))
{
continue;
}
yield return gizmo;
}
// 添加我们的转换按钮
if (Transporter != null && Transporter.innerContainer.Any)
{
Command_Action command = new Command_Action();
command.defaultLabel = "WULA_ConvertToSilver".Translate();
command.defaultDesc = "WULA_ConvertToSilverDesc".Translate(Props.conversionRate.ToStringPercent());
command.icon = ContentFinder<Texture2D>.Get("UI/Commands/ConvertToSilver");
command.action = delegate
{
this.TryLaunchToSilver();
};
// 添加禁用状态检查
if (!CanConvert())
{
command.Disable("WULA_CannotConvert".Translate());
}
yield return command;
}
}
/// <summary>
/// 检查是否可以执行转换
/// </summary>
private bool CanConvert()
{
if (Transporter == null || !Transporter.innerContainer.Any)
return false;
// 检查垃圾屏蔽
if (GarbageShieldComp != null && GarbageShieldComp.GarbageShieldEnabled)
{
List<Thing> forbiddenItems = GarbageShieldComp.GetForbiddenItems(Transporter.innerContainer);
if (forbiddenItems.Count > 0)
return false;
}
return true;
}
/// <summary>
/// 将物品价值转换为白银
/// </summary>
public void TryLaunchToSilver()
{
if (!this.parent.Spawned)
{
Log.Error("Tried to convert value from " + this.parent + " but it's not spawned.");
return;
}
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null)
{
Log.Error("Could not find GlobalStorageWorldComponent.");
return;
}
if (Transporter == null || !Transporter.innerContainer.Any)
{
Messages.Message("WULA_NoItemsToConvert".Translate(), this.parent, MessageTypeDefOf.RejectInput);
return;
}
// 检查垃圾屏蔽
if (GarbageShieldComp != null && GarbageShieldComp.GarbageShieldEnabled)
{
List<Thing> forbiddenItems = GarbageShieldComp.GetForbiddenItems(Transporter.innerContainer);
if (forbiddenItems.Count > 0)
{
StringBuilder forbiddenList = new StringBuilder();
foreach (Thing item in forbiddenItems)
{
if (forbiddenList.Length > 0) forbiddenList.Append(", ");
forbiddenList.Append($"{item.LabelCap} x{item.stackCount}");
}
Messages.Message("WULA_ConversionCancelledDueToForbiddenItems".Translate(forbiddenList.ToString()),
this.parent, MessageTypeDefOf.RejectInput);
GarbageShieldComp.ProcessGarbageShieldTrigger(forbiddenItems);
return;
}
}
// 计算总价值
float totalValue = CalculateTotalValue();
if (totalValue <= 0)
{
Messages.Message("WULA_NoValuableItems".Translate(), this.parent, MessageTypeDefOf.RejectInput);
return;
}
// 应用转换倍率
int silverAmount = CalculateSilverAmount(totalValue);
if (silverAmount <= 0)
{
Messages.Message("WULA_ConversionValueTooLow".Translate(), this.parent, MessageTypeDefOf.RejectInput);
return;
}
// 执行转换
PerformConversion(globalStorage, silverAmount, totalValue);
// 调用基类的发射方法,让它处理动画和销毁
// 注意:这里我们发射到当前地图的同一个位置,实际上只是利用发射动画
base.TryLaunch(this.parent.Map.Tile, null);
}
/// <summary>
/// 重写基类的TryLaunch方法阻止原版发射逻辑
/// </summary>
public new void TryLaunch(PlanetTile destinationTile, TransportersArrivalAction arrivalAction)
{
// 阻止原版发射逻辑,使用我们的转换逻辑
TryLaunchToSilver();
}
/// <summary>
/// 计算容器内物品的总价值
/// </summary>
private float CalculateTotalValue()
{
float totalValue = 0f;
foreach (Thing item in Transporter.innerContainer)
{
// 计算单个物品的市场价值
float itemValue = item.MarketValue * item.stackCount;
totalValue += itemValue;
if (Prefs.DevMode)
{
Log.Message($"[ValueConverter] {item.LabelCap} x{item.stackCount}: {item.MarketValue} each, total: {itemValue}");
}
}
if (Prefs.DevMode)
{
Log.Message($"[ValueConverter] Total value before conversion: {totalValue}");
}
return totalValue;
}
/// <summary>
/// 计算转换后的白银数量
/// </summary>
private int CalculateSilverAmount(float totalValue)
{
// 应用转换倍率
float convertedValue = totalValue * Props.conversionRate;
// 转换为白银白银的市场价值为1
int silverAmount = Mathf.FloorToInt(convertedValue);
if (Prefs.DevMode)
{
Log.Message($"[ValueConverter] After conversion rate ({Props.conversionRate}): {convertedValue}, Silver amount: {silverAmount}");
}
return silverAmount;
}
/// <summary>
/// 执行转换操作
/// </summary>
private void PerformConversion(GlobalStorageWorldComponent globalStorage, int silverAmount, float originalValue)
{
// 1. 将白银添加到全局存储器的输入端
ThingDef silverDef = Props.outputThingDef ?? ThingDefOf.Silver;
globalStorage.AddToInputStorage(silverDef, silverAmount);
// 2. 显示转换结果消息
ShowConversionMessage(silverAmount, originalValue);
// 4. 清空容器
Transporter.innerContainer.ClearAndDestroyContents();
// 5. 如果配置为转换后销毁,则销毁建筑
if (Props.destroyAfterConversion)
{
this.parent.Destroy(DestroyMode.Vanish);
}
}
/// <summary>
/// 显示转换结果消息
/// </summary>
private void ShowConversionMessage(int silverAmount, float originalValue)
{
string message;
if (Props.conversionRate < 1.0f)
{
message = "WULA_ValueConvertedWithLoss".Translate(
originalValue.ToString("F0"),
silverAmount,
Props.conversionRate.ToStringPercent()
);
}
else if (Props.conversionRate > 1.0f)
{
message = "WULA_ValueConvertedWithBonus".Translate(
originalValue.ToString("F0"),
silverAmount,
Props.conversionRate.ToStringPercent()
);
}
else
{
message = "WULA_ValueConverted".Translate(
originalValue.ToString("F0"),
silverAmount
);
}
Messages.Message(message, this.parent, MessageTypeDefOf.PositiveEvent);
}
/// <summary>
/// 获取转换效率描述(用于界面显示)
/// </summary>
public string GetConversionEfficiencyDescription()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("WULA_ConversionEfficiency".Translate(Props.conversionRate.ToStringPercent()));
if (Props.conversionRate < 1.0f)
{
sb.AppendLine("WULA_ConversionEfficiencyLoss".Translate());
}
else if (Props.conversionRate > 1.0f)
{
sb.AppendLine("WULA_ConversionEfficiencyBonus".Translate());
}
else
{
sb.AppendLine("WULA_ConversionEfficiencyNormal".Translate());
}
return sb.ToString();
}
/// <summary>
/// 在检查器中显示转换信息
/// </summary>
public override string CompInspectStringExtra()
{
StringBuilder sb = new StringBuilder();
if (Transporter != null && Transporter.innerContainer.Any)
{
// 显示容器内物品总价值
float currentValue = CalculateTotalValue();
int potentialSilver = CalculateSilverAmount(currentValue);
sb.AppendLine("WULA_CurrentValueInContainer".Translate(currentValue.ToString("F0")));
sb.AppendLine("WULA_PotentialSilver".Translate(potentialSilver));
sb.AppendLine("WULA_ConversionRate".Translate(Props.conversionRate.ToStringPercent()));
}
return sb.ToString().TrimEndNewlines();
}
}
}

View File

@@ -171,8 +171,10 @@
<Compile Include="Flyover\WULA_SpawnFlyOver\CompAbilityEffect_SpawnFlyOver.cs" />
<Compile Include="Flyover\WULA_SpawnFlyOver\CompProperties_AbilitySpawnFlyOver.cs" />
<Compile Include="GlobalWorkTable\Building_GlobalWorkTable.cs" />
<Compile Include="GlobalWorkTable\CompProperties_GarbageShield.cs" />
<Compile Include="GlobalWorkTable\WULA_Launchable_ToGlobalStorage\CompProperties_GarbageShield.cs" />
<Compile Include="GlobalWorkTable\CompProperties_ProductionCategory.cs" />
<Compile Include="GlobalWorkTable\WULA_ValueConverter\CompProperties_ValueConverter.cs" />
<Compile Include="GlobalWorkTable\WULA_ValueConverter\CompValueConverter.cs" />
<Compile Include="GlobalWorkTable\GlobalProductionOrder.cs" />
<Compile Include="GlobalWorkTable\GlobalProductionOrderStack.cs" />
<Compile Include="GlobalWorkTable\GlobalStorageWorldComponent.cs" />
@@ -180,8 +182,8 @@
<Compile Include="GlobalWorkTable\ITab_GlobalBills.cs" />
<Compile Include="GlobalWorkTable\WorkGiver_GlobalWorkTable.cs" />
<Compile Include="GlobalWorkTable\JobDriver_GlobalWorkTable.cs" />
<Compile Include="GlobalWorkTable\CompLaunchable_ToGlobalStorage.cs" />
<Compile Include="GlobalWorkTable\CompProperties_Launchable_ToGlobalStorage.cs" />
<Compile Include="GlobalWorkTable\WULA_Launchable_ToGlobalStorage\CompLaunchable_ToGlobalStorage.cs" />
<Compile Include="GlobalWorkTable\WULA_Launchable_ToGlobalStorage\CompProperties_Launchable_ToGlobalStorage.cs" />
<Compile Include="HarmonyPatches\Faction_ShouldHaveLeader_Patch.cs" />
<Compile Include="HarmonyPatches\Hediff_Mechlink_PostAdd_Patch.cs" />
<Compile Include="HarmonyPatches\Patch_ThingDefGenerator_Techprints_ImpliedTechprintDefs.cs" />