private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get SelectionStateMove_ProjectedHeatForState Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get CombatHUDWeaponSlot_SetHitChance Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get HostileDamageFactor_expectedDamageForMelee Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get CombatTestFire_MeleeAttackSequence Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get MechRepresentation_PlayImpactAnim Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get MeleeWithHighestPriorityEnemyNode_Tick Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get MoveTowardsHighestPriorityMoveCandidateNode_Tick Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get AIUtil_ExpectedDamageForMeleeAttackUsingUnitsBVs Category " + weapon.Category + "->" + result + "\n"); return(result); }
public static void Postfix(AbstractActor unit, bool isStationary, BehaviorTreeResults __result) { CustomAmmoCategoriesLog.Log.LogWrite("Choose result for " + unit.DisplayName + "\n"); try { if (__result.nodeState == BehaviorNodeState.Failure) { CustomAmmoCategoriesLog.Log.LogWrite(" AI choosed not attack\n"); } else if (__result.orderInfo is AttackOrderInfo) { CustomAmmoCategoriesLog.Log.LogWrite(" AI choosed to attack " + (__result.orderInfo as AttackOrderInfo).TargetUnit.DisplayName + "\n"); CustomAmmoCategories.ChooseBestWeaponForTarget(unit, (__result.orderInfo as AttackOrderInfo).TargetUnit, isStationary); } else { CustomAmmoCategoriesLog.Log.LogWrite(" AI choosed something else beside attaking\n"); } return; } catch (Exception e) { CustomAmmoCategoriesLog.Log.LogWrite("Exception " + e.ToString() + "\nFallback to default\n"); return; } }
private static WeaponCategory Category(Weapon weapon) { WeaponCategory result = CustomAmmoCategories.isWeaponUseInMelee(weapon); CustomAmmoCategoriesLog.Log.LogWrite("get AttackEvaluator_MakeAttackOrderForTarget_AP Category " + weapon.Category + "->" + result + "\n"); return(result); }
private static int ShotsWhenFiredDisplayOverider(Weapon weapon) { if (weapon.weaponDef.ComponentTags.Contains("wr-clustered_shots") || (CustomAmmoCategories.getWeaponDisabledClustering(weapon) == false)) { return(weapon.ShotsWhenFired * weapon.ProjectilesPerShot); } else { return(weapon.ShotsWhenFired); } }
public static bool Prefix(AbstractActor unit, ICombatant target, int enemyUnitIndex, bool isStationary) { CustomAmmoCategoriesLog.Log.LogWrite(unit.DisplayName + " choosing best weapon for target " + target.DisplayName + "\n"); try { CustomAmmoCategories.ChooseBestWeaponForTarget(unit, target, isStationary); return(true); } catch (Exception e) { CustomAmmoCategoriesLog.Log.LogWrite("Exception " + e.ToString() + "\nFallback to default\n"); return(true); } }
public static bool Prefix(MissileEffect __instance) { bool isIndirect = (bool)typeof(MissileEffect).GetField("isIndirect", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); CustomAmmoCategoriesLog.Log.LogWrite("MissileEffect.PlayProjectile " + __instance.weapon.UIName + " real isIndirect = " + isIndirect + "\n"); if (CustomAmmoCategories.getWeaponAlwaysIndirectVisuals(__instance.weapon) == true) { CustomAmmoCategoriesLog.Log.LogWrite(" always indirect\n"); typeof(MissileEffect).GetField("isIndirect", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(__instance, (object)true); } return(true); }
public static bool Prefix(AttackDirector.AttackSequence __instance, ref MessageCenterMessage message) { AttackSequenceImpactMessage impactMessage = (AttackSequenceImpactMessage)message; if (impactMessage.hitInfo.attackSequenceId != __instance.id) { return(true); } int attackGroupIndex = impactMessage.hitInfo.attackGroupIndex; int attackWeaponIndex = impactMessage.hitInfo.attackWeaponIndex; Weapon weapon = __instance.GetWeapon(attackGroupIndex, attackWeaponIndex); float rawDamage = impactMessage.hitDamage; float realDamage = rawDamage; CustomAmmoCategoriesLog.Log.LogWrite("OnAttackSequenceImpact\n"); CustomAmmoCategoriesLog.Log.LogWrite(" attacker = " + __instance.attacker.DisplayName + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" target = " + __instance.target.DisplayName + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" weapon = " + weapon.UIName + "\n"); CustomAmmoCategoriesLog.Log.LogWrite(" damage = " + rawDamage + "\n"); if (realDamage >= 1.0f) { if (CustomAmmoCategories.getWeaponDamageVariance(weapon) > CustomAmmoCategories.Epsilon) { realDamage = CustomAmmoCategories.WeaponDamageSimpleVariance(weapon, rawDamage); } if (CustomAmmoCategories.getWeaponDistantVariance(weapon) > CustomAmmoCategories.Epsilon) { if (CustomAmmoCategories.getWeaponDistantVarianceReversed(weapon)) { realDamage = CustomAmmoCategories.WeaponDamageDistance(__instance.attacker, __instance.target, weapon, realDamage, rawDamage); } else { realDamage = CustomAmmoCategories.WeaponDamageRevDistance(__instance.attacker, __instance.target, weapon, realDamage, rawDamage); } } } else { CustomAmmoCategoriesLog.Log.LogWrite("WARNING! raw damage is less than 1.0f. Variance calculation is forbidden with this damage value\n", true); } CustomAmmoCategoriesLog.Log.LogWrite(" real damage = " + realDamage + "\n"); if (realDamage < CustomAmmoCategories.Epsilon) { CustomAmmoCategoriesLog.Log.LogWrite("WARNING! real damage is less than epsilon. May be negative. That is sad. Rounding to zero\n", true); realDamage = 0.0f; } impactMessage.hitDamage = realDamage; return(true); }
public static void Postfix(Weapon __instance, ICombatant target, Vector3 position, Quaternion rotation, ref bool __result) { if (__result == true) { float forbiddenRange = CustomAmmoCategories.getWeaponForbiddenRange(__instance); if (forbiddenRange > (double)CustomAmmoCategories.Epsilon) { float ActualRange = Vector3.Distance(position, target.TargetPosition); if (ActualRange < forbiddenRange) { __result = false; } } } }
public static void Postfix(LOFCache __instance, AbstractActor shootingUnit, ICombatant targetUnit, Weapon weapon, ref bool __result) { if (__result == true) { float forbiddenRange = CustomAmmoCategories.getWeaponForbiddenRange(weapon); if (forbiddenRange > (double)CustomAmmoCategories.Epsilon) { float ActualRange = Vector3.Distance(shootingUnit.CurrentPosition, targetUnit.CurrentPosition); if (ActualRange < forbiddenRange) { __result = false; } } } }
public static void Postfix(AbstractActor attackerUnit, Vector3 attackPosition, ICombatant targetUnit, Vector3 targetPosition, bool targetIsEvasive, Weapon weapon, int numTargets, ref float __result) { if (__result > CustomAmmoCategories.Epsilon) { float forbiddenRange = CustomAmmoCategories.getWeaponForbiddenRange(weapon); if (forbiddenRange > (double)CustomAmmoCategories.Epsilon) { float ActualRange = Vector3.Distance(attackPosition, targetPosition); if (ActualRange < forbiddenRange) { __result = 0.0f; } } } }
public static void Postfix(ToHit __instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot, ref string __result) { string str = string.Empty; bool flag = lofLevel < LineOfFireLevel.LOFObstructed && (CustomAmmoCategories.getIndirectFireCapable(weapon)); float weaponDirectFireModifier = CustomAmmoCategories.getDirectFireModifier(weapon); if (flag == false) { //CustomAmmoCategoriesLog.Log.LogWrite(attacker.DisplayName + " has LOS on " + target.DisplayName + ". Apply DirectFireModifier " + weaponDirectFireModifier + "\n"); if (!NvMath.FloatIsNearZero(weaponDirectFireModifier)) { __result = string.Format("{0}WEAPON-DIRECT-FIRE {1:+#;-#}; ", (object)__result, (object)(int)weaponDirectFireModifier); } } CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); return; }
public static void registerComponentsForVFX(this AbstractActor unit) { Log.LogWrite("registerComponentsForVFX " + unit.DisplayName + ":" + unit.GUID + "\n"); foreach (MechComponent component in unit.allComponents) { string wGUID; if (CustomAmmoCategories.checkExistance(component.StatCollection, CustomAmmoCategories.GUIDStatisticName) == false) { wGUID = Guid.NewGuid().ToString(); component.StatCollection.AddStatistic <string>(CustomAmmoCategories.GUIDStatisticName, wGUID); } else { wGUID = component.StatCollection.GetStatistic(CustomAmmoCategories.GUIDStatisticName).Value <string>(); } Log.LogWrite(" " + component.defId + ":" + wGUID + "\n"); ComponentVFXHelper.componentsVFXObjects[wGUID] = new VFXObjects(component); } }
public static void Postfix(ToHit __instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot, ref float __result) { bool flag = lofLevel < LineOfFireLevel.LOFObstructed && (CustomAmmoCategories.getIndirectFireCapable(weapon)); float num = __result; if (flag == false) { //float directFireModifier = CustomAmmoCategories.getDirectFireModifier(weapon); //CustomAmmoCategoriesLog.Log.LogWrite(attacker.DisplayName+" has LOS on "+target.DisplayName+ ". Apply DirectFireModifier "+directFireModifier+"\n"); num += CustomAmmoCategories.getDirectFireModifier(weapon); } CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((double)num < 0.0 && !combat.Constants.ResolutionConstants.AllowTotalNegativeModifier) { num = 0.0f; } __result = num; return; }
public static ObjectSpawnDataSelf DestroyedVFX(this MechComponent component) { string wGUID; if (CustomAmmoCategories.checkExistance(component.StatCollection, CustomAmmoCategories.GUIDStatisticName) == false) { wGUID = Guid.NewGuid().ToString(); component.StatCollection.AddStatistic <string>(CustomAmmoCategories.GUIDStatisticName, wGUID); } else { wGUID = component.StatCollection.GetStatistic(CustomAmmoCategories.GUIDStatisticName).Value <string>(); } Log.LogWrite("DestroyedVFX(" + component.defId + ":" + wGUID + ")\n"); if (ComponentVFXHelper.componentsVFXObjects.ContainsKey(wGUID)) { return(ComponentVFXHelper.componentsVFXObjects[wGUID].destroyedObject); } return(null); }
/*static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) * { * var targetPropertyGetter = AccessTools.Property(typeof(Weapon), "IndirectFireCapable").GetGetMethod(); * var replacementMethod = AccessTools.Method(typeof(ToHit_GetAllModifiers), nameof(IndirectFireCapable)); * return Transpilers.MethodReplacer(instructions, targetPropertyGetter, replacementMethod); * } * * private static bool IndirectFireCapable(Weapon weapon) * { * //CustomAmmoCategoriesLog.Log.LogWrite("get ToHit_GetAllModifiers IndirectFireCapable\n"); * return CustomAmmoCategories.getIndirectFireCapable(weapon); * }*/ public static bool Prefix(ToHit __instance, AbstractActor attacker, Weapon weapon, ICombatant target, Vector3 attackPosition, Vector3 targetPosition, LineOfFireLevel lofLevel, bool isCalledShot, ref float __result) { bool flag = lofLevel < LineOfFireLevel.LOFObstructed && (CustomAmmoCategories.getIndirectFireCapable(weapon)); float num = __instance.GetRangeModifier(weapon, attackPosition, targetPosition) + __instance.GetCoverModifier(attacker, target, lofLevel) + __instance.GetSelfSpeedModifier(attacker) + __instance.GetSelfSprintedModifier(attacker) + __instance.GetSelfArmMountedModifier(weapon) + __instance.GetStoodUpModifier(attacker) + __instance.GetHeightModifier(attackPosition.y, targetPosition.y) + __instance.GetHeatModifier(attacker) + __instance.GetTargetTerrainModifier(target, targetPosition, false) + __instance.GetSelfTerrainModifier(attackPosition, false) + __instance.GetTargetSpeedModifier(target, weapon) + __instance.GetSelfDamageModifier(attacker, weapon) + __instance.GetTargetSizeModifier(target) + __instance.GetTargetShutdownModifier(target, false) + __instance.GetTargetProneModifier(target, false) + __instance.GetWeaponAccuracyModifier(attacker, weapon) + __instance.GetAttackerAccuracyModifier(attacker) + __instance.GetEnemyEffectModifier(target) + __instance.GetRefireModifier(weapon) + __instance.GetTargetDirectFireModifier(target, flag) + __instance.GetIndirectModifier(attacker, flag) + __instance.GetMoraleAttackModifier(target, isCalledShot); if (flag == false) { float directFireModifier = CustomAmmoCategories.getDirectFireModifier(weapon); CustomAmmoCategoriesLog.Log.LogWrite(attacker.DisplayName + " has LOS on " + target.DisplayName + ". Apply DirectFireModifier " + directFireModifier + "\n"); num += CustomAmmoCategories.getDirectFireModifier(weapon); } CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((double)num < 0.0 && !combat.Constants.ResolutionConstants.AllowTotalNegativeModifier) { num = 0.0f; } __result = num; return(false); }
public static void Postfix(AmmunitionDef __instance) { EffectData[] effects = CustomAmmoCategories.findExtAmmo(__instance.Description.Id).statusEffects; List <EffectData> tmpList = new List <EffectData>(); CustomAmmoCategoriesLog.Log.LogWrite("Checking on null status effects " + __instance.Description.Id + " " + effects.Length + ".\n"); foreach (EffectData effect in effects) { if ((effect.Description != null)) { if ((effect.Description.Id != null) && (effect.Description.Name != null)) { tmpList.Add(effect); continue; } else { if (effect.Description.Id == null) { CustomAmmoCategoriesLog.Log.LogWrite("!Warning! effect id is null " + __instance.Description.Id + ".\n"); } if (effect.Description.Name == null) { CustomAmmoCategoriesLog.Log.LogWrite("!Warning! effect name is null " + __instance.Description.Id + ".\n"); } } } else { CustomAmmoCategoriesLog.Log.LogWrite("!Warning! effect description is null " + __instance.Description.Id + ".\n"); } CustomAmmoCategoriesLog.Log.LogWrite("!Warning! null status effect detected at ammo " + __instance.Description.Id + ".\n"); } if (tmpList.Count != effects.Length) { CustomAmmoCategoriesLog.Log.LogWrite("!Warning! null (" + (effects.Length - tmpList.Count) + "/" + effects.Length + ") status effects detected at ammo " + __instance.Description.Id + ".Removing\n"); CustomAmmoCategories.findExtAmmo(__instance.Description.Id).statusEffects = tmpList.ToArray(); } }
public static bool Prefix(WeaponEffect __instance) { CustomAmmoCategoriesLog.Log.LogWrite("WeaponEffect.PlayProjectile"); try { //__instance.t = 0.0f; typeof(WeaponEffect).GetField("t", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, 0.0f); __instance.currentState = WeaponEffect.WeaponEffectState.Firing; GameObject projectileMeshObject = (GameObject)typeof(WeaponEffect).GetField("projectileMeshObject", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((UnityEngine.Object)projectileMeshObject != (UnityEngine.Object)null) { projectileMeshObject.SetActive(true); } GameObject projectileLightObject = (GameObject)typeof(WeaponEffect).GetField("projectileLightObject", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((UnityEngine.Object)projectileLightObject != (UnityEngine.Object)null) { projectileLightObject.SetActive(true); } ParticleSystem projectileParticles = (ParticleSystem)typeof(WeaponEffect).GetField("projectileParticles", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if ((UnityEngine.Object)projectileParticles != (UnityEngine.Object)null) { projectileParticles.Stop(true); projectileParticles.Clear(true); } Transform projectileTransform = (Transform)typeof(WeaponEffect).GetField("projectileTransform", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); Transform startingTransform = (Transform)typeof(WeaponEffect).GetField("startingTransform", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); projectileTransform.position = startingTransform.position; Vector3 endPos = (Vector3)typeof(WeaponEffect).GetField("endPos", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); projectileTransform.LookAt(endPos); typeof(WeaponEffect).GetField("startPos", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(__instance, startingTransform.position); //__instance.startPos = __instance.startingTransform.position; if ((UnityEngine.Object)projectileParticles != (UnityEngine.Object)null) { BTCustomRenderer.SetVFXMultiplier(projectileParticles); projectileParticles.Play(true); BTLightAnimator componentInChildren = projectileParticles.GetComponentInChildren <BTLightAnimator>(true); if ((UnityEngine.Object)componentInChildren != (UnityEngine.Object)null) { componentInChildren.StopAnimation(); componentInChildren.PlayAnimation(); } } if ((UnityEngine.Object)__instance.weapon.parent.GameRep != (UnityEngine.Object)null) { int num; switch ((ChassisLocations)__instance.weapon.Location) { case ChassisLocations.LeftArm: num = 1; break; case ChassisLocations.RightArm: num = 2; break; default: num = 0; break; } __instance.weapon.parent.GameRep.PlayFireAnim((AttackSourceLimb)num, CustomAmmoCategories.getWeaponAttackRecoil(__instance.weapon)); } int hitIndex = (int)typeof(WeaponEffect).GetField("hitIndex", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); if (!__instance.AllowMissSkipping || __instance.hitInfo.hitLocations[hitIndex] != 0 && __instance.hitInfo.hitLocations[hitIndex] != 65536) { return(false); } __instance.PublishWeaponCompleteMessage(); } catch (Exception e) { CustomAmmoCategoriesLog.Log.LogWrite("Exception " + e.ToString() + "\nFallback to default\n"); return(true); } return(false); }
static void Postfix(TooltipPrefab_Weapon __instance, object data, TextMeshProUGUI ___rangeType, TextMeshProUGUI ___damage) { Mod.Log.Debug?.Write("TP_W:SD entered."); ___rangeType.enabled = false; Transform rangeLabelT = ___rangeType.gameObject.transform.parent; rangeLabelT.gameObject.SetActive(false); Transform layoutT = rangeLabelT.gameObject.transform.parent; RectTransform rLayoutT = layoutT.gameObject.GetComponent <RectTransform>(); LayoutRebuilder.ForceRebuildLayoutImmediate(rLayoutT); WeaponDef weaponDef = (WeaponDef)data; if (weaponDef != null) { Mod.Log.Debug?.Write($" Updating tooltip for weapon: {weaponDef.Description.UIName}"); if (CustomAmmoCategories.isRegistredWeapon(weaponDef.Description.Id)) { // Is a CAC weapon, use HasShells ExtWeaponDef extDef = CustomAmmoCategories.getExtWeaponDef(weaponDef.Description.Id); Mod.Log.Debug?.Write($" Found CAC extension for weapon."); if (extDef == null) { Mod.Log.Warn?.Write($"Failed to load CAC ExtWeaponDef for {weaponDef.Description.Id}, but it was registered!"); return; } /* * "ImprovedBallistic": true, - whether use or not own ballistic weapon effect engine. * Difference between "improved" and vanilla engine: * 1. Improved mode uses ShotsWhenFire properly (vanilla had not used them at all) * 3. Improved mode fire ShotsWhenFire volleys with ProjectilesPerShot bullets in each. * Bullets in one volley fired simultaneously instead of one by one (as in WeaponRealizer) * But damage still dealt once per volley, not per bullet, to keep compatibility with vanilla. * NOTE! If ImprovedBallistic is set DisableClustering is forced to true and "wr-clustered_shots" tag removed from definition. * * "BallisticDamagePerPallet": true - if true damage inflicted per pallet instead of per shot. * Only working with ImprovedBallistic true, ballistic weapon effect and HasShels false * Damage will be divided by ProjectilesPerShot value, heat damage and stable damage too. */ /* * PER HARKONNEN HALLOWED BY THINE NAME * If ImprovedBallistic = false OR * ImprovedBallistic = true AND (HasShells = true or BallisticDamageperPellet = false) - > damage x shots * If ImprovedBallistic = true and BallisticDamageperPellet = true and DamageNotDivided = true > damage x projectiles x shots * If ImprovedBallistic = true and BallisticDamageperPellet = true and DamageNotDivided = false > (damage/projectiles) x projectiles x shots */ if (extDef.ImprovedBallistic) { // Damage is damage * shotsWhenFired (each shot = volley of projectiles, projectiles are visual only) float totalDamage = weaponDef.Damage * weaponDef.ShotsWhenFired; if (weaponDef.ShotsWhenFired != 1) { string localText = $"{weaponDef.Damage} x {weaponDef.ShotsWhenFired} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic weapon damage set to: {localText}<page>"); ___damage.SetText(localText); } if (extDef.HasShells == TripleBoolean.True || extDef.BallisticDamagePerPallet != TripleBoolean.True) { if (weaponDef.ShotsWhenFired != 1) { // damage x shots = total totalDamage = weaponDef.Damage * weaponDef.ShotsWhenFired; string localText = $"{weaponDef.Damage} x {weaponDef.ShotsWhenFired} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + HasShells || !BallisticDamagePerPallet weapon damage set to: {localText}; ShotsWhenFired != 1"); ___damage.SetText(localText); } else { totalDamage = weaponDef.Damage * weaponDef.ShotsWhenFired; string localText = $"{totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + HasShells || !BallisticDamagePerPallet weapon damage set to: {localText}; ShotsWhenFired == 1"); ___damage.SetText(localText); } } if (extDef.BallisticDamagePerPallet == TripleBoolean.True && extDef.DamageNotDivided == TripleBoolean.True) { if (weaponDef.ShotsWhenFired != 1 && weaponDef.ProjectilesPerShot != 1) { totalDamage = weaponDef.Damage * weaponDef.ProjectilesPerShot * weaponDef.ShotsWhenFired; string localText = $"{weaponDef.Damage} x {weaponDef.ProjectilesPerShot} x {weaponDef.ShotsWhenFired} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot != 1 AND ShotsWhenFired != 1"); ___damage.SetText(localText); } else if (weaponDef.ShotsWhenFired == 1 && weaponDef.ProjectilesPerShot != 1) { totalDamage = weaponDef.Damage * weaponDef.ProjectilesPerShot * weaponDef.ShotsWhenFired; string localText = $"{weaponDef.Damage} x {weaponDef.ProjectilesPerShot}= {totalDamage}"; Mod.Log.Debug?.Write( $"ImprovedBallistic + BallisticDamagePerPallet + DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot != 1 BUT ShotsWhenFired == 1"); ___damage.SetText(localText); } else if (weaponDef.ShotsWhenFired != 1 && weaponDef.ProjectilesPerShot == 1) { totalDamage = weaponDef.Damage * weaponDef.ProjectilesPerShot * weaponDef.ShotsWhenFired; string localText = $"{weaponDef.Damage} x {weaponDef.ShotsWhenFired} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot == 1 BUT ShotsWhenFired != 1"); ___damage.SetText(localText); } else { totalDamage = weaponDef.Damage * weaponDef.ProjectilesPerShot * weaponDef.ShotsWhenFired; string localText = $"{totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + HasShells || !BallisticDamagePerPallet weapon damage set to: {localText}; ShotsWhenFired AND ProjectilesPerShot == 1"); ___damage.SetText(localText); } } if (extDef.BallisticDamagePerPallet == TripleBoolean.True && extDef.DamageNotDivided != TripleBoolean.True) { if (weaponDef.ShotsWhenFired != 1 && weaponDef.ProjectilesPerShot != 1) { float damagePerPellet = weaponDef.Damage / weaponDef.ProjectilesPerShot; totalDamage = damagePerPellet * weaponDef.ShotsWhenFired * weaponDef.ProjectilesPerShot; string localText = $"{damagePerPellet} x {weaponDef.ShotsWhenFired} x {weaponDef.ProjectilesPerShot} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + !DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot != 1 AND ShotsWhenFired != 1"); ___damage.SetText(localText); } else if (weaponDef.ShotsWhenFired == 1 && weaponDef.ProjectilesPerShot != 1) { float damagePerPellet = weaponDef.Damage / weaponDef.ProjectilesPerShot; totalDamage = damagePerPellet * weaponDef.ShotsWhenFired * weaponDef.ProjectilesPerShot; string localText = $"{damagePerPellet} x {weaponDef.ProjectilesPerShot} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + !DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot != 1 BUT ShotsWhenFired == 1"); ___damage.SetText(localText); } else if (weaponDef.ShotsWhenFired != 1 && weaponDef.ProjectilesPerShot == 1) { float damagePerPellet = weaponDef.Damage / weaponDef.ProjectilesPerShot; totalDamage = damagePerPellet * weaponDef.ShotsWhenFired * weaponDef.ProjectilesPerShot; string localText = $"{damagePerPellet} x {weaponDef.ShotsWhenFired} = {totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + !DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot == 1 BUT ShotsWhenFired != 1"); ___damage.SetText(localText); } else { float damagePerPellet = weaponDef.Damage / weaponDef.ProjectilesPerShot; totalDamage = damagePerPellet * weaponDef.ShotsWhenFired * weaponDef.ProjectilesPerShot; string localText = $"{totalDamage}"; Mod.Log.Debug?.Write($"ImprovedBallistic + BallisticDamagePerPallet + !DamageNotDivided weapon damage set to: {localText}; ProjectilesPerShot == 1 AND ShotsWhenFired == 1"); ___damage.SetText(localText); } } } else { // Vanilla calculations, so ProjectilesPerShot is visual only. See https://github.com/BattletechModders/IRTweaks/issues/8 float totalDamage = weaponDef.Damage * weaponDef.ShotsWhenFired; if (weaponDef.ShotsWhenFired != 1) { string localText = $"{weaponDef.Damage} x {weaponDef.ShotsWhenFired} shots = {totalDamage}"; Mod.Log.Debug?.Write($"Vanilla + ShotsWhenFire > 1 weapon damage set to: {localText}"); ___damage.SetText(localText); } else { string localText = $"{weaponDef.Damage}"; Mod.Log.Debug?.Write($"Vanilla + 1 ShotsWhenFired weapon damage set to: {localText}"); ___damage.SetText(localText); } } /* * "AOEDamage": 0 - if > 0 alternative AoE damage algorithm will be used. Main projectile will not always miss. * Instead it will inflict damage twice one for main target - direct hit (this damage can be have variance) * and second for all targets in AoE range including main. * * "AOEHeatDamage": 0 - if > 0 alternative AoE damage algorithm will be used. Main projectile will not always miss. * Instead it will inflict damage twice one for main target - direct hit (this damage can be have variance) * and second for all targets in AoE range including main. * * "AOEInstability": 0 - instability AoE damage */ } else { // Not a CAC weapon, vanilla, so ProjectilesPerShot is visual only. See https://github.com/BattletechModders/IRTweaks/issues/8 float totalDamage = weaponDef.Damage * weaponDef.ShotsWhenFired; if (weaponDef.ShotsWhenFired != 1) { string localText = $"{weaponDef.Damage} x {weaponDef.ShotsWhenFired} shots = {totalDamage}"; Mod.Log.Debug?.Write($"Vanilla + ShotsWhenFire > 1 weapon damage set to: {localText}"); ___damage.SetText(localText); } else { string localText = $"{weaponDef.Damage}"; Mod.Log.Debug?.Write($"Vanilla + 1 ShotsWhenFired weapon damage set to: {localText}"); ___damage.SetText(localText); } } } }
private static bool IndirectFireCapable(Weapon weapon) { //CustomAmmoCategoriesLog.Log.LogWrite("get LOFCache_UnitHasLOFToTarget IndirectFireCapable\n"); return(CustomAmmoCategories.getIndirectFireCapable(weapon)); }
private static bool IndirectFireCapable(Weapon weapon) { //CustomAmmoCategoriesLog.Log.LogWrite("get AbstractActor_GetLongestRangeWeapon IndirectFireCapable\n"); return(CustomAmmoCategories.getIndirectFireCapable(weapon)); }
private static bool IndirectFireCapable(Weapon weapon) { //CustomAmmoCategoriesLog.Log.LogWrite("get AIRoleAssignment_EvaluateSniper IndirectFireCapable\n"); return(CustomAmmoCategories.getIndirectFireCapable(weapon)); }
public static bool Prefix(ToHit __instance, int evasivePips, Weapon weapon, ref float __result) { //CustomAmmoCategoriesLog.Log.LogWrite("ToHit.GetEvasivePipsModifier"); try { float num = 0.0f; if (evasivePips > 0) { int index = Mathf.RoundToInt((float)((double)evasivePips - 1.0 - (weapon == null ? 0.0 : (double)(CustomAmmoCategories.getWeaponEvasivePipsIgnored(weapon))))); if (index > -1) { CombatGameState combat = (CombatGameState)typeof(ToHit).GetField("combat", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance); num += combat.Constants.ToHit.ToHitMovingPipUMs[index]; } } __result = num; return(false); } catch (Exception e) { CustomAmmoCategoriesLog.Log.LogWrite("Exception " + e.ToString() + "\nFallback to default\n"); return(true); } }
public static bool Prefix(AttackDirector.AttackSequence __instance, Weapon weapon, int groupIdx, int weaponIdx, int numberOfShots, bool indirectFire, float dodgedDamage, ref WeaponHitInfo __result) { WeaponHitInfo hitInfo = new WeaponHitInfo(); hitInfo.attackerId = __instance.attacker.GUID; hitInfo.targetId = __instance.target.GUID; hitInfo.numberOfShots = numberOfShots; hitInfo.stackItemUID = __instance.stackItemUID; hitInfo.attackSequenceId = __instance.id; hitInfo.attackGroupIndex = groupIdx; hitInfo.attackWeaponIndex = weaponIdx; hitInfo.toHitRolls = new float[numberOfShots]; hitInfo.locationRolls = new float[numberOfShots]; hitInfo.dodgeRolls = new float[numberOfShots]; hitInfo.dodgeSuccesses = new bool[numberOfShots]; hitInfo.hitLocations = new int[numberOfShots]; hitInfo.hitPositions = new Vector3[numberOfShots]; hitInfo.hitVariance = new int[numberOfShots]; hitInfo.hitQualities = new AttackImpactQuality[numberOfShots]; if (AttackDirector.hitLogger.IsLogEnabled) { Vector3 collisionWorldPos; LineOfFireLevel lineOfFire = __instance.Director.Combat.LOS.GetLineOfFire(__instance.attacker, __instance.attackPosition, __instance.target, __instance.target.CurrentPosition, __instance.target.CurrentRotation, out collisionWorldPos); float allModifiers = __instance.Director.Combat.ToHit.GetAllModifiers(__instance.attacker, weapon, __instance.target, __instance.attackPosition + __instance.attacker.HighestLOSPosition, __instance.target.TargetPosition, lineOfFire, __instance.isMoraleAttack); string modifiersDescription = __instance.Director.Combat.ToHit.GetAllModifiersDescription(__instance.attacker, weapon, __instance.target, __instance.attackPosition + __instance.attacker.HighestLOSPosition, __instance.target.TargetPosition, lineOfFire, __instance.isMoraleAttack); Pilot pilot = __instance.attacker.GetPilot(); AttackDirector.hitLogger.Log((object)string.Format("======================================== Unit Firing: {0} | Weapon: {1} | Shots: {2}", (object)__instance.attacker.DisplayName, (object)weapon.Name, (object)numberOfShots)); AttackDirector.hitLogger.Log((object)string.Format("======================================== Hit Info: GROUP {0} | ID {1}", (object)groupIdx, (object)weaponIdx)); AttackDirector.hitLogger.Log((object)string.Format("======================================== MODIFIERS: {0}... FINAL: [[ {1} ]] ", (object)modifiersDescription, (object)allModifiers)); if (pilot != null) { AttackDirector.hitLogger.Log((object)__instance.Director.Combat.ToHit.GetBaseToHitChanceDesc(__instance.attacker)); } else { AttackDirector.hitLogger.Log((object)string.Format("======================================== Gunnery Check: NO PILOT")); } } float toHitChance = __instance.Director.Combat.ToHit.GetToHitChance(__instance.attacker, weapon, __instance.target, __instance.attackPosition, __instance.target.CurrentPosition, __instance.numTargets, __instance.meleeAttackType, __instance.isMoraleAttack); if (Mech.TEST_KNOCKDOWN) { toHitChance = 1f; } if (AttackDirector.hitLogger.IsLogEnabled) { AttackDirector.hitLogger.Log((object)string.Format("======================================== HIT CHANCE: [[ {0:P2} ]]", (object)toHitChance)); } hitInfo.attackDirection = __instance.Director.Combat.HitLocation.GetAttackDirection(__instance.attackPosition, __instance.target); hitInfo.attackDirectionVector = __instance.Director.Combat.HitLocation.GetAttackDirectionVector(__instance.attackPosition, __instance.target); object[] args = new object[6]; HitGeneratorType hitGenType = HitGeneratorType.NotSet; if (weapon.weaponDef.ComponentTags.Contains("wr-clustered_shots")) { hitGenType = HitGeneratorType.Individual; } if (hitGenType == HitGeneratorType.NotSet) { if (CustomAmmoCategories.checkExistance(weapon.StatCollection, CustomAmmoCategories.AmmoIdStatName) == true) { string ammoId = weapon.StatCollection.GetStatistic(CustomAmmoCategories.AmmoIdStatName).Value <string>(); ExtAmmunitionDef extAmmo = CustomAmmoCategories.findExtAmmo(ammoId); hitGenType = extAmmo.HitGenerator; } if (hitGenType == HitGeneratorType.NotSet) { ExtWeaponDef extWeapon = CustomAmmoCategories.getExtWeaponDef(weapon.weaponDef.Description.Id); hitGenType = extWeapon.HitGenerator; } } if (hitGenType != HitGeneratorType.NotSet) { switch (hitGenType) { case HitGeneratorType.Individual: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; break; case HitGeneratorType.Cluster: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetClusteredHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetClusteredHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; case HitGeneratorType.Streak: //args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; //typeof(AttackDirector.AttackSequence).GetMethod("GetClusteredHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); //hitInfo = (WeaponHitInfo)args[0]; AttackSequence_GenerateHitInfo.GetStreakHits(__instance, ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); //__instance.GetClusteredHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; default: AttackDirector.attackLogger.LogError((object)string.Format("GenerateHitInfo found invalid weapon type: {0}, using basic hit info", (object)hitGenType)); args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetIndividualHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; } } else { switch (weapon.Type) { case WeaponType.Autocannon: case WeaponType.Gauss: case WeaponType.Laser: case WeaponType.PPC: case WeaponType.Flamer: case WeaponType.Melee: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetIndividualHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; case WeaponType.LRM: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetClusteredHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetClusteredHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; case WeaponType.SRM: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetIndividualHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; case WeaponType.MachineGun: args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetIndividualHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; default: AttackDirector.attackLogger.LogError((object)string.Format("GenerateHitInfo found invalid weapon type: {0}, using basic hit info", (object)weapon.Type)); args[0] = hitInfo; args[1] = groupIdx; args[2] = weaponIdx; args[3] = weapon; args[4] = toHitChance; args[5] = dodgedDamage; typeof(AttackDirector.AttackSequence).GetMethod("GetIndividualHits", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, args); hitInfo = (WeaponHitInfo)args[0]; //__instance.GetIndividualHits(ref hitInfo, groupIdx, weaponIdx, weapon, toHitChance, dodgedDamage); break; } } __result = hitInfo; return(false); //return hitInfo; }