plugins/Guns.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.BepInEx.Configuration;
using SOD.Common.Extensions;
using SOD.Common.Helpers;
using UnityEngine;
using UniverseLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Guns")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Implements player-shootable guns into the game.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0-BE667+0b182f4c2176c5a5610292092ecc4e7adae62c78")]
[assembly: AssemblyProduct("Guns")]
[assembly: AssemblyTitle("Guns")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 Guns
{
	public class GunInfoEntry
	{
		public string ItemPresetName { get; }

		public Vector3 Rotation { get; }

		public float DelayBetweenShotsFactor { get; }

		public float DamageFactor { get; }

		public bool IsFullAuto { get; }

		public Vector3 RecoilPatternFactors { get; }

		public float RecoilAmplitude { get; }

		public float ZoomInOnAimPct { get; }

		public float BaseGameMinBuyPrice { get; }

		public int ProjectilesPerShot { get; }

		public InteractablePreset InteractablePreset { get; internal set; }

		public GunInfoEntry(string itemPresetName, Vector3 rotation, float delayBetweenShotsFactor, float damageFactor, bool isFullAuto, Vector3 recoilPatternFactors, float recoilAmplitude, float zoomInOnAimPct, float baseGameMinBuyPrice, int projectilesPerShot = 1)
		{
			//IL_0010: 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_002e: 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)
			ItemPresetName = itemPresetName;
			Rotation = rotation;
			DelayBetweenShotsFactor = delayBetweenShotsFactor;
			DamageFactor = damageFactor;
			IsFullAuto = isFullAuto;
			RecoilPatternFactors = recoilPatternFactors;
			RecoilAmplitude = recoilAmplitude;
			ZoomInOnAimPct = zoomInOnAimPct;
			BaseGameMinBuyPrice = baseGameMinBuyPrice;
			ProjectilesPerShot = projectilesPerShot;
		}
	}
	internal static class Helpers
	{
		internal static bool IsPlayerHeardByOthers()
		{
			return EnumerableExtensions.Where<AwarenessIcon>(InterfaceController.Instance.awarenessIcons, (Func<AwarenessIcon, bool>)((AwarenessIcon x) => x.alertProgress > 0f)).Any();
		}

		internal static bool IsPlayerBeingPursuedByMurderer()
		{
			return IsPlayerBeingPursuedByActor((Actor)(object)MurderController.Instance.currentMurderer);
		}

		internal static bool IsPlayerBeingPursuedByActor(Actor actor)
		{
			return Player.Instance.persuedProgressLag > 0f && (Object)(object)actor.ai != (Object)null && (Object)(object)actor.ai.persuitTarget == (Object)(object)Player.Instance;
		}

		internal static IEnumerable<T> GetPresetInstances<T>(Func<string, bool> presetNamePredicate = null, bool disallowDupes = true) where T : SoCustomComparison
		{
			Type typeFromHandle = typeof(T);
			IEnumerable<object> source = GetAllUnityObjectsOfType(typeFromHandle ?? typeof(SoCustomComparison));
			if (source.Count() == 0)
			{
				throw new NullReferenceException("No presets found with type " + typeFromHandle.FullName + ".");
			}
			if (presetNamePredicate != null)
			{
				source = source.Where((object obj) => presetNamePredicate(GetPresetName(obj)));
			}
			if (source.Count() <= 0)
			{
				throw new NullReferenceException("No presets of type " + typeFromHandle.FullName + " found matching predicate.");
			}
			if (disallowDupes)
			{
				source = source.DistinctBy(GetPresetKey);
			}
			return source.Select((object x) => ReflectionExtensions.TryCast<T>(x));
		}

		internal static string GetPresetKey(object obj)
		{
			return ReflectionExtensions.GetActualType(obj).FullName + "_" + GetPresetName(obj);
		}

		internal static string GetPresetName(object obj)
		{
			SoCustomComparison val = ReflectionExtensions.TryCast<SoCustomComparison>(obj);
			string presetName;
			try
			{
				return ((Object)val).name;
			}
			catch
			{
				presetName = val.presetName;
				if (presetName != null && presetName != null)
				{
					return presetName;
				}
				presetName = val.GetPresetName();
			}
			return presetName;
		}

		internal static IEnumerable<object> GetAllUnityObjectsOfType(Type type)
		{
			return RuntimeHelper.FindObjectsOfTypeAll(type);
		}

		internal static IEnumerable<object> GetAllUnityObjectsOfType<T>()
		{
			return RuntimeHelper.FindObjectsOfTypeAll(typeof(T));
		}
	}
	public interface IConfigBindings
	{
		[Binding(true, "If true, eject bullet casings.", null)]
		bool EjectBrass { get; set; }

		[Binding(1f, "The factor applied on top of recoil amplitude. Set to 0 to disable recoil completely.", null)]
		float RecoilAmplitudeFactor { get; set; }

		[Binding(0.2f, "The chance (from 0.0 to 1.0 = 100%) that citizens will warn you to put a gun away while you have one drawn.", null)]
		float GunDrawBarkChance { get; set; }

		[Binding(3f, "The number of seconds after a citizen is hit by the player's gunfire that the player has illegal status.", null)]
		float IllegalStatusDurationOnHit { get; set; }

		[Binding(0.5f, "How much of a citizen's nerve is lost per second that the player is aiming directly at them with a gun within the citizen's sight range. Citizen's tend to have maximum nerve values of around 0.4 to 0.5, and start running away around 0.1 (and may attempt to sound the alarm).", null)]
		float CitizenNerveLostPerSecondAimedAt { get; set; }

		[Binding(true, "Account for citizen alertness and blindness when calculating the actual nerve lost per second while being aimed at. The amount of nerve lost will be reduced by some factor depending on the citizen's traits while this setting is enabled.", null)]
		bool CitizenNerveLossAccountsForAwareness { get; set; }

		[Binding(false, "If true, add all guns and ammo to your inventory. Works immediately. Save the setting as false prior to setting it back to true to repeat the command.", null)]
		bool GunTestingMode { get; set; }
	}
	internal sealed class LifeAndLivingIntegration
	{
		internal const string LIFE_AND_LIVING_GUID = "Venomaus.SOD.LifeAndLiving";

		private ManualLogSource Log => PluginController<Plugin, IConfigBindings>.Log;

		internal bool IsActive => Lib.PluginDetection.IsPluginLoaded("Venomaus.SOD.LifeAndLiving");

		internal void Setup()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if (IsActive)
			{
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Detected plugin ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Venomaus.SOD.LifeAndLiving");
				}
				log.LogInfo(val);
				Lib.PluginDetection.AddPluginConfigEntryChangedListener("Venomaus.SOD.LifeAndLiving", (Action<SettingChangedEventArgs>)OnSettingChanged);
			}
		}

		internal void OnSettingChanged(SettingChangedEventArgs args)
		{
			List<string> list = new List<string> { "PercentageValueIncrease", "MinItemValue" };
			Log.LogInfo((object)args.ChangedSetting.Definition.Key);
			if (list.Contains(args.ChangedSetting.Definition.Key))
			{
				Log.LogInfo((object)"Detected adjustment in LifeAndLiving setting, re-adjusting gun prices...");
				PluginController<Plugin, IConfigBindings>.Instance.GunInfoEntries.ForEach(PluginController<Plugin, IConfigBindings>.Instance.CalculateBuyPrice);
			}
		}

		internal void OverwriteVars(ref int minItemValue, ref int percentageValueIncrease)
		{
			if (Lib.PluginDetection.IsPluginLoaded("Venomaus.SOD.LifeAndLiving"))
			{
				minItemValue = Lib.PluginDetection.GetPluginConfigEntryValue<int>("Venomaus.SOD.LifeAndLiving", "LifeAndLiving.ItemPrice", "MinItemValue");
				percentageValueIncrease = Lib.PluginDetection.GetPluginConfigEntryValue<int>("Venomaus.SOD.LifeAndLiving", "LifeAndLiving.ItemPrice", "PercentageValueIncrease");
			}
		}
	}
	internal class Patches
	{
		[HarmonyPatch(typeof(FirstPersonItemController), "FinishedDrawingNewItem")]
		internal class FirstPersonItemController_FinishedDrawingNewItem
		{
			[HarmonyPrefix]
			internal static void Prefix()
			{
				if (PluginController<Plugin, IConfigBindings>.Instance.IsPlayerHoldingAGun())
				{
					FirstPersonItem fpsItem = PluginController<Plugin, IConfigBindings>.Instance.CurrentInteractablePresetHeld.fpsItem;
					fpsItem.barkTriggerChance = 0f;
				}
			}

			[HarmonyPostfix]
			internal static void Postfix()
			{
				PluginController<Plugin, IConfigBindings>.Instance.CurrentWeaponPrimaryState = WeaponPrimaryState.NotAiming;
				if (!PluginController<Plugin, IConfigBindings>.Instance.IsPlayerHoldingAGun())
				{
					PluginController<Plugin, IConfigBindings>.Instance.CurrentWeaponSecondaryState = WeaponSecondaryState.NotEquipped;
					return;
				}
				PluginController<Plugin, IConfigBindings>.Instance.CurrentWeaponSecondaryState = WeaponSecondaryState.NotAiming;
				FirstPersonItem fpsItem = PluginController<Plugin, IConfigBindings>.Instance.CurrentInteractablePresetHeld.fpsItem;
				fpsItem.bark = (Bark)34;
				fpsItem.barkTriggerChance = ((PluginController<Plugin, IConfigBindings>)PluginController<Plugin, IConfigBindings>.Instance).Config.GunDrawBarkChance;
			}
		}

		[HarmonyPatch(typeof(Citizen), "RecieveDamage")]
		internal class Citizen_RecieveDamage
		{
			[HarmonyPrefix]
			internal static void Prefix(Citizen __instance, Actor fromWho, ref bool alertSurrounding)
			{
				if (!alertSurrounding && (!((Object)(object)fromWho != (Object)null) || fromWho.isPlayer) && !((Actor)__instance).isPlayer && PluginController<Plugin, IConfigBindings>.Instance.CurrentWeaponPrimaryState == WeaponPrimaryState.Firing && !Helpers.IsPlayerBeingPursuedByActor((Actor)(object)__instance) && ((Actor)Player.Instance).isSeenByOthers)
				{
					alertSurrounding = true;
				}
			}
		}
	}
	[BepInPlugin("Guns", "Guns", "0.2.0-BE667")]
	[BepInProcess("Shadows of Doubt.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : PluginController<Plugin, IConfigBindings>
	{
		public static Vector3 CircularRecoilPattern;

		public static Vector3 DiagonalRecoilPattern;

		public static Vector3 ShortOvalRecoilPattern;

		public static Vector3 VerticalRecoilPattern;

		internal const float DEFAULT_RECOIL_SPEED = 1f;

		internal const float EJECT_POINT_PROJECTION_FACTOR = 6f;

		internal const string ACTION_DDS_DICTIONARY_NAME = "ui.interaction";

		internal const string ACTION_NAME_AIM = "Aim";

		internal const string ACTION_NAME_ATTACK = "Attack";

		internal const string ACTION_NAME_FIRE = "Fire";

		internal const string ACTION_NAME_THROW = "Throw";

		internal const string LACK_AMMO_MESSAGE_START = "You lack the ammo needed to fire this weapon: ";

		internal const string PRIMARY = "Primary";

		internal const string SECONDARY = "Secondary";

		internal const float TIMER_DURATION = 0.25f;

		public List<GunInfoEntry> GunInfoEntries = new List<GunInfoEntry>
		{
			new GunInfoEntry("BattleRifle", new Vector3(0f, 0f, 0f), 0.2f, 0.7f, isFullAuto: true, DiagonalRecoilPattern, 2.25f, 0.2f, 1000f),
			new GunInfoEntry("Revolver", new Vector3(0f, -90f, 0f), 1f, 1.2f, isFullAuto: false, ShortOvalRecoilPattern, 15f, 0.2f, 400f),
			new GunInfoEntry("SemiAutomaticPistol", new Vector3(0f, -90f, 0f), 0.8f, 1.3f, isFullAuto: false, ShortOvalRecoilPattern, 1f, 0.2f, 150f),
			new GunInfoEntry("SemiAutomaticPistolSilenced", new Vector3(0f, -90f, 0f), 0.8f, 1.3f, isFullAuto: false, ShortOvalRecoilPattern, 1f, 0.2f, 200f),
			new GunInfoEntry("Shotgun", new Vector3(0f, 0f, 0f), 1f, 1f, isFullAuto: false, ShortOvalRecoilPattern, 20f, 0.1f, 500f, 8),
			new GunInfoEntry("SniperRifle", new Vector3(270f, 0f, 0f), 1.5f, 1.4f, isFullAuto: false, CircularRecoilPattern, 30f, 0.6f, 700f)
		};

		public Dictionary<string, GunInfoEntry> GunEntriesByPresetName = new Dictionary<string, GunInfoEntry>();

		private WeaponPrimaryState currentWeaponPrimaryState;

		private WeaponSecondaryState currentWeaponSecondaryState;

		public HashSet<int> WeaponsOnCooldown { get; internal set; } = new HashSet<int>();


		public WeaponPrimaryState CurrentWeaponPrimaryState
		{
			get
			{
				return currentWeaponPrimaryState;
			}
			internal set
			{
				currentWeaponPrimaryState = value;
				WeaponPrimaryState weaponPrimaryState = currentWeaponPrimaryState;
				WeaponPrimaryState weaponPrimaryState2 = weaponPrimaryState;
				if ((uint)(weaponPrimaryState2 - 1) <= 1u)
				{
					SetPrimaryActionFire(showAsFire: true);
				}
				else
				{
					SetPrimaryActionFire(showAsFire: false);
				}
			}
		}

		public WeaponSecondaryState CurrentWeaponSecondaryState
		{
			get
			{
				return currentWeaponSecondaryState;
			}
			internal set
			{
				currentWeaponSecondaryState = value;
				WeaponSecondaryState weaponSecondaryState = currentWeaponSecondaryState;
				WeaponSecondaryState weaponSecondaryState2 = weaponSecondaryState;
				if ((uint)(weaponSecondaryState2 - 1) <= 1u)
				{
					RestartCitizenNerveUnderAimCoroutine();
					SetSecondaryActionAim(showAsAim: true);
				}
				else
				{
					SetSecondaryActionAim(showAsAim: false);
				}
			}
		}

		private bool IsFireHeldDown { get; set; }

		private bool IsGamePaused { get; set; } = false;


		private bool InGameSetupCompleted { get; set; } = false;


		private Coroutine CameraFovTweenCoroutine { get; set; }

		private Coroutine CitizenNerveUnderAimCoroutine { get; set; }

		internal InteractablePreset CurrentInteractablePresetHeld
		{
			get
			{
				InventorySlot selectedSlot = BioScreenController.Instance.selectedSlot;
				object result;
				if (selectedSlot == null)
				{
					result = null;
				}
				else
				{
					Interactable interactable = selectedSlot.GetInteractable();
					result = ((interactable != null) ? interactable.preset : null);
				}
				return (InteractablePreset)result;
			}
		}

		internal LifeAndLivingIntegration LifeAndLivingIntegration { get; } = new LifeAndLivingIntegration();


		public override void Load()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			ManualLogSource log = PluginController<Plugin, IConfigBindings>.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Guns");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
			base.Harmony.PatchAll();
			ManualLogSource log2 = PluginController<Plugin, IConfigBindings>.Log;
			val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Guns");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is patched!");
			}
			log2.LogInfo(val);
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			Lib.SaveGame.OnAfterNewGame += OnAfterNewGame;
			Lib.Time.OnGamePaused += OnGamePaused;
			Lib.Time.OnGameResumed += OnGameResumed;
			Lib.InputDetection.OnButtonStateChanged += OnButtonStateChanged;
			base.ConfigFile.SettingChanged += ProcessSettingChange;
			LifeAndLivingIntegration.Setup();
		}

		public override bool Unload()
		{
			Harmony harmony = base.Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterNewGame -= OnAfterNewGame;
			Lib.Time.OnGamePaused -= OnGamePaused;
			Lib.Time.OnGameResumed -= OnGameResumed;
			Lib.InputDetection.OnButtonStateChanged -= OnButtonStateChanged;
			base.ConfigFile.SettingChanged -= ProcessSettingChange;
			return base.Unload();
		}

		private void ProcessSettingChange(object sender, SettingChangedEventArgs e)
		{
			if (InGameSetupCompleted && base.Config.GunTestingMode)
			{
				FirstPersonItemController.Instance.SetSlotSize(12);
				EnumerableExtensions.ForEach<InteractablePreset>(GunEntriesByPresetName.Values.Select((GunInfoEntry x) => x.InteractablePreset), (Action<InteractablePreset>)delegate(InteractablePreset x)
				{
					x.SpawnIntoInventory();
				});
				EnumerableExtensions.ForEach<InteractablePreset>(GunEntriesByPresetName.Values.Select((GunInfoEntry x) => x.InteractablePreset.weapon.ammunition[0]), (Action<InteractablePreset>)delegate(InteractablePreset x)
				{
					x.SpawnIntoInventory();
				});
			}
		}

		private void OnAfterNewGame(object sender, EventArgs e)
		{
			InGameSetup();
		}

		private void OnAfterLoad(object sender, SaveGameArgs e)
		{
			InGameSetup();
		}

		private Human GetHumanThatPlayerIsAimingAt()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002f: 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_0031: 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_0033: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)CameraController.Instance.cam).transform.position;
			Vector3 val = ((Component)CameraController.Instance.cam).transform.TransformPoint(Vector3.forward);
			Vector3 val2 = val - position;
			RaycastHit val3 = default(RaycastHit);
			if (!Physics.Raycast(position, ((Vector3)(ref val2)).normalized, ref val3, GameplayControls.Instance.citizenSightRange, Toolbox.Instance.physicalObjectsLayerMask))
			{
				return null;
			}
			Human val4 = ((Component)((RaycastHit)(ref val3)).transform).gameObject.GetComponent<Human>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = ((Component)((RaycastHit)(ref val3)).transform).gameObject.GetComponentInParent<Human>();
			}
			if ((Object)(object)val4 == (Object)null || ((Actor)val4).isPlayer || ((Actor)val4).isMachine)
			{
				return null;
			}
			return val4;
		}

		public void InGameSetup()
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			currentWeaponPrimaryState = WeaponPrimaryState.NotAiming;
			currentWeaponSecondaryState = WeaponSecondaryState.NotEquipped;
			GunEntriesByPresetName.Clear();
			IsFireHeldDown = false;
			WeaponsOnCooldown.Clear();
			Lib.DdsStrings.AddOrUpdateEntries("ui.interaction", new(string, string)[2]
			{
				("Aim", "Aim"),
				("Fire", "Fire")
			});
			IEnumerable<InteractablePreset> presetInstances = Helpers.GetPresetInstances<InteractablePreset>((Func<string, bool>)null, disallowDupes: true);
			for (int i = 0; i < GunInfoEntries.Count; i++)
			{
				GunInfoEntry entry = GunInfoEntries[i];
				entry.InteractablePreset = presetInstances.First((InteractablePreset x) => ((SoCustomComparison)x).presetName == entry.ItemPresetName);
				GunEntriesByPresetName.Add(entry.ItemPresetName, entry);
				CalculateBuyPrice(entry);
			}
			foreach (var (text2, gunInfoEntry2) in GunEntriesByPresetName)
			{
				gunInfoEntry2.InteractablePreset.fpsItemOffset = Vector3.zero;
				gunInfoEntry2.InteractablePreset.fpsItemRotation = gunInfoEntry2.Rotation;
			}
			InGameSetupCompleted = true;
		}

		internal void CalculateBuyPrice(GunInfoEntry entry)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			int minItemValue = 100;
			int percentageValueIncrease = 0;
			if (LifeAndLivingIntegration.IsActive)
			{
				LifeAndLivingIntegration.OverwriteVars(ref minItemValue, ref percentageValueIncrease);
			}
			InteractablePreset preset = entry.InteractablePreset;
			float num = entry.BaseGameMinBuyPrice / 100f;
			float num2 = Math.Max(100f, minItemValue) * (1f + (float)percentageValueIncrease / 100f) * num;
			float num3 = Math.Max(100f, minItemValue) * (1f + (float)percentageValueIncrease / 100f) * num;
			preset.value = new Vector2((float)(int)num2, (float)(int)num3);
			ManualLogSource log = PluginController<Plugin, IConfigBindings>.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Adjusted item purchase price of ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((SoCustomComparison)preset).presetName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" to (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(preset.value.x);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" - ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(preset.value.y);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
			}
			log.LogInfo(val);
			IEnumerable<Company> enumerable = from c in EnumerableExtensions.ToList<Company>(CityData.Instance.companyDirectory)
				where c.prices.ContainsKey(preset)
				select c;
			foreach (Company item in enumerable)
			{
				if (item.prices.ContainsKey(preset))
				{
					float num4 = Random.Shared.NextSingle() * (preset.value.y - preset.value.x) + preset.value.x;
					num4 = (float)Math.Floor(num4);
					item.prices[preset] = (int)num4;
					ManualLogSource log2 = PluginController<Plugin, IConfigBindings>.Log;
					val = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("  Applied change to ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.name);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num4);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
					}
					log2.LogInfo(val);
				}
			}
		}

		private void OnButtonStateChanged(object sender, InputDetectionEventArgs eventArgs)
		{
			if (!InGameSetupCompleted || (eventArgs.ActionName != "Primary" && eventArgs.ActionName != "Secondary"))
			{
				return;
			}
			if (!IsPlayerHoldingAGun())
			{
				CurrentWeaponSecondaryState = WeaponSecondaryState.NotEquipped;
				RestartCameraAimModeCoroutine(enter: false);
				return;
			}
			if (eventArgs.ActionName == "Primary")
			{
				IsFireHeldDown = eventArgs.IsDown;
			}
			switch (CurrentWeaponSecondaryState)
			{
			case WeaponSecondaryState.NotAiming:
				if (eventArgs.ActionName == "Secondary" && eventArgs.IsDown)
				{
					CurrentWeaponSecondaryState = WeaponSecondaryState.Aiming;
					CurrentWeaponPrimaryState = WeaponPrimaryState.Aiming;
					RestartCameraAimModeCoroutine(enter: true);
				}
				break;
			case WeaponSecondaryState.Aiming:
				if (eventArgs.ActionName == "Secondary" && !eventArgs.IsDown)
				{
					CurrentWeaponSecondaryState = WeaponSecondaryState.NotAiming;
					CurrentWeaponPrimaryState = WeaponPrimaryState.NotAiming;
					RestartCameraAimModeCoroutine(enter: false);
				}
				else if (IsFireHeldDown)
				{
					FireWeapon();
				}
				break;
			}
		}

		public bool IsPlayerHoldingAGun()
		{
			return (SoCustomComparison)(object)CurrentInteractablePresetHeld != (SoCustomComparison)null && GunEntriesByPresetName.Keys.Contains(((SoCustomComparison)CurrentInteractablePresetHeld).presetName);
		}

		private void RestartCitizenNerveUnderAimCoroutine()
		{
			if (CitizenNerveUnderAimCoroutine != null)
			{
				RuntimeHelper.StopCoroutine(CitizenNerveUnderAimCoroutine);
			}
			if (!(base.Config.CitizenNerveLostPerSecondAimedAt <= float.Epsilon))
			{
				CitizenNerveUnderAimCoroutine = RuntimeHelper.StartCoroutine(InGameTimer(0.25f, ReduceCitizenNerveUnderAim));
			}
		}

		private void ReduceCitizenNerveUnderAim()
		{
			//IL_0058: 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_0072: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPlayerHoldingAGun())
			{
				return;
			}
			Human humanThatPlayerIsAimingAt = GetHumanThatPlayerIsAimingAt();
			if ((Object)(object)humanThatPlayerIsAimingAt == (Object)null || ((Actor)humanThatPlayerIsAimingAt).isAsleep || ((Actor)humanThatPlayerIsAimingAt).isDead || ((Actor)humanThatPlayerIsAimingAt).isStunned)
			{
				RestartCitizenNerveUnderAimCoroutine();
				return;
			}
			Quaternion val = Quaternion.FromToRotation(((Actor)humanThatPlayerIsAimingAt).ai.facingDirection, ((Actor)Player.Instance).aimTransform.position - ((Actor)humanThatPlayerIsAimingAt).aimTransform.position);
			float num = Quaternion.Angle(Quaternion.identity, val);
			if (num > GameplayControls.Instance.citizenFOV / 2f)
			{
				RestartCitizenNerveUnderAimCoroutine();
				return;
			}
			float num2 = Player.Instance.visibilityLag;
			if (base.Config.CitizenNerveLossAccountsForAwareness)
			{
				num2 = ((humanThatPlayerIsAimingAt.blinded > 0f) ? (humanThatPlayerIsAimingAt.alertness - humanThatPlayerIsAimingAt.blinded) : humanThatPlayerIsAimingAt.alertness);
				num2 = Math.Clamp(num2, 0f, 1f);
			}
			float num3 = 1f - Vector3.Distance(((Component)Player.Instance).transform.position, ((Component)humanThatPlayerIsAimingAt).transform.position) / GameplayControls.Instance.citizenSightRange;
			float num4 = base.Config.CitizenNerveLostPerSecondAimedAt * 0.25f * num2 * num3;
			((Actor)humanThatPlayerIsAimingAt).AddNerve(-1f * num4, (Actor)(object)Player.Instance);
			RestartCitizenNerveUnderAimCoroutine();
		}

		private void RestartCameraAimModeCoroutine(bool enter)
		{
			if (CameraFovTweenCoroutine != null)
			{
				RuntimeHelper.StopCoroutine(CameraFovTweenCoroutine);
			}
			if (enter)
			{
				CameraFovTweenCoroutine = RuntimeHelper.StartCoroutine(InGameTween(0.25f, AdjustCameraEnterAimMode));
			}
			else
			{
				CameraFovTweenCoroutine = RuntimeHelper.StartCoroutine(InGameTween(0.25f, AdjustCameraExitAimMode));
			}
		}

		internal void AdjustCameraEnterAimMode(float progressPct)
		{
			if (!IsPlayerHoldingAGun())
			{
				RestartCameraAimModeCoroutine(enter: false);
				return;
			}
			float zoomInOnAimPct = GunEntriesByPresetName[((SoCustomComparison)CurrentInteractablePresetHeld).presetName].ZoomInOnAimPct;
			float fieldOfView = CameraController.Instance.cam.fieldOfView;
			int fov = Game.Instance.fov;
			float num = (float)fov * (1f - zoomInOnAimPct);
			CameraController.Instance.cam.fieldOfView = fieldOfView - (fieldOfView - num) * progressPct;
		}

		internal void AdjustCameraExitAimMode(float progressPct)
		{
			float fieldOfView = CameraController.Instance.cam.fieldOfView;
			int fov = Game.Instance.fov;
			CameraController.Instance.cam.fieldOfView = fieldOfView - (fieldOfView - (float)fov) * progressPct;
		}

		public void FireWeapon()
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			if (!InGameSetupCompleted || IsGamePaused)
			{
				return;
			}
			MurderWeaponPreset weapon = CurrentInteractablePresetHeld.weapon;
			int weaponHash = ((Object)weapon).GetHashCode();
			if (WeaponsOnCooldown.Contains(weaponHash) || CurrentWeaponSecondaryState != WeaponSecondaryState.Aiming || CurrentWeaponPrimaryState != WeaponPrimaryState.Aiming)
			{
				return;
			}
			CurrentWeaponPrimaryState = WeaponPrimaryState.Firing;
			GunInfoEntry gunInfoEntry = GunEntriesByPresetName[((SoCustomComparison)CurrentInteractablePresetHeld).presetName];
			float attackValue = weapon.GetAttackValue((AttackValue)0, (Human)(object)Player.Instance);
			float durationSec = weapon.GetAttackValue((AttackValue)1, (Human)(object)Player.Instance) * gunInfoEntry.DelayBetweenShotsFactor;
			float attackValue2 = weapon.GetAttackValue((AttackValue)2, (Human)(object)Player.Instance);
			float num = weapon.GetAttackValue((AttackValue)3, (Human)(object)Player.Instance) * gunInfoEntry.DamageFactor;
			Vector3 muzzlePoint = FirstPersonItemController.Instance.rightHandObjectParent.TransformPoint(weapon.itemRightLocalPos);
			Vector3 val = FirstPersonItemController.Instance.rightHandObjectParent.TransformPoint(weapon.itemRightLocalPos + Vector3.back * 6f);
			Vector3 position = ((Component)CameraController.Instance.cam).transform.position;
			Vector3 val2 = ((Component)CameraController.Instance.cam).transform.TransformPoint(Vector3.forward);
			CreateMuzzleFlash(weapon, muzzlePoint, val2);
			GameObject muzzleFlash = weapon.muzzleFlash;
			weapon.muzzleFlash = null;
			Toolbox.Instance.Shoot((Actor)(object)Player.Instance, position, val2, attackValue, attackValue2, num, weapon, base.Config.EjectBrass, val, false, true);
			if (gunInfoEntry.ProjectilesPerShot > 1)
			{
				AudioEvent fireEvent = weapon.fireEvent;
				weapon.fireEvent = null;
				AudioEvent impactEvent = weapon.impactEvent;
				weapon.impactEvent = null;
				AudioEvent impactEventPlayer = weapon.impactEventPlayer;
				weapon.impactEventPlayer = null;
				int i = 1;
				for (int projectilesPerShot = gunInfoEntry.ProjectilesPerShot; i < projectilesPerShot; i++)
				{
					Toolbox.Instance.Shoot((Actor)(object)Player.Instance, position, val2, attackValue, attackValue2, num, weapon, false, val, false, false);
				}
				weapon.fireEvent = fireEvent;
				weapon.impactEvent = impactEvent;
				weapon.impactEventPlayer = impactEventPlayer;
			}
			weapon.muzzleFlash = muzzleFlash;
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(Toolbox.Instance.Rand(-1f, 1f, false), Toolbox.Instance.Rand(-1f, 1f, false), Toolbox.Instance.Rand(-1f, 1f, false));
			((Vector3)(ref val3)).Scale(gunInfoEntry.RecoilPatternFactors);
			Player.Instance.fps.JoltCamera(val3, gunInfoEntry.RecoilAmplitude * base.Config.RecoilAmplitudeFactor, 1f);
			ApplyPlayerIllegalActionStatus();
			WeaponsOnCooldown.Add(weaponHash);
			CurrentWeaponPrimaryState = WeaponPrimaryState.Aiming;
			RuntimeHelper.StartCoroutine(InGameTimer(durationSec, delegate
			{
				if (WeaponsOnCooldown.Contains(weaponHash))
				{
					WeaponsOnCooldown.Remove(weaponHash);
				}
				if (gunInfoEntry.IsFullAuto && !((SoCustomComparison)(object)CurrentInteractablePresetHeld == (SoCustomComparison)null) && !((SoCustomComparison)(object)CurrentInteractablePresetHeld.weapon != (SoCustomComparison)(object)weapon) && IsFireHeldDown)
				{
					FireWeapon();
				}
			}));
		}

		private void CreateMuzzleFlash(MurderWeaponPreset weapon, Vector3 muzzlePoint, Vector3 forward)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)weapon.muzzleFlash == (Object)null))
			{
				GameObject val = Object.Instantiate<GameObject>(weapon.muzzleFlash, PrefabControls.Instance.mapContainer);
				val.transform.position = muzzlePoint;
				val.transform.rotation = Quaternion.LookRotation(forward, val.transform.up);
			}
		}

		private void ApplyPlayerIllegalActionStatus()
		{
			if (((Actor)Player.Instance).isHome || Helpers.IsPlayerBeingPursuedByMurderer() || (!((Actor)Player.Instance).isSeenByOthers && !Helpers.IsPlayerHeardByOthers()))
			{
				Lib.PlayerStatus.RemoveIllegalStatusModifier("Guns");
			}
			else
			{
				Lib.PlayerStatus.SetIllegalStatusModifier("Guns", (TimeSpan?)TimeSpan.FromSeconds(base.Config.IllegalStatusDurationOnHit), true);
			}
		}

		private IEnumerator InGameTimer(float durationSec, Action actionOnCompletion)
		{
			float timePassed = 0f;
			while (timePassed < durationSec)
			{
				yield return (object)new WaitForEndOfFrame();
				if (!IsGamePaused)
				{
					timePassed += Time.deltaTime;
				}
			}
			actionOnCompletion();
		}

		private IEnumerator InGameTween(float durationSec, Action<float> actionPerTick)
		{
			float timePassed = 0f;
			while (timePassed < durationSec)
			{
				yield return (object)new WaitForEndOfFrame();
				if (!IsGamePaused)
				{
					timePassed += Time.deltaTime;
					actionPerTick(timePassed / durationSec);
				}
			}
		}

		private void SetPrimaryActionFire(bool showAsFire)
		{
			if (!InGameSetupCompleted || (SoCustomComparison)(object)CurrentInteractablePresetHeld == (SoCustomComparison)null)
			{
				return;
			}
			FPSInteractionAction val;
			try
			{
				val = EnumerableExtensions.ToList<FPSInteractionAction>(CurrentInteractablePresetHeld.fpsItem.actions).First((FPSInteractionAction x) => ((SoCustomComparison)((InteractionAction)x).action).presetName == "FPSPunch");
			}
			catch
			{
				return;
			}
			if (!showAsFire)
			{
				((InteractionAction)val).interactionName = "Attack";
				val.useCameraJolt = true;
				val.mainSpecialAction = (SpecialAction)4;
				InteractionController.Instance.UpdateInteractionText();
			}
			else
			{
				((InteractionAction)val).interactionName = "Fire";
				val.useCameraJolt = false;
				val.mainSpecialAction = (SpecialAction)0;
				InteractionController.Instance.UpdateInteractionText();
			}
		}

		private void SetSecondaryActionAim(bool showAsAim)
		{
			if (!InGameSetupCompleted || (SoCustomComparison)(object)CurrentInteractablePresetHeld == (SoCustomComparison)null)
			{
				return;
			}
			FPSInteractionAction val;
			try
			{
				val = EnumerableExtensions.ToList<FPSInteractionAction>(CurrentInteractablePresetHeld.fpsItem.actions).First((FPSInteractionAction x) => ((SoCustomComparison)((InteractionAction)x).action).presetName == "FPSThrow");
			}
			catch
			{
				return;
			}
			if (!showAsAim)
			{
				((InteractionAction)val).interactionName = "Throw";
				((InteractionAction)val).action.throwObjectsAtTarget = true;
				val.mainSpecialAction = (SpecialAction)8;
				InteractionController.Instance.UpdateInteractionText();
			}
			else
			{
				((InteractionAction)val).interactionName = "Aim";
				((InteractionAction)val).action.throwObjectsAtTarget = false;
				val.mainSpecialAction = (SpecialAction)0;
				InteractionController.Instance.UpdateInteractionText();
			}
		}

		private void OnGameResumed(object sender, EventArgs e)
		{
			IsGamePaused = false;
		}

		private void OnGamePaused(object sender, EventArgs e)
		{
			IsGamePaused = true;
		}

		static Plugin()
		{
			//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_0008: 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_0021: 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_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)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_0063: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.one;
			CircularRecoilPattern = ((Vector3)(ref val)).normalized;
			val = new Vector3(1f, 0.5f, 1f);
			DiagonalRecoilPattern = ((Vector3)(ref val)).normalized;
			val = new Vector3(1f, 1f, 0.5f);
			ShortOvalRecoilPattern = ((Vector3)(ref val)).normalized;
			val = new Vector3(0.2f, 1f, 0.2f);
			VerticalRecoilPattern = ((Vector3)(ref val)).normalized;
		}
	}
	public enum WeaponPrimaryState
	{
		NotAiming,
		Aiming,
		Firing
	}
	public enum WeaponSecondaryState
	{
		NotEquipped,
		NotAiming,
		Aiming
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Guns";

		public const string PLUGIN_NAME = "Guns";

		public const string PLUGIN_VERSION = "0.2.0-BE667";
	}
}