Decompiled source of DefenseBudget v1.0.1

DefenseBudget.dll

Decompiled 18 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DefenseBudget.Artifacts;
using DefenseBudget.Items;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using RoR2;
using RoR2.ExpansionManagement;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DefenseBudget")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+8aae8f5dc77740bd536f6fa39d9e3e44e3584080")]
[assembly: AssemblyProduct("DefenseBudget")]
[assembly: AssemblyTitle("DefenseBudget")]
[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 DefenseBudget
{
	internal static class Assets
	{
		private static GameObject prefabHolder;

		internal static Transform PrefabHolder
		{
			get
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Expected O, but got Unknown
				if (!Object.op_Implicit((Object)(object)prefabHolder))
				{
					prefabHolder = new GameObject("DefenseBudgetPrefabHolder");
					Object.DontDestroyOnLoad((Object)(object)prefabHolder);
					prefabHolder.SetActive(false);
				}
				return prefabHolder.transform;
			}
		}

		internal static void SetItemTier(ItemDef def, ItemTier tier)
		{
			//IL_0007: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			typeof(ItemDef).GetField("deprecatedTier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(def, tier);
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(tier);
				if (Object.op_Implicit((Object)(object)itemTierDef))
				{
					typeof(ItemDef).GetField("_itemTierDef", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(def, itemTierDef);
				}
			});
		}

		internal static ItemDef CreateItemDef(string name, string tokenBase, ItemTier tier, Sprite icon, GameObject model, ItemTag[] tags, bool canRemove = true)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			ItemDef val = ScriptableObject.CreateInstance<ItemDef>();
			((Object)val).name = name;
			val.nameToken = tokenBase + "_NAME";
			val.pickupToken = tokenBase + "_PICKUP";
			val.descriptionToken = tokenBase + "_DESC";
			val.loreToken = tokenBase + "_LORE";
			val.canRemove = canRemove;
			val.hidden = false;
			val.tags = tags;
			val.pickupIconSprite = icon;
			val.pickupModelPrefab = model;
			SetItemTier(val, tier);
			return val;
		}

		private static byte[] ReadResource(string resourceName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		internal static Texture2D LoadRawTexture(string resourceName, int size)
		{
			//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_0037: Expected O, but got Unknown
			try
			{
				byte[] array = ReadResource(resourceName);
				if (array == null || array.Length != size * size * 4)
				{
					return null;
				}
				Texture2D val = new Texture2D(size, size, (TextureFormat)4, false)
				{
					wrapMode = (TextureWrapMode)1
				};
				val.LoadRawTextureData(array);
				val.Apply();
				return val;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to load texture '{resourceName}': {arg}");
				return null;
			}
		}

		internal static Sprite LoadSprite(string resourceName, int size)
		{
			//IL_0023: 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)
			Texture2D val = LoadRawTexture(resourceName, size);
			return Object.op_Implicit((Object)(object)val) ? Sprite.Create(val, new Rect(0f, 0f, (float)size, (float)size), new Vector2(0.5f, 0.5f)) : null;
		}

		internal static Material CreatePickupMaterial(Color color, Texture2D mainTexture, Color emission)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0059: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/LunarCoin/PickupLunarCoin.prefab").WaitForCompletion();
			Renderer val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<Renderer>(true) : null);
			Material val3 = ((Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.sharedMaterial)) ? new Material(val2.sharedMaterial) : new Material(Shader.Find("Standard")));
			string[] array = new string[5] { "_MainTex", "_NormalTex", "_BumpMap", "_EmTex", "_EmissionMap" };
			foreach (string text in array)
			{
				if (val3.HasProperty(text))
				{
					val3.SetTexture(text, (Texture)(object)((!(text == "_MainTex")) ? null : (Object.op_Implicit((Object)(object)mainTexture) ? mainTexture : Texture2D.whiteTexture)));
				}
			}
			if (val3.HasProperty("_Color"))
			{
				val3.color = color;
			}
			if (val3.HasProperty("_EmColor"))
			{
				val3.SetColor("_EmColor", emission);
			}
			return val3;
		}

		internal static Mesh LoadObjMesh(string resourceName)
		{
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = ReadResource(resourceName);
			if (array == null)
			{
				return null;
			}
			List<Vector3> positions = new List<Vector3>();
			List<Vector2> texCoords = new List<Vector2>();
			List<Vector3> objNormals = new List<Vector3>();
			Dictionary<(int, int, int), int> vertexMap = new Dictionary<(int, int, int), int>();
			List<Vector3> vertices = new List<Vector3>();
			List<Vector2> uvs = new List<Vector2>();
			List<Vector3> normals = new List<Vector3>();
			List<int> list = new List<int>();
			using (StreamReader streamReader = new StreamReader(new MemoryStream(array)))
			{
				string text;
				while ((text = streamReader.ReadLine()) != null)
				{
					string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
					if (array2.Length == 0)
					{
						continue;
					}
					switch (array2[0])
					{
					case "v":
						positions.Add(new Vector3(0f - float.Parse(array2[1], CultureInfo.InvariantCulture), float.Parse(array2[2], CultureInfo.InvariantCulture), float.Parse(array2[3], CultureInfo.InvariantCulture)));
						break;
					case "vt":
						texCoords.Add(new Vector2(float.Parse(array2[1], CultureInfo.InvariantCulture), float.Parse(array2[2], CultureInfo.InvariantCulture)));
						break;
					case "vn":
						objNormals.Add(new Vector3(0f - float.Parse(array2[1], CultureInfo.InvariantCulture), float.Parse(array2[2], CultureInfo.InvariantCulture), float.Parse(array2[3], CultureInfo.InvariantCulture)));
						break;
					case "f":
					{
						int item = ResolveVertex(array2[1]);
						int item2 = ResolveVertex(array2[2]);
						for (int i = 3; i < array2.Length; i++)
						{
							int num = ResolveVertex(array2[i]);
							list.Add(item);
							list.Add(num);
							list.Add(item2);
							item2 = num;
						}
						break;
					}
					}
				}
			}
			Mesh val = new Mesh
			{
				indexFormat = (IndexFormat)1
			};
			val.SetVertices(vertices);
			val.SetUVs(0, uvs);
			val.SetNormals(normals);
			val.SetTriangles(list, 0);
			val.RecalculateBounds();
			return val;
			int ResolveVertex(string token)
			{
				//IL_00f0: 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_0105: 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)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				string[] array3 = token.Split('/');
				int num2 = int.Parse(array3[0], CultureInfo.InvariantCulture);
				int num3 = ((array3.Length > 1 && array3[1].Length > 0) ? int.Parse(array3[1], CultureInfo.InvariantCulture) : 0);
				int num4 = ((array3.Length > 2 && array3[2].Length > 0) ? int.Parse(array3[2], CultureInfo.InvariantCulture) : 0);
				if (num2 < 0)
				{
					num2 += positions.Count + 1;
				}
				if (num3 < 0)
				{
					num3 += texCoords.Count + 1;
				}
				if (num4 < 0)
				{
					num4 += objNormals.Count + 1;
				}
				(int, int, int) key = (num2, num3, num4);
				if (vertexMap.TryGetValue(key, out var value))
				{
					return value;
				}
				value = vertices.Count;
				vertices.Add(positions[num2 - 1]);
				uvs.Add((num3 > 0) ? texCoords[num3 - 1] : Vector2.zero);
				normals.Add((num4 > 0) ? objNormals[num4 - 1] : Vector3.up);
				vertexMap[key] = value;
				return value;
			}
		}

		internal static GameObject CreatePickupModel(string name, string objResource, string textureResource, int textureSize, float targetSize, Func<GameObject> fallback = null)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00b8: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00ea: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Mesh val = LoadObjMesh(objResource);
				if ((Object)(object)val == (Object)null)
				{
					Log.Warning("Model resource '" + objResource + "' missing; using fallback model for " + name + ".");
					return (fallback != null) ? fallback() : MysteryModel();
				}
				Texture2D mainTexture = LoadRawTexture(textureResource, textureSize);
				GameObject val2 = new GameObject(name);
				val2.transform.SetParent(PrefabHolder);
				val2.AddComponent<MeshFilter>().mesh = val;
				((Renderer)val2.AddComponent<MeshRenderer>()).material = CreatePickupMaterial(Color.white, mainTexture, Color.black);
				float[] array = new float[3];
				Bounds bounds = val.bounds;
				array[0] = ((Bounds)(ref bounds)).size.x;
				bounds = val.bounds;
				array[1] = ((Bounds)(ref bounds)).size.y;
				bounds = val.bounds;
				array[2] = ((Bounds)(ref bounds)).size.z;
				float num = Mathf.Max(array);
				if (num > 0f)
				{
					val2.transform.localScale = Vector3.one * (targetSize / num);
				}
				return val2;
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to build pickup model {name}: {arg}");
				return (fallback != null) ? fallback() : MysteryModel();
			}
		}

		internal static GameObject MysteryModel()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Mystery/PickupMystery.prefab").WaitForCompletion();
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Isaac_Cummings.DefenseBudget", "DefenseBudget", "1.0.1")]
	public class DefenseBudgetPlugin : BaseUnityPlugin
	{
		private class CostTracker : MonoBehaviour
		{
			public PurchaseInteraction purchaseInteraction;

			public float appliedMultiplier = 1f;

			public int settleTicks = 2;
		}

		private class DebtTracker : MonoBehaviour
		{
			public double debt;

			public bool wasDefaulted;
		}

		public const string PluginGUID = "Isaac_Cummings.DefenseBudget";

		public const string PluginAuthor = "Isaac_Cummings";

		public const string PluginName = "DefenseBudget";

		public const string PluginVersion = "1.0.1";

		private const float DamageTickInterval = 0.5f;

		private const float MultiplierTickInterval = 0.2f;

		public static ItemDef itemDef;

		public static BuffDef inDebtBuff;

		public static BuffDef defaultedBuff;

		public static ConfigEntry<float> CostIncreasePerStack;

		public static ConfigEntry<float> IncomeReductionPerStack;

		public static ConfigEntry<int> BaseDebtLimit;

		public static ConfigEntry<float> InterestRatePerSecond;

		public static ConfigEntry<float> DefaultDamagePerSecond;

		public static ConfigEntry<float> DeficitSpendingBonusPerStack;

		public static ConfigEntry<KeyboardShortcut> DebugSpawnItemKey;

		public static ConfigEntry<KeyboardShortcut> DebugSpawnPackKey;

		private static readonly List<CostTracker> costTrackers = new List<CostTracker>();

		private static bool applyingDefaultDamage;

		private float interestTimer;

		private float damageTimer;

		private float multiplierTimer;

		private static readonly string[] DollarGlyph = new string[7] { "..X..", ".XXXX", "X.X..", ".XXX.", "..X.X", "XXXX.", "..X.." };

		private static Color moneyTextOriginalColor;

		private static bool moneyTextColorCached;

		public void Awake()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			Log.Init(((BaseUnityPlugin)this).Logger);
			BindConfig();
			CreateItem();
			CreateBuffs();
			CreateLanguage();
			SavingsBond.Init(((BaseUnityPlugin)this).Config);
			AccountsReceivable.Init(((BaseUnityPlugin)this).Config);
			GoldenParachute.Init(((BaseUnityPlugin)this).Config);
			FinalNotice.Init(((BaseUnityPlugin)this).Config);
			ArtifactOfCommunism.Init(((BaseUnityPlugin)this).Config);
			PurchaseInteraction.Awake += new hook_Awake(PurchaseInteraction_Awake);
			PurchaseInteraction.CanBeAffordedByInteractor += new hook_CanBeAffordedByInteractor(PurchaseInteraction_CanBeAffordedByInteractor);
			PurchaseInteraction.OnInteractionBegin += new hook_OnInteractionBegin(PurchaseInteraction_OnInteractionBegin);
			CharacterMaster.GiveMoney += new hook_GiveMoney(CharacterMaster_GiveMoney);
			HealthComponent.TakeDamage += new hook_TakeDamage(HealthComponent_TakeDamage);
			MoneyText.Update += new hook_Update(MoneyText_Update);
			Run.onRunStartGlobal += delegate
			{
				costTrackers.Clear();
			};
			Log.Info("DefenseBudget loaded.");
		}

		private void BindConfig()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			CostIncreasePerStack = ((BaseUnityPlugin)this).Config.Bind<float>("DefenseBudget", "CostIncreasePerStack", 0f, "Additional gold-cost multiplier per stack across all players. 2.0 = +200% per stack (x3 with one stack). WARNING: chest prices are shared, so in multiplayer this inflates costs for everyone, including players without the item. Disabled by default in favor of IncomeReductionPerStack.");
			IncomeReductionPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("DefenseBudget", "IncomeReductionPerStack", 0.25f, "Fraction of gold income lost per stack, multiplicative (0.25 = 75% income with one stack, 56% with two, 42% with three). Only affects the holder.");
			BaseDebtLimit = ((BaseUnityPlugin)this).Config.Bind<int>("DefenseBudget", "BaseDebtLimit", 75, "Debt limit per stack, in base gold. Scales with difficulty over time exactly like chest prices (a small chest is 25 base).");
			InterestRatePerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("DefenseBudget", "InterestRatePerSecond", 0.01f, "While in debt, debt grows by this fraction of itself per second (minimum 1 gold/sec).");
			DefaultDamagePerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("DefenseBudget", "DefaultDamagePerSecond", 0.02f, "Fraction of maximum health lost per second while debt exceeds the debt limit.");
			DeficitSpendingBonusPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("DefenseBudget", "DeficitSpendingBonusPerStack", 0.15f, "Damage bonus per stack while in debt ('deficit spending'). Set to 0 to disable.");
			DebugSpawnItemKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "SpawnItemKey", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Drops a Defense Budget at your feet for testing (host only). Set to an empty shortcut to disable.");
			DebugSpawnPackKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "SpawnPackKey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Drops one of each pack item (Savings Bond, Accounts Receivable, Golden Parachute, Final Notice) for testing (host only).");
		}

		private void CreateItem()
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			itemDef = ScriptableObject.CreateInstance<ItemDef>();
			((Object)itemDef).name = "DefenseBudget";
			itemDef.nameToken = "DEFENSE_BUDGET_NAME";
			itemDef.pickupToken = "DEFENSE_BUDGET_PICKUP";
			itemDef.descriptionToken = "DEFENSE_BUDGET_DESC";
			itemDef.loreToken = "DEFENSE_BUDGET_LORE";
			Assets.SetItemTier(itemDef, (ItemTier)3);
			itemDef.canRemove = true;
			itemDef.hidden = false;
			itemDef.tags = (ItemTag[])(object)new ItemTag[2]
			{
				(ItemTag)3,
				(ItemTag)4
			};
			itemDef.pickupIconSprite = Assets.LoadSprite("DefenseBudget.icon_item.rgba", 128);
			itemDef.pickupModelPrefab = Assets.CreatePickupModel("PickupDefenseBudget", "DefenseBudget.models.dollar_sign.obj", "DefenseBudget.models.dollar_sign.rgba", 512, 0.8f, CreateGlyphModel);
			ItemAPI.Add(new CustomItem(itemDef, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
		}

		private static GameObject CreateGlyphModel()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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)
			try
			{
				Color val = default(Color);
				((Color)(ref val))..ctor(1f, 0.78f, 0.25f);
				GameObject val2 = new GameObject("PickupDefenseBudgetGlyph");
				val2.transform.SetParent(Assets.PrefabHolder);
				val2.AddComponent<MeshFilter>().mesh = BuildDollarMesh(0.12f, 0.18f);
				((Renderer)val2.AddComponent<MeshRenderer>()).material = Assets.CreatePickupMaterial(val, null, val * 0.4f);
				return val2;
			}
			catch (Exception ex)
			{
				Log.Warning("Falling back to mystery pickup model: " + ex.Message);
				return Assets.MysteryModel();
			}
		}

		private static Mesh BuildDollarMesh(float cellSize, float depth)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_009d: 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)
			List<Vector3> vertices = new List<Vector3>();
			List<Vector3> normals = new List<Vector3>();
			List<Vector2> list = new List<Vector2>();
			List<int> list2 = new List<int>();
			int num = DollarGlyph.Length;
			int length = DollarGlyph[0].Length;
			Vector3 center = default(Vector3);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < length; j++)
				{
					if (DollarGlyph[i][j] == 'X')
					{
						((Vector3)(ref center))..ctor(((float)j + 0.5f - (float)length / 2f) * cellSize, ((float)(num - 1 - i) + 0.5f - (float)num / 2f) * cellSize, 0f);
						AddCube(vertices, normals, list, list2, center, new Vector3(cellSize, cellSize, depth));
					}
				}
			}
			Mesh val = new Mesh();
			val.SetVertices(vertices);
			val.SetNormals(normals);
			val.SetUVs(0, list);
			val.SetTriangles(list2, 0);
			val.RecalculateBounds();
			return val;
		}

		private static void AddCube(List<Vector3> vertices, List<Vector3> normals, List<Vector2> uvs, List<int> triangles, Vector3 center, Vector3 size)
		{
			//IL_0001: 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_0016: 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)
			//IL_0022: 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_002e: 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_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_004b: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007f: 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_00a0: 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_00a4: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b1: 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_00b7: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_00dd: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_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)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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)
			//IL_0094: 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_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = size * 0.5f;
			Vector3[] array = (Vector3[])(object)new Vector3[6]
			{
				Vector3.right,
				Vector3.left,
				Vector3.up,
				Vector3.down,
				Vector3.forward,
				Vector3.back
			};
			Vector3[] array2 = array;
			foreach (Vector3 val2 in array2)
			{
				Vector3 val3 = ((val2 == Vector3.up || val2 == Vector3.down) ? Vector3.right : Vector3.Cross(Vector3.up, val2));
				Vector3 val4 = Vector3.Cross(val2, val3);
				Vector3 val5 = center + Vector3.Scale(val2, val);
				Vector3 val6 = Vector3.Scale(val3, val);
				Vector3 val7 = Vector3.Scale(val4, val);
				int count = vertices.Count;
				vertices.Add(val5 - val6 - val7);
				vertices.Add(val5 - val6 + val7);
				vertices.Add(val5 + val6 + val7);
				vertices.Add(val5 + val6 - val7);
				for (int j = 0; j < 4; j++)
				{
					normals.Add(val2);
				}
				uvs.Add(new Vector2(0f, 0f));
				uvs.Add(new Vector2(0f, 1f));
				uvs.Add(new Vector2(1f, 1f));
				uvs.Add(new Vector2(1f, 0f));
				triangles.AddRange(new int[6]
				{
					count,
					count + 2,
					count + 1,
					count,
					count + 3,
					count + 2
				});
			}
		}

		private void CreateBuffs()
		{
			//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_00b4: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			Sprite iconSprite = Assets.LoadSprite("DefenseBudget.icon_buff.rgba", 128);
			inDebtBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)inDebtBuff).name = "DefenseBudgetInDebt";
			inDebtBuff.iconSprite = iconSprite;
			inDebtBuff.buffColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)210, (byte)70, byte.MaxValue));
			inDebtBuff.canStack = false;
			inDebtBuff.isDebuff = false;
			ContentAddition.AddBuffDef(inDebtBuff);
			defaultedBuff = ScriptableObject.CreateInstance<BuffDef>();
			((Object)defaultedBuff).name = "DefenseBudgetDefaulted";
			defaultedBuff.iconSprite = iconSprite;
			defaultedBuff.buffColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)60, (byte)60, byte.MaxValue));
			defaultedBuff.canStack = false;
			defaultedBuff.isDebuff = false;
			ContentAddition.AddBuffDef(defaultedBuff);
		}

		private void CreateLanguage()
		{
			int num = Mathf.RoundToInt(CostIncreasePerStack.Value * 100f);
			int num2 = Mathf.RoundToInt(IncomeReductionPerStack.Value * 100f);
			float num3 = InterestRatePerSecond.Value * 100f;
			float num4 = DefaultDamagePerSecond.Value * 100f;
			int num5 = Mathf.RoundToInt(DeficitSpendingBonusPerStack.Value * 100f);
			LanguageAPI.Add("DEFENSE_BUDGET_NAME", "Defense Budget");
			LanguageAPI.Add("DEFENSE_BUDGET_PICKUP", "Spend gold you don't have... <style=cDeath>but earn far less.</style>");
			string text = "";
			if (num2 > 0)
			{
				text += $"<style=cDeath>Reduce gold income by {num2}%</style> <style=cStack>(stacks multiplicatively)</style>. ";
			}
			if (num > 0)
			{
				text += $"All <style=cIsUtility>gold purchases</style> cost <style=cDeath>+{num}% (+{num}% per stack)</style>. ";
			}
			text = text + "Gain a <style=cIsUtility>line of credit</style> that scales with difficulty <style=cStack>(+100% per stack)</style>, letting you purchase while in <style=cIsHealth>deficit</style>. " + $"While in deficit, all gold income <style=cIsUtility>repays the deficit first</style> and the deficit grows by <style=cDeath>{num3:0.#}% per second</style>";
			if (num5 > 0)
			{
				text += $", but you deal <style=cIsDamage>+{num5}% damage (+{num5}% per stack)</style>";
			}
			text += $". Exceeding your credit limit causes you to <style=cDeath>lose {num4:0.#}% of your maximum health per second</style> until the deficit is repaid below the limit.";
			LanguageAPI.Add("DEFENSE_BUDGET_DESC", text);
			LanguageAPI.Add("DEFENSE_BUDGET_LORE", "Order: Line-Item Appropriation \"Defense Budget\"\nTracking Number: 13***********\nEstimated Delivery: Fiscal Year 2056\nShipping Method: Priority\nShipping Address: Committee Chambers, Sub-Basement 4, [REDACTED]\n\nThe committee has reviewed your request for additional funding. The committee reminds you that the budget has tripled for nine consecutive cycles, and that the deficit ceiling is a polite fiction we maintain for the auditors.\n\nSpend it anyway. They always do.\n\nShould expenditures exceed the ceiling, interest will be collected in the only currency of guaranteed supply: you.");
		}

		private static int TotalPlayerStacks()
		{
			int num = 0;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				Inventory val = (Object.op_Implicit((Object)(object)instance.master) ? instance.master.inventory : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					num += val.GetItemCount(itemDef);
				}
			}
			return num;
		}

		private static float CurrentCostMultiplier()
		{
			return 1f + CostIncreasePerStack.Value * (float)TotalPlayerStacks();
		}

		private void PurchaseInteraction_Awake(orig_Awake orig, PurchaseInteraction self)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			orig.Invoke(self);
			if (NetworkServer.active && (int)self.costType == 1)
			{
				CostTracker costTracker = ((Component)self).gameObject.AddComponent<CostTracker>();
				costTracker.purchaseInteraction = self;
				costTrackers.Add(costTracker);
			}
		}

		private static void ApplyMultiplier(CostTracker tracker, float multiplier)
		{
			if (!Mathf.Approximately(tracker.appliedMultiplier, multiplier))
			{
				PurchaseInteraction purchaseInteraction = tracker.purchaseInteraction;
				if (purchaseInteraction.cost > 0 && purchaseInteraction.Networkcost > 0)
				{
					purchaseInteraction.Networkcost = Mathf.Max(1, Mathf.RoundToInt((float)purchaseInteraction.Networkcost * (multiplier / tracker.appliedMultiplier)));
				}
				tracker.appliedMultiplier = multiplier;
			}
		}

		private static void UpdateCostMultipliers()
		{
			float multiplier = CurrentCostMultiplier();
			for (int num = costTrackers.Count - 1; num >= 0; num--)
			{
				CostTracker costTracker = costTrackers[num];
				if (!Object.op_Implicit((Object)(object)costTracker) || !Object.op_Implicit((Object)(object)costTracker.purchaseInteraction))
				{
					costTrackers.RemoveAt(num);
					continue;
				}
				if (costTracker.settleTicks > 0)
				{
					costTracker.settleTicks--;
					if (costTracker.settleTicks > 0)
					{
						continue;
					}
				}
				ApplyMultiplier(costTracker, multiplier);
			}
		}

		private static DebtTracker GetDebt(CharacterMaster master)
		{
			return Object.op_Implicit((Object)(object)master) ? ((Component)master).GetComponent<DebtTracker>() : null;
		}

		private static DebtTracker GetOrCreateDebt(CharacterMaster master)
		{
			DebtTracker component = ((Component)master).GetComponent<DebtTracker>();
			return Object.op_Implicit((Object)(object)component) ? component : ((Component)master).gameObject.AddComponent<DebtTracker>();
		}

		private static int GetStacks(CharacterMaster master)
		{
			return (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory)) ? master.inventory.GetItemCount(itemDef) : 0;
		}

		private static double DebtLimit(CharacterMaster master)
		{
			int stacks = GetStacks(master);
			if (stacks <= 0 || !Object.op_Implicit((Object)(object)Run.instance))
			{
				return 0.0;
			}
			return (double)Run.instance.GetDifficultyScaledCost(BaseDebtLimit.Value) * (double)stacks;
		}

		private static CharacterMaster GetMaster(Interactor activator)
		{
			if (!Object.op_Implicit((Object)(object)activator))
			{
				return null;
			}
			CharacterBody component = ((Component)activator).GetComponent<CharacterBody>();
			return Object.op_Implicit((Object)(object)component) ? component.master : null;
		}

		private bool PurchaseInteraction_CanBeAffordedByInteractor(orig_CanBeAffordedByInteractor orig, PurchaseInteraction self, Interactor activator)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			if (orig.Invoke(self, activator))
			{
				return true;
			}
			if ((int)self.costType != 1 || self.cost <= 0)
			{
				return false;
			}
			CharacterMaster master = GetMaster(activator);
			if (!Object.op_Implicit((Object)(object)master) || GetStacks(master) <= 0)
			{
				return false;
			}
			DebtTracker debt = GetDebt(master);
			double num = DebtLimit(master) - (((Object)(object)debt != (Object)null) ? debt.debt : 0.0);
			return num > 0.0 && (double)master.money + num >= (double)self.cost;
		}

		private void PurchaseInteraction_OnInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (NetworkServer.active && (int)self.costType == 1 && self.cost > 0)
			{
				CharacterMaster master = GetMaster(activator);
				if (Object.op_Implicit((Object)(object)master) && master.money < (uint)self.cost && GetStacks(master) > 0)
				{
					uint num = (uint)self.cost - master.money;
					DebtTracker orCreateDebt = GetOrCreateDebt(master);
					if (orCreateDebt.debt + (double)num <= DebtLimit(master) + 0.5)
					{
						orCreateDebt.debt += num;
						master.money = (uint)self.cost;
					}
				}
			}
			orig.Invoke(self, activator);
		}

		private void CharacterMaster_GiveMoney(orig_GiveMoney orig, CharacterMaster self, uint amount)
		{
			if (NetworkServer.active && amount != 0 && !applyingDefaultDamage)
			{
				int stacks = GetStacks(self);
				if (stacks > 0 && IncomeReductionPerStack.Value > 0f)
				{
					amount = (uint)Math.Round((double)amount * Math.Pow(1.0 - (double)Mathf.Clamp01(IncomeReductionPerStack.Value), stacks));
				}
				DebtTracker debt = GetDebt(self);
				if ((Object)(object)debt != (Object)null && debt.debt > 0.0)
				{
					uint num = (uint)Math.Min(amount, Math.Ceiling(debt.debt));
					debt.debt = Math.Max(0.0, debt.debt - (double)num);
					amount -= num;
				}
			}
			orig.Invoke(self, amount);
		}

		private void HealthComponent_TakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			if (NetworkServer.active && DeficitSpendingBonusPerStack.Value > 0f && damageInfo != null && Object.op_Implicit((Object)(object)damageInfo.attacker))
			{
				CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>();
				CharacterMaster val = (Object.op_Implicit((Object)(object)component) ? component.master : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					int stacks = GetStacks(val);
					if (stacks > 0)
					{
						DebtTracker debt = GetDebt(val);
						if ((Object)(object)debt != (Object)null && debt.debt > 0.0)
						{
							damageInfo.damage *= 1f + DeficitSpendingBonusPerStack.Value * (float)stacks;
						}
					}
				}
			}
			orig.Invoke(self, damageInfo);
		}

		private void MoneyText_Update(orig_Update orig, MoneyText self)
		{
			//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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)self.targetText) && !((Object)self).name.Contains("Lunar"))
			{
				if (!moneyTextColorCached)
				{
					moneyTextOriginalColor = ((Graphic)self.targetText).color;
					moneyTextColorCached = true;
				}
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				CharacterMaster val = ((firstLocalUser != null) ? firstLocalUser.cachedMaster : null);
				DebtTracker debtTracker = (Object.op_Implicit((Object)(object)val) ? GetDebt(val) : null);
				if ((Object)(object)debtTracker != (Object)null && debtTracker.debt > 0.0)
				{
					self.targetValue = -(int)Math.Round(debtTracker.debt);
					((Graphic)self.targetText).color = new Color(1f, 0.35f, 0.3f);
				}
				else
				{
					((Graphic)self.targetText).color = moneyTextOriginalColor;
				}
			}
			orig.Invoke(self);
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = DebugSpawnItemKey.Value;
			bool flag = ((KeyboardShortcut)(ref value)).IsDown();
			value = DebugSpawnPackKey.Value;
			bool flag2 = ((KeyboardShortcut)(ref value)).IsDown();
			if ((!flag && !flag2) || !NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance))
			{
				return;
			}
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			Vector3 forward = ((Component)val).gameObject.transform.forward;
			if (flag)
			{
				Log.Info("Debug: spawning Defense Budget");
				PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(itemDef.itemIndex), val.corePosition + Vector3.up * 1.5f, forward * 10f);
			}
			if (flag2)
			{
				Log.Info("Debug: spawning item pack");
				ItemDef[] array = (ItemDef[])(object)new ItemDef[4]
				{
					SavingsBond.Def,
					AccountsReceivable.Def,
					GoldenParachute.Def,
					FinalNotice.Def
				};
				for (int i = 0; i < array.Length; i++)
				{
					Vector3 val2 = Quaternion.AngleAxis(-30f + 20f * (float)i, Vector3.up) * forward;
					PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(array[i].itemIndex), val.corePosition + Vector3.up * 1.5f, val2 * 10f);
				}
			}
		}

		private void FixedUpdate()
		{
			if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance))
			{
				return;
			}
			interestTimer += Time.fixedDeltaTime;
			damageTimer += Time.fixedDeltaTime;
			multiplierTimer += Time.fixedDeltaTime;
			bool flag = false;
			bool flag2 = false;
			if (interestTimer >= 1f)
			{
				interestTimer -= 1f;
				flag = true;
			}
			if (damageTimer >= 0.5f)
			{
				damageTimer -= 0.5f;
				flag2 = true;
			}
			if (multiplierTimer >= 0.2f)
			{
				multiplierTimer = 0f;
				UpdateCostMultipliers();
			}
			SavingsBond.FixedUpdate();
			ArtifactOfCommunism.FixedUpdate();
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				CharacterMaster master = instance.master;
				if (!Object.op_Implicit((Object)(object)master))
				{
					continue;
				}
				DebtTracker debt = GetDebt(master);
				CharacterBody body = master.GetBody();
				bool flag3 = (Object)(object)debt != (Object)null && debt.debt > 0.0;
				double num = DebtLimit(master);
				if (flag3 && flag)
				{
					debt.debt += Math.Max(1.0, debt.debt * (double)InterestRatePerSecond.Value);
				}
				bool flag4 = flag3 && debt.debt > num;
				if (Object.op_Implicit((Object)(object)body))
				{
					UpdateBuff(body, inDebtBuff, flag3 && !flag4);
					UpdateBuff(body, defaultedBuff, flag4);
				}
				if ((Object)(object)debt != (Object)null)
				{
					if (flag4 && !debt.wasDefaulted)
					{
						AnnounceDefault(master);
					}
					debt.wasDefaulted = flag4;
				}
				if (flag4 && flag2 && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive)
				{
					ApplyDefaultDamage(master, body);
				}
			}
		}

		private static void UpdateBuff(CharacterBody body, BuffDef buff, bool active)
		{
			bool flag = body.HasBuff(buff);
			if (active && !flag)
			{
				body.AddBuff(buff);
			}
			else if (!active && flag)
			{
				body.RemoveBuff(buff);
			}
		}

		private static void ApplyDefaultDamage(CharacterMaster master, CharacterBody body)
		{
			//IL_0039: 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_0065: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_009f: Expected O, but got Unknown
			HealthComponent healthComponent = body.healthComponent;
			DebtTracker debt = GetDebt(master);
			uint money = master.money;
			double debt2 = (((Object)(object)debt != (Object)null) ? debt.debt : 0.0);
			applyingDefaultDamage = true;
			try
			{
				healthComponent.TakeDamage(new DamageInfo
				{
					damage = Mathf.Max(1f, healthComponent.fullCombinedHealth * DefaultDamagePerSecond.Value * 0.5f),
					position = body.corePosition,
					attacker = null,
					inflictor = null,
					crit = false,
					damageColorIndex = (DamageColorIndex)3,
					damageType = DamageTypeCombo.op_Implicit((DamageType)66)
				});
			}
			finally
			{
				applyingDefaultDamage = false;
				master.money = money;
				if ((Object)(object)debt != (Object)null)
				{
					debt.debt = debt2;
				}
			}
		}

		private static void AnnounceDefault(CharacterMaster master)
		{
			//IL_0036: 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_0056: Expected O, but got Unknown
			string text = "A survivor";
			PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController;
			if (Object.op_Implicit((Object)(object)playerCharacterMasterController) && Object.op_Implicit((Object)(object)playerCharacterMasterController.networkUser))
			{
				text = playerCharacterMasterController.networkUser.userName;
			}
			Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
			{
				baseToken = "<color=#ff5544>" + text + " has defaulted on their Defense Budget! Repay the deficit or perish.</color>"
			});
		}

		internal static double GetAvailableCredit(CharacterMaster master)
		{
			if (!Object.op_Implicit((Object)(object)master))
			{
				return 0.0;
			}
			DebtTracker debt = GetDebt(master);
			double num = (((Object)(object)debt != (Object)null) ? debt.debt : 0.0);
			return Math.Max(0.0, DebtLimit(master) - num);
		}

		internal static void PayWithCredit(CharacterMaster master, uint cost)
		{
			uint num = Math.Min(master.money, cost);
			master.money -= num;
			uint num2 = cost - num;
			if (num2 != 0)
			{
				GetOrCreateDebt(master).debt += num2;
			}
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}
	}
}
namespace DefenseBudget.Items
{
	internal static class AccountsReceivable
	{
		private class Claim : MonoBehaviour
		{
			internal readonly HashSet<CharacterMaster> claimants = new HashSet<CharacterMaster>();
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_TakeDamage <0>__MarkClaim;

			public static hook_OnCharacterDeath <1>__CollectClaims;
		}

		internal static ItemDef Def;

		internal static ConfigEntry<float> BountyBonusPerStack;

		internal static void Init(ConfigFile config)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0105: 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_0110: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			BountyBonusPerStack = config.Bind<float>("AccountsReceivable", "BountyBonusPerStack", 0.1f, "Bonus fraction of a marked enemy's gold bounty collected on its death, per stack.");
			Def = Assets.CreateItemDef("AccountsReceivable", "ACCOUNTS_RECEIVABLE", (ItemTier)1, Assets.LoadSprite("DefenseBudget.icon_accounts_receivable.rgba", 128), Assets.CreatePickupModel("PickupAccountsReceivable", "DefenseBudget.models.accounts_receivable.obj", "DefenseBudget.models.accounts_receivable.rgba", 512, 0.6f), (ItemTag[])(object)new ItemTag[1] { (ItemTag)3 });
			ItemAPI.Add(new CustomItem(Def, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
			int num = Mathf.RoundToInt(BountyBonusPerStack.Value * 100f);
			LanguageAPI.Add("ACCOUNTS_RECEIVABLE_NAME", "Accounts Receivable");
			LanguageAPI.Add("ACCOUNTS_RECEIVABLE_PICKUP", "Enemies you damage owe you a cut of their bounty.");
			LanguageAPI.Add("ACCOUNTS_RECEIVABLE_DESC", "Damaging an enemy <style=cIsUtility>marks</style> them. Marked enemies grant you an additional " + $"<style=cIsUtility>{num}% <style=cStack>(+{num}% per stack)</style></style> of their gold reward when killed by anyone.");
			LanguageAPI.Add("ACCOUNTS_RECEIVABLE_LORE", "INVOICE #44721\nServices rendered: ballistic consultation (1x)\nPayment due: immediately\nLate fee: continued ballistic consultation");
			object obj = <>O.<0>__MarkClaim;
			if (obj == null)
			{
				hook_TakeDamage val = MarkClaim;
				<>O.<0>__MarkClaim = val;
				obj = (object)val;
			}
			HealthComponent.TakeDamage += (hook_TakeDamage)obj;
			object obj2 = <>O.<1>__CollectClaims;
			if (obj2 == null)
			{
				hook_OnCharacterDeath val2 = CollectClaims;
				<>O.<1>__CollectClaims = val2;
				obj2 = (object)val2;
			}
			GlobalEventManager.OnCharacterDeath += (hook_OnCharacterDeath)obj2;
		}

		private static void MarkClaim(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_009b: 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)
			if (NetworkServer.active && damageInfo != null && !damageInfo.rejected && damageInfo.damage > 0f && Object.op_Implicit((Object)(object)damageInfo.attacker) && Object.op_Implicit((Object)(object)self.body))
			{
				CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>();
				CharacterMaster val = (Object.op_Implicit((Object)(object)component) ? component.master : null);
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.inventory) && Object.op_Implicit((Object)(object)component.teamComponent) && Object.op_Implicit((Object)(object)self.body.teamComponent) && component.teamComponent.teamIndex != self.body.teamComponent.teamIndex && val.inventory.GetItemCount(Def) > 0)
				{
					Claim claim = ((Component)self.body).GetComponent<Claim>();
					if (!Object.op_Implicit((Object)(object)claim))
					{
						claim = ((Component)self.body).gameObject.AddComponent<Claim>();
					}
					claim.claimants.Add(val);
				}
			}
			orig.Invoke(self, damageInfo);
		}

		private static void CollectClaims(orig_OnCharacterDeath orig, GlobalEventManager self, DamageReport damageReport)
		{
			uint num = 0u;
			Claim claim = null;
			if (NetworkServer.active && Object.op_Implicit((Object)(object)damageReport?.victimBody))
			{
				claim = ((Component)damageReport.victimBody).GetComponent<Claim>();
				if ((Object)(object)claim != (Object)null)
				{
					DeathRewards component = ((Component)damageReport.victimBody).GetComponent<DeathRewards>();
					num = (Object.op_Implicit((Object)(object)component) ? component.goldReward : 0u);
				}
			}
			orig.Invoke(self, damageReport);
			if ((Object)(object)claim == (Object)null || num == 0)
			{
				return;
			}
			foreach (CharacterMaster claimant in claim.claimants)
			{
				if (!Object.op_Implicit((Object)(object)claimant) || !Object.op_Implicit((Object)(object)claimant.inventory))
				{
					continue;
				}
				int itemCount = claimant.inventory.GetItemCount(Def);
				if (itemCount > 0)
				{
					uint num2 = (uint)Math.Round((float)num * BountyBonusPerStack.Value * (float)itemCount);
					if (num2 != 0)
					{
						claimant.GiveMoney(num2);
					}
				}
			}
		}
	}
	internal static class FinalNotice
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_TakeDamage <0>__BillDamage;
		}

		internal static ItemDef Def;

		internal static ConfigEntry<float> BaseConversion;

		internal static ConfigEntry<float> ConversionPerStack;

		internal static ConfigEntry<float> MaxConversion;

		internal static ConfigEntry<int> GoldCostPer100Damage;

		internal static void Init(ConfigFile config)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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)
			//IL_00f5: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Expected O, but got Unknown
			BaseConversion = config.Bind<float>("FinalNotice", "BaseConversion", 0.3f, "Fraction of incoming damage billed to gold with one stack.");
			ConversionPerStack = config.Bind<float>("FinalNotice", "ConversionPerStack", 0.1f, "Additional conversion fraction per stack beyond the first.");
			MaxConversion = config.Bind<float>("FinalNotice", "MaxConversion", 0.7f, "Maximum conversion fraction.");
			GoldCostPer100Damage = config.Bind<int>("FinalNotice", "GoldCostPer100Damage", 50, "Gold billed per 100 damage converted, in base gold (scaled by difficulty over time exactly like chest prices).");
			Def = Assets.CreateItemDef("FinalNotice", "FINAL_NOTICE", (ItemTier)6, Assets.LoadSprite("DefenseBudget.icon_final_notice.rgba", 128), Assets.CreatePickupModel("PickupFinalNotice", "DefenseBudget.models.final_notice.obj", "DefenseBudget.models.final_notice.rgba", 512, 0.6f), (ItemTag[])(object)new ItemTag[1] { (ItemTag)3 });
			Def.requiredExpansion = Addressables.LoadAssetAsync<ExpansionDef>((object)"RoR2/DLC1/Common/DLC1.asset").WaitForCompletion();
			ItemAPI.Add(new CustomItem(Def, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
			ItemDef itemDef = Addressables.LoadAssetAsync<ItemDef>((object)"RoR2/DLC1/GoldOnHurt/GoldOnHurt.asset").WaitForCompletion();
			ItemRelationshipProvider val = ScriptableObject.CreateInstance<ItemRelationshipProvider>();
			((Object)val).name = "DefenseBudgetContagiousItems";
			val.relationshipType = Addressables.LoadAssetAsync<ItemRelationshipType>((object)"RoR2/DLC1/Common/ContagiousItem.asset").WaitForCompletion();
			val.relationships = (Pair[])(object)new Pair[1]
			{
				new Pair
				{
					itemDef1 = itemDef,
					itemDef2 = Def
				}
			};
			ContentAddition.AddItemRelationshipProvider(val);
			int num = Mathf.RoundToInt(BaseConversion.Value * 100f);
			int num2 = Mathf.RoundToInt(ConversionPerStack.Value * 100f);
			int num3 = Mathf.RoundToInt(MaxConversion.Value * 100f);
			LanguageAPI.Add("FINAL_NOTICE_NAME", "Final Notice");
			LanguageAPI.Add("FINAL_NOTICE_PICKUP", "A portion of incoming damage is billed to your gold. <style=cIsVoid>Corrupts all Rolls of Pennies</style>.");
			LanguageAPI.Add("FINAL_NOTICE_DESC", $"<style=cIsUtility>{num}% <style=cStack>(+{num2}% per stack, up to {num3}%)</style></style> of incoming damage is " + "<style=cIsUtility>billed to your gold</style> at a difficulty-scaled rate instead of your health. Damage you cannot pay for is taken as normal. <style=cIsVoid>Corrupts all Rolls of Pennies</style>.");
			LanguageAPI.Add("FINAL_NOTICE_LORE", "ACCOUNT: OVERDUE\nThis is your FINAL NOTICE. Subsequent collection attempts will be performed in person.\n\nWe thank you for your continued patronage. There is no opting out.");
			object obj = <>O.<0>__BillDamage;
			if (obj == null)
			{
				hook_TakeDamage val2 = BillDamage;
				<>O.<0>__BillDamage = val2;
				obj = (object)val2;
			}
			HealthComponent.TakeDamage += (hook_TakeDamage)obj;
		}

		private static void BillDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			if (NetworkServer.active && damageInfo != null && !damageInfo.rejected && damageInfo.damage > 0f && Object.op_Implicit((Object)(object)self.body) && Object.op_Implicit((Object)(object)Run.instance))
			{
				CharacterMaster master = self.body.master;
				int num = ((Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory)) ? master.inventory.GetItemCount(Def) : 0);
				if (num > 0 && master.money != 0)
				{
					float num2 = Mathf.Min(BaseConversion.Value + ConversionPerStack.Value * (float)(num - 1), MaxConversion.Value);
					float num3 = damageInfo.damage * num2;
					float num4 = (float)Run.instance.GetDifficultyScaledCost(GoldCostPer100Damage.Value) / 100f;
					float num5 = Mathf.Max(1f, num3 * num4);
					if (num5 > (float)master.money)
					{
						num3 *= (float)master.money / num5;
						num5 = master.money;
					}
					master.money -= (uint)Mathf.CeilToInt(num5);
					damageInfo.damage -= num3;
				}
			}
			orig.Invoke(self, damageInfo);
		}
	}
	internal static class GoldenParachute
	{
		private class ParachuteCooldown : MonoBehaviour
		{
			internal float readyTime;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_TakeDamage <0>__InterceptLethal;
		}

		internal static ItemDef Def;

		internal static ConfigEntry<int> BaseCost;

		internal static ConfigEntry<float> CooldownSeconds;

		internal static ConfigEntry<float> CooldownReductionPerStack;

		internal static ConfigEntry<float> SurviveHealthFraction;

		internal static ConfigEntry<float> ImmunityDuration;

		internal static void Init(ConfigFile config)
		{
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			BaseCost = config.Bind<int>("GoldenParachute", "BaseCost", 40, "Severance fee in base gold, scaled by difficulty over time exactly like chest prices.");
			CooldownSeconds = config.Bind<float>("GoldenParachute", "CooldownSeconds", 45f, "Cooldown between deployments.");
			CooldownReductionPerStack = config.Bind<float>("GoldenParachute", "CooldownReductionPerStack", 0.25f, "Multiplicative cooldown reduction per stack beyond the first.");
			SurviveHealthFraction = config.Bind<float>("GoldenParachute", "SurviveHealthFraction", 0.15f, "Fraction of full health restored on deployment.");
			ImmunityDuration = config.Bind<float>("GoldenParachute", "ImmunityDuration", 1.5f, "Seconds of immunity granted on deployment (covers the rest of the killing burst).");
			Def = Assets.CreateItemDef("GoldenParachute", "GOLDEN_PARACHUTE", (ItemTier)2, Assets.LoadSprite("DefenseBudget.icon_golden_parachute.rgba", 128), Assets.CreatePickupModel("PickupGoldenParachute", "DefenseBudget.models.golden_parachute.obj", "DefenseBudget.models.golden_parachute.rgba", 512, 0.8f), (ItemTag[])(object)new ItemTag[2]
			{
				(ItemTag)3,
				(ItemTag)4
			});
			ItemAPI.Add(new CustomItem(Def, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
			LanguageAPI.Add("GOLDEN_PARACHUTE_NAME", "Golden Parachute");
			LanguageAPI.Add("GOLDEN_PARACHUTE_PICKUP", "Cheat death by cashing out.");
			LanguageAPI.Add("GOLDEN_PARACHUTE_DESC", "Upon taking lethal damage, pay a <style=cIsUtility>severance fee</style> of difficulty-scaled gold (drawing on <style=cIsUtility>credit</style> if you have a Defense Budget) to instead survive at " + $"<style=cIsHealing>{Mathf.RoundToInt(SurviveHealthFraction.Value * 100f)}% health</style>. " + $"If you cannot cover the fee, you die. Recharges every {CooldownSeconds.Value:0} seconds " + $"<style=cStack>(-{Mathf.RoundToInt(CooldownReductionPerStack.Value * 100f)}% per stack)</style>.");
			LanguageAPI.Add("GOLDEN_PARACHUTE_LORE", "Section 12(b): In the event of involuntary separation (termination, restructuring, evisceration), the executive shall receive one (1) severance package, deployment automatic, fee deducted from estate.\n\nThe board notes with approval that the executive has never once read Section 12(c): renewal fees.");
			object obj = <>O.<0>__InterceptLethal;
			if (obj == null)
			{
				hook_TakeDamage val = InterceptLethal;
				<>O.<0>__InterceptLethal = val;
				obj = (object)val;
			}
			HealthComponent.TakeDamage += (hook_TakeDamage)obj;
		}

		private static void InterceptLethal(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			if (NetworkServer.active && damageInfo != null && !damageInfo.rejected && damageInfo.damage > 0f && self.alive && Object.op_Implicit((Object)(object)self.body) && Object.op_Implicit((Object)(object)Run.instance))
			{
				CharacterMaster master = self.body.master;
				int num = ((Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory)) ? master.inventory.GetItemCount(Def) : 0);
				if (num > 0)
				{
					ParachuteCooldown parachuteCooldown = ((Component)master).GetComponent<ParachuteCooldown>();
					float time = Run.instance.time;
					if ((Object)(object)parachuteCooldown == (Object)null || time >= parachuteCooldown.readyTime)
					{
						float armor = self.body.armor;
						float num2 = ((armor >= 0f) ? (100f / (100f + armor)) : (2f - 100f / (100f - armor)));
						float num3 = damageInfo.damage * num2;
						if (num3 >= self.combinedHealth)
						{
							uint difficultyScaledCost = (uint)Run.instance.GetDifficultyScaledCost(BaseCost.Value);
							if ((double)master.money + DefenseBudgetPlugin.GetAvailableCredit(master) >= (double)difficultyScaledCost)
							{
								DefenseBudgetPlugin.PayWithCredit(master, difficultyScaledCost);
								self.body.AddTimedBuff(Buffs.Immune, ImmunityDuration.Value);
								self.Networkhealth = Mathf.Max(self.health, self.fullHealth * SurviveHealthFraction.Value);
								Log.Info($"Golden Parachute deployed for {Util.GetBestMasterName(master)} (fee {difficultyScaledCost})");
								if ((Object)(object)parachuteCooldown == (Object)null)
								{
									parachuteCooldown = ((Component)master).gameObject.AddComponent<ParachuteCooldown>();
								}
								parachuteCooldown.readyTime = time + CooldownSeconds.Value * Mathf.Pow(1f - CooldownReductionPerStack.Value, (float)(num - 1));
								Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage
								{
									baseToken = $"<color=#ffd24a>{Util.GetBestMasterName(master)}'s Golden Parachute deployed! Severance fee: {difficultyScaledCost} gold.</color>"
								});
							}
						}
					}
				}
			}
			orig.Invoke(self, damageInfo);
		}
	}
	internal static class SavingsBond
	{
		internal static ItemDef Def;

		internal static ConfigEntry<float> InterestRatePerStack;

		internal static ConfigEntry<float> InterestInterval;

		private static float timer;

		internal static void Init(ConfigFile config)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			InterestRatePerStack = config.Bind<float>("SavingsBond", "InterestRatePerStack", 0.02f, "Interest earned on held gold per stack, each interval.");
			InterestInterval = config.Bind<float>("SavingsBond", "InterestInterval", 10f, "Seconds between interest payments.");
			Def = Assets.CreateItemDef("SavingsBond", "SAVINGS_BOND", (ItemTier)0, Assets.LoadSprite("DefenseBudget.icon_savings_bond.rgba", 128), Assets.CreatePickupModel("PickupSavingsBond", "DefenseBudget.models.savings_bond.obj", "DefenseBudget.models.savings_bond.rgba", 512, 0.6f), (ItemTag[])(object)new ItemTag[1] { (ItemTag)3 });
			ItemAPI.Add(new CustomItem(Def, new ItemDisplayRuleDict((ItemDisplayRule[])null)));
			int num = Mathf.RoundToInt(InterestRatePerStack.Value * 100f);
			LanguageAPI.Add("SAVINGS_BOND_NAME", "Savings Bond");
			LanguageAPI.Add("SAVINGS_BOND_PICKUP", "Earn interest on your held gold.");
			LanguageAPI.Add("SAVINGS_BOND_DESC", $"Every {InterestInterval.Value:0} seconds, earn <style=cIsUtility>{num}% <style=cStack>(+{num}% per stack)</style> interest</style> on your held gold.");
			LanguageAPI.Add("SAVINGS_BOND_LORE", "\"Guaranteed 2% return, backed by the full faith and credit of whatever government still exists when it matures.\"\n\n- Prospectus fragment, recovered from contact light wreckage");
		}

		internal static void FixedUpdate()
		{
			timer += Time.fixedDeltaTime;
			if (timer < InterestInterval.Value)
			{
				return;
			}
			timer = 0f;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				CharacterMaster master = instance.master;
				if (Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory))
				{
					int itemCount = master.inventory.GetItemCount(Def);
					if (itemCount > 0 && master.money != 0)
					{
						uint num = (uint)Math.Max(1.0, Math.Floor((float)master.money * InterestRatePerStack.Value * (float)itemCount));
						master.GiveMoney(num);
					}
				}
			}
		}
	}
}
namespace DefenseBudget.Artifacts
{
	internal static class ArtifactOfCommunism
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_GiveMoney <0>__PoolIncome;
		}

		internal static ArtifactDef Def;

		internal static ConfigEntry<float> SharePenaltyPerExtraPlayer;

		private static double pool;

		private static uint lastSyncedMoney;

		private static bool poolInitialized;

		internal static bool Enabled => Object.op_Implicit((Object)(object)Def) && Object.op_Implicit((Object)(object)RunArtifactManager.instance) && RunArtifactManager.instance.IsArtifactEnabled(Def);

		internal static void Init(ConfigFile config)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			SharePenaltyPerExtraPlayer = config.Bind<float>("ArtifactOfCommunism", "SharePenaltyPerExtraPlayer", 0.25f, "Collectivization overhead. Total pool income is multiplied by playerCount - penalty * (playerCount - 1): 0.25 means 2 players earn x1.75, 4 players earn x3.25. Solo is unaffected.");
			Def = ScriptableObject.CreateInstance<ArtifactDef>();
			Def.cachedName = "ArtifactOfCommunism";
			Def.nameToken = "ARTIFACT_COMMUNISM_NAME";
			Def.descriptionToken = "ARTIFACT_COMMUNISM_DESC";
			Def.smallIconSelectedSprite = Assets.LoadSprite("DefenseBudget.icon_artifact_communism_enabled.rgba", 128);
			Def.smallIconDeselectedSprite = Assets.LoadSprite("DefenseBudget.icon_artifact_communism_disabled.rgba", 128);
			ContentAddition.AddArtifactDef(Def);
			LanguageAPI.Add("ARTIFACT_COMMUNISM_NAME", "Artifact of Communism");
			LanguageAPI.Add("ARTIFACT_COMMUNISM_DESC", "All gold belongs to the collective: every player earns into and spends from one shared pool. Total gold income is slightly less than the sum of what individuals would have earned.");
			object obj = <>O.<0>__PoolIncome;
			if (obj == null)
			{
				hook_GiveMoney val = PoolIncome;
				<>O.<0>__PoolIncome = val;
				obj = (object)val;
			}
			CharacterMaster.GiveMoney += (hook_GiveMoney)obj;
			Run.onRunStartGlobal += delegate
			{
				pool = 0.0;
				lastSyncedMoney = 0u;
				poolInitialized = false;
			};
		}

		private static void PoolIncome(orig_GiveMoney orig, CharacterMaster self, uint amount)
		{
			if (!NetworkServer.active || amount == 0 || !Enabled || !Object.op_Implicit((Object)(object)self.playerCharacterMasterController))
			{
				orig.Invoke(self, amount);
				return;
			}
			EnsureInitialized();
			int num = Mathf.Max(1, PlayerCharacterMasterController.instances.Count);
			float num2 = ((float)num - SharePenaltyPerExtraPlayer.Value * (float)(num - 1)) / (float)num;
			pool += (float)amount * num2;
		}

		private static void EnsureInitialized()
		{
			if (poolInitialized)
			{
				return;
			}
			poolInitialized = true;
			pool = 0.0;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				if (Object.op_Implicit((Object)(object)instance.master))
				{
					pool += instance.master.money;
				}
			}
			lastSyncedMoney = (uint)pool;
			Mirror();
		}

		private static void Mirror()
		{
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				CharacterMaster master = instance.master;
				if (Object.op_Implicit((Object)(object)master) && master.money != lastSyncedMoney)
				{
					master.money = lastSyncedMoney;
				}
			}
		}

		internal static void FixedUpdate()
		{
			if (!Enabled)
			{
				return;
			}
			EnsureInitialized();
			double num = 0.0;
			foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
			{
				CharacterMaster master = instance.master;
				if (Object.op_Implicit((Object)(object)master))
				{
					num += (double)master.money - (double)lastSyncedMoney;
				}
			}
			pool = Math.Max(0.0, pool + num);
			lastSyncedMoney = (uint)pool;
			Mirror();
		}
	}
}