using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using FMOD;
using FMOD.Studio;
using FMODUnity;
using Features.AIModule.Scripts;
using Features.AIModule.Scripts.ManInShadows;
using Fusion;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Shadowman")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Shadowman")]
[assembly: AssemblyTitle("Shadowman")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace LastPirates.Shadowman
{
[BepInPlugin("com.bwadd.lastpirates.shadowman", "Shadowman", "1.7.2")]
public sealed class Plugin : BaseUnityPlugin
{
private sealed class SpatialSmoothing
{
internal float Vertical = 1f;
internal float Occlusion = 1f;
}
private sealed class DeathPlayback
{
internal Channel Channel;
internal DSP Reverb;
internal Vector3 Position;
internal int ObstacleMask;
internal readonly SpatialSmoothing Smoothing = new SpatialSmoothing();
}
public const string PluginGuid = "com.bwadd.lastpirates.shadowman";
public const string PluginName = "Shadowman";
public const string PluginVersion = "1.7.2";
private const string AudioFileName = "Shadowman_18s.wav";
private const string DeathAudioFileName = "Shadowman_Death.mp3";
private const uint DeathAudioStartMilliseconds = 54000u;
internal static Plugin Instance;
internal static ConfigEntry<float> Volume;
internal static ConfigEntry<float> MinimumDistance;
internal static ConfigEntry<float> MaximumDistance;
internal static ConfigEntry<float> DeathVolume;
internal static ConfigEntry<float> FarReverbWetLevel;
internal static ConfigEntry<float> NearReverbWetLevel;
internal static ConfigEntry<float> PlaybackSpeed;
internal static ConfigEntry<float> VerticalSilenceDistance;
internal static ConfigEntry<float> OccludedVolumeMultiplier;
private readonly Dictionary<int, Channel> _channels = new Dictionary<int, Channel>();
private readonly Dictionary<int, DSP> _reverbs = new Dictionary<int, DSP>();
private readonly Dictionary<int, SpatialSmoothing> _spatialSmoothing = new Dictionary<int, SpatialSmoothing>();
private readonly List<DeathPlayback> _deathPlaybacks = new List<DeathPlayback>();
private Sound _replacementSound;
private Sound _deathSound;
private bool _soundReady;
private bool _deathSoundReady;
private Bus _sfxBus;
private void Awake()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Expected O, but got Unknown
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Expected O, but got Unknown
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Expected O, but got Unknown
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Expected O, but got Unknown
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Expected O, but got Unknown
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Expected O, but got Unknown
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_0226: Expected O, but got Unknown
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Volume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.5f, new ConfigDescription("Replacement whisper volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
MinimumDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MinimumDistance", 3f, new ConfigDescription("Distance where the replacement plays at full volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 50f), Array.Empty<object>()));
MaximumDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "MaximumDistance", 25f, new ConfigDescription("Distance where the replacement becomes inaudible.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>()));
DeathVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "DeathVolume", 1f, new ConfigDescription("Volume of the Shadowman death clip.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
FarReverbWetLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "FarReverbWetLevel", 3f, new ConfigDescription("Reverb wet level in decibels at maximum audible distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 20f), Array.Empty<object>()));
NearReverbWetLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "NearReverbWetLevel", -45f, new ConfigDescription("Reverb wet level in decibels while close to the Stalker.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 20f), Array.Empty<object>()));
PlaybackSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "PlaybackSpeed", 0.85f, new ConfigDescription("Replacement playback speed. Values below one are slower and lower-pitched.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 1.5f), Array.Empty<object>()));
VerticalSilenceDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Occlusion", "VerticalSilenceDistance", 5f, new ConfigDescription("Center of the two-metre vertical fade from audible to silent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
OccludedVolumeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Occlusion", "OccludedVolumeMultiplier", 0.16f, new ConfigDescription("Volume multiplier when a wall or other solid obstacle blocks the listener.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
MinimumDistance.SettingChanged += OnDistanceChanged;
MaximumDistance.SettingChanged += OnDistanceChanged;
new Harmony("com.bwadd.lastpirates.shadowman").PatchAll(typeof(Plugin).Assembly);
((MonoBehaviour)this).StartCoroutine(LoadSounds());
}
private void Update()
{
UpdateDeathPlaybacks();
}
private IEnumerator LoadSounds()
{
string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Shadowman_18s.wav");
string deathPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Shadowman_Death.mp3");
if (!File.Exists(path))
{
((BaseUnityPlugin)this).Logger.LogError((object)("Replacement audio not found: " + path));
yield break;
}
float deadline = Time.realtimeSinceStartup + 30f;
string lastError = "FMOD is not initialized.";
while (Time.realtimeSinceStartup < deadline)
{
try
{
System coreSystem = RuntimeManager.CoreSystem;
if (((System)(ref coreSystem)).hasHandle())
{
RESULT val = ((System)(ref coreSystem)).createSound(path, (MODE)4194450, ref _replacementSound);
if ((int)val == 0)
{
((Sound)(ref _replacementSound)).setLoopCount(-1);
((Sound)(ref _replacementSound)).set3DMinMaxDistance(MinimumDistance.Value, MaximumDistance.Value);
_soundReady = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Shadowman_18s.wav; Stalker whispers will be replaced locally.");
break;
}
lastError = $"{val}: {Error.String(val)}";
}
}
catch (Exception ex)
{
lastError = ex.ToString();
}
yield return (object)new WaitForSecondsRealtime(0.5f);
}
if (!_soundReady)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Could not load replacement through FMOD within 30 seconds: " + lastError));
}
if (!File.Exists(deathPath))
{
((BaseUnityPlugin)this).Logger.LogError((object)("Death audio not found: " + deathPath));
yield break;
}
System coreSystem2 = RuntimeManager.CoreSystem;
RESULT val2 = ((System)(ref coreSystem2)).createSound(deathPath, (MODE)4194449, ref _deathSound);
if ((int)val2 != 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Could not load Shadowman death audio: {val2}: {Error.String(val2)}");
yield break;
}
((Sound)(ref _deathSound)).set3DMinMaxDistance(MinimumDistance.Value, MaximumDistance.Value);
_deathSoundReady = true;
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Shadowman_Death.mp3; playback begins at 54 seconds on Stalker death.");
}
internal void PlayDeathSound(Vector3 worldPosition, int obstacleMask)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: 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_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: 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_00ed: 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_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
if (!_deathSoundReady)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)"Shadowman died before the death audio was ready.");
return;
}
System coreSystem = RuntimeManager.CoreSystem;
Channel channel = default(Channel);
RESULT val = ((System)(ref coreSystem)).playSound(_deathSound, default(ChannelGroup), true, ref channel);
if ((int)val != 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Could not start Shadowman death audio: {val}: {Error.String(val)}");
return;
}
VECTOR val2 = new VECTOR
{
x = worldPosition.x,
y = worldPosition.y,
z = worldPosition.z
};
VECTOR val3 = default(VECTOR);
((Channel)(ref channel)).set3DAttributes(ref val2, ref val3);
((Channel)(ref channel)).setPitch(PlaybackSpeed.Value);
DSP reverb = CreateDistanceReverb(channel);
((Channel)(ref channel)).setPosition(54000u, (TIMEUNIT)1);
((Channel)(ref channel)).setPaused(false);
DeathPlayback deathPlayback = new DeathPlayback
{
Channel = channel,
Reverb = reverb,
Position = worldPosition,
ObstacleMask = obstacleMask
};
_deathPlaybacks.Add(deathPlayback);
ApplySpatialEffects(channel, reverb, deathPlayback.Smoothing, worldPosition, obstacleMask, DeathVolume.Value);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Played Shadowman death audio from 54 seconds.");
}
private void UpdateDeathPlaybacks()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
bool flag = default(bool);
for (int num = _deathPlaybacks.Count - 1; num >= 0; num--)
{
DeathPlayback deathPlayback = _deathPlaybacks[num];
if (!((Channel)(ref deathPlayback.Channel)).hasHandle() || (int)((Channel)(ref deathPlayback.Channel)).isPlaying(ref flag) != 0 || !flag)
{
if (((DSP)(ref deathPlayback.Reverb)).hasHandle())
{
((DSP)(ref deathPlayback.Reverb)).release();
}
_deathPlaybacks.RemoveAt(num);
}
else
{
ApplySpatialEffects(deathPlayback.Channel, deathPlayback.Reverb, deathPlayback.Smoothing, deathPlayback.Position, deathPlayback.ObstacleMask, DeathVolume.Value);
}
}
}
private void OnDistanceChanged(object sender, EventArgs eventArgs)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
float value = MinimumDistance.Value;
float num = Mathf.Max(value + 0.1f, MaximumDistance.Value);
if (((Sound)(ref _replacementSound)).hasHandle())
{
((Sound)(ref _replacementSound)).set3DMinMaxDistance(value, num);
}
if (((Sound)(ref _deathSound)).hasHandle())
{
((Sound)(ref _deathSound)).set3DMinMaxDistance(value, num);
}
}
internal void UpdateReplacement(ManInShadowsBehaviour enemy, float visibilityVolume)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_0046: 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_0056: 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_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: 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)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: 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_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_0114: 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_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_0177: Unknown result type (might be due to invalid IL or missing references)
if (!_soundReady || (Object)(object)enemy == (Object)null)
{
return;
}
int instanceID = ((Object)enemy).GetInstanceID();
if (!_channels.TryGetValue(instanceID, out var value) || !((Channel)(ref value)).hasHandle())
{
System coreSystem = RuntimeManager.CoreSystem;
RESULT val = ((System)(ref coreSystem)).playSound(_replacementSound, default(ChannelGroup), false, ref value);
if ((int)val != 0)
{
((BaseUnityPlugin)this).Logger.LogError((object)$"Could not start Shadowman whisper: {val}: {Error.String(val)}");
return;
}
_channels[instanceID] = value;
_reverbs[instanceID] = CreateDistanceReverb(value);
_spatialSmoothing[instanceID] = new SpatialSmoothing();
((Channel)(ref value)).setPitch(PlaybackSpeed.Value);
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Started replacement whisper for Stalker instance {instanceID}.");
}
Vector3 val2 = ResolveVisionPosition(enemy);
VECTOR val3 = new VECTOR
{
x = val2.x,
y = val2.y,
z = val2.z
};
VECTOR val4 = default(VECTOR);
((Channel)(ref value)).set3DAttributes(ref val3, ref val4);
((Channel)(ref value)).setPitch(PlaybackSpeed.Value);
if (!_spatialSmoothing.TryGetValue(instanceID, out var value2))
{
value2 = new SpatialSmoothing();
_spatialSmoothing[instanceID] = value2;
}
_reverbs.TryGetValue(instanceID, out var value3);
ApplySpatialEffects(value, value3, value2, val2, ResolveObstacleMask(enemy), Mathf.Clamp01(visibilityVolume) * Volume.Value);
}
private void ApplySpatialEffects(Channel channel, DSP reverb, SpatialSmoothing smoothing, Vector3 worldPosition, int obstacleMask, float baseVolume)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0122: 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_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
if (!TryGetListenerPosition(out var position))
{
((Channel)(ref channel)).setVolume(baseVolume);
return;
}
float num = Mathf.Abs(position.y - worldPosition.y);
float num2 = Mathf.Max(0f, VerticalSilenceDistance.Value - 1f);
float num3 = VerticalSilenceDistance.Value + 1f;
float num4 = Mathf.InverseLerp(num2, num3, num);
float num5 = 1f - num4 * num4 * (3f - 2f * num4);
float num6 = (IsOccluded(position, worldPosition, obstacleMask) ? OccludedVolumeMultiplier.Value : 1f);
float num7 = 1f - Mathf.Exp(-7f * Time.unscaledDeltaTime);
smoothing.Vertical = Mathf.Lerp(smoothing.Vertical, num5, num7);
smoothing.Occlusion = Mathf.Lerp(smoothing.Occlusion, num6, num7);
((Channel)(ref channel)).setVolume(baseVolume * GetGameSfxVolume() * smoothing.Vertical * smoothing.Occlusion);
if (((DSP)(ref reverb)).hasHandle())
{
float value = MinimumDistance.Value;
float num8 = Mathf.Max(value + 0.1f, MaximumDistance.Value);
float num9 = Mathf.InverseLerp(value, num8, Vector3.Distance(position, worldPosition));
float num10 = num9 * num9;
float num11 = Mathf.Clamp01((1f - smoothing.Occlusion) / Mathf.Max(0.001f, 1f - OccludedVolumeMultiplier.Value));
num10 = Mathf.Max(num10, 0.72f * num11);
float num12 = Mathf.Lerp(NearReverbWetLevel.Value, FarReverbWetLevel.Value, num10);
((DSP)(ref reverb)).setParameterFloat(11, num12);
((DSP)(ref reverb)).setParameterFloat(12, Mathf.Lerp(0f, -10f, num10));
((DSP)(ref reverb)).setParameterFloat(0, Mathf.Lerp(900f, 9500f, num10));
((DSP)(ref reverb)).setParameterFloat(1, Mathf.Lerp(8f, 70f, num10));
((DSP)(ref reverb)).setParameterFloat(2, Mathf.Lerp(15f, 100f, num10));
((DSP)(ref reverb)).setParameterFloat(5, Mathf.Lerp(55f, 100f, num10));
((DSP)(ref reverb)).setParameterFloat(6, Mathf.Lerp(45f, 100f, num10));
float num13 = Mathf.Lerp(12000f, 4200f, num10);
num13 = Mathf.Lerp(num13, Mathf.Min(num13, 1800f), num11);
((DSP)(ref reverb)).setParameterFloat(9, num13);
}
}
private float GetGameSfxVolume()
{
//IL_0013: 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)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!((Bus)(ref _sfxBus)).isValid())
{
_sfxBus = RuntimeManager.GetBus("bus:/All/SFX");
}
float num = default(float);
float num2 = default(float);
if (((Bus)(ref _sfxBus)).isValid() && (int)((Bus)(ref _sfxBus)).getVolume(ref num, ref num2) == 0)
{
return Mathf.Clamp01(num2);
}
}
catch
{
}
return 1f;
}
private static bool TryGetListenerPosition(out Vector3 position)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: 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_005d: 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)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
try
{
System coreSystem = RuntimeManager.CoreSystem;
VECTOR val = default(VECTOR);
VECTOR val2 = default(VECTOR);
VECTOR val3 = default(VECTOR);
VECTOR val4 = default(VECTOR);
if ((int)((System)(ref coreSystem)).get3DListenerAttributes(0, ref val, ref val2, ref val3, ref val4) == 0)
{
position = new Vector3(val.x, val.y, val.z);
return true;
}
}
catch
{
}
Camera main = Camera.main;
position = (((Object)(object)main != (Object)null) ? ((Component)main).transform.position : Vector3.zero);
return (Object)(object)main != (Object)null;
}
internal static Vector3 ResolveVisionPosition(ManInShadowsBehaviour enemy)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: 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)
if ((Object)(object)enemy == (Object)null)
{
return Vector3.zero;
}
Transform value = Traverse.Create((object)enemy).Field("_visionPoint").GetValue<Transform>();
if (!((Object)(object)value != (Object)null))
{
return ((Component)enemy).transform.position + Vector3.up * 1.5f;
}
return value.position;
}
internal static int ResolveObstacleMask(ManInShadowsBehaviour enemy)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)enemy == (Object)null)
{
return -5;
}
LayerMask value = Traverse.Create((object)enemy).Field("_obstacleMask").GetValue<LayerMask>();
return ((LayerMask)(ref value)).value;
}
private static bool IsOccluded(Vector3 listenerPosition, Vector3 target, int obstacleMask)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: 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_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = target - listenerPosition;
float magnitude = ((Vector3)(ref val)).magnitude;
if (magnitude <= 0.01f)
{
return false;
}
return Physics.Raycast(listenerPosition + ((Vector3)(ref val)).normalized * 0.1f, ((Vector3)(ref val)).normalized, Mathf.Max(0f, magnitude - 0.1f), obstacleMask, (QueryTriggerInteraction)1);
}
internal void StopReplacement(ManInShadowsBehaviour enemy)
{
//IL_002c: 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)
if ((Object)(object)enemy == (Object)null)
{
return;
}
int instanceID = ((Object)enemy).GetInstanceID();
if (_channels.TryGetValue(instanceID, out var value))
{
if (((Channel)(ref value)).hasHandle())
{
((Channel)(ref value)).stop();
((Channel)(ref value)).clearHandle();
}
_channels.Remove(instanceID);
}
if (_reverbs.TryGetValue(instanceID, out var value2))
{
if (((DSP)(ref value2)).hasHandle())
{
((DSP)(ref value2)).release();
}
_reverbs.Remove(instanceID);
}
_spatialSmoothing.Remove(instanceID);
}
private DSP CreateDistanceReverb(Channel channel)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: 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_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: 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)
System coreSystem = RuntimeManager.CoreSystem;
DSP val2 = default(DSP);
RESULT val = ((System)(ref coreSystem)).createDSPByType((DSP_TYPE)17, ref val2);
if ((int)val != 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not create Shadowman reverb: {val}: {Error.String(val)}");
return default(DSP);
}
((DSP)(ref val2)).setParameterFloat(0, 1800f);
((DSP)(ref val2)).setParameterFloat(11, NearReverbWetLevel.Value);
((DSP)(ref val2)).setParameterFloat(12, 0f);
val = ((Channel)(ref channel)).addDSP(0, val2);
if ((int)val != 0)
{
((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not attach Shadowman reverb: {val}: {Error.String(val)}");
((DSP)(ref val2)).release();
return default(DSP);
}
return val2;
}
private void OnDestroy()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
MinimumDistance.SettingChanged -= OnDistanceChanged;
MaximumDistance.SettingChanged -= OnDistanceChanged;
foreach (Channel value in _channels.Values)
{
Channel current = value;
if (((Channel)(ref current)).hasHandle())
{
((Channel)(ref current)).stop();
}
}
_channels.Clear();
foreach (DSP value2 in _reverbs.Values)
{
DSP current2 = value2;
if (((DSP)(ref current2)).hasHandle())
{
((DSP)(ref current2)).release();
}
}
_reverbs.Clear();
_spatialSmoothing.Clear();
foreach (DeathPlayback deathPlayback in _deathPlaybacks)
{
if (((Channel)(ref deathPlayback.Channel)).hasHandle())
{
((Channel)(ref deathPlayback.Channel)).stop();
}
if (((DSP)(ref deathPlayback.Reverb)).hasHandle())
{
((DSP)(ref deathPlayback.Reverb)).release();
}
}
_deathPlaybacks.Clear();
if (((Sound)(ref _replacementSound)).hasHandle())
{
((Sound)(ref _replacementSound)).release();
((Sound)(ref _replacementSound)).clearHandle();
}
if (((Sound)(ref _deathSound)).hasHandle())
{
((Sound)(ref _deathSound)).release();
((Sound)(ref _deathSound)).clearHandle();
}
Instance = null;
}
}
[HarmonyPatch(typeof(SimpleEnemyHealthController), "ReceiveDamage")]
internal static class ShadowmanDeathPatch
{
private struct DeathState
{
internal bool WasAlive;
internal bool IsShadowman;
internal Vector3 Position;
internal int ObstacleMask;
}
private static void Prefix(SimpleEnemyHealthController __instance, ref DeathState __state)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
__state.WasAlive = __instance.CurrentHealth > 0f;
ManInShadowsBehaviour component = ((Component)__instance).GetComponent<ManInShadowsBehaviour>();
__state.IsShadowman = (Object)(object)component != (Object)null;
__state.Position = Plugin.ResolveVisionPosition(component);
__state.ObstacleMask = Plugin.ResolveObstacleMask(component);
}
private static void Postfix(SimpleEnemyHealthController __instance, DeathState __state)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (__state.WasAlive && __state.IsShadowman && __instance.CurrentHealth <= 0f)
{
Plugin.Instance?.PlayDeathSound(__state.Position, __state.ObstacleMask);
}
}
}
[HarmonyPatch(typeof(ManInShadowsBehaviour), "FixedUpdate")]
internal static class ReplaceWhisperUpdatePatch
{
private static void Postfix(ManInShadowsBehaviour __instance, ref EventInstance ____localVisibilitySoundInstance)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
float visibilityVolume = 1f;
if (((EventInstance)(ref ____localVisibilitySoundInstance)).isValid())
{
((EventInstance)(ref ____localVisibilitySoundInstance)).getVolume(ref visibilityVolume);
((EventInstance)(ref ____localVisibilitySoundInstance)).setVolume(0f);
}
Plugin.Instance?.UpdateReplacement(__instance, visibilityVolume);
}
}
[HarmonyPatch(typeof(ManInShadowsBehaviour), "Despawned")]
internal static class ReplaceWhisperDespawnPatch
{
private static void Prefix(ManInShadowsBehaviour __instance, NetworkRunner runner, bool hasState)
{
Plugin.Instance?.StopReplacement(__instance);
}
}
}