public static bool Prefix( Mech __instance, WeaponHitInfo hitInfo, ArmorLocation aLoc, ref float directStructureDamage, ref bool __result) { try { if (ComponentExplosionsFeature.IsInternalExplosionContained) { __result = false; Control.Logger.Warning.Log("prevented explosion pass through (you should never see this message)"); return(false); } if (ComponentExplosionsFeature.IsInternalExplosion) { var location = MechStructureRules.GetChassisLocationFromArmorLocation(aLoc); UpdateStructureDamage(__instance, location, hitInfo, ref directStructureDamage); } } catch (Exception e) { Control.Logger.Error.Log(e); } return(true); }
public static void Prefix(Mech __instance, int originalHitLoc, ArmorLocation aLoc, Weapon weapon, ref float totalArmorDamage, ref float directStructureDamage) { var mechTags = __instance.GetTags(); if (mechTags.Contains("BR_MQ_ArmourBaffleSystem") && ((ArmorLocation)originalHitLoc == ArmorLocation.LeftArm || (ArmorLocation)originalHitLoc == ArmorLocation.RightArm || (ArmorLocation)originalHitLoc == ArmorLocation.LeftLeg || (ArmorLocation)originalHitLoc == ArmorLocation.RightLeg)) { totalArmorDamage *= Core.Settings.ArmourBaffleFactor; directStructureDamage *= Core.Settings.ArmourBaffleFactor; } if (mechTags.Contains("BR_MQ_CrabClaws") && ((ArmorLocation)originalHitLoc == ArmorLocation.LeftArm || (ArmorLocation)originalHitLoc == ArmorLocation.RightArm)) { totalArmorDamage *= Core.Settings.CrabClawDamageFactor; directStructureDamage *= Core.Settings.CrabClawDamageFactor; } if (__instance.GetPilot().pilotDef.PilotTags.Contains("PQ_pilot_elite") && __instance.weightClass == WeightClass.MEDIUM) { var pips = __instance.EvasivePipsCurrent; totalArmorDamage *= 1 - pips * 0.05f; directStructureDamage *= 1 - pips * 0.05f; } if (__instance.GetPilot().pilotDef.SkillGuts >= 5) { float gutsBonus = (__instance.GetPilot().pilotDef.SkillGuts - 4) * 0.02f; if (__instance.GetPilot().pilotDef.SkillGuts >= 10) { gutsBonus += 0.03f; } totalArmorDamage *= 1 - gutsBonus; directStructureDamage *= 1 - gutsBonus; } }
static void Prefix(Mech __instance, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage) { Mod.Log.Trace?.Write("M:DL - entered"); if (aLoc == ArmorLocation.Head) { Mod.Log.Info?.Write($"Head hit from weapon:{weapon?.UIName} for {totalArmorDamage} armor damage and {directStructureDamage} structure damage."); float currHeadArmor = __instance.GetCurrentArmor(aLoc); int damageMod = (int)Math.Ceiling(totalArmorDamage); float damageThroughArmor = totalArmorDamage - currHeadArmor; Mod.Log.Debug?.Write($"TotalArmorDamage:{totalArmorDamage} - Head armor:{currHeadArmor} = throughArmor:{damageThroughArmor}"); if (totalArmorDamage - currHeadArmor <= 0) { damageMod = (int)Math.Floor(damageMod * Mod.Config.Combat.PainTolerance.HeadHitArmorOnlyResistPenaltyMulti); Mod.Log.Info?.Write($"Head hit impacted armor only, reduced damage to:{damageMod}"); } if (directStructureDamage != 0) { Mod.Log.Debug?.Write($"Attack inflicted ${directStructureDamage}, adding to total resist damage."); damageMod += (int)Math.Ceiling(directStructureDamage); } ModState.InjuryResistPenalty = damageMod * Mod.Config.Combat.PainTolerance.HeadDamageResistPenaltyPerArmorPoint; Mod.Log.Debug?.Write($"Headshot sets injury resist penalty to: {damageMod} x {Mod.Config.Combat.PainTolerance.HeadDamageResistPenaltyPerArmorPoint} = {ModState.InjuryResistPenalty}"); } }
static void Postfix(HUDMechArmorReadout __instance, ArmorLocation location, Mech ___displayedMech) { if (__instance == null || __instance.HUD == null || __instance.HUD.SelectedActor == null || __instance.HUD.SelectedTarget == null) { return; // nothing to do } if (__instance.UseForCalledShots && location == ArmorLocation.Head) { Mod.Log.Trace?.Write("HUDMAR:SHA entered"); bool attackerCanAlwaysMakeCalledShot = __instance.HUD.SelectedActor.CanAlwaysUseCalledShot(); bool targetCanBeCalledShot = __instance.HUD.SelectedTarget.IsShutDown || __instance.HUD.SelectedTarget.IsProne || attackerCanAlwaysMakeCalledShot; Mod.Log.Debug?.Write($" Hover - target:({___displayedMech.DistinctId()}) canBeTargeted:{targetCanBeCalledShot} by attacker:({__instance.HUD.SelectedActor.DistinctId()})"); Mod.Log.Debug?.Write($" isShutdown:{___displayedMech.IsShutDown} isProne:{___displayedMech.IsProne} canAlwaysCalledShot:{attackerCanAlwaysMakeCalledShot}"); if (!targetCanBeCalledShot) { Mod.Log.Debug?.Write(" preventing targeting of head."); __instance.ClearHoveredArmor(ArmorLocation.Head); } else { Mod.Log.Debug?.Write(" target head can be targeted."); } } }
static void Prefix(Mech __instance, ArmorLocation aLoc, float totalArmorDamage, float directStructureDamage) { if (aLoc == ArmorLocation.Head) { //var sim = UnityGameInstance.BattleTechGame.Simulation; //if (sim.CompanyTags.Contains("FewerHeadInjuriesDisabled")) // return; var currentArmor = __instance.GetCurrentArmor(aLoc); var maxArmor = __instance.GetMaxArmor(aLoc); if (Math.Abs(__instance.GetCurrentArmor(aLoc)) < float.Epsilon) { return; } if (currentArmor - totalArmorDamage + directStructureDamage <= 0) { return; } var Modifier = UnityGameInstance.BattleTechGame.Simulation.GetCareerModeOverallDifficultyMod(); var rng = new Random().Next(1, 101); if (rng <= currentArmor / maxArmor * 100 * Modifier) { IgnoreNextHeadHit.Add(__instance.pilot); } } }
internal static ArmorLocation GetPassthroughLocation( ArmorLocation location, AttackDirection attackDirection ) { try { if (ComponentExplosionsFeature.IsInternalExplosion && currentMech != null) { var chassisLocation = MechStructureRules.GetChassisLocationFromArmorLocation(location); var properties = ComponentExplosionsFeature.Shared.GetCASEProperties(currentMech, (int)chassisLocation); if (properties != null) { currentMech.PublishFloatieMessage("EXPLOSION CONTAINED"); //Control.mod.Logger.LogDebug($"prevented explosion pass through from {Mech.GetAbbreviatedChassisLocation(chassisLocation)}"); return(ArmorLocation.None); // CASE redirects damage, so lets redirect it to none } } } catch (Exception e) { Control.mod.Logger.LogError(e); } return(MechStructureRules.GetPassthroughLocation(location, attackDirection)); }
public static void Prefix(MechFallSequence __instance) { Mod.Log.Trace("MFS:OnComplete - entered."); int damagePointsTT = (int)Math.Ceiling(__instance.OwningMech.tonnage / 10f); Mod.Log.Debug($"Actor: {CombatantUtils.Label(__instance.OwningMech)} will suffer {damagePointsTT} TT damage points."); // Check for any pilot skill damage reduction float damageReduction = 1.0f - __instance.OwningMech.PilotCheckMod(Mod.Config.Piloting.DFAReductionMulti); float reducedDamage = (float)Math.Max(0f, Math.Floor(damageReduction * damagePointsTT)); Mod.Log.Debug($" Reducing TT fall damage from: {damagePointsTT} by {damageReduction:P1} to {reducedDamage}"); List <int> locationDamage = new List <int>(); while (damagePointsTT >= 5) { locationDamage.Add(5 * Mod.Config.Piloting.FallingDamagePerTenTons); damagePointsTT -= 5; } if (damagePointsTT > 0) { locationDamage.Add(damagePointsTT * Mod.Config.Piloting.FallingDamagePerTenTons); } Mod.Log.Debug($"Applying falling damage to actor: {CombatantUtils.Label(__instance.OwningMech)}"); foreach (int damage in locationDamage) { ArmorLocation location = FallingDamageLocations[__instance.OwningMech.Combat.NetworkRandom.Int(0, FallingDamageLocations.Length)]; Mod.Log.Debug($" {damage} damage to location: {location}"); __instance.OwningMech.DEBUG_DamageLocation(location, damage, __instance.OwningMech, DamageType.KnockdownSelf); } }
public static void Prefix(Mech __instance, WeaponHitInfo hitInfo, ArmorLocation aLoc, Weapon weapon, float totalArmorDamage, float directStructureDamage, int hitIndex, AttackImpactQuality impactQuality, DamageType damageType) { if (aLoc == ArmorLocation.Head) { Mod.Log.Info($"Head hit from weapon:{weapon?.UIName} for {totalArmorDamage} armor damage and {directStructureDamage} structure damage. " + $"Quality was:{impactQuality} with type:{damageType}"); float currHeadArmor = __instance.GetCurrentArmor(aLoc); int damageMod = (int)Math.Ceiling(totalArmorDamage); float damageThroughArmor = totalArmorDamage - currHeadArmor; Mod.Log.Debug($"TotalArmorDamage:{totalArmorDamage} - Head armor:{currHeadArmor} = throughArmor:{damageThroughArmor}"); if (totalArmorDamage - currHeadArmor <= 0) { damageMod = (int)Math.Floor(damageMod * Mod.Config.Combat.PainTolerance.HeadHitArmorOnlyMulti); Mod.Log.Info($"Head hit impacted armor only, reduced damage to:{damageMod}"); } if (directStructureDamage != 0) { Mod.Log.Debug($"Attack inflicted ${directStructureDamage}, adding to total resist damage."); damageMod += (int)Math.Ceiling(directStructureDamage); } ModState.InjuryResistPenalty = damageMod * Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage; Mod.Log.Info($"Setting resist penalty to:{damageMod} x {Mod.Config.Combat.PainTolerance.PenaltyPerHeadDamage} = {ModState.InjuryResistPenalty}"); } }
public Armor(string armorName, string armorType, int price, float weight, ArmorLocation location, int defenseValue, int defenseModifier, params string[] allowableClasses) : base(armorName, armorType, price, weight, allowableClasses) { Location = location; DefenseValue = defenseValue; DefenseModifier = defenseModifier; }
public static void RecordMechDamage(Mech __instance, ArmorLocation aLoc, float totalDamage) { if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid) { return; } RecordUnitDamage(aLoc.ToString(), totalDamage, __instance.GetCurrentArmor(aLoc), __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc))); }
public static bool Prefix(ArmorLocation location, ref ArmorLocation __result) { if (location == ArmorLocation.Head) { __result = ArmorLocation.CenterTorso; return(false); } return(true); }
public void AddArmorDamage(float damage, ArmorLocation loc) { float existingDamage = 0.0f; if (armorLocationDictionary.ContainsKey(loc)) { existingDamage = armorLocationDictionary[loc]; } armorLocationDictionary[loc] = existingDamage + damage; }
public static float GetRemainingHealth(this Mech mech, ArmorLocation aLocation) { ChassisLocations cLocation = MechStructureRules.GetChassisLocationFromArmorLocation(aLocation); float armorCurrent = mech.GetCurrentArmor(aLocation); float structureCurrent = mech.GetCurrentStructure(cLocation); Logger.Info($"[MechExtensions_GetRemainingHealth] ({aLocation}) H:{structureCurrent + armorCurrent}(S:{structureCurrent}, A:{armorCurrent})"); return(armorCurrent + structureCurrent); }
public ArmorItem(string _name, string _description, ItemType _itemType, int _value, bool _usedInCombat, int _AC, ArmorLocation _armorLocation) { name = _name; Id = SingleTon.GetItemManager().AllItems.Count; describtion = _description; itemType = _itemType; Value = _value; UseInCombat = _usedInCombat; AC = _AC; ArmorLocation = _armorLocation; Effect = "Def +" + AC; }
public static void LogMechHit(ArmorLocation __result, Dictionary <ArmorLocation, int> hitTable, float randomRoll, ArmorLocation bonusLocation, float bonusLocationMultiplier) { LogHitSequence(MechStructureRules.GetChassisLocationFromArmorLocation(__result), randomRoll, bonusLocation, bonusLocationMultiplier, TryGet(hitTable, ArmorLocation.Head) + Separator + (TryGet(hitTable, ArmorLocation.CenterTorso) + TryGet(hitTable, ArmorLocation.CenterTorsoRear)) + Separator + (TryGet(hitTable, ArmorLocation.LeftTorso) + TryGet(hitTable, ArmorLocation.LeftTorsoRear)) + Separator + (TryGet(hitTable, ArmorLocation.RightTorso) + TryGet(hitTable, ArmorLocation.RightTorsoRear)) + Separator + TryGet(hitTable, ArmorLocation.LeftArm) + Separator + TryGet(hitTable, ArmorLocation.RightArm) + Separator + TryGet(hitTable, ArmorLocation.LeftLeg) + Separator + TryGet(hitTable, ArmorLocation.RightLeg)); }
public RepairRecord() { InnerStructure = 0f; Armor = 0f; Components = 0; TurnsSinceDamage = 1; MechStructureLocations = new ChassisLocations[0]; MechArmorLocations = new ArmorLocation[0]; VehicleLocations = new VehicleChassisLocations[0]; AffectInstalledLocation = false; repairTrigger = new RepairTrigger(); }
public static float GetRemainingHealthRatio(this Mech mech, ArmorLocation aLocation) { ChassisLocations cLocation = MechStructureRules.GetChassisLocationFromArmorLocation(aLocation); float armorCurrent = mech.GetCurrentArmor(aLocation); float structureCurrent = mech.GetCurrentStructure(cLocation); float armorMax = mech.GetMaxArmor(aLocation); float structureMax = mech.GetMaxStructure(cLocation); Logger.Info($"[MechExtensions_GetRemainingHealthRatio] ({aLocation}) S:{structureCurrent}/{structureMax}, A:{armorCurrent}/{armorMax}"); return((armorCurrent + structureCurrent) / (armorMax + structureMax)); }
public Armor( string armorName, string armorType, int price, float weight, ArmorLocation location, int defenseValue, int defenseModifier) : base(armorName, armorType, price, weight) { this.location = location; this.defenseValue = defenseValue; this.defenseModifier = defenseModifier; }
public Armor( string armorName, string armorType, int price, float weight, ArmorLocation locaion, int defenseValue, int defenseModifier, params Type[] allowableClasses) : base(armorName, armorType, price, weight, allowableClasses) { Location = location; DefenseValue = defenseValue; DefenseModifier = defenseModifier; }
public Armor( string name, string type, int price, float weight, ArmorLocation location, int defenseValue = 0, int defenseModifier = 0, params string[] allowedClasses) : base(name, type, price, weight, allowedClasses) { Location = location; DefenseValue = defenseValue; DefenseModifier = defenseModifier; }
internal ArmorLocationState( ArmorLocation location, int allocationPriority, // used to calculate priority, priority is reduced linearly by assigned points int max, // actual max to calculate IsFull int assigned, ChassisLocationState?linkedChassisLocationState // used for torso armor locations that have shared limits ) { Location = location; AllocationPriority = allocationPriority; Max = max; Assigned = assigned; LinkedChassisLocationState = linkedChassisLocationState; }
// ============ Zombie ============ public static void FixZombieMech(Mech __instance, ref float totalDamage, ArmorLocation aLoc) { try { if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid) { return; } float armour = __instance.GetCurrentArmor(aLoc); if (armour >= totalDamage) { return; } KillZombie("mech", __instance.DisplayName, armour + __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc)), ref totalDamage); } catch (Exception ex) { Error(ex); } }
public static void Postfix(CombatHUD __instance) { try { // Only relevant for Precision Strike if (__instance.SelectionHandler.ActiveState == null || __instance.SelectionHandler.ActiveState.SelectionType != SelectionType.FireMorale) { return; } // No headshots from behind if (__instance.CalledShotPopUp.ShownAttackDirection == AttackDirection.FromBack) { return; } Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] Clear confirmed called headshot if enabled weapons change to an invalid amount..."); bool isCalledShotPopupVisible = __instance.CalledShotPopUp.Visible; Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] isCalledShotPopupVisible: " + isCalledShotPopupVisible); int enabledWeaponCount = Utilities.GetReadiedWeaponCount(__instance.SelectedActor.Weapons, __instance.SelectedTarget, true); Pilot selectedPilot = __instance.SelectedActor.GetPilot(); int maxAllowedWeapons = Utilities.GetMaxAllowedWeaponCountForHeadshots(selectedPilot); bool validWeaponCountForPrecisionStrike = enabledWeaponCount <= maxAllowedWeapons ? true : false; Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] enabledWeaponCount: " + enabledWeaponCount); Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] validWeaponCountForPrecisionStrike: " + validWeaponCountForPrecisionStrike); ArmorLocation baseCalledShotLocation = (ArmorLocation)typeof(SelectionStateFire).GetField("calledShotLocation", AccessTools.all).GetValue(__instance.SelectionHandler.ActiveState); bool headIsTargeted = baseCalledShotLocation == ArmorLocation.Head; Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] headIsTargeted: " + headIsTargeted); //bool isMoraleAttack = __instance.SelectionHandler.ActiveState is SelectionStateMoraleAttack; //Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] isMoraleAttack: " + isMoraleAttack); bool shouldBackOut = headIsTargeted && !isCalledShotPopupVisible && !validWeaponCountForPrecisionStrike; Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] shouldBackOut: " + shouldBackOut); if (shouldBackOut) { Logger.Debug("[CombatHUD_OnWeaponModified_POSTFIX] " + __instance.SelectionHandler.ActiveState.ToString() + ".BackOut()"); __instance.SelectionHandler.ActiveState.BackOut(); } } catch (Exception e) { Logger.Error(e); } }
public float GetArmorDamageForLocation(ArmorLocation loc) { float dmg = 0.0f; if (armorLocationDictionary.ContainsKey(loc)) { dmg = armorLocationDictionary[loc]; } for (int childIndex = 0; childIndex < children.Count; ++childIndex) { ChildWithProbability c = children[childIndex]; dmg += c.DamageExpectationRecord.GetArmorDamageForLocation(loc) * c.Probability; } return(dmg); }
// ============ UTILS ============ internal static float FixMultiplier(ArmorLocation location, float multiplier) { if (location == None) { return(0); } if (MechCalledShotMultiplier != 1) { multiplier *= MechCalledShotMultiplier; } if (location == Head && CallShotClustered && ClusterChanceNeverMultiplyHead) { return(multiplier * ClusterChanceOriginalLocationMultiplier); } return(multiplier); }
private static void ShowDamageFloatie(Mech mech, ArmorLocation location, float damage, string sourceGUID) { if (mech != null && mech.GameRep != null) { Vector3 vector = mech.GameRep.GetHitPosition((int)location) + UnityEngine.Random.insideUnitSphere * 5f; FloatieMessage.MessageNature nature = mech.GetCurrentArmor(location) > 0f ? FloatieMessage.MessageNature.ArmorDamage : FloatieMessage.MessageNature.StructureDamage; FloatieMessage message = new FloatieMessage(sourceGUID, mech.GUID, $"{damage}", SharedState.Combat.Constants.CombatUIConstants.floatieSizeMedium, nature, vector.x, vector.y, vector.z); SharedState.Combat.MessageCenter.PublishMessage(message); } }
public static void ShowCalledLocationHP(CombatHUDCalledShotPopUp __instance) { try { if (title == null) { title = UnityEngine.GameObject.Find("calledShot_Title")?.GetComponent <TMPro.TextMeshProUGUI>(); title.enableAutoSizing = false; if (title == null) { return; } } /* * public void SetText(StringBuilder text); * public void SetText(string text, float arg0, float arg1, float arg2); * public void SetText(string text, float arg0, float arg1); * public void SetText(string text, float arg0); * public void SetText(string text, bool syncTextInputBox); * public void SetText(string text);*/ CombatHUDCalledShotPopUp me = __instance; ArmorLocation hoveredArmor = me.MechArmorDisplay.HoveredArmor; if (me.locationNameText.text.StartsWith("-")) { title.SetText("Called Shot"); } else if (me.DisplayedActor is Mech mech) { float hp = mech.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(hoveredArmor)); if (hp <= 0) { title.SetText("Called Shot"); me.locationNameText.SetText("-choose target-", ZeroObjects); } else { float mhp = mech.GetMaxStructure(MechStructureRules.GetChassisLocationFromArmorLocation(hoveredArmor)), armour = mech.GetCurrentArmor(hoveredArmor), marmour = mech.GetMaxArmor(hoveredArmor); title.text = me.locationNameText.text; me.locationNameText.text = string.Format("{0:0}/{1:0} <#FFFFFF>{2:0}/{3:0}", hp, mhp, armour, marmour); } } } catch (Exception ex) { Error(ex); } }
internal static float GetCurrentArmor( this Mech mech, ArmorLocation location ) { try { if (ComponentExplosionsFeature.IsInternalExplosion) { return(0); } } catch (Exception e) { Control.mod.Logger.LogError(e); } return(mech.GetCurrentArmor(location)); }
public static void LogMechDamage(Mech __instance, ArmorLocation aLoc, Weapon weapon, DamageType damageType) { try { if (aLoc == ArmorLocation.None || aLoc == ArmorLocation.Invalid || !IsLoggedDamage(damageType)) { return; } int line = LogActorDamage(__instance.GetCurrentArmor(aLoc), __instance.GetCurrentStructure(MechStructureRules.GetChassisLocationFromArmorLocation(aLoc))); if (line >= 0 && Settings.CritFollowDamageTransfer && hitMap != null) { string newKey = GetHitKey(weapon.uid, aLoc, __instance.GUID); if (DebugLog) { Verbo("Log damage transfer {0} = {1}", newKey, line); } hitMap[newKey] = line; } } catch (Exception ex) { Error(ex); } }
// CLONE OF HBS CODE - LIKELY BRITTLE! public static float CalcCalledShotLocationTargetChance(Mech targetMech, ArmorLocation armorLoc, ChassisLocations chassisLoc) { LocationDamageLevel locationDamageLevel = targetMech.GetLocationDamageLevel(chassisLoc); if (locationDamageLevel == LocationDamageLevel.Destroyed) { return(0f); } float num; if (armorLoc != ArmorLocation.Head) { if (armorLoc != ArmorLocation.CenterTorso) { num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotOtherBaseChance).FloatVal; } else { num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotCenterTorsoBaseChance).FloatVal; } } else { num = AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotHeadBaseChance).FloatVal; } if (locationDamageLevel == LocationDamageLevel.Penalized || locationDamageLevel == LocationDamageLevel.NonFunctional) { num *= AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotDamagedChanceMultiplier).FloatVal; } List <MechComponent> componentsForLocation = targetMech.GetComponentsForLocation(chassisLoc, ComponentType.Weapon); float num2 = 0f; for (int i = 0; i < componentsForLocation.Count; i++) { Weapon weapon = componentsForLocation[i] as Weapon; if (weapon != null && weapon.CanFire) { float num3 = (float)weapon.ShotsWhenFired * weapon.DamagePerShot; num2 += num3; } } return(num + AIHelper.GetBehaviorVariableValue(targetMech.BehaviorTree, BehaviorVariableName.Float_CalledShotWeaponDamageChance).FloatVal *num2); }
// 0-1 == 1-2 = head -> 2 // 2-21 == 3-22 = center torso -> 20 // 22-37 == 23-38 = left torso -> 16 // 38-53 == 39-54 = right torso -> 16 // 54-63 == 55-64 = left arm -> 10 // 64-73 == 65-74 = right arm -> 10 // 74-86 == 75-87 = left leg -> 13 // 87-99 == 88-100 = right leg -> 13 public static ArmorLocation GetRandomMechArmorLocation() { ArmorLocation location = ArmorLocation.CenterTorso; bool isFront = Mod.Random.Next(0, 100) < 80; int locationIdx = Mod.Random.Next(0, 100); if (locationIdx <= 1) { location = ArmorLocation.Head; } else if (locationIdx <= 21) { location = isFront ? ArmorLocation.CenterTorso : ArmorLocation.CenterTorsoRear; } else if (locationIdx <= 37) { location = isFront ? ArmorLocation.LeftTorso : ArmorLocation.LeftTorsoRear; } else if (locationIdx <= 53) { location = isFront ? ArmorLocation.RightTorso : ArmorLocation.RightTorsoRear; } else if (locationIdx <= 63) { location = ArmorLocation.LeftArm; } else if (locationIdx <= 73) { location = ArmorLocation.RightArm; } else if (locationIdx <= 86) { location = ArmorLocation.LeftLeg; } else if (locationIdx <= 99) { location = ArmorLocation.RightLeg; } Mod.Log.Trace?.Write($" - Returning random location: {location}"); return(location); }
public static void FixRearStructureDisplay(HUDMechArmorReadout __instance, AttackDirection shownAttackDirection) { try { HUDMechArmorReadout me = __instance; float[] timeSinceStructureDamaged = (float[])timeSinceStructureDamagedProp.GetValue(me, null); Color[] structureRear = (Color[])structureRearProp.GetValue(me, null); float flashPeriod = 0f; Color flashColour = Color.black; if (LookAndColor == null) { TryRun(() => LookAndColor = HBS.LazySingletonBehavior <UIManager> .Instance.UILookAndColorConstants); } if (LookAndColor != null) { flashPeriod = LookAndColor.FlashArmorTime; flashColour = LookAndColor.ArmorFlash.color; } Dictionary <ArmorLocation, int> dictionary = null; bool mayDisableParts = shownAttackDirection != AttackDirection.None && me.UseForCalledShots; if (mayDisableParts) { dictionary = HUD.Combat.HitLocation.GetMechHitTable(shownAttackDirection, false); } for (int i = 0; i < 8; i++) { float structureFlash = Mathf.Clamp01(1f - timeSinceStructureDamaged[i] / flashPeriod); Color structureColor = structureRear[i]; // The first line that has typo in original code if (mayDisableParts) { ArmorLocation rearLocation = HUDMechArmorReadout.GetArmorLocationFromIndex(i, true, me.flipRearDisplay); bool isIntact = dictionary.ContainsKey(rearLocation) && dictionary[rearLocation] != 0; if (!isIntact) // And the second typo line { structureColor = Color.Lerp(structureColor, Color.black, me.hiddenColorLerp); } } UIHelpers.SetImageColor(me.StructureRear[i], Color.Lerp(structureColor, flashColour, structureFlash)); } } catch (Exception ex) { Error(ex); } }