/// <summary> /// Applies all DamageInfosToApply to the target. Increases damage on critical hits. /// </summary> /// <param name="target">Target to apply damage to</param> protected override DamageWorker.DamageResult ApplyMeleeDamageToTarget(LocalTargetInfo target) { DamageWorker.DamageResult result = new DamageWorker.DamageResult(); foreach (DamageInfo current in DamageInfosToApply(target, isCrit)) { if (target.ThingDestroyed) { break; } LastAttackVerb = this; result = target.Thing.TakeDamage(current); LastAttackVerb = null; } // Apply animal knockdown if (isCrit && CasterPawn.def.race.Animal) { var pawn = target.Thing as Pawn; if (pawn != null && !pawn.Dead) { //pawn.stances?.stunner.StunFor(KnockdownDuration); pawn.stances?.SetStance(new Stance_Cooldown(KnockdownDuration, pawn, null)); pawn.jobs?.StartJob(new Job(CE_JobDefOf.WaitKnockdown) { expiryInterval = KnockdownDuration }, JobCondition.InterruptForced, null, false, false); } } isCrit = false; return(result); }
/// <summary> /// Performs parry calculations. Deflects damage from defender-pawn onto parryThing, applying armor reduction in the process. /// On critical parry does a riposte against this verb's CasterPawn. /// </summary> /// <param name="defender">Pawn doing the parrying</param> /// <param name="parryThing">Thing used to parry the blow (weapon/shield)</param> /// <param name="isRiposte">Whether to do a riposte</param> private void DoParry(Pawn defender, Thing parryThing, bool isRiposte = false) { if (parryThing != null) { foreach (var dinfo in DamageInfosToApply(defender)) { LastAttackVerb = this; ArmorUtilityCE.ApplyParryDamage(dinfo, parryThing); LastAttackVerb = null; } } if (isRiposte) { SoundDef sound = null; if (parryThing is Apparel_Shield) { // Shield bash DamageInfo dinfo = new DamageInfo(DamageDefOf.Blunt, 6, parryThing.GetStatValue(CE_StatDefOf.MeleePenetrationFactor), -1, defender, null, parryThing.def); dinfo.SetBodyRegion(BodyPartHeight.Undefined, BodyPartDepth.Outside); dinfo.SetAngle((CasterPawn.Position - defender.Position).ToVector3()); caster.TakeDamage(dinfo); if (!parryThing.Stuff.stuffProps.soundMeleeHitBlunt.NullOrUndefined()) { sound = parryThing.Stuff.stuffProps.soundMeleeHitBlunt; } } else { Verb_MeleeAttackCE verb = defender.meleeVerbs.TryGetMeleeVerb(caster) as Verb_MeleeAttackCE; if (verb == null) { Log.Error("CE failed to get attack verb for riposte from Pawn " + defender.ToString()); } else { verb.ApplyMeleeDamageToTarget(caster); sound = verb.SoundHitPawn(); } } // Held, because the caster may have died and despawned sound?.PlayOneShot(new TargetInfo(caster.PositionHeld, caster.MapHeld)); } // Register with parry tracker ParryTracker tracker = defender.MapHeld?.GetComponent <ParryTracker>(); if (tracker == null) { Log.Error("CE failed to find ParryTracker to register pawn " + defender.ToString()); } else { tracker.RegisterParryFor(defender, verbProps.AdjustedCooldownTicks(this, defender)); } }
/// <summary> /// Performs parry calculations. Deflects damage from defender-pawn onto parryThing, applying armor reduction in the process. /// On critical parry does a riposte against this verb's CasterPawn. /// </summary> /// <param name="defender">Pawn doing the parrying</param> /// <param name="parryThing">Thing used to parry the blow (weapon/shield)</param> /// <param name="isRiposte">Whether to do a riposte</param> private void DoParry(Pawn defender, Thing parryThing, bool isRiposte = false) { if (parryThing != null) { foreach (var dinfo in DamageInfosToApply(defender)) { ArmorUtilityCE.ApplyParryDamage(dinfo, parryThing); } } if (isRiposte) { SoundDef sound = null; if (parryThing is Apparel_Shield) { // Shield bash DamageInfo dinfo = new DamageInfo(DamageDefOf.Blunt, 6, -1, defender, null, parryThing.def); caster.TakeDamage(dinfo); if (!parryThing.Stuff.stuffProps.soundMeleeHitBlunt.NullOrUndefined()) { sound = parryThing.Stuff.stuffProps.soundMeleeHitBlunt; } } else { Verb_MeleeAttackCE verb = defender.meleeVerbs.TryGetMeleeVerb() as Verb_MeleeAttackCE; if (verb == null) { Log.Error("CE failed to get attack verb for riposte from Pawn " + defender.ToString()); } else { verb.ApplyMeleeDamageToTarget(caster); sound = verb.SoundHitPawn(); } } sound?.PlayOneShot(new TargetInfo(caster.Position, caster.Map)); } // Register with parry tracker ParryTracker tracker = defender.Map.GetComponent <ParryTracker>(); if (tracker == null) { Log.Error("CE failed to find ParryTracker to register pawn " + defender.ToString()); } else { tracker.RegisterParryFor(defender, verbProps.AdjustedCooldownTicks(ownerEquipment)); } }