diff --git a/Source/CombatExtended/CombatExtended/CE_Utility.cs b/Source/CombatExtended/CombatExtended/CE_Utility.cs index b4b9af0c63..25429f39d5 100644 --- a/Source/CombatExtended/CombatExtended/CE_Utility.cs +++ b/Source/CombatExtended/CombatExtended/CE_Utility.cs @@ -736,32 +736,50 @@ public static Thing GetWeaponFromLauncher(Thing launcher) #endregion Misc #region MoteThrower - public static void ThrowEmptyCasing(Vector3 loc, Map map, FleckDef casingFleckDef, float size = 1f) + public static void GenerateAmmoCasings(ProjectilePropertiesCE projProps, Vector3 drawPosition, Map map, float shotRotation = -180f, float recoilAmount = 2f) { - if (!Controller.settings.ShowCasings || !loc.ShouldSpawnMotesAt(map) || map.moteCounter.SaturatedLowPriority) + if (projProps.dropsCasings) { - return; + if (Controller.settings.ShowCasings) + { + ThrowEmptyCasing(drawPosition, map, DefDatabase.GetNamed(projProps.casingMoteDefname), recoilAmount, shotRotation); + } + if (Controller.settings.CreateCasingsFilth) + { + MakeCasingFilth(drawPosition.ToIntVec3(), map, DefDatabase.GetNamed(projProps.casingFilthDefname)); + } } + } + + public static void ThrowEmptyCasing(Vector3 loc, Map map, FleckDef casingFleckDef, float recoilAmount, float shotRotation, float size = 1f) + { + if (!loc.ShouldSpawnMotesAt(map) || map.moteCounter.SaturatedLowPriority) + { + return; + } + if (recoilAmount <= 0) + { + recoilAmount = 1; //avoid division errors in case of guns without recoil + } Rand.PushState(); FleckCreationData creationData = FleckMaker.GetDataStatic(loc, map, casingFleckDef); creationData.airTimeLeft = 1.5f; creationData.scale = Rand.Range(0.5f, 0.3f) * size; - creationData.rotation = Rand.Range(-3f, 4f); creationData.spawnPosition = loc; - creationData.velocitySpeed = Rand.Range(0.7f, 0.5f); - creationData.velocityAngle = Rand.Range(160, 200); - creationData.rotationRate = (float)Rand.Range(-300, 300); + creationData.velocitySpeed = Rand.Range(0.6f, 0.4f) * recoilAmount; + int randomAngle = Rand.Range(-20, 20); + //shotRotation goes from -270 to +90, while fleck angle uses 0 to 360 degrees (0 deg being North for both cases), so a conversion is used + //+90 makes casings fly to gun's right side + creationData.velocityAngle = shotRotation > 0 ? 360 - shotRotation + 90 + randomAngle : 0 - shotRotation + 90 + randomAngle; + creationData.rotation = creationData.velocityAngle + Rand.Range(-3f, 4f); + creationData.rotationRate = (float)Rand.Range(-150, 150) / recoilAmount; map.flecks.CreateFleck(creationData); Rand.PopState(); } public static void MakeCasingFilth(IntVec3 position, Map map, ThingDef casingFilthDef) { - if (!Controller.settings.CreateCasingsFilth) - { - return; - } Rand.PushState(); float makeFilthChance = Rand.Range(0f, 1f); if (makeFilthChance > 0.9f && position.Walkable(map)) diff --git a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs index 8b6331a2cd..c494e6dd0f 100644 --- a/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs +++ b/Source/CombatExtended/CombatExtended/Verbs/Verb_ShootCE.cs @@ -362,10 +362,9 @@ protected virtual bool OnCastSuccessful() ShooterPawn.records.Increment(RecordDefOf.ShotsFired); } //Drop casings - if (VerbPropsCE.ejectsCasings && projectilePropsCE.dropsCasings) + if (VerbPropsCE.ejectsCasings) { - CE_Utility.ThrowEmptyCasing(caster.DrawPos, caster.Map, DefDatabase.GetNamed(projectilePropsCE.casingMoteDefname)); - CE_Utility.MakeCasingFilth(caster.Position, caster.Map, DefDatabase.GetNamed(projectilePropsCE.casingFilthDefname)); + CE_Utility.GenerateAmmoCasings(projectilePropsCE, caster.DrawPos, caster.Map, shotRotation, VerbPropsCE.recoilAmount); } // This needs to here for weapons without magazine to ensure their last shot plays sounds if (CompAmmo != null && !CompAmmo.HasMagazine && CompAmmo.UseAmmo)