using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BitWizrd.PlayerPainSounds.Configuration;
using FistVR;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Player Pain Sounds")]
[assembly: AssemblyDescription("Custom injury and death sounds for H3VR")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BitWizrd")]
[assembly: AssemblyProduct("Player Pain Sounds")]
[assembly: AssemblyCopyright("Copyright © BitWizrd 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a1b2c3d4-e5f6-4a5b-8c7d-9e0f1a2b3c4d")]
[assembly: AssemblyFileVersion("1.0.7.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.7.0")]
[module: UnverifiableCode]
namespace BitWizrd.PlayerPainSounds
{
public static class DamageCalculationHelper
{
public enum DamageType
{
Abstract,
Projectile,
Explosive,
Melee,
Environmental,
Pistol,
Shotgun,
SMGRifle,
Support,
ExplosiveAmmo,
MeleeWeapon,
Trap,
Blunt,
Piercing,
Cutting,
Thermal,
Chilling,
EMP,
Stunning,
Blinding,
Unknown
}
public enum BodyLocation
{
Head,
Torso,
Hand,
Unknown
}
public struct DamageInfo
{
public float TotalDamage;
public float KineticDamage;
public float EnergeticDamage;
public float BluntDamage;
public float PiercingDamage;
public float CuttingDamage;
public float ThermalDamage;
public float ChillingDamage;
public float EMPDamage;
public float StunningDamage;
public float BlindingDamage;
public float PointsDamage;
public float StunDamage;
public float MPa;
public float MPaRootMeter;
public Vector3 Force;
public Vector2 UVCoords;
public DamageType PrimaryType;
public DamageType SecondaryType;
public DamageClass SourceClass;
public DamageType SourceDamageType;
public BodyLocation Location;
public PlayerHitBoxType HitboxType;
public Vector3 ImpactPosition;
public Vector3 HitNormal;
public Vector3 StrikeDirection;
public Vector3 EdgeNormal;
public float DamageSize;
public bool IsInitialContact;
public bool IsInside;
public bool IsMelee;
public bool IsPlayer;
public bool DoesIgnite;
public bool DoesFreeze;
public bool DoesDisrupt;
public int SourceIFF;
public Transform SourceTransform;
public Vector3 SourcePoint;
public Transform ShotOrigin;
public FVRFireArm SourceFirearm;
public bool WouldAffectHealth;
public float HealthBefore;
public float HealthAfter;
public float HealthBeforeRaw;
public float HealthAfterRaw;
public float MaxHealth;
public float DamagePercentage;
public string SeverityCategory;
public bool PlayerHasDamageResist;
public bool PlayerHasDamageMultiplier;
public float PlayerDamageResistValue;
public float PlayerDamageMultiplier;
public bool PlayerIsBlort;
public bool PlayerIsDlort;
public float EffectiveDamageAfterResist;
}
private const float MIN_EFFECTIVE_DAMAGE = 0.1f;
private const float HEALTH_PRECISION_MULTIPLIER = 100f;
private const float HIGH_DAMAGE_THRESHOLD = 0.5f;
private const float LOW_DAMAGE_THRESHOLD = 0.1f;
public static DamageInfo AnalyzeDamage(float damageAmount, FVRPlayerHitbox hitbox, Vector3 impactPosition)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
DamageInfo info = default(DamageInfo);
info.TotalDamage = damageAmount;
info.KineticDamage = damageAmount;
info.EnergeticDamage = 0f;
info.BluntDamage = damageAmount;
info.PrimaryType = DamageType.Blunt;
info.SourceClass = (DamageClass)0;
info.SourceDamageType = (DamageType)0;
info.HitboxType = hitbox.Type;
info.Location = ConvertHitboxToBodyLocation(hitbox.Type);
info.ImpactPosition = impactPosition;
info.IsInitialContact = true;
CalculatePlayerStateFactors(ref info);
CalculateHealthImpact(ref info);
info.SeverityCategory = CategorizeDamageSeverity(info.DamagePercentage);
LogDamageAnalysis(info);
return info;
}
public static DamageInfo AnalyzeDamage(Damage damageObj, FVRPlayerHitbox hitbox, Vector3 impactPosition)
{
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
DamageInfo info = default(DamageInfo);
info.BluntDamage = damageObj.Dam_Blunt;
info.PiercingDamage = damageObj.Dam_Piercing;
info.CuttingDamage = damageObj.Dam_Cutting;
info.KineticDamage = damageObj.Dam_TotalKinetic;
info.ThermalDamage = damageObj.Dam_Thermal;
info.ChillingDamage = damageObj.Dam_Chilling;
info.EMPDamage = damageObj.Dam_EMP;
info.EnergeticDamage = damageObj.Dam_TotalEnergetic;
info.StunningDamage = damageObj.Dam_Stunning;
info.BlindingDamage = damageObj.Dam_Blinding;
info.TotalDamage = info.KineticDamage + info.EnergeticDamage;
info.SourceClass = damageObj.Class;
info.PrimaryType = DeterminePrimaryDamageType(damageObj);
info.SecondaryType = DetermineSecondaryDamageType(damageObj);
info.HitboxType = hitbox.Type;
info.Location = ConvertHitboxToBodyLocation(hitbox.Type);
info.ImpactPosition = impactPosition;
info.HitNormal = damageObj.hitNormal;
info.StrikeDirection = damageObj.strikeDir;
info.EdgeNormal = damageObj.edgeNormal;
info.DamageSize = damageObj.damageSize;
info.IsInitialContact = true;
info.SourceIFF = damageObj.Source_IFF;
info.SourceTransform = damageObj.Source_Transform;
info.SourcePoint = damageObj.Source_Point;
CalculatePlayerStateFactors(ref info);
CalculateHealthImpact(ref info);
info.SeverityCategory = CategorizeDamageSeverity(info.DamagePercentage);
LogDamageAnalysis(info);
return info;
}
public static DamageInfo AnalyzeDamage(DamageDealt damageDealt, FVRPlayerHitbox hitbox, Vector3 impactPosition)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
DamageInfo info = default(DamageInfo);
info.PointsDamage = damageDealt.PointsDamage;
info.StunDamage = damageDealt.StunDamage;
info.MPa = damageDealt.MPa;
info.MPaRootMeter = damageDealt.MPaRootMeter;
info.Force = damageDealt.force;
info.UVCoords = damageDealt.uvCoords;
info.TotalDamage = damageDealt.PointsDamage;
info.KineticDamage = damageDealt.PointsDamage;
info.EnergeticDamage = 0f;
info.SourceDamageType = damageDealt.Type;
info.PrimaryType = ConvertDamageDealtTypeToDamageType(damageDealt.Type);
if (damageDealt.IsMelee)
{
info.SecondaryType = DamageType.MeleeWeapon;
}
info.HitboxType = hitbox.Type;
info.Location = ConvertHitboxToBodyLocation(hitbox.Type);
info.ImpactPosition = impactPosition;
info.HitNormal = damageDealt.hitNormal;
info.StrikeDirection = damageDealt.strikeDir;
info.IsInitialContact = damageDealt.IsInitialContact;
info.IsInside = damageDealt.IsInside;
info.IsMelee = damageDealt.IsMelee;
info.IsPlayer = damageDealt.IsPlayer;
info.DoesIgnite = damageDealt.DoesIgnite;
info.DoesFreeze = damageDealt.DoesFreeze;
info.DoesDisrupt = damageDealt.DoesDisrupt;
info.ShotOrigin = damageDealt.ShotOrigin;
info.SourceFirearm = damageDealt.SourceFirearm;
CalculatePlayerStateFactors(ref info);
CalculateHealthImpact(ref info);
info.SeverityCategory = CategorizeDamageSeverity(info.DamagePercentage);
LogDamageAnalysis(info);
return info;
}
public static bool WouldDamageAffectHealth(float damageAmount)
{
if (damageAmount <= 0f)
{
return false;
}
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
return false;
}
float health = GM.CurrentPlayerBody.Health;
float num = health - damageAmount;
int num2 = (int)health;
int num3 = (int)num;
bool flag = num2 != num3;
if (PlayerPainSoundsPlugin.configDebugMessages.Value)
{
PlayerPainSoundsPlugin.LogInfo($"H3VR Health Impact: damage={damageAmount}, rawHealth: {health:F4} -> {num:F4}, truncated: {num2} -> {num3}, affects={flag}");
}
return flag;
}
public static bool WouldDamageAffectHealth(DamageInfo damageInfo)
{
return WouldDamageAffectHealth((damageInfo.EffectiveDamageAfterResist > 0f) ? damageInfo.EffectiveDamageAfterResist : damageInfo.TotalDamage);
}
public static bool ShouldTriggerPainSound(DamageInfo damageInfo)
{
if (damageInfo.TotalDamage <= 0f)
{
return false;
}
if (!damageInfo.IsInitialContact)
{
return false;
}
if (!WouldPassH3VRHitboxThreshold(damageInfo))
{
return false;
}
if (!damageInfo.WouldAffectHealth)
{
return false;
}
return true;
}
private static bool WouldPassH3VRHitboxThreshold(DamageInfo damageInfo)
{
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
return false;
}
float num = damageInfo.TotalDamage;
if (GM.CurrentPlayerBody.IsBlort && damageInfo.EnergeticDamage > 0f)
{
num = damageInfo.KineticDamage;
}
else if (GM.CurrentPlayerBody.IsDlort && damageInfo.EnergeticDamage > 0f)
{
num = damageInfo.KineticDamage + damageInfo.EnergeticDamage * 3f;
}
float num2 = 1f;
float num3 = 1f;
if (GM.CurrentPlayerBody.IsDamResist)
{
num2 = GM.CurrentPlayerBody.GetDamageResist();
}
if (GM.CurrentPlayerBody.IsDamMult)
{
num3 = GM.CurrentPlayerBody.GetDamageMult();
}
if (num2 <= 0.01f)
{
return false;
}
num *= num2;
num *= num3;
bool flag = num > 0.1f;
if (PlayerPainSoundsPlugin.configDebugMessages.Value)
{
PlayerPainSoundsPlugin.LogInfo($"H3VR Hitbox Threshold Check: original={damageInfo.TotalDamage}, processed={num}, passes={flag}");
}
return flag;
}
public static string GetSoundCategoryForDamage(DamageInfo damageInfo)
{
if (damageInfo.DamagePercentage >= 0.5f)
{
return "pain_high";
}
if (damageInfo.DamagePercentage <= 0.1f)
{
return "pain_low";
}
return "pain_default";
}
private static BodyLocation ConvertHitboxToBodyLocation(PlayerHitBoxType hitboxType)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected I4, but got Unknown
return (int)hitboxType switch
{
0 => BodyLocation.Head,
1 => BodyLocation.Torso,
2 => BodyLocation.Hand,
_ => BodyLocation.Unknown,
};
}
private static void CalculatePlayerStateFactors(ref DamageInfo info)
{
if (!((Object)(object)GM.CurrentPlayerBody == (Object)null))
{
info.PlayerHasDamageResist = GM.CurrentPlayerBody.IsDamResist || GM.CurrentPlayerBody.IsDamMult;
info.PlayerHasDamageMultiplier = GM.CurrentPlayerBody.IsDamMult || GM.CurrentPlayerBody.isDamPowerUp;
info.PlayerIsBlort = GM.CurrentPlayerBody.IsBlort;
info.PlayerIsDlort = GM.CurrentPlayerBody.IsDlort;
if (info.PlayerHasDamageResist)
{
info.PlayerDamageResistValue = GM.CurrentPlayerBody.GetDamageResist();
}
else
{
info.PlayerDamageResistValue = 1f;
}
if (info.PlayerHasDamageMultiplier)
{
info.PlayerDamageMultiplier = GM.CurrentPlayerBody.GetDamageMult();
}
else
{
info.PlayerDamageMultiplier = 1f;
}
float num = info.TotalDamage;
if (info.PlayerIsBlort && info.EnergeticDamage > 0f)
{
num = info.KineticDamage;
}
else if (info.PlayerIsDlort && info.EnergeticDamage > 0f)
{
num = info.KineticDamage + info.EnergeticDamage * 3f;
}
num = ((!(info.PlayerDamageResistValue <= 0.01f)) ? (num * info.PlayerDamageResistValue) : 0f);
if (info.PlayerDamageMultiplier != 0f)
{
num *= info.PlayerDamageMultiplier;
}
info.EffectiveDamageAfterResist = num;
}
}
private static void CalculateHealthImpact(ref DamageInfo info)
{
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
info.WouldAffectHealth = false;
info.HealthBefore = 0f;
info.HealthAfter = 0f;
info.HealthBeforeRaw = 0f;
info.HealthAfterRaw = 0f;
info.MaxHealth = 0f;
info.DamagePercentage = 0f;
return;
}
float health = GM.CurrentPlayerBody.Health;
float num = GM.CurrentPlayerBody.GetMaxHealthPlayerRaw();
float num2 = ((info.EffectiveDamageAfterResist > 0f) ? info.EffectiveDamageAfterResist : info.TotalDamage);
float num3 = health - num2;
info.HealthBeforeRaw = health;
info.HealthAfterRaw = num3;
info.MaxHealth = num;
info.HealthBefore = GM.CurrentPlayerBody.GetPlayerHealth();
info.HealthAfter = num3 / num;
if (num > 0f)
{
info.DamagePercentage = num2 / num;
}
else
{
info.DamagePercentage = 0f;
}
info.WouldAffectHealth = WouldDamageAffectHealth(info);
}
private static string CategorizeDamageSeverity(float damagePercentage)
{
if (damagePercentage >= 0.5f)
{
return "High";
}
if (damagePercentage <= 0.1f)
{
return "Low";
}
return "Medium";
}
private static DamageType DeterminePrimaryDamageType(Damage damageObj)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected I4, but got Unknown
DamageClass @class = damageObj.Class;
switch (@class - 1)
{
case 0:
return DamageType.Projectile;
case 1:
return DamageType.Explosive;
case 2:
return DamageType.Melee;
case 3:
return DamageType.Environmental;
default:
{
float num = 0f;
DamageType result = DamageType.Unknown;
if (damageObj.Dam_Blunt > num)
{
num = damageObj.Dam_Blunt;
result = DamageType.Blunt;
}
if (damageObj.Dam_Piercing > num)
{
num = damageObj.Dam_Piercing;
result = DamageType.Piercing;
}
if (damageObj.Dam_Cutting > num)
{
num = damageObj.Dam_Cutting;
result = DamageType.Cutting;
}
if (damageObj.Dam_Thermal > num)
{
num = damageObj.Dam_Thermal;
result = DamageType.Thermal;
}
if (damageObj.Dam_Chilling > num)
{
num = damageObj.Dam_Chilling;
result = DamageType.Chilling;
}
if (damageObj.Dam_EMP > num)
{
num = damageObj.Dam_EMP;
result = DamageType.EMP;
}
if (damageObj.Dam_Stunning > num)
{
num = damageObj.Dam_Stunning;
result = DamageType.Stunning;
}
if (damageObj.Dam_Blinding > num)
{
num = damageObj.Dam_Blinding;
result = DamageType.Blinding;
}
return result;
}
}
}
private static DamageType DetermineSecondaryDamageType(Damage damageObj)
{
float[] array = new float[8] { damageObj.Dam_Blunt, damageObj.Dam_Piercing, damageObj.Dam_Cutting, damageObj.Dam_Thermal, damageObj.Dam_Chilling, damageObj.Dam_EMP, damageObj.Dam_Stunning, damageObj.Dam_Blinding };
DamageType[] array2 = new DamageType[8]
{
DamageType.Blunt,
DamageType.Piercing,
DamageType.Cutting,
DamageType.Thermal,
DamageType.Chilling,
DamageType.EMP,
DamageType.Stunning,
DamageType.Blinding
};
float num = 0f;
float num2 = 0f;
int num3 = -1;
int num4 = -1;
for (int i = 0; i < array.Length; i++)
{
if (array[i] > num)
{
num2 = num;
num4 = num3;
num = array[i];
num3 = i;
}
else if (array[i] > num2)
{
num2 = array[i];
num4 = i;
}
}
if (num4 < 0)
{
return DamageType.Unknown;
}
return array2[num4];
}
private static DamageType ConvertDamageDealtTypeToDamageType(DamageType sourceType)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Expected I4, but got Unknown
return (sourceType - 1) switch
{
0 => DamageType.Pistol,
1 => DamageType.Shotgun,
2 => DamageType.SMGRifle,
3 => DamageType.Support,
4 => DamageType.ExplosiveAmmo,
5 => DamageType.MeleeWeapon,
6 => DamageType.Trap,
_ => DamageType.Unknown,
};
}
private static void LogDamageAnalysis(DamageInfo info)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
if (PlayerPainSoundsPlugin.configDebugMessages.Value)
{
PlayerPainSoundsPlugin.LogInfo($"=== Damage Analysis ===");
PlayerPainSoundsPlugin.LogInfo($"Total: {info.TotalDamage:F2} damage to {info.Location} ({info.HitboxType})");
PlayerPainSoundsPlugin.LogInfo($"Breakdown - K:{info.KineticDamage:F2}, E:{info.EnergeticDamage:F2} | Blunt:{info.BluntDamage:F2}, Pierce:{info.PiercingDamage:F2}, Cut:{info.CuttingDamage:F2}");
PlayerPainSoundsPlugin.LogInfo($"Energetic - Thermal:{info.ThermalDamage:F2}, Chill:{info.ChillingDamage:F2}, EMP:{info.EMPDamage:F2}");
PlayerPainSoundsPlugin.LogInfo($"Special - Stun:{info.StunningDamage:F2}, Blind:{info.BlindingDamage:F2}");
PlayerPainSoundsPlugin.LogInfo($"Type: {info.PrimaryType} / {info.SecondaryType} | Class: {info.SourceClass} | Source: {info.SourceDamageType}");
PlayerPainSoundsPlugin.LogInfo($"Health: {info.HealthBeforeRaw:F0} -> {info.HealthAfterRaw:F0} ({info.DamagePercentage * 100f:F1}% of {info.MaxHealth:F0})");
PlayerPainSoundsPlugin.LogInfo($"Player State - Resist:{info.PlayerDamageResistValue:F2}, Mult:{info.PlayerDamageMultiplier:F2}, Blort:{info.PlayerIsBlort}, Dlort:{info.PlayerIsDlort}");
PlayerPainSoundsPlugin.LogInfo($"Effective Damage: {info.EffectiveDamageAfterResist:F2} | Affects Health: {info.WouldAffectHealth} | Category: {GetSoundCategoryForDamage(info)}");
PlayerPainSoundsPlugin.LogInfo($"========================");
}
}
public static float ApplyLocationMultiplier(float baseDamage, BodyLocation location, DamageInfo damageInfo)
{
switch (location)
{
case BodyLocation.Head:
return baseDamage * 1f;
case BodyLocation.Torso:
return baseDamage * 1f;
case BodyLocation.Hand:
if ((Object)(object)damageInfo.SourceFirearm != (Object)null)
{
return 0f;
}
return baseDamage * 1f;
default:
return baseDamage;
}
}
public static float CalculateDamageReduction(DamageInfo damageInfo)
{
return 0f;
}
public static DamageInfo ProcessEnvironmentalDamage(float damage, Vector3 position, DamageType environmentType)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
DamageInfo result = default(DamageInfo);
result.TotalDamage = damage;
result.PrimaryType = environmentType;
result.ImpactPosition = position;
return result;
}
public static string GetImpactSoundCategory(Damage damage)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Invalid comparison between Unknown and I4
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Invalid comparison between Unknown and I4
if (damage == null)
{
return "impact_default";
}
if ((int)damage.Class == 1)
{
return "impact_bullet";
}
if ((int)damage.Class == 2)
{
return "impact_default";
}
if (damage.Dam_Cutting > 0f || damage.Dam_Piercing > 0f)
{
return "impact_default";
}
if (damage.Dam_Blunt > 0f)
{
return "impact_default";
}
_ = damage.Dam_Thermal;
_ = 0f;
return "impact_default";
}
public static string GetImpactSoundCategory(PlayerHitBoxType hitboxType, float damageAmount)
{
_ = 50f;
return "impact_default";
}
}
public class InjurySoundManager : MonoBehaviour
{
[CompilerGenerated]
private sealed class <>c__DisplayClass100_0
{
public string packName;
internal bool <LoadSinglePackAndSwitch>b__0(OuchPackInfo p)
{
return p.Name == packName;
}
}
[CompilerGenerated]
private sealed class <LoadCustomSoundPacks>d__97 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
private List<OuchPackInfo>.Enumerator <>7__wrap1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadCustomSoundPacks>d__97(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = default(List<OuchPackInfo>.Enumerator);
<>1__state = -2;
}
private bool MoveNext()
{
try
{
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = PlayerPainSoundsPlugin.DiscoveredOuchPacks.GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
break;
}
if (<>7__wrap1.MoveNext())
{
OuchPackInfo current = <>7__wrap1.Current;
string name = current.Name;
string path = current.Path;
injurySoundManager.InitializePackDictionaries(name);
injurySoundManager.injurySounds[name].Clear();
injurySoundManager.deathSounds[name].Clear();
injurySoundManager.availableCategories[name].Clear();
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSoundPackCategories(name, path));
<>1__state = 1;
return true;
}
<>m__Finally1();
<>7__wrap1 = default(List<OuchPackInfo>.Enumerator);
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>7__wrap1).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadSinglePackAndSwitch>d__100 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string packName;
public InjurySoundManager <>4__this;
private <>c__DisplayClass100_0 <>8__1;
private string <packPath>5__2;
private Dictionary<string, List<AudioClip>> <packInjurySounds>5__3;
private Dictionary<string, List<AudioClip>> <packDeathSounds>5__4;
private Dictionary<string, List<AudioClip>> <packImpactSounds>5__5;
private string[] <>7__wrap5;
private int <>7__wrap6;
private string <category>5__8;
private List<AudioClip> <clips>5__9;
private string[] <>7__wrap9;
private int <>7__wrap10;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadSinglePackAndSwitch>d__100(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>8__1 = null;
<packPath>5__2 = null;
<packInjurySounds>5__3 = null;
<packDeathSounds>5__4 = null;
<packImpactSounds>5__5 = null;
<>7__wrap5 = null;
<category>5__8 = null;
<clips>5__9 = null;
<>7__wrap9 = null;
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
<>7__wrap10++;
goto IL_01ee;
}
<>1__state = -1;
<>8__1 = new <>c__DisplayClass100_0();
<>8__1.packName = packName;
OuchPackInfo ouchPackInfo = PlayerPainSoundsPlugin.DiscoveredOuchPacks.FirstOrDefault((OuchPackInfo p) => p.Name == <>8__1.packName);
if (ouchPackInfo == null)
{
PlayerPainSoundsPlugin.LogError("Pack not found: " + <>8__1.packName);
injurySoundManager.currentSoundPack = "Default";
injurySoundManager.ClearLoadedSounds();
injurySoundManager.LoadDefaultSounds();
PlayerPainSoundsPlugin.LogInfo("Fell back to Default sound pack");
return false;
}
<packPath>5__2 = ouchPackInfo.Path;
if (string.IsNullOrEmpty(<packPath>5__2) || !Directory.Exists(<packPath>5__2))
{
PlayerPainSoundsPlugin.LogError("Invalid pack path: " + <packPath>5__2);
injurySoundManager.currentSoundPack = "Default";
injurySoundManager.ClearLoadedSounds();
injurySoundManager.LoadDefaultSounds();
PlayerPainSoundsPlugin.LogInfo("Fell back to Default sound pack due to invalid path");
return false;
}
PlayerPainSoundsPlugin.LogInfo("Loading sound pack from path: " + <packPath>5__2);
<packInjurySounds>5__3 = new Dictionary<string, List<AudioClip>>();
<packDeathSounds>5__4 = new Dictionary<string, List<AudioClip>>();
<packImpactSounds>5__5 = new Dictionary<string, List<AudioClip>>();
<>7__wrap5 = SoundCategories.ALL_CATEGORIES;
<>7__wrap6 = 0;
goto IL_032c;
IL_0317:
<category>5__8 = null;
<>7__wrap6++;
goto IL_032c;
IL_032c:
if (<>7__wrap6 < <>7__wrap5.Length)
{
<category>5__8 = <>7__wrap5[<>7__wrap6];
string path = Path.Combine(<packPath>5__2, <category>5__8);
if (Directory.Exists(path))
{
<clips>5__9 = new List<AudioClip>();
string[] files = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
<>7__wrap9 = files;
<>7__wrap10 = 0;
goto IL_01ee;
}
goto IL_0317;
}
<>7__wrap5 = null;
bool flag = false;
injurySoundManager.InitializePackDictionaries(<>8__1.packName);
if (<packInjurySounds>5__3.Count > 0)
{
injurySoundManager.injurySounds[<>8__1.packName] = <packInjurySounds>5__3;
foreach (string key in <packInjurySounds>5__3.Keys)
{
injurySoundManager.availableCategories[<>8__1.packName].Add(key);
}
flag = true;
}
if (<packDeathSounds>5__4.Count > 0)
{
injurySoundManager.deathSounds[<>8__1.packName] = <packDeathSounds>5__4;
foreach (string key2 in <packDeathSounds>5__4.Keys)
{
injurySoundManager.availableCategories[<>8__1.packName].Add(key2);
}
flag = true;
}
if (<packImpactSounds>5__5.Count > 0)
{
injurySoundManager.impactSounds[<>8__1.packName] = <packImpactSounds>5__5;
foreach (string key3 in <packImpactSounds>5__5.Keys)
{
injurySoundManager.availableCategories[<>8__1.packName].Add(key3);
}
flag = true;
}
if (!flag)
{
PlayerPainSoundsPlugin.LogWarning("No sounds found in pack: " + <>8__1.packName);
injurySoundManager.currentSoundPack = "Default";
injurySoundManager.ClearLoadedSounds();
injurySoundManager.LoadDefaultSounds();
PlayerPainSoundsPlugin.LogInfo("Fell back to Default sound pack due to no sounds found");
}
else
{
injurySoundManager.currentSoundPack = <>8__1.packName;
PlayerPainSoundsPlugin.LogInfo("Successfully loaded sound pack: " + <>8__1.packName);
}
if (injurySoundManager.hasInitialized && injurySoundManager.isInLastStand)
{
injurySoundManager.PlayerStateCheck();
}
return false;
IL_01ee:
if (<>7__wrap10 < <>7__wrap9.Length)
{
string file = <>7__wrap9[<>7__wrap10];
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSoundFile(file, <clips>5__9, <category>5__8));
<>1__state = 1;
return true;
}
<>7__wrap9 = null;
if (<clips>5__9.Count > 0)
{
if (<category>5__8 == "death")
{
<packDeathSounds>5__4[<category>5__8] = <clips>5__9;
PlayerPainSoundsPlugin.LogInfo("Loaded " + <clips>5__9.Count + " death sounds for category: " + <category>5__8);
}
else if (SoundCategories.IS_IMPACT_CATEGORY[<category>5__8])
{
<packImpactSounds>5__5[<category>5__8] = <clips>5__9;
PlayerPainSoundsPlugin.LogInfo("Loaded " + <clips>5__9.Count + " impact sounds for category: " + <category>5__8);
}
else
{
<packInjurySounds>5__3[<category>5__8] = <clips>5__9;
PlayerPainSoundsPlugin.LogInfo("Loaded " + <clips>5__9.Count + " injury sounds for category: " + <category>5__8);
}
}
<clips>5__9 = null;
goto IL_0317;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadSoundFile>d__136 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string file;
public List<AudioClip> clips;
public string category;
private string <fileUrl>5__2;
private WWW <www>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadSoundFile>d__136(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<fileUrl>5__2 = null;
<www>5__3 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
if (string.IsNullOrEmpty(file) || clips == null)
{
PlayerPainSoundsPlugin.LogError("Invalid parameters passed to LoadSoundFile");
return false;
}
string text = Path.GetExtension(file).ToLower();
if (ConfigurationConstants.IsSupportedAudioFormat(text))
{
<fileUrl>5__2 = "file:///" + file.Replace("\\", "/");
PlayerPainSoundsPlugin.LogInfo("Loading sound file: " + <fileUrl>5__2);
<www>5__3 = null;
<www>5__3 = new WWW(<fileUrl>5__2);
<>2__current = <www>5__3;
<>1__state = 1;
return true;
}
PlayerPainSoundsPlugin.LogWarning("Unsupported audio file format: " + text + " - File: " + file);
break;
}
case 1:
<>1__state = -1;
try
{
if (!string.IsNullOrEmpty(<www>5__3.error))
{
PlayerPainSoundsPlugin.LogError("Error loading sound file: " + <fileUrl>5__2 + " - " + <www>5__3.error);
return false;
}
AudioClip audioClip = WWWAudioExtensions.GetAudioClip(<www>5__3, false, false);
if ((Object)(object)audioClip != (Object)null)
{
((Object)audioClip).name = Path.GetFileNameWithoutExtension(file);
clips.Add(audioClip);
PlayerPainSoundsPlugin.LogInfo("Successfully loaded sound: " + ((Object)audioClip).name + " for category: " + category);
}
else
{
PlayerPainSoundsPlugin.LogError("Failed to create AudioClip from: " + <fileUrl>5__2);
}
}
catch (Exception ex)
{
PlayerPainSoundsPlugin.LogError("Exception in LoadSoundFile: " + ex.Message);
}
finally
{
if (<www>5__3 != null)
{
<www>5__3.Dispose();
}
}
<fileUrl>5__2 = null;
<www>5__3 = null;
break;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <LoadSoundPackCategories>d__99 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string packPath;
public InjurySoundManager <>4__this;
public string packName;
private string[] <>7__wrap1;
private int <>7__wrap2;
private string <category>5__4;
private bool <hasValidSounds>5__5;
private string[] <>7__wrap5;
private int <>7__wrap6;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <LoadSoundPackCategories>d__99(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>7__wrap1 = null;
<category>5__4 = null;
<>7__wrap5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = SoundCategories.ALL_CATEGORIES;
<>7__wrap2 = 0;
goto IL_0303;
case 1:
<>1__state = -1;
goto IL_02a1;
case 2:
<>1__state = -1;
goto IL_02a1;
case 3:
{
<>1__state = -1;
goto IL_02a1;
}
IL_0303:
if (<>7__wrap2 < <>7__wrap1.Length)
{
<category>5__4 = <>7__wrap1[<>7__wrap2];
string path = Path.Combine(packPath, <category>5__4);
if (Directory.Exists(path))
{
string[] files = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
<hasValidSounds>5__5 = false;
<>7__wrap5 = files;
<>7__wrap6 = 0;
goto IL_02af;
}
goto IL_02ee;
}
<>7__wrap1 = null;
PlayerPainSoundsPlugin.LogInfo(string.Format("Loaded pack '{0}' with categories: {1}", packName, string.Join(", ", injurySoundManager.availableCategories[packName].ToArray())));
return false;
IL_02ee:
<category>5__4 = null;
<>7__wrap2++;
goto IL_0303;
IL_02a1:
<>7__wrap6++;
goto IL_02af;
IL_02af:
if (<>7__wrap6 < <>7__wrap5.Length)
{
string text = <>7__wrap5[<>7__wrap6];
string text2 = Path.GetExtension(text).ToLower();
if (text2 == ".wav" || text2 == ".ogg")
{
<hasValidSounds>5__5 = true;
if (<category>5__4 == "death")
{
if (!injurySoundManager.deathSounds[packName].ContainsKey(<category>5__4))
{
injurySoundManager.deathSounds[packName][<category>5__4] = new List<AudioClip>();
}
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSoundFile(text, injurySoundManager.deathSounds[packName][<category>5__4], <category>5__4));
<>1__state = 1;
return true;
}
if (SoundCategories.IS_IMPACT_CATEGORY[<category>5__4])
{
if (!injurySoundManager.impactSounds[packName].ContainsKey(<category>5__4))
{
injurySoundManager.impactSounds[packName][<category>5__4] = new List<AudioClip>();
}
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSoundFile(text, injurySoundManager.impactSounds[packName][<category>5__4], <category>5__4));
<>1__state = 2;
return true;
}
if (!injurySoundManager.injurySounds[packName].ContainsKey(<category>5__4))
{
injurySoundManager.injurySounds[packName][<category>5__4] = new List<AudioClip>();
}
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSoundFile(text, injurySoundManager.injurySounds[packName][<category>5__4], <category>5__4));
<>1__state = 3;
return true;
}
goto IL_02a1;
}
<>7__wrap5 = null;
if (<hasValidSounds>5__5)
{
injurySoundManager.availableCategories[packName].Add(<category>5__4);
}
goto IL_02ee;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <PlayCriticalHealthSoundWithDelay>d__88 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayCriticalHealthSoundWithDelay>d__88(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
case 1:
{
<>1__state = -1;
if (!injurySoundManager.isCriticalHealthEnabled || (Object)(object)injurySoundManager.audioSource == (Object)null || injurySoundManager.isDying)
{
return false;
}
AudioClip val = null;
if (injurySoundManager.currentSoundPack == "Default")
{
val = injurySoundManager.GetDefaultCriticalHealthSound();
}
else if (injurySoundManager.injurySounds.ContainsKey(injurySoundManager.currentSoundPack) && injurySoundManager.injurySounds[injurySoundManager.currentSoundPack].ContainsKey("critical_health") && injurySoundManager.injurySounds[injurySoundManager.currentSoundPack]["critical_health"].Count > 0)
{
List<AudioClip> sounds = injurySoundManager.injurySounds[injurySoundManager.currentSoundPack]["critical_health"];
val = injurySoundManager.GetUniqueRandomSound("critical_health", sounds);
}
if ((Object)(object)val == (Object)null)
{
PlayerPainSoundsPlugin.LogInfo("No critical health sound available");
return false;
}
float num2 = 1f * injurySoundManager.GetVolumeMultiplier();
injurySoundManager.audioSource2D.pitch = 1f;
injurySoundManager.audioSource2D.PlayOneShot(val, num2);
PlayerPainSoundsPlugin.LogInfo("Playing critical health sound");
return false;
}
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <PlayInjuryClipsWithDelay>d__123 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float delay;
public InjurySoundManager <>4__this;
public Vector3 headPosition;
public float pitch;
public AudioClip clip;
public float spatialVolume;
public float volume2D;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayInjuryClipsWithDelay>d__123(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
if (delay > 0f)
{
<>2__current = (object)new WaitForSeconds(delay);
<>1__state = 1;
return true;
}
break;
case 1:
<>1__state = -1;
break;
}
((Component)injurySoundManager.audioSource).transform.position = headPosition;
injurySoundManager.audioSource.pitch = pitch;
injurySoundManager.audioSource2D.pitch = pitch;
injurySoundManager.audioSource.PlayOneShot(clip, spatialVolume);
injurySoundManager.audioSource2D.PlayOneShot(clip, volume2D);
injurySoundManager.lastInjurySoundTime = Time.time;
injurySoundManager.lastPlayedInjuryClip = clip;
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
string text = delay.ToString();
Vector3 val = headPosition;
PlayerPainSoundsPlugin.LogInfo("Playing injury sound with delay " + text + " seconds at head position: " + ((object)(Vector3)(ref val)).ToString());
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <PlayPainAndDeathSequence>d__129 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
public AudioClip deathSound;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayPainAndDeathSequence>d__129(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Expected O, but got Unknown
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
{
<>1__state = -1;
Vector3 position = GM.CurrentPlayerBody.Head.position;
AudioClip appropriateSound = injurySoundManager.GetAppropriateSound();
if ((Object)(object)appropriateSound != (Object)null)
{
float num2 = 1f * injurySoundManager.GetVolumeMultiplier();
((Component)injurySoundManager.audioSource).transform.position = position;
injurySoundManager.audioSource.spatialBlend = 1f;
float num3 = num2 * 0.2f;
injurySoundManager.audioSource.PlayOneShot(appropriateSound, num3);
injurySoundManager.audioSource2D.PlayOneShot(appropriateSound, num2);
PlayerPainSoundsPlugin.LogInfo($"Playing pain sound before death at head position: {position}");
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 1;
return true;
}
break;
}
case 1:
<>1__state = -1;
break;
}
if ((Object)(object)deathSound != (Object)null)
{
Vector3 position = GM.CurrentPlayerBody.Head.position;
float num4 = 1f * injurySoundManager.GetVolumeMultiplier();
((Component)injurySoundManager.audioSource).transform.position = position;
injurySoundManager.audioSource.spatialBlend = 1f;
float num5 = num4 * 0.2f;
injurySoundManager.audioSource.PlayOneShot(deathSound, num5);
injurySoundManager.audioSource2D.PlayOneShot(deathSound, num4);
PlayerPainSoundsPlugin.LogInfo($"Playing death sound after pain at head position: {position}");
((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.ResetStateAfterDeathSound());
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <ResetStateAfterDeathSound>d__135 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ResetStateAfterDeathSound>d__135(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
injurySoundManager.isDying = false;
injurySoundManager.m_hasPlayedDeathSound = false;
if (PlayerPainSoundsPlugin.IsManagerReady())
{
injurySoundManager.PlayerStateCheck();
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <StartLoadingSoundPacks>d__92 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <StartLoadingSoundPacks>d__92(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
<>1__state = -1;
injurySoundManager.isLoading = true;
injurySoundManager.LoadDefaultSounds();
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadCustomSoundPacks());
<>1__state = 1;
return true;
case 1:
{
<>1__state = -1;
string value = PlayerPainSoundsPlugin.configInjurySoundPack.Value;
injurySoundManager.SetSoundPack(value);
injurySoundManager.isLoading = false;
return false;
}
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <TransitionLastStandSound>d__96 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public InjurySoundManager <>4__this;
public string newPackName;
private bool <wasInLastStand>5__2;
private bool <shouldBeInLastStand>5__3;
private float <startVolume>5__4;
private float <fadeStartTime>5__5;
private float <fadeDuration>5__6;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TransitionLastStandSound>d__96(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_0290: Expected O, but got Unknown
int num = <>1__state;
InjurySoundManager injurySoundManager = <>4__this;
switch (num)
{
default:
return false;
case 0:
{
<>1__state = -1;
injurySoundManager.isTransitioningPacks = true;
<wasInLastStand>5__2 = injurySoundManager.isInLastStand;
PlayerPainSoundsPlugin.LogInfo("Starting transition to sound pack: " + newPackName + " (was in last stand: " + <wasInLastStand>5__2 + ")");
float num2 = GM.CurrentPlayerBody.GetPlayerHealthRaw();
float num3 = GM.CurrentPlayerBody.GetMaxHealthPlayerRaw();
float num4 = num2 / num3;
<shouldBeInLastStand>5__3 = num4 <= injurySoundManager.lastStandThreshold && injurySoundManager.isLastStandEnabled;
if (<wasInLastStand>5__2 && (Object)(object)injurySoundManager.lastStandAudioSource != (Object)null && injurySoundManager.lastStandAudioSource.isPlaying)
{
<startVolume>5__4 = injurySoundManager.lastStandAudioSource.volume;
<fadeStartTime>5__5 = Time.time;
<fadeDuration>5__6 = 0.5f;
PlayerPainSoundsPlugin.LogInfo("Fading out last stand sound");
goto IL_0159;
}
goto IL_0184;
}
case 1:
<>1__state = -1;
goto IL_0159;
case 2:
<>1__state = -1;
PlayerPainSoundsPlugin.LogInfo("Finished loading sounds for pack: " + newPackName);
goto IL_026a;
case 3:
{
<>1__state = -1;
injurySoundManager.StartLastStandSound();
PlayerPainSoundsPlugin.LogInfo("Restarted last stand with new sound pack");
break;
}
IL_0184:
if (newPackName == "Default")
{
injurySoundManager.currentSoundPack = "Default";
injurySoundManager.ClearLoadedSounds();
injurySoundManager.LoadDefaultSounds();
PlayerPainSoundsPlugin.LogInfo("Transitioned to Default sound pack");
}
else
{
if (!injurySoundManager.injurySounds.ContainsKey(newPackName) || !injurySoundManager.deathSounds.ContainsKey(newPackName) || !injurySoundManager.availableCategories.ContainsKey(newPackName))
{
PlayerPainSoundsPlugin.LogInfo("Loading sounds for pack: " + newPackName);
<>2__current = ((MonoBehaviour)injurySoundManager).StartCoroutine(injurySoundManager.LoadSinglePackAndSwitch(newPackName));
<>1__state = 2;
return true;
}
injurySoundManager.currentSoundPack = newPackName;
PlayerPainSoundsPlugin.LogInfo("Transitioned to sound pack: " + newPackName);
}
goto IL_026a;
IL_0159:
if (Time.time < <fadeStartTime>5__5 + <fadeDuration>5__6)
{
float num5 = (Time.time - <fadeStartTime>5__5) / <fadeDuration>5__6;
injurySoundManager.lastStandAudioSource.volume = Mathf.Lerp(<startVolume>5__4, 0f, num5);
<>2__current = null;
<>1__state = 1;
return true;
}
injurySoundManager.lastStandAudioSource.Stop();
injurySoundManager.lastStandAudioSource.clip = null;
goto IL_0184;
IL_026a:
if (<wasInLastStand>5__2 & <shouldBeInLastStand>5__3)
{
injurySoundManager.isInLastStand = true;
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 3;
return true;
}
break;
}
injurySoundManager.isTransitioningPacks = false;
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static InjurySoundManager _instance;
private Dictionary<string, Dictionary<string, List<AudioClip>>> injurySounds = new Dictionary<string, Dictionary<string, List<AudioClip>>>();
private Dictionary<string, Dictionary<string, List<AudioClip>>> deathSounds = new Dictionary<string, Dictionary<string, List<AudioClip>>>();
private Dictionary<string, Dictionary<string, List<AudioClip>>> impactSounds = new Dictionary<string, Dictionary<string, List<AudioClip>>>();
private Dictionary<string, HashSet<string>> availableCategories = new Dictionary<string, HashSet<string>>();
private string currentSoundPack = "Default";
private bool isDying;
private const float DEATH_SOUND_VOLUME = 1f;
private const float MIN_PITCH_VARIANCE = 0.98f;
private const float MAX_PITCH_VARIANCE = 1.02f;
private const float CRITICAL_HEALTH_DELAY = 0.5f;
private const float PAIN_DEATH_DELAY = 0.1f;
private AudioSource lastStandAudioSource;
private bool isInLastStand;
private bool isLastStandEnabled = true;
private float lastStandThreshold = 0.25f;
private const float FADE_DURATION = 2f;
private float fadeStartTime;
private float targetVolume = 1f;
private bool isFadingIn;
private bool isFadingOut;
private bool shouldBeInLastStand;
private bool hasCriticalHealthTriggered;
private bool isCriticalHealthEnabled = true;
private float criticalHealthThreshold = 0.25f;
private const float HIGH_DAMAGE_THRESHOLD = 0.5f;
private const float LOW_DAMAGE_THRESHOLD = 0.1f;
private bool playPainWithDeath;
private bool enableImpactSounds = true;
private float impactVolumeMultiplier = 1f;
private float lastImpactSoundTime;
private const float MIN_TIME_BETWEEN_IMPACTS = 0.05f;
private AudioSource audioSource;
private AudioSource audioSource2D;
private AudioSource impactAudioSource;
private float lastInjurySoundTime;
private const float MIN_TIME_BETWEEN_SOUNDS = 0.1f;
private AudioClip lastPlayedInjuryClip;
private bool hasInitialized;
private bool isTransitioningPacks;
public bool m_hasPlayedDeathSound;
private Dictionary<string, AudioClip> lastPlayedClips = new Dictionary<string, AudioClip>();
private bool enablePainSounds = true;
private bool preventPainOverlap;
private bool respectInvincibility = true;
private bool enableInvinciblePainSounds = true;
private bool enableInvincibleImpacts = true;
private bool enableInvincibleFallSounds;
private float volumeMultiplier = 1f;
public static InjurySoundManager Instance
{
get
{
return _instance;
}
set
{
_instance = value;
}
}
public bool isLoading { get; private set; }
public string CurrentSoundPack => currentSoundPack;
public bool IsDying
{
get
{
return isDying;
}
set
{
isDying = value;
}
}
public float LastStandThreshold => lastStandThreshold;
public float CriticalHealthThreshold => criticalHealthThreshold;
public void SetVolumeMultiplier(float multiplier)
{
volumeMultiplier = Mathf.Clamp(multiplier, 0f, 2f);
}
private float GetVolumeMultiplier()
{
return volumeMultiplier;
}
public void SetLastStandEnabled(bool enabled)
{
isLastStandEnabled = enabled;
if (!enabled && isInLastStand)
{
StopLastStandSound();
}
PlayerStateCheck();
}
public void SetLastStandThreshold(float threshold)
{
lastStandThreshold = Mathf.Clamp01(threshold);
PlayerStateCheck();
}
public void SetCriticalHealthEnabled(bool enabled)
{
isCriticalHealthEnabled = enabled;
if (!enabled)
{
hasCriticalHealthTriggered = false;
}
PlayerStateCheck();
}
public void SetCriticalHealthThreshold(float threshold)
{
criticalHealthThreshold = Mathf.Clamp01(threshold);
hasCriticalHealthTriggered = false;
PlayerStateCheck();
}
public void SetPlayPainWithDeath(bool enabled)
{
playPainWithDeath = enabled;
PlayerPainSoundsPlugin.LogInfo("Play pain with death set to: " + enabled);
}
public void SetEnableImpactSounds(bool enabled)
{
enableImpactSounds = enabled;
PlayerPainSoundsPlugin.LogInfo("Impact sounds enabled: " + enabled);
}
public void SetImpactVolumeMultiplier(float multiplier)
{
impactVolumeMultiplier = Mathf.Clamp(multiplier, 0f, 5f);
PlayerPainSoundsPlugin.LogInfo("Impact volume multiplier set to: " + multiplier);
}
public void SetEnablePainSounds(bool enabled)
{
enablePainSounds = enabled;
PlayerPainSoundsPlugin.LogInfo("Pain sounds enabled: " + enabled);
}
public void SetPreventPainOverlap(bool enabled)
{
preventPainOverlap = enabled;
PlayerPainSoundsPlugin.LogInfo("Prevent pain overlap enabled: " + enabled);
}
public void SetRespectInvincibility(bool enabled)
{
respectInvincibility = enabled;
PlayerPainSoundsPlugin.LogInfo("Respect invincibility enabled: " + enabled);
}
public void SetEnableInvinciblePainSounds(bool enabled)
{
enableInvinciblePainSounds = enabled;
PlayerPainSoundsPlugin.LogInfo("Enable invincible pain sounds: " + enabled);
}
public void SetEnableInvincibleImpacts(bool enabled)
{
enableInvincibleImpacts = enabled;
PlayerPainSoundsPlugin.LogInfo("Enable invincible impacts enabled: " + enabled);
}
public void SetEnableInvincibleFallSounds(bool enabled)
{
enableInvincibleFallSounds = enabled;
PlayerPainSoundsPlugin.LogInfo("Enable invincible fall sounds enabled: " + enabled);
}
private float GetImpactVolumeMultiplier()
{
return impactVolumeMultiplier;
}
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
audioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
audioSource.spatialBlend = 1f;
audioSource.minDistance = 0.1f;
audioSource.maxDistance = 15f;
audioSource.rolloffMode = (AudioRolloffMode)0;
audioSource2D = ((Component)this).gameObject.AddComponent<AudioSource>();
audioSource2D.spatialBlend = 0f;
audioSource2D.volume = 1f;
audioSource2D.priority = 0;
audioSource.priority = 128;
lastStandAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
lastStandAudioSource.spatialBlend = 0f;
lastStandAudioSource.minDistance = 1f;
lastStandAudioSource.maxDistance = 15f;
lastStandAudioSource.rolloffMode = (AudioRolloffMode)1;
lastStandAudioSource.loop = true;
lastStandAudioSource.playOnAwake = false;
impactAudioSource = ((Component)this).gameObject.AddComponent<AudioSource>();
impactAudioSource.spatialBlend = 1f;
impactAudioSource.minDistance = 0.1f;
impactAudioSource.maxDistance = 25f;
impactAudioSource.rolloffMode = (AudioRolloffMode)1;
impactAudioSource.priority = 64;
}
else
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
private void Update()
{
if ((Object)(object)lastStandAudioSource != (Object)null && lastStandAudioSource.isPlaying)
{
UpdateFadeState();
}
}
private void UpdateFadeState()
{
if (isFadingIn)
{
float num = Mathf.Clamp01((Time.time - fadeStartTime) / 2f);
lastStandAudioSource.volume = Mathf.Lerp(0f, targetVolume, num);
if (num >= 1f)
{
isFadingIn = false;
}
}
else if (isFadingOut)
{
float num2 = Mathf.Clamp01((Time.time - fadeStartTime) / 2f);
lastStandAudioSource.volume = Mathf.Lerp(targetVolume, 0f, num2);
if (num2 >= 1f)
{
lastStandAudioSource.Stop();
isFadingOut = false;
isInLastStand = false;
}
}
}
private void StartFadeIn(AudioSource source, float targetVol, float duration)
{
source.volume = 0f;
targetVolume = targetVol * GetVolumeMultiplier();
fadeStartTime = Time.time;
isFadingIn = true;
isFadingOut = false;
}
private void StartFadeOut(AudioSource source, float duration)
{
targetVolume = source.volume;
fadeStartTime = Time.time;
isFadingOut = true;
isFadingIn = false;
}
public void PlayerStateCheck()
{
if ((Object)(object)GM.CurrentPlayerBody == (Object)null || !hasInitialized)
{
hasInitialized = true;
return;
}
CheckGameDeathState();
if (PlayerStatusHelper.IsPlayerDead())
{
return;
}
float num = GM.CurrentPlayerBody.GetPlayerHealthRaw();
float num2 = GM.CurrentPlayerBody.GetMaxHealthPlayerRaw();
if (num2 <= 0f)
{
return;
}
float num3 = num / num2;
CheckCriticalHealthState(num3);
if (!isLastStandEnabled)
{
if (isInLastStand)
{
isInLastStand = false;
StopLastStandSound();
}
return;
}
shouldBeInLastStand = num3 <= lastStandThreshold && !isDying;
if (shouldBeInLastStand && !isInLastStand && !lastStandAudioSource.isPlaying)
{
isInLastStand = true;
StartLastStandSound();
}
else if (!shouldBeInLastStand && isInLastStand)
{
isInLastStand = false;
StopLastStandSound();
}
}
private void CheckCriticalHealthState(float healthPercent)
{
if (isCriticalHealthEnabled)
{
bool flag = healthPercent <= criticalHealthThreshold;
if (flag && !hasCriticalHealthTriggered && !isDying)
{
((MonoBehaviour)this).StartCoroutine(PlayCriticalHealthSoundWithDelay());
hasCriticalHealthTriggered = true;
}
else if (!flag && hasCriticalHealthTriggered)
{
hasCriticalHealthTriggered = false;
}
}
}
private IEnumerator PlayCriticalHealthSoundWithDelay()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayCriticalHealthSoundWithDelay>d__88(0)
{
<>4__this = this
};
}
private AudioClip GetDefaultCriticalHealthSound()
{
return Resources.Load<AudioClip>("Sounds/Default/critical_health");
}
private void StartLastStandSound()
{
if (isLastStandEnabled && !((Object)(object)lastStandAudioSource == (Object)null) && !lastStandAudioSource.isPlaying)
{
AudioClip val = null;
if (currentSoundPack == "Default")
{
val = GetDefaultLastStandSound();
}
else if (injurySounds.ContainsKey(currentSoundPack) && injurySounds[currentSoundPack].ContainsKey("last_stand") && injurySounds[currentSoundPack]["last_stand"].Count > 0)
{
List<AudioClip> sounds = injurySounds[currentSoundPack]["last_stand"];
val = GetUniqueRandomSound("last_stand", sounds);
}
if ((Object)(object)val == (Object)null)
{
isInLastStand = false;
return;
}
lastStandAudioSource.clip = val;
StartFadeIn(lastStandAudioSource, 1f, 2f);
lastStandAudioSource.Play();
}
}
private void StopLastStandSound()
{
if ((Object)(object)lastStandAudioSource != (Object)null && lastStandAudioSource.isPlaying)
{
StartFadeOut(lastStandAudioSource, 2f);
}
}
public IEnumerator StartLoadingSoundPacks()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <StartLoadingSoundPacks>d__92(0)
{
<>4__this = this
};
}
public void StopAllSounds()
{
if ((Object)(object)audioSource != (Object)null)
{
audioSource.Stop();
audioSource.clip = null;
}
if ((Object)(object)audioSource2D != (Object)null)
{
audioSource2D.Stop();
audioSource2D.clip = null;
}
if ((Object)(object)impactAudioSource != (Object)null)
{
impactAudioSource.Stop();
impactAudioSource.clip = null;
}
if ((Object)(object)lastStandAudioSource != (Object)null)
{
lastStandAudioSource.Stop();
lastStandAudioSource.clip = null;
isFadingIn = false;
isFadingOut = false;
}
lastPlayedInjuryClip = null;
lastInjurySoundTime = 0f;
lastImpactSoundTime = 0f;
}
public void SetSoundPack(string packName)
{
if (!string.IsNullOrEmpty(packName) && !(packName == currentSoundPack))
{
PlayerPainSoundsPlugin.LogInfo("Switching sound pack from '" + currentSoundPack + "' to '" + packName + "'");
if ((Object)(object)audioSource != (Object)null)
{
audioSource.Stop();
}
if ((Object)(object)audioSource2D != (Object)null)
{
audioSource2D.Stop();
}
if ((Object)(object)lastStandAudioSource != (Object)null && lastStandAudioSource.isPlaying)
{
((MonoBehaviour)this).StartCoroutine(TransitionLastStandSound(packName));
}
else
{
SwitchSoundPackDirect(packName);
}
}
}
private void SwitchSoundPackDirect(string packName)
{
if (packName == "Default")
{
currentSoundPack = "Default";
ClearLoadedSounds();
LoadDefaultSounds();
PlayerPainSoundsPlugin.LogInfo("Switched to Default sound pack");
PlayerStateCheck();
}
else if (!injurySounds.ContainsKey(packName) || !deathSounds.ContainsKey(packName) || !availableCategories.ContainsKey(packName))
{
PlayerPainSoundsPlugin.LogInfo("Loading sounds for pack: " + packName);
((MonoBehaviour)this).StartCoroutine(LoadSinglePackAndSwitch(packName));
}
else
{
currentSoundPack = packName;
PlayerPainSoundsPlugin.LogInfo("Switched to sound pack: " + packName);
PlayerStateCheck();
}
}
private IEnumerator TransitionLastStandSound(string newPackName)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TransitionLastStandSound>d__96(0)
{
<>4__this = this,
newPackName = newPackName
};
}
private IEnumerator LoadCustomSoundPacks()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadCustomSoundPacks>d__97(0)
{
<>4__this = this
};
}
private void InitializePackDictionaries(string packName)
{
if (!injurySounds.ContainsKey(packName))
{
injurySounds[packName] = new Dictionary<string, List<AudioClip>>();
}
if (!deathSounds.ContainsKey(packName))
{
deathSounds[packName] = new Dictionary<string, List<AudioClip>>();
}
if (!impactSounds.ContainsKey(packName))
{
impactSounds[packName] = new Dictionary<string, List<AudioClip>>();
}
if (!availableCategories.ContainsKey(packName))
{
availableCategories[packName] = new HashSet<string>();
}
}
private IEnumerator LoadSoundPackCategories(string packName, string packPath)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadSoundPackCategories>d__99(0)
{
<>4__this = this,
packName = packName,
packPath = packPath
};
}
private IEnumerator LoadSinglePackAndSwitch(string packName)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <LoadSinglePackAndSwitch>d__100(0)
{
<>4__this = this,
packName = packName
};
}
private void LoadDefaultSounds()
{
LoadDefaultInjurySounds();
LoadDefaultDeathSounds();
LoadDefaultLastStandSound();
}
private void LoadDefaultInjurySounds()
{
if (!injurySounds.ContainsKey("Default"))
{
injurySounds["Default"] = new Dictionary<string, List<AudioClip>>();
}
string[] aLL_CATEGORIES = SoundCategories.ALL_CATEGORIES;
foreach (string key in aLL_CATEGORIES)
{
if (SoundCategories.IS_INJURY_CATEGORY[key] && !injurySounds["Default"].ContainsKey(key))
{
injurySounds["Default"][key] = new List<AudioClip>();
}
}
}
private void LoadDefaultDeathSounds()
{
if (!deathSounds.ContainsKey("Default"))
{
deathSounds["Default"] = new Dictionary<string, List<AudioClip>>();
}
if (!deathSounds["Default"].ContainsKey("death"))
{
deathSounds["Default"]["death"] = new List<AudioClip>();
}
}
private void LoadDefaultLastStandSound()
{
if (!injurySounds.ContainsKey("Default"))
{
injurySounds["Default"] = new Dictionary<string, List<AudioClip>>();
}
if (!injurySounds["Default"].ContainsKey("last_stand"))
{
injurySounds["Default"]["last_stand"] = new List<AudioClip>();
}
if (!injurySounds["Default"].ContainsKey("critical_health"))
{
injurySounds["Default"]["critical_health"] = new List<AudioClip>();
}
}
private void ClearLoadedSounds()
{
foreach (string item in injurySounds.Keys.ToList())
{
injurySounds[item].Clear();
}
foreach (string item2 in deathSounds.Keys.ToList())
{
deathSounds[item2].Clear();
}
foreach (string item3 in impactSounds.Keys.ToList())
{
impactSounds[item3].Clear();
}
availableCategories.Clear();
if (lastPlayedClips != null)
{
lastPlayedClips.Clear();
}
}
public bool HasSoundsInCategory(string packName, string category)
{
if (injurySounds.ContainsKey(packName) && injurySounds[packName].ContainsKey(category))
{
return injurySounds[packName][category].Count > 0;
}
return false;
}
public bool HasDeathSoundsInCategory(string packName, string category)
{
if (deathSounds.ContainsKey(packName) && deathSounds[packName].ContainsKey(category))
{
return deathSounds[packName][category].Count > 0;
}
return false;
}
public void PlayInjurySound(Vector3 position)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
if (enablePainSounds && injurySounds.ContainsKey(currentSoundPack) && !((Object)(object)GM.CurrentPlayerBody == (Object)null) && !((float)GM.CurrentPlayerBody.GetPlayerHealthRaw() <= 0f) && !PlayerStatusHelper.IsPlayerDead() && !isDying)
{
PlayInjurySoundInternal(position, 1f, (PlayerHitBoxType)1, null);
}
}
public void PlayInjurySound(Vector3 position, float distanceMult)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
if (enablePainSounds && injurySounds.ContainsKey(currentSoundPack) && !((Object)(object)GM.CurrentPlayerBody == (Object)null) && !((float)GM.CurrentPlayerBody.GetPlayerHealthRaw() <= 0f) && !PlayerStatusHelper.IsPlayerDead() && !isDying)
{
PlayInjurySoundInternal(position, distanceMult, (PlayerHitBoxType)1, null);
}
}
public void PlayInjurySound(Vector3 position, float distanceMult, PlayerHitBoxType hitboxType)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
if (enablePainSounds && injurySounds.ContainsKey(currentSoundPack) && !((Object)(object)GM.CurrentPlayerBody == (Object)null) && !((float)GM.CurrentPlayerBody.GetPlayerHealthRaw() <= 0f) && !PlayerStatusHelper.IsPlayerDead() && !isDying)
{
PlayInjurySoundInternal(position, distanceMult, hitboxType, null);
}
}
public void PlayInjurySound(Vector3 position, float distanceMult, PlayerHitBoxType hitboxType, Damage damage)
{
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
if (!enablePainSounds)
{
return;
}
if (respectInvincibility && PlayerStatusHelper.IsPlayerCompletelyInvincible())
{
PlayerPainSoundsPlugin.LogInfo("Pain sound blocked - player has complete invincibility powerup active");
}
else
{
if (isTransitioningPacks || !hasInitialized || currentSoundPack == "Default")
{
return;
}
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - CurrentPlayerBody is null");
return;
}
float num = GM.CurrentPlayerBody.GetPlayerHealthRaw();
if (num <= 0f)
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - player health is " + num + " (dead)");
return;
}
if (PlayerStatusHelper.IsPlayerDead() || isDying)
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - player dead or dying");
return;
}
if (damage == null)
{
if (PlayerPainSoundsPlugin.configDebugMessages.Value)
{
PlayerPainSoundsPlugin.LogInfo("PlayInjurySound called with null damage - pain sound blocked");
}
return;
}
float num2 = damage.Dam_TotalKinetic + damage.Dam_TotalEnergetic;
if (num2 <= 0f)
{
if (PlayerPainSoundsPlugin.configDebugMessages.Value)
{
PlayerPainSoundsPlugin.LogInfo($"PlayInjurySound called with zero damage ({num2}) - pain sound blocked");
}
}
else if (!playPainWithDeath && num - num2 <= 0f)
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - damage would be lethal and play pain with death is disabled");
}
else
{
PlayInjurySoundInternalWithDamage(position, distanceMult, hitboxType, null, num2);
}
}
}
public void PlayInjurySoundWithDamage(Vector3 position, float distanceMult, PlayerHitBoxType hitboxType, float damageAmount)
{
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
if (!enablePainSounds)
{
return;
}
if (respectInvincibility && PlayerStatusHelper.IsPlayerCompletelyInvincible())
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Pain sound blocked - player has complete invincibility powerup active");
}
}
else
{
if (isTransitioningPacks || !hasInitialized || currentSoundPack == "Default")
{
return;
}
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - CurrentPlayerBody is null");
}
return;
}
float num = GM.CurrentPlayerBody.GetPlayerHealthRaw();
if (num <= 0f)
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - player health is " + num + " (dead)");
}
}
else if (PlayerStatusHelper.IsPlayerDead() || isDying)
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - player dead or dying");
}
}
else if (damageAmount <= 0f)
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo($"PlayInjurySoundWithDamage called with zero damage ({damageAmount}) - pain sound blocked");
}
}
else if (!playPainWithDeath && num - damageAmount <= 0f)
{
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Pain blocked - damage would be lethal and play pain with death is disabled");
}
}
else
{
PlayInjurySoundInternalWithDamage(position, distanceMult, hitboxType, null, damageAmount);
}
}
}
private AudioClip GetInvinciblePainClip()
{
if (!injurySounds.ContainsKey(currentSoundPack))
{
return null;
}
if (!injurySounds[currentSoundPack].ContainsKey("invincible_pain"))
{
return null;
}
List<AudioClip> list = injurySounds[currentSoundPack]["invincible_pain"];
if (list == null || list.Count == 0)
{
return null;
}
return list[Random.Range(0, list.Count)];
}
public void OnPlayerHitDetected(PlayerHitBoxType hitboxType, float damageAmount, Vector3 position)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo($"Hit detected on {hitboxType}: damage={damageAmount}, position={position}");
}
}
public void PlayImpactSound(Vector3 position, Damage damage)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
if (!enableImpactSounds || damage == null || Time.time - lastImpactSoundTime < 0.05f)
{
return;
}
string impactSoundCategory = DamageCalculationHelper.GetImpactSoundCategory(damage);
string actualCategory;
AudioClip impactSoundAndCategory = GetImpactSoundAndCategory(impactSoundCategory, out actualCategory);
if ((Object)(object)impactSoundAndCategory != (Object)null)
{
float num = 1f * GetImpactVolumeMultiplier();
float pitch = Random.Range(0.98f, 1.02f);
((Component)impactAudioSource).transform.position = position;
impactAudioSource.pitch = pitch;
impactAudioSource.PlayOneShot(impactSoundAndCategory, num);
lastImpactSoundTime = Time.time;
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo($"Playing impact sound: {actualCategory} at {position}");
}
}
}
public void PlayImpactSoundWithType(Vector3 position, PlayerHitBoxType hitboxType, float damageAmount)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
if (enableImpactSounds && !(Time.time - lastImpactSoundTime < 0.05f))
{
string impactSoundCategory = DamageCalculationHelper.GetImpactSoundCategory(hitboxType, damageAmount);
string actualCategory;
AudioClip impactSoundAndCategory = GetImpactSoundAndCategory(impactSoundCategory, out actualCategory);
if ((Object)(object)impactSoundAndCategory != (Object)null)
{
float num = 1f * GetImpactVolumeMultiplier();
float pitch = Random.Range(0.98f, 1.02f);
((Component)impactAudioSource).transform.position = position;
impactAudioSource.pitch = pitch;
impactAudioSource.PlayOneShot(impactSoundAndCategory, num);
lastImpactSoundTime = Time.time;
PlayerPainSoundsPlugin.LogInfo($"Playing impact sound: {actualCategory} at {position}");
}
}
}
private AudioClip GetImpactSound(string category)
{
string actualCategory;
return GetImpactSoundAndCategory(category, out actualCategory);
}
private AudioClip GetImpactSoundAndCategory(string category, out string actualCategory)
{
actualCategory = category;
if (!impactSounds.ContainsKey(currentSoundPack))
{
PlayerPainSoundsPlugin.LogInfo("No impact sounds loaded for current sound pack: " + currentSoundPack);
return null;
}
if (enableInvincibleImpacts && PlayerStatusHelper.IsPlayerCompletelyInvincible())
{
if (impactSounds[currentSoundPack].ContainsKey("invincible_impact") && impactSounds[currentSoundPack]["invincible_impact"].Count > 0)
{
List<AudioClip> list = impactSounds[currentSoundPack]["invincible_impact"];
int index = Random.Range(0, list.Count);
actualCategory = "invincible_impact";
PlayerPainSoundsPlugin.LogInfo(string.Format("Using invincible impact sounds: {0} ({1} sounds available)", "invincible_impact", list.Count));
return list[index];
}
PlayerPainSoundsPlugin.LogInfo("Player is invincible but no invincible impact sounds available, skipping impact sound");
return null;
}
if (impactSounds[currentSoundPack].ContainsKey(category) && impactSounds[currentSoundPack][category].Count > 0)
{
List<AudioClip> list2 = impactSounds[currentSoundPack][category];
int index2 = Random.Range(0, list2.Count);
PlayerPainSoundsPlugin.LogInfo($"Using impact category: {category} ({list2.Count} sounds available)");
return list2[index2];
}
if (category != "impact_default")
{
PlayerPainSoundsPlugin.LogInfo(string.Format("Impact category {0} not found, falling back to {1}", category, "impact_default"));
actualCategory = "impact_default";
return GetImpactSoundAndCategory("impact_default", out actualCategory);
}
if (impactSounds[currentSoundPack].Count > 0)
{
string arg = string.Join(", ", impactSounds[currentSoundPack].Keys.ToArray());
PlayerPainSoundsPlugin.LogInfo($"Impact category {category} not found. Available impact categories: {arg}");
}
else
{
PlayerPainSoundsPlugin.LogInfo("No impact sounds available in current sound pack");
}
return null;
}
private void PlayInjurySoundInternal(Vector3 position, float distanceMult, PlayerHitBoxType hitboxType, AudioClip forcedClip)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
PlayInjurySoundInternalWithDamage(position, distanceMult, hitboxType, forcedClip, 0f);
}
private void PlayInjurySoundInternalWithDamage(Vector3 position, float distanceMult, PlayerHitBoxType hitboxType, AudioClip forcedClip, float damageAmount)
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!enablePainSounds)
{
return;
}
bool flag = PlayerStatusHelper.IsPlayerCompletelyInvincible();
if (respectInvincibility && flag)
{
if (!enableInvinciblePainSounds)
{
return;
}
AudioClip invinciblePainClip = GetInvinciblePainClip();
if ((Object)(object)invinciblePainClip == (Object)null)
{
PlayerPainSoundsPlugin.LogInfo("Pain sound blocked - invincible pain category missing while player is invincible");
return;
}
forcedClip = invinciblePainClip;
}
if (preventPainOverlap && (audioSource.isPlaying || audioSource2D.isPlaying))
{
PlayerPainSoundsPlugin.LogInfo("Pain sound blocked due to overlap prevention - previous sound still playing");
return;
}
if (Time.time - lastInjurySoundTime < 0.1f)
{
PlayerPainSoundsPlugin.LogInfo("Pain sound rate limited - too soon after last sound");
return;
}
Vector3 position2 = ((Component)GM.CurrentPlayerBody.Head).transform.position;
if (isTransitioningPacks || !hasInitialized || currentSoundPack == "Default" || Time.time - lastInjurySoundTime < 0.1f)
{
return;
}
if (!injurySounds.ContainsKey(currentSoundPack))
{
PlayerPainSoundsPlugin.LogWarning("No injury sounds found for current sound pack: " + currentSoundPack);
return;
}
AudioClip val = forcedClip;
if ((Object)(object)val == (Object)null)
{
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
return;
}
val = ((!(damageAmount > 0f)) ? GetAppropriateSound() : GetAppropriateSoundForDamage(damageAmount));
}
if (!((Object)(object)val != (Object)null))
{
return;
}
float num = 1f * distanceMult * GetVolumeMultiplier();
float pitch = Random.Range(0.98f, 1.02f);
float num2 = 0f;
if (enableImpactSounds)
{
float num3 = Time.time - lastImpactSoundTime;
num2 = 0.25f - num3;
if (num2 < 0f)
{
num2 = 0f;
}
}
float spatialVolume = num * 0.2f;
lastInjurySoundTime = Time.time;
((MonoBehaviour)this).StartCoroutine(PlayInjuryClipsWithDelay(val, spatialVolume, num, pitch, position2, num2));
}
catch (Exception ex)
{
PlayerPainSoundsPlugin.LogError("Error in PlayInjurySoundInternalWithDamage: " + ex.Message);
}
}
public void PlayFallSound(bool isHighFall)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)GM.CurrentPlayerBody == (Object)null)
{
return;
}
if (PlayerStatusHelper.IsPlayerCompletelyInvincible() && !enableInvincibleFallSounds)
{
PlayerPainSoundsPlugin.LogInfo("Fall sound blocked - player is invincible and invincible fall sounds are disabled");
return;
}
AudioClip fallClip = GetFallClip(isHighFall);
if ((Object)(object)fallClip == (Object)null)
{
PlayerPainSoundsPlugin.LogInfo("No fall sound available for the requested height category");
return;
}
Vector3 position = GM.CurrentPlayerBody.Head.position;
PlayInjurySoundInternal(position, 1f, (PlayerHitBoxType)1, fallClip);
}
private AudioClip GetFallClip(bool isHighFall)
{
if (isHighFall)
{
AudioClip clipForCategory = GetClipForCategory("fall_high");
if ((Object)(object)clipForCategory != (Object)null)
{
return clipForCategory;
}
AudioClip clipForCategory2 = GetClipForCategory("pain_high");
if ((Object)(object)clipForCategory2 != (Object)null)
{
return clipForCategory2;
}
return GetClipForCategory("pain_default");
}
AudioClip clipForCategory3 = GetClipForCategory("fall_low");
if ((Object)(object)clipForCategory3 != (Object)null)
{
return clipForCategory3;
}
AudioClip clipForCategory4 = GetClipForCategory("pain_low");
if ((Object)(object)clipForCategory4 != (Object)null)
{
return clipForCategory4;
}
return GetClipForCategory("pain_default");
}
private IEnumerator PlayInjuryClipsWithDelay(AudioClip clip, float spatialVolume, float volume2D, float pitch, Vector3 headPosition, float delay)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayInjuryClipsWithDelay>d__123(0)
{
<>4__this = this,
clip = clip,
spatialVolume = spatialVolume,
volume2D = volume2D,
pitch = pitch,
headPosition = headPosition,
delay = delay
};
}
private AudioClip GetAppropriateSound()
{
float num = GM.CurrentPlayerBody.GetPlayerHealthRaw();
float num2 = GM.CurrentPlayerBody.GetMaxHealthPlayerRaw();
if (num2 <= 0f)
{
return null;
}
float num3 = num / num2;
string text = "pain_default";
List<AudioClip> list = null;
if (num3 <= 0.5f && injurySounds[currentSoundPack].ContainsKey("pain_high"))
{
list = injurySounds[currentSoundPack]["pain_high"];
if (list != null && list.Count > 0)
{
text = "pain_high";
}
}
if (list == null || list.Count == 0)
{
text = "pain_default";
if (injurySounds[currentSoundPack].ContainsKey("pain_default") && injurySounds[currentSoundPack]["pain_default"].Count > 0)
{
list = injurySounds[currentSoundPack]["pain_default"];
}
}
if ((list == null || list.Count == 0) && injurySounds[currentSoundPack].ContainsKey("pain_low"))
{
list = injurySounds[currentSoundPack]["pain_low"];
if (list != null && list.Count > 0)
{
text = "pain_low";
}
}
if (list == null || list.Count == 0)
{
text = "pain_default";
if (injurySounds[currentSoundPack].ContainsKey("pain_default") && injurySounds[currentSoundPack]["pain_default"].Count > 0)
{
list = injurySounds[currentSoundPack]["pain_default"];
}
}
if (list != null && list.Count > 0)
{
AudioClip uniqueRandomSound = GetUniqueRandomSound(text, list);
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo("Selected sound from category: " + text + " (health-based fallback)");
}
return uniqueRandomSound;
}
return null;
}
private AudioClip GetAppropriateSoundForDamage(float damageAmount)
{
float num = GM.CurrentPlayerBody.GetMaxHealthPlayerRaw();
if (num <= 0f || damageAmount <= 0f)
{
return null;
}
DamageCalculationHelper.DamageInfo damageInfo = default(DamageCalculationHelper.DamageInfo);
damageInfo.TotalDamage = damageAmount;
damageInfo.DamagePercentage = damageAmount / num;
string text = DamageCalculationHelper.GetSoundCategoryForDamage(damageInfo);
List<AudioClip> list = null;
if (injurySounds[currentSoundPack].ContainsKey(text) && injurySounds[currentSoundPack][text].Count > 0)
{
list = injurySounds[currentSoundPack][text];
}
if (list == null || list.Count == 0)
{
text = "pain_default";
if (injurySounds[currentSoundPack].ContainsKey("pain_default") && injurySounds[currentSoundPack]["pain_default"].Count > 0)
{
list = injurySounds[currentSoundPack]["pain_default"];
}
}
if (list == null || list.Count == 0)
{
if (injurySounds[currentSoundPack].ContainsKey("pain_high") && injurySounds[currentSoundPack]["pain_high"].Count > 0)
{
list = injurySounds[currentSoundPack]["pain_high"];
text = "pain_high";
}
else if (injurySounds[currentSoundPack].ContainsKey("pain_low") && injurySounds[currentSoundPack]["pain_low"].Count > 0)
{
list = injurySounds[currentSoundPack]["pain_low"];
text = "pain_low";
}
}
if (list != null && list.Count > 0)
{
AudioClip uniqueRandomSound = GetUniqueRandomSound(text, list);
if (PlayerPainSoundsPlugin.IsDebugEnabled())
{
PlayerPainSoundsPlugin.LogInfo($"Selected sound from category: {text} (damage={damageAmount:F2}, damagePercent={damageInfo.DamagePercentage * 100f:F1}%)");
}
return uniqueRandomSound;
}
return null;
}
private AudioClip GetClipForCategory(string category)
{
if (!injurySounds.ContainsKey(currentSoundPack))
{
return null;
}
if (!injurySounds[currentSoundPack].ContainsKey(category))
{
return null;
}
List<AudioClip> list = injurySounds[currentSoundPack][category];
if (list == null || list.Count == 0)
{
return null;
}
return GetUniqueRandomSound(category, list);
}
private AudioClip GetUniqueRandomSound(string category, List<AudioClip> sounds)
{
if (sounds == null || sounds.Count == 0)
{
return null;
}
if (sounds.Count == 1)
{
return sounds[0];
}
AudioClip val = null;
if (lastPlayedClips.ContainsKey(category))
{
val = lastPlayedClips[category];
}
List<AudioClip> list = sounds;
if ((Object)(object)val != (Object)null)
{
List<AudioClip> list2 = new List<AudioClip>();
foreach (AudioClip sound in sounds)
{
if ((Object)(object)sound != (Object)(object)val)
{
list2.Add(sound);
}
}
if (list2.Count > 0)
{
list = list2;
}
}
AudioClip val2 = list[Random.Range(0, list.Count)];
lastPlayedClips[category] = val2;
return val2;
}
public void PlayDeathSound()
{
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)audioSource == (Object)null || currentSoundPack == "Default")
{
return;
}
try
{
if (m_hasPlayedDeathSound)
{
PlayerPainSoundsPlugin.LogInfo("Death sound already played, ignoring duplicate call");
return;
}
m_hasPlayedDeathSound = true;
isDying = true;
StopLastStandSound();
PlayerPainSoundsPlugin.LogInfo("Playing death sound (flag set to prevent duplicates)");
if (!deathSounds.ContainsKey(currentSoundPack))
{
PlayerPainSoundsPlugin.LogWarning("No death sounds dictionary found for pack: " + currentSoundPack);
return;
}
if (!deathSounds[currentSoundPack].ContainsKey("death"))
{
PlayerPainSoundsPlugin.LogWarning("No death sounds category found for pack: " + currentSoundPack);
return;
}
List<AudioClip> list = deathSounds[currentSoundPack]["death"];
if (list == null || list.Count == 0)
{
PlayerPainSoundsPlugin.LogInfo("No death sounds available in death category for pack: " + currentSoundPack);
return;
}
AudioClip uniqueRandomSound = GetUniqueRandomSound("death", list);
if (playPainWithDeath)
{
((MonoBehaviour)this).StartCoroutine(PlayPainAndDeathSequence(uniqueRandomSound));
}
else if ((Object)(object)uniqueRandomSound != (Object)null)
{
Vector3 position = GM.CurrentPlayerBody.Head.position;
float num = 1f * GetVolumeMultiplier();
((Component)audioSource).transform.position = position;
audioSource.spatialBlend = 1f;
float num2 = num * 0.2f;
audioSource.PlayOneShot(uniqueRandomSound, num2);
audioSource2D.PlayOneShot(uniqueRandomSound, num);
PlayerPainSoundsPlugin.LogInfo($"Playing death sound at head position: {position}");
((MonoBehaviour)this).StartCoroutine(ResetStateAfterDeathSound());
}
}
catch (Exception ex)
{
PlayerPainSoundsPlugin.LogError("Error in PlayDeathSound: " + ex.Message);
}
}
private IEnumerator PlayPainAndDeathSequence(AudioClip deathSound)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayPainAndDeathSequence>d__129(0)
{
<>4__this = this,
deathSound = deathSound
};
}
public void ResetDyingState()
{
isDying = false;
m_hasPlayedDeathSound = false;
hasCriticalHealthTriggered = false;
StopAllSounds();
}
public void CheckGameDeathState()
{
if (!GM.IsDead() && isDying)
{
PlayerPainSoundsPlugin.LogInfo("Auto-resetting isDying - GM.IsDead() returned false");
ResetDyingState();
}
}
private AudioClip GetDefaultLastStandSound()
{
return Resources.Load<AudioClip>("Sounds/Default/last_stand");
}
public AudioClip GetRandomSound(string category)
{
if (injurySounds.ContainsKey(currentSoundPack) && injurySounds[currentSoundPack].ContainsKey(category) && injurySounds[currentSoundPack][category].Count > 0)
{
List<AudioClip> list = injurySounds[currentSoundPack][category];
return list[Random.Range(0, list.Count)];
}
return null;
}
public void PlaySoundAtPosition(AudioClip clip, Vector3 position, float distanceMult)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)audioSource == (Object)null)
{
PlayerPainSoundsPlugin.LogError("AudioSource is null when trying to play sound");
return;
}
if ((Object)(object)clip == (Object)null)
{
PlayerPainSoundsPlugin.LogError("AudioClip is null when trying to play sound");
return;
}
if (audioSource.spatialBlend != 1f)
{
audioSource.spatialBlend = 1f;
PlayerPainSoundsPlugin.LogWarning("Reset audio source spatial blend to 3D");
}
if (audioSource.isPlaying)
{
audioSource.Stop();
}
Vector3 position2 = GM.CurrentPlayerBody.Head.position;
((Component)audioSource).transform.position = position2;
audioSource.volume = 1f * distanceMult * GetVolumeMultiplier();
audioSource.pitch = Random.Range(0.98f, 1.02f);
audioSource.clip = clip;
audioSource.Play();
string[] obj = new string[10]
{
"Playing sound: ",
((Object)clip).name,
" at head position ",
null,
null,
null,
null,
null,
null,
null
};
Vector3 val = position2;
obj[3] = ((object)(Vector3)(ref val)).ToString();
obj[4] = " with volume ";
obj[5] = audioSource.volume.ToString();
obj[6] = " and spatial blend "