public static void Prefix(AttackDirector.AttackSequence __instance, MessageCenterMessage message, List <List <Weapon> > ___sortedWeapons, WeaponHitInfo?[][] ___weaponHitInfo) { try { AttackSequenceWeaponPreFireCompleteMessage attackSequenceWeaponPreFireCompleteMessage = (AttackSequenceWeaponPreFireCompleteMessage)message; if (attackSequenceWeaponPreFireCompleteMessage.sequenceId != __instance.id) { return; } int groupIdx = attackSequenceWeaponPreFireCompleteMessage.groupIdx; int weaponIdx = attackSequenceWeaponPreFireCompleteMessage.weaponIdx; Weapon weapon = ___sortedWeapons[groupIdx][weaponIdx]; Logger.Debug($"[AttackDirector.AttackSequence_OnAttackSequenceWeaponPreFireComplete_PREFIX] ({weapon.parent.DisplayName}) HANDLED AttackSequence: {__instance.id}, WeaponGroup: {groupIdx}, Weapon: {weapon.Name}({weaponIdx})"); Logger.Debug($"---"); } catch (Exception e) { Logger.Error(e); } }
public static bool Prefix(AttackDirector.AttackSequence __instance, MessageCenterMessage message, List <List <Weapon> > ___sortedWeapons, ref int[][] ___numberOfShots, ref WeaponHitInfo?[][] ___weaponHitInfo) { try { AttackSequenceFireMessage attackSequenceFireMessage = (AttackSequenceFireMessage)message; if (attackSequenceFireMessage.sequenceId != __instance.id) { return(false); } int groupIdx = attackSequenceFireMessage.groupIdx; int weaponIdx = attackSequenceFireMessage.weaponIdx; Weapon weapon = ___sortedWeapons[groupIdx][weaponIdx]; Logger.Debug($"---"); Logger.Debug($"[AttackDirector.AttackSequence_OnAttackSequenceFire_PREFIX] ({weapon.parent.DisplayName}) STARTED AttackSequence: {__instance.id}, WeaponGroup: {groupIdx}, Weapon: {weapon.Name}({weaponIdx})"); //if(weapon.weaponDef.ComponentTags.Contains("component_type_srmstreak")) if (weapon.Type == WeaponType.SRM && weapon.AmmoCategoryValue.Name == "SRMStreak") { WeaponHitInfo weaponHitInfo = ___weaponHitInfo[groupIdx][weaponIdx].Value; bool streakWillHit = weaponHitInfo.DidShotHitChosenTarget(0); // If first missile hits/misses, all will hit/miss Logger.Info($"[AttackDirector.AttackSequence_OnAttackSequenceFire_PREFIX] ({weapon.Name}) streakWillHit: {streakWillHit}"); // Fire targeting laser Vector3 floatieVector = new Vector3(); Utilities.CreateAndFireStreakTargetingLaser(__instance, weapon, out floatieVector, streakWillHit); if (streakWillHit) { // Only floaties, everything else is prepared at this point // Big Floatie //__instance.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.chosenTarget.GUID, __instance.chosenTarget.GUID, "STREAK LOCKED-ON", FloatieMessage.MessageNature.CriticalHit)); // Small Floatie FloatieMessage hitFloatie = new FloatieMessage(__instance.attacker.GUID, __instance.chosenTarget.GUID, "STREAK LOCKED-ON", __instance.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.Suppression, floatieVector.x, floatieVector.y, floatieVector.z); __instance.Director.Combat.MessageCenter.PublishMessage(hitFloatie); return(true); } else { // Cancel firing, see code of original method... // Mark Streak SRMs as having fired nevertheless because a failed lock on should be handled like "fired" new Traverse(weapon).Property("HasFired").SetValue(true); weapon.CompleteFiring(); Logger.Info($"[AttackDirector.AttackSequence_OnAttackSequenceFire_PREFIX] ({weapon.Name}) HasFired: {weapon.HasFired}, RoundsSinceLastFire: {weapon.roundsSinceLastFire}"); // If weapon already prefired we would need to reincrement ammo (Note that Weapon.OffsetAmmo() is a custom extension method) if (weapon.HasPreFired) { weapon.OffsetAmmo(); } // Send out all necessary messages to keep the current AttackSequence in sync AttackSequenceWeaponPreFireCompleteMessage weaponPreFireCompleteMessage = new AttackSequenceWeaponPreFireCompleteMessage(__instance.stackItemUID, __instance.id, groupIdx, weaponIdx); __instance.Director.Combat.MessageCenter.PublishMessage(weaponPreFireCompleteMessage); int numberOfShots = ___numberOfShots[groupIdx][weaponIdx]; for (int j = 0; j < numberOfShots; j++) { float hitDamage = weapon.DamagePerShotAdjusted(weapon.parent.occupiedDesignMask); float structureDamage = weapon.StructureDamagePerShotAdjusted(weapon.parent.occupiedDesignMask); AttackSequenceImpactMessage impactMessage = new AttackSequenceImpactMessage(weaponHitInfo, j, hitDamage, structureDamage); __instance.Director.Combat.MessageCenter.PublishMessage(impactMessage); } AttackSequenceResolveDamageMessage resolveDamageMessage = new AttackSequenceResolveDamageMessage(weaponHitInfo); __instance.Director.Combat.MessageCenter.PublishMessage(resolveDamageMessage); AttackSequenceWeaponCompleteMessage weaponCompleteMessage = new AttackSequenceWeaponCompleteMessage(__instance.stackItemUID, __instance.id, groupIdx, weaponIdx); __instance.Director.Combat.MessageCenter.PublishMessage(weaponCompleteMessage); // Big Floaties //__instance.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(weapon.parent.GUID, weapon.parent.GUID, "STREAK LOCK-ON FAILED", FloatieMessage.MessageNature.Debuff)); //__instance.Director.Combat.MessageCenter.PublishMessage(new FloatieMessage(__instance.chosenTarget.GUID, __instance.chosenTarget.GUID, "STREAK LOCK-ON AVOIDED", FloatieMessage.MessageNature.Buff)); // Small Floatie FloatieMessage missFloatie = new FloatieMessage(__instance.attacker.GUID, __instance.chosenTarget.GUID, "STREAK LOCK-ON FAILED", __instance.Director.Combat.Constants.CombatUIConstants.floatieSizeMedium, FloatieMessage.MessageNature.Dodge, floatieVector.x, floatieVector.y, floatieVector.z); __instance.Director.Combat.MessageCenter.PublishMessage(missFloatie); // Skip original method! return(false); } } return(true); } catch (Exception e) { Logger.Error(e); return(true); } }