public static Func <AttackModifier> GetMeleeModifierFactor(string factorId) { switch (factorId) { case "armmounted": return(() => { AttackModifier result = new AttackModifier("PUNCHING ARM"); if (AttackType == MeleeAttackType.DFA || Target is Vehicle || Target.IsProne || !(Attacker is Mech mech)) { return result; } if (mech.MechDef.Chassis.PunchesWithLeftArm) { if (mech.IsLocationDestroyed(ChassisLocations.LeftArm)) { return result; } } else if (mech.IsLocationDestroyed(ChassisLocations.RightArm)) { return result; } return result.SetValue(CombatConstants.ToHit.ToHitSelfArmMountedWeapon); }); case "dfa": return(() => new AttackModifier("DEATH FROM ABOVE", Hit.GetDFAModifier(AttackType))); case "height": return(() => { AttackModifier result = new AttackModifier("HEIGHT DIFF"); if (AttackType == MeleeAttackType.DFA) { return result.SetValue(Hit.GetHeightModifier(Attacker.CurrentPosition.y, Target.CurrentPosition.y)); } float diff = AttackPos.y - Target.CurrentPosition.y; if (Math.Abs(diff) < HalfMaxMeleeVerticalOffset || (diff < 0 && !CombatConstants.ToHit.ToHitElevationApplyPenalties)) { return result; } float mod = CombatConstants.ToHit.ToHitElevationModifierPerLevel; return result.SetValue(diff <= 0 ? mod : -mod); }); case "obstruction": return(() => new AttackModifier("OBSTRUCTED", Hit.GetCoverModifier(Attacker, Target, Combat.LOS.GetLineOfFire(Attacker, AttackPos, Target, TargetPos, Target.CurrentRotation, out Vector3 collision)))); case "refire": return(() => new AttackModifier("RE-ATTACK", Hit.GetRefireModifier(AttackWeapon))); case "selfchassis": return(() => new AttackModifier(Hit.GetMeleeChassisToHitModifier(Attacker, AttackType)).SetName("CHASSIS PENALTY", "CHASSIS BONUS")); case "targetevasion": return(() => { AttackModifier result = new AttackModifier("TARGET MOVED"); if (!(Target is AbstractActor actor)) { return result; } return result.SetValue(Hit.GetEvasivePipsModifier(actor.EvasivePipsCurrent, AttackWeapon)); }); case "targetprone": return(() => new AttackModifier("TARGET PRONE", Hit.GetTargetProneModifier(Target, true))); case "targetshutdown": return(() => new AttackModifier("TARGET SHUTDOWN", Hit.GetTargetShutdownModifier(Target, true))); } return(null); }