private void ApplySuppression(Pawn pawn) { ShieldBelt shield = null; if (pawn.RaceProps.Humanlike) { // check for shield user List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = 0; i < wornApparel.Count; i++) { var personalShield = wornApparel[i] as ShieldBelt; if (personalShield != null) { shield = personalShield; break; } } } //Add suppression CompSuppressable compSuppressable = pawn.TryGetComp <CompSuppressable>(); if (compSuppressable != null && pawn.Faction != launcher?.Faction && (shield == null || shield?.ShieldState == ShieldState.Resetting)) { suppressionAmount = def.projectile.GetDamageAmount(CE_Utility.GetWeaponFromLauncher(launcher)); var propsCE = def.projectile as ProjectilePropertiesCE; float penetrationAmount = propsCE == null ? 0f : propsCE.armorPenetration; suppressionAmount *= 1 - Mathf.Clamp(compSuppressable.ParentArmor - penetrationAmount, 0, 1); compSuppressable.AddSuppression(suppressionAmount, OriginIV3); } }
protected virtual void Explode() { ExplosionCE explosion = GenSpawn.Spawn(CE_ThingDefOf.ExplosionCE, ExactPosition.ToIntVec3(), Map) as ExplosionCE; explosion.height = ExactPosition.y; explosion.radius = def.projectile.explosionRadius; explosion.damType = def.projectile.damageDef; explosion.instigator = launcher; explosion.damAmount = def.projectile.GetDamageAmount(CE_Utility.GetWeaponFromLauncher(launcher)); explosion.weapon = equipmentDef; explosion.projectile = def; explosion.preExplosionSpawnThingDef = def.projectile.preExplosionSpawnThingDef; explosion.preExplosionSpawnChance = def.projectile.preExplosionSpawnChance; explosion.preExplosionSpawnThingCount = def.projectile.preExplosionSpawnThingCount; explosion.postExplosionSpawnThingDef = def.projectile.postExplosionSpawnThingDef; explosion.postExplosionSpawnChance = def.projectile.postExplosionSpawnChance; explosion.postExplosionSpawnThingCount = def.projectile.postExplosionSpawnThingCount; explosion.applyDamageToExplosionCellsNeighbors = def.projectile.applyDamageToExplosionCellsNeighbors; explosion.chanceToStartFire = def.projectile.explosionChanceToStartFire; explosion.damageFalloff = def.projectile.explosionDamageFalloff; explosion.StartExplosion(def.projectile.soundExplode); if (this.def.projectile.explosionEffect != null) { Effecter effecter = this.def.projectile.explosionEffect.Spawn(); effecter.Trigger(new TargetInfo(ExactPosition.ToIntVec3(), Map, false), new TargetInfo(ExactPosition.ToIntVec3(), Map, false)); effecter.Cleanup(); } //This code was disabled because it didn't run under previous circumstances. Could be enabled if necessary /* * if (map != null && base.ExactPosition.ToIntVec3().IsValid) * { * ThrowBigExplode(base.ExactPosition + Gen.RandomHorizontalVector(def.projectile.explosionRadius * 0.5f), base.Map, def.projectile.explosionRadius * 0.4f); * } */ base.Impact(null); // base.Impact() handles this.Destroy() and comp.Explode() }
protected override void Impact(Thing hitThing) { Map map = base.Map; BattleLogEntry_RangedImpact logEntry = null; if (logMisses || (!logMisses && hitThing != null && (hitThing is Pawn || hitThing is Building_Turret) )) { LogImpact(hitThing, out logEntry); } if (hitThing != null) { // launcher being the pawn equipping the weapon, not the weapon itself int damageAmountBase = def.projectile.GetDamageAmount(CE_Utility.GetWeaponFromLauncher(launcher)); DamageDefExtensionCE damDefCE = def.projectile.damageDef.GetModExtension <DamageDefExtensionCE>() ?? new DamageDefExtensionCE(); var projectilePropsCE = def.projectile as ProjectilePropertiesCE; DamageInfo dinfo = new DamageInfo( def.projectile.damageDef, damageAmountBase, projectilePropsCE.armorPenetration, //Armor Penetration ExactRotation.eulerAngles.y, launcher, null, def); // Set impact height BodyPartDepth partDepth = damDefCE != null && damDefCE.harmOnlyOutsideLayers ? BodyPartDepth.Outside : BodyPartDepth.Undefined; //NOTE: ExactPosition.y isn't always Height at the point of Impact! BodyPartHeight partHeight = new CollisionVertical(hitThing).GetCollisionBodyHeight(ExactPosition.y); dinfo.SetBodyRegion(partHeight, partDepth); if (damDefCE != null && damDefCE.harmOnlyOutsideLayers) { dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); } // Apply primary damage hitThing.TakeDamage(dinfo).AssociateWithLog(logEntry); // Apply secondary to non-pawns (pawn secondary damage is handled in the damage worker) if (!(hitThing is Pawn) && projectilePropsCE != null && !projectilePropsCE.secondaryDamage.NullOrEmpty()) { foreach (SecondaryDamage cur in projectilePropsCE.secondaryDamage) { if (hitThing.Destroyed) { break; } var secDinfo = new DamageInfo( cur.def, cur.amount, projectilePropsCE.armorPenetration, //Armor Penetration ExactRotation.eulerAngles.y, launcher, null, def ); hitThing.TakeDamage(secDinfo).AssociateWithLog(logEntry); } } } else { SoundDefOf.BulletImpact_Ground.PlayOneShot(new TargetInfo(base.Position, map, false)); //Only display a dirt hit for projectiles with a dropshadow if (base.castShadow) { MoteMaker.MakeStaticMote(ExactPosition, map, ThingDefOf.Mote_ShotHit_Dirt, 1f); } } base.Impact(hitThing); }