11
This commit is contained in:
Binary file not shown.
@@ -121,6 +121,36 @@
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
<AbilityDef>
|
||||
<defName>ARA_Suicide_Fast_Ability</defName>
|
||||
<label>自杀</label>
|
||||
<description>只要一声令下,阿拉克涅虫族随时可以为了虫巢的大业立刻死去</description>
|
||||
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Suicide_Ability</iconPath>
|
||||
<cooldownTicksRange>1</cooldownTicksRange>
|
||||
<aiCanUse>false</aiCanUse>
|
||||
<displayOrder>9900</displayOrder>
|
||||
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
|
||||
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
|
||||
<warmupStartSound>AcidSpray_Warmup</warmupStartSound>
|
||||
<verbProperties>
|
||||
<verbClass>Verb_CastAbility</verbClass>
|
||||
<range>24</range>
|
||||
<warmupTime>2</warmupTime>
|
||||
<soundCast>AcidSpray_Resolve</soundCast>
|
||||
<violent>false</violent>
|
||||
<targetable>false</targetable>
|
||||
<targetParams>
|
||||
<canTargetSelf>true</canTargetSelf>
|
||||
</targetParams>
|
||||
</verbProperties>
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AbilityDestroyOwnBodyPart">
|
||||
<bodyPartsToDestroy>
|
||||
<li>Brain</li>
|
||||
</bodyPartsToDestroy>
|
||||
</li>
|
||||
</comps>
|
||||
</AbilityDef>
|
||||
|
||||
<!-- 女皇 -->
|
||||
<AbilityDef>
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
</li>
|
||||
</moveSpeedFactorByTerrainTag>
|
||||
</PawnKindDef>
|
||||
<PawnKindDef Name="ArachnaeQueen_Colonist" ParentName="ArachnaeQueenBasePawnKind">
|
||||
<defName>ARA_ArachnaeQueen</defName>
|
||||
<PawnKindDef ParentName="ArachnaeQueenBasePawnKind">
|
||||
<defName>ArachnaeQueen_Race_Titan</defName>
|
||||
<label>阿拉克涅女皇种</label>
|
||||
<race>ArachnaeQueen_Race_Titan</race>
|
||||
<defaultFactionType>PlayerColony</defaultFactionType>
|
||||
@@ -64,6 +64,26 @@
|
||||
<li>ARA_TumorSpew</li>
|
||||
</abilities>
|
||||
</PawnKindDef>
|
||||
<PawnKindDef ParentName="ArachnaeQueenBasePawnKind">
|
||||
<defName>ArachnaeQueen_Race_Neurotyrant</defName>
|
||||
<label>阿拉克涅女皇种</label>
|
||||
<race>ArachnaeQueen_Race_Neurotyrant</race>
|
||||
<defaultFactionType>PlayerColony</defaultFactionType>
|
||||
<invNutrition>0</invNutrition>
|
||||
<backstoryFiltersOverride>
|
||||
<li>
|
||||
<categories>
|
||||
<li>ArachnaeQueen_spawnCategoriesA</li>
|
||||
<li>ArachnaeQueen_spawnCategoriesB</li>
|
||||
</categories>
|
||||
</li>
|
||||
</backstoryFiltersOverride>
|
||||
<apparelTags>
|
||||
</apparelTags>
|
||||
<apparelMoney>0</apparelMoney>
|
||||
<abilities>
|
||||
</abilities>
|
||||
</PawnKindDef>
|
||||
<AlienRace.RaceSettings>
|
||||
<defName>ArachnaeQueen_Race_TitanSettings</defName>
|
||||
<pawnKindSettings>
|
||||
@@ -72,7 +92,7 @@
|
||||
<pawnKindEntries>
|
||||
<li>
|
||||
<kindDefs>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
</kindDefs>
|
||||
<chance>100.0</chance>
|
||||
</li>
|
||||
@@ -87,7 +107,7 @@
|
||||
<pawnKindEntries>
|
||||
<li>
|
||||
<kindDefs>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
<li>ArachnaeNode_Race_ShieldHead</li>
|
||||
<li>ArachnaeNode_Race_WeaponSmith</li>
|
||||
<li>ArachnaeNode_Race_Fighter</li>
|
||||
@@ -110,7 +130,7 @@
|
||||
<alienslavekinds>
|
||||
<li>
|
||||
<kindDefs>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
<li>ArachnaeNode_Race_ShieldHead</li>
|
||||
<li>ArachnaeNode_Race_WeaponSmith</li>
|
||||
<li>ArachnaeNode_Race_Fighter</li>
|
||||
@@ -128,7 +148,7 @@
|
||||
<alienrefugeekinds>
|
||||
<li>
|
||||
<kindDefs>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
<li>ArachnaeNode_Race_ShieldHead</li>
|
||||
<li>ArachnaeNode_Race_WeaponSmith</li>
|
||||
<li>ArachnaeNode_Race_Fighter</li>
|
||||
@@ -444,6 +464,9 @@
|
||||
<value>3.0</value>
|
||||
</li>
|
||||
</moveSpeedFactorByTerrainTag>
|
||||
<abilities>
|
||||
<li>ARA_Suicide_Fast_Ability</li>
|
||||
</abilities>
|
||||
</PawnKindDef>
|
||||
<PawnKindDef ParentName="ARA_InsectKindBase">
|
||||
<defName>ArachnaeBase_Race_Larva</defName>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
<kindCounts>
|
||||
<li>
|
||||
<requiredAtStart>True</requiredAtStart>
|
||||
<kindDef>ARA_ArachnaeQueen</kindDef>
|
||||
<kindDef>ArachnaeQueen_Race_Titan</kindDef>
|
||||
</li>
|
||||
</kindCounts>
|
||||
</li>
|
||||
|
||||
@@ -675,7 +675,7 @@
|
||||
<showGizmoOnNonPlayerControlled>true</showGizmoOnNonPlayerControlled>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_PawnFlight">
|
||||
<flightCondition>Always</flightCondition>
|
||||
<flightCondition>DraftedAndMove</flightCondition>
|
||||
|
||||
<flyingAnimationNorth>ARA_Psi_FlyNorth</flyingAnimationNorth>
|
||||
<flyingAnimationEast>ARA_Psi_FlyNorth</flyingAnimationEast>
|
||||
|
||||
@@ -693,6 +693,11 @@
|
||||
</race>
|
||||
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>ARA_RaceBaseSwarmProduceSwitchHediff</disableHediff>
|
||||
<spawnEffecter>CocoonDestroyed</spawnEffecter>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_UniquePawn">
|
||||
<globalVariable>Unique_Arachnae_Queen</globalVariable>
|
||||
<showDeathMessage>true</showDeathMessage>
|
||||
@@ -786,11 +791,6 @@
|
||||
</tools>
|
||||
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>ARA_RaceBaseSwarmProduceSwitchHediff</disableHediff>
|
||||
<spawnEffecter>CocoonDestroyed</spawnEffecter>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AreaDamage">
|
||||
<radius>3</radius>
|
||||
<damageIntervalTicks>180</damageIntervalTicks>
|
||||
@@ -805,601 +805,58 @@
|
||||
</li>
|
||||
</comps>
|
||||
</AlienRace.ThingDef_AlienRace>
|
||||
<AlienRace.ThingDef_AlienRace Name="ARA_QueenBase" ParentName="ARA_PawnBase">
|
||||
<AlienRace.ThingDef_AlienRace ParentName="ARA_QueenBase">
|
||||
<defName>ArachnaeQueen_Race_Neurotyrant</defName>
|
||||
<label>阿拉克涅灵吸种</label>
|
||||
<description>阿拉克涅灵吸种是女皇种亚种之一,归属于阿拉克涅的灵能触须。她们负责维持虫族蜂巢灵能网路的通讯,并作为中继节点链接各战区女皇种和虫巢舰队。\n\n但是灵吸种可不是脆弱的“文官”,她们强大的灵能使得她们可以通过超自然力量主宰当地战局,随着她们不断吞噬本地物种,其灵能能力还能得到不断的进化。</description>
|
||||
|
||||
<alienRace>
|
||||
<!-- 核心设置 -->
|
||||
<generalSettings>
|
||||
<!-- 男性生成几率 -->
|
||||
<maleGenderProbability>0</maleGenderProbability>
|
||||
<!-- 无视年龄疾病 -->
|
||||
<immuneToAge>true</immuneToAge>
|
||||
<!-- 在口角中造成的最大伤害 -->
|
||||
<maxDamageForSocialfight>15</maxDamageForSocialfight>
|
||||
<!-- 免疫人类的异形歧视 -->
|
||||
<immuneToXenophobia>false</immuneToXenophobia>
|
||||
<!-- 最小的可生成成人背景的年龄 -->
|
||||
<minAgeForAdulthood>0</minAgeForAdulthood>
|
||||
<!-- 手术继承自人类 -->
|
||||
<humanRecipeImport>false</humanRecipeImport>
|
||||
<!-- 睡觉定义 -->
|
||||
<canLayDown>false</canLayDown>
|
||||
<!-- 各种零件定义 -->
|
||||
<alienPartGenerator Inherit="False">
|
||||
<!-- 允许的头部 -->
|
||||
<headTypes Inherit="False">
|
||||
<li>Female_AverageNormal</li>
|
||||
<!-- <li>Female_AverageWide</li>
|
||||
<li>Female_AveragePointy</li> -->
|
||||
</headTypes>
|
||||
<!-- 身体类型 -->
|
||||
<bodyTypes Inherit="False">
|
||||
<li>Thin</li>
|
||||
</bodyTypes>
|
||||
<!-- 颜色设置 -->
|
||||
<colorChannels Inherit="false">
|
||||
<!-- 皮肤是特殊的,因为现在由基因定义肤色 -->
|
||||
<li>
|
||||
<name>skin</name>
|
||||
<first Class="AlienRace.ColorGenerator_SkinColorMelanin">
|
||||
<minMelanin>0</minMelanin>
|
||||
<maxMelanin>0</maxMelanin>
|
||||
</first>
|
||||
</li>
|
||||
<!-- 头发颜色 -->
|
||||
<li>
|
||||
<name>hair</name>
|
||||
<first Class="ColorGenerator_Options">
|
||||
<options>
|
||||
<li>
|
||||
<weight>15</weight>
|
||||
<min>(0.4,0.3,0.5)</min>
|
||||
<max>(0.6,0.1,0.7)</max>
|
||||
</li>
|
||||
<li>
|
||||
<weight>6</weight>
|
||||
<min>(0.9,0.9,0.9)</min>
|
||||
<max>(0.9,0.9,0.9)</max>
|
||||
</li>
|
||||
<li>
|
||||
<weight>6</weight>
|
||||
<min>(1,0.8,0.8)</min>
|
||||
<max>(1,0.9,0.9)</max>
|
||||
</li>
|
||||
<li>
|
||||
<weight>3</weight>
|
||||
<min>(1,1,1)</min>
|
||||
<max>(1,1,1)</max>
|
||||
</li>
|
||||
</options>
|
||||
</first>
|
||||
</li>
|
||||
</colorChannels>
|
||||
<!-- 额外身体部件 -->
|
||||
<bodyAddons>
|
||||
</bodyAddons>
|
||||
<!-- 图像放大 -->
|
||||
<borderScale>4</borderScale>
|
||||
<atlasScale>4</atlasScale>
|
||||
<customDrawSize>(4,4)</customDrawSize>
|
||||
<customHeadDrawSize>(1.0,1.0)</customHeadDrawSize>
|
||||
<customPortraitDrawSize>(2,2)</customPortraitDrawSize>
|
||||
</alienPartGenerator>
|
||||
<growthAges Inherit="False">
|
||||
<li>0</li>
|
||||
</growthAges>
|
||||
<!-- 年龄工作效率等的覆盖 -->
|
||||
<ageStatOverrides Inherit="False">
|
||||
<WorkSpeedGlobal>
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0,1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</WorkSpeedGlobal>
|
||||
<ShootingAccuracyChildFactor MayRequire="Ludeon.RimWorld.Biotech">
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0,1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</ShootingAccuracyChildFactor>
|
||||
<MarketValue>
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0,1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</MarketValue>
|
||||
<MeleeHitChance>
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0,1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</MeleeHitChance>
|
||||
<AimingDelayFactor>
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0,1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</AimingDelayFactor>
|
||||
<ArrestSuccessChance>
|
||||
<useBiologicalYears>true</useBiologicalYears>
|
||||
<curve>
|
||||
<points>
|
||||
<li>(0, 1)</li>
|
||||
</points>
|
||||
</curve>
|
||||
</ArrestSuccessChance>
|
||||
</ageStatOverrides>
|
||||
<!-- 生育设置,将妊娠设为男性来避免开局刷妊娠 -->
|
||||
<reproduction>
|
||||
<gestatingGender>Male</gestatingGender>
|
||||
<femaleFertilityAgeFactor>
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1,0)</li>
|
||||
<li>(999,0)</li>
|
||||
<li>(9999,0)</li>
|
||||
</points>
|
||||
</femaleFertilityAgeFactor>
|
||||
</reproduction>
|
||||
<growthFactorByAge Inherit="False">
|
||||
<points>
|
||||
<li>(0,0)</li>
|
||||
<li>(1,0)</li>
|
||||
<li>(999,0)</li>
|
||||
<li>(9999,0)</li>
|
||||
</points>
|
||||
</growthFactorByAge>
|
||||
</generalSettings>
|
||||
<!-- 图形 -->
|
||||
<graphicPaths>
|
||||
<!-- 皮肤颜色 -->
|
||||
<skinColor>(1,1,1,1)</skinColor>
|
||||
<!-- 皮肤着色器 -->
|
||||
<skinShader>Cutout</skinShader>
|
||||
<body>ArachnaeSwarm/Things/ARA_HiveQueen/Bodies/</body>
|
||||
<head>ArachnaeSwarm/Things/ARA_HiveQueen/Heads/</head>
|
||||
<skeleton>Things/Pawn/Humanlike/Bodies/Dessicated/Dessicated_Thin</skeleton>
|
||||
<stump>ArachnaeSwarm/Things/ARA_HiveQueen/Bodies/</stump>
|
||||
</graphicPaths>
|
||||
<!-- 风格设置 -->
|
||||
<styleSettings>
|
||||
<!-- 头发 -->
|
||||
<li>
|
||||
<key>HairDef</key>
|
||||
<value>
|
||||
<hasStyle>true</hasStyle>
|
||||
<styleTagsOverride>
|
||||
<li>Bald</li>
|
||||
</styleTagsOverride>
|
||||
</value>
|
||||
</li>
|
||||
<!-- 纹身 -->
|
||||
<li>
|
||||
<key>TattooDef</key>
|
||||
<value>
|
||||
<hasStyle>false</hasStyle>
|
||||
</value>
|
||||
</li>
|
||||
<!-- 胡须 -->
|
||||
<li>
|
||||
<key>BeardDef</key>
|
||||
<value>
|
||||
<hasStyle>false</hasStyle>
|
||||
</value>
|
||||
</li>
|
||||
</styleSettings>
|
||||
<!-- 种族的允许和禁止特化设置 -->
|
||||
<raceRestriction>
|
||||
<!-- 无法拥有的内源性基因 -->
|
||||
<blackEndoCategories MayRequire="Ludeon.RimWorld.Biotech">
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">HairColor</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Melanin</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">BodyType</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Ears</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Nose</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Voice</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Headbone</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Head</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Jaw</li>
|
||||
</blackEndoCategories>
|
||||
<!-- 无法拥有的Tag基因 -->
|
||||
<blackGeneTags MayRequire="Ludeon.RimWorld.Biotech">
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">EyeColor</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Tail</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">BeardStyle</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Fur</li>
|
||||
</blackGeneTags>
|
||||
<!-- 无法拥有的基因列表 -->
|
||||
<blackGeneList>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Furskin</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Brow_Heavy</li>
|
||||
</blackGeneList>
|
||||
<!-- 禁止的异形变种 -->
|
||||
<blackXenotypeList>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Dirtmole</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Genie</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Hussar</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Sanguophage</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Neanderthal</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Pigskin</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Impid</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Waster</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Yttakin</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">Highmate</li>
|
||||
</blackXenotypeList>
|
||||
<!-- 异种类型列表 -->
|
||||
<xenotypeList>
|
||||
</xenotypeList>
|
||||
<onlyUseRaceRestrictedXenotypes>true</onlyUseRaceRestrictedXenotypes>
|
||||
<!-- 食物列表 -->
|
||||
<whiteFoodList>
|
||||
<li>ARA_InsectJelly</li>
|
||||
<li>ARA_NutrientPasteMeal</li>
|
||||
<li>ARA_PheromoneSolvent</li>
|
||||
</whiteFoodList>
|
||||
<onlyEatRaceRestrictedFood>true</onlyEatRaceRestrictedFood>
|
||||
<!-- 可以驯服的宠物,主要是防止小虫由别人驯服 -->
|
||||
<petList>
|
||||
<li>ArachnaeBase_Race_Scavenger</li>
|
||||
<li>ArachnaeBase_Race_Larva</li>
|
||||
</petList>
|
||||
<onlyTameRaceRestrictedPets>true</onlyTameRaceRestrictedPets>
|
||||
<!-- 可以穿戴的衣服 -->
|
||||
<apparelList>
|
||||
</apparelList>
|
||||
<blackApparelList>
|
||||
</blackApparelList>
|
||||
<!-- 仅使用种族限制的服装 -->
|
||||
<onlyUseRaceRestrictedApparel>true</onlyUseRaceRestrictedApparel>
|
||||
<!-- 生育能力 -->
|
||||
<onlyReproduceWithRestrictedRaces>true</onlyReproduceWithRestrictedRaces>
|
||||
<canReproduce>false</canReproduce>
|
||||
<!-- 允许操纵的配方 -->
|
||||
<recipeList>
|
||||
</recipeList>
|
||||
<!-- <workGiverList>
|
||||
</workGiverList> -->
|
||||
<!-- 允许的特质类型 -->
|
||||
<traitList>
|
||||
</traitList>
|
||||
<blackTraitList>
|
||||
<li>BodyPurist</li>
|
||||
<li>Cannibal</li>
|
||||
<li>CreepyBreathing</li>
|
||||
<li>DislikesWomen</li>
|
||||
<li>Gourmand</li>
|
||||
<li>QuickSleeper</li>
|
||||
<li>Wimp</li>
|
||||
<li>Beauty</li>
|
||||
<li>DrugDesire</li>
|
||||
<li>Immunity</li>
|
||||
<li>PsychicSensitivity</li>
|
||||
</blackTraitList>
|
||||
</raceRestriction>
|
||||
<!-- 想法设置 -->
|
||||
<thoughtSettings>
|
||||
<!-- 不会产生的想法 -->
|
||||
<cannotReceiveThoughts>
|
||||
<li>ColonistLost</li>
|
||||
<li>KnowColonistDied</li>
|
||||
<li>PawnWithGoodOpinionDied</li>
|
||||
<li>PsychicDrone</li>
|
||||
<li>Naked</li>
|
||||
<li>AnyBodyPartButGroinCovered_Disapproved_Female</li>
|
||||
<li>AnyBodyPartButGroinCovered_Disapproved_Male</li>
|
||||
<li>AnyBodyPartButGroinCovered_Disapproved_Memory</li>
|
||||
<li>AnyBodyPartButGroinCovered_Disapproved_Social_Female</li>
|
||||
<li>AnyBodyPartButGroinCovered_Disapproved_Social_Male</li>
|
||||
<li>AnyBodyPartCovered_Disapproved_Female</li>
|
||||
<li>AnyBodyPartCovered_Disapproved_Male</li>
|
||||
<li>AnyBodyPartCovered_Disapproved_Memory</li>
|
||||
<li>AnyBodyPartCovered_Disapproved_Social_Female</li>
|
||||
<li>AnyBodyPartCovered_Disapproved_Social_Male</li>
|
||||
<li>GroinChestHairOrFaceUncovered_Disapproved_Female</li>
|
||||
<li>GroinChestHairOrFaceUncovered_Disapproved_Male</li>
|
||||
<li>GroinChestHairOrFaceUncovered_Disapproved_Social_Female</li>
|
||||
<li>GroinChestHairOrFaceUncovered_Disapproved_Social_Male</li>
|
||||
<li>GroinChestOrHairUncovered_Disapproved_Female</li>
|
||||
<li>GroinChestOrHairUncovered_Disapproved_Male</li>
|
||||
<li>GroinChestOrHairUncovered_Disapproved_Social_Female</li>
|
||||
<li>GroinChestOrHairUncovered_Disapproved_Social_Male</li>
|
||||
<li>GroinOrChestUncovered_Disapproved_Female</li>
|
||||
<li>GroinOrChestUncovered_Disapproved_Male</li>
|
||||
<li>GroinOrChestUncovered_Disapproved_Social_Female</li>
|
||||
<li>GroinOrChestUncovered_Disapproved_Social_Male</li>
|
||||
<li>GroinUncovered_Disapproved_Female</li>
|
||||
<li>GroinUncovered_Disapproved_Male</li>
|
||||
<li>GroinUncovered_Disapproved_Social_Female</li>
|
||||
<li>GroinUncovered_Disapproved_Social_Male</li>
|
||||
<li>WitnessedDeathAlly</li>
|
||||
<li>ObservedLayingCorpse</li>
|
||||
<li>ObservedLayingRottingCorpse</li>
|
||||
<li>ApparelDamaged</li>
|
||||
<li>ProsthophileHappy</li>
|
||||
<li>ProsthophobeUnhappy</li>
|
||||
<li>BrawlerUnhappy</li>
|
||||
<li>PyromaniacHappy</li>
|
||||
<li>Greedy</li>
|
||||
<li>Jealous</li>
|
||||
<li>SharedBed</li>
|
||||
<li>AteWithoutTable</li>
|
||||
<li>SleptOutside</li>
|
||||
<li>SleptOnGround</li>
|
||||
<li>SleptInCold</li>
|
||||
<li>SleptInHeat</li>
|
||||
<li>Ugly</li>
|
||||
<li>AteKibble</li>
|
||||
<li>AteInsectMeatDirect</li>
|
||||
<li>AteInsectMeatAsIngredient</li>
|
||||
<li>AteRawFood</li>
|
||||
<li>AteHumanlikeMeatDirect</li>
|
||||
<li>AteHumanlikeMeatAsIngredient</li>
|
||||
<li>KnowButcheredHumanlikeCorpse</li>
|
||||
<li>ButcheredHumanlikeCorpseOpinion</li>
|
||||
<li>AteRawHumanlikeMeat</li>
|
||||
</cannotReceiveThoughts>
|
||||
<!-- 该种族特有想法 -->
|
||||
<restrictedThoughts>
|
||||
</restrictedThoughts>
|
||||
</thoughtSettings>
|
||||
<!-- 关系设置,不会生成任何随机关系 -->
|
||||
<relationSettings>
|
||||
<relationChanceModifierLover>0</relationChanceModifierLover>
|
||||
<relationChanceModifierExLover>0</relationChanceModifierExLover>
|
||||
|
||||
<relationChanceModifierFiance>0</relationChanceModifierFiance>
|
||||
<relationChanceModifierSpouse>0</relationChanceModifierSpouse>
|
||||
<relationChanceModifierExSpouse>0</relationChanceModifierExSpouse>
|
||||
|
||||
<relationChanceModifierParent>0</relationChanceModifierParent>
|
||||
<relationChanceModifierChild>0</relationChanceModifierChild>
|
||||
<relationChanceModifierSibling>0</relationChanceModifierSibling>
|
||||
</relationSettings>
|
||||
</alienRace>
|
||||
|
||||
<recipes Inherit="False">
|
||||
<li>ARA_CureBloodRot</li>
|
||||
<li>ARA_CureAcid</li>
|
||||
<li>RemovePorcupineQuill</li>
|
||||
<li>SurgicalInspection</li>
|
||||
<li>ARA_Surgery_Install_Plasteel</li>
|
||||
<li>ARA_Surgery_Install_Carapace_Shell</li>
|
||||
<li>ARA_Surgery_Install_Huge_Stomach</li>
|
||||
<li>ARA_Surgery_Install_Cycle_Suppression</li>
|
||||
<li>ARA_Surgery_Install_Shell_Thorn</li>
|
||||
<li>ARA_Surgery_Install_Reactive_Shell</li>
|
||||
<li>ARA_Surgery_Install_Strengthening_Tendon</li>
|
||||
<li>ARA_Surgery_Install_Slide_Patagium</li>
|
||||
<li>ARA_Surgery_Install_Baneling_Pouch</li>
|
||||
<li>ARA_Surgery_Install_Tumor_Pouch</li>
|
||||
<li>ARA_Surgery_Install_Internal_Circulation_Lung</li>
|
||||
</recipes>
|
||||
|
||||
<!-- 基础属性设置 -->
|
||||
<statBases>
|
||||
<!-- 市场价值 -->
|
||||
<MarketValue>2000</MarketValue>
|
||||
<RoyalFavorValue>5</RoyalFavorValue>
|
||||
|
||||
<!-- 移动速度 -->
|
||||
<MoveSpeed>1.75</MoveSpeed>
|
||||
<MoveSpeed>2.5</MoveSpeed>
|
||||
<Mass>250</Mass>
|
||||
|
||||
<!-- <RestRateMultiplier>1</RestRateMultiplier> -->
|
||||
<!-- <HungerRateMultiplier>1</HungerRateMultiplier> -->
|
||||
<EatingSpeed>2</EatingSpeed>
|
||||
<!-- 女皇很长时间才需要补充一次食物 -->
|
||||
<MaxNutrition>0.5</MaxNutrition>
|
||||
<MaxNutrition>1</MaxNutrition>
|
||||
|
||||
<!-- 女皇的负重,设为0以避免女皇能背东西 -->
|
||||
<CarryingCapacity>200</CarryingCapacity>
|
||||
<MeatAmount>450</MeatAmount>
|
||||
<LeatherAmount>600</LeatherAmount>
|
||||
<MeatAmount>350</MeatAmount>
|
||||
<LeatherAmount>300</LeatherAmount>
|
||||
|
||||
<!-- 疼痛休克,女皇很难因为疼痛而倒下,虽并不是像机器人一样不会休克 -->
|
||||
<PainShockThreshold>1</PainShockThreshold>
|
||||
<!-- 女皇非常擅长灵能,以维持蜂群的蜂巢意识链接 -->
|
||||
<PainShockThreshold>1.25</PainShockThreshold>
|
||||
<PsychicSensitivity>2.5</PsychicSensitivity>
|
||||
<!-- 女皇的崩溃概率 -->
|
||||
<MentalBreakThreshold>0</MentalBreakThreshold>
|
||||
<!-- 女皇的高耸身躯和强健循环系统使得很难被毒倒下 -->
|
||||
<ToxicResistance>0.95</ToxicResistance>
|
||||
<ToxicEnvironmentResistance MayRequire="Ludeon.RimWorld.Biotech">0.95</ToxicEnvironmentResistance>
|
||||
<!-- 女皇的甲壳可以抵御火焰侵袭,难以燃烧-->
|
||||
<Flammability>0.1</Flammability>
|
||||
<Flammability>0.2</Flammability>
|
||||
|
||||
<!-- 女皇的庞大申请很难闪开近战 -->
|
||||
<MeleeDodgeChance>0.25</MeleeDodgeChance>
|
||||
<!-- <MeleeHitChance>1</MeleeHitChance> -->
|
||||
<MeleeDodgeChance>0.4</MeleeDodgeChance>
|
||||
|
||||
<!-- <NegotiationAbility>1</NegotiationAbility> -->
|
||||
<!-- <SellPriceFactor>1</SellPriceFactor> -->
|
||||
<!-- <SocialImpact>1</SocialImpact> -->
|
||||
<!-- <TradePriceImprovement>0.5</TradePriceImprovement> -->
|
||||
<ArmorRating_Blunt>0.35</ArmorRating_Blunt>
|
||||
<ArmorRating_Sharp>0.35</ArmorRating_Sharp>
|
||||
<ArmorRating_Heat>0.25</ArmorRating_Heat>
|
||||
|
||||
<!-- 自带的甲壳可以防御外部攻击 -->
|
||||
<ArmorRating_Blunt>0.6</ArmorRating_Blunt>
|
||||
<ArmorRating_Sharp>0.8</ArmorRating_Sharp>
|
||||
<ArmorRating_Heat>0.5</ArmorRating_Heat>
|
||||
<InjuryHealingFactor>2</InjuryHealingFactor>
|
||||
|
||||
<!-- 虫群拥有惊人的愈合速度 -->
|
||||
<InjuryHealingFactor>5</InjuryHealingFactor>
|
||||
|
||||
<!-- 在野外采集的营养 -->
|
||||
<ForagedNutritionPerDay>0</ForagedNutritionPerDay>
|
||||
|
||||
<ARA_GestaltBandwidth>15</ARA_GestaltBandwidth>
|
||||
<ARA_GestaltBandwidth>18</ARA_GestaltBandwidth>
|
||||
<MechControlGroups>1</MechControlGroups>
|
||||
</statBases>
|
||||
|
||||
<race>
|
||||
<!-- 身体类型 -->
|
||||
<body>ArachnaeQueen_Body</body>
|
||||
<fleshType>Normal</fleshType>
|
||||
<!-- AI行为,勿改 -->
|
||||
<thinkTreeMain>ARA_Humanlike</thinkTreeMain>
|
||||
<!-- 智力水平 -->
|
||||
<intelligence>Humanlike</intelligence>
|
||||
<!-- 肉和皮革的定义 -->
|
||||
<nameCategory>HumanStandard</nameCategory>
|
||||
<bloodDef>Filth_BloodInsect</bloodDef>
|
||||
<bloodSmearDef>Filth_BloodSmear</bloodSmearDef>
|
||||
<!-- 身形大小 -->
|
||||
<baseBodySize>10</baseBodySize>
|
||||
<!-- 基础血量,很高 -->
|
||||
<baseHealthScale>10</baseHealthScale>
|
||||
<!-- 解剖产物 -->
|
||||
<leatherDef>ARA_Carapace</leatherDef>
|
||||
|
||||
<soundMeleeHitPawn>Pawn_Melee_BigBash_HitPawn</soundMeleeHitPawn>
|
||||
<soundMeleeHitBuilding>Pawn_Melee_BigBash_HitBuilding</soundMeleeHitBuilding>
|
||||
<soundMeleeMiss>Pawn_Melee_BigBash_Miss</soundMeleeMiss>
|
||||
<soundMeleeDodge>Pawn_MeleeDodge</soundMeleeDodge>
|
||||
<!-- 年龄阶段 -->
|
||||
<lifeExpectancy>300</lifeExpectancy>
|
||||
<lifeStageWorkSettings MayRequire="Ludeon.RimWorld.Biotech" Inherit="False">
|
||||
<Firefighter>0</Firefighter>
|
||||
<Patient>0</Patient>
|
||||
<Doctor>0</Doctor>
|
||||
<PatientBedRest>0</PatientBedRest>
|
||||
<Childcare MayRequire="Ludeon.RimWorld.Biotech">0</Childcare>
|
||||
<BasicWorker>0</BasicWorker>
|
||||
<Warden>0</Warden>
|
||||
<Handling>0</Handling>
|
||||
<Cooking>0</Cooking>
|
||||
<Hunting>0</Hunting>
|
||||
<Construction>0</Construction>
|
||||
<Growing>0</Growing>
|
||||
<Mining>0</Mining>
|
||||
<PlantCutting>0</PlantCutting>
|
||||
<Smithing>0</Smithing>
|
||||
<Tailoring>0</Tailoring>
|
||||
<Art>0</Art>
|
||||
<Crafting>0</Crafting>
|
||||
<Hauling>0</Hauling>
|
||||
<Cleaning>0</Cleaning>
|
||||
<Research>0</Research>
|
||||
<DarkStudy MayRequire="Ludeon.RimWorld.Anomaly">0</DarkStudy>
|
||||
</lifeStageWorkSettings>
|
||||
<lifeStageAges Inherit="False">
|
||||
<li>
|
||||
<def>HumanlikeBaby</def>
|
||||
<minAge>0</minAge>
|
||||
</li>
|
||||
<li>
|
||||
<def>HumanlikeChild</def>
|
||||
<minAge>0.25</minAge>
|
||||
</li>
|
||||
<li MayRequire="Ludeon.RimWorld.Biotech">
|
||||
<def>HumanlikePreTeenager</def>
|
||||
<minAge>0.5</minAge>
|
||||
</li>
|
||||
<li>
|
||||
<def>HumanlikeTeenager</def>
|
||||
<minAge>0.75</minAge>
|
||||
</li>
|
||||
<li>
|
||||
<def>HumanlikeAdult</def>
|
||||
<minAge>1</minAge>
|
||||
<soundWounded>Pawn_HiveQueen_Wounded</soundWounded>
|
||||
<soundDeath>Pawn_HiveQueen_Death</soundDeath>
|
||||
<soundCall>Pawn_HiveQueen_Call</soundCall>
|
||||
<soundAngry>Pawn_HiveQueen_Angry</soundAngry>
|
||||
</li>
|
||||
</lifeStageAges>
|
||||
<canFlyInVacuum>false</canFlyInVacuum>
|
||||
<baseBodySize>5</baseBodySize>
|
||||
<baseHealthScale>4</baseHealthScale>
|
||||
<canFlyInVacuum>true</canFlyInVacuum>
|
||||
</race>
|
||||
|
||||
<!-- 工具设置(攻击方式) -->
|
||||
<tools>
|
||||
<li>
|
||||
<label>头顶</label>
|
||||
<capacities>
|
||||
<li>Poke</li>
|
||||
</capacities>
|
||||
<power>16</power>
|
||||
<cooldownTime>2</cooldownTime>
|
||||
<linkedBodyPartsGroup>HeadAttackTool</linkedBodyPartsGroup>
|
||||
<ensureLinkedBodyPartsGroupAlwaysUsable>true</ensureLinkedBodyPartsGroupAlwaysUsable>
|
||||
<chanceFactor>0.01</chanceFactor>
|
||||
</li>
|
||||
<li>
|
||||
<label>踩踏</label>
|
||||
<capacities>
|
||||
<li>Blunt</li>
|
||||
<li>Poke</li>
|
||||
</capacities>
|
||||
<power>35</power>
|
||||
<cooldownTime>2.5</cooldownTime>
|
||||
<linkedBodyPartsGroup>Legs</linkedBodyPartsGroup>
|
||||
</li>
|
||||
<li>
|
||||
<label>腿部穿刺</label>
|
||||
<capacities>
|
||||
<li>Stab</li>
|
||||
</capacities>
|
||||
<power>50</power>
|
||||
<cooldownTime>3</cooldownTime>
|
||||
<linkedBodyPartsGroup>Legs</linkedBodyPartsGroup>
|
||||
</li>
|
||||
<li>
|
||||
<label>钳击</label>
|
||||
<capacities>
|
||||
<li>Cut</li>
|
||||
</capacities>
|
||||
<power>30</power>
|
||||
<cooldownTime>2</cooldownTime>
|
||||
<linkedBodyPartsGroup>Hands</linkedBodyPartsGroup>
|
||||
</li>
|
||||
</tools>
|
||||
|
||||
<comps>
|
||||
<li Class="ArachnaeSwarm.CompProperties_UniquePawn">
|
||||
<globalVariable>Unique_Arachnae_Queen</globalVariable>
|
||||
<showDeathMessage>true</showDeathMessage>
|
||||
<deathMessageKey>ARA_QueenAlreadyExists</deathMessageKey>
|
||||
<!-- <killDamageDef>AcidBurn</killDamageDef> -->
|
||||
<li Class="ArachnaeSwarm.CompProperties_PawnFlight">
|
||||
<flightCondition>DraftedAndMove</flightCondition>
|
||||
|
||||
<flyingAnimationNorth>ARA_Psi_FlyNorth</flyingAnimationNorth>
|
||||
<flyingAnimationEast>ARA_Psi_FlyEast</flyingAnimationEast>
|
||||
<flyingAnimationSouth>ARA_Psi_FlySouth</flyingAnimationSouth>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_HediffGiver">
|
||||
<hediffs>
|
||||
<li>ARA_HiveStrength</li>
|
||||
<li>ARA_HiveMindMaster</li>
|
||||
</hediffs>
|
||||
<addChance>1.0</addChance>
|
||||
<allowDuplicates>false</allowDuplicates>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AutoMechCarrier">
|
||||
<freeProduction>true</freeProduction>
|
||||
<disableHediff>ARA_RaceBaseSwarmProduceSwitchHediff</disableHediff>
|
||||
<spawnEffecter>CocoonDestroyed</spawnEffecter>
|
||||
</li>
|
||||
<li Class="ArachnaeSwarm.CompProperties_AreaDamage">
|
||||
<radius>3</radius>
|
||||
<damageIntervalTicks>180</damageIntervalTicks>
|
||||
<damageDef>Crush</damageDef>
|
||||
<damageAmount>10</damageAmount>
|
||||
<scaleWithPsychicSensitivity>false</scaleWithPsychicSensitivity>
|
||||
<areaEffecterDef>ARA_Area_Crush</areaEffecterDef>
|
||||
<startEnabled>false</startEnabled>
|
||||
<toggleLabel>践踏</toggleLabel>
|
||||
<toggleDescription>这只阿拉克涅虫族的身躯是如此巨大,以至于靠近它的敌人会被直接一脚踩死</toggleDescription>
|
||||
<toggleIconPath>ArachnaeSwarm/UI/Abilities/ARA_Area_Crush</toggleIconPath>
|
||||
</li>
|
||||
<!-- 添加 Gestalt 组件 -->
|
||||
<li Class="ArachnaeSwarm.CompProperties_Gestalt" />
|
||||
</comps>
|
||||
</AlienRace.ThingDef_AlienRace>
|
||||
</Defs>
|
||||
@@ -76,7 +76,7 @@
|
||||
</li>
|
||||
</spawnablePawns>
|
||||
<whitelist>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
</whitelist>
|
||||
<destroyOnSpawn>true</destroyOnSpawn>
|
||||
</li>
|
||||
@@ -124,12 +124,12 @@
|
||||
<li Class="ArachnaeSwarm.CompProperties_SpawnPawnFromList">
|
||||
<spawnablePawns>
|
||||
<li>
|
||||
<pawnKind>ARA_ArachnaeQueen</pawnKind>
|
||||
<pawnKind>ArachnaeQueen_Race_Titan</pawnKind>
|
||||
<delayTicks>180000</delayTicks>
|
||||
</li>
|
||||
</spawnablePawns>
|
||||
<!-- <whitelist>
|
||||
<li>ARA_ArachnaeQueen</li>
|
||||
<li>ArachnaeQueen_Race_Titan</li>
|
||||
</whitelist> -->
|
||||
<destroyOnSpawn>true</destroyOnSpawn>
|
||||
</li>
|
||||
|
||||
Binary file not shown.
@@ -1,7 +1,28 @@
|
||||
{
|
||||
"Version": 1,
|
||||
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
|
||||
"Documents": [],
|
||||
"Documents": [
|
||||
{
|
||||
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_uniquepawn\\compuniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compuniquepawn.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\\pawn_comps\\ara_uniquepawn\\uniquepawnmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\uniquepawnmanager.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\\pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_uniquepawn\\compproperties_uniquepawn.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\\pawn_comps\\ara_flight\\pawn_flighttrackerpatches.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\pawn_flighttrackerpatches.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\\pawn_comps\\ara_flight\\compproperties_pawnflight.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
|
||||
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_flight\\compproperties_pawnflight.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
|
||||
}
|
||||
],
|
||||
"DocumentGroupContainers": [
|
||||
{
|
||||
"Orientation": 0,
|
||||
@@ -9,8 +30,73 @@
|
||||
"DocumentGroups": [
|
||||
{
|
||||
"DockedWidth": 200,
|
||||
"SelectedChildIndex": -1,
|
||||
"SelectedChildIndex": 1,
|
||||
"Children": [
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 1,
|
||||
"Title": "UniquePawnManager.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\UniquePawnManager.cs",
|
||||
"ViewState": "AgIAAIIBAAAAAAAAAAAtwJUBAAANAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-01-28T09:15:15.046Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 0,
|
||||
"Title": "CompUniquePawn.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompUniquePawn.cs",
|
||||
"ViewState": "AgIAAFwAAAAAAAAAAAApwHcAAAANAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-01-28T09:15:14.392Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 2,
|
||||
"Title": "CompProperties_UniquePawn.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_UniquePawn\\CompProperties_UniquePawn.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAAAAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-01-28T09:15:09.995Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 3,
|
||||
"Title": "Pawn_FlightTrackerPatches.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\Pawn_FlightTrackerPatches.cs",
|
||||
"ViewState": "AgIAAC8AAAAAAAAAAAAawEEAAAAQAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-01-28T08:32:19.011Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Document",
|
||||
"DocumentIndex": 4,
|
||||
"Title": "CompProperties_PawnFlight.cs",
|
||||
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
|
||||
"RelativeDocumentMoniker": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
|
||||
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
|
||||
"RelativeToolTip": "Pawn_Comps\\ARA_Flight\\CompProperties_PawnFlight.cs",
|
||||
"ViewState": "AgIAAAAAAAAAAAAAAAAuwAgAAAAWAAAAAAAAAA==",
|
||||
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
|
||||
"WhenOpened": "2026-01-28T08:30:19.937Z",
|
||||
"EditorCaption": ""
|
||||
},
|
||||
{
|
||||
"$type": "Bookmark",
|
||||
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
|
||||
|
||||
@@ -361,14 +361,14 @@
|
||||
<Compile Include="Pawn_Comps\ARA_TrainingWork\CompAdvancedTraining.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Clean\JobGiver_Cleaner.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Clean\ThinkNode_ConditionalAnimalShouldDoCleaningWork.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompProperties_UniquePawn.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompUniquePawn.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\UniquePawnManager.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_ArachnaeClean.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Plant\JobGiver_Grower.cs" />
|
||||
<Compile Include="Jobs\JobDriver_Plant\ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_ArachnaeSow.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_TrainingWork\TrainingSystem_Patcher.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompProperties_UniquePawn.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\CompUniquePawn.cs" />
|
||||
<Compile Include="Pawn_Comps\ARA_UniquePawn\Patch_UniquePawn.cs" />
|
||||
<Compile Include="Placeworker\CompProperties_CustomRadius.cs" />
|
||||
<Compile Include="Plants\Plant_Transforming.cs" />
|
||||
<Compile Include="PowerArmor\ARA_PowerArmor.cs" />
|
||||
@@ -439,6 +439,7 @@
|
||||
<Compile Include="WorkGivers\WorkGiver_StripChitin.cs" />
|
||||
<Compile Include="WorkGivers\WorkGiver_SwarmMaintain.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- 自定义清理任务,删除obj文件夹中的临时文件 -->
|
||||
<Target Name="CleanDebugFiles" AfterTargets="Build">
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace ArachnaeSwarm
|
||||
public enum FlightCondition
|
||||
{
|
||||
Drafted,
|
||||
DraftedAndMove,
|
||||
Always
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
shouldBeFlying = true;
|
||||
}
|
||||
else if (compProps.flightCondition == FlightCondition.DraftedAndMove && ___pawn.Drafted || ___pawn.pather.MovingNow)
|
||||
{
|
||||
shouldBeFlying = true;
|
||||
}
|
||||
else if (compProps.flightCondition == FlightCondition.Drafted && ___pawn.Drafted)
|
||||
{
|
||||
shouldBeFlying = true;
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompProperties_UniquePawn : CompProperties
|
||||
{
|
||||
// 全局变量的唯一标识符
|
||||
// 唯一标识符
|
||||
public string globalVariable;
|
||||
|
||||
// 可选:杀死pawn时是否显示消息
|
||||
@@ -15,6 +15,12 @@ namespace ArachnaeSwarm
|
||||
|
||||
// 可选:杀死pawn的方式
|
||||
public DamageDef killDamageDef = null;
|
||||
|
||||
// 验证间隔(ticks)
|
||||
public int verificationInterval = 300;
|
||||
|
||||
// 是否启用调试日志
|
||||
public bool enableDebugLogging = false;
|
||||
|
||||
public CompProperties_UniquePawn()
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
@@ -6,30 +6,61 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
public class CompUniquePawn : ThingComp
|
||||
{
|
||||
#region 字段
|
||||
private bool _checked = false;
|
||||
private bool _scheduledForCheck = false;
|
||||
private int _lastVerificationTick = -1;
|
||||
private const int VERIFICATION_SIGNAL_INTERVAL = 300; // 每5秒发送一次验证信号
|
||||
#endregion
|
||||
|
||||
#region 属性
|
||||
public CompProperties_UniquePawn Props => (CompProperties_UniquePawn)this.props;
|
||||
|
||||
public string GlobalVariable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Props == null || string.IsNullOrEmpty(Props.globalVariable))
|
||||
{
|
||||
Log.Warning("CompUniquePawn: Props.globalVariable is null or empty");
|
||||
return null;
|
||||
}
|
||||
return Props.globalVariable;
|
||||
}
|
||||
}
|
||||
|
||||
public int SpawnTick { get; private set; } = -1;
|
||||
#endregion
|
||||
|
||||
#region 生命周期方法
|
||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||
{
|
||||
base.PostSpawnSetup(respawningAfterLoad);
|
||||
|
||||
// 基本安全检查
|
||||
if (this.parent == null || !(this.parent is Pawn pawn) || !pawn.Spawned)
|
||||
return;
|
||||
|
||||
// 只在首次生成时检查,不是加载存档时
|
||||
if (respawningAfterLoad || _checked || _scheduledForCheck)
|
||||
// 记录生成时间
|
||||
if (SpawnTick < 0)
|
||||
SpawnTick = Find.TickManager.TicksGame;
|
||||
|
||||
// 如果是重新生成,检查是否有效
|
||||
if (respawningAfterLoad)
|
||||
{
|
||||
HandleRespawnAfterLoad(pawn);
|
||||
return;
|
||||
}
|
||||
|
||||
// 首次生成时检查
|
||||
if (_checked || _scheduledForCheck)
|
||||
return;
|
||||
|
||||
// 确保属性有效
|
||||
if (this.props == null || string.IsNullOrEmpty(Props?.globalVariable))
|
||||
if (string.IsNullOrEmpty(GlobalVariable))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
// 延迟整个检查过程到下一帧
|
||||
// 延迟检查
|
||||
_scheduledForCheck = true;
|
||||
|
||||
LongEventHandler.QueueLongEvent(() =>
|
||||
@@ -45,50 +76,135 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in delayed unique pawn check: {ex}");
|
||||
Log.Error($"Error in delayed unique pawn check: {ex}");
|
||||
_scheduledForCheck = false;
|
||||
}
|
||||
}, "ArachnaeSwarm_UniquePawnCheck", false, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in CompUniquePawn.PostSpawnSetup: {ex}");
|
||||
Log.Error($"Error in CompUniquePawn.PostSpawnSetup: {ex}");
|
||||
_scheduledForCheck = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void CompTick()
|
||||
{
|
||||
base.CompTick();
|
||||
|
||||
// 定期发送验证信号
|
||||
if (Find.TickManager.TicksGame - _lastVerificationTick > VERIFICATION_SIGNAL_INTERVAL)
|
||||
{
|
||||
SendVerificationSignal();
|
||||
_lastVerificationTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
}
|
||||
|
||||
public override void PostDestroy(DestroyMode mode, Map previousMap)
|
||||
{
|
||||
base.PostDestroy(mode, previousMap);
|
||||
|
||||
// Pawn被销毁时注销
|
||||
if (this.parent is Pawn pawn && !string.IsNullOrEmpty(GlobalVariable))
|
||||
{
|
||||
UniquePawnManager.Instance?.UnregisterPawn(pawn, GlobalVariable);
|
||||
}
|
||||
}
|
||||
|
||||
public void PostDeSpawn(Map map)
|
||||
{
|
||||
// Pawn被反生成时也注销
|
||||
if (this.parent is Pawn pawn && !string.IsNullOrEmpty(GlobalVariable))
|
||||
{
|
||||
UniquePawnManager.Instance?.UnregisterPawn(pawn, GlobalVariable);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 公共方法
|
||||
/// <summary>
|
||||
/// 发送验证信号给管理器
|
||||
/// </summary>
|
||||
public void SendVerificationSignal()
|
||||
{
|
||||
if (this.parent is Pawn pawn && !string.IsNullOrEmpty(GlobalVariable) && pawn.Spawned && !pawn.Destroyed)
|
||||
{
|
||||
UniquePawnManager.Instance?.SendVerificationSignal(pawn, GlobalVariable);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否是有效的唯一Pawn
|
||||
/// </summary>
|
||||
public bool IsValidUniquePawn()
|
||||
{
|
||||
if (this.parent is Pawn pawn && !string.IsNullOrEmpty(GlobalVariable))
|
||||
{
|
||||
return UniquePawnManager.Instance?.IsEarliestPawn(pawn, GlobalVariable) ?? false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 私有方法
|
||||
private void CheckAndHandleUniquePawn(Pawn pawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
string variable = Props.globalVariable;
|
||||
string variable = GlobalVariable;
|
||||
|
||||
if (string.IsNullOrEmpty(variable))
|
||||
{
|
||||
ArachnaeLog.Debug("CompUniquePawn: globalVariable is null or empty");
|
||||
Log.Error("CompUniquePawn: globalVariable is null or empty");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查变量是否已存在
|
||||
if (GlobalVariableManager.HasVariable(variable))
|
||||
// 向管理器注册
|
||||
bool registered = UniquePawnManager.Instance.RegisterPawn(pawn, variable);
|
||||
|
||||
if (!registered)
|
||||
{
|
||||
// 变量已存在,杀死pawn
|
||||
// 注册失败,说明有更早的Pawn存在
|
||||
KillPawn(pawn, variable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 变量不存在,添加变量
|
||||
GlobalVariableManager.SetVariable(variable);
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"Added global variable '{variable}' for pawn {pawn.Label}");
|
||||
}
|
||||
Log.Message($"[唯一Pawn系统] 成功注册Pawn: {pawn.Label} (变量: {variable})");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in CheckAndHandleUniquePawn: {ex}");
|
||||
Log.Error($"Error in CheckAndHandleUniquePawn: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRespawnAfterLoad(Pawn pawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
string variable = GlobalVariable;
|
||||
|
||||
if (string.IsNullOrEmpty(variable))
|
||||
return;
|
||||
|
||||
// 检查是否仍然是最早的Pawn
|
||||
bool isEarliest = UniquePawnManager.Instance?.IsEarliestPawn(pawn, variable) ?? false;
|
||||
|
||||
if (!isEarliest)
|
||||
{
|
||||
// 有更早的Pawn存在,杀死当前Pawn
|
||||
KillPawn(pawn, variable);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 重新发送验证信号
|
||||
SendVerificationSignal();
|
||||
_checked = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"Error in HandleRespawnAfterLoad: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,16 +218,13 @@ namespace ArachnaeSwarm
|
||||
string deathMessage = Props.deathMessageKey.Translate(pawn.Label, variable);
|
||||
if (!string.IsNullOrEmpty(deathMessage))
|
||||
{
|
||||
Messages.Message(deathMessage, MessageTypeDefOf.NegativeEvent);
|
||||
Messages.Message(deathMessage, pawn, MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"Killing pawn {pawn.Label} because global variable '{variable}' already exists");
|
||||
}
|
||||
Log.Message($"[唯一Pawn系统] 移除重复Pawn: {pawn.Label} (变量: {variable})");
|
||||
|
||||
// 使用更安全的延迟执行
|
||||
// 延迟执行杀死操作
|
||||
LongEventHandler.QueueLongEvent(() =>
|
||||
{
|
||||
try
|
||||
@@ -131,21 +244,24 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in delayed pawn kill: {ex}");
|
||||
Log.Error($"Error in delayed pawn kill: {ex}");
|
||||
}
|
||||
}, "ArachnaeSwarm_KillDuplicatePawn", false, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in KillPawn: {ex}");
|
||||
Log.Error($"Error in KillPawn: {ex}");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override void PostExposeData()
|
||||
#region 序列化
|
||||
public void ExposeData()
|
||||
{
|
||||
base.PostExposeData();
|
||||
Scribe_Values.Look(ref _checked, "checked", false);
|
||||
Scribe_Values.Look(ref _scheduledForCheck, "scheduledForCheck", false);
|
||||
Scribe_Values.Look(ref _lastVerificationTick, "lastVerificationTick", -1);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,299 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
[StaticConstructorOnStartup]
|
||||
public static class ModInit
|
||||
{
|
||||
static ModInit()
|
||||
{
|
||||
var harmony = new Harmony("ArachnaeSwarm.Mod");
|
||||
harmony.PatchAll();
|
||||
|
||||
// 初始化全局变量管理器
|
||||
GlobalVariableManager.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Game), "ExposeData")]
|
||||
public static class Game_ExposeData_Patch
|
||||
{
|
||||
public static void Postfix(Game __instance)
|
||||
{
|
||||
GlobalVariableManager.ExposeData();
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:在游戏开始或结束时清理变量
|
||||
[HarmonyPatch(typeof(Game), "InitNewGame")]
|
||||
public static class Game_InitNewGame_Patch
|
||||
{
|
||||
public static void Postfix()
|
||||
{
|
||||
// 新游戏开始时清理所有变量
|
||||
GlobalVariableManager.ClearAllVariables();
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug("GlobalVariableManager: Cleared all variables for new game");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:在游戏加载时确保变量正确
|
||||
[HarmonyPatch(typeof(Game), "LoadGame")]
|
||||
public static class Game_LoadGame_Patch
|
||||
{
|
||||
public static void Postfix()
|
||||
{
|
||||
// 确保变量管理器已初始化
|
||||
GlobalVariableManager.Initialize();
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug("GlobalVariableManager: Initialized for loaded game");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 新增:在返回主菜单时清理变量
|
||||
[HarmonyPatch(typeof(Game), "FinalizeInit")]
|
||||
public static class Game_FinalizeInit_Patch
|
||||
{
|
||||
public static void Postfix()
|
||||
{
|
||||
// 确保变量管理器已初始化
|
||||
GlobalVariableManager.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
// 复活拦截补丁
|
||||
[HarmonyPatch]
|
||||
public static class ResurrectionUtility_Patch
|
||||
{
|
||||
private static MethodInfo TargetMethod()
|
||||
{
|
||||
// 尝试找到复活方法
|
||||
return AccessTools.Method("ResurrectionUtility:TryResurrect") ??
|
||||
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrect");
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static bool Prefix(Pawn pawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查 pawn 是否有 CompUniquePawn 组件
|
||||
var comp = pawn?.GetComp<CompUniquePawn>();
|
||||
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
|
||||
{
|
||||
string variable = comp.Props.globalVariable;
|
||||
|
||||
// 如果全局变量已存在,阻止复活
|
||||
if (GlobalVariableManager.HasVariable(variable))
|
||||
{
|
||||
// 显示阻止复活的消息
|
||||
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
|
||||
{
|
||||
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
|
||||
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
|
||||
{
|
||||
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
|
||||
}
|
||||
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
|
||||
}
|
||||
|
||||
// __result = false; // void methods cannot return a value
|
||||
return false; // 跳过原始方法
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in resurrection prevention: {ex}");
|
||||
}
|
||||
|
||||
return true; // 继续执行原始方法
|
||||
}
|
||||
}
|
||||
|
||||
// 带副作用的复活拦截补丁
|
||||
[HarmonyPatch]
|
||||
public static class ResurrectionUtility_Patch2
|
||||
{
|
||||
private static MethodInfo TargetMethod()
|
||||
{
|
||||
// 尝试找到带副作用的复活方法
|
||||
return AccessTools.Method("ResurrectionUtility:TryResurrectWithSideEffects") ??
|
||||
AccessTools.Method("RimWorld.ResurrectionUtility:TryResurrectWithSideEffects");
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
public static bool Prefix(Pawn pawn)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 检查 pawn 是否有 CompUniquePawn 组件
|
||||
if (pawn == null) return true;
|
||||
var comp = pawn.GetComp<CompUniquePawn>();
|
||||
if (comp != null && !string.IsNullOrEmpty(comp.Props?.globalVariable))
|
||||
{
|
||||
string variable = comp.Props.globalVariable;
|
||||
|
||||
// 如果全局变量已存在,阻止复活
|
||||
if (GlobalVariableManager.HasVariable(variable))
|
||||
{
|
||||
// 显示阻止复活的消息
|
||||
if (comp.Props.showDeathMessage && !string.IsNullOrEmpty(comp.Props.deathMessageKey))
|
||||
{
|
||||
string preventMessage = "ARA_ResurrectionPrevented".Translate(pawn.Label, variable);
|
||||
if (string.IsNullOrEmpty(preventMessage) || preventMessage == "ARA_ResurrectionPrevented")
|
||||
{
|
||||
preventMessage = "无法复活 {0},因为 {1} 已经存在。".Translate(pawn.Label, variable);
|
||||
}
|
||||
Messages.Message(preventMessage, MessageTypeDefOf.NegativeEvent);
|
||||
}
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"阻止复活 {pawn.Label},因为全局变量 '{variable}' 已存在");
|
||||
}
|
||||
|
||||
// __result = false; // void methods cannot return a value
|
||||
return false; // 跳过原始方法
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in resurrection prevention: {ex}");
|
||||
}
|
||||
|
||||
return true; // 继续执行原始方法
|
||||
}
|
||||
}
|
||||
|
||||
public static class GlobalVariableManager
|
||||
{
|
||||
private static HashSet<string> _globalVariables;
|
||||
private static bool _initialized = false;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!_initialized)
|
||||
{
|
||||
_globalVariables = new HashSet<string>();
|
||||
_initialized = true;
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug("GlobalVariableManager: Initialized");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExposeData()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 确保在保存或加载前已初始化
|
||||
Initialize();
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.Saving)
|
||||
{
|
||||
if (_globalVariables.Count > 0)
|
||||
{
|
||||
List<string> variablesList = new List<string>(_globalVariables);
|
||||
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"GlobalVariableManager: Saved {_globalVariables.Count} variables");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Scribe.mode == LoadSaveMode.LoadingVars)
|
||||
{
|
||||
List<string> variablesList = null;
|
||||
Scribe_Collections.Look(ref variablesList, "ArachnaeSwarm_GlobalVariables", LookMode.Value);
|
||||
|
||||
if (variablesList != null)
|
||||
{
|
||||
_globalVariables = new HashSet<string>(variablesList);
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"GlobalVariableManager: Loaded {_globalVariables.Count} variables");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_globalVariables = new HashSet<string>();
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug("GlobalVariableManager: No variables found in save, initializing empty set");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
ArachnaeLog.Debug($"Error in GlobalVariableManager.ExposeData: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool HasVariable(string variable)
|
||||
{
|
||||
Initialize();
|
||||
return _globalVariables.Contains(variable);
|
||||
}
|
||||
|
||||
public static void SetVariable(string variable)
|
||||
{
|
||||
Initialize();
|
||||
_globalVariables.Add(variable);
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"GlobalVariableManager: Added variable '{variable}'");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool RemoveVariable(string variable)
|
||||
{
|
||||
Initialize();
|
||||
bool removed = _globalVariables.Remove(variable);
|
||||
|
||||
if (removed && Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"GlobalVariableManager: Removed variable '{variable}'");
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetAllVariables()
|
||||
{
|
||||
Initialize();
|
||||
return _globalVariables;
|
||||
}
|
||||
|
||||
public static void ClearAllVariables()
|
||||
{
|
||||
Initialize();
|
||||
int count = _globalVariables.Count;
|
||||
_globalVariables.Clear();
|
||||
|
||||
if (Prefs.DevMode)
|
||||
{
|
||||
ArachnaeLog.Debug($"GlobalVariableManager: Cleared {count} variables");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,459 @@
|
||||
using RimWorld;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
/// <summary>
|
||||
/// 唯一Pawn管理器
|
||||
/// 管理所有具有唯一标识的Pawn,确保同一标识只有一个存活
|
||||
/// </summary>
|
||||
public class UniquePawnManager : GameComponent
|
||||
{
|
||||
#region 单例和静态访问
|
||||
private static UniquePawnManager _instance;
|
||||
public static UniquePawnManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null && Current.Game != null)
|
||||
{
|
||||
_instance = Current.Game.GetComponent<UniquePawnManager>();
|
||||
if (_instance == null)
|
||||
{
|
||||
_instance = new UniquePawnManager(Current.Game);
|
||||
Current.Game.components.Add(_instance);
|
||||
}
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 数据定义
|
||||
/// <summary>
|
||||
/// Pawn注册信息
|
||||
/// </summary>
|
||||
public class UniquePawnInfo : IExposable
|
||||
{
|
||||
public string globalVariable;
|
||||
public int thingID;
|
||||
public int spawnTick;
|
||||
public Map map;
|
||||
public string pawnName;
|
||||
public bool isValid = true;
|
||||
public int lastVerificationTick = -1;
|
||||
|
||||
public void ExposeData()
|
||||
{
|
||||
Scribe_Values.Look(ref globalVariable, "globalVariable");
|
||||
Scribe_Values.Look(ref thingID, "thingID");
|
||||
Scribe_Values.Look(ref spawnTick, "spawnTick");
|
||||
Scribe_References.Look(ref map, "map");
|
||||
Scribe_Values.Look(ref pawnName, "pawnName");
|
||||
Scribe_Values.Look(ref isValid, "isValid", true);
|
||||
Scribe_Values.Look(ref lastVerificationTick, "lastVerificationTick", -1);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 字段
|
||||
private List<UniquePawnInfo> registeredPawns = new List<UniquePawnInfo>();
|
||||
private int lastVerificationTick = -1;
|
||||
private const int VERIFICATION_INTERVAL = 600; // 每10秒验证一次
|
||||
private const int VERIFICATION_TIMEOUT = 1200; // 20秒无响应视为失效
|
||||
private object syncLock = new object();
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
public UniquePawnManager(Game game) : base()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
if (registeredPawns == null)
|
||||
registeredPawns = new List<UniquePawnInfo>();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 公共接口
|
||||
/// <summary>
|
||||
/// 注册唯一Pawn
|
||||
/// </summary>
|
||||
public bool RegisterPawn(Pawn pawn, string globalVariable)
|
||||
{
|
||||
if (pawn == null || string.IsNullOrEmpty(globalVariable))
|
||||
{
|
||||
Log.Warning("尝试注册空Pawn或空全局变量");
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
// 清理无效注册
|
||||
CleanupInvalidRegistrations();
|
||||
|
||||
// 获取当前tick
|
||||
int currentTick = Find.TickManager.TicksGame;
|
||||
|
||||
// 检查是否已存在相同全局变量的Pawn
|
||||
var existingInfos = GetInfosForVariable(globalVariable);
|
||||
var validExistingInfos = existingInfos.Where(info => info.isValid).ToList();
|
||||
|
||||
// 如果有有效的已注册Pawn
|
||||
if (validExistingInfos.Count > 0)
|
||||
{
|
||||
// 按生成时间排序,保留最早的
|
||||
var earliestInfo = validExistingInfos.OrderBy(info => info.spawnTick).First();
|
||||
|
||||
// 如果当前Pawn不是最早的,则杀死
|
||||
if (earliestInfo.thingID != pawn.thingIDNumber)
|
||||
{
|
||||
Log.Message($"[唯一Pawn系统] 检测到重复Pawn: {pawn.Label} (变量: {globalVariable})");
|
||||
Log.Message($"[唯一Pawn系统] 保留最早Pawn: {earliestInfo.pawnName} (生成于tick: {earliestInfo.spawnTick})");
|
||||
|
||||
// 杀死当前Pawn
|
||||
KillDuplicatePawn(pawn, globalVariable, earliestInfo.pawnName);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 当前Pawn就是最早的,更新验证时间
|
||||
var info = registeredPawns.FirstOrDefault(i => i.globalVariable == globalVariable && i.thingID == pawn.thingIDNumber);
|
||||
if (info != null)
|
||||
{
|
||||
info.lastVerificationTick = currentTick;
|
||||
info.isValid = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 创建新注册信息
|
||||
var newInfo = new UniquePawnInfo
|
||||
{
|
||||
globalVariable = globalVariable,
|
||||
thingID = pawn.thingIDNumber,
|
||||
spawnTick = currentTick,
|
||||
map = pawn.Map,
|
||||
pawnName = pawn.Label,
|
||||
isValid = true,
|
||||
lastVerificationTick = currentTick
|
||||
};
|
||||
|
||||
registeredPawns.Add(newInfo);
|
||||
Log.Message($"[唯一Pawn系统] 注册新Pawn: {pawn.Label} (变量: {globalVariable}, ID: {pawn.thingIDNumber})");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销Pawn
|
||||
/// </summary>
|
||||
public void UnregisterPawn(Pawn pawn, string globalVariable)
|
||||
{
|
||||
if (pawn == null || string.IsNullOrEmpty(globalVariable))
|
||||
return;
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
var info = registeredPawns.FirstOrDefault(i =>
|
||||
i.globalVariable == globalVariable &&
|
||||
i.thingID == pawn.thingIDNumber);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
info.isValid = false;
|
||||
Log.Message($"[唯一Pawn系统] 注销Pawn: {pawn.Label} (变量: {globalVariable})");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送验证信号
|
||||
/// </summary>
|
||||
public void SendVerificationSignal(Pawn pawn, string globalVariable)
|
||||
{
|
||||
if (pawn == null || string.IsNullOrEmpty(globalVariable) || pawn.Destroyed || !pawn.Spawned)
|
||||
return;
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
var info = registeredPawns.FirstOrDefault(i =>
|
||||
i.globalVariable == globalVariable &&
|
||||
i.thingID == pawn.thingIDNumber);
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
info.lastVerificationTick = Find.TickManager.TicksGame;
|
||||
info.isValid = true;
|
||||
info.map = pawn.Map;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pawn未注册,尝试重新注册
|
||||
RegisterPawn(pawn, globalVariable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Pawn是否是最早的
|
||||
/// </summary>
|
||||
public bool IsEarliestPawn(Pawn pawn, string globalVariable)
|
||||
{
|
||||
if (pawn == null || string.IsNullOrEmpty(globalVariable))
|
||||
return false;
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
var existingInfos = GetInfosForVariable(globalVariable);
|
||||
var validExistingInfos = existingInfos.Where(info => info.isValid).ToList();
|
||||
|
||||
if (validExistingInfos.Count == 0)
|
||||
return true;
|
||||
|
||||
var earliestInfo = validExistingInfos.OrderBy(info => info.spawnTick).First();
|
||||
return earliestInfo.thingID == pawn.thingIDNumber;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定变量的所有Pawn信息
|
||||
/// </summary>
|
||||
public List<UniquePawnInfo> GetInfosForVariable(string globalVariable)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
return registeredPawns.Where(info => info.globalVariable == globalVariable).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取调试信息
|
||||
/// </summary>
|
||||
public string GetDebugInfo()
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
sb.AppendLine("=== 唯一Pawn管理器调试信息 ===");
|
||||
sb.AppendLine($"已注册Pawn数量: {registeredPawns.Count}");
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
var grouped = registeredPawns
|
||||
.Where(info => info.isValid)
|
||||
.GroupBy(info => info.globalVariable)
|
||||
.OrderBy(g => g.Key);
|
||||
|
||||
foreach (var group in grouped)
|
||||
{
|
||||
sb.AppendLine($"变量: {group.Key}");
|
||||
var ordered = group.OrderBy(info => info.spawnTick).ToList();
|
||||
|
||||
for (int i = 0; i < ordered.Count; i++)
|
||||
{
|
||||
var info = ordered[i];
|
||||
string status = i == 0 ? "[最早]" : "[重复]";
|
||||
int ageTicks = Find.TickManager.TicksGame - info.spawnTick;
|
||||
int lastVerifyAgo = Find.TickManager.TicksGame - info.lastVerificationTick;
|
||||
|
||||
sb.AppendLine($" {status} {info.pawnName} (ID: {info.thingID})");
|
||||
sb.AppendLine($" 生成时间: {info.spawnTick} ({ageTicks} ticks前)");
|
||||
sb.AppendLine($" 最后验证: {info.lastVerificationTick} ({lastVerifyAgo} ticks前)");
|
||||
sb.AppendLine($" 地图: {info.map?.Index ?? -1}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 内部方法
|
||||
/// <summary>
|
||||
/// 清理无效注册
|
||||
/// </summary>
|
||||
private void CleanupInvalidRegistrations()
|
||||
{
|
||||
int currentTick = Find.TickManager.TicksGame;
|
||||
int removedCount = 0;
|
||||
|
||||
for (int i = registeredPawns.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var info = registeredPawns[i];
|
||||
|
||||
// 移除无效的
|
||||
if (!info.isValid)
|
||||
{
|
||||
registeredPawns.RemoveAt(i);
|
||||
removedCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查超时
|
||||
if (info.lastVerificationTick > 0 &&
|
||||
currentTick - info.lastVerificationTick > VERIFICATION_TIMEOUT)
|
||||
{
|
||||
// 尝试查找Pawn
|
||||
Pawn pawn = FindPawnByID(info.thingID, info.map);
|
||||
if (pawn == null || pawn.Destroyed || !pawn.Spawned)
|
||||
{
|
||||
info.isValid = false;
|
||||
registeredPawns.RemoveAt(i);
|
||||
removedCount++;
|
||||
Log.Message($"[唯一Pawn系统] 清理超时Pawn: {info.pawnName} (变量: {info.globalVariable})");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pawn仍然存在,更新验证时间
|
||||
info.lastVerificationTick = currentTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过ID查找Pawn
|
||||
/// </summary>
|
||||
private Pawn FindPawnByID(int thingID, Map map)
|
||||
{
|
||||
if (map == null || thingID <= 0)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return map.listerThings.ThingsInGroup(ThingRequestGroup.Pawn)
|
||||
.OfType<Pawn>()
|
||||
.FirstOrDefault(p => p.thingIDNumber == thingID);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"查找Pawn失败: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 杀死重复的Pawn
|
||||
/// </summary>
|
||||
private void KillDuplicatePawn(Pawn pawn, string globalVariable, string earliestPawnName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (pawn == null || pawn.Destroyed || !pawn.Spawned)
|
||||
return;
|
||||
|
||||
// 显示死亡消息
|
||||
string deathMessage = $"{pawn.Label} 被移除,因为 {earliestPawnName} 是更早生成的唯一Pawn ({globalVariable})";
|
||||
Messages.Message(deathMessage, pawn, MessageTypeDefOf.NegativeEvent);
|
||||
|
||||
// 使用安全的杀死方法
|
||||
pawn.Kill(null);
|
||||
|
||||
Log.Message($"[唯一Pawn系统] 移除重复Pawn: {pawn.Label} (变量: {globalVariable})");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"杀死重复Pawn失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 定期验证所有Pawn
|
||||
/// </summary>
|
||||
private void VerifyAllPawns()
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
int currentTick = Find.TickManager.TicksGame;
|
||||
int verifiedCount = 0;
|
||||
int timeoutCount = 0;
|
||||
|
||||
foreach (var info in registeredPawns.Where(i => i.isValid))
|
||||
{
|
||||
// 查找Pawn
|
||||
Pawn pawn = FindPawnByID(info.thingID, info.map);
|
||||
|
||||
if (pawn == null || pawn.Destroyed || !pawn.Spawned)
|
||||
{
|
||||
// Pawn已不存在
|
||||
info.isValid = false;
|
||||
timeoutCount++;
|
||||
}
|
||||
else if (currentTick - info.lastVerificationTick > VERIFICATION_INTERVAL)
|
||||
{
|
||||
// 需要发送验证请求
|
||||
SendVerificationRequest(pawn, info.globalVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
verifiedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 清理无效的
|
||||
CleanupInvalidRegistrations();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送验证请求给Pawn
|
||||
/// </summary>
|
||||
private void SendVerificationRequest(Pawn pawn, string globalVariable)
|
||||
{
|
||||
// 这里可以发送信号或事件给Pawn
|
||||
// 为了简化,我们直接更新验证时间
|
||||
// 实际应用中,Pawn应该定期主动发送验证信号
|
||||
var comp = pawn.TryGetComp<CompUniquePawn>();
|
||||
if (comp != null)
|
||||
{
|
||||
comp.SendVerificationSignal();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GameComponent实现
|
||||
public override void GameComponentTick()
|
||||
{
|
||||
base.GameComponentTick();
|
||||
|
||||
if (Find.TickManager.TicksGame - lastVerificationTick > VERIFICATION_INTERVAL)
|
||||
{
|
||||
VerifyAllPawns();
|
||||
lastVerificationTick = Find.TickManager.TicksGame;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData()
|
||||
{
|
||||
base.ExposeData();
|
||||
|
||||
lock (syncLock)
|
||||
{
|
||||
Scribe_Collections.Look(ref registeredPawns, "registeredPawns", LookMode.Deep);
|
||||
|
||||
if (Scribe.mode == LoadSaveMode.PostLoadInit)
|
||||
{
|
||||
// 加载后初始化
|
||||
Initialize();
|
||||
|
||||
// 清理无效数据
|
||||
CleanupInvalidRegistrations();
|
||||
|
||||
Log.Message($"[唯一Pawn系统] 加载了 {registeredPawns?.Count ?? 0} 个Pawn注册信息");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user