private bool ValidateAttack(Mech attacker, AbstractActor target, HashSet <MeleeAttackType> validAnimations) { ActorMeleeCondition meleeCondition = ModState.GetMeleeCondition(attacker); if (!meleeCondition.CanPunch()) { Mod.MeleeLog.Info?.Write($"Attacker cannot punch, skipping."); return(false); } // If we cannot punch - not a valid attack if (!validAnimations.Contains(MeleeAttackType.Punch) && !(validAnimations.Contains(MeleeAttackType.Tackle))) { Mod.MeleeLog.Info?.Write("Animations do not include a punch or tackle, attacker cannot punch!"); return(false); } if (target.UnaffectedPathing()) { Mod.MeleeLog.Info?.Write($"Target is unaffected by pathing, likely a VTOL or LAM in flight. Cannot melee it!"); return(false); } // If distance > walkSpeed, disable kick/physical weapon/punch if (!state.HasWalkAttackNodes) { Mod.MeleeLog.Info?.Write($"No walking nodes found for melee attack!"); return(false); } Mod.MeleeLog.Info?.Write("PUNCH ATTACK validated"); return(true); }
public static float PunchInstability(this Mech mech) { ActorMeleeCondition attackerCondition = ModState.GetMeleeCondition(mech); if (!attackerCondition.CanPunch()) { return(0); } // 0 is a signal that there's no divisor float tonnageMulti = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstability) && mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstability) > 0 ? mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstability) : Mod.Config.Melee.Punch.TargetInstabilityPerAttackerTon; float raw = (float)Math.Ceiling(tonnageMulti * mech.tonnage); Mod.MeleeLog.Debug?.Write($"PUNCH instability => tonnageMulti: {tonnageMulti} x attacker tonnage: {mech.tonnage} = raw: {raw}"); // Modifiers float mod = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstabilityMod) ? mech.StatCollection.GetValue <int>(ModStats.PunchTargetInstabilityMod) : 0f; float multi = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetInstabilityMulti) ? mech.StatCollection.GetValue <float>(ModStats.PunchTargetInstabilityMulti) : 1f; // Leg actuator damage float leftReductionMulti = 1f; int damagedLeftCount = 2 - attackerCondition.LeftArmActuatorsCount; for (int i = 0; i < damagedLeftCount; i++) { leftReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction; } Mod.MeleeLog.Debug?.Write($" - Left actuator damage multi is: {leftReductionMulti}"); float rightReductionMulti = 1f; int damagedRightCount = 2 - attackerCondition.RightArmActuatorsCount; for (int i = 0; i < damagedRightCount; i++) { rightReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction; } Mod.MeleeLog.Debug?.Write($" - Right actuator damage multi is: {rightReductionMulti}"); float actuatorMulti = leftReductionMulti >= rightReductionMulti ? leftReductionMulti : rightReductionMulti; Mod.MeleeLog.Debug?.Write($" - Using actuator damage multi of: {actuatorMulti}"); // Roll up instability float final = (float)Math.Ceiling((raw + mod) * multi * actuatorMulti); Mod.MeleeLog.Info?.Write($" - Target instability => final: {final} = (raw: {raw} + mod: {mod}) x " + $"multi: {multi} x actuatorMulti: {actuatorMulti}"); return(final); }
public static float PunchDamage(this Mech mech) { ActorMeleeCondition attackerCondition = ModState.GetMeleeCondition(mech); if (!attackerCondition.CanPunch()) { return(0); } float tonnageMulti = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamage) && mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamage) > 0 ? mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamage) : Mod.Config.Melee.Punch.TargetDamagePerAttackerTon; float raw = (float)Math.Ceiling(tonnageMulti * mech.tonnage); Mod.MeleeLog.Debug?.Write($"PUNCH damage => tonnageMulti: {tonnageMulti} x attacker tonnage: {mech.tonnage} = raw: {raw}"); // Modifiers float mod = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamageMod) ? mech.StatCollection.GetValue <int>(ModStats.PunchTargetDamageMod) : 0f; float multi = mech.StatCollection.ContainsStatistic(ModStats.PunchTargetDamageMulti) ? mech.StatCollection.GetValue <float>(ModStats.PunchTargetDamageMulti) : 1f; // Actuator damage float leftReductionMulti = 1f; int damagedLeftActuators = 2 - attackerCondition.LeftArmActuatorsCount; for (int i = 0; i < damagedLeftActuators; i++) { leftReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction; } Mod.MeleeLog.Debug?.Write($" - Left arm actuator damage is: {leftReductionMulti}"); float rightReductionMulti = 1f; int damagedRightActuators = 2 - attackerCondition.RightArmActuatorsCount; for (int i = 0; i < damagedRightActuators; i++) { rightReductionMulti *= Mod.Config.Melee.Punch.ArmActuatorDamageReduction; } Mod.MeleeLog.Debug?.Write($" - Right arm actuator damage is: {rightReductionMulti}"); float reductionMulti = leftReductionMulti >= rightReductionMulti ? leftReductionMulti : rightReductionMulti; Mod.MeleeLog.Debug?.Write($" - Using arm actuator damage reduction of: {reductionMulti}"); // Roll up final damage float final = (float)Math.Ceiling((raw + mod) * multi * reductionMulti); Mod.MeleeLog.Debug?.Write($" - Target damage per strike => final: {final} = (raw: {raw} + mod: {mod}) x " + $"multi: {multi} x reductionMulti: {reductionMulti}"); return(final); }