暂存
This commit is contained in:
Binary file not shown.
280
1.6/1.6/Defs/DamageDefs/ARA_Damage_Freeze.xml
Normal file
280
1.6/1.6/Defs/DamageDefs/ARA_Damage_Freeze.xml
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
|
||||||
|
<!-- 首先是冷冻效果的定义 -->
|
||||||
|
<HediffDef>
|
||||||
|
<defName>ARA_Hediff_Frozen</defName>
|
||||||
|
<label>冷冻中</label>
|
||||||
|
<description>这个身体部位正在被冷冻。移动会因此减慢。如果该部位被完全冷冻,它将在下一次受到冲击时碎裂。</description>
|
||||||
|
<hediffClass>ArachnaeSwarm.Hediff_Frozen</hediffClass>
|
||||||
|
<isBad>true</isBad>
|
||||||
|
<comps>
|
||||||
|
<li Class="HediffCompProperties_SeverityPerDay">
|
||||||
|
<severityPerDay>-6</severityPerDay>
|
||||||
|
</li>
|
||||||
|
<li Class="ArachnaeSwarm.HediffCompProperties_GlobalFreeze">
|
||||||
|
<stunThreshold>0.3</stunThreshold> <!-- 全身30%的健康值被转化为冷冻值时,目标将被眩晕 -->
|
||||||
|
</li>
|
||||||
|
<li Class="HediffCompProperties_DisappearsOnDeath"/>
|
||||||
|
</comps>
|
||||||
|
<injuryProps>
|
||||||
|
<painPerSeverity>0</painPerSeverity>
|
||||||
|
<canMerge>true</canMerge>
|
||||||
|
<destroyedLabel>已碎裂</destroyedLabel>
|
||||||
|
</injuryProps>
|
||||||
|
<stages>
|
||||||
|
<li>
|
||||||
|
<label>轻微</label>
|
||||||
|
<becomeVisible>true</becomeVisible>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>轻微</label>
|
||||||
|
<minSeverity>0.2</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>40</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>中等</label>
|
||||||
|
<minSeverity>0.35</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>80</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Moving</capacity>
|
||||||
|
<offset>-0.1</offset>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<capacity>Manipulation</capacity>
|
||||||
|
<offset>-0.2</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>严重</label>
|
||||||
|
<minSeverity>0.5</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>120</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Moving</capacity>
|
||||||
|
<offset>-0.3</offset>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<capacity>Manipulation</capacity>
|
||||||
|
<offset>-0.4</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>极度</label>
|
||||||
|
<minSeverity>0.65</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>160</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Moving</capacity>
|
||||||
|
<offset>-0.5</offset>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<capacity>Manipulation</capacity>
|
||||||
|
<offset>-0.6</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>完全</label>
|
||||||
|
<minSeverity>0.85</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>200</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Moving</capacity>
|
||||||
|
<setMax>0.2</setMax>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<capacity>Manipulation</capacity>
|
||||||
|
<setMax>0.2</setMax>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
</stages>
|
||||||
|
</HediffDef>
|
||||||
|
|
||||||
|
<HediffDef>
|
||||||
|
<defName>ARA_Hediff_FrostCoverd_after</defName>
|
||||||
|
<label>霜冻覆盖</label>
|
||||||
|
<description>此人被一片冰霜之云所覆盖。</description>
|
||||||
|
<defaultLabelColor>(1, 1, 0.8)</defaultLabelColor>
|
||||||
|
<hediffClass>HediffWithComps</hediffClass>
|
||||||
|
<comps>
|
||||||
|
<li Class="HediffCompProperties_SeverityPerDay">
|
||||||
|
<severityPerDay>-4</severityPerDay>
|
||||||
|
</li>
|
||||||
|
<li Class="ArachnaeSwarm.HediffCompProperties_TimedExplosion">
|
||||||
|
<damageDef>ARA_Damage_Freeze</damageDef>
|
||||||
|
<soundDef>Explosion_Stun</soundDef>
|
||||||
|
<explosionRadius>3</explosionRadius>
|
||||||
|
<showRemainingTime>true</showRemainingTime>
|
||||||
|
<damageAmount>5</damageAmount>
|
||||||
|
<armorPenetration>0.10</armorPenetration>
|
||||||
|
<disappearsAfterTicks>60~120</disappearsAfterTicks>
|
||||||
|
<postExplosionSpawnThingDef>ARA_FrostGasCloud</postExplosionSpawnThingDef>
|
||||||
|
<postExplosionSpawnChance>1</postExplosionSpawnChance>
|
||||||
|
<postExplosionSpawnThingCount>1</postExplosionSpawnThingCount>
|
||||||
|
</li>
|
||||||
|
<li Class="HediffCompProperties_DisappearsOnDeath"/>
|
||||||
|
</comps>
|
||||||
|
<stages>
|
||||||
|
</stages>
|
||||||
|
</HediffDef>
|
||||||
|
|
||||||
|
<HediffDef>
|
||||||
|
<defName>ARA_CryoShock</defName>
|
||||||
|
<label>低温休克</label>
|
||||||
|
<description>此人正处于低温休克状态。</description>
|
||||||
|
<defaultLabelColor>(1, 1, 0.8)</defaultLabelColor>
|
||||||
|
<hediffClass>ArachnaeSwarm.HediffCurseFlame</hediffClass>
|
||||||
|
<comps>
|
||||||
|
<li Class="HediffCompProperties_SeverityPerDay">
|
||||||
|
<severityPerDay>-6</severityPerDay>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.CurseFlameModExt">
|
||||||
|
<damageDefName>Stun</damageDefName>
|
||||||
|
<damageRange>1~2</damageRange>
|
||||||
|
<damageIntervalTicks>80</damageIntervalTicks>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
|
<injuryProps>
|
||||||
|
<painPerSeverity>0.02</painPerSeverity>
|
||||||
|
</injuryProps>
|
||||||
|
<stages>
|
||||||
|
<li>
|
||||||
|
<label>轻微</label>
|
||||||
|
<becomeVisible>true</becomeVisible>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>轻微</label>
|
||||||
|
<minSeverity>0.2</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>40</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Consciousness</capacity>
|
||||||
|
<offset>-0.10</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>中等</label>
|
||||||
|
<minSeverity>0.35</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>80</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Consciousness</capacity>
|
||||||
|
<offset>-0.20</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>严重</label>
|
||||||
|
<minSeverity>0.5</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>120</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Consciousness</capacity>
|
||||||
|
<offset>-0.20</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>极度</label>
|
||||||
|
<minSeverity>0.65</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>160</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Consciousness</capacity>
|
||||||
|
<offset>-0.30</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<label>完全</label>
|
||||||
|
<minSeverity>0.85</minSeverity>
|
||||||
|
<statOffsets>
|
||||||
|
<ComfyTemperatureMin>200</ComfyTemperatureMin>
|
||||||
|
</statOffsets>
|
||||||
|
<capMods>
|
||||||
|
<li>
|
||||||
|
<capacity>Consciousness</capacity>
|
||||||
|
<offset>-0.30</offset>
|
||||||
|
</li>
|
||||||
|
</capMods>
|
||||||
|
</li>
|
||||||
|
</stages>
|
||||||
|
</HediffDef>
|
||||||
|
|
||||||
|
<!-- 然后是冷冻伤害本身的定义 -->
|
||||||
|
<DamageDef>
|
||||||
|
<defName>ARA_Damage_Freeze</defName>
|
||||||
|
<label>冷冻</label>
|
||||||
|
<workerClass>DamageWorker_AddInjury</workerClass> <!-- 使用原版的伤害工人 -->
|
||||||
|
<externalViolence>true</externalViolence>
|
||||||
|
<deathMessage>{0}的身体在极寒中化为了冰雕,随后碎裂四散。</deathMessage>
|
||||||
|
<hediff>ARA_Hediff_Frozen</hediff> <!-- 核心!将伤害转化为这个Hediff的严重性 -->
|
||||||
|
<hediffSolid>ARA_Hediff_Frozen</hediffSolid> <!-- 对非血肉生物也使用这个Hediff -->
|
||||||
|
<harmsHealth>false</harmsHealth> <!-- 核心!不造成常规生命值伤害 -->
|
||||||
|
<armorCategory>Heat</armorCategory> <!-- 可以被抗热/冷的护甲减免 -->
|
||||||
|
<overkillPctToDestroyPart>0</overkillPctToDestroyPart> <!-- 伤害足够时直接摧毁(我们的C#代码会处理这个) -->
|
||||||
|
<defaultDamage>3</defaultDamage>
|
||||||
|
<defaultArmorPenetration>0</defaultArmorPenetration>
|
||||||
|
<buildingDamageFactorImpassable>0</buildingDamageFactorImpassable>
|
||||||
|
<buildingDamageFactorPassable>0</buildingDamageFactorPassable>
|
||||||
|
</DamageDef>
|
||||||
|
|
||||||
|
<!-- 然后是冷冻伤害本身的定义 -->
|
||||||
|
<DamageDef>
|
||||||
|
<defName>ARA_Damage_Freeze_ex</defName>
|
||||||
|
<label>冷冻</label>
|
||||||
|
<workerClass>DamageWorker_AddInjury</workerClass> <!-- 使用原版的伤害工人 -->
|
||||||
|
<externalViolence>true</externalViolence>
|
||||||
|
<deathMessage>{0}的身体在极寒中化为了冰雕,随后碎裂四散。</deathMessage>
|
||||||
|
<hediff>ARA_Hediff_Frozen</hediff> <!-- 核心!将伤害转化为这个Hediff的严重性 -->
|
||||||
|
<hediffSolid>ARA_Hediff_Frozen</hediffSolid> <!-- 对非血肉生物也使用这个Hediff -->
|
||||||
|
<harmsHealth>false</harmsHealth> <!-- 核心!不造成常规生命值伤害 -->
|
||||||
|
<armorCategory>Heat</armorCategory> <!-- 可以被抗热/冷的护甲减免 -->
|
||||||
|
<overkillPctToDestroyPart>0</overkillPctToDestroyPart> <!-- 伤害足够时直接摧毁(我们的C#代码会处理这个) -->
|
||||||
|
<defaultDamage>3</defaultDamage>
|
||||||
|
<defaultArmorPenetration>0</defaultArmorPenetration>
|
||||||
|
<buildingDamageFactorImpassable>0</buildingDamageFactorImpassable>
|
||||||
|
<buildingDamageFactorPassable>0</buildingDamageFactorPassable>
|
||||||
|
<additionalHediffs>
|
||||||
|
<li>
|
||||||
|
<hediff>ARA_CryoShock</hediff>
|
||||||
|
<severityPerDamageDealt>0.01</severityPerDamageDealt>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<hediff>ARA_Hediff_FrostCoverd_after</hediff>
|
||||||
|
<severityPerDamageDealt>0.01</severityPerDamageDealt>
|
||||||
|
<inverseStatScaling>true</inverseStatScaling>
|
||||||
|
<victimSeverityScalingByInvBodySize>true</victimSeverityScalingByInvBodySize>
|
||||||
|
</li>
|
||||||
|
</additionalHediffs>
|
||||||
|
</DamageDef>
|
||||||
|
|
||||||
|
</Defs>
|
||||||
@@ -66,6 +66,7 @@
|
|||||||
<buildingDef>ARA_Building_SpiderOne</buildingDef>
|
<buildingDef>ARA_Building_SpiderOne</buildingDef>
|
||||||
<hediffOnEmptyFuel>ARA_PowerArmor_NoFuel</hediffOnEmptyFuel>
|
<hediffOnEmptyFuel>ARA_PowerArmor_NoFuel</hediffOnEmptyFuel>
|
||||||
<fuelConsumptionRate>0.5</fuelConsumptionRate>
|
<fuelConsumptionRate>0.5</fuelConsumptionRate>
|
||||||
|
<powerArmorWeapon>ARA_RW_Icez_Mortar</powerArmorWeapon>
|
||||||
</li>
|
</li>
|
||||||
</modExtensions>
|
</modExtensions>
|
||||||
<recipeMaker>
|
<recipeMaker>
|
||||||
|
|||||||
@@ -41,31 +41,86 @@
|
|||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
<!-- Gas : Thing -->
|
<!-- Gas : Thing -->
|
||||||
<ThingDef ParentName="ARA_BaseGas">
|
<ThingDef ParentName="ARA_BaseGas">
|
||||||
<defName>ARA_AcidGasCloud</defName>
|
<defName>ARA_AcidGasCloud</defName>
|
||||||
<label>阿拉克涅酸雾</label>
|
<label>阿拉克涅酸雾</label>
|
||||||
<graphicData>
|
<graphicData>
|
||||||
<texPath>Things/Gas/Puff</texPath>
|
<texPath>Things/Gas/Puff</texPath>
|
||||||
<drawSize>2.6</drawSize>
|
<drawSize>2.6</drawSize>
|
||||||
<color>(0.56, 1, 0.03,0.5)</color>
|
<color>(0.56, 1, 0.03,0.5)</color>
|
||||||
</graphicData>
|
</graphicData>
|
||||||
<gas>
|
<gas>
|
||||||
<expireSeconds>
|
<expireSeconds>
|
||||||
<min>30</min>
|
<min>30</min>
|
||||||
<max>50</max>
|
<max>50</max>
|
||||||
</expireSeconds>
|
</expireSeconds>
|
||||||
<!--<blockTurretTracking>true</blockTurretTracking>
|
<!--<blockTurretTracking>true</blockTurretTracking>
|
||||||
<accuracyPenalty>0.3</accuracyPenalty>-->
|
<accuracyPenalty>0.3</accuracyPenalty>-->
|
||||||
<rotationSpeed>20</rotationSpeed>
|
<rotationSpeed>20</rotationSpeed>
|
||||||
</gas>
|
</gas>
|
||||||
<thingClass>ArachnaeSwarm.OPToxicGas</thingClass>
|
<thingClass>ArachnaeSwarm.OPToxicGas</thingClass>
|
||||||
<modExtensions>
|
<modExtensions>
|
||||||
<li Class="ArachnaeSwarm.OPToxicDefs">
|
<li Class="ArachnaeSwarm.OPToxicDefs">
|
||||||
<OPToxicHediff>ARA_AcidCoverd</OPToxicHediff> <!-- Name of HediffDef to apply, change to own HediffDef -->
|
<OPToxicHediff>ARA_AcidCoverd</OPToxicHediff> <!-- Name of HediffDef to apply, change to own HediffDef -->
|
||||||
<OPToxicSeverity>0.1</OPToxicSeverity> <!-- Severity build up per Tick period -->
|
<OPToxicSeverity>0.1</OPToxicSeverity> <!-- Severity build up per Tick period -->
|
||||||
<OPSevUpTickPeriod>240</OPSevUpTickPeriod> <!-- No of game ticks per each build up, recommend >= 120 -->
|
<OPSevUpTickPeriod>240</OPSevUpTickPeriod> <!-- No of game ticks per each build up, recommend >= 120 -->
|
||||||
</li>
|
</li>
|
||||||
</modExtensions>
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
|
<!-- Gas : Thing -->
|
||||||
|
<ThingDef ParentName="ARA_BaseGas">
|
||||||
|
<defName>ARA_FrostGasCloud_Ex</defName>
|
||||||
|
<label>Frost cloud</label>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>Things/Gas/Puff</texPath>
|
||||||
|
<drawSize>2.6</drawSize>
|
||||||
|
<color>(0.52, 1, 0.95,0.5)</color>
|
||||||
|
</graphicData>
|
||||||
|
<gas>
|
||||||
|
<expireSeconds>
|
||||||
|
<min>5</min>
|
||||||
|
<max>10</max>
|
||||||
|
</expireSeconds>
|
||||||
|
<!--<blockTurretTracking>true</blockTurretTracking>
|
||||||
|
<accuracyPenalty>0.3</accuracyPenalty>-->
|
||||||
|
<rotationSpeed>5</rotationSpeed>
|
||||||
|
</gas>
|
||||||
|
<thingClass>ArachnaeSwarm.OPToxicGas</thingClass>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.OPToxicDefs">
|
||||||
|
<OPToxicHediff>ARA_Hediff_FrostCoverd_after</OPToxicHediff> <!-- Name of HediffDef to apply, change to own HediffDef -->
|
||||||
|
<OPToxicSeverity>0.1</OPToxicSeverity> <!-- Severity build up per Tick period -->
|
||||||
|
<OPSevUpTickPeriod>240</OPSevUpTickPeriod> <!-- No of game ticks per each build up, recommend >= 120 -->
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
|
</ThingDef>
|
||||||
|
|
||||||
|
<ThingDef ParentName="ARA_BaseGas">
|
||||||
|
<defName>ARA_FrostGasCloud</defName>
|
||||||
|
<label>Frost cloud</label>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>Things/Gas/Puff</texPath>
|
||||||
|
<drawSize>2.6</drawSize>
|
||||||
|
<color>(0.52, 1, 0.95,0.5)</color>
|
||||||
|
</graphicData>
|
||||||
|
<gas>
|
||||||
|
<expireSeconds>
|
||||||
|
<min>5</min>
|
||||||
|
<max>10</max>
|
||||||
|
</expireSeconds>
|
||||||
|
<!--<blockTurretTracking>true</blockTurretTracking>
|
||||||
|
<accuracyPenalty>0.3</accuracyPenalty>-->
|
||||||
|
<rotationSpeed>5</rotationSpeed>
|
||||||
|
</gas>
|
||||||
|
<thingClass>ArachnaeSwarm.OPToxicGas</thingClass>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.OPToxicDefs">
|
||||||
|
<OPToxicHediff>ARA_CryoShock</OPToxicHediff> <!-- Name of HediffDef to apply, change to own HediffDef -->
|
||||||
|
<OPToxicSeverity>0.1</OPToxicSeverity> <!-- Severity build up per Tick period -->
|
||||||
|
<OPSevUpTickPeriod>240</OPSevUpTickPeriod> <!-- No of game ticks per each build up, recommend >= 120 -->
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
|
</ThingDef>
|
||||||
|
|
||||||
</Defs>
|
</Defs>
|
||||||
@@ -1093,7 +1093,7 @@
|
|||||||
<isMortar>true</isMortar>
|
<isMortar>true</isMortar>
|
||||||
<requireLineOfSight>false</requireLineOfSight>
|
<requireLineOfSight>false</requireLineOfSight>
|
||||||
<minRange>5</minRange>
|
<minRange>5</minRange>
|
||||||
<range>120</range>
|
<range>80</range>
|
||||||
<burstShotCount>1</burstShotCount>
|
<burstShotCount>1</burstShotCount>
|
||||||
<soundCast>SpitterSpit</soundCast>
|
<soundCast>SpitterSpit</soundCast>
|
||||||
<targetParams>
|
<targetParams>
|
||||||
|
|||||||
122
1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_Icez.xml
Normal file
122
1.6/1.6/Defs/Thing_Misc/Weapons/ARA_Weapon_Icez.xml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<Defs>
|
||||||
|
<ThingDef ParentName="BaseHumanMakeableGun">
|
||||||
|
<defName>ARA_RW_Icez_Mortar</defName>
|
||||||
|
<label>武装器官"霜星炮"</label>
|
||||||
|
<description>阿拉克涅虫群督虫使用大型远程武装器官,可以发射极度冰冷的霜冻气团,被接触到的敌人会产生霜冻爆炸,一旦被冻结不会立即致死,但随之而来的任何外来伤害都会立刻摧毁脆弱的冰雕。</description>
|
||||||
|
<tickerType>Normal</tickerType>
|
||||||
|
<techLevel>Animal</techLevel>
|
||||||
|
<descriptionHyperlinks>
|
||||||
|
<ThingDef>ARA_Cocoon_Weapon_2Stage</ThingDef>
|
||||||
|
</descriptionHyperlinks>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>ArachnaeSwarm/Weapon/ARA_RW_Acid_Mortar</texPath>
|
||||||
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
|
<drawSize>1.5</drawSize>
|
||||||
|
</graphicData>
|
||||||
|
<uiIconScale>0.75</uiIconScale>
|
||||||
|
<soundInteract>SpitterSpawn</soundInteract>
|
||||||
|
<recipeMaker>
|
||||||
|
<recipeUsers Inherit="False" />
|
||||||
|
<researchPrerequisite>ARA_Technology_9VXI</researchPrerequisite>
|
||||||
|
<unfinishedThingDef>UnfinishedWeapon</unfinishedThingDef>
|
||||||
|
</recipeMaker>
|
||||||
|
<statBases>
|
||||||
|
<MarketValue>2500</MarketValue>
|
||||||
|
<WorkToMake>1300</WorkToMake>
|
||||||
|
<!-- <MarketValue>370</MarketValue> -->
|
||||||
|
<Mass>3.5</Mass>
|
||||||
|
<AccuracyTouch>0.3</AccuracyTouch>
|
||||||
|
<AccuracyShort>0.3</AccuracyShort>
|
||||||
|
<AccuracyMedium>0.25</AccuracyMedium>
|
||||||
|
<AccuracyLong>0.1</AccuracyLong>
|
||||||
|
<RangedWeapon_Cooldown>3.5</RangedWeapon_Cooldown>
|
||||||
|
<ARA_IncubationCost>450</ARA_IncubationCost>
|
||||||
|
<ARA_IncubationTime>15</ARA_IncubationTime>
|
||||||
|
</statBases>
|
||||||
|
<verbs>
|
||||||
|
<li>
|
||||||
|
<verbClass>Verb_Shoot</verbClass>
|
||||||
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
|
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
||||||
|
<warmupTime>1.5</warmupTime>
|
||||||
|
<forcedMissRadius>3</forcedMissRadius>
|
||||||
|
<defaultProjectile>Bullet_ARA_RW_Icez_Mortar</defaultProjectile>
|
||||||
|
<isMortar>true</isMortar>
|
||||||
|
<requireLineOfSight>false</requireLineOfSight>
|
||||||
|
<minRange>5</minRange>
|
||||||
|
<range>80</range>
|
||||||
|
<burstShotCount>1</burstShotCount>
|
||||||
|
<soundCast>SpitterSpit</soundCast>
|
||||||
|
<targetParams>
|
||||||
|
<canTargetLocations>true</canTargetLocations>
|
||||||
|
</targetParams>
|
||||||
|
</li>
|
||||||
|
</verbs>
|
||||||
|
<costList Inherit="False">
|
||||||
|
<ARA_Carapace>50</ARA_Carapace>
|
||||||
|
</costList>
|
||||||
|
<weaponTags Inherit="False">
|
||||||
|
<li>ARA_Armed_Organ</li>
|
||||||
|
<li>ARA_Armed_Organ_Ranged</li>
|
||||||
|
<li>ARA_Armed_Organ_T2</li>
|
||||||
|
</weaponTags>
|
||||||
|
<generateCommonality>0</generateCommonality>
|
||||||
|
<tradeability>None</tradeability>
|
||||||
|
<thingSetMakerTags Inherit="False"/>
|
||||||
|
<comps>
|
||||||
|
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
|
||||||
|
<cocoonDefs>
|
||||||
|
<li>ARA_Cocoon_Weapon_2Stage</li>
|
||||||
|
<li>ARA_BioforgeIncubator_Thing</li>
|
||||||
|
</cocoonDefs>
|
||||||
|
</li>
|
||||||
|
<li Class="ArachnaeSwarm.CompProperties_CustomUniqueWeapon" MayRequire="Ludeon.RimWorld.Odyssey">
|
||||||
|
<forcedTraits>
|
||||||
|
<li>ARA_Huge_Weapon</li>
|
||||||
|
<li>ARA_Weapon_Damage_Acid</li>
|
||||||
|
</forcedTraits>
|
||||||
|
<numTraitsRange>
|
||||||
|
<min>2</min>
|
||||||
|
<max>2</max>
|
||||||
|
</numTraitsRange>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</ThingDef>
|
||||||
|
<ThingDef ParentName="BaseBullet">
|
||||||
|
<defName>Bullet_ARA_RW_Icez_Mortar</defName>
|
||||||
|
<label>大型霜雾团</label>
|
||||||
|
<graphicData>
|
||||||
|
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
|
||||||
|
<texPath>Things/Projectile/FleshmassSpitterProjectileSheet</texPath>
|
||||||
|
<drawSize>(.75, .75)</drawSize>
|
||||||
|
<shaderType>MoteGlow</shaderType>
|
||||||
|
</graphicData>
|
||||||
|
<uiIconScale>0.8</uiIconScale>
|
||||||
|
<thingClass>Projectile_Explosive</thingClass>
|
||||||
|
<projectile>
|
||||||
|
<useGraphicClass>True</useGraphicClass>
|
||||||
|
<shadowSize>1</shadowSize>
|
||||||
|
<damageDef>ARA_Damage_Freeze_ex</damageDef>
|
||||||
|
<spinRate>15</spinRate>
|
||||||
|
<damageAmountBase>25</damageAmountBase>
|
||||||
|
<speed>45</speed>
|
||||||
|
<arcHeightFactor>1</arcHeightFactor>
|
||||||
|
<explosionRadius>3.5</explosionRadius>
|
||||||
|
<flyOverhead>true</flyOverhead>
|
||||||
|
<postExplosionSpawnThingDef>ARA_FrostGasCloud_Ex</postExplosionSpawnThingDef> <!-- ARL_ToxicGasCloud -->
|
||||||
|
<postExplosionSpawnChance>1</postExplosionSpawnChance>
|
||||||
|
<postExplosionSpawnThingCount>1</postExplosionSpawnThingCount>
|
||||||
|
<soundExplode>Explosion_Stun</soundExplode>
|
||||||
|
<doExplosionVFX>false</doExplosionVFX>
|
||||||
|
</projectile>
|
||||||
|
<comps>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitStream</effecterDef>
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_ProjectileEffecter">
|
||||||
|
<effecterDef>Shell_AcidSpitLaunched</effecterDef>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</ThingDef>
|
||||||
|
</Defs>
|
||||||
@@ -1,19 +1,21 @@
|
|||||||
using RimWorld;
|
using RimWorld;
|
||||||
using Verse;
|
using Verse;
|
||||||
using Verse.Sound;
|
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
[DefOf]
|
[DefOf]
|
||||||
public static class ARA_HediffDefOf
|
public static class ARA_HediffDefOf
|
||||||
{
|
{
|
||||||
public static HediffDef ARA_AcidCoverd;
|
public static HediffDef ARA_Hediff_Frozen;
|
||||||
|
public static HediffDef ARA_Hediff_FrostCoverd_after;
|
||||||
|
public static HediffDef ARA_CryoShock;
|
||||||
public static HediffDef ARA_HiveMindMaster;
|
public static HediffDef ARA_HiveMindMaster;
|
||||||
public static HediffDef ARA_HiveMindDrone;
|
public static HediffDef ARA_HiveMindDrone;
|
||||||
public static HediffDef ARA_HiveMindWorker;
|
public static HediffDef ARA_HiveMindWorker; // 如果存在这个Def
|
||||||
|
|
||||||
static ARA_HediffDefOf()
|
static ARA_HediffDefOf()
|
||||||
{
|
{
|
||||||
DefOfHelper.EnsureInitializedInCtor(typeof(HediffDefOf));
|
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_HediffDefOf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,6 +192,9 @@
|
|||||||
<Compile Include="Hediffs\MoharHediffs\HediffComp_Spawner.cs" />
|
<Compile Include="Hediffs\MoharHediffs\HediffComp_Spawner.cs" />
|
||||||
<Compile Include="Hediffs\MoharHediffs\Tools.cs" />
|
<Compile Include="Hediffs\MoharHediffs\Tools.cs" />
|
||||||
<Compile Include="Hediffs\ProphecyGearEffect.cs" />
|
<Compile Include="Hediffs\ProphecyGearEffect.cs" />
|
||||||
|
<Compile Include="HediffComp_TimedExplosion.cs" />
|
||||||
|
<Compile Include="Hediff_Frozen.cs" />
|
||||||
|
<Compile Include="HediffComp_GlobalFreeze.cs" />
|
||||||
<Compile Include="Hediffs\WULA_HediffDamgeShield\DRMDamageShield.cs" />
|
<Compile Include="Hediffs\WULA_HediffDamgeShield\DRMDamageShield.cs" />
|
||||||
<Compile Include="Hediffs\WULA_HediffDamgeShield\Hediff_DamageShield.cs" />
|
<Compile Include="Hediffs\WULA_HediffDamgeShield\Hediff_DamageShield.cs" />
|
||||||
<Compile Include="Thing_Comps\ARA_ThingComp_GuardianPsyField\Hediff_DynamicInterceptor.cs" />
|
<Compile Include="Thing_Comps\ARA_ThingComp_GuardianPsyField\Hediff_DynamicInterceptor.cs" />
|
||||||
@@ -272,12 +275,12 @@
|
|||||||
<Compile Include="Buildings\Building_CatastropheMissileSilo\Building_CatastropheMissileSilo.cs" />
|
<Compile Include="Buildings\Building_CatastropheMissileSilo\Building_CatastropheMissileSilo.cs" />
|
||||||
<Compile Include="Buildings\Building_CatastropheMissileSilo\WorldObject_CatastropheMissile.cs" />
|
<Compile Include="Buildings\Building_CatastropheMissileSilo\WorldObject_CatastropheMissile.cs" />
|
||||||
<Compile Include="HarmonyPatches\Patch_ForceTargetable.cs" />
|
<Compile Include="HarmonyPatches\Patch_ForceTargetable.cs" />
|
||||||
|
<Compile Include="HarmonyPatch_Pawn_HealthTracker_PreApplyDamage.cs" />
|
||||||
<Compile Include="Building_Comps\CompForceTargetable.cs" />
|
<Compile Include="Building_Comps\CompForceTargetable.cs" />
|
||||||
<Compile Include="PowerArmor\ARA_PowerArmor.cs" />
|
<Compile Include="PowerArmor\ARA_PowerArmor.cs" />
|
||||||
<Compile Include="PowerArmor\CompPowerArmorStation.cs" />
|
<Compile Include="PowerArmor\CompPowerArmorStation.cs" />
|
||||||
<Compile Include="PowerArmor\Gizmo_StructurePanel.cs" />
|
<Compile Include="PowerArmor\Gizmo_StructurePanel.cs" />
|
||||||
<Compile Include="PowerArmor\JobDriver_EnterPowerArmor.cs" />
|
<Compile Include="PowerArmor\JobDriver_EnterPowerArmor.cs" />
|
||||||
<Compile Include="PowerArmor\Harmony_ThingWithComps_GetFloatMenuOptions.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Jobs\JobDriver_SuperCarry\SuperCarryExtension.cs" />
|
<Compile Include="Jobs\JobDriver_SuperCarry\SuperCarryExtension.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Linq;
|
||||||
|
using UnityEngine; // For FleckMaker
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
// Harmony 入口点,将在 Mod 加载时自动初始化
|
||||||
|
[StaticConstructorOnStartup]
|
||||||
|
public static class HarmonyPatches
|
||||||
|
{
|
||||||
|
static HarmonyPatches()
|
||||||
|
{
|
||||||
|
var harmony = new Harmony("ArachnaeSwarm.FreezeMod");
|
||||||
|
harmony.PatchAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 补丁目标:Pawn_HealthTracker 类的 PreApplyDamage 方法
|
||||||
|
[HarmonyPatch(typeof(Pawn_HealthTracker), "PreApplyDamage")]
|
||||||
|
public static class HarmonyPatch_Pawn_HealthTracker_PreApplyDamage
|
||||||
|
{
|
||||||
|
// Postfix 补丁:在原方法执行后运行
|
||||||
|
// __instance 是 Pawn_HealthTracker 的实例
|
||||||
|
// dinfo 是 DamageInfo 的引用
|
||||||
|
// absorbed 是 out bool 参数的引用
|
||||||
|
public static void Postfix(Pawn_HealthTracker __instance, ref DamageInfo dinfo, ref bool absorbed)
|
||||||
|
{
|
||||||
|
// 如果伤害已经被吸收,或者没有击中任何部位,则不处理
|
||||||
|
if (absorbed || dinfo.HitPart == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pawn pawn = (Pawn)AccessTools.Field(typeof(Pawn_HealthTracker), "pawn").GetValue(__instance);
|
||||||
|
if (pawn == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制一份 dinfo,避免 ref 参数在 lambda 中使用的问题
|
||||||
|
DamageInfo currentDinfo = dinfo;
|
||||||
|
|
||||||
|
// 获取被击中部位上的 Hediff_Frozen
|
||||||
|
Hediff_Frozen frozenHediff = pawn.health.hediffSet.hediffs.OfType<Hediff_Frozen>()
|
||||||
|
.FirstOrDefault(h => h.Part == currentDinfo.HitPart);
|
||||||
|
|
||||||
|
// 如果该部位存在 Hediff_Frozen 并且已经完全冷冻
|
||||||
|
if (frozenHediff != null && frozenHediff.Severity >= currentDinfo.HitPart.def.GetMaxHealth(pawn))
|
||||||
|
{
|
||||||
|
// 检查伤害是否是我们的冷冻伤害(防止循环触发)
|
||||||
|
if (currentDinfo.Def.hediff == ARA_HediffDefOf.ARA_Hediff_Frozen)
|
||||||
|
{
|
||||||
|
return; // 忽略我们自己的冷冻伤害
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查伤害是否是会造成生命值损伤的普通伤害
|
||||||
|
if (currentDinfo.Def.harmsHealth && currentDinfo.Amount > 0.01f)
|
||||||
|
{
|
||||||
|
// 施加一个巨大的、足以摧毁该部位的伤害
|
||||||
|
DamageInfo fatalDamage = new DamageInfo(DamageDefOf.Crush, 99999f, 999f, -1f, currentDinfo.Instigator, currentDinfo.HitPart);
|
||||||
|
pawn.TakeDamage(fatalDamage);
|
||||||
|
|
||||||
|
// 播放一个破碎的特效
|
||||||
|
FleckMaker.Static(pawn.Position, pawn.Map, FleckDefOf.ExplosionFlash, 2f);
|
||||||
|
|
||||||
|
absorbed = true; // 标记原伤害已被处理,阻止其继续执行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
Source/ArachnaeSwarm/HediffComp_GlobalFreeze.cs
Normal file
72
Source/ArachnaeSwarm/HediffComp_GlobalFreeze.cs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class HediffComp_GlobalFreeze : HediffComp
|
||||||
|
{
|
||||||
|
private const int CheckInterval = 60; // 每60 ticks检查一次 (1秒)
|
||||||
|
private bool isStunnedByFreeze = false; // 用于追踪是否是由我们这个组件造成的眩晕
|
||||||
|
|
||||||
|
public HediffCompProperties_GlobalFreeze Props => (HediffCompProperties_GlobalFreeze)props;
|
||||||
|
|
||||||
|
public override void CompPostTick(ref float severityAdjustment)
|
||||||
|
{
|
||||||
|
base.CompPostTick(ref severityAdjustment);
|
||||||
|
|
||||||
|
// 每隔一段时间才执行一次,避免性能问题
|
||||||
|
if (Pawn.IsHashIntervalTick(CheckInterval))
|
||||||
|
{
|
||||||
|
// 计算全身所有Hediff_Frozen的总严重性
|
||||||
|
float totalFreezeSeverity = Pawn.health.hediffSet.hediffs
|
||||||
|
.OfType<Hediff_Frozen>()
|
||||||
|
.Sum(h => h.Severity);
|
||||||
|
|
||||||
|
// 获取Pawn的总生命值作为参考
|
||||||
|
float totalBodyHealth = Pawn.health.summaryHealth.SummaryHealthPercent * Pawn.MaxHitPoints;
|
||||||
|
|
||||||
|
// 计算冷冻阈值
|
||||||
|
float stunThreshold = totalBodyHealth * Props.stunThreshold;
|
||||||
|
|
||||||
|
// 如果总冷冻值超过阈值
|
||||||
|
if (totalFreezeSeverity >= stunThreshold)
|
||||||
|
{
|
||||||
|
// 如果Pawn当前没有被眩晕,则施加一个“永久”的眩晕
|
||||||
|
// StunFor会取最大值,所以我们给一个足够长的时间(5秒),它会在下一轮检查时被刷新
|
||||||
|
if (!Pawn.stances.stunner.Stunned)
|
||||||
|
{
|
||||||
|
Pawn.stances.stunner.StunFor(300, Pawn, false, true);
|
||||||
|
isStunnedByFreeze = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果总冷冻值低于阈值,并且之前是由我们造成的眩晕
|
||||||
|
else if (isStunnedByFreeze)
|
||||||
|
{
|
||||||
|
// 立即停止眩晕
|
||||||
|
// 我们通过将stunTicksLeft设置为0来直接唤醒它
|
||||||
|
Pawn.stances.stunner.StunFor(0, Pawn, false, false);
|
||||||
|
isStunnedByFreeze = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存和加载我们的状态,确保读档后逻辑正确
|
||||||
|
public override void CompExposeData()
|
||||||
|
{
|
||||||
|
base.CompExposeData();
|
||||||
|
Scribe_Values.Look(ref isStunnedByFreeze, "isStunnedByFreeze", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HediffCompProperties_GlobalFreeze : HediffCompProperties
|
||||||
|
{
|
||||||
|
// XML中可配置的阈值,默认为全身健康的30%
|
||||||
|
public float stunThreshold = 0.3f;
|
||||||
|
|
||||||
|
public HediffCompProperties_GlobalFreeze()
|
||||||
|
{
|
||||||
|
compClass = typeof(HediffComp_GlobalFreeze);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
244
Source/ArachnaeSwarm/HediffComp_TimedExplosion.cs
Normal file
244
Source/ArachnaeSwarm/HediffComp_TimedExplosion.cs
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using Verse;
|
||||||
|
using Verse.Noise;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm // 修正命名空间
|
||||||
|
{
|
||||||
|
public class HediffComp_TimedExplosion : HediffComp
|
||||||
|
{
|
||||||
|
// 倒计时相关字段
|
||||||
|
public int ticksToDisappear;
|
||||||
|
public int disappearsAfterTicks;
|
||||||
|
public int seed;
|
||||||
|
|
||||||
|
// 配置属性快捷访问
|
||||||
|
public HediffCompProperties_TimedExplosion Props =>
|
||||||
|
(HediffCompProperties_TimedExplosion)props;
|
||||||
|
|
||||||
|
// 消失判定属性
|
||||||
|
public override bool CompShouldRemove
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (ticksToDisappear > 0) return false;
|
||||||
|
if (Props.requiredMentalState != null)
|
||||||
|
{
|
||||||
|
return parent.pawn.MentalStateDef != Props.requiredMentalState;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进度计算
|
||||||
|
public float Progress =>
|
||||||
|
1f - (float)ticksToDisappear / Mathf.Max(1, disappearsAfterTicks);
|
||||||
|
|
||||||
|
public int EffectiveTicksToDisappear => ticksToDisappear / TicksLostPerTick;
|
||||||
|
|
||||||
|
public float NoisyProgress => AddNoiseToProgress(Progress, seed);
|
||||||
|
|
||||||
|
public virtual int TicksLostPerTick => 1;
|
||||||
|
|
||||||
|
public override string CompLabelInBracketsExtra
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Props.showRemainingTime)
|
||||||
|
{
|
||||||
|
if (EffectiveTicksToDisappear < 2500)
|
||||||
|
{
|
||||||
|
return EffectiveTicksToDisappear.ToStringSecondsFromTicks("F0");
|
||||||
|
}
|
||||||
|
return EffectiveTicksToDisappear.ToStringTicksToPeriod(allowSeconds: true, shortForm: true, canUseDecimals: true, allowYears: true, Props.canUseDecimalsShortForm);
|
||||||
|
}
|
||||||
|
return base.CompLabelInBracketsExtra;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float AddNoiseToProgress(float progress, int seed)
|
||||||
|
{
|
||||||
|
float num = (float)Perlin.GetValue(progress, 0.0, 0.0, 9.0, seed);
|
||||||
|
float num2 = 0.25f * (1f - progress);
|
||||||
|
return Mathf.Clamp01(progress + num2 * num);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
public override void CompPostMake()
|
||||||
|
{
|
||||||
|
base.CompPostMake();
|
||||||
|
disappearsAfterTicks = Props.disappearsAfterTicks.RandomInRange;
|
||||||
|
seed = Rand.Int;
|
||||||
|
ticksToDisappear = disappearsAfterTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每帧更新
|
||||||
|
public override void CompPostTick(ref float severityAdjustment)
|
||||||
|
{
|
||||||
|
ticksToDisappear--;
|
||||||
|
if (CompShouldRemove)
|
||||||
|
{
|
||||||
|
parent.pawn.health.RemoveHediff(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除后处理
|
||||||
|
public override void CompPostPostRemoved()
|
||||||
|
{
|
||||||
|
base.CompPostPostRemoved();
|
||||||
|
|
||||||
|
// 处理新鲜伤口状态
|
||||||
|
if (!Props.leaveFreshWounds && parent.Part != null)
|
||||||
|
{
|
||||||
|
foreach (BodyPartRecord part in parent.Part.GetPartAndAllChildParts())
|
||||||
|
{
|
||||||
|
Hediff_MissingPart hediff = parent.pawn.health.hediffSet.GetMissingPartFor(part) as Hediff_MissingPart;
|
||||||
|
if (hediff != null)
|
||||||
|
{
|
||||||
|
hediff.IsFresh = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发爆炸逻辑
|
||||||
|
if (ShouldTriggerExplosion())
|
||||||
|
{
|
||||||
|
TriggerExplosion();
|
||||||
|
DestroyGearIfNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送消息通知
|
||||||
|
if (!Props.messageOnDisappear.NullOrEmpty() && PawnUtility.ShouldSendNotificationAbout(parent.pawn))
|
||||||
|
{
|
||||||
|
Messages.Message(
|
||||||
|
Props.messageOnDisappear.Formatted(parent.pawn.Named("PAWN")),
|
||||||
|
parent.pawn,
|
||||||
|
MessageTypeDefOf.NeutralEvent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送信件通知
|
||||||
|
if (!Props.letterTextOnDisappear.NullOrEmpty() &&
|
||||||
|
!Props.letterLabelOnDisappear.NullOrEmpty() &&
|
||||||
|
PawnUtility.ShouldSendNotificationAbout(parent.pawn))
|
||||||
|
{
|
||||||
|
Find.LetterStack.ReceiveLetter(
|
||||||
|
Props.letterLabelOnDisappear.Formatted(parent.pawn.Named("PAWN")),
|
||||||
|
Props.letterTextOnDisappear.Formatted(parent.pawn.Named("PAWN")),
|
||||||
|
LetterDefOf.NegativeEvent,
|
||||||
|
parent.pawn
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 爆炸条件检查
|
||||||
|
private bool ShouldTriggerExplosion()
|
||||||
|
{
|
||||||
|
return parent.pawn.Spawned &&
|
||||||
|
Props.explosionRadius > 0.01f &&
|
||||||
|
Props.damageDef != null &&
|
||||||
|
parent.pawn.Map != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行爆炸
|
||||||
|
private void TriggerExplosion()
|
||||||
|
{
|
||||||
|
GenExplosion.DoExplosion(
|
||||||
|
center: parent.pawn.Position,
|
||||||
|
map: parent.pawn.Map,
|
||||||
|
radius: Props.explosionRadius,
|
||||||
|
damType: Props.damageDef,
|
||||||
|
instigator: parent.pawn,
|
||||||
|
damAmount: Props.damageAmount,
|
||||||
|
armorPenetration: Props.armorPenetration,
|
||||||
|
explosionSound: Props.soundDef,
|
||||||
|
weapon: null,
|
||||||
|
projectile: null,
|
||||||
|
intendedTarget: null,
|
||||||
|
postExplosionSpawnThingDef: Props.postExplosionSpawnThingDef,
|
||||||
|
postExplosionSpawnChance: Props.postExplosionSpawnChance,
|
||||||
|
postExplosionSpawnThingCount: Props.postExplosionSpawnThingCount,
|
||||||
|
postExplosionGasType: null,
|
||||||
|
applyDamageToExplosionCellsNeighbors: false,
|
||||||
|
chanceToStartFire: Props.chanceToStartFire,
|
||||||
|
damageFalloff: Props.damageFalloff,
|
||||||
|
direction: null,
|
||||||
|
ignoredThings: new List<Thing> { parent.pawn }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 装备销毁
|
||||||
|
private void DestroyGearIfNeeded()
|
||||||
|
{
|
||||||
|
if (!Props.destroyGear) return;
|
||||||
|
|
||||||
|
if (parent.pawn.equipment != null)
|
||||||
|
{
|
||||||
|
parent.pawn.equipment.DestroyAllEquipment(DestroyMode.Vanish);
|
||||||
|
}
|
||||||
|
if (parent.pawn.apparel != null)
|
||||||
|
{
|
||||||
|
parent.pawn.apparel.DestroyAll(DestroyMode.Vanish);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据持久化
|
||||||
|
public override void CompExposeData()
|
||||||
|
{
|
||||||
|
Scribe_Values.Look(ref ticksToDisappear, "ticksToDisappear", 0);
|
||||||
|
Scribe_Values.Look(ref disappearsAfterTicks, "disappearsAfterTicks", 0);
|
||||||
|
Scribe_Values.Look(ref seed, "seed", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调试信息
|
||||||
|
public override string CompDebugString()
|
||||||
|
{
|
||||||
|
return $"倒计时: {ticksToDisappear}\n爆炸半径: {Props.explosionRadius}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class HediffCompProperties_TimedExplosion : HediffCompProperties
|
||||||
|
{
|
||||||
|
[Header("消失设置")]
|
||||||
|
public IntRange disappearsAfterTicks = new IntRange(600, 1200);
|
||||||
|
public bool showRemainingTime = true;
|
||||||
|
public bool canUseDecimalsShortForm;
|
||||||
|
public MentalStateDef requiredMentalState;
|
||||||
|
public bool leaveFreshWounds = true;
|
||||||
|
|
||||||
|
[Header("爆炸设置")]
|
||||||
|
public float explosionRadius = 3f;
|
||||||
|
public DamageDef damageDef;
|
||||||
|
public int damageAmount = 20;
|
||||||
|
public float armorPenetration;
|
||||||
|
public SoundDef soundDef;
|
||||||
|
public float chanceToStartFire;
|
||||||
|
public bool damageFalloff = true;
|
||||||
|
|
||||||
|
[Header("后续效果")]
|
||||||
|
public bool destroyGear;
|
||||||
|
public GasType gasType;
|
||||||
|
public ThingDef postExplosionSpawnThingDef;
|
||||||
|
public float postExplosionSpawnChance;
|
||||||
|
public int postExplosionSpawnThingCount = 1;
|
||||||
|
|
||||||
|
[Header("通知设置")]
|
||||||
|
[MustTranslate]
|
||||||
|
public string messageOnDisappear;
|
||||||
|
[MustTranslate]
|
||||||
|
public string letterLabelOnDisappear;
|
||||||
|
[MustTranslate]
|
||||||
|
public string letterTextOnDisappear;
|
||||||
|
public bool sendLetterOnDisappearIfDead = true;
|
||||||
|
|
||||||
|
public HediffCompProperties_TimedExplosion()
|
||||||
|
{
|
||||||
|
compClass = typeof(HediffComp_TimedExplosion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
Source/ArachnaeSwarm/Hediff_Frozen.cs
Normal file
46
Source/ArachnaeSwarm/Hediff_Frozen.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class Hediff_Frozen : Hediff_Injury
|
||||||
|
{
|
||||||
|
// 我们需要覆盖这个方法来改变在健康面板上显示的标签
|
||||||
|
public override string LabelInBrackets
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// 如果严重性达到了部位的满生命值,就显示“完全冷冻”
|
||||||
|
if (Severity >= Part.def.GetMaxHealth(pawn))
|
||||||
|
{
|
||||||
|
return "Fully Frozen";
|
||||||
|
}
|
||||||
|
return base.LabelInBrackets;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当部位的疼痛感,可以根据严重性调整
|
||||||
|
public override float PainOffset
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// 冷冻不造成额外疼痛
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当一个部位的伤害被治疗(在这里就是冷冻值减少)时调用
|
||||||
|
public override void Heal(float amount)
|
||||||
|
{
|
||||||
|
// 减少严重性,但不让它低于0
|
||||||
|
Severity -= amount;
|
||||||
|
if (Severity < 0)
|
||||||
|
{
|
||||||
|
Severity = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 伤害拦截逻辑将通过 Harmony 补丁实现,不在 Hediff 内部处理
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ namespace ArachnaeSwarm
|
|||||||
public float structurePointsMax = 500f;
|
public float structurePointsMax = 500f;
|
||||||
public HediffDef hediffOnEmptyFuel;
|
public HediffDef hediffOnEmptyFuel;
|
||||||
public float fuelConsumptionRate = 0.5f; // Nutrition per day
|
public float fuelConsumptionRate = 0.5f; // Nutrition per day
|
||||||
|
public ThingDef powerArmorWeapon;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StaticConstructorOnStartup]
|
[StaticConstructorOnStartup]
|
||||||
@@ -51,6 +52,12 @@ namespace ArachnaeSwarm
|
|||||||
public float StructurePointsPercent => StructurePoints / StructurePointsMax;
|
public float StructurePointsPercent => StructurePoints / StructurePointsMax;
|
||||||
|
|
||||||
public Building sourceBuilding;
|
public Building sourceBuilding;
|
||||||
|
private ThingWithComps originalWeapon;
|
||||||
|
|
||||||
|
public void SetOriginalWeapon(ThingWithComps weapon)
|
||||||
|
{
|
||||||
|
originalWeapon = weapon;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Ticker
|
#region Ticker
|
||||||
@@ -110,6 +117,7 @@ namespace ArachnaeSwarm
|
|||||||
base.ExposeData();
|
base.ExposeData();
|
||||||
Scribe_Values.Look(ref structurePoints, "structurePoints", -1f);
|
Scribe_Values.Look(ref structurePoints, "structurePoints", -1f);
|
||||||
Scribe_References.Look(ref sourceBuilding, "sourceBuilding");
|
Scribe_References.Look(ref sourceBuilding, "sourceBuilding");
|
||||||
|
Scribe_References.Look(ref originalWeapon, "originalWeapon");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -143,6 +151,25 @@ namespace ArachnaeSwarm
|
|||||||
{
|
{
|
||||||
base.Notify_Unequipped(pawn);
|
base.Notify_Unequipped(pawn);
|
||||||
|
|
||||||
|
// Handle weapon restoration
|
||||||
|
if (Ext?.powerArmorWeapon != null && pawn?.equipment != null)
|
||||||
|
{
|
||||||
|
ThingWithComps primaryWeapon = pawn.equipment.Primary;
|
||||||
|
if (primaryWeapon != null && primaryWeapon.def == Ext.powerArmorWeapon)
|
||||||
|
{
|
||||||
|
// Destroy the power armor's weapon instead of dropping it.
|
||||||
|
pawn.equipment.Remove(primaryWeapon);
|
||||||
|
primaryWeapon.Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (originalWeapon != null && pawn?.equipment != null)
|
||||||
|
{
|
||||||
|
pawn.equipment.MakeRoomFor(originalWeapon);
|
||||||
|
pawn.equipment.AddEquipment(originalWeapon);
|
||||||
|
originalWeapon = null;
|
||||||
|
}
|
||||||
|
|
||||||
Building building = sourceBuilding;
|
Building building = sourceBuilding;
|
||||||
|
|
||||||
// If the source building reference is lost, create a new one as a fallback.
|
// If the source building reference is lost, create a new one as a fallback.
|
||||||
@@ -171,6 +198,12 @@ namespace ArachnaeSwarm
|
|||||||
buildingFuelComp.ReceiveFuel(apparelFuelComp.Fuel);
|
buildingFuelComp.ReceiveFuel(apparelFuelComp.Fuel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync quality back to building
|
||||||
|
if (this.TryGetComp<CompQuality>() is CompQuality apparelQuality && building.TryGetComp<CompQuality>() is CompQuality buildingQuality)
|
||||||
|
{
|
||||||
|
buildingQuality.SetQuality(apparelQuality.Quality, ArtGenerationContext.Colony);
|
||||||
|
}
|
||||||
|
|
||||||
Log.Message($"[PA_Debug] Notify_Unequipped: Before spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
|
Log.Message($"[PA_Debug] Notify_Unequipped: Before spawning building (ID: {building.thingIDNumber}) - HitPoints: {building.HitPoints}, StackCount: {building.stackCount}");
|
||||||
|
|
||||||
// Ensure stackCount is at least 1 for buildings, as 0 stackCount causes errors during spawning
|
// Ensure stackCount is at least 1 for buildings, as 0 stackCount causes errors during spawning
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using RimWorld;
|
using RimWorld;
|
||||||
using Verse;
|
using Verse;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Verse.AI; // For PathEndMode and Danger
|
||||||
|
using UnityEngine; // For Texture2D
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
@@ -16,5 +19,34 @@ namespace ArachnaeSwarm
|
|||||||
public class CompPowerArmorStation : ThingComp
|
public class CompPowerArmorStation : ThingComp
|
||||||
{
|
{
|
||||||
public CompProperties_PowerArmorStation Props => (CompProperties_PowerArmorStation)props;
|
public CompProperties_PowerArmorStation Props => (CompProperties_PowerArmorStation)props;
|
||||||
|
|
||||||
|
public override IEnumerable<FloatMenuOption> CompFloatMenuOptions(Pawn selPawn)
|
||||||
|
{
|
||||||
|
foreach (FloatMenuOption option in base.CompFloatMenuOptions(selPawn))
|
||||||
|
{
|
||||||
|
yield return option;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there's an apparelDef defined
|
||||||
|
if (Props.apparelDef == null)
|
||||||
|
{
|
||||||
|
yield break; // No apparel to wear
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the pawn can interact with the building
|
||||||
|
if (!selPawn.CanReserveAndReach(parent, PathEndMode.InteractionCell, Danger.Deadly))
|
||||||
|
{
|
||||||
|
yield return new FloatMenuOption("CannotEnterPowerArmor".Translate() + ": " + "CannotReach".Translate(), null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void enterAction()
|
||||||
|
{
|
||||||
|
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_EnterPowerArmor"), parent);
|
||||||
|
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
||||||
|
}
|
||||||
|
yield return new FloatMenuOption("EnterPowerArmor".Translate(parent.Label), enterAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using HarmonyLib;
|
|
||||||
using RimWorld;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Verse;
|
|
||||||
using Verse.AI;
|
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
|
||||||
{
|
|
||||||
[HarmonyPatch(typeof(ThingWithComps), "GetFloatMenuOptions")]
|
|
||||||
public static class Harmony_ThingWithComps_GetFloatMenuOptions
|
|
||||||
{
|
|
||||||
[HarmonyPostfix]
|
|
||||||
public static IEnumerable<FloatMenuOption> Postfix(IEnumerable<FloatMenuOption> values, ThingWithComps __instance, Pawn selPawn)
|
|
||||||
{
|
|
||||||
// First, return all original options
|
|
||||||
foreach (var value in values)
|
|
||||||
{
|
|
||||||
yield return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- DEBUG LOGGING ---
|
|
||||||
// Use a more specific check to avoid log spam
|
|
||||||
if (__instance.def.defName != null && __instance.def.defName.StartsWith("ARA_"))
|
|
||||||
{
|
|
||||||
Log.Message($"[PA_Debug] GetFloatMenuOptions Postfix triggered for: {__instance.def.defName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if the thing is our power armor building
|
|
||||||
var comp = __instance.GetComp<CompPowerArmorStation>();
|
|
||||||
|
|
||||||
if (comp == null && __instance.def.defName != null && __instance.def.defName.StartsWith("ARA_"))
|
|
||||||
{
|
|
||||||
Log.Message($"[PA_Debug] CompPowerArmorStation is NULL for {__instance.def.defName}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comp != null)
|
|
||||||
{
|
|
||||||
Log.Message($"[PA_Debug] CompPowerArmorStation FOUND for {__instance.def.defName}. Checking reachability.");
|
|
||||||
|
|
||||||
// Check if the pawn can interact
|
|
||||||
if (!selPawn.CanReserveAndReach(__instance, PathEndMode.InteractionCell, Danger.Deadly))
|
|
||||||
{
|
|
||||||
yield return new FloatMenuOption("CannotEnterPowerArmor".Translate() + ": " + "CannotReach".Translate(), null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Action to give the job
|
|
||||||
void enterAction()
|
|
||||||
{
|
|
||||||
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_EnterPowerArmor"), __instance);
|
|
||||||
selPawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
|
|
||||||
}
|
|
||||||
|
|
||||||
yield return new FloatMenuOption("EnterPowerArmor".Translate(__instance.Label), enterAction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -50,11 +50,38 @@ namespace ArachnaeSwarm
|
|||||||
apparelFuelComp.ReceiveFuel(buildingFuelComp.Fuel);
|
apparelFuelComp.ReceiveFuel(buildingFuelComp.Fuel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync quality
|
||||||
|
if (building.TryGetComp<CompQuality>() is CompQuality buildingQuality && apparel.TryGetComp<CompQuality>() is CompQuality apparelQuality)
|
||||||
|
{
|
||||||
|
apparelQuality.SetQuality(buildingQuality.Quality, ArtGenerationContext.Colony);
|
||||||
|
}
|
||||||
|
|
||||||
// Wear the apparel. The second argument 'false' is lockWhileWorn.
|
// Wear the apparel. The second argument 'false' is lockWhileWorn.
|
||||||
// The third argument 'false' is playerForced, which is CRITICAL.
|
// The third argument 'false' is playerForced, which is CRITICAL.
|
||||||
// If playerForced is true, the game automatically locks the apparel.
|
// If playerForced is true, the game automatically locks the apparel.
|
||||||
actor.apparel.Wear(apparel, false, false);
|
actor.apparel.Wear(apparel, false, false);
|
||||||
|
|
||||||
|
// Handle weapon switching
|
||||||
|
if (apparel.Ext.powerArmorWeapon != null)
|
||||||
|
{
|
||||||
|
if (actor.equipment.Primary != null)
|
||||||
|
{
|
||||||
|
apparel.SetOriginalWeapon(actor.equipment.Primary);
|
||||||
|
actor.equipment.TryDropEquipment(actor.equipment.Primary, out _, actor.Position, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingWithComps weapon = (ThingWithComps)ThingMaker.MakeThing(apparel.Ext.powerArmorWeapon);
|
||||||
|
|
||||||
|
// Sync weapon quality with armor quality
|
||||||
|
if (apparel.TryGetComp<CompQuality>() is CompQuality existingApparelQuality && weapon.TryGetComp<CompQuality>() is CompQuality weaponQuality)
|
||||||
|
{
|
||||||
|
weaponQuality.SetQuality(existingApparelQuality.Quality, ArtGenerationContext.Colony);
|
||||||
|
}
|
||||||
|
|
||||||
|
actor.equipment.MakeRoomFor(weapon);
|
||||||
|
actor.equipment.AddEquipment(weapon);
|
||||||
|
}
|
||||||
|
|
||||||
// Despawn the building
|
// Despawn the building
|
||||||
building.DeSpawn();
|
building.DeSpawn();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user