This commit is contained in:
2025-12-05 17:31:34 +08:00
parent a2a3390ed8
commit 284727e3ba
11 changed files with 1583 additions and 147 deletions

View File

@@ -5,25 +5,11 @@
<rootSelectionWeight>0</rootSelectionWeight>
<expireDaysRange>1</expireDaysRange>
<sendAvailableLetter>true</sendAvailableLetter>
<isRootSpecial>true</isRootSpecial> <!-- 特殊任务 -->
<isRootSpecial>true</isRootSpecial> <!-- 特殊任务 -->
<questNameRules>
<rulesStrings>
<li>questName->The [bandit] [camp]</li>
<li>questName->[bandit] [camp]</li>
<li>questName->[asker_nameDef] and the [camp]</li>
<li>camp->Camp</li>
<li>camp->Outpost</li>
<li>camp->Lair</li>
<li>camp->Encampment</li>
<li>bandit->Bandit</li>
<li>bandit->Raider</li>
<li>bandit->Outlaw</li>
<li>bandit->Desperado</li>
<li>bandit->Fugitive</li>
<li>bandit->Marauder</li>
<li>bandit->Robber</li>
<li>bandit->Brigand</li>
<li>questName->WULA_Attack_Robber_Camp_questName</li>
</rulesStrings>
</questNameRules>
<questDescriptionRules>
@@ -46,109 +32,44 @@
</li>
<li Class="QuestNode_GetMap">
<canBeSpace>true</canBeSpace>
<canBeSpace>false</canBeSpace>
</li>
<li Class="QuestNode_GetPawn">
<storeAs>asker</storeAs>
<mustBeFactionLeader>true</mustBeFactionLeader>
<allowPermanentEnemyFaction>false</allowPermanentEnemyFaction>
<hostileWeight>0.15</hostileWeight>
</li>
<li Class="QuestNode_GetSiteTile">
<storeAs>siteTile</storeAs>
<preferCloserTiles>true</preferCloserTiles>
<selectLandmarkChance>0.5</selectLandmarkChance>
<allowedLandmarks>
<li MayRequire="Ludeon.RimWorld.Odyssey">Oasis</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Lake</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">LakeWithIsland</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">LakeWithIslands</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Pond</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">DryLake</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">ToxicLake</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Wetland</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">HotSprings</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Archipelago</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">CoastalIsland</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Peninsula</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Bay</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Valley</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Cavern</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Chasm</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Cliffs</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Hollow</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">TerraformingScar</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">LavaLake</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">Dunes</li>
<li MayRequire="Ludeon.RimWorld.Odyssey">AncientHeatVent</li>
</allowedLandmarks>
</li>
<li Class="QuestNode_GetSitePartDefsByTagsAndFaction">
<storeAs>sitePartDefs</storeAs>
<storeFactionAs>siteFaction</storeFactionAs>
<sitePartsTags>
<li><tag>BanditCamp</tag></li>
</sitePartsTags>
<li Class="QuestNode_GetFaction">
<storeAs>siteFaction</storeAs>
<allowEnemy>true</allowEnemy>
<mustBeHostileToFactionOf>$asker</mustBeHostileToFactionOf>
<mustBePermanentEnemy>true</mustBePermanentEnemy>
</li>
<li Class="QuestNode_GetDefaultSitePartsParams">
<tile>$siteTile</tile>
<li Class="QuestEditor_Library.QuestNode_RandomCustomMap">
<datas>
<li>
<key>WULA_Camp_Captured_By_Robber</key>
<value>1</value>
</li>
</datas>
<buffer>5</buffer>
<bufferMin>10</bufferMin>
<siteIconPath>Things/Building/Natural/Hive/HiveC</siteIconPath>
<expandingIconPath>Things/Building/Natural/Hive/HiveC</expandingIconPath>
<storeAs>site</storeAs>
<faction>$siteFaction</faction>
<sitePartDefs>$sitePartDefs</sitePartDefs>
<storeSitePartsParamsAs>sitePartsParams</storeSitePartsParamsAs>
<distance>
<min>5</min>
<max>10</max>
</distance>
<blacklist />
</li>
<li Class="QuestNode_GetSiteThreatPoints">
<storeAs>sitePoints</storeAs>
<sitePartsParams>$sitePartsParams</sitePartsParams>
</li>
<li Class="QuestNode_SubScript">
<def>Util_GetDefaultRewardValueFromPoints</def>
<parms>
<!-- Use the actual threat points generated (some site parts define a minimum threshold) -->
<points>$sitePoints</points>
<points>$points</points>
</parms>
</li>
<!-- Inflate reward value. Since we're basing the reward value on the threat points generated, we need to do this
even though the threat points was deflated from the input points already. -->
<li Class="QuestNode_Multiply">
<value1>$rewardValue</value1>
<value2>1.75</value2>
<storeAs>rewardValue</storeAs>
</li>
<li Class="QuestNode_SubScript">
<def>Util_GenerateSite</def>
</li>
<li Class="QuestNode_SpawnWorldObjects">
<worldObjects>$site</worldObjects>
</li>
<li Class="QuestNode_WorldObjectTimeout">
<worldObject>$site</worldObject>
<isQuestTimeout>true</isQuestTimeout>
<delayTicks>$(randInt(12,28)*60000)</delayTicks>
<inSignalDisable>site.MapGenerated</inSignalDisable>
<destroyOnCleanup>true</destroyOnCleanup>
<node Class="QuestNode_Sequence">
<nodes>
<li Class="QuestNode_Letter">
<label TKey="LetterLabelQuestExpired">Quest expired: [resolvedQuestName]</label>
<text TKey="LetterTextQuestExpired">The bandit camp has packed up and moved on. The quest [resolvedQuestName] has expired.</text>
</li>
<li Class="QuestNode_End">
<outcome>Fail</outcome>
</li>
</nodes>
</node>
</li>
<!-- If we enter and leave, the map is destroyed. Fail the quest. -->
<li Class="QuestNode_Signal">
<inSignal>site.Destroyed</inSignal>
@@ -199,4 +120,138 @@
</nodes>
</root>
</QuestScriptDef>
<QuestEditor_Library.CustomMapDataDef>
<defName>WULA_Camp_Captured_By_Robber</defName>
<label>被异族占据的哨站</label>
<size>(44, 1, 44)</size>
<isPart>true</isPart>
<commonality>0</commonality>
<pawns>
<li>
<key>(21, 0, 24)</key>
<value>
<li Class="QuestEditor_Library.PawnSpawnData_Faction">
<dataName>Robber</dataName>
<enableLord>true</enableLord>
<lordDataName>RobberGroup</lordDataName>
<faction>MapFaction</faction>
<duty>DefendBase</duty>
<spawnType>MapGeneration</spawnType>
<point>1000~2000</point>
</li>
</value>
</li>
</pawns>
<thingDatas>
<li>
<def>WULA_TransportPod</def>
<allRect>
<li>(24,20,24,20)</li>
<li>(24,23,24,23)</li>
</allRect>
</li>
<li>
<def>Brazier</def>
<stuff>Steel</stuff>
<position>(16,0,22)</position>
</li>
<li>
<def>Bedroll</def>
<stuff>Cloth</stuff>
<rotation>3</rotation>
<allRect>
<li>(23,14,23,16)</li>
</allRect>
</li>
<li>
<def>Wula_Fusion_Generators</def>
<storedEnergy>29.99023</storedEnergy>
<position>(30,0,27)</position>
</li>
<li>
<def>WULA_Wall_Flag_Building</def>
<allRect>
<li>(16,13,16,13)</li>
<li>(25,30,25,30)</li>
<li>(27,30,27,30)</li>
</allRect>
</li>
<li>
<def>WULA_Machine_Recharger</def>
<position>(14,0,16)</position>
</li>
<li>
<def>WulaWall</def>
<allRect>
<li>(12,14,16,14)</li>
<li>(12,15,12,18)</li>
<li>(11,18,11,18)</li>
<li>(10,20,10,21)</li>
<li>(9,21,9,27)</li>
<li>(20,12,22,12)</li>
<li>(22,13,23,13)</li>
<li>(25,13,29,13)</li>
<li>(10,27,11,27)</li>
<li>(11,28,11,29)</li>
<li>(12,29,12,29)</li>
<li>(29,14,30,14)</li>
<li>(30,15,31,16)</li>
<li>(14,32,14,35)</li>
<li>(31,17,31,21)</li>
<li>(33,16,35,16)</li>
<li>(15,35,21,35)</li>
<li>(35,17,35,18)</li>
<li>(21,33,24,33)</li>
<li>(24,31,25,31)</li>
<li>(21,34,21,34)</li>
<li>(24,32,24,32)</li>
<li>(36,18,37,18)</li>
<li>(32,25,34,25)</li>
<li>(27,31,27,32)</li>
<li>(32,26,32,29)</li>
<li>(37,19,37,22)</li>
<li>(34,24,34,24)</li>
<li>(31,29,31,32)</li>
<li>(28,32,30,32)</li>
</allRect>
</li>
<li>
<def>WulaDoor</def>
<allRect>
<li>(32,16,32,16)</li>
<li>(26,31,26,31)</li>
</allRect>
</li>
<li>
<def>Wula_Sonar_Mine</def>
<allRect>
<li>(10,22,10,22)</li>
<li>(28,14,28,14)</li>
<li>(30,31,30,31)</li>
</allRect>
</li>
<li>
<def>Bedroll</def>
<stuff>Cloth</stuff>
<rotation>1</rotation>
<allRect>
<li>(10,24,10,26)</li>
</allRect>
</li>
<li>
<def>WulaShelter</def>
<allRect>
<li>(12,6,15,6)</li>
<li>(9,10,12,10)</li>
<li>(12,7,12,9)</li>
<li>(7,32,7,36)</li>
<li>(34,9,38,9)</li>
<li>(8,36,10,36)</li>
<li>(38,10,38,12)</li>
<li>(35,35,38,35)</li>
<li>(38,32,38,34)</li>
</allRect>
</li>
</thingDatas>
</QuestEditor_Library.CustomMapDataDef>
</Defs>

View File

@@ -668,4 +668,17 @@
<li>WULA_Colony_License_LV3_Technology</li>
</prerequisites>
</ResearchProjectDef>
<!-- 特殊 -->
<ResearchProjectDef ParentName="WULAtechBase">
<defName>WULA_Building_Teleporter_Technology</defName>
<researchViewX>10.00</researchViewX>
<researchViewY>2.70</researchViewY>
<label>建筑传送许可</label>
<description>允许通过传送将乌拉帝国的建筑直接传送到空投区,这使得建筑可以立刻部署到目标地点,且无视厚岩顶阻挡。</description>
<baseCost>2000</baseCost>
<prerequisites>
<li>WULA_Colony_License_LV3_Technology</li>
</prerequisites>
</ResearchProjectDef>
</Defs>

View File

@@ -71,6 +71,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WulaWall</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef Name="WulaWall_Incoming" ParentName="SkyfallerBase">
@@ -248,6 +256,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WulaDoor</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef Name="WulaDoor_Incoming" ParentName="SkyfallerBase">
@@ -467,6 +483,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WulaShelter</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -634,6 +658,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_MaintenancePod</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -831,6 +863,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_WeaponArmor_Productor</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -1062,7 +1102,7 @@
<designationHotKey>Misc12</designationHotKey>
<fillPercent>0.5</fillPercent>
<uiOrder>2200</uiOrder>
<terrainAffordanceNeeded>Medium</terrainAffordanceNeeded>
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
<statBases>
<MaxHitPoints>250</MaxHitPoints>
<WorkToBuild>1600</WorkToBuild>
@@ -1426,6 +1466,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_Machine_Recharger</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -1596,6 +1644,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_Charging_Station_Synth</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -1761,6 +1817,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_Cube_Productor</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -1948,6 +2012,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_DarkEnergy_Generators</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -2150,6 +2222,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_Fusion_Generators</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">

View File

@@ -73,6 +73,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_Sonar_Mine</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -328,6 +336,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>WULA_Cat_Bunker</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -588,6 +604,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_Base_ATGun_Turret</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -881,6 +905,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_Base_Laser_Turret</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
@@ -1176,6 +1208,14 @@
<allowThinRoof>true</allowThinRoof>
<allowThickRoof>false</allowThickRoof>
</li>
<li Class="WulaFallenEmpire.CompProperties_BuildingSpawner">
<buildingToSpawn>Wula_Base_Mortar_Turret</buildingToSpawn>
<destroyBuilding>true</destroyBuilding>
<spawnEffecter>WULA_Psi_Skip_Entry</spawnEffecter>
<spawnSound>VoidStructure_Emerge</spawnSound>
<inheritFaction>true</inheritFaction>
<requiredResearch>WULA_Building_Teleporter_Technology</requiredResearch>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">

View File

@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<LanguageData>
<WULA_Attack_Robber_Camp.questNameRules.rulesStrings>
<li>questName->[bandit][camp]</li>
<li>questName->[bandit][camp]</li>
<li>questName->[asker_nameDef]与[camp]</li>
<li>questName->[bandit]占据的乌拉帝国[camp]</li>
<li>camp->营地</li>
<li>camp->哨所</li>
<li>camp->窝点</li>
<li>camp->据点</li>
<li>bandit->土匪</li>
<li>bandit->劫掠者</li>
@@ -18,6 +15,6 @@
<li>bandit->劫匪</li>
</WULA_Attack_Robber_Camp.questNameRules.rulesStrings>
<WULA_Attack_Robber_Camp.questDescriptionRules.rulesStrings>
<li>questDescription->[asker_faction_name]的[asker_faction_leaderTitle][asker_nameFull],向我们发来了一条讯息。根据他们掌握的情报,一个属于[siteFaction_name]派系,由[siteFaction_pawnsPlural]建立的营地一直在袭击他们的远行队。\n\n[asker_nameDef]请求我们帮助他们摧毁这个营地,彻底消灭敌人的成员和炮塔。[asker_label]还提醒我们:\n\n[sitePart0_description]</li>
<li>questDescription->乌拉帝国行星封锁机关的总控AI向殖民地发送了一个请求。[siteFaction_name]的一群战士控制了一个废弃的乌拉帝国空投前哨站。可能是这个前哨站没有按照标准流程启动报废程序,导致其被异族占据,里面有一些科技造物是不能外泄到异族手中的。\n\n这个营地必须被抹去其中的乌拉帝国科技造物可以回收也可以就地销毁。现场人数无法评估仍然有可能有一些未触发的&lt;color=#AA3020>&lt;i>弹射地雷&lt;/i>&lt;/color>,但是未发现已经启动的乌拉帝国炮塔</li>
</WULA_Attack_Robber_Camp.questDescriptionRules.rulesStrings>
</LanguageData>

View File

@@ -4,6 +4,6 @@
<li>questName->晋级任务:回收皇家机密</li>
</WULA_Recycle_PIA_Legion_File.questNameRules.rulesStrings>
<WULA_Recycle_PIA_Legion_File.questDescriptionRules.rulesStrings>
<li>questDescription->乌拉帝国行星封锁机关的总控AI向殖民地发送了一个特殊的请求有一个装着皇室机密的保险箱被乌拉帝国的进步派叛军控制了殖民地必须将其回收随后将其交回乌拉帝国舰队。如果保险箱已经被打开就要杀光在场的所有人。\n\n目前叛军很可能在试图打开这个保险箱你需要检查其哨站内的工作台。\n\n你只有5天的时间处理这个任务取得保险箱后你可以建造&lt;color=#6BB7B7>&lt;i>乌拉帝国物资输送舱&lt;/i>&lt;/color>来将保险箱输送到位于轨道上的舰队。</li>
<li>questDescription->乌拉帝国行星封锁机关的总控AI向殖民地发送了一个特殊的请求有一个装着皇室机密的保险箱被乌拉帝国的进步派叛军控制了殖民地必须将其回收随后将其交回乌拉帝国舰队。如果保险箱已经被打开就要杀光在场的所有人。\n\n目前叛军很可能在试图打开这个保险箱你需要检查其哨站内的工作台。大约有&lt;color=#AA3020>&lt;i>10~20个叛军合成人&lt;/i>&lt;/color>被拍摄到,现场同时发现了正在运作的&lt;color=#AA3020>&lt;i>若干炮台&lt;/i>&lt;/color>。\n\n你只有5天的时间处理这个任务取得保险箱后你可以建造&lt;color=#6BB7B7>&lt;i>乌拉帝国物资输送舱&lt;/i>&lt;/color>来将保险箱输送到位于轨道上的舰队。</li>
</WULA_Recycle_PIA_Legion_File.questDescriptionRules.rulesStrings>
</LanguageData>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
using RimWorld;
using System.Collections.Generic;
using Verse;
namespace WulaFallenEmpire
{
public class CompProperties_BuildingSpawner : CompProperties
{
public ThingDef buildingToSpawn;
public bool destroyBuilding = true;
public int delayTicks = 0;
// 自动召唤设置
public bool canAutoCall = true;
public int autoCallDelayTicks = 0; // 默认10秒
// FlyOver 前提条件
public bool requireFlyOver = false;
// 屋顶限制
public bool allowThinRoof = true;
public bool allowThickRoof = true;
// 新增:科技需求
public ResearchProjectDef requiredResearch;
// 新增:生成时的效果器
public EffecterDef spawnEffecter;
// 新增:音效
public SoundDef spawnSound;
// 新增:建筑朝向设置
public Rot4 buildingRotation = Rot4.North;
// 新增:位置偏移
public IntVec2 spawnOffset = IntVec2.Zero;
// 新增:允许替换现有建筑
public bool canReplaceExisting = false;
// 新增:是否继承原建筑的派系
public bool inheritFaction = true;
// 新增:建筑生成后的燃料量(如果适用)
public FloatRange fuelRange = new FloatRange(1f, 1f);
public CompProperties_BuildingSpawner()
{
compClass = typeof(CompBuildingSpawner);
}
public override void ResolveReferences(ThingDef parentDef)
{
base.ResolveReferences(parentDef);
// 验证buildingToSpawn
if (buildingToSpawn != null && buildingToSpawn.category != ThingCategory.Building)
{
Log.Error($"CompProperties_BuildingSpawner: buildingToSpawn must be a building, but got {buildingToSpawn.defName}");
buildingToSpawn = null;
}
}
public override IEnumerable<string> ConfigErrors(ThingDef parentDef)
{
foreach (string item in base.ConfigErrors(parentDef))
{
yield return item;
}
if (buildingToSpawn == null)
{
yield return "buildingToSpawn is not set";
}
else if (buildingToSpawn.category != ThingCategory.Building)
{
yield return $"buildingToSpawn must be a building, but got {buildingToSpawn.defName}";
}
}
}
}

View File

@@ -11,17 +11,21 @@ namespace WulaFallenEmpire
// 记录已经处理过的建筑(避免重复)
private HashSet<Thing> processedBuildings = new HashSet<Thing>();
// 组件类型过滤
public bool includeBuildingSpawner = true;
public bool includeSkyfallerCaller = true;
public Designator_CallSkyfallerInArea()
{
defaultLabel = "WULA_Designator_CallSkyfallerInArea".Translate();
defaultDesc = "WULA_Designator_CallSkyfallerInAreaDesc".Translate();
icon = ContentFinder<Texture2D>.Get("Wula/UI/Designators/Designator_CallSkyfallerInArea");
defaultLabel = "WULA_Designator_CallInArea".Translate();
defaultDesc = "WULA_Designator_CallInAreaDesc".Translate();
icon = ContentFinder<Texture2D>.Get("Wula/UI/Designators/Designator_CallInArea");
soundDragSustain = SoundDefOf.Designate_DragStandard;
soundDragChanged = SoundDefOf.Designate_DragStandard_Changed;
useMouseIcon = true;
soundSucceeded = SoundDefOf.Designate_Claim;
hotKey = KeyBindingDefOf.Misc12;
tutorTag = "CallSkyfallerInArea";
tutorTag = "CallInArea";
}
public override DrawStyleCategoryDef DrawStyleCategory => DrawStyleCategoryDefOf.FilledRectangle;
@@ -35,13 +39,13 @@ namespace WulaFallenEmpire
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)
HasValidComponent(thing))
{
return true;
}
@@ -50,6 +54,28 @@ namespace WulaFallenEmpire
// 即使单元格内没有符合条件的建筑,也允许选择(这样用户可以拖动区域)
return true;
}
// 检查建筑是否有有效的组件
private bool HasValidComponent(Thing thing)
{
// 检查 Building Spawner 组件
if (includeBuildingSpawner)
{
var buildingSpawner = thing.TryGetComp<CompBuildingSpawner>();
if (buildingSpawner != null && buildingSpawner.CanCallBuilding)
return true;
}
// 检查 Skyfaller Caller 组件
if (includeSkyfallerCaller)
{
var skyfallerCaller = thing.TryGetComp<CompSkyfallerCaller>();
if (skyfallerCaller != null && skyfallerCaller.CanCallSkyfaller)
return true;
}
return false;
}
public override void DesignateSingleCell(IntVec3 c)
{
@@ -63,30 +89,53 @@ namespace WulaFallenEmpire
processedBuildings.Clear();
int totalBuildings = 0;
int buildingSpawnerCount = 0;
int skyfallerCallerCount = 0;
// 处理所有选中的单元格
foreach (var cell in cells)
{
if (cell.InBounds(Map))
{
// 统计该单元格处理的建筑数量
int cellCount = processedBuildings.Count;
ProcessCell(cell);
int newBuildings = processedBuildings.Count - cellCount;
// 统计每个组件类型的调用数量
foreach (var building in processedBuildings)
{
if (building.Destroyed) continue;
if (building.TryGetComp<CompBuildingSpawner>()?.calling == true)
buildingSpawnerCount++;
else if (building.TryGetComp<CompSkyfallerCaller>()?.calling == true)
skyfallerCallerCount++;
}
totalBuildings += newBuildings;
}
}
// 计算成功和失败的数量
// 这里需要跟踪每个建筑的调用结果
// 由于我们直接调用CallSkyfaller需要知道哪些失败了
// 简化处理在ProcessCell中统计
// 显示简单的结果消息
// 显示结果消息
if (totalBuildings > 0)
{
Messages.Message("WULA_AreaCallInitiated".Translate(totalBuildings),
MessageTypeDefOf.PositiveEvent);
string message = "WULA_AreaCallInitiated".Translate(totalBuildings);
if (buildingSpawnerCount > 0 && skyfallerCallerCount > 0)
{
message += "\n" + "WULA_BothComponentsCalled".Translate(
buildingSpawnerCount, skyfallerCallerCount);
}
else if (buildingSpawnerCount > 0)
{
message += "\n" + "WULA_BuildingSpawnerCalled".Translate(buildingSpawnerCount);
}
else if (skyfallerCallerCount > 0)
{
message += "\n" + "WULA_SkyfallerCallerCalled".Translate(skyfallerCallerCount);
}
Messages.Message(message, MessageTypeDefOf.PositiveEvent);
}
else
{
@@ -113,21 +162,44 @@ namespace WulaFallenEmpire
if (processedBuildings.Contains(thing))
continue;
// 获取空投组件
var comp = thing.TryGetComp<CompSkyfallerCaller>();
if (comp == null)
continue;
// 标记为已处理
processedBuildings.Add(thing);
// 尝试呼叫空投
if (comp.CanCallSkyfaller)
// 尝试调用两种组件(如果有且可以调用)
bool anyCalled = false;
// 1. 先尝试 Building Spawner
if (includeBuildingSpawner)
{
comp.CallSkyfaller(false);
processedBuildings.Add(thing);
var buildingSpawner = thing.TryGetComp<CompBuildingSpawner>();
if (buildingSpawner != null && buildingSpawner.CanCallBuilding)
{
buildingSpawner.CallBuilding(false);
anyCalled = true;
// 如果建筑被销毁,记录日志
if (thing.Destroyed)
{
Log.Message($"[Designator] Building destroyed after BuildingSpawner call at {cell}");
}
}
}
// 即使不能呼叫,也添加到已处理列表,避免重复尝试
else
// 2. 尝试 Skyfaller Caller如果建筑还存在
if (!thing.Destroyed && includeSkyfallerCaller)
{
processedBuildings.Add(thing);
var skyfallerCaller = thing.TryGetComp<CompSkyfallerCaller>();
if (skyfallerCaller != null && skyfallerCaller.CanCallSkyfaller)
{
skyfallerCaller.CallSkyfaller(false);
anyCalled = true;
}
}
// 如果没有任何组件被调用,从处理列表中移除(防止重复尝试)
if (!anyCalled)
{
processedBuildings.Remove(thing);
}
}
}
@@ -141,20 +213,43 @@ namespace WulaFallenEmpire
if (t.Faction != Faction.OfPlayer)
return false;
var comp = t.TryGetComp<CompSkyfallerCaller>();
if (comp == null)
return false;
return true;
return HasValidComponent(t);
}
public override void DesignateThing(Thing t)
{
// 用于反向设计器(右键菜单)
var comp = t.TryGetComp<CompSkyfallerCaller>();
if (comp != null && comp.CanCallSkyfaller)
processedBuildings.Add(t);
// 尝试调用两种组件
bool anyCalled = false;
// 1. 先尝试 Building Spawner
if (includeBuildingSpawner)
{
comp.CallSkyfaller(false);
var buildingSpawner = t.TryGetComp<CompBuildingSpawner>();
if (buildingSpawner != null && buildingSpawner.CanCallBuilding)
{
buildingSpawner.CallBuilding(false);
anyCalled = true;
}
}
// 2. 尝试 Skyfaller Caller如果建筑还存在
if (!t.Destroyed && includeSkyfallerCaller)
{
var skyfallerCaller = t.TryGetComp<CompSkyfallerCaller>();
if (skyfallerCaller != null && skyfallerCaller.CanCallSkyfaller)
{
skyfallerCaller.CallSkyfaller(false);
anyCalled = true;
}
}
if (!anyCalled)
{
Messages.Message("WULA_NoComponentCanCall".Translate(),
t, MessageTypeDefOf.RejectInput);
}
}
@@ -162,8 +257,32 @@ namespace WulaFallenEmpire
{
// 参考Designator_Deconstruct只绘制鼠标悬停方框
GenUI.RenderMouseoverBracket();
// 可以添加额外的视觉效果来显示哪些建筑将被影响
if (Find.DesignatorManager.SelectedDesignator == this)
{
DrawAffectedBuildings();
}
}
// 绘制受影响的建筑
private void DrawAffectedBuildings()
{
if (Map == null) return;
// 这里可以绘制高亮显示哪些建筑会被影响
// 但由于性能考虑,只在特定条件下绘制
if (DebugSettings.godMode)
{
foreach (var building in Map.listerBuildings.allBuildingsColonist)
{
if (HasValidComponent(building))
{
GenDraw.DrawFieldEdges(new List<IntVec3> { building.Position },
building.Destroyed ? Color.red : Color.green);
}
}
}
}
}
}

View File

@@ -106,6 +106,8 @@
<Compile Include="BuildingComp\WULA_BuildingBombardment\CompProperties_BuildingBombardment.cs" />
<Compile Include="Ability\WULA_AbilityCallSkyfaller\MapComponent_SkyfallerDelayed.cs" />
<Compile Include="BuildingComp\Building_TurretGunHasSpeed.cs" />
<Compile Include="BuildingComp\WULA_BuildingSpawner\CompBuildingSpawner.cs" />
<Compile Include="BuildingComp\WULA_BuildingSpawner\CompProperties_BuildingSpawner.cs" />
<Compile Include="BuildingComp\WULA_EnergyLanceTurret\CompEnergyLanceTurret.cs" />
<Compile Include="BuildingComp\WULA_EnergyLanceTurret\CompProperties_EnergyLanceTurret.cs" />
<Compile Include="BuildingComp\WULA_InitialFaction\CompProperties_InitialFaction.cs" />