feat(weapons): 为多种武器添加偏移射击功能并更新相关配置
为多个武器定义添加了带偏移的射击 Verb 类,并引入 `ArachnaeSwarm.ModExtension_ShootWithOffset` 扩展以支持 自定义射击位置偏移。同时优化了 `CompGiveHediffOnShot` 组件的 Harmony 补丁逻辑,使其兼容新 Verb 类型。 此外,调整了 Swarm Turret 的电力消耗逻辑和建造成本,
This commit is contained in:
Binary file not shown.
@@ -415,7 +415,7 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>Verb_Shoot</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
||||||
<warmupTime>0.8</warmupTime>
|
<warmupTime>0.8</warmupTime>
|
||||||
@@ -457,6 +457,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
<ThingDef ParentName="BaseHumanMakeableGun">
|
<ThingDef ParentName="BaseHumanMakeableGun">
|
||||||
<defName>ARA_RW_Toxic_Needle_SG</defName>
|
<defName>ARA_RW_Toxic_Needle_SG</defName>
|
||||||
@@ -493,7 +500,7 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>ArachnaeSwarm.Verb_ShootShotgun</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootShotgunWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
||||||
<warmupTime>0.8</warmupTime>
|
<warmupTime>0.8</warmupTime>
|
||||||
@@ -535,6 +542,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
<ThingDef ParentName="BaseBullet">
|
<ThingDef ParentName="BaseBullet">
|
||||||
<defName>ARA_Bullet_SniperCannon</defName>
|
<defName>ARA_Bullet_SniperCannon</defName>
|
||||||
@@ -587,7 +601,7 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>Verb_Shoot</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<defaultProjectile>ARA_Bullet_SniperCannon</defaultProjectile>
|
<defaultProjectile>ARA_Bullet_SniperCannon</defaultProjectile>
|
||||||
<warmupTime>2.5</warmupTime>
|
<warmupTime>2.5</warmupTime>
|
||||||
@@ -632,6 +646,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
<ThingDef ParentName="BaseBullet">
|
<ThingDef ParentName="BaseBullet">
|
||||||
<defName>ARA_Bullet_Rail</defName>
|
<defName>ARA_Bullet_Rail</defName>
|
||||||
@@ -693,7 +714,7 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>Verb_Shoot</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<defaultProjectile>ARA_Bullet_Rail</defaultProjectile>
|
<defaultProjectile>ARA_Bullet_Rail</defaultProjectile>
|
||||||
<warmupTime>2.5</warmupTime>
|
<warmupTime>2.5</warmupTime>
|
||||||
@@ -734,6 +755,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
<!-- 酸 -->
|
<!-- 酸 -->
|
||||||
@@ -1150,7 +1178,7 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>ArachnaeSwarm.Verb_ShootShotgun</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootShotgunWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
||||||
<warmupTime>3</warmupTime>
|
<warmupTime>3</warmupTime>
|
||||||
@@ -1193,6 +1221,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
<ThingDef ParentName="BaseBullet">
|
<ThingDef ParentName="BaseBullet">
|
||||||
<defName>Bullet_RW_Missile_HG_Gun</defName>
|
<defName>Bullet_RW_Missile_HG_Gun</defName>
|
||||||
@@ -1275,13 +1310,13 @@
|
|||||||
</statBases>
|
</statBases>
|
||||||
<verbs>
|
<verbs>
|
||||||
<li>
|
<li>
|
||||||
<verbClass>Verb_Shoot</verbClass>
|
<verbClass>ArachnaeSwarm.Verb_ShootWithOffset</verbClass>
|
||||||
<hasStandardCommand>true</hasStandardCommand>
|
<hasStandardCommand>true</hasStandardCommand>
|
||||||
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
<forceNormalTimeSpeed>false</forceNormalTimeSpeed>
|
||||||
<warmupTime>4.5</warmupTime>
|
<warmupTime>2.8</warmupTime>
|
||||||
<defaultProjectile>Bullet_RW_Missile_AR_Gun</defaultProjectile>
|
<defaultProjectile>Bullet_RW_Missile_AR_Gun</defaultProjectile>
|
||||||
<range>38</range>
|
<range>38</range>
|
||||||
<burstShotCount>12</burstShotCount>
|
<burstShotCount>10</burstShotCount>
|
||||||
<ticksBetweenBurstShots>4</ticksBetweenBurstShots>
|
<ticksBetweenBurstShots>4</ticksBetweenBurstShots>
|
||||||
<soundCast>SpitterSpit</soundCast>
|
<soundCast>SpitterSpit</soundCast>
|
||||||
<targetParams>
|
<targetParams>
|
||||||
@@ -1319,6 +1354,13 @@
|
|||||||
</numTraitsRange>
|
</numTraitsRange>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="ArachnaeSwarm.ModExtension_ShootWithOffset">
|
||||||
|
<offsets>
|
||||||
|
<li>(0, -1.4)</li>
|
||||||
|
</offsets>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
<ThingDef ParentName="BaseBullet">
|
<ThingDef ParentName="BaseBullet">
|
||||||
<defName>Bullet_RW_Missile_AR_Gun</defName>
|
<defName>Bullet_RW_Missile_AR_Gun</defName>
|
||||||
|
|||||||
@@ -141,7 +141,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li Class="CompProperties_MechPowerCell">
|
<li Class="CompProperties_MechPowerCell">
|
||||||
<totalPowerTicks>600000</totalPowerTicks>
|
<totalPowerTicks>600000</totalPowerTicks>
|
||||||
<killWhenDepleted>true</killWhenDepleted>
|
<killWhenDepleted>false</killWhenDepleted>
|
||||||
<labelOverride>寿命</labelOverride>
|
<labelOverride>寿命</labelOverride>
|
||||||
<tooltipOverride>这种半植物生命的寿命转瞬即逝。</tooltipOverride>
|
<tooltipOverride>这种半植物生命的寿命转瞬即逝。</tooltipOverride>
|
||||||
</li>
|
</li>
|
||||||
@@ -357,6 +357,9 @@
|
|||||||
<ShootingAccuracyTurret>0.9</ShootingAccuracyTurret>
|
<ShootingAccuracyTurret>0.9</ShootingAccuracyTurret>
|
||||||
<Beauty>-20</Beauty>
|
<Beauty>-20</Beauty>
|
||||||
</statBases>
|
</statBases>
|
||||||
|
<costList>
|
||||||
|
<ARA_Carapace>50</ARA_Carapace>
|
||||||
|
</costList>
|
||||||
<damageMultipliers>
|
<damageMultipliers>
|
||||||
<li>
|
<li>
|
||||||
<damageDef>Flame</damageDef>
|
<damageDef>Flame</damageDef>
|
||||||
@@ -506,6 +509,9 @@
|
|||||||
<ShootingAccuracyTurret>0.9</ShootingAccuracyTurret>
|
<ShootingAccuracyTurret>0.9</ShootingAccuracyTurret>
|
||||||
<Beauty>-20</Beauty>
|
<Beauty>-20</Beauty>
|
||||||
</statBases>
|
</statBases>
|
||||||
|
<costList>
|
||||||
|
<ARA_Carapace>50</ARA_Carapace>
|
||||||
|
</costList>
|
||||||
<damageMultipliers>
|
<damageMultipliers>
|
||||||
<li>
|
<li>
|
||||||
<damageDef>Flame</damageDef>
|
<damageDef>Flame</damageDef>
|
||||||
|
|||||||
@@ -233,6 +233,7 @@
|
|||||||
<Compile Include="Verbs\Verb_ShootArc.cs" />
|
<Compile Include="Verbs\Verb_ShootArc.cs" />
|
||||||
<Compile Include="Verbs\Verb_ShootMeltBeam.cs" />
|
<Compile Include="Verbs\Verb_ShootMeltBeam.cs" />
|
||||||
<Compile Include="Verbs\Verb_ShootShotgun.cs" />
|
<Compile Include="Verbs\Verb_ShootShotgun.cs" />
|
||||||
|
<Compile Include="Verbs\Verb_ShootShotgunWithOffset.cs" />
|
||||||
<Compile Include="Verbs\Verb_ShootFireSpew.cs" />
|
<Compile Include="Verbs\Verb_ShootFireSpew.cs" />
|
||||||
<Compile Include="Verbs\VerbProperties_FireSpew.cs" />
|
<Compile Include="Verbs\VerbProperties_FireSpew.cs" />
|
||||||
<Compile Include="Verbs\Verb_ShootConsumeNutrition.cs" />
|
<Compile Include="Verbs\Verb_ShootConsumeNutrition.cs" />
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Verse;
|
|||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
// 1. 定义CompProperties来存储我们的数据
|
|
||||||
public class CompProperties_GiveHediffOnShot : CompProperties
|
public class CompProperties_GiveHediffOnShot : CompProperties
|
||||||
{
|
{
|
||||||
public HediffDef hediffDef;
|
public HediffDef hediffDef;
|
||||||
@@ -16,60 +15,68 @@ namespace ArachnaeSwarm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 创建一个简单的Comp来挂载到武器上,它只负责持有数据
|
|
||||||
public class CompGiveHediffOnShot : ThingComp
|
public class CompGiveHediffOnShot : ThingComp
|
||||||
{
|
{
|
||||||
public CompProperties_GiveHediffOnShot Props => (CompProperties_GiveHediffOnShot)props;
|
public CompProperties_GiveHediffOnShot Props => (CompProperties_GiveHediffOnShot)props;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 创建Harmony补丁
|
// Patch 1: For all standard projectile verbs.
|
||||||
// 补丁目标为 Verb_LaunchProjectile.TryCastShot。这是所有发射弹丸动作的通用入口。
|
|
||||||
[HarmonyPatch(typeof(Verb_LaunchProjectile), "TryCastShot")]
|
[HarmonyPatch(typeof(Verb_LaunchProjectile), "TryCastShot")]
|
||||||
public static class Patch_Verb_Shoot_TryCastShot
|
public static class Patch_Verb_LaunchProjectile_TryCastShot
|
||||||
{
|
{
|
||||||
// 使用[HarmonyPostfix]特性来创建一个在原方法执行后运行的补丁
|
public static void Postfix(Verb_LaunchProjectile __instance, bool __result)
|
||||||
// 添加一个bool类型的返回值`__result`,它代表了原方法的返回值
|
|
||||||
public static void Postfix(Verb_Shoot __instance, bool __result)
|
|
||||||
{
|
{
|
||||||
// __result 是原方法 TryCastShot 的返回值。
|
if (!__result) return;
|
||||||
// 如果 __result 为 false,意味着射击动作因某些原因(如目标无效、没有弹药)失败了,我们就不应该添加Hediff。
|
if (__instance.CasterPawn == null || __instance.EquipmentSource == null) return;
|
||||||
if (!__result)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// __instance是原方法的实例对象,也就是那个Verb_Shoot
|
|
||||||
// 检查这个Verb是否来源于一个装备(武器)
|
|
||||||
if (__instance.EquipmentSource == null || __instance.CasterPawn == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 尝试从武器上获取我们自定义的Comp
|
|
||||||
CompGiveHediffOnShot comp = __instance.EquipmentSource.GetComp<CompGiveHediffOnShot>();
|
CompGiveHediffOnShot comp = __instance.EquipmentSource.GetComp<CompGiveHediffOnShot>();
|
||||||
if (comp == null)
|
if (comp == null || comp.Props.hediffDef == null) return;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查XML中是否配置了hediffDef
|
|
||||||
if (comp.Props.hediffDef == null)
|
|
||||||
{
|
|
||||||
Log.ErrorOnce($"[ArachnaeSwarm] CompGiveHediffOnShot on {__instance.EquipmentSource.def.defName} has null hediffDef.", __instance.EquipmentSource.def.GetHashCode());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 为射击者(CasterPawn)添加或增加Hediff的严重性
|
|
||||||
Hediff hediff = __instance.CasterPawn.health.GetOrAddHediff(comp.Props.hediffDef);
|
Hediff hediff = __instance.CasterPawn.health.GetOrAddHediff(comp.Props.hediffDef);
|
||||||
hediff.Severity += comp.Props.severityToAdd;
|
hediff.Severity += comp.Props.severityToAdd;
|
||||||
|
|
||||||
// 检查Hediff是否带有HediffComp_Disappears组件
|
var disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
|
||||||
HediffComp_Disappears disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
|
disappearsComp?.ResetElapsedTicks();
|
||||||
if (disappearsComp != null)
|
}
|
||||||
{
|
}
|
||||||
// 如果有,则调用正确的方法重置它的消失计时器
|
|
||||||
disappearsComp.ResetElapsedTicks();
|
// Patch 2: Specifically for Verb_ShootWithOffset.
|
||||||
}
|
[HarmonyPatch(typeof(Verb_ShootWithOffset), "TryCastShot")]
|
||||||
|
public static class Patch_Verb_ShootWithOffset_TryCastShot
|
||||||
|
{
|
||||||
|
public static void Postfix(Verb_ShootWithOffset __instance, bool __result)
|
||||||
|
{
|
||||||
|
if (!__result) return;
|
||||||
|
if (__instance.CasterPawn == null || __instance.EquipmentSource == null) return;
|
||||||
|
|
||||||
|
CompGiveHediffOnShot comp = __instance.EquipmentSource.GetComp<CompGiveHediffOnShot>();
|
||||||
|
if (comp == null || comp.Props.hediffDef == null) return;
|
||||||
|
|
||||||
|
Hediff hediff = __instance.CasterPawn.health.GetOrAddHediff(comp.Props.hediffDef);
|
||||||
|
hediff.Severity += comp.Props.severityToAdd;
|
||||||
|
|
||||||
|
var disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
|
||||||
|
disappearsComp?.ResetElapsedTicks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Patch 3: Specifically for our new Verb_ShootShotgunWithOffset.
|
||||||
|
[HarmonyPatch(typeof(Verb_ShootShotgunWithOffset), "TryCastShot")]
|
||||||
|
public static class Patch_Verb_ShootShotgunWithOffset_TryCastShot
|
||||||
|
{
|
||||||
|
public static void Postfix(Verb_ShootShotgunWithOffset __instance, bool __result)
|
||||||
|
{
|
||||||
|
if (!__result) return;
|
||||||
|
if (__instance.CasterPawn == null || __instance.EquipmentSource == null) return;
|
||||||
|
|
||||||
|
CompGiveHediffOnShot comp = __instance.EquipmentSource.GetComp<CompGiveHediffOnShot>();
|
||||||
|
if (comp == null || comp.Props.hediffDef == null) return;
|
||||||
|
|
||||||
|
Hediff hediff = __instance.CasterPawn.health.GetOrAddHediff(comp.Props.hediffDef);
|
||||||
|
hediff.Severity += comp.Props.severityToAdd;
|
||||||
|
|
||||||
|
var disappearsComp = hediff.TryGetComp<HediffComp_Disappears>();
|
||||||
|
disappearsComp?.ResetElapsedTicks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
158
Source/ArachnaeSwarm/Verbs/Verb_ShootShotgunWithOffset.cs
Normal file
158
Source/ArachnaeSwarm/Verbs/Verb_ShootShotgunWithOffset.cs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class Verb_ShootShotgunWithOffset : Verb_Shoot
|
||||||
|
{
|
||||||
|
protected override bool TryCastShot()
|
||||||
|
{
|
||||||
|
// Fire the first shot
|
||||||
|
bool initialShotSuccess = this.BaseTryCastShot(0);
|
||||||
|
if (initialShotSuccess && CasterIsPawn)
|
||||||
|
{
|
||||||
|
CasterPawn.records.Increment(RecordDefOf.ShotsFired);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get shotgun extension
|
||||||
|
ShotgunExtension shotgunExtension = ShotgunExtension.Get(this.verbProps.defaultProjectile);
|
||||||
|
if (initialShotSuccess && shotgunExtension != null && shotgunExtension.pelletCount > 1)
|
||||||
|
{
|
||||||
|
// Fire the rest of the pellets in a loop
|
||||||
|
for (int i = 1; i < shotgunExtension.pelletCount; i++)
|
||||||
|
{
|
||||||
|
this.BaseTryCastShot(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return initialShotSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected bool BaseTryCastShot(int pelletIndex)
|
||||||
|
{
|
||||||
|
if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThingDef projectile = Projectile;
|
||||||
|
if (projectile == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShootLine resultingLine;
|
||||||
|
bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out resultingLine);
|
||||||
|
if (verbProps.stopBurstWithoutLos && !flag)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (base.EquipmentSource != null)
|
||||||
|
{
|
||||||
|
base.EquipmentSource.GetComp<CompChangeableProjectile>()?.Notify_ProjectileLaunched();
|
||||||
|
base.EquipmentSource.GetComp<CompApparelVerbOwner_Charged>()?.UsedOnce();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastShotTick = Find.TickManager.TicksGame;
|
||||||
|
Thing manningPawn = caster;
|
||||||
|
Thing equipmentSource = base.EquipmentSource;
|
||||||
|
CompMannable compMannable = caster.TryGetComp<CompMannable>();
|
||||||
|
if (compMannable?.ManningPawn != null)
|
||||||
|
{
|
||||||
|
manningPawn = compMannable.ManningPawn;
|
||||||
|
equipmentSource = caster;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 drawPos = caster.DrawPos;
|
||||||
|
drawPos = ApplyProjectileOffset(drawPos, equipmentSource, pelletIndex);
|
||||||
|
Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, resultingLine.Source, caster.Map);
|
||||||
|
if (equipmentSource.TryGetComp(out CompUniqueWeapon comp))
|
||||||
|
{
|
||||||
|
foreach (WeaponTraitDef item in comp.TraitsListForReading)
|
||||||
|
{
|
||||||
|
if (item.damageDefOverride != null)
|
||||||
|
{
|
||||||
|
projectile2.damageDefOverride = item.damageDefOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!item.extraDamages.NullOrEmpty())
|
||||||
|
{
|
||||||
|
if (projectile2.extraDamages == null)
|
||||||
|
{
|
||||||
|
projectile2.extraDamages = new List<ExtraDamage>();
|
||||||
|
}
|
||||||
|
projectile2.extraDamages.AddRange(item.extraDamages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbProps.ForcedMissRadius > 0.5f)
|
||||||
|
{
|
||||||
|
float num = verbProps.ForcedMissRadius;
|
||||||
|
if (manningPawn is Pawn pawn)
|
||||||
|
{
|
||||||
|
num *= verbProps.GetForceMissFactorFor(equipmentSource, pawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
float num2 = VerbUtility.CalculateAdjustedForcedMiss(num, currentTarget.Cell - caster.Position);
|
||||||
|
if (num2 > 0.5f)
|
||||||
|
{
|
||||||
|
IntVec3 forcedMissTarget = GetForcedMissTarget(num2);
|
||||||
|
if (forcedMissTarget != currentTarget.Cell)
|
||||||
|
{
|
||||||
|
projectile2.Launch(manningPawn, drawPos, forcedMissTarget, currentTarget, ProjectileHitFlags.All, preventFriendlyFire, equipmentSource);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget);
|
||||||
|
if (verbProps.canGoWild && !Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture))
|
||||||
|
{
|
||||||
|
bool flyOverhead = projectile2?.def?.projectile != null && projectile2.def.projectile.flyOverhead;
|
||||||
|
resultingLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget, flyOverhead, caster.Map);
|
||||||
|
projectile2.Launch(manningPawn, drawPos, resultingLine.Dest, currentTarget, ProjectileHitFlags.NonTargetWorld, preventFriendlyFire, equipmentSource, shotReport.GetRandomCoverToMissInto()?.def);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTarget.Thing != null && currentTarget.Thing.def.CanBenefitFromCover && !Rand.Chance(shotReport.PassCoverChance))
|
||||||
|
{
|
||||||
|
projectile2.Launch(manningPawn, drawPos, shotReport.GetRandomCoverToMissInto(), currentTarget, ProjectileHitFlags.NonTargetWorld, preventFriendlyFire, equipmentSource, shotReport.GetRandomCoverToMissInto()?.def);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
projectile2.Launch(manningPawn, drawPos, currentTarget, currentTarget, ProjectileHitFlags.IntendedTarget, preventFriendlyFire, equipmentSource, shotReport.GetRandomCoverToMissInto()?.def);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Vector3 ApplyProjectileOffset(Vector3 originalDrawPos, Thing equipmentSource, int pelletIndex)
|
||||||
|
{
|
||||||
|
if (equipmentSource != null)
|
||||||
|
{
|
||||||
|
ModExtension_ShootWithOffset offsetExtension = (base.EquipmentSource?.def)?.GetModExtension<ModExtension_ShootWithOffset>();
|
||||||
|
|
||||||
|
if (offsetExtension != null && offsetExtension.offsets != null && offsetExtension.offsets.Count > 0)
|
||||||
|
{
|
||||||
|
Vector2 offset = offsetExtension.GetOffsetFor(pelletIndex);
|
||||||
|
|
||||||
|
Vector3 targetPos = currentTarget.CenterVector3;
|
||||||
|
Vector3 casterPos = caster.DrawPos;
|
||||||
|
float rimworldAngle = targetPos.AngleToFlat(casterPos);
|
||||||
|
|
||||||
|
float correctedAngle = -rimworldAngle - 90f;
|
||||||
|
|
||||||
|
Vector2 rotatedOffset = offset.RotatedBy(correctedAngle);
|
||||||
|
|
||||||
|
originalDrawPos += new Vector3(rotatedOffset.x, 0f, rotatedOffset.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalDrawPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user