This commit is contained in:
Tourswen
2025-11-20 01:00:41 +08:00
parent 5e550d89fc
commit 44bea4dbb8
18 changed files with 423 additions and 153 deletions

View File

@@ -238,9 +238,6 @@
</targetParams> </targetParams>
</verbProperties> </verbProperties>
<comps> <comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Light_Fighter_Drone_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike"> <li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_MotherShip_Entity</requiredAircraftType> <requiredAircraftType>WULA_MotherShip_Entity</requiredAircraftType>
<aircraftCooldownTicks>15000</aircraftCooldownTicks> <aircraftCooldownTicks>15000</aircraftCooldownTicks>

View File

@@ -35,21 +35,40 @@
<FactionDef ParentName="FactionBase"> <FactionDef ParentName="FactionBase">
<defName>Wula_PIA_Legion_Faction</defName> <defName>Wula_PIA_Legion_Faction</defName>
<label>乌拉帝国 行星封锁机关</label> <label>乌拉帝国 行星封锁机关</label>
<description>隶属于乌拉帝国开发署的暴力机关,主要职责是对那些已经有人占领但是军事实力较弱的星球进行封锁和原住民驱离。虽然她们不是真正的军队,但是所保有的舰队和武装力量足以支撑其发起一场横跨星域的战争。</description> <description>隶属于乌拉帝国开发署的暴力机关,主要职责是对那些已经有人占领但是军事实力较弱的星球进行封锁和原住民驱离。虽然她们不是真正的军队,但是所保有的舰队和武装力量足以支撑其发起一场横跨星域的战争。\n\n她们之中大部分人居住在自己的庞大舰队中地表只有零星前哨殖民地。她们也不会派出商队之类的交易者只会在自己的派系范围内活动并使用舰队支援这些地面据点的生产和战斗。你可以通过任务接洽和</description>
<basicMemberKind>Wula_PawnKind</basicMemberKind> <basicMemberKind>Wula_PawnKind</basicMemberKind>
<pawnSingular>乌拉帝国合成人</pawnSingular> <pawnSingular>乌拉帝国合成人</pawnSingular>
<pawnsPlural>乌拉帝国合成人</pawnsPlural> <pawnsPlural>乌拉帝国合成人</pawnsPlural>
<requiredCountAtGameStart>1</requiredCountAtGameStart> <requiredCountAtGameStart>1</requiredCountAtGameStart>
<factionNameMaker>NamerFaction_Wula_PIA_Legion_Faction</factionNameMaker> <factionNameMaker>NamerFaction_Wula_PIA_Legion_Faction</factionNameMaker>
<factionIconPath>Wula/World/WorldObjects/Expanding/Wula_PIA_Legion_Faction</factionIconPath> <factionIconPath>Wula/World/WorldObjects/Expanding/Wula_PIA_Legion_Faction</factionIconPath>
<!-- <settlementGenerationWeight>1</settlementGenerationWeight> --> <settlementGenerationWeight>0</settlementGenerationWeight>
<maxConfigurableAtWorldCreation>1</maxConfigurableAtWorldCreation>
<canGenerateQuestSites>false</canGenerateQuestSites>
<displayInFactionSelection>false</displayInFactionSelection>
<requiredCountAtGameStart>1</requiredCountAtGameStart> <requiredCountAtGameStart>1</requiredCountAtGameStart>
<canSiege>false</canSiege> <canSiege>false</canSiege>
<canStageAttacks>true</canStageAttacks> <canStageAttacks>true</canStageAttacks>
<canRequestTraders>false</canRequestTraders>
<canRequestMilitaryAid>false</canRequestMilitaryAid>
<canRequestOrbitalTrader>true</canRequestOrbitalTrader>
<canGenerateQuestSites>false</canGenerateQuestSites>
<hideGiftingInHostilityText>true</hideGiftingInHostilityText>
<caravanTraderKinds />
<visitorTraderKinds />
<orbitalTraderKinds>
<li>Orbital_BulkGoods</li>
<li>Orbital_CombatSupplier</li>
<li>Orbital_Exotic</li>
<li>Orbital_PirateMerchant</li>
</orbitalTraderKinds>
<arrivalLayerWhitelist> <arrivalLayerWhitelist>
<li>Surface</li> <li>Surface</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li> <li MayRequire="Ludeon.RimWorld.Odyssey">Orbit</li>
</arrivalLayerWhitelist> </arrivalLayerWhitelist>
<layerWhitelist>
<li>Orbit</li>
</layerWhitelist>
<colorSpectrum> <colorSpectrum>
<li>(1, 1, 1)</li> <li>(1, 1, 1)</li>
</colorSpectrum> </colorSpectrum>
@@ -73,7 +92,7 @@
</points> </points>
</raidLootValueFromPointsCurve> </raidLootValueFromPointsCurve>
<humanlikeFaction>true</humanlikeFaction> <humanlikeFaction>true</humanlikeFaction>
<hidden>true</hidden> <hidden>false</hidden>
<autoFlee>false</autoFlee> <autoFlee>false</autoFlee>
<canUseAvoidGrid>false</canUseAvoidGrid> <canUseAvoidGrid>false</canUseAvoidGrid>
<techLevel>Ultra</techLevel> <techLevel>Ultra</techLevel>

View File

@@ -51,10 +51,6 @@
<li Class="QuestNode_GetMap" /> <li Class="QuestNode_GetMap" />
<!-- 获取边缘进入点 --> <!-- 获取边缘进入点 -->
<li Class="QuestNode_GetWalkInSpot" /> <li Class="QuestNode_GetWalkInSpot" />
<!-- 产生超链接 -->
<li Class="QuestNode_RoyalTitleHyperlink">
<faction>Wula_PIA_Legion_Faction</faction>
</li>
<!-- 选取敌对派系 --> <!-- 选取敌对派系 -->
<li Class="QuestNode_GetFaction"> <li Class="QuestNode_GetFaction">
<allowEnemy>true</allowEnemy> <allowEnemy>true</allowEnemy>
@@ -62,6 +58,13 @@
<storeAs>enemyFaction</storeAs> <storeAs>enemyFaction</storeAs>
</li> </li>
<!-- 产生超链接 -->
<li Class="WulaFallenEmpire.QuestNode_Hyperlinks">
<factionDefs>
<li>Wula_PIA_Legion_Faction</li>
</factionDefs>
</li>
<!-- 生成物品奖励 --> <!-- 生成物品奖励 -->
<!-- <li Class="QuestNode_GenerateThingSet"> <!-- <li Class="QuestNode_GenerateThingSet">
<thingSetMaker>Reward_GravshipUpgrade</thingSetMaker> <thingSetMaker>Reward_GravshipUpgrade</thingSetMaker>
@@ -647,18 +650,39 @@
<!-- 运行规则 --> <!-- 运行规则 -->
<root Class="QuestNode_Sequence"> <root Class="QuestNode_Sequence">
<nodes> <nodes>
<!-- 设置钢铁需求 --> <!-- 获取地图 -->
<li Class="QuestNode_GetMap" />
<!-- 生成物品奖励 -->
<li Class="QuestNode_GenerateThingSet">
<thingSetMaker>WULA_Base_Tex_Reward</thingSetMaker>
<storeAs>permissionReward</storeAs>
</li>
<!-- 产生超链接 -->
<li Class="WulaFallenEmpire.QuestNode_Hyperlinks">
<thingDefs>
<li>WULA_GlobalStorageSenderPod</li>
</thingDefs>
<factionDefs>
<li>Wula_PIA_Legion_Faction</li>
</factionDefs>
</li>
<li Class="QuestNode_Set"> <li Class="QuestNode_Set">
<name>taxAmount</name> <name>taxAmount</name>
<value>100</value> <value>1</value>
</li> </li>
<li Class="QuestNode_Set"> <li Class="QuestNode_Set">
<name>taxInterval</name> <name>taxInterval</name>
<value>250</value> <!-- 较短的测试间隔 --> <value>250</value> <!-- 较短的测试间隔 -->
</li> </li>
<!-- 检查全局资源 -->
<li Class="QuestNode_Multiply">
<value1>$points</value1>
<value2>1</value2>
<storeAs>taxAmount</storeAs>
</li>
<li Class="WulaFallenEmpire.QuestNode_CheckGlobalResource"> <li Class="WulaFallenEmpire.QuestNode_CheckGlobalResource">
<resourceDef>Steel</resourceDef> <resourceDef>Silver</resourceDef>
<requiredCount>$taxAmount</requiredCount> <requiredCount>$taxAmount</requiredCount>
<retryDelayTicks>$taxInterval</retryDelayTicks> <retryDelayTicks>$taxInterval</retryDelayTicks>
<successSignal>TaxPaymentSuccess</successSignal> <successSignal>TaxPaymentSuccess</successSignal>
@@ -666,6 +690,14 @@
<deductOnSuccess>true</deductOnSuccess> <deductOnSuccess>true</deductOnSuccess>
<useInputStorage>true</useInputStorage> <useInputStorage>true</useInputStorage>
</li> </li>
<!-- 通知 -->
<li Class="QuestNode_Letter">
<label>什一税</label>
<text>唯死亡和税收不可避免——按时上交什一税是乌拉帝国殖民地的光荣义务。\n\n查看任务列表以了解更多。</text>
<letterDef>NegativeEvent</letterDef>
</li>
<!-- 支付成功处理 --> <!-- 支付成功处理 -->
<li Class="QuestNode_Signal"> <li Class="QuestNode_Signal">
<inSignal>TaxPaymentSuccess</inSignal> <inSignal>TaxPaymentSuccess</inSignal>
@@ -673,9 +705,17 @@
<nodes> <nodes>
<li Class="QuestNode_Letter"> <li Class="QuestNode_Letter">
<label>纳税完成</label> <label>纳税完成</label>
<text>已成功从全局储存中扣除100钢铁作为税款。</text> <text>帝国已经接收了税款,为了表彰你在纳税上的良好表现,一封税金缴纳凭证已经送到你的殖民地中!</text>
<letterDef>PositiveEvent</letterDef> <letterDef>PositiveEvent</letterDef>
</li> </li>
<li Class="QuestNode_AddItemsReward">
<items>$permissionReward</items>
</li>
<li Class="QuestNode_ChangeFactionGoodwill">
<faction>Wula_PIA_Legion_Faction</faction>
<change>10</change>
<reason>WULA_Base_Tex_Quest_Handle_Intime</reason>
</li>
<li Class="QuestNode_End"> <li Class="QuestNode_End">
<outcome>Success</outcome> <outcome>Success</outcome>
<sendStandardLetter>false</sendStandardLetter> <sendStandardLetter>false</sendStandardLetter>
@@ -683,7 +723,116 @@
</nodes> </nodes>
</node> </node>
</li> </li>
<!-- 倒计时 -->
<li Class="QuestNode_LoopCount">
<loopCount>2</loopCount>
<storeLoopCounterAs>Handle_Outtime_Counter</storeLoopCounterAs>
<node Class="QuestNode_Sequence">
<nodes>
<li Class="QuestNode_Delay">
<delayTicks>60000</delayTicks>
<!-- <delayTicks>360</delayTicks> -->
<node Class="QuestNode_ChangeFactionGoodwill">
<faction>Wula_PIA_Legion_Faction</faction>
<change>-5</change>
<reason>WULA_Base_Tex_Quest_Handle_Outtime</reason>
</node>
</li>
</nodes>
</node>
</li>
<li Class="QuestNode_Delay">
<delayTicks>180000</delayTicks>
<!-- <delayTicks>360</delayTicks> -->
<node Class="QuestNode_Sequence">
<nodes>
<li Class="QuestNode_SendSignals">
<outSignals>Handle_Outtime</outSignals>
</li>
</nodes>
</node>
</li>
<!-- 超时结束 -->
<li Class="QuestNode_Signal">
<inSignal>Handle_Outtime</inSignal>
<node Class="QuestNode_Sequence">
<nodes>
<li Class="WulaFallenEmpire.QuestNode_EventLetter">
<inSignal>Handle_Outtime</inSignal>
<eventDefName>WULA_Base_Tex_Quest_UI_1</eventDefName>
</li>
<li Class="QuestNode_Letter">
<label>未按时纳税</label>
<text>作为乌拉帝国的殖民地,你被发现未按时纳税——或许一次两次她们可以原谅你,但是一直拖欠必然会激怒她们!</text>
<letterDef>NegativeEvent</letterDef>
</li>
<li Class="QuestNode_ChangeFactionGoodwill">
<faction>Wula_PIA_Legion_Faction</faction>
<change>-10</change>
<reason>WULA_Base_Tex_Quest_Handle_Outtime</reason>
</li>
<li Class="QuestNode_End">
<outcome>Fail</outcome>
</li>
</nodes>
</node>
</li>
</nodes> </nodes>
</root> </root>
</QuestScriptDef> </QuestScriptDef>
<HistoryEventDef>
<defName>WULA_Base_Tex_Quest_Handle_Intime</defName>
<label>按时上交帝国什一税</label>
</HistoryEventDef>
<HistoryEventDef>
<defName>WULA_Base_Tex_Quest_Handle_Outtime</defName>
<label>拖欠帝国什一税</label>
</HistoryEventDef>
<ThingSetMakerDef>
<defName>WULA_Base_Tex_Reward</defName>
<root Class="ThingSetMaker_RandomOption">
<options>
<li>
<weight>1</weight>
<thingSetMaker Class="ThingSetMaker_StackCount">
<fixedParams>
<filter>
<thingDefs>
<li>WULA_Tex_Voucher</li>
</thingDefs>
</filter>
<countRange>1</countRange>
</fixedParams>
</thingSetMaker>
</li>
</options>
</root>
</ThingSetMakerDef>
<WulaFallenEmpire.EventDef>
<defName>WULA_Base_Tex_Quest_UI_1</defName>
<label>和P.I.A的通讯</label>
<portraitPath>Wula/Events/Portraits/WULA_Legion_6</portraitPath>
<characterName>「军团」,P.I.A</characterName>
<descriptions>
<li>你们没有按时交税——你们应该知道吧?\n\n&lt;color=#820D13>&lt;i>我们都希望局势不会进一步恶化。&lt;/i>&lt;/color></li>
</descriptions>
<options>
<li>
<label>下次一定</label>
<useCustomColors>true</useCustomColors>
<normalColor>(255,255,255,255)</normalColor>
<hoverColor>(157,201,185,195)</hoverColor>
<textColor>(255,255,255,255)</textColor>
<textHoverColor>(255,255,255,255)</textHoverColor>
<optionEffects>
<li>
<effects>
<li Class="WulaFallenEmpire.Effect_CloseDialog" />
</effects>
</li>
</optionEffects>
</li>
</options>
</WulaFallenEmpire.EventDef>
</Defs> </Defs>

View File

@@ -270,4 +270,31 @@
</li> </li>
</modExtensions> --> </modExtensions> -->
</ThingDef> </ThingDef>
<ThingDef ParentName="ResourceBase">
<defName>WULA_Tex_Voucher</defName>
<label>税金缴纳凭证</label>
<description>这是乌拉帝国颁发的凭证,包含了一系列秘钥和电子身份信息,证明这个殖民地的公民是按时交税的模范公民。\n\n呃她们该不会是在电子储存器上盖了个红印章吧</description>
<graphicData>
<texPath>Wula/Item/WULA_Tex_Voucher</texPath>
<graphicClass>Graphic_Single</graphicClass>
</graphicData>
<tradeability>None</tradeability>
<genericMarketSellable>false</genericMarketSellable>
<soundInteract>Metal_Drop</soundInteract>
<soundDrop>Metal_Drop</soundDrop>
<useHitPoints>true</useHitPoints>
<healthAffectsPrice>false</healthAffectsPrice>
<statBases>
<MarketValue>1</MarketValue>
<Mass>0.01</Mass>
<MaxHitPoints>50</MaxHitPoints>
</statBases>
<thingCategories>
<li>ResourcesRaw</li>
</thingCategories>
<burnableByRecipe>false</burnableByRecipe>
<smeltable>false</smeltable>
</ThingDef>
</Defs> </Defs>

View File

@@ -790,7 +790,7 @@
<minSafeDistanceFromMain>60</minSafeDistanceFromMain> <!-- 与主飞行物的距离检查 --> <minSafeDistanceFromMain>60</minSafeDistanceFromMain> <!-- 与主飞行物的距离检查 -->
<!-- 飞行配置 --> <!-- 飞行配置 -->
<escortSpeedMultiplier>30</escortSpeedMultiplier> <!-- 比主舰稍快 --> <escortSpeedMultiplier>10</escortSpeedMultiplier> <!-- 比主舰稍快 -->
<escortAltitudeOffset>10</escortAltitudeOffset> <!-- 比主舰稍高 --> <escortAltitudeOffset>10</escortAltitudeOffset> <!-- 比主舰稍高 -->
<mirrorMovement>false</mirrorMovement> <mirrorMovement>false</mirrorMovement>

View File

@@ -55,4 +55,11 @@
<WULA_Intro_Spy.LetterLabelQuestFailed.slateRef>任务失败:[resolvedQuestName]</WULA_Intro_Spy.LetterLabelQuestFailed.slateRef> <WULA_Intro_Spy.LetterLabelQuestFailed.slateRef>任务失败:[resolvedQuestName]</WULA_Intro_Spy.LetterLabelQuestFailed.slateRef>
<!-- EN: The shuttle sent to collect [asker_nameDef] has departed without [asker_objective]. [asker_pronoun] will now leave on foot. [failLetterEndingCommon] --> <!-- EN: The shuttle sent to collect [asker_nameDef] has departed without [asker_objective]. [asker_pronoun] will now leave on foot. [failLetterEndingCommon] -->
<WULA_Intro_Spy.LetterTextQuestFailed.slateRef>前来迎接[asker_nameDef]的穿梭机在离开时因为一些原因落下了[asker_objective]。[asker_pronoun]现在只能走回去了。[failLetterEndingCommon]</WULA_Intro_Spy.LetterTextQuestFailed.slateRef> <WULA_Intro_Spy.LetterTextQuestFailed.slateRef>前来迎接[asker_nameDef]的穿梭机在离开时因为一些原因落下了[asker_objective]。[asker_pronoun]现在只能走回去了。[failLetterEndingCommon]</WULA_Intro_Spy.LetterTextQuestFailed.slateRef>
<WULA_Base_Tex_Quest.questNameRules.rulesStrings>
<li>questName->什一税税收</li>
</WULA_Base_Tex_Quest.questNameRules.rulesStrings>
<WULA_Base_Tex_Quest.questDescriptionRules.rulesStrings>
<li>questDescription->唯死亡和税收不可避免——按时上交什一税是乌拉帝国殖民地的光荣义务。\n\n乌拉帝国的什一税会从殖民地储存在舰队中的资产里面扣除你可以建造&lt;color=#6BB7B7>&lt;i>乌拉帝国物资输送舱&lt;/i>&lt;/color>来将物资输送到位于轨道上的舰队。\n\n你可以快速地准备好税金乌拉帝国对积极纳税的殖民地会给予更多关照——但是如果一直拖延则会惹其不快甚至有可能被定性为叛国</li>
</WULA_Base_Tex_Quest.questDescriptionRules.rulesStrings>
</LanguageData> </LanguageData>

View File

@@ -339,4 +339,9 @@
<SkyfallerPawnLanded>战争机械已部署</SkyfallerPawnLanded> <SkyfallerPawnLanded>战争机械已部署</SkyfallerPawnLanded>
<DisappearWithEffect_TimeRemaining>剩余时间: {0}</DisappearWithEffect_TimeRemaining> <DisappearWithEffect_TimeRemaining>剩余时间: {0}</DisappearWithEffect_TimeRemaining>
<WULA_TaxCollection.Waiting>什一税征收:等待激活...</WULA_TaxCollection.Waiting>
<WULA_TaxCollection.Status>什一税征收:{0} {1} {2}</WULA_TaxCollection.Status>
<WULA_TaxCollection.Status.Succeeded>- 征收已完成</WULA_TaxCollection.Status.Succeeded>
<WULA_TaxCollection.Status.Failed>- 逾期</WULA_TaxCollection.Status.Failed>
</LanguageData> </LanguageData>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<WULA_GlobalStorageSenderPod.label>全局存储输送舱</WULA_GlobalStorageSenderPod.label>
<WULA_GlobalStorageSenderPod.description>一个一次性的物资输送装置,可以将装载的货物直接发射到全局存储网络中,而无需选择目标地点。发射后即告销毁。</WULA_GlobalStorageSenderPod.description>
</LanguageData>

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<WULA_LaunchToGlobalStorage>发射到全局存储</WULA_LaunchToGlobalStorage>
<WULA_LaunchToGlobalStorageDesc>将此输送舱中的所有物品直接发送到全局存储网络中。此操作将消耗燃料并销毁输送舱。</WULA_LaunchToGlobalStorageDesc>
<WULA_ItemsSentToGlobalStorage>已将 {0} 发送到全局存储。</WULA_ItemsSentToGlobalStorage>
<WULA_NoItemsToSendToGlobalStorage>输送舱是空的,没有什么可以发送的。</WULA_NoItemsToSendToGlobalStorage>
</LanguageData>

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -127,8 +127,6 @@ namespace WulaFallenEmpire
} }
} }
Log.Message($"[FactoryFacility Check] Found {allFlyOvers.Count} FlyOvers on map");
foreach (var thing in allFlyOvers) foreach (var thing in allFlyOvers)
{ {
if (thing is FlyOver flyOver && !flyOver.Destroyed) if (thing is FlyOver flyOver && !flyOver.Destroyed)
@@ -137,23 +135,16 @@ namespace WulaFallenEmpire
var facilitiesComp = flyOver.GetComp<CompFlyOverFacilities>(); var facilitiesComp = flyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp == null) if (facilitiesComp == null)
{ {
Log.Warning($"[FactoryFacility Check] FlyOver at {flyOver.Position} has no CompFlyOverFacilities");
continue; continue;
} }
if (facilitiesComp.HasFacility("FactoryFacility")) if (facilitiesComp.HasFacility("FactoryFacility"))
{ {
Log.Message($"[FactoryFacility Check] Found valid FlyOver at {flyOver.Position} with FactoryFacility");
return true; return true;
} }
else
{
Log.Message($"[FactoryFacility Check] FlyOver at {flyOver.Position} missing FactoryFacility. Has: {string.Join(", ", facilitiesComp.GetActiveFacilities())}");
}
} }
} }
Log.Message("[FactoryFacility Check] No FlyOver with FactoryFacility found");
return false; return false;
} }
catch (System.Exception ex) catch (System.Exception ex)
@@ -333,8 +324,6 @@ namespace WulaFallenEmpire
// 如果是Pawn需要特殊处理 // 如果是Pawn需要特殊处理
if (thingDef.race != null) if (thingDef.race != null)
{ {
Log.Message($"[Airdrop] Processing {remainingCount} pawns of type {thingDef.defName}");
// 对于Pawn每个单独生成 // 对于Pawn每个单独生成
for (int i = 0; i < remainingCount; i++) for (int i = 0; i < remainingCount; i++)
{ {
@@ -352,7 +341,6 @@ namespace WulaFallenEmpire
pawn.drafter = new Pawn_DraftController(pawn); pawn.drafter = new Pawn_DraftController(pawn);
allItems.Add(pawn); allItems.Add(pawn);
Log.Message($"[Airdrop] Successfully generated pawn: {pawn.Label}");
} }
else else
{ {
@@ -405,10 +393,8 @@ namespace WulaFallenEmpire
} }
if (allItems.Count == 0) if (allItems.Count == 0)
{ {
Log.Message("[Airdrop] No items to distribute");
return podContents; return podContents;
} }
Log.Message($"[Airdrop] Total items to distribute: {allItems.Count}");
// 平均分配物品到空投舱 // 平均分配物品到空投舱
int currentPod = 0; int currentPod = 0;
foreach (Thing item in allItems) foreach (Thing item in allItems)
@@ -453,13 +439,11 @@ namespace WulaFallenEmpire
{ {
// 金属类 -> 玻璃钢 // 金属类 -> 玻璃钢
selectedStuff = ThingDefOf.Plasteel; selectedStuff = ThingDefOf.Plasteel;
Log.Message($"[Material Rule] {thingDef.defName} requires metallic, using Plasteel");
} }
else if (fabricCategory != null) else if (fabricCategory != null)
{ {
// 布革类 -> 超织物 // 布革类 -> 超织物
selectedStuff = ThingDefOf_WULA.Hyperweave; selectedStuff = ThingDefOf_WULA.Hyperweave;
Log.Message($"[Material Rule] {thingDef.defName} requires fabric/leather, using Hyperweave");
} }
// 创建带有指定材质的物品 // 创建带有指定材质的物品
@@ -493,7 +477,6 @@ namespace WulaFallenEmpire
Log.Error($"[Airdrop] Work table has no faction"); Log.Error($"[Airdrop] Work table has no faction");
return null; return null;
} }
Log.Message($"[Airdrop] Work table faction: {workTableFaction.def.defName}");
// 获取该种族的所有PawnKindDef // 获取该种族的所有PawnKindDef
var availableKinds = DefDatabase<PawnKindDef>.AllDefs var availableKinds = DefDatabase<PawnKindDef>.AllDefs
.Where(kind => kind.race == pawnType) .Where(kind => kind.race == pawnType)
@@ -503,7 +486,6 @@ namespace WulaFallenEmpire
Log.Error($"[Airdrop] No PawnKindDef found for race: {pawnType.defName}"); Log.Error($"[Airdrop] No PawnKindDef found for race: {pawnType.defName}");
return null; return null;
} }
Log.Message($"[Airdrop] Found {availableKinds.Count} PawnKindDefs for {pawnType.defName}");
// 最高优先级与工作台派系完全相同的PawnKind // 最高优先级与工作台派系完全相同的PawnKind
var matchingFactionKinds = availableKinds var matchingFactionKinds = availableKinds
.Where(kind => kind.defaultFactionDef != null && .Where(kind => kind.defaultFactionDef != null &&
@@ -512,7 +494,6 @@ namespace WulaFallenEmpire
if (matchingFactionKinds.Count > 0) if (matchingFactionKinds.Count > 0)
{ {
var selected = matchingFactionKinds.RandomElement(); var selected = matchingFactionKinds.RandomElement();
Log.Message($"[Airdrop] Selected matching faction PawnKind: {selected.defName} (faction: {workTableFaction.def.defName})");
return selected; return selected;
} }
// 次高优先级玩家派系的PawnKind如果工作台是玩家派系 // 次高优先级玩家派系的PawnKind如果工作台是玩家派系
@@ -526,7 +507,6 @@ namespace WulaFallenEmpire
if (playerFactionKinds.Count > 0) if (playerFactionKinds.Count > 0)
{ {
var selected = playerFactionKinds.RandomElement(); var selected = playerFactionKinds.RandomElement();
Log.Message($"[Airdrop] Selected player faction PawnKind: {selected.defName}");
return selected; return selected;
} }
} }

View File

@@ -11,19 +11,19 @@ namespace WulaFallenEmpire
// 输入参数 // 输入参数
public SlateRef<ThingDef> resourceDef; public SlateRef<ThingDef> resourceDef;
public SlateRef<int> requiredCount; public SlateRef<int> requiredCount;
public SlateRef<int> retryDelayTicks = 60; // 默认60 ticks (1秒) public SlateRef<int> retryDelayTicks = 60;
public SlateRef<string> successSignal;
public SlateRef<string> failSignal;
public SlateRef<bool> deductOnSuccess = true;
public SlateRef<bool> useInputStorage = true; // true=输入存储, false=输出存储
// 保护参数不被序列化
[NoTranslate] [NoTranslate]
private string debugInfo; public SlateRef<string> successSignal;
[NoTranslate]
public SlateRef<string> failSignal;
public SlateRef<bool> deductOnSuccess = true;
public SlateRef<bool> useInputStorage = true;
protected override bool TestRunInt(Slate slate) protected override bool TestRunInt(Slate slate)
{ {
// 测试模式下只检查参数是否有效
if (resourceDef == null || resourceDef.GetValue(slate) == null) if (resourceDef == null || resourceDef.GetValue(slate) == null)
{ {
Log.Error("QuestNode_CheckGlobalResource: resourceDef is null"); Log.Error("QuestNode_CheckGlobalResource: resourceDef is null");
@@ -36,7 +36,6 @@ namespace WulaFallenEmpire
return false; return false;
} }
// 测试全局存储组件是否存在
var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>(); var globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null) if (globalStorage == null)
{ {
@@ -55,13 +54,13 @@ namespace WulaFallenEmpire
ThingDef actualResourceDef = resourceDef.GetValue(slate); ThingDef actualResourceDef = resourceDef.GetValue(slate);
int actualRequiredCount = requiredCount.GetValue(slate); int actualRequiredCount = requiredCount.GetValue(slate);
int actualRetryDelay = retryDelayTicks.GetValue(slate); int actualRetryDelay = retryDelayTicks.GetValue(slate);
string actualSuccessSignal = successSignal.GetValue(slate); string actualSuccessSignal = QuestGenUtility.HardcodedSignalWithQuestID(successSignal.GetValue(slate));
string actualFailSignal = failSignal.GetValue(slate); string actualFailSignal = QuestGenUtility.HardcodedSignalWithQuestID(failSignal.GetValue(slate));
bool actualDeductOnSuccess = deductOnSuccess.GetValue(slate); bool actualDeductOnSuccess = deductOnSuccess.GetValue(slate);
bool actualUseInputStorage = useInputStorage.GetValue(slate); bool actualUseInputStorage = useInputStorage.GetValue(slate);
// 创建调试信息 // 创建调试信息
debugInfo = $"Checking {actualRequiredCount} {actualResourceDef?.defName ?? "NULL"} in {(actualUseInputStorage ? "Input" : "Output")} Storage with retry delay {actualRetryDelay}"; string debugInfo = $"Checking {actualRequiredCount} {actualResourceDef?.defName ?? "NULL"} in {(actualUseInputStorage ? "Input" : "Output")} Storage with retry delay {actualRetryDelay}";
// 添加任务部分 // 添加任务部分
QuestPart_GlobalResourceCheck part = new QuestPart_GlobalResourceCheck QuestPart_GlobalResourceCheck part = new QuestPart_GlobalResourceCheck
@@ -73,7 +72,9 @@ namespace WulaFallenEmpire
failSignal = actualFailSignal, failSignal = actualFailSignal,
deductOnSuccess = actualDeductOnSuccess, deductOnSuccess = actualDeductOnSuccess,
useInputStorage = actualUseInputStorage, useInputStorage = actualUseInputStorage,
debugInfo = debugInfo debugInfo = debugInfo,
// 关键:设置激活信号为任务接受信号
inSignalEnable = QuestGenUtility.HardcodedSignalWithQuestID(quest.InitiateSignal)
}; };
quest.AddPart(part); quest.AddPart(part);

View File

@@ -0,0 +1,75 @@
using RimWorld;
using RimWorld.QuestGen;
using System.Collections.Generic;
using Verse;
namespace WulaFallenEmpire
{
public class QuestNode_Hyperlinks : QuestNode
{
// 输入参数 - 使用 SlateRef 来支持从任务slate中获取值
public SlateRef<List<ThingDef>> thingDefs;
public SlateRef<List<Pawn>> pawns;
public SlateRef<List<FactionDef>> factionDefs; // 改为 FactionDef 而不是 Faction
public SlateRef<List<ResearchProjectDef>> researchProjects;
protected override bool TestRunInt(Slate slate)
{
// 测试模式下只要参数有效就返回true
return true;
}
protected override void RunInt()
{
Slate slate = QuestGen.slate;
Quest quest = QuestGen.quest;
// 获取实际的值
List<ThingDef> actualThingDefs = thingDefs.GetValue(slate);
List<Pawn> actualPawns = pawns.GetValue(slate);
List<FactionDef> actualFactionDefs = factionDefs.GetValue(slate);
List<ResearchProjectDef> actualResearchProjects = researchProjects.GetValue(slate);
// 创建任务部分
QuestPart_Hyperlinks hyperlinksPart = new QuestPart_Hyperlinks();
// 设置超链接数据
if (actualThingDefs != null)
{
hyperlinksPart.thingDefs.AddRange(actualThingDefs);
}
if (actualPawns != null)
{
hyperlinksPart.pawns.AddRange(actualPawns);
}
if (actualFactionDefs != null)
{
// 将 FactionDef 转换为 Faction
foreach (FactionDef factionDef in actualFactionDefs)
{
Faction faction = Find.FactionManager.FirstFactionOfDef(factionDef);
if (faction != null)
{
hyperlinksPart.factions.Add(faction);
}
else
{
Log.Warning($"QuestNode_Hyperlinks: Could not find faction for def {factionDef.defName}");
}
}
}
if (actualResearchProjects != null)
{
hyperlinksPart.researchProjects.AddRange(actualResearchProjects);
}
// 添加到任务
quest.AddPart(hyperlinksPart);
Log.Message($"QuestNode_Hyperlinks: Added hyperlinks - Things: {actualThingDefs?.Count ?? 0}, Pawns: {actualPawns?.Count ?? 0}, Factions: {actualFactionDefs?.Count ?? 0}, Research: {actualResearchProjects?.Count ?? 0}");
}
}
}

View File

@@ -1,5 +1,6 @@
using RimWorld; using RimWorld;
using RimWorld.Planet; using RimWorld.Planet;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Verse; using Verse;
using RimWorld.QuestGen; using RimWorld.QuestGen;
@@ -12,19 +13,38 @@ namespace WulaFallenEmpire
public ThingDef resourceDef; public ThingDef resourceDef;
public int requiredCount; public int requiredCount;
public int retryDelayTicks = 60; public int retryDelayTicks = 60;
[NoTranslate]
public string successSignal; public string successSignal;
[NoTranslate]
public string failSignal; public string failSignal;
public bool deductOnSuccess = true; public bool deductOnSuccess = true;
public bool useInputStorage = true; public bool useInputStorage = true;
public string debugInfo; public string debugInfo;
// 状态变量 // 状态变量
private int nextRetryTick = -1; public int nextRetryTick = -1;
private bool hasSucceeded = false; private bool hasSucceeded = false;
private bool hasFailed = false; private bool hasFailed = false;
private int retryCount = 0; private int retryCount = 0;
private const int MAX_RETRY_COUNT = 1000; private const int MAX_RETRY_COUNT = 1000;
public override void AssignDebugData()
{
base.AssignDebugData();
resourceDef = ThingDefOf.Steel;
requiredCount = 100;
retryDelayTicks = 60;
successSignal = "TaxPaymentSuccess";
failSignal = "TaxPaymentFailed";
deductOnSuccess = true;
useInputStorage = true;
debugInfo = "Debug: Tax Collection Check";
}
protected override void Enable(SignalArgs receivedArgs) protected override void Enable(SignalArgs receivedArgs)
{ {
base.Enable(receivedArgs); base.Enable(receivedArgs);
@@ -34,32 +54,28 @@ namespace WulaFallenEmpire
Log.Message($"QuestPart_GlobalResourceCheck Enabled: Will check for {requiredCount} {resourceDef?.defName} in {(useInputStorage ? "Input" : "Output")} Storage"); Log.Message($"QuestPart_GlobalResourceCheck Enabled: Will check for {requiredCount} {resourceDef?.defName} in {(useInputStorage ? "Input" : "Output")} Storage");
} }
public override void Notify_QuestSignalReceived(Signal signal)
{
base.Notify_QuestSignalReceived(signal);
// 如果任务已经结束,停止所有操作
if (quest.State != QuestState.Ongoing && quest.State != QuestState.NotYetAccepted)
{
DoCleanup();
return;
}
}
public override void QuestPartTick() public override void QuestPartTick()
{ {
base.QuestPartTick(); base.QuestPartTick();
// 如果已经成功或失败,或者任务已结束,不再处理 // 如果任务已结束,停止处理
if (hasSucceeded || hasFailed || (quest.State != QuestState.Ongoing && quest.State != QuestState.NotYetAccepted)) if (quest.State != QuestState.Ongoing)
{
return;
}
// 如果已经成功或失败,不再处理
if (hasSucceeded || hasFailed)
{ {
DoCleanup();
return; return;
} }
// 检查是否到了重试时间 // 检查是否到了重试时间
if (Find.TickManager.TicksGame < nextRetryTick && nextRetryTick != -1) int currentTick = Find.TickManager.TicksGame;
if (nextRetryTick == -1 || currentTick < nextRetryTick)
{
return; return;
}
// 执行资源检查 // 执行资源检查
CheckGlobalResource(); CheckGlobalResource();
@@ -67,44 +83,52 @@ namespace WulaFallenEmpire
private void CheckGlobalResource() private void CheckGlobalResource()
{ {
// 更新下次重试时间 try
nextRetryTick = Find.TickManager.TicksGame + retryDelayTicks;
retryCount++;
// 获取全局资源储存器
GlobalStorageWorldComponent globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null)
{ {
Log.Error("QuestPart_GlobalResourceCheck: GlobalStorageWorldComponent not found"); // 更新下次重试时间
HandleFailure("Global storage component missing"); nextRetryTick = Find.TickManager.TicksGame + retryDelayTicks;
return; retryCount++;
// 获取全局资源储存器
GlobalStorageWorldComponent globalStorage = Find.World.GetComponent<GlobalStorageWorldComponent>();
if (globalStorage == null)
{
Log.Error("QuestPart_GlobalResourceCheck: GlobalStorageWorldComponent not found");
HandleFailure("Global storage component missing");
return;
}
if (resourceDef == null)
{
Log.Error("QuestPart_GlobalResourceCheck: resourceDef is null");
HandleFailure("Resource definition is null");
return;
}
// 检查资源是否足够
int currentAmount = useInputStorage ?
globalStorage.GetInputStorageCount(resourceDef) :
globalStorage.GetOutputStorageCount(resourceDef);
bool hasEnough = currentAmount >= requiredCount;
Log.Message($"GlobalResourceCheck [{retryCount}]: {currentAmount}/{requiredCount} {resourceDef.defName} in {(useInputStorage ? "Input" : "Output")} Storage - Enough: {hasEnough}");
if (hasEnough)
{
// 资源足够,处理成功
HandleSuccess(globalStorage);
}
else
{
// 资源不足,安排重试
HandleFailure($"Insufficient resources: {currentAmount}/{requiredCount}");
}
} }
catch (Exception ex)
if (resourceDef == null)
{ {
Log.Error("QuestPart_GlobalResourceCheck: resourceDef is null"); Log.Error($"GlobalResourceCheck: Exception during check - {ex}");
HandleFailure("Resource definition is null"); HandleFailure($"Exception: {ex.Message}");
return;
}
// 检查资源是否足够
int currentAmount = useInputStorage ?
globalStorage.GetInputStorageCount(resourceDef) :
globalStorage.GetOutputStorageCount(resourceDef);
bool hasEnough = currentAmount >= requiredCount;
Log.Message($"GlobalResourceCheck [{retryCount}]: {currentAmount}/{requiredCount} {resourceDef.defName} in {(useInputStorage ? "Input" : "Output")} Storage - Enough: {hasEnough}");
if (hasEnough)
{
// 资源足够,处理成功
HandleSuccess(globalStorage);
}
else
{
// 资源不足,安排重试
HandleFailure($"Insufficient resources: {currentAmount}/{requiredCount}");
} }
} }
@@ -127,16 +151,15 @@ namespace WulaFallenEmpire
Log.Message($"GlobalResourceCheck: SUCCESS - {(deductOnSuccess ? "Deducted" : "Found")} {requiredCount} {resourceDef.defName} from {(useInputStorage ? "Input" : "Output")} Storage"); Log.Message($"GlobalResourceCheck: SUCCESS - {(deductOnSuccess ? "Deducted" : "Found")} {requiredCount} {resourceDef.defName} from {(useInputStorage ? "Input" : "Output")} Storage");
// 发送成功信号 - 使用 QuestGenUtility 来生成带任务前缀的信号 // 发送成功信号
if (!successSignal.NullOrEmpty()) if (!successSignal.NullOrEmpty())
{ {
string fullSignal = QuestGenUtility.HardcodedSignalWithQuestID(successSignal); Find.SignalManager.SendSignal(new Signal(successSignal));
Find.SignalManager.SendSignal(new Signal(fullSignal)); Log.Message($"GlobalResourceCheck: Sent success signal '{successSignal}'");
Log.Message($"GlobalResourceCheck: Sent success signal '{fullSignal}'");
} }
// 清理这个任务部分 // 完成这个任务部分
DoCleanup(); Complete();
} }
private void HandleFailure(string reason = "") private void HandleFailure(string reason = "")
@@ -150,12 +173,11 @@ namespace WulaFallenEmpire
// 发送失败信号 // 发送失败信号
if (!failSignal.NullOrEmpty()) if (!failSignal.NullOrEmpty())
{ {
string fullSignal = QuestGenUtility.HardcodedSignalWithQuestID(failSignal); Find.SignalManager.SendSignal(new Signal(failSignal));
Find.SignalManager.SendSignal(new Signal(fullSignal)); Log.Message($"GlobalResourceCheck: Sent fail signal '{failSignal}' after max retries");
Log.Message($"GlobalResourceCheck: Sent fail signal '{fullSignal}' after max retries");
} }
DoCleanup(); Complete();
return; return;
} }
@@ -171,13 +193,6 @@ namespace WulaFallenEmpire
Log.Message($"GlobalResourceCheck: Scheduled retry #{retryCount + 1} in {retryDelayTicks} ticks for {requiredCount} {resourceDef.defName}. Reason: {reason}"); Log.Message($"GlobalResourceCheck: Scheduled retry #{retryCount + 1} in {retryDelayTicks} ticks for {requiredCount} {resourceDef.defName}. Reason: {reason}");
} }
// 使用新名称避免与基类冲突
private void DoCleanup()
{
// 标记为已完成停止tick更新
nextRetryTick = -1;
}
public override void ExposeData() public override void ExposeData()
{ {
base.ExposeData(); base.ExposeData();
@@ -197,29 +212,39 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref retryCount, "retryCount"); Scribe_Values.Look(ref retryCount, "retryCount");
} }
public override void AssignDebugData()
{
base.AssignDebugData();
resourceDef = ThingDefOf.Steel;
requiredCount = 100;
retryDelayTicks = 60;
successSignal = "TaxPaymentSuccess";
failSignal = "TaxPaymentFailed";
deductOnSuccess = true;
useInputStorage = true;
debugInfo = "Debug: Tax Collection Check";
}
public override string DescriptionPart public override string DescriptionPart
{ {
get get
{ {
string status = hasSucceeded ? "SUCCEEDED" : if (State != QuestPartState.Enabled)
hasFailed ? "FAILED" : return "WULA_TaxCollection.Waiting".Translate(); // 等待激活
$"CHECKING (retry #{retryCount}, next in {nextRetryTick - Find.TickManager.TicksGame} ticks)";
return $"Tax Collection: {requiredCount} {resourceDef?.defName ?? "NULL"} - {status}"; string statusKey = hasSucceeded ? "WULA_TaxCollection.Status.Succeeded" :
hasFailed ? "WULA_TaxCollection.Status.Failed" :
"";
string statusText;
if (hasSucceeded || hasFailed)
{
statusText = statusKey.Translate();
}
else
{
// 只有在调试模式下才显示下一次检查的tick
if (Prefs.DevMode)
{
statusText = statusKey.Translate(retryCount, Math.Max(0, nextRetryTick - Find.TickManager.TicksGame));
}
else
{
statusText = statusKey.Translate(retryCount);
}
}
// 硬编码状态文本颜色为 #820D13
string coloredStatusText = $"<color=#820D13>{statusText}</color>";
return "WULA_TaxCollection.Status".Translate(requiredCount, resourceDef?.label ?? "NULL", coloredStatusText);
} }
} }
} }

View File

@@ -209,6 +209,7 @@
<Compile Include="Pawn\WULA_Maintenance\WorkGiver_DoMaintenance.cs" /> <Compile Include="Pawn\WULA_Maintenance\WorkGiver_DoMaintenance.cs" />
<Compile Include="Placeworker\CompProperties_CustomRadius.cs" /> <Compile Include="Placeworker\CompProperties_CustomRadius.cs" />
<Compile Include="QuestNodes\QuestNode_CheckGlobalResource.cs" /> <Compile Include="QuestNodes\QuestNode_CheckGlobalResource.cs" />
<Compile Include="QuestNodes\QuestNode_Hyperlinks.cs" />
<Compile Include="QuestNodes\QuestPart_GlobalResourceCheck.cs" /> <Compile Include="QuestNodes\QuestPart_GlobalResourceCheck.cs" />
<Compile Include="Stat\StatWorker_Energy.cs" /> <Compile Include="Stat\StatWorker_Energy.cs" />
<Compile Include="Stat\StatWorker_Maintenance.cs" /> <Compile Include="Stat\StatWorker_Maintenance.cs" />