Advertisement
kregano

BattleTech.AttackDirector.AttackSequence.cs

Jun 28th, 2023
1,118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 85.87 KB | Source Code | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using BattleTech;
  4. using BattleTech.AttackDirectorHelpers;
  5. using fastJSON;
  6. using HBS.Logging;
  7. using Localize;
  8. using UnityEngine;
  9.  
  10. // Token: 0x02000CDB RID: 3291
  11. public class AttackSequence
  12. {
  13.     // Token: 0x17000D6D RID: 3437
  14.     // (get) Token: 0x06006014 RID: 24596 RVA: 0x001A1B05 File Offset: 0x0019FD05
  15.     // (set) Token: 0x06006015 RID: 24597 RVA: 0x001A1B0D File Offset: 0x0019FD0D
  16.     public AttackDirector Director { get; private set; }
  17.  
  18.     // Token: 0x17000D6E RID: 3438
  19.     // (get) Token: 0x06006016 RID: 24598 RVA: 0x001A1B16 File Offset: 0x0019FD16
  20.     public int weaponGroupCount
  21.     {
  22.         get
  23.         {
  24.             return this.sortedWeapons.Count;
  25.         }
  26.     }
  27.  
  28.     // Token: 0x17000D6F RID: 3439
  29.     // (get) Token: 0x06006017 RID: 24599 RVA: 0x001A1B23 File Offset: 0x0019FD23
  30.     public bool HasWeapons
  31.     {
  32.         get
  33.         {
  34.             return this.allSelectedWeapons.Count > 0;
  35.         }
  36.     }
  37.  
  38.     // Token: 0x17000D70 RID: 3440
  39.     // (get) Token: 0x06006018 RID: 24600 RVA: 0x001A1B33 File Offset: 0x0019FD33
  40.     public int TotalWeaponCount
  41.     {
  42.         get
  43.         {
  44.             return this.allSelectedWeapons.Count;
  45.         }
  46.     }
  47.  
  48.     // Token: 0x17000D71 RID: 3441
  49.     // (get) Token: 0x06006019 RID: 24601 RVA: 0x001A1B40 File Offset: 0x0019FD40
  50.     // (set) Token: 0x0600601A RID: 24602 RVA: 0x001A1B48 File Offset: 0x0019FD48
  51.     public List<string> allAffectedTargetIds { get; private set; }
  52.  
  53.     // Token: 0x17000D72 RID: 3442
  54.     // (get) Token: 0x0600601B RID: 24603 RVA: 0x001A1B51 File Offset: 0x0019FD51
  55.     // (set) Token: 0x0600601C RID: 24604 RVA: 0x001A1B59 File Offset: 0x0019FD59
  56.     public bool attackCompletelyMissed { get; private set; }
  57.  
  58.     // Token: 0x17000D73 RID: 3443
  59.     // (get) Token: 0x0600601D RID: 24605 RVA: 0x001A1B62 File Offset: 0x0019FD62
  60.     // (set) Token: 0x0600601E RID: 24606 RVA: 0x001A1B6A File Offset: 0x0019FD6A
  61.     public bool attackDestroyedAttackerLeg { get; private set; }
  62.  
  63.     // Token: 0x17000D74 RID: 3444
  64.     // (get) Token: 0x0600601F RID: 24607 RVA: 0x001A1B73 File Offset: 0x0019FD73
  65.     // (set) Token: 0x06006020 RID: 24608 RVA: 0x001A1B7B File Offset: 0x0019FD7B
  66.     public int attackTotalShotsFired { get; private set; }
  67.  
  68.     // Token: 0x17000D75 RID: 3445
  69.     // (get) Token: 0x06006021 RID: 24609 RVA: 0x001A1B84 File Offset: 0x0019FD84
  70.     // (set) Token: 0x06006022 RID: 24610 RVA: 0x001A1B8C File Offset: 0x0019FD8C
  71.     public int attackTotalShotsHit { get; private set; }
  72.  
  73.     // Token: 0x17000D76 RID: 3446
  74.     // (get) Token: 0x06006023 RID: 24611 RVA: 0x001A1B95 File Offset: 0x0019FD95
  75.     public float RatioSuccessfulHits
  76.     {
  77.         get
  78.         {
  79.             return (float)this.attackTotalShotsHit / (float)this.attackTotalShotsFired;
  80.         }
  81.     }
  82.  
  83.     // Token: 0x17000D77 RID: 3447
  84.     // (get) Token: 0x06006024 RID: 24612 RVA: 0x001A1BA6 File Offset: 0x0019FDA6
  85.     // (set) Token: 0x06006025 RID: 24613 RVA: 0x001A1BAE File Offset: 0x0019FDAE
  86.     public bool CoordinatedMesssagesSuccessful { get; private set; }
  87.  
  88.     // Token: 0x06006026 RID: 24614 RVA: 0x001A1BB8 File Offset: 0x0019FDB8
  89.     public void RecordMechDamage(string mechGUID, int originalHitLocation, WeaponHitInfo hitInfo, ArmorLocation armorLocation, Weapon weapon, float totalDamage, int hitIndex, AttackImpactQuality impactQuality)
  90.     {
  91.         if (this.Director == null || !this.Director.recordStats)
  92.         {
  93.             return;
  94.         }
  95.         AttackDirector.AttackSequence.MechDamage mechDamage = new AttackDirector.AttackSequence.MechDamage();
  96.         mechDamage.mechGUID = mechGUID;
  97.         mechDamage.index = this.recordedMechDamage.Count;
  98.         mechDamage.originalHitLocation = originalHitLocation;
  99.         mechDamage.weaponGroupIndex = hitInfo.attackGroupIndex;
  100.         mechDamage.weaponIndex = hitInfo.attackWeaponIndex;
  101.         mechDamage.hitIndex = hitIndex;
  102.         mechDamage.weaponName = ((weapon != null) ? weapon.Name : "null");
  103.         mechDamage.hitLocation = armorLocation;
  104.         mechDamage.impactQuality = impactQuality;
  105.         mechDamage.totalDamage = totalDamage;
  106.         this.recordedMechDamage.Add(mechDamage);
  107.     }
  108.  
  109.     // Token: 0x06006027 RID: 24615 RVA: 0x001A1C5C File Offset: 0x0019FE5C
  110.     public Dictionary<string, string> GetRecordedMechDamageDictionary()
  111.     {
  112.         this.damageStatsGatherer.Clear();
  113.         for (int i = 0; i < this.recordedMechDamage.Count; i++)
  114.         {
  115.             this.recordedMechDamage[i].AppendToStatsGatherer(this.damageStatsGatherer);
  116.         }
  117.         return this.damageStatsGatherer.GetDictionary();
  118.     }
  119.  
  120.     // Token: 0x06006028 RID: 24616 RVA: 0x001A1CAC File Offset: 0x0019FEAC
  121.     public AttackSequence(AttackDirector director, AbstractActor attacker, ICombatant target, Vector3 attackPosition, Quaternion attackRotation, int attackSequenceIdx, List<Weapon> selectedWeapons, MeleeAttackType meleeAttackType, int calledShotLocation, bool isMoraleAttack, int id, int stackItemUID)
  122.     {
  123.         this.Director = director;
  124.         this.attacker = attacker;
  125.         this.chosenTarget = target;
  126.         this.attackPosition = attackPosition;
  127.         this.attackRotation = attackRotation;
  128.         this.attackSequenceIdx = attackSequenceIdx;
  129.         this.calledShotLocation = calledShotLocation;
  130.         this.allSelectedWeapons = selectedWeapons;
  131.         this.isMoraleAttack = isMoraleAttack;
  132.         this.id = id;
  133.         this.stackItemUID = stackItemUID;
  134.         this.currentFiringGroup = 0;
  135.         this.cumulativeDamage = 0f;
  136.         this.numTargets = 1;
  137.         if (attacker.team.GUID == director.Combat.LocalPlayerTeamGuid)
  138.         {
  139.             this.previousTeamHealthDifference = attacker.team.CompareTeamHealthPercentages(target.team);
  140.         }
  141.         else
  142.         {
  143.             this.previousTeamHealthDifference = target.team.CompareTeamHealthPercentages(attacker.team);
  144.         }
  145.         this.allWeaponIds = new List<string>();
  146.         for (int i = 0; i < selectedWeapons.Count; i++)
  147.         {
  148.             this.allWeaponIds.Add(selectedWeapons[i].uid);
  149.             if (!selectedWeapons[i].WillFireAtTargetFromPosition(target, attackPosition, attackRotation))
  150.             {
  151.                 AttackDirector.AttackSequence.logger.LogWarning(string.Format("AttackSequence: Weapon {0} is firing at target {1}, but technically cannot fire at that target.", selectedWeapons[i].Name, target.DisplayName));
  152.             }
  153.         }
  154.         this.indirectFire = attacker.HasIndirectLOFToTargetUnit(attackPosition, attackRotation, target, true);
  155.         if (meleeAttackType != MeleeAttackType.NotSet)
  156.         {
  157.             this.isMelee = true;
  158.             this.meleeAttackType = meleeAttackType;
  159.         }
  160.         if (target.GameRep != null)
  161.         {
  162.             target.GameRep.SetVFXColliderEnabled(true);
  163.         }
  164.         this.attackDestroyedWeapon = new Dictionary<string, bool>();
  165.         this.attackDestroyedWeapon.Add(target.GUID, false);
  166.         this.attackCausedAmmoExplosion = new Dictionary<string, bool>();
  167.         this.attackCausedAmmoExplosion.Add(target.GUID, false);
  168.         this.attackContainsDodge = new Dictionary<string, bool>();
  169.         this.attackContainsDodge.Add(target.GUID, false);
  170.         this.attackCrits = new Dictionary<string, int>();
  171.         this.attackCrits.Add(target.GUID, 0);
  172.         this.attackWeaponCrits = new Dictionary<string, List<Weapon>>();
  173.         this.attackWeaponCrits.Add(target.GUID, new List<Weapon>());
  174.         this.attackAmmoCrits = new Dictionary<string, List<AmmunitionBox>>();
  175.         this.attackAmmoCrits.Add(target.GUID, new List<AmmunitionBox>());
  176.         this.attackDidDamage = new Dictionary<string, bool>();
  177.         this.attackDidDamage.Add(target.GUID, false);
  178.         this.attackArmorDamage = new Dictionary<string, float>();
  179.         this.attackArmorDamage.Add(target.GUID, 0f);
  180.         this.lowArmorStruck = new Dictionary<string, bool>();
  181.         this.lowArmorStruck.Add(target.GUID, false);
  182.         this.attackStructureDamage = new Dictionary<string, float>();
  183.         this.attackStructureDamage.Add(target.GUID, 0f);
  184.         this.attackDestroyedLeg = new Dictionary<string, bool>();
  185.         this.attackDestroyedLeg.Add(target.GUID, false);
  186.         this.attackDestroyedAnyLocation = new Dictionary<string, bool>();
  187.         this.attackDestroyedAnyLocation.Add(target.GUID, false);
  188.         this.attackDealtHeatDamage = new Dictionary<string, bool>();
  189.         this.attackDealtHeatDamage.Add(target.GUID, false);
  190.         this.attackCausedKnockdown = new Dictionary<string, bool>();
  191.         this.attackCausedKnockdown.Add(target.GUID, false);
  192.         this.attackCompletelyMissed = true;
  193.         this.attackDestroyedAttackerLeg = false;
  194.         this.attackTotalShotsFired = 0;
  195.         this.attackTotalShotsHit = 0;
  196.         this.allAffectedTargetIds = new List<string>();
  197.         this.AddAffectedTarget(target.GUID);
  198.         this.Init();
  199.     }
  200.  
  201.     // Token: 0x06006029 RID: 24617 RVA: 0x001A202C File Offset: 0x001A022C
  202.     private void Init()
  203.     {
  204.         MessageCenter messageCenter = this.Director.Combat.MessageCenter;
  205.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceGroupBegin, new ReceiveMessageCenterMessage(this.OnAttackSequenceGroupBegin));
  206.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceFire, new ReceiveMessageCenterMessage(this.OnAttackSequenceFire));
  207.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceWeaponPreFireComplete, new ReceiveMessageCenterMessage(this.OnAttackSequenceWeaponPreFireComplete));
  208.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceImpact, new ReceiveMessageCenterMessage(this.OnAttackSequenceImpact));
  209.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceResolveDamage, new ReceiveMessageCenterMessage(this.OnAttackSequenceResolveDamage));
  210.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceWeaponComplete, new ReceiveMessageCenterMessage(this.OnAttackSequenceWeaponComplete));
  211.         messageCenter.AddSubscriber(MessageCenterMessageType.OnAttackSequenceGroupEnd, new ReceiveMessageCenterMessage(this.OnAttackSequenceGroupEnd));
  212.         this.SortSelectedWeapons();
  213.         this.GenerateRandomCache();
  214.         this.GenerateNumberOfShots();
  215.         this.GenerateToHitInfo();
  216.         this.messageCoordinator.Initialize(this, this.weaponHitInfo);
  217.     }
  218.  
  219.     // Token: 0x0600602A RID: 24618 RVA: 0x001A20FE File Offset: 0x001A02FE
  220.     private int[] GetMinFudgeCache(int size)
  221.     {
  222.         return this.GetForcedFudgeCache(size, -1);
  223.     }
  224.  
  225.     // Token: 0x0600602B RID: 24619 RVA: 0x001A2108 File Offset: 0x001A0308
  226.     private int[] GetMaxFudgeCache(int size)
  227.     {
  228.         return this.GetForcedFudgeCache(size, 1);
  229.     }
  230.  
  231.     // Token: 0x0600602C RID: 24620 RVA: 0x001A2114 File Offset: 0x001A0314
  232.     private int[] GetForcedFudgeCache(int size, int value)
  233.     {
  234.         int[] array = new int[size];
  235.         for (int i = 0; i < size; i++)
  236.         {
  237.             array[i] = value;
  238.         }
  239.         return array;
  240.     }
  241.  
  242.     // Token: 0x0600602D RID: 24621 RVA: 0x001A213C File Offset: 0x001A033C
  243.     private void GenerateRandomCache()
  244.     {
  245.         int count = this.sortedWeapons.Count;
  246.         this.randomCache = new float[count][][];
  247.         this.randomCacheValuesUsed = new int[count][];
  248.         for (int i = 0; i < count; i++)
  249.         {
  250.             List<Weapon> list = this.sortedWeapons[i];
  251.             int count2 = list.Count;
  252.             float[][] array = new float[count2][];
  253.             int[] array2 = new int[count2];
  254.             for (int j = 0; j < count2; j++)
  255.             {
  256.                 int shotsWhenFired = list[j].ShotsWhenFired;
  257.                 int num = 6 * shotsWhenFired + 2 + 5;
  258.                 array[j] = this.Director.Combat.NetworkRandom.GetRandomCache(num);
  259.                 array2[j] = 0;
  260.             }
  261.             this.randomCache[i] = array;
  262.             this.randomCacheValuesUsed[i] = array2;
  263.         }
  264.         this.varianceCache = new int[count][][];
  265.         this.varianceCacheValuesUsed = new int[count][];
  266.         for (int k = 0; k < count; k++)
  267.         {
  268.             List<Weapon> list2 = this.sortedWeapons[k];
  269.             int count3 = list2.Count;
  270.             int[][] array3 = new int[count3][];
  271.             int[] array4 = new int[count3];
  272.             for (int l = 0; l < count3; l++)
  273.             {
  274.                 Weapon weapon = list2[l];
  275.                 int shotsWhenFired2 = weapon.ShotsWhenFired;
  276.                 int damageVariance = weapon.DamageVariance;
  277.                 int[] array5 = new int[shotsWhenFired2];
  278.                 for (int m = 0; m < shotsWhenFired2; m++)
  279.                 {
  280.                     int[] fudgeCache = this.Director.Combat.NetworkRandom.GetFudgeCache(damageVariance);
  281.                     int num2 = 0;
  282.                     for (int n = 0; n < damageVariance; n++)
  283.                     {
  284.                         num2 += fudgeCache[n];
  285.                     }
  286.                     array5[m] = num2;
  287.                 }
  288.                 array3[l] = array5;
  289.                 array4[l] = 0;
  290.             }
  291.             this.varianceCache[k] = array3;
  292.             this.varianceCacheValuesUsed[k] = array4;
  293.         }
  294.     }
  295.  
  296.     // Token: 0x0600602E RID: 24622 RVA: 0x001A2304 File Offset: 0x001A0504
  297.     public float GetRandomNumber(int groupIndex, int weaponIndex)
  298.     {
  299.         float num = 0f;
  300.         float[] array = this.randomCache[groupIndex][weaponIndex];
  301.         int num2 = this.randomCacheValuesUsed[groupIndex][weaponIndex];
  302.         if (num2 >= array.Length)
  303.         {
  304.             if (AttackDirector.hitLogger.IsLogEnabled)
  305.             {
  306.                 AttackDirector.hitLogger.Log(string.Format("???????? Random Values Used for Weapon Group: {0} // Weapon: {1}: {2} / {3} | Returning: {4}", new object[] { groupIndex, weaponIndex, num2, array.Length, num }));
  307.             }
  308.             return num;
  309.         }
  310.         num = array[num2];
  311.         num2++;
  312.         this.randomCacheValuesUsed[groupIndex][weaponIndex] = num2;
  313.         if (AttackDirector.hitLogger.IsLogEnabled)
  314.         {
  315.             AttackDirector.hitLogger.Log(string.Format("???????? Random Value Grabbed for Weapon Group: {0} // Weapon: {1}: [[ {2} ]] | {3} / {4} Values Used", new object[] { groupIndex, weaponIndex, num, num2, array.Length }));
  316.         }
  317.         return num;
  318.     }
  319.  
  320.     // Token: 0x0600602F RID: 24623 RVA: 0x001A23F4 File Offset: 0x001A05F4
  321.     public float[] GetRandomNumbers(int groupIndex, int weaponIndex, int amount)
  322.     {
  323.         float[] array = new float[amount];
  324.         for (int i = 0; i < amount; i++)
  325.         {
  326.             array[i] = this.GetRandomNumber(groupIndex, weaponIndex);
  327.         }
  328.         return array;
  329.     }
  330.  
  331.     // Token: 0x06006030 RID: 24624 RVA: 0x001A2420 File Offset: 0x001A0620
  332.     public int GetVarianceValue(int groupIndex, int weaponIndex, Weapon weapon)
  333.     {
  334.         int num = 0;
  335.         int[] array = this.varianceCache[groupIndex][weaponIndex];
  336.         int num2 = this.varianceCacheValuesUsed[groupIndex][weaponIndex];
  337.         if (num2 >= array.Length)
  338.         {
  339.             if (AttackDirector.damageLogger.IsLogEnabled)
  340.             {
  341.                 AttackDirector.damageLogger.Log(string.Format("Variance values for weapon group {0} weapon {1} are all used! Only {2} were created. Returning {3}", new object[] { groupIndex, weaponIndex, array.Length, num }));
  342.             }
  343.             return num;
  344.         }
  345.         num = array[num2];
  346.         num2++;
  347.         this.varianceCacheValuesUsed[groupIndex][weaponIndex] = num2;
  348.         return num;
  349.     }
  350.  
  351.     // Token: 0x06006031 RID: 24625 RVA: 0x001A24B0 File Offset: 0x001A06B0
  352.     public int[] GetVarianceSums(int groupIndex, int weaponIndex, int amount, Weapon weapon)
  353.     {
  354.         if (AttackDirector.damageLogger.IsLogEnabled)
  355.         {
  356.             AttackDirector.damageLogger.Log(string.Format("------------------------------------------------------------- Creating an array of {0} Variance value(s) for {1} (ID {2})", amount, weapon.Name, weaponIndex));
  357.         }
  358.         int[] array = new int[amount];
  359.         for (int i = 0; i < amount; i++)
  360.         {
  361.             array[i] = this.GetVarianceValue(groupIndex, weaponIndex, weapon);
  362.         }
  363.         if (AttackDirector.damageLogger.IsLogEnabled)
  364.         {
  365.             string text = "Variance values:";
  366.             for (int j = 0; j < amount; j++)
  367.             {
  368.                 text = string.Format("{0} {1}", text, array[j]);
  369.             }
  370.             AttackDirector.damageLogger.Log(text);
  371.         }
  372.         return array;
  373.     }
  374.  
  375.     // Token: 0x06006032 RID: 24626 RVA: 0x001A2550 File Offset: 0x001A0750
  376.     private void GenerateNumberOfShots()
  377.     {
  378.         int count = this.sortedWeapons.Count;
  379.         this.numberOfShots = new int[count][];
  380.         for (int i = 0; i < count; i++)
  381.         {
  382.             List<Weapon> list = this.sortedWeapons[i];
  383.             int count2 = list.Count;
  384.             int[] array = new int[count2];
  385.             for (int j = 0; j < count2; j++)
  386.             {
  387.                 Weapon weapon = list[j];
  388.                 array[j] = -1;
  389.                 if (weapon.WillFire)
  390.                 {
  391.                     array[j] = 0;
  392.                     int num = weapon.PreFireWeapon(this.stackItemUID);
  393.                     if (num >= 1)
  394.                     {
  395.                         array[j] = num;
  396.                     }
  397.                 }
  398.             }
  399.             this.numberOfShots[i] = array;
  400.         }
  401.     }
  402.  
  403.     // Token: 0x06006033 RID: 24627 RVA: 0x001A25F4 File Offset: 0x001A07F4
  404.     private void GenerateToHitInfo()
  405.     {
  406.         int count = this.sortedWeapons.Count;
  407.         this.weaponHitInfo = new WeaponHitInfo?[count][];
  408.         float num = 0f;
  409.         for (int i = 0; i < count; i++)
  410.         {
  411.             List<Weapon> list = this.sortedWeapons[i];
  412.             int count2 = list.Count;
  413.             WeaponHitInfo?[] array = new WeaponHitInfo?[count2];
  414.             int[] array2 = this.numberOfShots[i];
  415.             for (int j = 0; j < count2; j++)
  416.             {
  417.                 Weapon weapon = list[j];
  418.                 array[j] = null;
  419.                 int num2 = array2[j];
  420.                 if (num2 != -1 && num2 != 0)
  421.                 {
  422.                     WeaponHitInfo weaponHitInfo = this.GenerateHitInfo(weapon, i, j, num2, this.indirectFire, num);
  423.                     this.AddAllAffectedTargets(weaponHitInfo);
  424.                     array[j] = new WeaponHitInfo?(weaponHitInfo);
  425.                 }
  426.             }
  427.             this.weaponHitInfo[i] = array;
  428.         }
  429.     }
  430.  
  431.     // Token: 0x06006034 RID: 24628 RVA: 0x001A26CC File Offset: 0x001A08CC
  432.     public void Cleanup()
  433.     {
  434.         MessageCenter messageCenter = this.Director.Combat.MessageCenter;
  435.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceGroupBegin, new ReceiveMessageCenterMessage(this.OnAttackSequenceGroupBegin));
  436.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceFire, new ReceiveMessageCenterMessage(this.OnAttackSequenceFire));
  437.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceWeaponPreFireComplete, new ReceiveMessageCenterMessage(this.OnAttackSequenceWeaponPreFireComplete));
  438.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceImpact, new ReceiveMessageCenterMessage(this.OnAttackSequenceImpact));
  439.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceResolveDamage, new ReceiveMessageCenterMessage(this.OnAttackSequenceResolveDamage));
  440.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceWeaponComplete, new ReceiveMessageCenterMessage(this.OnAttackSequenceWeaponComplete));
  441.         messageCenter.RemoveSubscriber(MessageCenterMessageType.OnAttackSequenceGroupEnd, new ReceiveMessageCenterMessage(this.OnAttackSequenceGroupEnd));
  442.     }
  443.  
  444.     // Token: 0x06006035 RID: 24629 RVA: 0x001A2774 File Offset: 0x001A0974
  445.     public void FlagAttackDestroyedWeapon(string id)
  446.     {
  447.         this.AddAffectedTarget(id);
  448.         this.attackDestroyedWeapon[id] = true;
  449.     }
  450.  
  451.     // Token: 0x06006036 RID: 24630 RVA: 0x001A278C File Offset: 0x001A098C
  452.     public bool GetAttackDestroyedWeapon(string id)
  453.     {
  454.         bool flag = false;
  455.         this.attackDestroyedWeapon.TryGetValue(id, out flag);
  456.         return flag;
  457.     }
  458.  
  459.     // Token: 0x06006037 RID: 24631 RVA: 0x001A27AB File Offset: 0x001A09AB
  460.     public void FlagAttackCausedAmmoExplosion(string id)
  461.     {
  462.         this.AddAffectedTarget(id);
  463.         this.attackCausedAmmoExplosion[id] = true;
  464.     }
  465.  
  466.     // Token: 0x06006038 RID: 24632 RVA: 0x001A27C4 File Offset: 0x001A09C4
  467.     public bool GetAttackCausedAmmoExplosion(string id)
  468.     {
  469.         bool flag = false;
  470.         this.attackCausedAmmoExplosion.TryGetValue(id, out flag);
  471.         return flag;
  472.     }
  473.  
  474.     // Token: 0x06006039 RID: 24633 RVA: 0x001A27E3 File Offset: 0x001A09E3
  475.     public void FlagAttackContainsDodge(string id)
  476.     {
  477.         this.AddAffectedTarget(id);
  478.         this.attackContainsDodge[id] = true;
  479.     }
  480.  
  481.     // Token: 0x0600603A RID: 24634 RVA: 0x001A27FC File Offset: 0x001A09FC
  482.     public bool GetAttackContainsDodge(string id)
  483.     {
  484.         bool flag = false;
  485.         this.attackContainsDodge.TryGetValue(id, out flag);
  486.         return flag;
  487.     }
  488.  
  489.     // Token: 0x0600603B RID: 24635 RVA: 0x001A281B File Offset: 0x001A0A1B
  490.     public void FlagAttackDestroyedLeg(string id)
  491.     {
  492.         this.AddAffectedTarget(id);
  493.         this.attackDestroyedLeg[id] = true;
  494.     }
  495.  
  496.     // Token: 0x0600603C RID: 24636 RVA: 0x001A2834 File Offset: 0x001A0A34
  497.     public bool GetAttackDestroyedLeg(string id)
  498.     {
  499.         bool flag = false;
  500.         this.attackDestroyedLeg.TryGetValue(id, out flag);
  501.         return flag;
  502.     }
  503.  
  504.     // Token: 0x0600603D RID: 24637 RVA: 0x001A2853 File Offset: 0x001A0A53
  505.     public void FlagAttackDestroyedAttackerLeg()
  506.     {
  507.         this.attackDestroyedAttackerLeg = true;
  508.     }
  509.  
  510.     // Token: 0x0600603E RID: 24638 RVA: 0x001A285C File Offset: 0x001A0A5C
  511.     public void FlagAttackDestroyedAnyLocation(string id)
  512.     {
  513.         this.AddAffectedTarget(id);
  514.         this.attackDestroyedAnyLocation[id] = true;
  515.     }
  516.  
  517.     // Token: 0x0600603F RID: 24639 RVA: 0x001A2874 File Offset: 0x001A0A74
  518.     public bool GetAttackDestroyedAnyLocation(string id)
  519.     {
  520.         bool flag = false;
  521.         this.attackDestroyedAnyLocation.TryGetValue(id, out flag);
  522.         return flag;
  523.     }
  524.  
  525.     // Token: 0x06006040 RID: 24640 RVA: 0x001A2893 File Offset: 0x001A0A93
  526.     public void FlagAttackDidDamage(string id)
  527.     {
  528.         this.AddAffectedTarget(id);
  529.         this.attackDidDamage[id] = true;
  530.     }
  531.  
  532.     // Token: 0x06006041 RID: 24641 RVA: 0x001A28AC File Offset: 0x001A0AAC
  533.     public bool GetAttackDidDamage(string id)
  534.     {
  535.         bool flag = false;
  536.         this.attackDidDamage.TryGetValue(id, out flag);
  537.         return flag;
  538.     }
  539.  
  540.     // Token: 0x06006042 RID: 24642 RVA: 0x001A28CC File Offset: 0x001A0ACC
  541.     public void FlagArmorDamage(string id, float amount)
  542.     {
  543.         this.AddAffectedTarget(id);
  544.         if (!this.attackArmorDamage.ContainsKey(id))
  545.         {
  546.             this.attackArmorDamage.Add(id, 0f);
  547.         }
  548.         float num = this.attackArmorDamage[id] + amount;
  549.         this.attackArmorDamage[id] = num;
  550.     }
  551.  
  552.     // Token: 0x06006043 RID: 24643 RVA: 0x001A291C File Offset: 0x001A0B1C
  553.     public float GetArmorDamageDealt(string id)
  554.     {
  555.         float num = 0f;
  556.         this.attackArmorDamage.TryGetValue(id, out num);
  557.         return num;
  558.     }
  559.  
  560.     // Token: 0x06006044 RID: 24644 RVA: 0x001A293F File Offset: 0x001A0B3F
  561.     public void FlagLowArmorStruck(string id)
  562.     {
  563.         this.AddAffectedTarget(id);
  564.         this.lowArmorStruck[id] = true;
  565.     }
  566.  
  567.     // Token: 0x06006045 RID: 24645 RVA: 0x001A2958 File Offset: 0x001A0B58
  568.     public bool GetLowArmorStruck(string id)
  569.     {
  570.         bool flag = false;
  571.         this.lowArmorStruck.TryGetValue(id, out flag);
  572.         return flag;
  573.     }
  574.  
  575.     // Token: 0x06006046 RID: 24646 RVA: 0x001A2978 File Offset: 0x001A0B78
  576.     public void FlagStructureDamage(string id, float amount)
  577.     {
  578.         this.AddAffectedTarget(id);
  579.         if (!this.attackStructureDamage.ContainsKey(id))
  580.         {
  581.             this.attackStructureDamage.Add(id, 0f);
  582.         }
  583.         float num = this.attackStructureDamage[id] + amount;
  584.         this.attackStructureDamage[id] = num;
  585.     }
  586.  
  587.     // Token: 0x06006047 RID: 24647 RVA: 0x001A29C8 File Offset: 0x001A0BC8
  588.     public float GetStructureDamageDealt(string id)
  589.     {
  590.         float num = 0f;
  591.         this.attackStructureDamage.TryGetValue(id, out num);
  592.         return num;
  593.     }
  594.  
  595.     // Token: 0x06006048 RID: 24648 RVA: 0x001A29EB File Offset: 0x001A0BEB
  596.     public void FlagAttackDidHeatDamage(string id)
  597.     {
  598.         this.AddAffectedTarget(id);
  599.         this.attackDealtHeatDamage[id] = true;
  600.     }
  601.  
  602.     // Token: 0x06006049 RID: 24649 RVA: 0x001A2A04 File Offset: 0x001A0C04
  603.     public bool GetAttackDidHeatDamage(string id)
  604.     {
  605.         bool flag = false;
  606.         this.attackDealtHeatDamage.TryGetValue(id, out flag);
  607.         return flag;
  608.     }
  609.  
  610.     // Token: 0x0600604A RID: 24650 RVA: 0x001A2A23 File Offset: 0x001A0C23
  611.     public void FlagAttackCausedKnockdown(string id)
  612.     {
  613.         this.AddAffectedTarget(id);
  614.         this.attackCausedKnockdown[id] = true;
  615.     }
  616.  
  617.     // Token: 0x0600604B RID: 24651 RVA: 0x001A2A3C File Offset: 0x001A0C3C
  618.     public bool GetAttackCausedKnockdown(string id)
  619.     {
  620.         bool flag = false;
  621.         this.attackCausedKnockdown.TryGetValue(id, out flag);
  622.         return flag;
  623.     }
  624.  
  625.     // Token: 0x0600604C RID: 24652 RVA: 0x001A2A5C File Offset: 0x001A0C5C
  626.     public void FlagShotHit()
  627.     {
  628.         int num = this.attackTotalShotsFired + 1;
  629.         this.attackTotalShotsFired = num;
  630.         num = this.attackTotalShotsHit + 1;
  631.         this.attackTotalShotsHit = num;
  632.     }
  633.  
  634.     // Token: 0x0600604D RID: 24653 RVA: 0x001A2A8C File Offset: 0x001A0C8C
  635.     public void FlagShotMissed()
  636.     {
  637.         int num = this.attackTotalShotsFired + 1;
  638.         this.attackTotalShotsFired = num;
  639.     }
  640.  
  641.     // Token: 0x0600604E RID: 24654 RVA: 0x001A2AAC File Offset: 0x001A0CAC
  642.     public void FlagAttackScoredCrit(string id, Weapon weapon, AmmunitionBox ammoBox)
  643.     {
  644.         this.AddAffectedTarget(id);
  645.         if (!this.attackCrits.ContainsKey(id))
  646.         {
  647.             this.attackCrits.Add(id, 0);
  648.         }
  649.         int num = this.attackCrits[id] + 1;
  650.         this.attackCrits[id] = num;
  651.         if (weapon != null)
  652.         {
  653.             if (!this.attackWeaponCrits.ContainsKey(id))
  654.             {
  655.                 this.attackWeaponCrits.Add(id, new List<Weapon>());
  656.             }
  657.             List<Weapon> list = this.attackWeaponCrits[id];
  658.             if (!list.Contains(weapon))
  659.             {
  660.                 list.Add(weapon);
  661.             }
  662.             this.attackWeaponCrits[id] = list;
  663.         }
  664.         if (ammoBox != null)
  665.         {
  666.             if (!this.attackAmmoCrits.ContainsKey(id))
  667.             {
  668.                 this.attackAmmoCrits.Add(id, new List<AmmunitionBox>());
  669.             }
  670.             List<AmmunitionBox> list2 = this.attackAmmoCrits[id];
  671.             if (!list2.Contains(ammoBox))
  672.             {
  673.                 list2.Add(ammoBox);
  674.             }
  675.             this.attackAmmoCrits[id] = list2;
  676.         }
  677.     }
  678.  
  679.     // Token: 0x0600604F RID: 24655 RVA: 0x001A2B90 File Offset: 0x001A0D90
  680.     public int GetAttackCritsCount(string id)
  681.     {
  682.         int num = 0;
  683.         this.attackCrits.TryGetValue(id, out num);
  684.         return num;
  685.     }
  686.  
  687.     // Token: 0x06006050 RID: 24656 RVA: 0x001A2BB0 File Offset: 0x001A0DB0
  688.     public List<Weapon> GetAttackWeaponCrits(string id)
  689.     {
  690.         List<Weapon> list = new List<Weapon>();
  691.         if (this.attackWeaponCrits.TryGetValue(id, out list))
  692.         {
  693.             return list;
  694.         }
  695.         return new List<Weapon>();
  696.     }
  697.  
  698.     // Token: 0x06006051 RID: 24657 RVA: 0x001A2BDC File Offset: 0x001A0DDC
  699.     public List<AmmunitionBox> GetAttackAmmoCrits(string id)
  700.     {
  701.         List<AmmunitionBox> list = new List<AmmunitionBox>();
  702.         if (this.attackAmmoCrits.TryGetValue(id, out list))
  703.         {
  704.             return list;
  705.         }
  706.         return new List<AmmunitionBox>();
  707.     }
  708.  
  709.     // Token: 0x06006052 RID: 24658 RVA: 0x001A2C06 File Offset: 0x001A0E06
  710.     public void AddAffectedTarget(string id)
  711.     {
  712.         if (!string.IsNullOrEmpty(id) && !this.allAffectedTargetIds.Contains(id))
  713.         {
  714.             this.allAffectedTargetIds.Add(id);
  715.         }
  716.     }
  717.  
  718.     // Token: 0x06006053 RID: 24659 RVA: 0x001A2C2C File Offset: 0x001A0E2C
  719.     public void AddAllAffectedTargets(WeaponHitInfo hitInfo)
  720.     {
  721.         if (hitInfo.secondaryTargetIds == null)
  722.         {
  723.             return;
  724.         }
  725.         foreach (string text in hitInfo.secondaryTargetIds)
  726.         {
  727.             this.AddAffectedTarget(text);
  728.         }
  729.     }
  730.  
  731.     // Token: 0x06006054 RID: 24660 RVA: 0x001A2C62 File Offset: 0x001A0E62
  732.     public Weapon GetWeapon(int groupIdx, int weaponIdx)
  733.     {
  734.         return this.sortedWeapons[groupIdx][weaponIdx];
  735.     }
  736.  
  737.     // Token: 0x06006055 RID: 24661 RVA: 0x001A2C78 File Offset: 0x001A0E78
  738.     private WeaponHitInfo GenerateHitInfo(Weapon weapon, int groupIdx, int weaponIdx, int numberOfShots, bool indirectFire, float dodgedDamage)
  739.     {
  740.         WeaponHitInfo weaponHitInfo = default(WeaponHitInfo);
  741.         weaponHitInfo.attackerId = this.attacker.GUID;
  742.         weaponHitInfo.targetId = this.chosenTarget.GUID;
  743.         weaponHitInfo.numberOfShots = numberOfShots;
  744.         weaponHitInfo.stackItemUID = this.stackItemUID;
  745.         weaponHitInfo.attackSequenceId = this.id;
  746.         weaponHitInfo.attackGroupIndex = groupIdx;
  747.         weaponHitInfo.attackWeaponIndex = weaponIdx;
  748.         weaponHitInfo.toHitRolls = new float[numberOfShots];
  749.         weaponHitInfo.locationRolls = new float[numberOfShots];
  750.         weaponHitInfo.dodgeRolls = new float[numberOfShots];
  751.         weaponHitInfo.dodgeSuccesses = new bool[numberOfShots];
  752.         weaponHitInfo.hitLocations = new int[numberOfShots];
  753.         weaponHitInfo.hitPositions = new Vector3[numberOfShots];
  754.         weaponHitInfo.hitVariance = new int[numberOfShots];
  755.         weaponHitInfo.hitQualities = new AttackImpactQuality[numberOfShots];
  756.         weaponHitInfo.secondaryTargetIds = new string[numberOfShots];
  757.         weaponHitInfo.secondaryHitLocations = new int[numberOfShots];
  758.         weaponHitInfo.attackDirections = new AttackDirection[numberOfShots];
  759.         if (AttackDirector.hitLogger.IsLogEnabled)
  760.         {
  761.             Vector3 vector;
  762.             LineOfFireLevel lineOfFire = this.Director.Combat.LOS.GetLineOfFire(this.attacker, this.attackPosition, this.chosenTarget, this.chosenTarget.CurrentPosition, this.chosenTarget.CurrentRotation, out vector);
  763.             float allModifiers = this.Director.Combat.ToHit.GetAllModifiers(this.attacker, weapon, this.chosenTarget, this.attackPosition + this.attacker.HighestLOSPosition, this.chosenTarget.TargetPosition, lineOfFire, this.isMoraleAttack);
  764.             string allModifiersDescription = this.Director.Combat.ToHit.GetAllModifiersDescription(this.attacker, weapon, this.chosenTarget, this.attackPosition + this.attacker.HighestLOSPosition, this.chosenTarget.TargetPosition, lineOfFire, this.isMoraleAttack);
  765.             bool pilot = this.attacker.GetPilot() != null;
  766.             AttackDirector.hitLogger.Log(string.Format("======================================== Unit Firing: {0} | Weapon: {1} | Shots: {2}", this.attacker.DisplayName, weapon.Name, numberOfShots));
  767.             AttackDirector.hitLogger.Log(string.Format("======================================== Hit Info: GROUP {0} | ID {1}", groupIdx, weaponIdx));
  768.             AttackDirector.hitLogger.Log(string.Format("======================================== MODIFIERS: {0}... FINAL: [[ {1} ]] ", allModifiersDescription, allModifiers));
  769.             if (pilot)
  770.             {
  771.                 AttackDirector.hitLogger.Log(this.Director.Combat.ToHit.GetBaseToHitChanceDesc(this.attacker));
  772.             }
  773.             else
  774.             {
  775.                 AttackDirector.hitLogger.Log(string.Format("======================================== Gunnery Check: NO PILOT", Array.Empty<object>()));
  776.             }
  777.         }
  778.         float num = this.Director.Combat.ToHit.GetToHitChance(this.attacker, weapon, this.chosenTarget, this.attackPosition, this.chosenTarget.CurrentPosition, this.numTargets, this.meleeAttackType, this.isMoraleAttack);
  779.         if (Mech.TEST_KNOCKDOWN)
  780.         {
  781.             num = 1f;
  782.         }
  783.         if (AttackDirector.hitLogger.IsLogEnabled)
  784.         {
  785.             AttackDirector.hitLogger.Log(string.Format("======================================== HIT CHANCE: [[ {0:P2} ]]", num));
  786.         }
  787.         switch (weapon.Type)
  788.         {
  789.         case WeaponType.Autocannon:
  790.         case WeaponType.Gauss:
  791.         case WeaponType.Laser:
  792.         case WeaponType.PPC:
  793.         case WeaponType.Flamer:
  794.         case WeaponType.Melee:
  795.         case WeaponType.COIL:
  796.             this.GetIndividualHits(ref weaponHitInfo, groupIdx, weaponIdx, weapon, num, dodgedDamage);
  797.             return weaponHitInfo;
  798.         case WeaponType.LRM:
  799.             this.GetClusteredHits(ref weaponHitInfo, groupIdx, weaponIdx, weapon, num, dodgedDamage);
  800.             return weaponHitInfo;
  801.         case WeaponType.SRM:
  802.             this.GetIndividualHits(ref weaponHitInfo, groupIdx, weaponIdx, weapon, num, dodgedDamage);
  803.             return weaponHitInfo;
  804.         case WeaponType.MachineGun:
  805.             this.GetIndividualHits(ref weaponHitInfo, groupIdx, weaponIdx, weapon, num, dodgedDamage);
  806.             return weaponHitInfo;
  807.         }
  808.         AttackDirector.attackLogger.LogError(string.Format("GenerateHitInfo found invalid weapon type: {0}, using basic hit info", weapon.Type));
  809.         this.GetIndividualHits(ref weaponHitInfo, groupIdx, weaponIdx, weapon, num, dodgedDamage);
  810.         return weaponHitInfo;
  811.     }
  812.  
  813.     // Token: 0x17000D78 RID: 3448
  814.     // (get) Token: 0x06006056 RID: 24662 RVA: 0x001A3041 File Offset: 0x001A1241
  815.     public bool IsBreachingShot
  816.     {
  817.         get
  818.         {
  819.             return this.attacker.HasBreachingShotAbility && this.TotalWeaponCount == 1 && this.allSelectedWeapons[0].Type != WeaponType.Melee;
  820.         }
  821.     }
  822.  
  823.     // Token: 0x06006057 RID: 24663 RVA: 0x001A3074 File Offset: 0x001A1274
  824.     private float GetCorrectedRoll(float roll, Team team)
  825.     {
  826.         float num = roll;
  827.         if (AttackDirector.AttackSequence.UseWeightedHitNumbers)
  828.         {
  829.             float num2 = roll * 1.6f - 0.8f;
  830.             num = (num2 * num2 * num2 + 0.5f) / 2f + roll / 2f;
  831.         }
  832.         if (AttackDirector.AttackSequence.PrintDebugInfo)
  833.         {
  834.             AttackDirector.attackLogger.Log(string.Format("Roll correction: {0}/{1}", roll, num));
  835.         }
  836.         if (team != null)
  837.         {
  838.             num -= team.StreakBreakingValue;
  839.         }
  840.         return num;
  841.     }
  842.  
  843.     // Token: 0x06006058 RID: 24664 RVA: 0x001A30E8 File Offset: 0x001A12E8
  844.     private void GetIndividualHits(ref WeaponHitInfo hitInfo, int groupIdx, int weaponIdx, Weapon weapon, float toHitChance, float prevDodgedDamage)
  845.     {
  846.         if (AttackDirector.hitLogger.IsLogEnabled)
  847.         {
  848.             AttackDirector.hitLogger.Log(string.Format("???????? RANDOM HIT ROLLS (GetIndividualHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  849.         }
  850.         hitInfo.toHitRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  851.         if (AttackDirector.hitLogger.IsLogEnabled)
  852.         {
  853.             AttackDirector.hitLogger.Log(string.Format("???????? RANDOM LOCATION ROLLS (GetIndividualHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  854.         }
  855.         hitInfo.locationRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  856.         if (AttackDirector.hitLogger.IsLogEnabled)
  857.         {
  858.             AttackDirector.hitLogger.Log(string.Format("???????? DODGE ROLLS (GetIndividualHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  859.         }
  860.         hitInfo.dodgeRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  861.         hitInfo.hitVariance = this.GetVarianceSums(groupIdx, weaponIdx, hitInfo.numberOfShots, weapon);
  862.         AbstractActor abstractActor = this.chosenTarget as AbstractActor;
  863.         Team team = ((weapon != null && weapon.parent != null && weapon.parent.team != null) ? weapon.parent.team : null);
  864.         float num = this.attacker.CalledShotBonusMultiplier;
  865.         for (int i = 0; i < hitInfo.numberOfShots; i++)
  866.         {
  867.             float correctedRoll = this.GetCorrectedRoll(hitInfo.toHitRolls[i], team);
  868.             bool flag = correctedRoll <= toHitChance;
  869.             if (team != null)
  870.             {
  871.                 team.ProcessRandomRoll(toHitChance, flag);
  872.             }
  873.             bool flag2 = false;
  874.             if (abstractActor != null)
  875.             {
  876.                 flag2 = abstractActor.CheckDodge(this.attacker, weapon, hitInfo, i, this.IsBreachingShot);
  877.             }
  878.             if (flag && flag2)
  879.             {
  880.                 hitInfo.dodgeSuccesses[i] = true;
  881.                 this.FlagAttackContainsDodge(abstractActor.GUID);
  882.             }
  883.             else
  884.             {
  885.                 hitInfo.dodgeSuccesses[i] = false;
  886.             }
  887.             if (AttackDirector.attackLogger.IsLogEnabled)
  888.             {
  889.                 string text = string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Roll Value: {3}", new object[] { this.id, weaponIdx, i, correctedRoll });
  890.                 AttackDirector.attackLogger.Log(text);
  891.             }
  892.             if (flag && !flag2)
  893.             {
  894.                 hitInfo.hitLocations[i] = this.chosenTarget.GetHitLocation(this.attacker, this.attackPosition, hitInfo.locationRolls[i], this.calledShotLocation, num);
  895.                 num = Mathf.Lerp(num, 1f, this.Director.Combat.Constants.HitTables.CalledShotBonusDegradeLerpFactor);
  896.                 if (AttackDirector.attackLogger.IsLogEnabled)
  897.                 {
  898.                     AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Hit! Location: {3}", new object[]
  899.                     {
  900.                         this.id,
  901.                         weaponIdx,
  902.                         i,
  903.                         hitInfo.hitLocations[i]
  904.                     }));
  905.                 }
  906.                 if (AttackDirector.hitminLogger.IsLogEnabled)
  907.                 {
  908.                     AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Hits! ////// HEX VAL {2}", weapon.Name, i, hitInfo.hitLocations[i]));
  909.                 }
  910.                 hitInfo.hitQualities[i] = this.Director.Combat.ToHit.GetBlowQuality(this.attacker, this.attackPosition, weapon, this.chosenTarget, this.meleeAttackType, this.IsBreachingShot);
  911.                 this.FlagShotHit();
  912.             }
  913.             else
  914.             {
  915.                 hitInfo.hitLocations[i] = 0;
  916.                 if (AttackDirector.attackLogger.IsLogEnabled)
  917.                 {
  918.                     AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Miss!", this.id, weaponIdx, i));
  919.                 }
  920.                 if (AttackDirector.hitminLogger.IsLogEnabled)
  921.                 {
  922.                     AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Misses!", weapon.Name, i));
  923.                 }
  924.                 this.FlagShotMissed();
  925.             }
  926.             hitInfo.hitPositions[i] = this.chosenTarget.GetImpactPosition(this.attacker, this.attackPosition, weapon, ref hitInfo.hitLocations[i], ref hitInfo.attackDirections[i], ref hitInfo.secondaryTargetIds[i], ref hitInfo.secondaryHitLocations[i]);
  927.             this.RefreshHitQualitiesForSecondaryTargets(ref hitInfo, weapon, i);
  928.         }
  929.     }
  930.  
  931.     // Token: 0x06006059 RID: 24665 RVA: 0x001A34F8 File Offset: 0x001A16F8
  932.     private void GetClusteredHits(ref WeaponHitInfo hitInfo, int groupIdx, int weaponIdx, Weapon weapon, float toHitChance, float prevDodgedDamage)
  933.     {
  934.         if (AttackDirector.hitLogger.IsLogEnabled)
  935.         {
  936.             AttackDirector.hitLogger.Log(string.Format("???????? RANDOM HIT ROLLS (GetClusteredHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  937.         }
  938.         hitInfo.toHitRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  939.         if (AttackDirector.hitLogger.IsLogEnabled)
  940.         {
  941.             AttackDirector.hitLogger.Log(string.Format("???????? RANDOM LOCATION ROLLS (GetClusteredHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  942.         }
  943.         hitInfo.locationRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  944.         if (AttackDirector.hitLogger.IsLogEnabled)
  945.         {
  946.             AttackDirector.hitLogger.Log(string.Format("???????? DODGE ROLLS (GetClusteredHits): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  947.         }
  948.         hitInfo.dodgeRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  949.         hitInfo.hitVariance = this.GetVarianceSums(groupIdx, weaponIdx, hitInfo.numberOfShots, weapon);
  950.         int num = 0;
  951.         float num2 = 1f + weapon.ClusteringModifier;
  952.         float num3 = 1f;
  953.         AbstractActor abstractActor = this.chosenTarget as AbstractActor;
  954.         Team team = ((weapon != null && weapon.parent != null && weapon.parent.team != null) ? weapon.parent.team : null);
  955.         for (int i = 0; i < hitInfo.numberOfShots; i++)
  956.         {
  957.             bool flag = this.GetCorrectedRoll(hitInfo.toHitRolls[i], team) <= toHitChance;
  958.             if (team != null)
  959.             {
  960.                 team.ProcessRandomRoll(toHitChance, flag);
  961.             }
  962.             bool flag2 = false;
  963.             if (abstractActor != null)
  964.             {
  965.                 flag2 = abstractActor.CheckDodge(this.attacker, weapon, hitInfo, i, this.IsBreachingShot);
  966.             }
  967.             if (flag && flag2)
  968.             {
  969.                 hitInfo.dodgeSuccesses[i] = true;
  970.                 this.FlagAttackContainsDodge(abstractActor.GUID);
  971.             }
  972.             else
  973.             {
  974.                 hitInfo.dodgeSuccesses[i] = false;
  975.             }
  976.             if (flag && !flag2)
  977.             {
  978.                 if (num == 0)
  979.                 {
  980.                     num = this.chosenTarget.GetHitLocation(this.attacker, this.attackPosition, hitInfo.locationRolls[i], this.calledShotLocation, this.attacker.CalledShotBonusMultiplier);
  981.                     hitInfo.hitLocations[i] = num;
  982.                     if (AttackDirector.attackLogger.IsLogEnabled)
  983.                     {
  984.                         AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Initial clustered hit! Location: {3}", new object[]
  985.                         {
  986.                             this.id,
  987.                             weaponIdx,
  988.                             i,
  989.                             hitInfo.hitLocations[i]
  990.                         }));
  991.                     }
  992.                     if (AttackDirector.hitminLogger.IsLogEnabled)
  993.                     {
  994.                         AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Hits! ////// INITIAL HIT - HEX VAL {2}", weapon.Name, i, hitInfo.hitLocations[i]));
  995.                     }
  996.                 }
  997.                 else
  998.                 {
  999.                     hitInfo.hitLocations[i] = this.chosenTarget.GetAdjacentHitLocation(this.attackPosition, hitInfo.locationRolls[i], num, num2, num3);
  1000.                     if (AttackDirector.attackLogger.IsLogEnabled)
  1001.                     {
  1002.                         AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Clustered hit! Location: {3}", new object[]
  1003.                         {
  1004.                             this.id,
  1005.                             weaponIdx,
  1006.                             i,
  1007.                             hitInfo.hitLocations[i]
  1008.                         }));
  1009.                     }
  1010.                     if (AttackDirector.hitminLogger.IsLogEnabled)
  1011.                     {
  1012.                         AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Hits! ////// CLUSTER HIT - HEX VAL {2}", weapon.Name, i, hitInfo.hitLocations[i]));
  1013.                     }
  1014.                 }
  1015.                 hitInfo.hitQualities[i] = this.Director.Combat.ToHit.GetBlowQuality(this.attacker, this.attackPosition, weapon, this.chosenTarget, this.meleeAttackType, this.IsBreachingShot);
  1016.                 this.FlagShotHit();
  1017.             }
  1018.             else
  1019.             {
  1020.                 hitInfo.hitLocations[i] = 0;
  1021.                 if (AttackDirector.attackLogger.IsLogEnabled)
  1022.                 {
  1023.                     AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Miss!", new object[]
  1024.                     {
  1025.                         this.id,
  1026.                         weaponIdx,
  1027.                         i,
  1028.                         hitInfo.hitLocations[i]
  1029.                     }));
  1030.                 }
  1031.                 if (AttackDirector.hitminLogger.IsLogEnabled)
  1032.                 {
  1033.                     AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Misses!", weapon.Name, i));
  1034.                 }
  1035.                 this.FlagShotMissed();
  1036.             }
  1037.             hitInfo.hitPositions[i] = this.chosenTarget.GetImpactPosition(this.attacker, this.attackPosition, weapon, ref hitInfo.hitLocations[i], ref hitInfo.attackDirections[i], ref hitInfo.secondaryTargetIds[i], ref hitInfo.secondaryHitLocations[i]);
  1038.             this.RefreshHitQualitiesForSecondaryTargets(ref hitInfo, weapon, i);
  1039.         }
  1040.     }
  1041.  
  1042.     // Token: 0x0600605A RID: 24666 RVA: 0x001A39A4 File Offset: 0x001A1BA4
  1043.     private void GetSingleClusteredHit(ref WeaponHitInfo hitInfo, int groupIdx, int weaponIdx, Weapon weapon, float toHitChance, float originalMultiplier = 1f, float adjacentMultiplier = 1f)
  1044.     {
  1045.         float randomNumber = this.GetRandomNumber(groupIdx, weaponIdx);
  1046.         for (int i = 0; i < hitInfo.numberOfShots; i++)
  1047.         {
  1048.             hitInfo.toHitRolls[i] = randomNumber;
  1049.         }
  1050.         if (AttackDirector.hitLogger.IsLogEnabled)
  1051.         {
  1052.             AttackDirector.hitLogger.Log(string.Format("???????? RANDOM LOCATION ROLLS (GetSingleClusteredHit): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  1053.         }
  1054.         hitInfo.locationRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  1055.         if (AttackDirector.hitLogger.IsLogEnabled)
  1056.         {
  1057.             AttackDirector.hitLogger.Log(string.Format("???????? DODGE ROLLS (GetSingleClusteredHit): Weapon Group: {0} // Weapon: {1}", groupIdx, weaponIdx));
  1058.         }
  1059.         hitInfo.dodgeRolls = this.GetRandomNumbers(groupIdx, weaponIdx, hitInfo.numberOfShots);
  1060.         hitInfo.hitVariance = this.GetVarianceSums(groupIdx, weaponIdx, hitInfo.numberOfShots, weapon);
  1061.         int num = 0;
  1062.         AbstractActor abstractActor = this.chosenTarget as AbstractActor;
  1063.         for (int j = 0; j < hitInfo.numberOfShots; j++)
  1064.         {
  1065.             bool flag = hitInfo.toHitRolls[j] <= toHitChance;
  1066.             bool flag2 = abstractActor != null && abstractActor.CheckDodge(this.attacker, weapon, hitInfo, j, this.IsBreachingShot);
  1067.             if (flag && flag2)
  1068.             {
  1069.                 hitInfo.dodgeSuccesses[j] = true;
  1070.                 this.FlagAttackContainsDodge(abstractActor.GUID);
  1071.             }
  1072.             else
  1073.             {
  1074.                 hitInfo.dodgeSuccesses[j] = false;
  1075.             }
  1076.             if (flag && !flag2)
  1077.             {
  1078.                 if (num == 0)
  1079.                 {
  1080.                     num = this.chosenTarget.GetHitLocation(this.attacker, this.attackPosition, hitInfo.locationRolls[j], this.calledShotLocation, this.attacker.CalledShotBonusMultiplier);
  1081.                     hitInfo.hitLocations[j] = num;
  1082.                     if (AttackDirector.attackLogger.IsLogEnabled)
  1083.                     {
  1084.                         AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Initial single clustered hit! Location: {3}", new object[]
  1085.                         {
  1086.                             this.id,
  1087.                             weaponIdx,
  1088.                             j,
  1089.                             hitInfo.hitLocations[j]
  1090.                         }));
  1091.                     }
  1092.                     if (AttackDirector.hitminLogger.IsLogEnabled)
  1093.                     {
  1094.                         AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Hits! ////// INITIAL HIT - HEX VAL {2}", weapon.Name, j, hitInfo.hitLocations[j]));
  1095.                     }
  1096.                 }
  1097.                 else
  1098.                 {
  1099.                     this.chosenTarget.GetAdjacentHitLocation(this.attackPosition, hitInfo.locationRolls[j], num, originalMultiplier, adjacentMultiplier);
  1100.                     if (AttackDirector.attackLogger.IsLogEnabled)
  1101.                     {
  1102.                         AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Single clustered hit! Location: {3}", new object[]
  1103.                         {
  1104.                             this.id,
  1105.                             weaponIdx,
  1106.                             j,
  1107.                             hitInfo.hitLocations[j]
  1108.                         }));
  1109.                     }
  1110.                     if (AttackDirector.hitminLogger.IsLogEnabled)
  1111.                     {
  1112.                         AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Hits! ////// CLUSTER HIT - HEX VAL {2}", weapon.Name, j, hitInfo.hitLocations[j]));
  1113.                     }
  1114.                 }
  1115.                 hitInfo.hitQualities[j] = this.Director.Combat.ToHit.GetBlowQuality(this.attacker, this.attackPosition, weapon, this.chosenTarget, this.meleeAttackType, this.IsBreachingShot);
  1116.                 this.FlagShotHit();
  1117.             }
  1118.             else
  1119.             {
  1120.                 hitInfo.hitLocations[j] = 0;
  1121.                 if (AttackDirector.attackLogger.IsLogEnabled)
  1122.                 {
  1123.                     AttackDirector.attackLogger.Log(string.Format("SEQ:{0}: WEAP:{1} SHOT:{2} Single clustered miss!", this.id, weaponIdx, j));
  1124.                 }
  1125.                 if (AttackDirector.hitminLogger.IsLogEnabled)
  1126.                 {
  1127.                     AttackDirector.hitminLogger.Log(string.Format("WEAPON: {0} - SHOT: {1} Misses!", weapon.Name, j));
  1128.                 }
  1129.                 this.FlagShotMissed();
  1130.             }
  1131.             hitInfo.hitPositions[j] = this.chosenTarget.GetImpactPosition(this.attacker, this.attackPosition, weapon, ref hitInfo.hitLocations[j], ref hitInfo.attackDirections[j], ref hitInfo.secondaryTargetIds[j], ref hitInfo.secondaryHitLocations[j]);
  1132.             this.RefreshHitQualitiesForSecondaryTargets(ref hitInfo, weapon, j);
  1133.         }
  1134.     }
  1135.  
  1136.     // Token: 0x0600605B RID: 24667 RVA: 0x001A3DB0 File Offset: 0x001A1FB0
  1137.     private void RefreshHitQualitiesForSecondaryTargets(ref WeaponHitInfo hitInfo, Weapon weapon, int hitIdx)
  1138.     {
  1139.         if (!string.IsNullOrEmpty(hitInfo.secondaryTargetIds[hitIdx]))
  1140.         {
  1141.             ICombatant combatant = this.Director.Combat.FindCombatantByGUID(hitInfo.secondaryTargetIds[hitIdx], false);
  1142.             hitInfo.hitQualities[hitIdx] = this.Director.Combat.ToHit.GetBlowQuality(this.attacker, this.attackPosition, weapon, combatant, this.meleeAttackType, this.IsBreachingShot);
  1143.         }
  1144.     }
  1145.  
  1146.     // Token: 0x0600605C RID: 24668 RVA: 0x001A3E20 File Offset: 0x001A2020
  1147.     private void SortSelectedWeapons()
  1148.     {
  1149.         this.sortedWeapons = new List<List<Weapon>>();
  1150.         for (int i = 0; i < this.allSelectedWeapons.Count; i++)
  1151.         {
  1152.             if (this.allSelectedWeapons[i].HasFired)
  1153.             {
  1154.                 AttackDirector.attackLogger.LogError(string.Format("Weapon {0} has already fired! This is Very Bad(tm)", this.allSelectedWeapons[i].Name));
  1155.             }
  1156.         }
  1157.         if (this.allSelectedWeapons.Count < 1)
  1158.         {
  1159.             return;
  1160.         }
  1161.         this.allSelectedWeapons.Sort((Weapon x, Weapon y) => x.uid.CompareTo(y.uid));
  1162.         for (int j = this.allSelectedWeapons.Count - 1; j >= 0; j--)
  1163.         {
  1164.             Weapon weapon = this.allSelectedWeapons[j];
  1165.             if (weapon.WeaponCategoryValue.IsMelee)
  1166.             {
  1167.                 List<Weapon> list = new List<Weapon>();
  1168.                 list.Add(weapon);
  1169.                 this.sortedWeapons.Add(list);
  1170.             }
  1171.         }
  1172.         this.allSelectedWeapons.Sort((Weapon x, Weapon y) => (y.DamagePerShotAdjusted(y.parent.occupiedDesignMask) * (1f + y.HeatDamagePerShot)).CompareTo(x.DamagePerShotAdjusted(x.parent.occupiedDesignMask) * (1f + x.HeatDamagePerShot)));
  1173.         List<Weapon> list2 = new List<Weapon>();
  1174.         for (int k = 0; k < this.allSelectedWeapons.Count; k++)
  1175.         {
  1176.             if (!this.allSelectedWeapons[k].WeaponCategoryValue.IsMelee)
  1177.             {
  1178.                 list2.Add(this.allSelectedWeapons[k]);
  1179.             }
  1180.         }
  1181.         if (list2.Count > 0)
  1182.         {
  1183.             this.sortedWeapons.Add(list2);
  1184.             if (AttackDirector.attackLogger.IsDebugEnabled)
  1185.             {
  1186.                 AttackDirector.attackLogger.LogDebug("sorted weapons");
  1187.                 for (int l = 0; l < list2.Count; l++)
  1188.                 {
  1189.                     AttackDirector.attackLogger.Log(string.Format("Weapon {0} index {1} sort value {2}", list2[l].Name, l, list2[l].DamagePerShotAdjusted(list2[l].parent.occupiedDesignMask)));
  1190.                 }
  1191.             }
  1192.         }
  1193.     }
  1194.  
  1195.     // Token: 0x0600605D RID: 24669 RVA: 0x001A4018 File Offset: 0x001A2218
  1196.     private bool CheckAllWeaponsComplete(int group)
  1197.     {
  1198.         List<Weapon> list = this.sortedWeapons[group];
  1199.         for (int i = 0; i < list.Count; i++)
  1200.         {
  1201.             if (!list[i].FiringComplete)
  1202.             {
  1203.                 return false;
  1204.             }
  1205.         }
  1206.         return true;
  1207.     }
  1208.  
  1209.     // Token: 0x0600605E RID: 24670 RVA: 0x001A4054 File Offset: 0x001A2254
  1210.     private bool CheckAllGroupsComplete()
  1211.     {
  1212.         for (int i = 0; i < this.sortedWeapons.Count; i++)
  1213.         {
  1214.             if (!this.CheckAllWeaponsComplete(i))
  1215.             {
  1216.                 return false;
  1217.             }
  1218.         }
  1219.         return true;
  1220.     }
  1221.  
  1222.     // Token: 0x0600605F RID: 24671 RVA: 0x001A4084 File Offset: 0x001A2284
  1223.     public void ResetWeapons()
  1224.     {
  1225.         for (int i = 0; i < this.allSelectedWeapons.Count; i++)
  1226.         {
  1227.             this.allSelectedWeapons[i].ResetWeapon();
  1228.         }
  1229.     }
  1230.  
  1231.     // Token: 0x06006060 RID: 24672 RVA: 0x001A40B8 File Offset: 0x001A22B8
  1232.     public void OnAttackSequenceGroupBegin(MessageCenterMessage message)
  1233.     {
  1234.         AttackSequenceGroupBeginMessage attackSequenceGroupBeginMessage = (AttackSequenceGroupBeginMessage)message;
  1235.         if (attackSequenceGroupBeginMessage.sequenceId != this.id)
  1236.         {
  1237.             return;
  1238.         }
  1239.         int groupIdx = attackSequenceGroupBeginMessage.groupIdx;
  1240.         this.currentFiringGroup = groupIdx;
  1241.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1242.         {
  1243.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceGroupBegin] ID {0}, Group {1}", this.id, groupIdx));
  1244.         }
  1245.         List<Weapon> list = this.sortedWeapons[this.currentFiringGroup];
  1246.         if (list.Count > 0)
  1247.         {
  1248.             AttackSequenceFireMessage attackSequenceFireMessage = new AttackSequenceFireMessage(this.stackItemUID, this.id, groupIdx, 0);
  1249.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceFireMessage);
  1250.         }
  1251.         WeaponHitInfo? weaponHitInfo = this.weaponHitInfo[groupIdx][0];
  1252.         if (weaponHitInfo != null)
  1253.         {
  1254.             WeaponHitInfo value = weaponHitInfo.Value;
  1255.             this.AddAllAffectedTargets(value);
  1256.             List<WeaponCategoryValue> list2 = new List<WeaponCategoryValue>();
  1257.             for (int i = 0; i < list.Count; i++)
  1258.             {
  1259.                 Weapon weapon = list[i];
  1260.                 if (!list2.Contains(weapon.WeaponCategoryValue))
  1261.                 {
  1262.                     list2.Add(weapon.WeaponCategoryValue);
  1263.                 }
  1264.                 foreach (EffectData effectData in weapon.weaponDef.statusEffects)
  1265.                 {
  1266.                     if (effectData.targetingData.effectTriggerType == EffectTriggerType.OnWeaponFire)
  1267.                     {
  1268.                         string text = string.Format("{0}Effect_{1}_{2}", effectData.targetingData.effectTriggerType.ToString(), weapon.parent.GUID, value.attackSequenceId);
  1269.                         foreach (ICombatant combatant in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData, weapon.parent, this.chosenTarget))
  1270.                         {
  1271.                             this.Director.Combat.EffectManager.CreateEffect(effectData, text, this.stackItemUID, weapon.parent, combatant, value, i, false);
  1272.                             if (!effectData.targetingData.hideApplicationFloatie)
  1273.                             {
  1274.                                 this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(weapon.parent.GUID, weapon.parent.GUID, effectData.Description.Name, FloatieMessage.MessageNature.Buff));
  1275.                             }
  1276.                             if (!effectData.targetingData.hideApplicationFloatie)
  1277.                             {
  1278.                                 this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(weapon.parent.GUID, combatant.GUID, effectData.Description.Name, FloatieMessage.MessageNature.Buff));
  1279.                             }
  1280.                         }
  1281.                     }
  1282.                 }
  1283.             }
  1284.             List<EffectData> componentStatusEffectsForTriggerType = this.attacker.GetComponentStatusEffectsForTriggerType(EffectTriggerType.OnWeaponFire, ComponentType.Upgrade);
  1285.             for (int k = 0; k < componentStatusEffectsForTriggerType.Count; k++)
  1286.             {
  1287.                 EffectData effectData2 = componentStatusEffectsForTriggerType[k];
  1288.                 if (effectData2.effectType != EffectType.StatisticEffect || effectData2.statisticData.targetCollection != StatisticEffectData.TargetCollection.Weapon || list2.Contains(effectData2.statisticData.TargetWeaponCategoryValue))
  1289.                 {
  1290.                     string text2 = string.Format("{0}Effect_{1}_{2}", effectData2.targetingData.effectTriggerType.ToString(), this.attacker.GUID, value.attackSequenceId);
  1291.                     foreach (ICombatant combatant2 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData2, this.attacker, this.chosenTarget))
  1292.                     {
  1293.                         this.Director.Combat.EffectManager.CreateEffect(effectData2, text2, this.stackItemUID, this.attacker, combatant2, value, 0, false);
  1294.                         if (!effectData2.targetingData.hideApplicationFloatie)
  1295.                         {
  1296.                             this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(this.attacker.GUID, combatant2.GUID, effectData2.Description.Name, FloatieMessage.MessageNature.Debuff));
  1297.                         }
  1298.                     }
  1299.                 }
  1300.             }
  1301.             List<EffectData> abilityStatusEffectsForTriggerType = this.attacker.GetPilot().GetAbilityStatusEffectsForTriggerType(EffectTriggerType.OnWeaponFire);
  1302.             for (int l = 0; l < abilityStatusEffectsForTriggerType.Count; l++)
  1303.             {
  1304.                 EffectData effectData3 = abilityStatusEffectsForTriggerType[l];
  1305.                 if (effectData3.effectType != EffectType.StatisticEffect || effectData3.statisticData.targetCollection != StatisticEffectData.TargetCollection.Weapon || list2.Contains(effectData3.statisticData.TargetWeaponCategoryValue))
  1306.                 {
  1307.                     string text3 = string.Format("{0}Effect_{1}_{2}", effectData3.targetingData.effectTriggerType.ToString(), this.attacker.GUID, value.attackSequenceId);
  1308.                     foreach (ICombatant combatant3 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData3, this.attacker, this.chosenTarget))
  1309.                     {
  1310.                         this.Director.Combat.EffectManager.CreateEffect(effectData3, text3, this.stackItemUID, this.attacker, combatant3, value, 0, false);
  1311.                         if (!effectData3.targetingData.hideApplicationFloatie)
  1312.                         {
  1313.                             this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(this.attacker.GUID, combatant3.GUID, effectData3.Description.Name, FloatieMessage.MessageNature.Debuff));
  1314.                         }
  1315.                     }
  1316.                 }
  1317.             }
  1318.             return;
  1319.         }
  1320.         AttackDirector.AttackSequence.logger.LogError("[OnAttackSequenceFire] had to generate hit info because pre-calculated hit info was not available!");
  1321.     }
  1322.  
  1323.     // Token: 0x06006061 RID: 24673 RVA: 0x001A4670 File Offset: 0x001A2870
  1324.     public void OnAttackSequenceWeaponPreFireComplete(MessageCenterMessage message)
  1325.     {
  1326.         AttackSequenceWeaponPreFireCompleteMessage attackSequenceWeaponPreFireCompleteMessage = (AttackSequenceWeaponPreFireCompleteMessage)message;
  1327.         if (attackSequenceWeaponPreFireCompleteMessage.sequenceId != this.id)
  1328.         {
  1329.             return;
  1330.         }
  1331.         int groupIdx = attackSequenceWeaponPreFireCompleteMessage.groupIdx;
  1332.         int num = attackSequenceWeaponPreFireCompleteMessage.weaponIdx;
  1333.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1334.         {
  1335.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceWeaponPreFireComplete] ID {0}, Group {1}, Weapon {2}", this.id, groupIdx, num));
  1336.         }
  1337.         List<Weapon> list = this.sortedWeapons[groupIdx];
  1338.         num++;
  1339.         if (num < list.Count)
  1340.         {
  1341.             AttackSequenceFireMessage attackSequenceFireMessage = new AttackSequenceFireMessage(this.stackItemUID, this.id, groupIdx, num);
  1342.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceFireMessage);
  1343.         }
  1344.     }
  1345.  
  1346.     // Token: 0x06006062 RID: 24674 RVA: 0x0000D184 File Offset: 0x0000B384
  1347.     private void PlayAttackVO()
  1348.     {
  1349.     }
  1350.  
  1351.     // Token: 0x06006063 RID: 24675 RVA: 0x001A4720 File Offset: 0x001A2920
  1352.     public void OnAttackSequenceFire(MessageCenterMessage message)
  1353.     {
  1354.         AttackSequenceFireMessage attackSequenceFireMessage = (AttackSequenceFireMessage)message;
  1355.         if (attackSequenceFireMessage.sequenceId != this.id)
  1356.         {
  1357.             return;
  1358.         }
  1359.         int groupIdx = attackSequenceFireMessage.groupIdx;
  1360.         int weaponIdx = attackSequenceFireMessage.weaponIdx;
  1361.         Weapon weapon = this.sortedWeapons[groupIdx][weaponIdx];
  1362.         if (AttackDirector.attackLogger.IsDebugEnabled)
  1363.         {
  1364.             AttackDirector.attackLogger.LogDebug("MeleeType = " + this.meleeAttackType.ToString());
  1365.         }
  1366.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1367.         {
  1368.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceFire] ID {0}, Group {1}, Weapon {2}, Weapon Name {3}", new object[] { this.id, groupIdx, weaponIdx, weapon.Name }));
  1369.         }
  1370.         if (AttackDirector.hitminLogger.IsLogEnabled)
  1371.         {
  1372.             AttackDirector.hitminLogger.Log(string.Format("============================================================= STARTING NEW ATTACK SEQUENCE FOR {0} (ID {1}):", weapon.Name, weaponIdx));
  1373.         }
  1374.         int num = this.numberOfShots[groupIdx][weaponIdx];
  1375.         if (num == -1)
  1376.         {
  1377.             if (weapon.HasPreFired)
  1378.             {
  1379.                 AttackDirector.AttackSequence.logger.LogError(string.Format("[OnAttackSequenceFire] Weapon {0} should not have prefired if it wasn't going to fire!", weapon.Name));
  1380.             }
  1381.             AttackDirector.AttackSequence.logger.LogWarning(string.Format("Weapon {0} can't fire, skipping", weapon.Description.Name));
  1382.             AttackSequenceWeaponPreFireCompleteMessage attackSequenceWeaponPreFireCompleteMessage = new AttackSequenceWeaponPreFireCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1383.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponPreFireCompleteMessage);
  1384.             AttackSequenceWeaponCompleteMessage attackSequenceWeaponCompleteMessage = new AttackSequenceWeaponCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1385.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponCompleteMessage);
  1386.             return;
  1387.         }
  1388.         weapon.FireWeapon();
  1389.         if (num == 0)
  1390.         {
  1391.             AttackDirector.AttackSequence.logger.LogError(string.Format("[OnAttackSequenceFire] Weapon {0} tried to fire 0 shots (this should not happen!), skipping", weapon.Description.Name));
  1392.             AttackSequenceWeaponPreFireCompleteMessage attackSequenceWeaponPreFireCompleteMessage2 = new AttackSequenceWeaponPreFireCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1393.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponPreFireCompleteMessage2);
  1394.             AttackSequenceWeaponCompleteMessage attackSequenceWeaponCompleteMessage2 = new AttackSequenceWeaponCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1395.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponCompleteMessage2);
  1396.             return;
  1397.         }
  1398.         WeaponHitInfo? weaponHitInfo = this.weaponHitInfo[groupIdx][weaponIdx];
  1399.         WeaponHitInfo weaponHitInfo2;
  1400.         if (weaponHitInfo != null)
  1401.         {
  1402.             weaponHitInfo2 = weaponHitInfo.Value;
  1403.             this.AddAllAffectedTargets(weaponHitInfo2);
  1404.         }
  1405.         else
  1406.         {
  1407.             AttackDirector.AttackSequence.logger.LogError("[OnAttackSequenceFire] had to generate hit info because pre-calculated hit info was not available!");
  1408.             weaponHitInfo2 = this.GenerateHitInfo(weapon, groupIdx, weaponIdx, num, this.indirectFire, 0f);
  1409.             this.AddAllAffectedTargets(weaponHitInfo2);
  1410.         }
  1411.         weapon.CompleteFiring();
  1412.         foreach (EffectData effectData in weapon.weaponDef.statusEffects)
  1413.         {
  1414.             if (effectData.targetingData.effectTriggerType == EffectTriggerType.OnActivation)
  1415.             {
  1416.                 string text = string.Format("{0}Effect_{1}_{2}", effectData.targetingData.effectTriggerType.ToString(), weapon.parent.GUID, weaponHitInfo2.attackSequenceId);
  1417.                 foreach (ICombatant combatant in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData, weapon.parent, this.chosenTarget))
  1418.                 {
  1419.                     this.Director.Combat.EffectManager.CreateEffect(effectData, text, this.stackItemUID, weapon.parent, combatant, weaponHitInfo2, weaponIdx, false);
  1420.                     if (!effectData.targetingData.hideApplicationFloatie)
  1421.                     {
  1422.                         this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(weapon.parent.GUID, weapon.parent.GUID, effectData.Description.Name, FloatieMessage.MessageNature.Buff));
  1423.                     }
  1424.                     if (!effectData.targetingData.hideApplicationFloatie)
  1425.                     {
  1426.                         this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(weapon.parent.GUID, combatant.GUID, effectData.Description.Name, FloatieMessage.MessageNature.Buff));
  1427.                     }
  1428.                 }
  1429.             }
  1430.         }
  1431.         bool flag = weapon.weaponRep != null && weapon.weaponRep.HasWeaponEffect;
  1432.         if (DebugBridge.TestToolsEnabled)
  1433.         {
  1434.             flag = flag && !DebugBridge.DisableWeaponEffectDrivenAttacks;
  1435.         }
  1436.         if (flag)
  1437.         {
  1438.             weapon.weaponRep.PlayWeaponEffect(weaponHitInfo2);
  1439.             return;
  1440.         }
  1441.         if (DebugBridge.TestToolsEnabled || !DebugBridge.DisableWeaponEffectDrivenAttacks)
  1442.         {
  1443.             AttackDirector.attackLogger.LogError("NO WEAPONEFFECT for " + weapon.Description.Name + ", skipping straight to resolving damage.");
  1444.         }
  1445.         AttackSequenceWeaponPreFireCompleteMessage attackSequenceWeaponPreFireCompleteMessage3 = new AttackSequenceWeaponPreFireCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1446.         this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponPreFireCompleteMessage3);
  1447.         for (int j = 0; j < num; j++)
  1448.         {
  1449.             float num2 = weapon.DamagePerShotAdjusted(weapon.parent.occupiedDesignMask);
  1450.             float num3 = weapon.StructureDamagePerShotAdjusted(weapon.parent.occupiedDesignMask);
  1451.             AttackSequenceImpactMessage attackSequenceImpactMessage = new AttackSequenceImpactMessage(weaponHitInfo2, j, num2, num3);
  1452.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceImpactMessage);
  1453.         }
  1454.         AttackSequenceResolveDamageMessage attackSequenceResolveDamageMessage = new AttackSequenceResolveDamageMessage(weaponHitInfo2);
  1455.         this.Director.Combat.MessageCenter.PublishMessage(attackSequenceResolveDamageMessage);
  1456.         AttackSequenceWeaponCompleteMessage attackSequenceWeaponCompleteMessage3 = new AttackSequenceWeaponCompleteMessage(this.stackItemUID, this.id, groupIdx, weaponIdx);
  1457.         this.Director.Combat.MessageCenter.PublishMessage(attackSequenceWeaponCompleteMessage3);
  1458.     }
  1459.  
  1460.     // Token: 0x06006064 RID: 24676 RVA: 0x001A4C8C File Offset: 0x001A2E8C
  1461.     public void OnAttackSequenceImpact(MessageCenterMessage message)
  1462.     {
  1463.         AttackSequenceImpactMessage attackSequenceImpactMessage = (AttackSequenceImpactMessage)message;
  1464.         if (attackSequenceImpactMessage.hitInfo.attackSequenceId != this.id)
  1465.         {
  1466.             return;
  1467.         }
  1468.         int attackGroupIndex = attackSequenceImpactMessage.hitInfo.attackGroupIndex;
  1469.         int attackWeaponIndex = attackSequenceImpactMessage.hitInfo.attackWeaponIndex;
  1470.         int hitIndex = attackSequenceImpactMessage.hitIndex;
  1471.         Weapon weapon = this.GetWeapon(attackGroupIndex, attackWeaponIndex);
  1472.         int num = attackSequenceImpactMessage.hitInfo.ShotHitLocation(hitIndex);
  1473.         Vector3 vector = attackSequenceImpactMessage.hitInfo.hitPositions[hitIndex];
  1474.         float hitDamage = attackSequenceImpactMessage.hitDamage;
  1475.         float structureDamage = attackSequenceImpactMessage.structureDamage;
  1476.         float blowQualityMultiplier = this.Director.Combat.ToHit.GetBlowQualityMultiplier(attackSequenceImpactMessage.hitInfo.hitQualities[hitIndex]);
  1477.         float num2 = hitDamage * blowQualityMultiplier;
  1478.         float num3 = structureDamage * blowQualityMultiplier;
  1479.         bool flag = !string.IsNullOrEmpty(attackSequenceImpactMessage.hitInfo.secondaryTargetIds[hitIndex]);
  1480.         ICombatant combatant = null;
  1481.         if (flag)
  1482.         {
  1483.             combatant = this.Director.Combat.FindCombatantByGUID(attackSequenceImpactMessage.hitInfo.secondaryTargetIds[hitIndex], false);
  1484.         }
  1485.         AbstractActor abstractActor = this.chosenTarget as AbstractActor;
  1486.         if (abstractActor != null)
  1487.         {
  1488.             LineOfFireLevel lineOfFireLevel = this.attacker.VisibilityCache.VisibilityToTarget(abstractActor).LineOfFireLevel;
  1489.             num2 = abstractActor.GetAdjustedDamage(num2, weapon.WeaponCategoryValue, abstractActor.occupiedDesignMask, lineOfFireLevel, true);
  1490.             num2 = abstractActor.GetAdjustedDamageForMelee(num2, weapon.WeaponCategoryValue);
  1491.             num3 = abstractActor.GetAdjustedDamage(num3, weapon.WeaponCategoryValue, abstractActor.occupiedDesignMask, lineOfFireLevel, true);
  1492.             num3 = abstractActor.GetAdjustedDamageForMelee(num3, weapon.WeaponCategoryValue);
  1493.         }
  1494.         if (num2 <= 0f)
  1495.         {
  1496.             AttackDirector.attackLogger.LogWarning(string.Format("OnAttackSequenceImpact is dealing <= 0 damage: base dmg: {0}, total: {1}", hitDamage, num2));
  1497.             num2 = 0f;
  1498.         }
  1499.         if (num3 <= 0f)
  1500.         {
  1501.             num3 = 0f;
  1502.         }
  1503.         bool flag2 = this.messageCoordinator.CanProcessMessage(attackSequenceImpactMessage);
  1504.         bool flag3 = attackSequenceImpactMessage.hitInfo.DidShotHitChosenTarget(hitIndex);
  1505.         if (!attackSequenceImpactMessage.hasPlayedImpact)
  1506.         {
  1507.             if (AttackDirector.AttackSequence.logger.IsDebugEnabled)
  1508.             {
  1509.                 AttackDirector.AttackSequence.logger.LogDebug(string.Format("[OnAttackSequenceImpact] playing impact \"visuals\" for ID {0}, Group {1}, Weapon {2}, Hit {3}. Will process during this call? {4}", new object[] { this.id, attackGroupIndex, attackWeaponIndex, hitIndex, flag2 }));
  1510.             }
  1511.             attackSequenceImpactMessage.hasPlayedImpact = true;
  1512.             if (this.chosenTarget.GameRep != null)
  1513.             {
  1514.                 if (flag3)
  1515.                 {
  1516.                     this.chosenTarget.GameRep.PlayImpactAnim(attackSequenceImpactMessage.hitInfo, hitIndex, weapon, this.meleeAttackType, this.cumulativeDamage);
  1517.                     Vector3 vector2 = vector;
  1518.                     if (this.chosenTarget.ArmorForLocation(num) < num2)
  1519.                     {
  1520.                         FloatieMessage floatieMessage = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, this.chosenTarget.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num2) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.StructureDamage, vector2.x, vector2.y, vector2.z);
  1521.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage);
  1522.                     }
  1523.                     else
  1524.                     {
  1525.                         FloatieMessage floatieMessage2 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, this.chosenTarget.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num2) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.ArmorDamage, vector2.x, vector2.y, vector2.z);
  1526.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage2);
  1527.                     }
  1528.                     if (num3 > 0f)
  1529.                     {
  1530.                         FloatieMessage floatieMessage3 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, this.chosenTarget.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num3) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.StructureDamage, vector2.x, vector2.y, vector2.z);
  1531.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage3);
  1532.                     }
  1533.                 }
  1534.                 else
  1535.                 {
  1536.                     Vector3 vector3 = this.chosenTarget.TargetPosition + Random.insideUnitSphere * 5f;
  1537.                     if (attackSequenceImpactMessage.hitInfo.dodgeSuccesses[hitIndex])
  1538.                     {
  1539.                         this.chosenTarget.GameRep.PlayImpactAnim(attackSequenceImpactMessage.hitInfo, hitIndex, weapon, this.meleeAttackType, this.cumulativeDamage);
  1540.                         FloatieMessage floatieMessage4 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, this.chosenTarget.GUID, new Text("EVADE", Array.Empty<object>()), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.Dodge, vector3.x, vector3.y, vector3.z);
  1541.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage4);
  1542.                     }
  1543.                     else if (this.meleeAttackType != MeleeAttackType.NotSet)
  1544.                     {
  1545.                         this.chosenTarget.GameRep.PlayImpactAnim(attackSequenceImpactMessage.hitInfo, hitIndex, weapon, this.meleeAttackType, this.cumulativeDamage);
  1546.                         FloatieMessage floatieMessage5 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, attackSequenceImpactMessage.hitInfo.targetId, new Text("MISS!", Array.Empty<object>()), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.MeleeMiss, vector3.x, vector3.y, vector3.z);
  1547.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage5);
  1548.                     }
  1549.                     else
  1550.                     {
  1551.                         FloatieMessage.MessageNature messageNature = ((weapon.ShotsWhenFired > 1) ? FloatieMessage.MessageNature.Miss : FloatieMessage.MessageNature.MeleeMiss);
  1552.                         FloatieMessage floatieMessage6 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, attackSequenceImpactMessage.hitInfo.targetId, new Text("MISS!", Array.Empty<object>()), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, messageNature, vector3.x, vector3.y, vector3.z);
  1553.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage6);
  1554.                     }
  1555.                     if (flag)
  1556.                     {
  1557.                         FloatieMessage floatieMessage7 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, attackSequenceImpactMessage.hitInfo.targetId, new Text("STRAY SHOT", Array.Empty<object>()), this.Director.Combat.Constants.CombatUIConstants.floatieSizeLarge, FloatieMessage.MessageNature.MeleeMiss, vector.x, vector.y, vector.z);
  1558.                         this.Director.Combat.MessageCenter.PublishMessage(floatieMessage7);
  1559.                         if (combatant != null && combatant.GameRep != null)
  1560.                         {
  1561.                             combatant.GameRep.PlayImpactAnim(attackSequenceImpactMessage.hitInfo, hitIndex, weapon, this.meleeAttackType, this.cumulativeDamage);
  1562.                         }
  1563.                     }
  1564.                 }
  1565.             }
  1566.             if (weapon.Type != WeaponType.Laser && weapon.Type != WeaponType.Flamer)
  1567.             {
  1568.                 CameraControl.Instance.AddCameraShake((num2 + num3) * this.Director.Combat.Constants.CombatUIConstants.ScreenShakeRangedDamageRelativeMod + this.Director.Combat.Constants.CombatUIConstants.ScreenShakeRangedDamageAbsoluteMod, 1f, vector);
  1569.             }
  1570.         }
  1571.         if (!flag2)
  1572.         {
  1573.             this.messageCoordinator.StoreMessage(attackSequenceImpactMessage);
  1574.             return;
  1575.         }
  1576.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1577.         {
  1578.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceImpact]  ID {0}, Group {1}, Weapon {2}, Hit {3}.", new object[] { this.id, attackGroupIndex, attackWeaponIndex, hitIndex }));
  1579.             if (AttackDirector.AttackSequence.logger.IsDebugEnabled)
  1580.             {
  1581.                 AttackDirector.AttackSequence.logger.LogDebug(string.Format("\t WeaponName {0}, MeleeType {1}, HitLocation {2}", weapon.Name, this.meleeAttackType.ToString(), num.ToString()));
  1582.             }
  1583.         }
  1584.         if (flag3)
  1585.         {
  1586.             this.cumulativeDamage += num2;
  1587.             this.cumulativeDamage += num3;
  1588.             this.chosenTarget.TakeWeaponDamage(attackSequenceImpactMessage.hitInfo, num, weapon, num2, num3, hitIndex, DamageType.Weapon);
  1589.             this.chosenTarget.HandleDeath(this.attacker.GUID);
  1590.         }
  1591.         else if (flag && combatant != null)
  1592.         {
  1593.             num2 = hitDamage * blowQualityMultiplier;
  1594.             num3 = structureDamage * blowQualityMultiplier;
  1595.             AbstractActor abstractActor2 = combatant as AbstractActor;
  1596.             if (abstractActor2 != null)
  1597.             {
  1598.                 LineOfFireLevel lineOfFireLevel2 = this.attacker.VisibilityCache.VisibilityToTarget(abstractActor2).LineOfFireLevel;
  1599.                 num2 = abstractActor2.GetAdjustedDamage(num2, weapon.WeaponCategoryValue, abstractActor2.occupiedDesignMask, lineOfFireLevel2, true);
  1600.                 num2 = abstractActor2.GetAdjustedDamageForMelee(num2, weapon.WeaponCategoryValue);
  1601.                 num3 = abstractActor2.GetAdjustedDamage(num3, weapon.WeaponCategoryValue, abstractActor2.occupiedDesignMask, lineOfFireLevel2, true);
  1602.                 num3 = abstractActor2.GetAdjustedDamageForMelee(num3, weapon.WeaponCategoryValue);
  1603.             }
  1604.             if (combatant.ArmorForLocation(num) < num2)
  1605.             {
  1606.                 FloatieMessage floatieMessage8 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, combatant.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num2) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.StructureDamage, vector.x, vector.y, vector.z);
  1607.                 this.Director.Combat.MessageCenter.PublishMessage(floatieMessage8);
  1608.             }
  1609.             else
  1610.             {
  1611.                 FloatieMessage floatieMessage9 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, combatant.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num2) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.ArmorDamage, vector.x, vector.y, vector.z);
  1612.                 this.Director.Combat.MessageCenter.PublishMessage(floatieMessage9);
  1613.             }
  1614.             if (num3 > 0f)
  1615.             {
  1616.                 FloatieMessage floatieMessage10 = new FloatieMessage(attackSequenceImpactMessage.hitInfo.attackerId, combatant.GUID, new Text("{0}", new object[] { (int)Mathf.Max(1f, num3) }), this.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.StructureDamage, vector.x, vector.y, vector.z);
  1617.                 this.Director.Combat.MessageCenter.PublishMessage(floatieMessage10);
  1618.             }
  1619.             combatant.TakeWeaponDamage(attackSequenceImpactMessage.hitInfo, attackSequenceImpactMessage.hitInfo.ShotHitLocation(hitIndex), weapon, num2, num3, hitIndex, DamageType.Weapon);
  1620.             combatant.HandleDeath(this.attacker.GUID);
  1621.         }
  1622.         this.messageCoordinator.MessageComplete(attackSequenceImpactMessage);
  1623.     }
  1624.  
  1625.     // Token: 0x06006065 RID: 24677 RVA: 0x001A577C File Offset: 0x001A397C
  1626.     public void OnAttackSequenceResolveDamage(MessageCenterMessage message)
  1627.     {
  1628.         AttackSequenceResolveDamageMessage attackSequenceResolveDamageMessage = (AttackSequenceResolveDamageMessage)message;
  1629.         WeaponHitInfo hitInfo = attackSequenceResolveDamageMessage.hitInfo;
  1630.         if (hitInfo.attackSequenceId != this.id)
  1631.         {
  1632.             return;
  1633.         }
  1634.         if (!this.messageCoordinator.CanProcessMessage(attackSequenceResolveDamageMessage))
  1635.         {
  1636.             this.messageCoordinator.StoreMessage(attackSequenceResolveDamageMessage);
  1637.             return;
  1638.         }
  1639.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1640.         {
  1641.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceResolveDamage]  ID {0}, Group {1}, Weapon {2}, AttackerId [{3}], TargetId [{4}]", new object[] { this.id, hitInfo.attackGroupIndex, hitInfo.attackWeaponIndex, hitInfo.attackerId, hitInfo.targetId }));
  1642.         }
  1643.         int attackGroupIndex = attackSequenceResolveDamageMessage.hitInfo.attackGroupIndex;
  1644.         int attackWeaponIndex = attackSequenceResolveDamageMessage.hitInfo.attackWeaponIndex;
  1645.         Weapon weapon = this.GetWeapon(attackGroupIndex, attackWeaponIndex);
  1646.         if (this.meleeAttackType == MeleeAttackType.DFA)
  1647.         {
  1648.             float num = Mathf.Max(0f, this.attacker.StatCollection.GetValue<float>("DFASelfDamage"));
  1649.             this.attacker.TakeWeaponDamage(attackSequenceResolveDamageMessage.hitInfo, 64, weapon, num, 0f, 0, DamageType.DFASelf);
  1650.             this.attacker.TakeWeaponDamage(attackSequenceResolveDamageMessage.hitInfo, 128, weapon, num, 0f, 0, DamageType.DFASelf);
  1651.             if (AttackDirector.damageLogger.IsLogEnabled)
  1652.             {
  1653.                 AttackDirector.damageLogger.Log(string.Format("@@@@@@@@ {0} takes {1} damage to its legs from the DFA attack!", this.attacker.DisplayName, num));
  1654.             }
  1655.         }
  1656.         List<ICombatant> list = new List<ICombatant>();
  1657.         this.chosenTarget.ResolveWeaponDamage(attackSequenceResolveDamageMessage.hitInfo);
  1658.         list.Add(this.chosenTarget);
  1659.         if (hitInfo.GetFirstHitLocationForTarget(this.chosenTarget.GUID) >= 0)
  1660.         {
  1661.             this.attackCompletelyMissed = false;
  1662.         }
  1663.         for (int i = 0; i < attackSequenceResolveDamageMessage.hitInfo.secondaryTargetIds.Length; i++)
  1664.         {
  1665.             ICombatant combatant = this.Director.Combat.FindCombatantByGUID(attackSequenceResolveDamageMessage.hitInfo.secondaryTargetIds[i], false);
  1666.             if (combatant != null && !list.Contains(combatant))
  1667.             {
  1668.                 list.Add(combatant);
  1669.                 combatant.ResolveWeaponDamage(attackSequenceResolveDamageMessage.hitInfo);
  1670.             }
  1671.         }
  1672.         AttackDirector.AttackSequence attackSequence = this.Director.GetAttackSequence(hitInfo.attackSequenceId);
  1673.         for (int j = 0; j < attackSequence.allAffectedTargetIds.Count; j++)
  1674.         {
  1675.             AbstractActor abstractActor = this.Director.Combat.FindActorByGUID(attackSequence.allAffectedTargetIds[j]);
  1676.             if (abstractActor != null)
  1677.             {
  1678.                 int firstHitLocationForTarget = hitInfo.GetFirstHitLocationForTarget(abstractActor.GUID);
  1679.                 if (firstHitLocationForTarget >= 0 && !abstractActor.IsDead)
  1680.                 {
  1681.                     foreach (EffectData effectData in weapon.weaponDef.statusEffects)
  1682.                     {
  1683.                         if (effectData.targetingData.effectTriggerType == EffectTriggerType.OnHit)
  1684.                         {
  1685.                             string text = string.Format("{0}Effect_{1}_{2}", effectData.targetingData.effectTriggerType.ToString(), this.attacker.GUID, attackSequenceResolveDamageMessage.hitInfo.attackSequenceId);
  1686.                             foreach (ICombatant combatant2 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData, this.attacker, abstractActor))
  1687.                             {
  1688.                                 this.Director.Combat.EffectManager.CreateEffect(effectData, text, this.stackItemUID, this.attacker, combatant2, hitInfo, firstHitLocationForTarget, false);
  1689.                                 if (effectData.durationData.activeTrackedEffect)
  1690.                                 {
  1691.                                     weapon.AddCreatedEffectID(text);
  1692.                                 }
  1693.                                 if (!effectData.targetingData.hideApplicationFloatie)
  1694.                                 {
  1695.                                     this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(this.attacker.GUID, combatant2.GUID, effectData.Description.Name, FloatieMessage.MessageNature.Debuff));
  1696.                                 }
  1697.                             }
  1698.                         }
  1699.                     }
  1700.                     List<EffectData> componentStatusEffectsForTriggerType = this.attacker.GetComponentStatusEffectsForTriggerType(EffectTriggerType.OnHit, ComponentType.Upgrade);
  1701.                     for (int l = 0; l < componentStatusEffectsForTriggerType.Count; l++)
  1702.                     {
  1703.                         EffectData effectData2 = componentStatusEffectsForTriggerType[l];
  1704.                         if (effectData2.effectType != EffectType.StatisticEffect || effectData2.statisticData.targetCollection != StatisticEffectData.TargetCollection.Weapon || effectData2.statisticData.TargetWeaponCategoryValue.Equals(weapon.WeaponCategoryValue))
  1705.                         {
  1706.                             string text2 = string.Format("{0}Effect_{1}_{2}", effectData2.targetingData.effectTriggerType.ToString(), this.attacker.GUID, attackSequenceResolveDamageMessage.hitInfo.attackSequenceId);
  1707.                             foreach (ICombatant combatant3 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData2, this.attacker, abstractActor))
  1708.                             {
  1709.                                 this.Director.Combat.EffectManager.CreateEffect(effectData2, text2, this.stackItemUID, this.attacker, combatant3, hitInfo, firstHitLocationForTarget, false);
  1710.                                 if (!effectData2.targetingData.hideApplicationFloatie)
  1711.                                 {
  1712.                                     this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(this.attacker.GUID, combatant3.GUID, effectData2.Description.Name, FloatieMessage.MessageNature.Debuff));
  1713.                                 }
  1714.                             }
  1715.                         }
  1716.                     }
  1717.                     List<EffectData> abilityStatusEffectsForTriggerType = this.attacker.GetPilot().GetAbilityStatusEffectsForTriggerType(EffectTriggerType.OnHit);
  1718.                     for (int m = 0; m < abilityStatusEffectsForTriggerType.Count; m++)
  1719.                     {
  1720.                         EffectData effectData3 = abilityStatusEffectsForTriggerType[m];
  1721.                         if (effectData3.effectType != EffectType.StatisticEffect || effectData3.statisticData.targetCollection != StatisticEffectData.TargetCollection.Weapon || effectData3.statisticData.TargetWeaponCategoryValue.Equals(weapon.WeaponCategoryValue))
  1722.                         {
  1723.                             string text3 = string.Format("{0}Effect_{1}_{2}", effectData3.targetingData.effectTriggerType.ToString(), this.attacker.GUID, attackSequenceResolveDamageMessage.hitInfo.attackSequenceId);
  1724.                             foreach (ICombatant combatant4 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData3, this.attacker, abstractActor))
  1725.                             {
  1726.                                 this.Director.Combat.EffectManager.CreateEffect(effectData3, text3, this.stackItemUID, this.attacker, combatant4, hitInfo, firstHitLocationForTarget, false);
  1727.                                 if (!effectData3.targetingData.hideApplicationFloatie)
  1728.                                 {
  1729.                                     this.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(this.attacker.GUID, combatant4.GUID, effectData3.Description.Name, FloatieMessage.MessageNature.Debuff));
  1730.                                 }
  1731.                             }
  1732.                         }
  1733.                     }
  1734.                     List<EffectData> componentStatusEffectsForTriggerType2 = abstractActor.GetComponentStatusEffectsForTriggerType(EffectTriggerType.OnDamaged, ComponentType.NotSet);
  1735.                     for (int n = 0; n < componentStatusEffectsForTriggerType2.Count; n++)
  1736.                     {
  1737.                         EffectData effectData4 = componentStatusEffectsForTriggerType2[n];
  1738.                         foreach (ICombatant combatant5 in this.Director.Combat.EffectManager.GetTargetCombatantForEffect(effectData4, abstractActor, this.attacker))
  1739.                         {
  1740.                             string text4 = string.Format("OnDamagedEffect_{0}_{1}", abstractActor.GUID, attackSequenceResolveDamageMessage.hitInfo.attackSequenceId);
  1741.                             this.Director.Combat.EffectManager.CreateEffect(effectData4, text4, this.stackItemUID, abstractActor, combatant5, hitInfo, firstHitLocationForTarget, false);
  1742.                         }
  1743.                     }
  1744.                 }
  1745.             }
  1746.         }
  1747.         this.attacker.HandleDeath(this.attacker.GUID);
  1748.         this.messageCoordinator.MessageComplete(attackSequenceResolveDamageMessage);
  1749.     }
  1750.  
  1751.     // Token: 0x06006066 RID: 24678 RVA: 0x001A5F54 File Offset: 0x001A4154
  1752.     public void OnAttackSequenceWeaponComplete(MessageCenterMessage message)
  1753.     {
  1754.         AttackSequenceWeaponCompleteMessage attackSequenceWeaponCompleteMessage = (AttackSequenceWeaponCompleteMessage)message;
  1755.         if (attackSequenceWeaponCompleteMessage.sequenceId != this.id)
  1756.         {
  1757.             return;
  1758.         }
  1759.         int groupIdx = attackSequenceWeaponCompleteMessage.groupIdx;
  1760.         int weaponIdx = attackSequenceWeaponCompleteMessage.weaponIdx;
  1761.         this.sortedWeapons[groupIdx][weaponIdx].FlagAsComplete();
  1762.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1763.         {
  1764.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceWeaponComplete]  ID {0}, Group {1}, Weapon {2}.", this.id, groupIdx, weaponIdx));
  1765.         }
  1766.         if (this.CheckAllWeaponsComplete(this.currentFiringGroup))
  1767.         {
  1768.             AttackSequenceGroupEndMessage attackSequenceGroupEndMessage = new AttackSequenceGroupEndMessage(this.stackItemUID, this.id, groupIdx);
  1769.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceGroupEndMessage);
  1770.         }
  1771.     }
  1772.  
  1773.     // Token: 0x06006067 RID: 24679 RVA: 0x001A600C File Offset: 0x001A420C
  1774.     public void OnAttackSequenceGroupEnd(MessageCenterMessage message)
  1775.     {
  1776.         AttackSequenceGroupEndMessage attackSequenceGroupEndMessage = (AttackSequenceGroupEndMessage)message;
  1777.         if (attackSequenceGroupEndMessage.sequenceId != this.id)
  1778.         {
  1779.             return;
  1780.         }
  1781.         if (AttackDirector.AttackSequence.logger.IsLogEnabled)
  1782.         {
  1783.             int groupIdx = attackSequenceGroupEndMessage.groupIdx;
  1784.             AttackDirector.AttackSequence.logger.Log(string.Format("[OnAttackSequenceGroupEnd]  ID {0}, Group {1}.", this.id, groupIdx));
  1785.         }
  1786.         this.currentFiringGroup++;
  1787.         if (this.currentFiringGroup < this.weaponGroupCount)
  1788.         {
  1789.             AttackSequenceGroupBeginMessage attackSequenceGroupBeginMessage = new AttackSequenceGroupBeginMessage(this.stackItemUID, this.id, this.currentFiringGroup);
  1790.             this.Director.Combat.MessageCenter.PublishMessage(attackSequenceGroupBeginMessage);
  1791.             return;
  1792.         }
  1793.         this.CoordinatedMesssagesSuccessful = this.messageCoordinator.VerifyAllMessagesComplete();
  1794.         AttackSequenceEndMessage attackSequenceEndMessage = new AttackSequenceEndMessage(this.stackItemUID, this.id);
  1795.         AttackDirector.AttackSequence attackSequence = this.Director.GetAttackSequence(this.id);
  1796.         for (int i = 0; i < attackSequence.allAffectedTargetIds.Count; i++)
  1797.         {
  1798.             ICombatant combatant = this.Director.Combat.FindCombatantByGUID(attackSequence.allAffectedTargetIds[i], false);
  1799.             if (combatant != null)
  1800.             {
  1801.                 combatant.ResolveAttackSequence(attackSequence.attacker.GUID, this.id, attackSequence.stackItemUID, this.Director.Combat.HitLocation.GetAttackDirection(attackSequence.attackPosition, combatant));
  1802.             }
  1803.         }
  1804.         this.Director.Combat.MessageCenter.PublishMessage(attackSequenceEndMessage);
  1805.         this.messageCoordinator.VerifyAllMessagesComplete();
  1806.     }
  1807.  
  1808.     // Token: 0x04003E0A RID: 15882
  1809.     [JsonIgnore]
  1810.     [NonSerialized]
  1811.     public static readonly ILog logger = HBS.Logging.Logger.GetLogger("CombatLog.AttackSequence", LogLevel.Log);
  1812.  
  1813.     // Token: 0x04003E0C RID: 15884
  1814.     public int id;
  1815.  
  1816.     // Token: 0x04003E0D RID: 15885
  1817.     public int stackItemUID;
  1818.  
  1819.     // Token: 0x04003E0E RID: 15886
  1820.     public AbstractActor attacker;
  1821.  
  1822.     // Token: 0x04003E0F RID: 15887
  1823.     public ICombatant chosenTarget;
  1824.  
  1825.     // Token: 0x04003E10 RID: 15888
  1826.     public Vector3 attackPosition;
  1827.  
  1828.     // Token: 0x04003E11 RID: 15889
  1829.     public Quaternion attackRotation;
  1830.  
  1831.     // Token: 0x04003E12 RID: 15890
  1832.     public int attackSequenceIdx;
  1833.  
  1834.     // Token: 0x04003E13 RID: 15891
  1835.     public int calledShotLocation;
  1836.  
  1837.     // Token: 0x04003E14 RID: 15892
  1838.     public bool isMoraleAttack;
  1839.  
  1840.     // Token: 0x04003E15 RID: 15893
  1841.     public bool isMelee;
  1842.  
  1843.     // Token: 0x04003E16 RID: 15894
  1844.     public MeleeAttackType meleeAttackType;
  1845.  
  1846.     // Token: 0x04003E17 RID: 15895
  1847.     public bool isParentMelee;
  1848.  
  1849.     // Token: 0x04003E18 RID: 15896
  1850.     public bool indirectFire;
  1851.  
  1852.     // Token: 0x04003E19 RID: 15897
  1853.     public int numTargets;
  1854.  
  1855.     // Token: 0x04003E1A RID: 15898
  1856.     private List<string> allWeaponIds;
  1857.  
  1858.     // Token: 0x04003E1B RID: 15899
  1859.     private int[][] randomCacheValuesUsed;
  1860.  
  1861.     // Token: 0x04003E1C RID: 15900
  1862.     private float[][][] randomCache;
  1863.  
  1864.     // Token: 0x04003E1D RID: 15901
  1865.     private int[][] varianceCacheValuesUsed;
  1866.  
  1867.     // Token: 0x04003E1E RID: 15902
  1868.     private int[][][] varianceCache;
  1869.  
  1870.     // Token: 0x04003E1F RID: 15903
  1871.     private WeaponHitInfo?[][] weaponHitInfo;
  1872.  
  1873.     // Token: 0x04003E20 RID: 15904
  1874.     private int[][] numberOfShots;
  1875.  
  1876.     // Token: 0x04003E21 RID: 15905
  1877.     private MessageCoordinator messageCoordinator = new MessageCoordinator();
  1878.  
  1879.     // Token: 0x04003E22 RID: 15906
  1880.     public List<Weapon> allSelectedWeapons;
  1881.  
  1882.     // Token: 0x04003E23 RID: 15907
  1883.     private List<List<Weapon>> sortedWeapons;
  1884.  
  1885.     // Token: 0x04003E24 RID: 15908
  1886.     public float cumulativeDamage;
  1887.  
  1888.     // Token: 0x04003E25 RID: 15909
  1889.     public int currentFiringGroup;
  1890.  
  1891.     // Token: 0x04003E26 RID: 15910
  1892.     private Dictionary<string, bool> attackDestroyedWeapon;
  1893.  
  1894.     // Token: 0x04003E27 RID: 15911
  1895.     private Dictionary<string, bool> attackCausedAmmoExplosion;
  1896.  
  1897.     // Token: 0x04003E28 RID: 15912
  1898.     private Dictionary<string, bool> attackContainsDodge;
  1899.  
  1900.     // Token: 0x04003E29 RID: 15913
  1901.     private Dictionary<string, int> attackCrits;
  1902.  
  1903.     // Token: 0x04003E2A RID: 15914
  1904.     private Dictionary<string, List<Weapon>> attackWeaponCrits;
  1905.  
  1906.     // Token: 0x04003E2B RID: 15915
  1907.     private Dictionary<string, List<AmmunitionBox>> attackAmmoCrits;
  1908.  
  1909.     // Token: 0x04003E2C RID: 15916
  1910.     private Dictionary<string, bool> attackDidDamage;
  1911.  
  1912.     // Token: 0x04003E2D RID: 15917
  1913.     private Dictionary<string, float> attackArmorDamage;
  1914.  
  1915.     // Token: 0x04003E2E RID: 15918
  1916.     private Dictionary<string, bool> lowArmorStruck;
  1917.  
  1918.     // Token: 0x04003E2F RID: 15919
  1919.     private Dictionary<string, float> attackStructureDamage;
  1920.  
  1921.     // Token: 0x04003E30 RID: 15920
  1922.     private Dictionary<string, bool> attackDestroyedLeg;
  1923.  
  1924.     // Token: 0x04003E31 RID: 15921
  1925.     private Dictionary<string, bool> attackDestroyedAnyLocation;
  1926.  
  1927.     // Token: 0x04003E32 RID: 15922
  1928.     private Dictionary<string, bool> attackDealtHeatDamage;
  1929.  
  1930.     // Token: 0x04003E33 RID: 15923
  1931.     private Dictionary<string, bool> attackCausedKnockdown;
  1932.  
  1933.     // Token: 0x04003E3A RID: 15930
  1934.     public float previousTeamHealthDifference;
  1935.  
  1936.     // Token: 0x04003E3B RID: 15931
  1937.     private List<AttackDirector.AttackSequence.MechDamage> recordedMechDamage = new List<AttackDirector.AttackSequence.MechDamage>();
  1938.  
  1939.     // Token: 0x04003E3C RID: 15932
  1940.     private StatsGatherer damageStatsGatherer = new StatsGatherer();
  1941.  
  1942.     // Token: 0x04003E3D RID: 15933
  1943.     private const int RANDOM_ROLLS_PER_SHOT_PER_WEAPON = 6;
  1944.  
  1945.     // Token: 0x04003E3E RID: 15934
  1946.     private const int RANDOM_PILOT_ROLLS_PER_WEAPON = 2;
  1947.  
  1948.     // Token: 0x04003E3F RID: 15935
  1949.     private const int RANDOM_BUFFER_PER_WEAPON = 5;
  1950.  
  1951.     // Token: 0x04003E40 RID: 15936
  1952.     private const int WONT_FIRE_SHOT_COUNT = -1;
  1953.  
  1954.     // Token: 0x04003E41 RID: 15937
  1955.     private const int NO_AMMO_SHOT_COUNT = 0;
  1956.  
  1957.     // Token: 0x04003E42 RID: 15938
  1958.     private static bool UseWeightedHitNumbers = true;
  1959.  
  1960.     // Token: 0x04003E43 RID: 15939
  1961.     private static bool PrintDebugInfo = false;
  1962.  
  1963.     // Token: 0x02000CDC RID: 3292
  1964.     private class MechDamage
  1965.     {
  1966.         // Token: 0x06006069 RID: 24681 RVA: 0x001A61A8 File Offset: 0x001A43A8
  1967.         public void AppendToStatsGatherer(StatsGatherer statsGatherer)
  1968.         {
  1969.             this.statsGatherer = statsGatherer;
  1970.             this.Add("Damaged GUID", this.mechGUID);
  1971.             this.Add("Weapon Group Index", this.weaponGroupIndex);
  1972.             this.Add("Weapon Index", this.weaponIndex);
  1973.             this.Add("Hit Index", this.hitIndex);
  1974.             this.Add("Weapon Name", this.weaponName);
  1975.             this.Add("Original Hit Location", (ArmorLocation)this.originalHitLocation);
  1976.             this.Add("Hit Location", this.hitLocation);
  1977.             this.Add("Impact Quality", this.impactQuality);
  1978.             this.Add("Remaining Damage", this.totalDamage);
  1979.             this.statsGatherer = null;
  1980.         }
  1981.  
  1982.         // Token: 0x0600606A RID: 24682 RVA: 0x001A6280 File Offset: 0x001A4480
  1983.         private void Add(string key, object value)
  1984.         {
  1985.             string text = string.Format("Impact {0} {1}", this.index, key);
  1986.             this.statsGatherer.Add(text, value);
  1987.         }
  1988.  
  1989.         // Token: 0x04003E44 RID: 15940
  1990.         public string mechGUID;
  1991.  
  1992.         // Token: 0x04003E45 RID: 15941
  1993.         public int weaponGroupIndex;
  1994.  
  1995.         // Token: 0x04003E46 RID: 15942
  1996.         public int weaponIndex;
  1997.  
  1998.         // Token: 0x04003E47 RID: 15943
  1999.         public int hitIndex;
  2000.  
  2001.         // Token: 0x04003E48 RID: 15944
  2002.         public string weaponName;
  2003.  
  2004.         // Token: 0x04003E49 RID: 15945
  2005.         public int originalHitLocation;
  2006.  
  2007.         // Token: 0x04003E4A RID: 15946
  2008.         public ArmorLocation hitLocation;
  2009.  
  2010.         // Token: 0x04003E4B RID: 15947
  2011.         public AttackImpactQuality impactQuality;
  2012.  
  2013.         // Token: 0x04003E4C RID: 15948
  2014.         public float totalDamage;
  2015.  
  2016.         // Token: 0x04003E4D RID: 15949
  2017.         public int index;
  2018.  
  2019.         // Token: 0x04003E4E RID: 15950
  2020.         private StatsGatherer statsGatherer;
  2021.     }
  2022. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement