Ejemplo n.º 1
0
 private static IComparer <ChassisLocations> LocationSorter(Mech mech)
 {
     return(new FunctionalComparer <ChassisLocations>((a, b) => {
         LocationDamageLevel aDead = mech.GetLocationDamageLevel(a), bDead = mech.GetLocationDamageLevel(b);
         if (aDead != bDead) // Dead location has last priority
         {
             if (aDead >= LocationDamageLevel.Destroyed)
             {
                 return 1;
             }
             else if (bDead >= LocationDamageLevel.Destroyed)
             {
                 return -1;
             }
         }
         if (aDead >= LocationDamageLevel.Destroyed)
         {
             return 0;                                       // Both destroyed.
         }
         float aArm = WeakestArmour(mech, a), bArm = WeakestArmour(mech, b);
         if (aArm == 0 || bArm == 0) // Armor breached!
         {
             if (aArm != bArm)
             {
                 return Compare(aArm, bArm);                         // Breached one goes first
             }
             return Compare(WeakestHP(mech, a), WeakestHP(mech, b)); // Both breached, compare HP.
         }
         return Compare(aArm, bArm);
     }));
 }
Ejemplo n.º 2
0
        public static bool Prefix(Mech __instance, LocationDamageLevel oldDamageLevel, LocationDamageLevel newDamageLevel, WeaponHitInfo hitInfo)
        {
            var mech = __instance;

            if (newDamageLevel == oldDamageLevel)
            {
                return(true);
            }

            if (newDamageLevel != LocationDamageLevel.Destroyed)
            {
                return(true);
            }

            var attackSequence = mech.Combat.AttackDirector.GetAttackSequence(hitInfo.attackSequenceId);

            if (attackSequence != null)
            {
                return(true);
            }

            // do vanilla code but without using the attack sequence (as its null)
            mech.pilot.SetNeedsInjury(InjuryReason.HeadHit);
            mech.pilot.LethalInjurePilot(mech.Combat.Constants, hitInfo.attackerId, hitInfo.stackItemUID, true, DamageType.HeadShot, null, null);
            mech.Combat.MessageCenter.PublishMessage(new AddSequenceToStackMessage(new ShowActorInfoSequence(mech, "PILOT: LETHAL DAMAGE!", FloatieMessage.MessageNature.PilotInjury, true)));

            return(false);
        }
Ejemplo n.º 3
0
 public static bool Prefix(Mech __instance, ChassisLocations location, LocationDamageLevel oldDamageLevel, LocationDamageLevel newDamageLevel, WeaponHitInfo hitInfo)
 {
     if (__instance.StatCollection.GetOrCreateStatisic <bool>(Core.Settings.unaffectedByHeadHitStatName, false).Value <bool>())
     {
         return(false);
     }
     return(true);
 }
Ejemplo n.º 4
0
        // CLONE OF HBS CODE - LIKELY BRITTLE!
        public static float CalcCalledShotLocationTargetChance(Mech targetMech, ArmorLocation armorLoc, ChassisLocations chassisLoc)
        {
            LocationDamageLevel locationDamageLevel = targetMech.GetLocationDamageLevel(chassisLoc);

            if (locationDamageLevel == LocationDamageLevel.Destroyed)
            {
                return(0f);
            }
            float num;

            if (armorLoc != ArmorLocation.Head)
            {
                if (armorLoc != ArmorLocation.CenterTorso)
                {
                    num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotOtherBaseChance).FloatVal;
                }
                else
                {
                    num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotCenterTorsoBaseChance).FloatVal;
                }
            }
            else
            {
                num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotHeadBaseChance).FloatVal;
            }
            if (locationDamageLevel == LocationDamageLevel.Penalized || locationDamageLevel == LocationDamageLevel.NonFunctional)
            {
                num *= AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotDamagedChanceMultiplier).FloatVal;
            }
            List <MechComponent> componentsForLocation = targetMech.GetComponentsForLocation(chassisLoc, ComponentType.Weapon);
            float num2 = 0f;

            for (int i = 0; i < componentsForLocation.Count; i++)
            {
                Weapon weapon = componentsForLocation[i] as Weapon;
                if (weapon != null && weapon.CanFire)
                {
                    float num3 = (float)weapon.ShotsWhenFired * weapon.DamagePerShot;
                    num2 += num3;
                }
            }
            return(num + AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotWeaponDamageChance).FloatVal *num2);
        }
Ejemplo n.º 5
0
        public void Repair(MechComponent component, bool isFloatieMessage = false)
        {
            Mech    mech    = component.parent as Mech;
            Vehicle vehicle = component.parent as Vehicle;
            Turret  turret  = component.parent as Turret;

            Log.Debug?.Write("Repair:" + component.parent.DisplayName + ":" + component.parent.GUID + ":" + component.defId + " mech:" + (mech != null ? "true" : "false") + " vehicle:" + (vehicle != null ? "true" : "false") + " turret:" + (turret != null ? "true" : "false") + "\n");
            HashSet <int> affectedISLocations    = new HashSet <int>();
            HashSet <int> affectedArmorLocations = new HashSet <int>();
            bool          armorReparied          = false;
            bool          structureReparied      = false;

            if (this.AffectInstalledLocation)
            {
                affectedISLocations.Add(component.Location);
                if (mech != null)
                {
                    ChassisLocations componentLocation = (ChassisLocations)component.Location;
                    switch (componentLocation)
                    {
                    case ChassisLocations.CenterTorso:
                        affectedArmorLocations.Add((int)ArmorLocation.CenterTorso);
                        affectedArmorLocations.Add((int)ArmorLocation.CenterTorsoRear);
                        break;

                    case ChassisLocations.RightTorso:
                        affectedArmorLocations.Add((int)ArmorLocation.RightTorso);
                        affectedArmorLocations.Add((int)ArmorLocation.RightTorsoRear);
                        break;

                    case ChassisLocations.LeftTorso:
                        affectedArmorLocations.Add((int)ArmorLocation.LeftTorso);
                        affectedArmorLocations.Add((int)ArmorLocation.LeftTorsoRear);
                        break;

                    default:
                        affectedArmorLocations.Add((int)componentLocation);
                        break;
                    }
                }
                else
                {
                    affectedArmorLocations.Add(component.Location);
                }
            }
            ;
            int stackItemUID = component.parent.Combat.StackManager.NextStackUID;

            if (mech != null)
            {
                for (int t = 0; t < this.MechStructureLocations.Length; ++t)
                {
                    affectedISLocations.Add((int)this.MechStructureLocations[t]);
                }
                for (int t = 0; t < this.MechArmorLocations.Length; ++t)
                {
                    affectedArmorLocations.Add((int)this.MechArmorLocations[t]);
                }
            }
            else
            if (vehicle != null)
            {
                for (int t = 0; t < this.VehicleLocations.Length; ++t)
                {
                    affectedISLocations.Add((int)this.VehicleLocations[t]);
                    affectedArmorLocations.Add((int)this.VehicleLocations[t]);
                }
            }
            else
            {
                for (int t = 0; t < this.BuildingLocations.Length; ++t)
                {
                    affectedISLocations.Add((int)this.BuildingLocations[t]);
                    affectedArmorLocations.Add((int)this.BuildingLocations[t]);
                }
            }
            Log.Debug?.Write(" Affected armor locations:");
            foreach (var loc in affectedArmorLocations)
            {
                Log.Debug?.Write(" " + loc);
            }
            Log.Debug?.Write(" \n");
            if (this.Armor > Core.Epsilon)
            {
                foreach (int Location in affectedArmorLocations)
                {
                    Statistic stat = component.parent.GetArmorStatisticForLocation(Location);
                    if (stat == null)
                    {
                        Log.Debug?.TWriteCritical(0, "Can't get armor stat " + new Text(component.parent.DisplayName).ToString() + " location:" + Location);
                        continue;
                    }
                    Log.Debug?.TWL(0, "turnsSinceLocationDamage:" + component.parent.turnsSinceLocationDamage(Location) + " component:" + TurnsSinceDamage);
                    if (TurnsSinceDamage >= 0)
                    {
                        if (component.parent.turnsSinceLocationDamage(Location) > TurnsSinceDamage)
                        {
                            Log.Debug?.WL(1, "damage too long ago. No reparing performed.");
                            continue;
                        }
                    }
                    float maxArmor          = stat.DefaultValue <float>();
                    float currentArmor      = stat.Value <float>();
                    int   StructureLocation = Location;
                    if (mech != null)
                    {
                        StructureLocation = (int)MechStructureRules.GetChassisLocationFromArmorLocation((ArmorLocation)Location);
                    }
                    currentArmor += this.Armor;
                    if (currentArmor > maxArmor)
                    {
                        currentArmor = maxArmor;
                    }
                    ;
                    float delta = currentArmor - component.parent.ArmorForLocation(Location);
                    Log.Debug?.WL(2, "location:" + Location + " maxArmor:" + maxArmor + " currentArmor:" + currentArmor + "(" + delta + ")");
                    if (delta > Core.Epsilon)
                    {
                        if (mech != null)
                        {
                            Log.Debug?.Write("  mech stat armor location:" + mech.GetStringForArmorLocation((ArmorLocation)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = mech.GetLocationDamageLevel((ChassisLocations)StructureLocation);
                            if (locationDamageLevel >= LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                continue;
                            }
                            armorReparied = true;
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, mech.GetStringForArmorLocation((ArmorLocation)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        if (vehicle != null)
                        {
                            Log.Debug?.Write("  vehicle stat armor location:" + vehicle.GetStringForArmorLocation((VehicleChassisLocations)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = vehicle.GetLocationDamageLevel((VehicleChassisLocations)StructureLocation);
                            if (locationDamageLevel >= LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                continue;
                            }
                            armorReparied = true;
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, vehicle.GetStringForArmorLocation((VehicleChassisLocations)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        if (turret != null)
                        {
                            Log.Debug?.Write("  turret stat armor location:" + turret.GetStringForArmorLocation((BuildingLocation)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = turret.GetLocationDamageLevel((BuildingLocation)StructureLocation);
                            if (locationDamageLevel >= LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                armorReparied = true;
                                continue;
                            }
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, turret.GetStringForArmorLocation((BuildingLocation)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        {
                            Log.Debug?.Write("  combatant has no armor\n");
                        }
                    }
                }
            }
            Log.Debug?.Write(" Affected inner structure locations:");
            foreach (var loc in affectedISLocations)
            {
                Log.Debug?.Write(" " + loc);
            }
            Log.Debug?.Write(" \n");
            if (this.InnerStructure > Core.Epsilon)
            {
                foreach (int Location in affectedISLocations)
                {
                    float maxStructure     = component.parent.MaxStructureForLocation(Location);
                    float currentStructure = component.parent.StructureForLocation(Location);
                    if (currentStructure < Core.Epsilon)
                    {
                        Log.Debug?.Write(" can't repair locations with zero structure\n");
                        continue;
                    }
                    currentStructure += this.InnerStructure;
                    if (currentStructure > maxStructure)
                    {
                        currentStructure = maxStructure;
                    }
                    ;
                    float delta = currentStructure - component.parent.StructureForLocation(Location);
                    Log.Debug?.Write(" inner structure repair amount:" + delta + "\n");
                    if (delta > Core.Epsilon)
                    {
                        if (mech != null)
                        {
                            Log.Debug?.Write("  mech stat structure location:" + mech.GetStringForStructureLocation((ChassisLocations)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = mech.GetLocationDamageLevel((ChassisLocations)Location);
                            if (locationDamageLevel >= LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                continue;
                            }
                            structureReparied = true;
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, mech.GetStringForStructureLocation((ChassisLocations)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        if (vehicle != null)
                        {
                            Log.Debug?.Write("  vehicle stat structure location:" + vehicle.GetStringForStructureLocation((VehicleChassisLocations)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = vehicle.GetLocationDamageLevel((VehicleChassisLocations)Location);
                            if (locationDamageLevel >= LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                continue;
                            }
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, vehicle.GetStringForStructureLocation((VehicleChassisLocations)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        if (turret != null)
                        {
                            Log.Debug?.Write("  turret stat structure location:" + turret.GetStringForArmorLocation((BuildingLocation)Location) + "\n");
                            LocationDamageLevel locationDamageLevel = turret.GetLocationDamageLevel((BuildingLocation)Location);
                            if (locationDamageLevel == LocationDamageLevel.Destroyed)
                            {
                                Log.Debug?.Write(" can't repair destroyed location\n");
                                continue;
                            }
                            structureReparied = true;
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, turret.GetStringForStructureLocation((BuildingLocation)Location), StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                        else
                        {
                            Log.Debug?.Write("  other structure location:" + "Structure" + "\n");
                            structureReparied = true;
                            component.parent.StatCollection.ModifyStat <float>(component.parent.GUID, stackItemUID, "Structure", StatCollection.StatOperation.Float_Add, delta, -1, true);
                        }
                    }
                }
            }
            if ((armorReparied || structureReparied) && (isFloatieMessage))
            {
                string text = component.Description.UIName + " __/CAE.REPAIRED/__" + (armorReparied ? " __/CAE.REPAIRARMOR/__" : " ") + (structureReparied ? " __/CAE.REPAIRSTRUCTURE/__" : "");
                component.parent.Combat.MessageCenter.PublishMessage((MessageCenterMessage) new FloatieMessage(component.parent.GUID, component.parent.GUID, text, FloatieMessage.MessageNature.Buff));
            }
        }