diff --git a/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
index 154a0445ba..52d2173cb5 100644
--- a/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
+++ b/Source/CombatExtended/CombatExtended/Comps/CompAmmoUser.cs
@@ -337,36 +337,12 @@ private void AssignJobToWielder(Job job)
}
}
- public bool Notify_ShotFired()
- {
- if (ammoToBeDeleted != null)
- {
- ammoToBeDeleted.Destroy();
- ammoToBeDeleted = null;
- CompInventory.UpdateInventory();
- if (!HasAmmoOrMagazine)
- {
- return false;
- }
- }
- return true;
- }
-
- public bool Notify_PostShotFired()
- {
- if (!HasAmmoOrMagazine)
- {
- DoOutOfAmmoAction();
- return false;
- }
- return true;
- }
///
/// Reduces ammo count and updates inventory if necessary, call this whenever ammo is consumed by the gun (e.g. firing a shot, clearing a jam).
/// Has an optional argument for the amount of ammo to consume per shot, which defaults to 1; this caters for special cases such as different sci-fi weapons using up different amounts of the same energy cell ammo type per shot, or a double-barrelled shotgun that fires both cartridges at the same time (projectile treated as a single, more powerful bullet)
///
- public bool TryReduceAmmoCount(int ammoConsumedPerShot = 1)
+ public void Notify_ShotFired(int ammoConsumedPerShot = 1)
{
ammoConsumedPerShot = (ammoConsumedPerShot > 0) ? ammoConsumedPerShot : 1;
@@ -378,48 +354,72 @@ public bool TryReduceAmmoCount(int ammoConsumedPerShot = 1)
// Mag-less weapons feed directly from inventory
if (!HasMagazine)
{
- if (UseAmmo)
+ if (ammoToBeDeleted != null)
{
- if (!TryFindAmmoInInventory(out ammoToBeDeleted))
- {
- return false;
- }
- if (ammoToBeDeleted.def != CurrentAmmo)
- {
- currentAmmoInt = ammoToBeDeleted.def as AmmoDef;
- }
-
- if (ammoToBeDeleted.stackCount > 1)
- {
- ammoToBeDeleted = ammoToBeDeleted.SplitOff(1);
- }
+ ammoToBeDeleted.Destroy();
+ ammoToBeDeleted = null;
+ CompInventory.UpdateInventory();
}
- return true;
}
- // If magazine is empty, return false
+
if (curMagCountInt <= 0)
{
- CurMagCount = 0;
- return false;
+ Log.Error($"{parent} tried reducing its ammo count when already empty");
}
// Reduce ammo count and update inventory
CurMagCount = (curMagCountInt - ammoConsumedPerShot < 0) ? 0 : curMagCountInt - ammoConsumedPerShot;
+ }
-
- /*if (curMagCountInt - ammoConsumedPerShot < 0)
+ public bool Notify_PostShotFired()
+ {
+ if (!HasAmmoOrMagazine)
{
- curMagCountInt = 0;
- } else
+ DoOutOfAmmoAction();
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// Check whether ammo is available for firing a shot.
+ ///
+ ///
+ /// For weapons without a magazine, this may update the currently selected ammo type
+ /// if we ran out of the currently selected ammo type but have different, compatible, types
+ /// available in the inventory.
+ ///
+ ///
+ public bool TryPrepareShot()
+ {
+ if (HasMagazine)
{
- curMagCountInt = curMagCountInt - ammoConsumedPerShot;
- }*/
+ // If magazine is empty, return false
+ if (curMagCountInt <= 0)
+ {
+ CurMagCount = 0;
+ return false;
+ }
+ return true;
+ }
- // Original: curMagCountInt--;
- if (curMagCountInt < 0)
+ if (UseAmmo)
{
- TryStartReload();
+ if (!TryFindAmmoInInventory(out ammoToBeDeleted))
+ {
+ return false;
+ }
+ if (ammoToBeDeleted.def != CurrentAmmo)
+ {
+ currentAmmoInt = ammoToBeDeleted.def as AmmoDef;
+ }
+
+ if (ammoToBeDeleted.stackCount > 1)
+ {
+ ammoToBeDeleted = ammoToBeDeleted.SplitOff(1);
+ }
}
+
return true;
}
diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs
index 5336478f0d..c1102daf44 100644
--- a/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs
+++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_LaunchProjectileCE.cs
@@ -33,7 +33,7 @@ public class Verb_LaunchProjectileCE : Verb
protected float distance = 10f;
public CompCharges compCharges = null;
- public CompAmmoUser compAmmo = null;
+
public CompFireModes compFireModes = null;
public CompChangeableProjectile compChangeable = null;
public CompApparelReloadable compReloadable = null;
@@ -139,26 +139,10 @@ public float ShootingAccuracy
public float SightsEfficiency => EquipmentSource?.GetStatValue(CE_StatDefOf.SightsEfficiency) ?? 1f;
public virtual float SwayAmplitude => Mathf.Max(0, (4.5f - ShootingAccuracy) * (EquipmentSource?.GetStatValue(CE_StatDefOf.SwayFactor) ?? 1f));
- // Ammo variables
- public virtual CompAmmoUser CompAmmo
- {
- get
- {
- if (compAmmo == null && EquipmentSource != null)
- {
- compAmmo = EquipmentSource.TryGetComp();
- }
- return compAmmo;
- }
- }
public virtual ThingDef Projectile
{
get
{
- if (CompAmmo != null && CompAmmo.CurrentAmmo != null)
- {
- return CompAmmo.CurAmmoProjectile;
- }
if (CompChangeable != null && CompChangeable.Loaded)
{
return CompChangeable.Projectile;
@@ -220,8 +204,6 @@ public float RecoilAmount
}
}
- private bool IsAttacking => ShooterPawn?.CurJobDef == JobDefOf.AttackStatic || WarmingUp;
-
private LightingTracker _lightingTracker = null;
protected LightingTracker LightingTracker
{
@@ -286,14 +268,7 @@ public override bool Available()
}
}
- // Add check for reload
- if (Projectile == null || (IsAttacking && CompAmmo != null && !CompAmmo.CanBeFiredNow))
- {
- CompAmmo?.TryStartReload();
- resetRetarget();
- return false;
- }
- return true;
+ return Projectile != null;
}
///
@@ -471,19 +446,13 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO
Apparel LegArmor = LegArmors.MaxByWithFallback(funcArmor);
#endregion
- #region get CompAmmo's Current ammo projectile
-
- var ProjCE = (ProjectilePropertiesCE)compAmmo?.CurAmmoProjectile?.projectile ?? null;
-
- #endregion
-
#region checks for whether the pawn can penetrate armor, which armor is stronger, etc
var TargetedBodyPartArmor = TorsoArmor;
bool flagTorsoArmor = ((TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f));
- bool flag2 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f));
+ bool flag2 = (projectilePropsCE.armorPenetrationSharp >= (TorsoArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f));
//Headshots do too little damage too often, so if the pawn can penetrate torso armor, they should aim at it
if ((flagTorsoArmor && !flag2))
{
@@ -493,7 +462,7 @@ public virtual void ShiftTarget(ShiftVecReport report, bool calculateMechanicalO
bool flag3 = (TargetedBodyPartArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) >= ((LegArmor?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0f) + 4f);
//bool for whether the pawn can penetrate helmet
- bool flag4 = ((ProjCE?.armorPenetrationSharp ?? 0f) >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f));
+ bool flag4 = (projectilePropsCE.armorPenetrationSharp >= (Helmet?.GetStatValue(StatDefOf.ArmorRating_Sharp) ?? 0.1f));
//if the pawn can penetrate the helmet or torso armor there's no need to aim for legs
if (flag3 && (!flag4) && (!flag2))
@@ -1116,11 +1085,6 @@ public override bool TryCastShot()
numShotsFired++;
if (ShooterPawn != null)
{
- if (CompAmmo != null && !CompAmmo.CanBeFiredNow)
- {
- CompAmmo?.TryStartReload();
- resetRetarget();
- }
if (CompReloadable != null)
{
CompReloadable.UsedOnce();
diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs
index dc1b5636d5..92bad73fa4 100644
--- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs
+++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs
@@ -31,6 +31,8 @@ public class Verb_ShootCE : Verb_LaunchProjectileCE
public Vector3 drawPos;
+ private CompAmmoUser compAmmo;
+
#endregion
#region Properties
@@ -126,6 +128,17 @@ public float AimAngle
// Whether our shooter is currently under suppressive fire
private bool IsSuppressed => ShooterPawn?.TryGetComp()?.isSuppressed ?? false;
+ public CompAmmoUser CompAmmo
+ {
+ get
+ {
+ compAmmo ??= EquipmentSource?.TryGetComp();
+ return compAmmo;
+ }
+ }
+
+ public override ThingDef Projectile => CompAmmo?.CurrentAmmo != null ? CompAmmo.CurAmmoProjectile : base.Projectile;
+
#endregion
#region Methods
@@ -240,6 +253,25 @@ public override void WarmupComplete()
}
}
+ public override bool Available()
+ {
+ if (!base.Available())
+ {
+ return false;
+ }
+
+ // Add check for reload
+ bool isAttacking = ShooterPawn?.CurJobDef == JobDefOf.AttackStatic || WarmingUp;
+ if (isAttacking && !(CompAmmo?.CanBeFiredNow ?? true))
+ {
+ CompAmmo?.TryStartReload();
+ resetRetarget();
+ return false;
+ }
+
+ return true;
+ }
+
public override void VerbTickCE()
{
if (_isAiming)
@@ -344,13 +376,9 @@ public void ExternalCallDropCasing(int randomSeedOffset = -1)
public override bool TryCastShot()
{
- //Reduce ammunition
- if (CompAmmo != null)
+ if (!CompAmmo?.TryPrepareShot() ?? false)
{
- if (!CompAmmo.TryReduceAmmoCount(((CompAmmo.Props.ammoSet != null) ? CompAmmo.Props.ammoSet.ammoConsumedPerShot : 1) * VerbPropsCE.ammoConsumedPerShotCount))
- {
- return false;
- }
+ return false;
}
if (base.TryCastShot())
{
@@ -374,10 +402,25 @@ protected virtual bool OnCastSuccessful()
{
CE_Utility.GenerateAmmoCasings(projectilePropsCE, fromPawn ? drawPos : caster.DrawPos, caster.Map, AimAngle, VerbPropsCE.recoilAmount, fromPawn: fromPawn, extension: ext);
}
+
+ if (CompAmmo == null)
+ {
+ return true;
+ }
+
+ int ammoConsumedPerShot = (CompAmmo.Props.ammoSet?.ammoConsumedPerShot ?? 1) * VerbPropsCE.ammoConsumedPerShotCount;
+ CompAmmo.Notify_ShotFired(ammoConsumedPerShot);
+
+ if (ShooterPawn != null && !CompAmmo.CanBeFiredNow)
+ {
+ CompAmmo.TryStartReload();
+ resetRetarget();
+ }
+
// This needs to here for weapons without magazine to ensure their last shot plays sounds
- if (CompAmmo != null && !CompAmmo.HasMagazine && CompAmmo.UseAmmo)
+ if (!CompAmmo.HasMagazine && CompAmmo.UseAmmo)
{
- if (!CompAmmo.Notify_ShotFired())
+ if (!CompAmmo.HasAmmoOrMagazine)
{
if (VerbPropsCE.muzzleFlashScale > 0.01f)
{
diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootMortarCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootMortarCE.cs
index 9b86b0d4bb..709d93e1b1 100644
--- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootMortarCE.cs
+++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootMortarCE.cs
@@ -206,10 +206,6 @@ public virtual bool TryCastGlobalShot()
numShotsFired++;
if (ShooterPawn != null)
{
- if (CompAmmo != null && !CompAmmo.CanBeFiredNow)
- {
- CompAmmo?.TryStartReload();
- }
if (CompReloadable != null)
{
CompReloadable.UsedOnce();
@@ -225,13 +221,7 @@ public override bool TryCastShot()
{
return base.TryCastShot();
}
- if (CompAmmo != null)
- {
- if (!CompAmmo.TryReduceAmmoCount(CompAmmo.Props.ammoSet.ammoConsumedPerShot * VerbPropsCE.ammoConsumedPerShotCount))
- {
- return false;
- }
- }
+
if (this.TryCastGlobalShot())
{
return this.OnCastSuccessful();