예제 #1
0
        public AttackDetails(AbstractActor attacker, ICombatant target, Vector3 attackPos, Vector3 targetPos, bool useRevengeBonus)
        {
            this.Attacker = attacker;
            this.Target   = target;

            this.AttackPosition = attackPos;
            this.TargetPosition = targetPos;

            this.UseRevengeBonus = useRevengeBonus;

            // Precalculate some values heavily used by the prediction engine

            // Impact quality for any melee attack is always solid
            this.BaseRangedImpactQuality = SharedState.Combat.ToHit.GetBlowQuality(attacker, attackPos,
                                                                                   null, target, MeleeAttackType.Punch, false);

            this.AttackerDesignMask = SharedState.Combat.MapMetaData.GetPriorityDesignMaskAtPos(attackPos);
            if (this.AttackerDesignMask == null)
            {
                AttackerDesignMask = new DesignMaskDef();
            }
            this.TargetDesignMask = SharedState.Combat.MapMetaData.GetPriorityDesignMaskAtPos(targetPos);
            if (this.TargetDesignMask == null)
            {
                TargetDesignMask = new DesignMaskDef();
            }

            // Calculate the total damage multiplier for attacks by weaponType
            this.DamageMultipliers.Add(DamageMultiType.Ballistic, CalculateDamageMulti(DamageMultiType.Ballistic, target));
            this.DamageMultipliers.Add(DamageMultiType.Energy, CalculateDamageMulti(DamageMultiType.Energy, target));
            this.DamageMultipliers.Add(DamageMultiType.Missile, CalculateDamageMulti(DamageMultiType.Missile, target));
            this.DamageMultipliers.Add(DamageMultiType.Support, CalculateDamageMulti(DamageMultiType.Support, target));
            this.DamageMultipliers.Add(DamageMultiType.Generic, CalculateDamageMulti(DamageMultiType.Generic, target));
        }
예제 #2
0
        public static void Prefix(Mech __instance, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage,
                                  int hitIndex, AttackImpactQuality impactQuality, DamageType damageType)
        {
            if (aLoc == ArmorLocation.Head)
            {
                Mod.Log.Info($"Head hit from weapon:{weapon?.UIName} for {totalArmorDamage} armor damage and {directStructureDamage} structure damage. " +
                             $"Quality was:{impactQuality} with type:{damageType}");

                float currHeadArmor      = __instance.GetCurrentArmor(aLoc);
                int   damageMod          = (int)Math.Ceiling(totalArmorDamage);
                float damageThroughArmor = totalArmorDamage - currHeadArmor;
                Mod.Log.Debug($"TotalArmorDamage:{totalArmorDamage} - Head armor:{currHeadArmor} = throughArmor:{damageThroughArmor}");

                if (totalArmorDamage - currHeadArmor <= 0)
                {
                    damageMod = (int)Math.Floor(damageMod * Mod.Config.Combat.PainTolerance.HeadHitArmorOnlyMulti);
                    Mod.Log.Info($"Head hit impacted armor only, reduced damage to:{damageMod}");
                }

                if (directStructureDamage != 0)
                {
                    Mod.Log.Debug($"Attack inflicted ${directStructureDamage}, adding to total resist damage.");
                    damageMod += (int)Math.Ceiling(directStructureDamage);
                }

                ModState.InjuryResistPenalty = damageMod * Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage;
                Mod.Log.Info($"Setting resist penalty to:{damageMod} x {Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage} = {ModState.InjuryResistPenalty}");
            }
        }
예제 #3
0
            static void Prefix(Mech __instance, int originalHitLoc, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon,
                               float totalArmorDamage, float directStructureDamage, int hitIndex, AttackImpactQuality impactQuality, DamageType damageType)
            {
                if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid)
                {
                    return;
                }


                float num          = totalArmorDamage;
                float currentArmor = __instance.GetCurrentArmor(aLoc);

                if (currentArmor > 0f)
                {
                    num = totalArmorDamage - currentArmor;
                }
                num += directStructureDamage; // account for damage split: this should get us back where we were when we both had armour spillover damage and
                // any damage done directly to the structure
                if (num <= 0f)
                {
                    return; //no need to continue if the shot doesn't do anything we care about
                }
                ChassisLocations chassisLocationFromArmorLocation = MechStructureRules.GetChassisLocationFromArmorLocation(aLoc);


                float currentStructure = __instance.GetCurrentStructure(chassisLocationFromArmorLocation);

                if (currentStructure > 0f)
                {
                    float num4         = Math.Min(num, currentStructure);
                    bool  WasDestroyed = (currentStructure - num) <= 0; //if currentstructure minus remaining damage is less or equal to 0, then the location is destroyed.

                    num -= num4;
                    if (WasDestroyed && num4 > 0.01f) //this location was destroyed, so we now check for dependents.
                    {
                        if (chassisLocationFromArmorLocation == ChassisLocations.LeftArm)
                        {
                            Holder.LeftArmSurvived = false; //invalidate if the actual arm was destroyed
                        }
                        else if (chassisLocationFromArmorLocation == ChassisLocations.RightArm)
                        {
                            Holder.RightArmSurvived = false; //invalidate if the actual arm was destroyed
                        }
                        ChassisLocations dependentLocation = MechStructureRules.GetDependentLocation(chassisLocationFromArmorLocation);
                        if (dependentLocation != ChassisLocations.None && !__instance.IsLocationDestroyed(dependentLocation))
                        {
                            if (dependentLocation == ChassisLocations.LeftArm)
                            {
                                Holder.LeftArmSurvived = true; //side torso was destroyed, no reason the arm should be totally trashed.
                            }
                            else if (dependentLocation == ChassisLocations.RightArm)
                            {
                                Holder.RightArmSurvived = true; //side torso was destroyed, no reason the arm should be totally trashed.
                            }
                        }
                    }
                }
            }
예제 #4
0
        static void Prefix(Mech __instance, int originalHitLoc, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalDamage, int hitIndex, AttackImpactQuality impactQuality)
        {
            if (aLoc == ArmorLocation.Head)
            {
                //we do some quick calculation of damage to see if it's an armor hit or an structure hit
                float currentArmor    = __instance.GetCurrentArmor(aLoc);
                float remainingDamage = totalDamage - currentArmor;

                if (remainingDamage <= 0 && totalDamage < LessHeadInjuries.ArmorHeadHitIgnoreDamageBelow)
                {
                    //remainign damage less or equal to zero mean no structure penetration. Treat as an armour hit.
                    LessHeadInjuries.IgnoreNextHeadHit.Add(__instance.pilot);
                }
                else if (remainingDamage > 0 && totalDamage < LessHeadInjuries.StructHeadHitIgnoreDamageBelow)
                {
                    LessHeadInjuries.IgnoreNextHeadHit.Add(__instance.pilot);
                }
            }
        }
예제 #5
0
        static void Prefix(Mech __instance, int originalHitLoc, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon,
                           float totalArmorDamage, float directStructureDamage, int hitIndex, AttackImpactQuality impactQuality, DamageType damageType)
        {
            if (aLoc == ArmorLocation.Head)
            {
                Boolean DirectHit = false;

                //we do some quick calculation of damage to see if it's an armor hit or an structure hit
                float currentArmor = Math.Max(__instance.GetCurrentArmor(aLoc), 0f); //either it has armor remaining or it's got nothing left

                float remainingDamage = totalArmorDamage - currentArmor;             // subtract our armour damage by totalArmorDamage: if it's more than 0, we calculate for structure damage

                float structureDamage = directStructureDamage;
                if (remainingDamage > 0f)
                {
                    structureDamage += remainingDamage;
                }
                if (structureDamage >= 0f) // need to account for direct structure damage
                {
                    DirectHit = true;
                }
                if (!DirectHit && totalArmorDamage < LessHeadInjuries.Settings.ArmorHitDamageMinimum)
                {
                    //remainign damage less or equal to zero mean no structure penetration. Treat as an armour hit.
                    LessHeadInjuries.IgnoreNextHeadHit.Add(__instance.pilot);
                }
                else if (DirectHit && structureDamage < LessHeadInjuries.Settings.StructureHitDamageMinimum)
                {
                    LessHeadInjuries.IgnoreNextHeadHit.Add(__instance.pilot);
                }
            }
        }
 internal static bool DamageLocation(this Mech mech, int originalHitLoc, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage, int hitIndex, AttackImpactQuality impactQuality, DamageType damageType)
 {
     return(Traverse.Create(mech).Method(nameof(DamageLocation), originalHitLoc, hitInfo, aLoc, weapon, totalArmorDamage, directStructureDamage, hitIndex, impactQuality, damageType).GetValue <bool>());
 }
예제 #7
0
 internal static bool DamageLocation(this Vehicle vehicle, WeaponHitInfo hitInfo, int originalHitLoc, VehicleChassisLocations vLoc, Weapon weapon, float totalDamage, AttackImpactQuality impactQuality)
 {
     return(Traverse.Create(vehicle).Method(nameof(DamageLocation), hitInfo, originalHitLoc, vLoc, weapon, totalDamage, impactQuality).GetValue <bool>());
 }
 internal static void Postfix(Mech __instance, int originalHitLoc, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalDamage, int hitIndex, AttackImpactQuality impactQuality, bool __result)
 {
     currentMech = null;
 }