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);
        }