虫群的自定义袭击
This commit is contained in:
Binary file not shown.
@@ -699,12 +699,12 @@
|
||||
<sound>AcidSpray_Resolve</sound>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowTemperatureRange">
|
||||
<temperatureCheckBuilding>ARA_Cocoon_Weapon_2Stage</temperatureCheckBuilding>
|
||||
<temperatureCheckBuilding>ARA_Cocoon_Medicine_From_Death</temperatureCheckBuilding>
|
||||
<customLabel>温度要求</customLabel>
|
||||
<showCurrentTemperature>true</showCurrentTemperature>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityShowInteractiveThing">
|
||||
<cocoonBuildingDef>ARA_Cocoon_Weapon_2Stage</cocoonBuildingDef>
|
||||
<cocoonBuildingDef>ARA_Cocoon_Medicine_From_Death</cocoonBuildingDef>
|
||||
<customLabel>可孵化物品列表</customLabel>
|
||||
<showResearchRequirements>true</showResearchRequirements>
|
||||
<showNutritionCost>true</showNutritionCost>
|
||||
|
||||
45
1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml
Normal file
45
1.6/1.6/Defs/FactionDefs/ARA_Factions_Hostile_Hive.xml
Normal file
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<FactionDef ParentName="FactionBase">
|
||||
<defName>ARA_Hostile_Hive</defName>
|
||||
<label>阿拉克涅军团断须</label>
|
||||
<description>向闪耀世界方向侵略的阿拉克涅虫巢舰队被闪耀世界联军击败后,残留于星域中的虫群子个体。这些虫群子个体由于无法和蜂巢网络建立联系,其自行组织的反常网络只有低度的智能,只能让其成员如野兽般行动——然而她们依然是一群危险的敌人,于无数敌手交战留下的基因性反射使得她们的锋芒不减当年。\n\n她们不会对任何人展现仁慈,即使她们的对手是自己的同族。</description>
|
||||
<pawnSingular>虫群</pawnSingular>
|
||||
<pawnsPlural>虫群</pawnsPlural>
|
||||
<requiredCountAtGameStart>1</requiredCountAtGameStart>
|
||||
<fixedName>阿拉克涅断须</fixedName>
|
||||
<factionIconPath>World/WorldObjects/Expanding/Insects</factionIconPath>
|
||||
<colorSpectrum>
|
||||
<li>(0.44, 0.41, 0.32)</li>
|
||||
<li>(0.61, 0.58, 0.49)</li>
|
||||
<li>(0.60, 0.49, 0.36)</li>
|
||||
</colorSpectrum>
|
||||
<raidCommonalityFromPointsCurve>
|
||||
<points>
|
||||
<li>(0, 0)</li>
|
||||
</points>
|
||||
</raidCommonalityFromPointsCurve>
|
||||
<maxPawnCostPerTotalPointsCurve>
|
||||
<points>
|
||||
<li>(100,100)</li>
|
||||
<li>(10000,10000)</li>
|
||||
</points>
|
||||
</maxPawnCostPerTotalPointsCurve>
|
||||
<pawnGroupMakers>
|
||||
<!-- 虫巢不发起任何常规袭击,而是使用自定义袭击 -->
|
||||
</pawnGroupMakers>
|
||||
<humanlikeFaction>false</humanlikeFaction>
|
||||
<hidden>true</hidden>
|
||||
<autoFlee>false</autoFlee>
|
||||
<canUseAvoidGrid>false</canUseAvoidGrid>
|
||||
<techLevel>Animal</techLevel>
|
||||
<animalsFleeDanger>false</animalsFleeDanger>
|
||||
<permanentEnemyToEveryoneExcept>
|
||||
<li MayRequire="Ludeon.RimWorld.Anomaly">Entities</li>
|
||||
</permanentEnemyToEveryoneExcept>
|
||||
<settlementTexturePath>World/WorldObjects/DefaultSettlement</settlementTexturePath>
|
||||
<allowedArrivalTemperatureRange>-2000~2000</allowedArrivalTemperatureRange>
|
||||
<maxConfigurableAtWorldCreation>1</maxConfigurableAtWorldCreation>
|
||||
<configurationListOrderPriority>1000</configurationListOrderPriority>
|
||||
</FactionDef>
|
||||
</Defs>
|
||||
@@ -19,7 +19,8 @@
|
||||
</backstoryFilters>
|
||||
<!-- 命名规则 -->
|
||||
<factionNameMaker>ARA_New_Hive_NamerFaction</factionNameMaker>
|
||||
<settlementNameMaker>NamerSettlementOutlander</settlementNameMaker>
|
||||
<settlementNameMaker>ARA_NamerSettlement</settlementNameMaker>
|
||||
<playerInitialSettlementNameMaker>ARA_NamerInitialSettlement</playerInitialSettlementNameMaker>
|
||||
<allowedCultures><li>Astropolitan</li></allowedCultures>
|
||||
<factionIconPath>World/WorldObjects/Expanding/Town</factionIconPath>
|
||||
<startingResearchTags>
|
||||
@@ -41,29 +42,58 @@
|
||||
<rulePack>
|
||||
<rulesStrings>
|
||||
<li>r_name->[hivename1] [hivename2]</li>
|
||||
<li>hivename1->猩红</li>
|
||||
<li>hivename1->至高</li>
|
||||
<li>hivename1->唯一</li>
|
||||
<li>hivename1->蔓延</li>
|
||||
<li>hivename1->永恒</li>
|
||||
<li>hivename1->永续</li>
|
||||
<li>hivename1->虚空</li>
|
||||
<li>hivename1->深渊</li>
|
||||
<li>hivename1->吞噬</li>
|
||||
<li>hivename1->进化</li>
|
||||
<li>hivename1->原生</li>
|
||||
<li>hivename1->融合</li>
|
||||
<li>hivename1->蚀骨</li>
|
||||
|
||||
<li>hivename2->核心</li>
|
||||
<li>hivename2->内核</li>
|
||||
<li>hivename2->要点</li>
|
||||
<li>hivename2->中心</li>
|
||||
<li>hivename2->焦点</li>
|
||||
<li>hivename2->原点</li>
|
||||
<li>hivename2->支点</li>
|
||||
<li>hivename2->枢轴</li>
|
||||
<li>hivename2->中枢</li>
|
||||
<li>hivename2->母体</li>
|
||||
<li>hivename2->源泉</li>
|
||||
<li>hivename2->源地</li>
|
||||
<li>hivename2->基体</li>
|
||||
<li>hivename2->始祖</li>
|
||||
<li>hivename2->主脑</li>
|
||||
<li>hivename2->巢心</li>
|
||||
<li>hivename2->蜂巢</li>
|
||||
<li>hivename2->虫群</li>
|
||||
<li>hivename2->爪牙</li>
|
||||
<li>hivename2->兽群</li>
|
||||
<li>hivename2->触须</li>
|
||||
</rulesStrings>
|
||||
</rulePack>
|
||||
</RulePackDef>
|
||||
<RulePackDef>
|
||||
<defName>ARA_NamerSettlement</defName>
|
||||
<rulePack>
|
||||
<rulesStrings>
|
||||
<li>r_name->[hivesettlementname1] [hivesettlementname2]</li>
|
||||
<li>hivesettlementname1->猩红</li>
|
||||
<li>hivesettlementname1->至高</li>
|
||||
<li>hivesettlementname1->唯一</li>
|
||||
<li>hivesettlementname1->蔓延</li>
|
||||
<li>hivesettlementname1->永恒</li>
|
||||
<li>hivesettlementname1->永续</li>
|
||||
|
||||
<li>hivesettlementname2->核心</li>
|
||||
<li>hivesettlementname2->内核</li>
|
||||
<li>hivesettlementname2->要点</li>
|
||||
<li>hivesettlementname2->中心</li>
|
||||
<li>hivesettlementname2->焦点</li>
|
||||
<li>hivesettlementname2->原点</li>
|
||||
<li>hivesettlementname2->支点</li>
|
||||
<li>hivesettlementname2->枢轴</li>
|
||||
<li>hivesettlementname2->中枢</li>
|
||||
<li>hivesettlementname2->母体</li>
|
||||
<li>hivesettlementname2->源泉</li>
|
||||
<li>hivesettlementname2->源地</li>
|
||||
<li>hivesettlementname2->基体</li>
|
||||
<li>hivesettlementname2->始祖</li>
|
||||
<li>hivesettlementname2->主脑</li>
|
||||
<li>hivesettlementname2->巢心</li>
|
||||
</rulesStrings>
|
||||
</rulePack>
|
||||
</RulePackDef>
|
||||
<RulePackDef>
|
||||
<defName>ARA_NamerInitialSettlement</defName>
|
||||
<rulePack>
|
||||
<rulesStrings>
|
||||
<li>r_name->虫巢</li>
|
||||
</rulesStrings>
|
||||
</rulePack>
|
||||
</RulePackDef>
|
||||
|
||||
192
1.6/1.6/Defs/HiveRaidDef/ARA_CustomRaidDef.xml
Normal file
192
1.6/1.6/Defs/HiveRaidDef/ARA_CustomRaidDef.xml
Normal file
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<!-- 自定义袭击定义 -->
|
||||
<ArachnaeSwarm.CustomRaidDef>
|
||||
<defName>ARA_Stage1_Raid</defName>
|
||||
<factionDef>ARA_Hostile_Hive</factionDef>
|
||||
<pointWavePools>
|
||||
<li>
|
||||
<minPoints>0</minPoints>
|
||||
<maxPoints>800</maxPoints> <!-- 第一阶段点数上限,点数为人数*100 -->
|
||||
<wavePool>ARA_WavePool_Stage1</wavePool>
|
||||
</li>
|
||||
</pointWavePools>
|
||||
<baseRaidNembers>3</baseRaidNembers>
|
||||
<pointsGrowthPerWave>
|
||||
<growthType>Linear</growthType>
|
||||
<linearGrowth>1.2</linearGrowth>
|
||||
</pointsGrowthPerWave>
|
||||
</ArachnaeSwarm.CustomRaidDef>
|
||||
<!-- 第一阶段波次池 -->
|
||||
<ArachnaeSwarm.RaidWavePoolDef>
|
||||
<defName>ARA_WavePool_Stage1</defName>
|
||||
<waves>
|
||||
<li>ARA_Wave_Scout_Patrol</li>
|
||||
<li>ARA_Wave_Assault_Team</li>
|
||||
<li>ARA_Wave_Acid_Swarm</li>
|
||||
<li>ARA_Wave_Heavy_Defense</li>
|
||||
<li>ARA_Wave_Mixed_Forces</li>
|
||||
</waves>
|
||||
<selectionWeights>
|
||||
<li>
|
||||
<key>ARA_Wave_Scout_Patrol</key>
|
||||
<value>0.25</value>
|
||||
</li>
|
||||
<li>
|
||||
<key>ARA_Wave_Assault_Team</key>
|
||||
<value>0.25</value>
|
||||
</li>
|
||||
<li>
|
||||
<key>ARA_Wave_Acid_Swarm</key>
|
||||
<value>0.20</value>
|
||||
</li>
|
||||
<li>
|
||||
<key>ARA_Wave_Heavy_Defense</key>
|
||||
<value>0.15</value>
|
||||
</li>
|
||||
<li>
|
||||
<key>ARA_Wave_Mixed_Forces</key>
|
||||
<value>0.15</value>
|
||||
</li>
|
||||
</selectionWeights>
|
||||
</ArachnaeSwarm.RaidWavePoolDef>
|
||||
|
||||
<!-- 波次1: 侦察巡逻队 -->
|
||||
<ArachnaeSwarm.RaidWaveDef>
|
||||
<defName>ARA_Wave_Scout_Patrol</defName>
|
||||
<label>侦察巡逻队</label>
|
||||
<description>一支小型侦察队伍,主要由远程单位组成,进行骚扰射击</description>
|
||||
<pawnComposition>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Shooter</pawnKind>
|
||||
<ratio>0.7</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>6</maxCount>
|
||||
<DefaultUnit>true</DefaultUnit>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Assault</pawnKind>
|
||||
<ratio>0.3</ratio>
|
||||
<minCount>1</minCount>
|
||||
<maxCount>3</maxCount>
|
||||
</li>
|
||||
</pawnComposition>
|
||||
</ArachnaeSwarm.RaidWaveDef>
|
||||
<!-- 波次2: 突击小队 -->
|
||||
<ArachnaeSwarm.RaidWaveDef>
|
||||
<defName>ARA_Wave_Assault_Team</defName>
|
||||
<label>突击小队</label>
|
||||
<description>以近战单位为主的快速突击队伍,擅长冲锋陷阵</description>
|
||||
<pawnComposition>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Assault</pawnKind>
|
||||
<ratio>0.6</ratio>
|
||||
<minCount>3</minCount>
|
||||
<maxCount>8</maxCount>
|
||||
<DefaultUnit>true</DefaultUnit>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Shooter</pawnKind>
|
||||
<ratio>0.4</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>4</maxCount>
|
||||
</li>
|
||||
</pawnComposition>
|
||||
</ArachnaeSwarm.RaidWaveDef>
|
||||
<!-- 波次3: 酸液虫群 -->
|
||||
<ArachnaeSwarm.RaidWaveDef>
|
||||
<defName>ARA_Wave_Acid_Swarm</defName>
|
||||
<label>酸液虫群</label>
|
||||
<description>大量酸噬种辅虫组成的虫海战术,数量庞大但个体脆弱</description>
|
||||
<pawnComposition>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_AcidSwarm</pawnKind>
|
||||
<ratio>0.8</ratio>
|
||||
<minCount>8</minCount>
|
||||
<maxCount>20</maxCount>
|
||||
<DefaultUnit>true</DefaultUnit>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Assault</pawnKind>
|
||||
<ratio>0.2</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>5</maxCount>
|
||||
</li>
|
||||
</pawnComposition>
|
||||
</ArachnaeSwarm.RaidWaveDef>
|
||||
<!-- 波次4: 重装防御 -->
|
||||
<ArachnaeSwarm.RaidWaveDef>
|
||||
<defName>ARA_Wave_Heavy_Defense</defName>
|
||||
<label>重装防御队</label>
|
||||
<description>以盾头种为主的防御型队伍,移动缓慢但防御力强</description>
|
||||
<pawnComposition>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Heavy</pawnKind>
|
||||
<ratio>0.5</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>6</maxCount>
|
||||
<DefaultUnit>true</DefaultUnit>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Shooter</pawnKind>
|
||||
<ratio>0.3</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>4</maxCount>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Acidling</pawnKind>
|
||||
<ratio>0.2</ratio>
|
||||
<minCount>3</minCount>
|
||||
<maxCount>8</maxCount>
|
||||
</li>
|
||||
</pawnComposition>
|
||||
<strategy>Defensive</strategy> <!-- 防御战术 -->
|
||||
</ArachnaeSwarm.RaidWaveDef>
|
||||
<!-- 波次5: 混合部队 -->
|
||||
<ArachnaeSwarm.RaidWaveDef>
|
||||
<defName>ARA_Wave_Mixed_Forces</defName>
|
||||
<label>混合部队</label>
|
||||
<description>均衡配置的混合部队,包含各种单位类型</description>
|
||||
<pawnComposition>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Assault</pawnKind>
|
||||
<ratio>0.3</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>5</maxCount>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Shooter</pawnKind>
|
||||
<ratio>0.3</ratio>
|
||||
<minCount>2</minCount>
|
||||
<maxCount>5</maxCount>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_Heavy</pawnKind>
|
||||
<ratio>0.2</ratio>
|
||||
<minCount>1</minCount>
|
||||
<maxCount>3</maxCount>
|
||||
</li>
|
||||
<li>
|
||||
<pawnKind>ARA_Raid_AcidSwarm</pawnKind>
|
||||
<ratio>0.2</ratio>
|
||||
<minCount>3</minCount>
|
||||
<maxCount>6</maxCount>
|
||||
<DefaultUnit>true</DefaultUnit>
|
||||
</li>
|
||||
</pawnComposition>
|
||||
<strategy>Balanced</strategy> <!-- 均衡战术 -->
|
||||
</ArachnaeSwarm.RaidWaveDef>
|
||||
|
||||
<!-- 事件定义 -->
|
||||
<IncidentDef>
|
||||
<defName>ARA_Raid_Incident</defName>
|
||||
<label>阿拉克涅虫群袭击</label>
|
||||
<workerClass>ArachnaeSwarm.IncidentWorker_CustomRaid</workerClass>
|
||||
<category>Special</category>
|
||||
<minRefireDays>5</minRefireDays>
|
||||
<baseChance>0</baseChance>
|
||||
<targetTags>
|
||||
<li>Map_PlayerHome</li>
|
||||
</targetTags>
|
||||
</IncidentDef>
|
||||
</Defs>
|
||||
144
1.6/1.6/Defs/PawnKindDef/ARA_Hostile_Hive_PawnKinds.xml
Normal file
144
1.6/1.6/Defs/PawnKindDef/ARA_Hostile_Hive_PawnKinds.xml
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Defs>
|
||||
<!-- 基础袭击者类型 -->
|
||||
<PawnKindDef Name="ARA_RaidBase" Abstract="True">
|
||||
<combatPower>150</combatPower>
|
||||
<isFighter>true</isFighter>
|
||||
<trader>false</trader>
|
||||
<chemicalAddictionChance>0</chemicalAddictionChance>
|
||||
<apparelIgnoreSeasons>true</apparelIgnoreSeasons>
|
||||
<forceNormalGearQuality>true</forceNormalGearQuality>
|
||||
<initialWillRange>99~99</initialWillRange>
|
||||
<initialResistanceRange>99~99</initialResistanceRange>
|
||||
<overrideDeathOnDownedChance>1</overrideDeathOnDownedChance>
|
||||
<forceDeathOnDowned>true</forceDeathOnDowned>
|
||||
<maxGenerationAge>2</maxGenerationAge>
|
||||
<minGenerationAge>1</minGenerationAge>
|
||||
<canBeScattered>false</canBeScattered>
|
||||
<defaultFactionType>ARA_Hostile_Hive</defaultFactionType>
|
||||
<techHediffsMoney>0</techHediffsMoney>
|
||||
<requiredWorkTags>
|
||||
<li>Violent</li>
|
||||
</requiredWorkTags>
|
||||
<moveSpeedFactorByTerrainTag>
|
||||
<li>
|
||||
<key>ARA_Creep</key>
|
||||
<value>3.0</value>
|
||||
</li>
|
||||
</moveSpeedFactorByTerrainTag>
|
||||
</PawnKindDef>
|
||||
|
||||
<!-- 传统类:以毒针、酸液和近战战士虫组成阵线,辅助以小辅虫 -->
|
||||
<!-- 近战突击单位 -->
|
||||
<PawnKindDef ParentName="ARA_RaidBase">
|
||||
<defName>ARA_Raid_Assault</defName>
|
||||
<label>阿拉克涅突击者</label>
|
||||
<race>ArachnaeNode_Race_Fighter</race>
|
||||
<combatPower>200</combatPower>
|
||||
<weaponTags>
|
||||
<li>ARA_Armed_Organ_Melee</li>
|
||||
</weaponTags>
|
||||
<apparelTags>
|
||||
<li>ARA_Inner</li>
|
||||
<li>ARA_Clothes</li>
|
||||
</apparelTags>
|
||||
<apparelMoney>200</apparelMoney>
|
||||
<weaponMoney>200</weaponMoney>
|
||||
<abilities>
|
||||
<li>ARA_BaseRace_Acid_Launcher</li>
|
||||
</abilities>
|
||||
</PawnKindDef>
|
||||
<!-- 远程射手单位 -->
|
||||
<PawnKindDef ParentName="ARA_RaidBase">
|
||||
<defName>ARA_Raid_Shooter</defName>
|
||||
<label>阿拉克涅射手</label>
|
||||
<race>ArachnaeNode_Race_Fighter</race>
|
||||
<combatPower>180</combatPower>
|
||||
<weaponTags>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<apparelTags>
|
||||
<li>ARA_Inner</li>
|
||||
</apparelTags>
|
||||
<apparelMoney>150</apparelMoney>
|
||||
<weaponMoney>400</weaponMoney>
|
||||
<techHediffsMoney>100</techHediffsMoney>
|
||||
<abilities>
|
||||
<li>ARA_Hibernate_Ability</li>
|
||||
</abilities>
|
||||
</PawnKindDef>
|
||||
<!-- 辅虫群单位 -->
|
||||
<PawnKindDef ParentName="ARA_RaidBase">
|
||||
<defName>ARA_Raid_AcidSwarm</defName>
|
||||
<label>阿拉克涅酸噬群</label>
|
||||
<combatPower>80</combatPower>
|
||||
<apparelMoney>0</apparelMoney>
|
||||
<weaponMoney>0</weaponMoney>
|
||||
<techHediffsMoney>0</techHediffsMoney>
|
||||
<race>ArachnaeBase_Race_Acidcut</race>
|
||||
<lifeStages>
|
||||
<li>
|
||||
<bodyGraphicData>
|
||||
<texPath>ArachnaeSwarm/Things/ARA_Acidcut/Bodies/Naked_Thin</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
<shadowData>
|
||||
<volume>(0.4, 0.5, 0.37)</volume>
|
||||
<offset>(0,0,-0.15)</offset>
|
||||
</shadowData>
|
||||
</bodyGraphicData>
|
||||
<dessicatedBodyGraphicData>
|
||||
<texPath>Things/Pawn/Animal/Spelopede/Dessicated_Spelopede</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
</dessicatedBodyGraphicData>
|
||||
</li>
|
||||
</lifeStages>
|
||||
</PawnKindDef>
|
||||
|
||||
<!-- 重装类:远近盾头混搭,辅以自杀辅虫和攻击辅虫 -->
|
||||
<!-- 重型单位,远近混搭 -->
|
||||
<PawnKindDef ParentName="ARA_RaidBase">
|
||||
<defName>ARA_Raid_Heavy</defName>
|
||||
<label>阿拉克涅重装兵</label>
|
||||
<race>ArachnaeNode_Race_ShieldHead</race>
|
||||
<combatPower>350</combatPower>
|
||||
<weaponTags>
|
||||
<li>ARA_Armed_Organ_Melee</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<apparelTags>
|
||||
<li>ARA_Inner</li>
|
||||
<li>ARA_Clothes</li>
|
||||
</apparelTags>
|
||||
<apparelMoney>400</apparelMoney>
|
||||
<weaponMoney>600</weaponMoney>
|
||||
<techHediffsMoney>0</techHediffsMoney>
|
||||
</PawnKindDef>
|
||||
<!-- 自杀辅虫群单位 -->
|
||||
<PawnKindDef ParentName="ARA_InsectKindBase">
|
||||
<defName>ARA_Raid_Acidling</defName>
|
||||
<label>阿拉克涅爆裂群</label>
|
||||
<race>ArachnaeBase_Race_Acidling</race>
|
||||
<combatPower>50</combatPower>
|
||||
<apparelMoney>0</apparelMoney>
|
||||
<weaponMoney>0</weaponMoney>
|
||||
<techHediffsMoney>0</techHediffsMoney>
|
||||
<lifeStages>
|
||||
<li>
|
||||
<bodyGraphicData>
|
||||
<texPath>ArachnaeSwarm/Things/ARA_Acidling/Bodies/Naked_Thin</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
<shadowData>
|
||||
<volume>(0.4, 0.5, 0.37)</volume>
|
||||
<offset>(0,0,-0.15)</offset>
|
||||
</shadowData>
|
||||
</bodyGraphicData>
|
||||
<dessicatedBodyGraphicData>
|
||||
<texPath>Things/Pawn/Animal/Spelopede/Dessicated_Spelopede</texPath>
|
||||
<drawSize>1</drawSize>
|
||||
</dessicatedBodyGraphicData>
|
||||
</li>
|
||||
</lifeStages>
|
||||
</PawnKindDef>
|
||||
</Defs>
|
||||
@@ -9,8 +9,14 @@
|
||||
<listOrder>20</listOrder>
|
||||
<comps>
|
||||
<!-- Intro -->
|
||||
<!-- <li Class="StorytellerCompProperties_OnOffCycle">
|
||||
<incident>ARA_Raid_Incident</incident>
|
||||
<onDays>1</onDays>
|
||||
<offDays>0</offDays>
|
||||
<minSpacingDays>0.01</minSpacingDays>
|
||||
<numIncidentsRange>1~2</numIncidentsRange>
|
||||
</li> -->
|
||||
<!-- <li Class="StorytellerCompProperties_ClassicIntro"/> -->
|
||||
<!-- 袭击生成器 -->
|
||||
<li Class="StorytellerCompProperties_OnOffCycle">
|
||||
<category>ThreatBig</category> <!-- 大型袭击 -->
|
||||
<minDaysPassed>15.0</minDaysPassed> <!-- 最低在15日后开始生成 -->
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<tools>
|
||||
</tools>
|
||||
<race>
|
||||
<!-- <nameGenerator>ARA_NamerHivePawnGeneric</nameGenerator> -->
|
||||
|
||||
<useMeatFrom>Megaspider</useMeatFrom>
|
||||
<thinkTreeMain>Humanlike</thinkTreeMain>
|
||||
<thinkTreeConstant>HumanlikeConstant</thinkTreeConstant>
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
|
||||
<cocoonDefs>
|
||||
<li>ARA_Cocoon_Medicine</li>
|
||||
<li>ARA_Cocoon_Medicine_From_Death</li>
|
||||
<li>ARA_BioforgeIncubator_Thing</li>
|
||||
</cocoonDefs>
|
||||
</li>
|
||||
@@ -87,6 +88,7 @@
|
||||
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
|
||||
<cocoonDefs>
|
||||
<li>ARA_Cocoon_Medicine</li>
|
||||
<li>ARA_Cocoon_Medicine_From_Death</li>
|
||||
<li>ARA_BioforgeIncubator_Thing</li>
|
||||
</cocoonDefs>
|
||||
</li>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Melee</li>
|
||||
<li>ARA_Armed_Organ_T1</li>
|
||||
<li>ARA_MW_Bone_Sword</li>
|
||||
</weaponTags>
|
||||
<graphicData>
|
||||
<texPath>ArachnaeSwarm/Weapon/ARA_MW_Bone_Sword</texPath>
|
||||
@@ -313,6 +314,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T1</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -427,6 +429,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -524,6 +527,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -637,6 +641,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Huge_Ranged_Needle</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -752,6 +757,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Needle</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -854,6 +860,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T1</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -969,6 +976,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Huge_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1118,6 +1126,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Huge_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1236,6 +1245,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T3</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1370,6 +1380,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T3</li>
|
||||
<li>ARA_Armed_Organ_Huge_Ranged_Acid</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1506,6 +1517,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T1</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_SP</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1658,6 +1670,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Small_Ranged_Energy</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
@@ -1764,6 +1777,7 @@
|
||||
<li>ARA_Armed_Organ</li>
|
||||
<li>ARA_Armed_Organ_Ranged</li>
|
||||
<li>ARA_Armed_Organ_T2</li>
|
||||
<li>ARA_Armed_Organ_Huge_Ranged_Energy</li>
|
||||
</weaponTags>
|
||||
<generateCommonality>0</generateCommonality>
|
||||
<tradeability>None</tradeability>
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>20</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -715,7 +715,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>20</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -804,7 +804,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>20</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -825,7 +825,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>20</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -922,7 +922,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>60</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -943,7 +943,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>60</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1035,7 +1035,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>60</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1056,7 +1056,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>60</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1145,7 +1145,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>110</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1166,7 +1166,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>110</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1279,7 +1279,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>0.2</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>110</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
@@ -1300,7 +1300,7 @@
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<initialFuelPercent>1</initialFuelPercent>
|
||||
<autoRefuelPercent>1</autoRefuelPercent>
|
||||
<initialConfigurableTargetFuelLevel>999</initialConfigurableTargetFuelLevel>
|
||||
<initialConfigurableTargetFuelLevel>110</initialConfigurableTargetFuelLevel>
|
||||
</li>
|
||||
</comps>
|
||||
</ThingDef>
|
||||
|
||||
@@ -71,9 +71,8 @@
|
||||
<fuelCapacity>20</fuelCapacity>
|
||||
<fuelConsumptionRate>0</fuelConsumptionRate>
|
||||
<consumeFuelOnlyWhenUsed>true</consumeFuelOnlyWhenUsed>
|
||||
<autoRefuelPercent>0</autoRefuelPercent>
|
||||
<autoRefuelPercent>-1</autoRefuelPercent>
|
||||
<initialAllowAutoRefuel>true</initialAllowAutoRefuel>
|
||||
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
|
||||
|
||||
<fuelFilter>
|
||||
<thingDefs>
|
||||
@@ -82,7 +81,7 @@
|
||||
</fuelFilter>
|
||||
|
||||
<targetFuelLevelConfigurable>false</targetFuelLevelConfigurable>
|
||||
<showAllowAutoRefuelToggle>true</showAllowAutoRefuelToggle>
|
||||
<showAllowAutoRefuelToggle>false</showAllowAutoRefuelToggle>
|
||||
<canEjectFuel>true</canEjectFuel>
|
||||
</li>
|
||||
|
||||
|
||||
Binary file not shown.
@@ -3,12 +3,8 @@
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\abilities\\compabilityeffect_transformcorpse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\compabilityeffect_transformcorpse.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
},
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\building_comps\\comprefuelablenutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\comprefuelablenutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\storyteller\\incidentworker_customraid.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:storyteller\\incidentworker_customraid.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
@@ -18,35 +14,23 @@
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": 2,
|
||||
"SelectedChildIndex": 1,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "CompRefuelableNutrition.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs",
|
||||
"RelativeDocumentMoniker": "Building_Comps\\CompRefuelableNutrition.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs",
|
||||
"RelativeToolTip": "Building_Comps\\CompRefuelableNutrition.cs",
|
||||
"ViewState": "AgIAABAAAAAAAAAAAAAuwBYAAAAhAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-15T08:04:45.513Z"
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompAbilityEffect_TransformCorpse.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_TransformCorpse.cs",
|
||||
"RelativeDocumentMoniker": "Abilities\\CompAbilityEffect_TransformCorpse.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\CompAbilityEffect_TransformCorpse.cs",
|
||||
"RelativeToolTip": "Abilities\\CompAbilityEffect_TransformCorpse.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABIAAABCAAAAAAAAAA==",
|
||||
"Title": "IncidentWorker_CustomRaid.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\IncidentWorker_CustomRaid.cs",
|
||||
"RelativeDocumentMoniker": "Storyteller\\IncidentWorker_CustomRaid.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Storyteller\\IncidentWorker_CustomRaid.cs",
|
||||
"RelativeToolTip": "Storyteller\\IncidentWorker_CustomRaid.cs",
|
||||
"ViewState": "AgIAAAYBAAAAAAAAAAAgwBYBAAAyAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2025-10-15T08:02:12.842Z",
|
||||
"WhenOpened": "2025-10-16T07:14:58.682Z",
|
||||
"EditorCaption": ""
|
||||
}
|
||||
]
|
||||
|
||||
@@ -120,6 +120,12 @@
|
||||
<Compile Include="EventSystem\Letter_EventChoice.cs" />
|
||||
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
|
||||
<Compile Include="Jobs\JobDriver_CarryPrisonerToRefuelingVat.cs" />
|
||||
<Compile Include="Storyteller\CustomRaidDef.cs" />
|
||||
<Compile Include="Storyteller\CustomRaidTracker.cs" />
|
||||
<Compile Include="Storyteller\IncidentParmsExtensions.cs" />
|
||||
<Compile Include="Storyteller\IncidentWorker_CustomRaid.cs" />
|
||||
<Compile Include="Storyteller\RaidWaveDef.cs" />
|
||||
<Compile Include="Storyteller\RaidWavePoolDef.cs" />
|
||||
<Compile Include="Verbs\Verb_ShootWithOffset.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowTemperatureRange\CompAbilityEffect_AbilityShowTemperatureRange.cs" />
|
||||
<Compile Include="Abilities\ARA_ShowTemperatureRange\CompProperties_AbilityShowTemperatureRange.cs" />
|
||||
|
||||
51
Source/ArachnaeSwarm/Storyteller/CustomRaidDef.cs
Normal file
51
Source/ArachnaeSwarm/Storyteller/CustomRaidDef.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CustomRaidDef : Def
|
||||
{
|
||||
public FactionDef factionDef;
|
||||
public List<PointWavePool> pointWavePools;
|
||||
public int baseRaidNembers;
|
||||
public PointsGrowthPerWave pointsGrowthPerWave;
|
||||
|
||||
public override IEnumerable<string> ConfigErrors()
|
||||
{
|
||||
foreach (string error in base.ConfigErrors())
|
||||
{
|
||||
yield return error;
|
||||
}
|
||||
|
||||
if (factionDef == null)
|
||||
{
|
||||
yield return "factionDef is not defined";
|
||||
}
|
||||
|
||||
if (pointWavePools.NullOrEmpty())
|
||||
{
|
||||
yield return "pointWavePools is empty";
|
||||
}
|
||||
|
||||
if (baseRaidNembers <= 0)
|
||||
{
|
||||
yield return "baseRaidNembers must be positive";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PointWavePool
|
||||
{
|
||||
public float minPoints;
|
||||
public float maxPoints = 99999f; // 默认值表示无上限
|
||||
public RaidWavePoolDef wavePool;
|
||||
}
|
||||
|
||||
public class PointsGrowthPerWave
|
||||
{
|
||||
public string growthType = "Linear"; // Linear/Exponential
|
||||
public float linearGrowth = 1f;
|
||||
public float exponentialBase = 1.15f;
|
||||
}
|
||||
}
|
||||
73
Source/ArachnaeSwarm/Storyteller/CustomRaidTracker.cs
Normal file
73
Source/ArachnaeSwarm/Storyteller/CustomRaidTracker.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class CustomRaidTracker : GameComponent
|
||||
{
|
||||
private Dictionary<string, int> waveCounters = new Dictionary<string, int>();
|
||||
|
||||
public CustomRaidTracker(Game game)
|
||||
{
|
||||
// 构造函数
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
Scribe_Collections.Look(ref waveCounters, "waveCounters", LookMode.Value, LookMode.Value);
|
||||
|
||||
// 如果waveCounters为null(加载旧存档时可能发生),初始化它
|
||||
if (waveCounters == null)
|
||||
{
|
||||
waveCounters = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
||||
|
||||
public int GetCurrentWave(CustomRaidDef raidDef)
|
||||
{
|
||||
if (raidDef == null)
|
||||
{
|
||||
Log.Warning("GetCurrentWave called with null raidDef");
|
||||
return 0;
|
||||
}
|
||||
|
||||
string key = raidDef.defName;
|
||||
if (!waveCounters.ContainsKey(key))
|
||||
{
|
||||
waveCounters[key] = 0;
|
||||
}
|
||||
|
||||
return waveCounters[key];
|
||||
}
|
||||
|
||||
public void IncrementWave(CustomRaidDef raidDef)
|
||||
{
|
||||
if (raidDef != null)
|
||||
{
|
||||
string key = raidDef.defName;
|
||||
int currentWave = GetCurrentWave(raidDef);
|
||||
waveCounters[key] = currentWave + 1;
|
||||
|
||||
Log.Message($"CustomRaidTracker: Incremented wave for {raidDef.defName} to {waveCounters[key]}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Warning("IncrementWave called with null raidDef");
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetWave(CustomRaidDef raidDef)
|
||||
{
|
||||
if (raidDef != null)
|
||||
{
|
||||
waveCounters[raidDef.defName] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetAllWaves()
|
||||
{
|
||||
waveCounters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
111
Source/ArachnaeSwarm/Storyteller/IncidentParmsExtensions.cs
Normal file
111
Source/ArachnaeSwarm/Storyteller/IncidentParmsExtensions.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using RimWorld;
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public static class IncidentParmsExtensions
|
||||
{
|
||||
// 使用静态字典来存储自定义数据
|
||||
private static Dictionary<IncidentParms, CustomRaidData> customRaidData = new Dictionary<IncidentParms, CustomRaidData>();
|
||||
|
||||
public class CustomRaidData
|
||||
{
|
||||
public RaidWaveDef WaveDef { get; set; }
|
||||
public int RaidSize { get; set; } = -1;
|
||||
public CustomRaidDef RaidDef { get; set; }
|
||||
public int WaveNumber { get; set; }
|
||||
}
|
||||
|
||||
public static void SetCustomRaidWave(this IncidentParms parms, RaidWaveDef waveDef)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
customRaidData[parms] = new CustomRaidData();
|
||||
|
||||
customRaidData[parms].WaveDef = waveDef;
|
||||
}
|
||||
|
||||
public static RaidWaveDef GetCustomRaidWave(this IncidentParms parms)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
return null;
|
||||
|
||||
return customRaidData[parms].WaveDef;
|
||||
}
|
||||
|
||||
public static void SetCustomRaidSize(this IncidentParms parms, int raidSize)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
customRaidData[parms] = new CustomRaidData();
|
||||
|
||||
customRaidData[parms].RaidSize = raidSize;
|
||||
}
|
||||
|
||||
public static int GetCustomRaidSize(this IncidentParms parms)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
return -1;
|
||||
|
||||
return customRaidData[parms].RaidSize;
|
||||
}
|
||||
|
||||
public static void SetCustomRaidDef(this IncidentParms parms, CustomRaidDef raidDef)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
customRaidData[parms] = new CustomRaidData();
|
||||
|
||||
customRaidData[parms].RaidDef = raidDef;
|
||||
}
|
||||
|
||||
public static CustomRaidDef GetCustomRaidDef(this IncidentParms parms)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
return null;
|
||||
|
||||
return customRaidData[parms].RaidDef;
|
||||
}
|
||||
|
||||
public static void SetCustomRaidWaveNumber(this IncidentParms parms, int waveNumber)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
customRaidData[parms] = new CustomRaidData();
|
||||
|
||||
customRaidData[parms].WaveNumber = waveNumber;
|
||||
}
|
||||
|
||||
public static int GetCustomRaidWaveNumber(this IncidentParms parms)
|
||||
{
|
||||
if (!customRaidData.ContainsKey(parms))
|
||||
return 0;
|
||||
|
||||
return customRaidData[parms].WaveNumber;
|
||||
}
|
||||
|
||||
public static bool IsCustomRaid(this IncidentParms parms)
|
||||
{
|
||||
return parms.GetCustomRaidWave() != null;
|
||||
}
|
||||
|
||||
// 清理方法,在事件完成后调用
|
||||
public static void ClearCustomData(this IncidentParms parms)
|
||||
{
|
||||
if (customRaidData.ContainsKey(parms))
|
||||
customRaidData.Remove(parms);
|
||||
}
|
||||
|
||||
// 批量清理方法,用于清理所有不再使用的 IncidentParms
|
||||
public static void CleanupOrphanedData()
|
||||
{
|
||||
// 这里可以添加逻辑来清理不再使用的 IncidentParms 引用
|
||||
// 例如,如果 IncidentParms 已经被销毁,我们可以从字典中移除
|
||||
// 由于 RimWorld 没有提供弱引用,这个清理可能需要手动触发
|
||||
// 或者定期调用
|
||||
}
|
||||
|
||||
// 获取所有存储的自定义数据(用于调试)
|
||||
public static int GetStoredDataCount()
|
||||
{
|
||||
return customRaidData.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
418
Source/ArachnaeSwarm/Storyteller/IncidentWorker_CustomRaid.cs
Normal file
418
Source/ArachnaeSwarm/Storyteller/IncidentWorker_CustomRaid.cs
Normal file
@@ -0,0 +1,418 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class IncidentWorker_CustomRaid : IncidentWorker_Raid
|
||||
{
|
||||
private CustomRaidTracker GetTracker()
|
||||
{
|
||||
if (Current.ProgramState != ProgramState.Playing) return null;
|
||||
|
||||
Game game = Current.Game;
|
||||
if (game == null) return null;
|
||||
|
||||
CustomRaidTracker tracker = game.GetComponent<CustomRaidTracker>();
|
||||
if (tracker == null)
|
||||
{
|
||||
tracker = new CustomRaidTracker(game);
|
||||
game.components.Add(tracker);
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
|
||||
protected override bool CanFireNowSub(IncidentParms parms)
|
||||
{
|
||||
// 获取自定义袭击定义
|
||||
CustomRaidDef raidDef = GetCustomRaidDef();
|
||||
if (raidDef == null)
|
||||
{
|
||||
Log.Warning("CustomRaidDef not found in CanFireNowSub");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查最小天数
|
||||
if (GenDate.DaysPassedSinceSettle < 15f) // 可以配置化
|
||||
{
|
||||
Log.Message($"Custom raid cannot fire: only {GenDate.DaysPassedSinceSettle} days passed, need 15");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查目标是否有效
|
||||
if (parms.target == null)
|
||||
{
|
||||
Log.Warning("Custom raid target is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查目标是否有有效的地图
|
||||
Map map = parms.target as Map;
|
||||
if (map == null)
|
||||
{
|
||||
Log.Warning("Custom raid target is not a Map or map is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查派系是否存在
|
||||
Faction faction = Find.FactionManager.FirstFactionOfDef(raidDef.factionDef);
|
||||
if (faction == null)
|
||||
{
|
||||
Log.Warning($"Faction {raidDef.factionDef?.defName} not found for custom raid");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.CanFireNowSub(parms);
|
||||
}
|
||||
|
||||
protected override bool TryExecuteWorker(IncidentParms parms)
|
||||
{
|
||||
Log.Message("=== Custom Raid Incident Started ===");
|
||||
|
||||
// 检查目标地图
|
||||
Map map = parms.target as Map;
|
||||
if (map == null)
|
||||
{
|
||||
Log.Error("Custom raid target is not a valid Map");
|
||||
return false;
|
||||
}
|
||||
|
||||
CustomRaidDef raidDef = GetCustomRaidDef();
|
||||
if (raidDef == null)
|
||||
{
|
||||
Log.Error("CustomRaidDef not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
CustomRaidTracker tracker = GetTracker();
|
||||
if (tracker == null)
|
||||
{
|
||||
Log.Error("CustomRaidTracker not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取当前波次
|
||||
int currentWave = tracker.GetCurrentWave(raidDef);
|
||||
Log.Message($"Current wave: {currentWave}");
|
||||
|
||||
// 计算袭击规模
|
||||
int raidSize = CalculateRaidSize(currentWave, raidDef);
|
||||
Log.Message($"Calculated raid size: {raidSize}");
|
||||
|
||||
// 选择波次定义
|
||||
RaidWaveDef waveDef = SelectWaveForSize(raidSize, raidDef);
|
||||
if (waveDef == null)
|
||||
{
|
||||
Log.Error($"No wave found for raid size {raidSize}");
|
||||
return false;
|
||||
}
|
||||
Log.Message($"Selected wave: {waveDef.defName}");
|
||||
|
||||
// 设置派系
|
||||
parms.faction = Find.FactionManager.FirstFactionOfDef(raidDef.factionDef);
|
||||
if (parms.faction == null)
|
||||
{
|
||||
Log.Error($"Faction {raidDef.factionDef.defName} not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 设置点数
|
||||
parms.points = CalculateThreatPoints(raidSize);
|
||||
Log.Message($"Threat points: {parms.points}");
|
||||
|
||||
// 设置袭击策略
|
||||
parms.raidStrategy = RaidStrategyDefOf.ImmediateAttack;
|
||||
|
||||
// 设置自定义参数
|
||||
parms.SetCustomRaidWave(waveDef);
|
||||
parms.SetCustomRaidSize(raidSize);
|
||||
parms.SetCustomRaidDef(raidDef);
|
||||
parms.SetCustomRaidWaveNumber(currentWave);
|
||||
|
||||
Log.Message($"Custom raid parameters set: wave={waveDef.defName}, size={raidSize}, waveNum={currentWave}");
|
||||
|
||||
// 执行袭击
|
||||
bool success = base.TryExecuteWorker(parms);
|
||||
|
||||
if (success)
|
||||
{
|
||||
// 成功执行后增加波次
|
||||
tracker.IncrementWave(raidDef);
|
||||
Log.Message($"Custom raid wave {currentWave + 1} executed successfully. Next wave will be {currentWave + 2}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("Custom raid execution failed");
|
||||
}
|
||||
|
||||
Log.Message("=== Custom Raid Incident Finished ===");
|
||||
return success;
|
||||
}
|
||||
|
||||
protected override bool TryResolveRaidFaction(IncidentParms parms)
|
||||
{
|
||||
// 对于自定义袭击,我们已经通过扩展设置了派系
|
||||
if (parms.faction != null)
|
||||
{
|
||||
Log.Message($"Raid faction resolved: {parms.faction.Name}");
|
||||
return true;
|
||||
}
|
||||
|
||||
// 如果没有设置派系,尝试从自定义袭击定义中获取
|
||||
CustomRaidDef raidDef = parms.GetCustomRaidDef();
|
||||
if (raidDef?.factionDef != null)
|
||||
{
|
||||
parms.faction = Find.FactionManager.FirstFactionOfDef(raidDef.factionDef);
|
||||
bool success = parms.faction != null;
|
||||
Log.Message($"Resolved faction from raidDef: {raidDef.factionDef.defName}, success: {success}");
|
||||
return success;
|
||||
}
|
||||
|
||||
Log.Warning("Could not resolve raid faction");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ResolveRaidStrategy(IncidentParms parms, PawnGroupKindDef groupKind)
|
||||
{
|
||||
// 如果已经设置了袭击策略,直接使用
|
||||
if (parms.raidStrategy != null)
|
||||
{
|
||||
Log.Message($"Raid strategy already set: {parms.raidStrategy.defName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从自定义波次定义中获取策略
|
||||
RaidWaveDef waveDef = parms.GetCustomRaidWave();
|
||||
if (waveDef != null)
|
||||
{
|
||||
// 这里可以根据 waveDef 的内容设置不同的策略
|
||||
// 例如,如果有特定标签就使用特定策略
|
||||
parms.raidStrategy = RaidStrategyDefOf.ImmediateAttack;
|
||||
Log.Message($"Set raid strategy from waveDef: {parms.raidStrategy.defName}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 默认策略
|
||||
parms.raidStrategy = RaidStrategyDefOf.ImmediateAttack;
|
||||
Log.Message($"Set default raid strategy: {parms.raidStrategy.defName}");
|
||||
}
|
||||
|
||||
protected override void ResolveRaidPoints(IncidentParms parms)
|
||||
{
|
||||
// 如果已经设置了点数,直接使用
|
||||
if (parms.points > 0)
|
||||
{
|
||||
Log.Message($"Raid points already set: {parms.points}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 从自定义袭击规模计算点数
|
||||
int raidSize = parms.GetCustomRaidSize();
|
||||
if (raidSize > 0)
|
||||
{
|
||||
parms.points = CalculateThreatPoints(raidSize);
|
||||
Log.Message($"Set raid points from custom size: {raidSize} -> {parms.points}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 回退到原版点数计算
|
||||
parms.points = StorytellerUtility.DefaultThreatPointsNow(parms.target);
|
||||
Log.Message($"Set raid points from default calculation: {parms.points}");
|
||||
}
|
||||
|
||||
protected override string GetLetterLabel(IncidentParms parms)
|
||||
{
|
||||
// 自定义袭击的信件标签
|
||||
RaidWaveDef waveDef = parms.GetCustomRaidWave();
|
||||
int waveNumber = parms.GetCustomRaidWaveNumber();
|
||||
CustomRaidDef raidDef = parms.GetCustomRaidDef();
|
||||
|
||||
if (waveDef != null && raidDef != null)
|
||||
{
|
||||
return $"Special Attack Wave {waveNumber + 1} - {waveDef.label ?? waveDef.defName}";
|
||||
}
|
||||
|
||||
return "Special Attack";
|
||||
}
|
||||
|
||||
protected override string GetLetterText(IncidentParms parms, List<Pawn> pawns)
|
||||
{
|
||||
// 自定义袭击的信件文本
|
||||
RaidWaveDef waveDef = parms.GetCustomRaidWave();
|
||||
int waveNumber = parms.GetCustomRaidWaveNumber();
|
||||
Faction faction = parms.faction;
|
||||
|
||||
string waveName = waveDef?.label ?? waveDef?.defName ?? "Unknown";
|
||||
string baseText = $"A special attack wave {waveNumber + 1} - {waveName} from {faction.Name} is approaching!";
|
||||
|
||||
// 添加袭击策略信息
|
||||
if (parms.raidStrategy != null)
|
||||
{
|
||||
baseText += "\n\n" + parms.raidStrategy.arrivalTextEnemy;
|
||||
}
|
||||
|
||||
return baseText;
|
||||
}
|
||||
|
||||
protected override LetterDef GetLetterDef()
|
||||
{
|
||||
// 使用威胁大的信件定义
|
||||
return LetterDefOf.ThreatBig;
|
||||
}
|
||||
|
||||
protected override string GetRelatedPawnsInfoLetterText(IncidentParms parms)
|
||||
{
|
||||
// 如果有相关pawn的信息,返回相应的文本
|
||||
return "LetterRelatedPawnsRaid".Translate(Faction.OfPlayer.def.pawnsPlural, parms.faction.def.pawnsPlural);
|
||||
}
|
||||
|
||||
// 自定义方法
|
||||
private CustomRaidDef GetCustomRaidDef()
|
||||
{
|
||||
// 从 DefDatabase 获取自定义袭击定义
|
||||
return DefDatabase<CustomRaidDef>.GetNamedSilentFail("ARA_SpecialAttack");
|
||||
}
|
||||
|
||||
private int CalculateRaidSize(int currentWave, CustomRaidDef raidDef)
|
||||
{
|
||||
int baseSize = raidDef.baseRaidNembers;
|
||||
var growthConfig = raidDef.pointsGrowthPerWave;
|
||||
|
||||
Log.Message($"Calculating raid size: base={baseSize}, wave={currentWave}, growthType={growthConfig.growthType}");
|
||||
|
||||
if (growthConfig.growthType == "Linear")
|
||||
{
|
||||
int result = baseSize + (int)(currentWave * growthConfig.linearGrowth);
|
||||
Log.Message($"Linear growth: {baseSize} + ({currentWave} * {growthConfig.linearGrowth}) = {result}");
|
||||
return result;
|
||||
}
|
||||
else if (growthConfig.growthType == "Exponential")
|
||||
{
|
||||
int result = (int)(baseSize * System.Math.Pow(growthConfig.exponentialBase, currentWave));
|
||||
Log.Message($"Exponential growth: {baseSize} * {growthConfig.exponentialBase}^{currentWave} = {result}");
|
||||
return result;
|
||||
}
|
||||
|
||||
// 默认线性增长
|
||||
int defaultResult = baseSize + currentWave;
|
||||
Log.Message($"Default growth: {baseSize} + {currentWave} = {defaultResult}");
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
private RaidWaveDef SelectWaveForSize(int raidSize, CustomRaidDef raidDef)
|
||||
{
|
||||
Log.Message($"Selecting wave for size: {raidSize}");
|
||||
|
||||
foreach (var poolRange in raidDef.pointWavePools)
|
||||
{
|
||||
bool minCondition = raidSize >= poolRange.minPoints;
|
||||
bool maxCondition = poolRange.maxPoints >= 99999f || raidSize < poolRange.maxPoints;
|
||||
|
||||
Log.Message($"Checking pool range: min={poolRange.minPoints}, max={poolRange.maxPoints}, matches={minCondition && maxCondition}");
|
||||
|
||||
if (minCondition && maxCondition)
|
||||
{
|
||||
var selectedWave = SelectWaveFromPool(poolRange.wavePool);
|
||||
Log.Message($"Selected wave from pool {poolRange.wavePool.defName}: {selectedWave?.defName}");
|
||||
return selectedWave;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有匹配的区间,返回最后一个池
|
||||
if (raidDef.pointWavePools.Count > 0)
|
||||
{
|
||||
var lastPool = raidDef.pointWavePools[raidDef.pointWavePools.Count - 1];
|
||||
var selectedWave = SelectWaveFromPool(lastPool.wavePool);
|
||||
Log.Message($"Selected wave from last pool {lastPool.wavePool.defName}: {selectedWave?.defName}");
|
||||
return selectedWave;
|
||||
}
|
||||
|
||||
Log.Error("No wave pools found in CustomRaidDef");
|
||||
return null;
|
||||
}
|
||||
|
||||
private RaidWaveDef SelectWaveFromPool(RaidWavePoolDef wavePool)
|
||||
{
|
||||
if (wavePool == null)
|
||||
{
|
||||
Log.Error("WavePool is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (wavePool.waves.NullOrEmpty())
|
||||
{
|
||||
Log.Error($"WavePool {wavePool.defName} has no waves");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果有权重配置,使用权重随机
|
||||
if (wavePool.selectionWeights != null && wavePool.selectionWeights.Count > 0)
|
||||
{
|
||||
var weightedWaves = wavePool.waves.Where(w => wavePool.selectionWeights.ContainsKey(w.defName)).ToList();
|
||||
if (weightedWaves.Any())
|
||||
{
|
||||
var selected = weightedWaves.RandomElementByWeight(waveDef => wavePool.selectionWeights[waveDef.defName]);
|
||||
Log.Message($"Selected weighted wave: {selected.defName}");
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
|
||||
// 否则均匀随机
|
||||
var randomWave = wavePool.waves.RandomElement();
|
||||
Log.Message($"Selected random wave: {randomWave.defName}");
|
||||
return randomWave;
|
||||
}
|
||||
|
||||
private float CalculateThreatPoints(int raidSize)
|
||||
{
|
||||
// 根据袭击规模计算威胁点数
|
||||
// 这里可以基于原版的威胁点数计算逻辑进行调整
|
||||
float points = raidSize * 100f;
|
||||
Log.Message($"Calculated threat points: {raidSize} * 100 = {points}");
|
||||
return points;
|
||||
}
|
||||
|
||||
// 重写生成pawn的方法,确保使用自定义波次定义
|
||||
public override void ResolveRaidArriveMode(IncidentParms parms)
|
||||
{
|
||||
if (parms.raidArrivalMode != null)
|
||||
{
|
||||
Log.Message($"Raid arrival mode already set: {parms.raidArrivalMode.defName}");
|
||||
return;
|
||||
}
|
||||
// 对于自定义袭击,默认使用边缘进入
|
||||
parms.raidArrivalMode = PawnsArrivalModeDefOf.EdgeWalkIn;
|
||||
Log.Message($"Set raid arrival mode: {parms.raidArrivalMode.defName}");
|
||||
}
|
||||
|
||||
// 可选:重写其他方法以提供更好的调试信息
|
||||
public override string ToString()
|
||||
{
|
||||
return base.ToString() + " (CustomRaid)";
|
||||
}
|
||||
|
||||
public static void TestCustomRaid()
|
||||
{
|
||||
Map map = Find.CurrentMap;
|
||||
if (map == null)
|
||||
{
|
||||
Log.Error("No current map found");
|
||||
return;
|
||||
}
|
||||
|
||||
IncidentDef raidIncident = DefDatabase<IncidentDef>.GetNamed("CustomRaidIncident");
|
||||
if (raidIncident != null)
|
||||
{
|
||||
var parms = StorytellerUtility.DefaultParmsNow(raidIncident.category, map);
|
||||
bool success = raidIncident.Worker.TryExecute(parms);
|
||||
Messages.Message(success ? "Custom raid test executed!" : "Custom raid test failed",
|
||||
success ? MessageTypeDefOf.PositiveEvent : MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error("CustomRaidIncident not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Source/ArachnaeSwarm/Storyteller/RaidWaveDef.cs
Normal file
37
Source/ArachnaeSwarm/Storyteller/RaidWaveDef.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class RaidWaveDef : Def
|
||||
{
|
||||
public List<PawnComposition> pawnComposition;
|
||||
|
||||
public override IEnumerable<string> ConfigErrors()
|
||||
{
|
||||
foreach (string error in base.ConfigErrors())
|
||||
{
|
||||
yield return error;
|
||||
}
|
||||
|
||||
if (pawnComposition.NullOrEmpty())
|
||||
{
|
||||
yield return "pawnComposition is empty";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PawnComposition
|
||||
{
|
||||
public PawnKindDef pawnKind;
|
||||
public float ratio = 1f;
|
||||
public int minCount = 0;
|
||||
public int maxCount = 0; // 0表示无限制
|
||||
public bool DefaultUnit = false;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{pawnKind?.defName ?? "null"} (ratio: {ratio}, min: {minCount}, max: {maxCount}, default: {DefaultUnit})";
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Source/ArachnaeSwarm/Storyteller/RaidWavePoolDef.cs
Normal file
24
Source/ArachnaeSwarm/Storyteller/RaidWavePoolDef.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class RaidWavePoolDef : Def
|
||||
{
|
||||
public List<RaidWaveDef> waves;
|
||||
public Dictionary<string, float> selectionWeights;
|
||||
|
||||
public override IEnumerable<string> ConfigErrors()
|
||||
{
|
||||
foreach (string error in base.ConfigErrors())
|
||||
{
|
||||
yield return error;
|
||||
}
|
||||
|
||||
if (waves.NullOrEmpty())
|
||||
{
|
||||
yield return "waves list is empty";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user