using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using REPOLib; using REPOLib.Modules; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyTitle("Dogpope")] [assembly: AssemblyDescription("A personal mod adding Maple and Kimchi as R.E.P.O. valuables.")] [assembly: CompilationRelaxations(8)] [assembly: AssemblyCompany("Bobpope")] [assembly: AssemblyProduct("Dogpope")] [assembly: AssemblyCopyright("Copyright (c) 2026 Bobpope")] [assembly: AssemblyFileVersion("1.0.5.0")] [assembly: AssemblyVersion("1.0.5.0")] namespace Bobpope.Dogpope; [BepInProcess("REPO.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("bobpope.repo.dogpope", "Dogpope", "1.0.5")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(NetworkPrefabs), "SpawnNetworkPrefab")] private static class SpawnNetworkPrefabPatch { [HarmonyPostfix] private static void Postfix(PrefabRef prefabRef, GameObject __result) { if ((Object)(object)__result != (Object)null && (prefabRef == _maplePrefabRef || prefabRef == _kimchiPrefabRef) && !__result.activeSelf) { __result.SetActive(true); } } } private sealed class ColliderSpec { public readonly string Name; public readonly Vector3 Center; public readonly Vector3 Size; public ColliderSpec(string name, Vector3 center, Vector3 size) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0016: Unknown result type (might be due to invalid IL or missing references) Name = name; Center = center; Size = size; } } public const string PluginGuid = "bobpope.repo.dogpope"; public const string PluginName = "Dogpope"; public const string PluginVersion = "1.0.5"; public const string MaplePrefabName = "Valuable Maple"; public const string KimchiPrefabName = "Valuable Kimchi"; private const string ModelBundleFileName = "mapleandkimchimodels.bundle"; private static Plugin _instance; private static ManualLogSource _log; private static PrefabRef _maplePrefabRef; private static PrefabRef _kimchiPrefabRef; private static GameObject _maplePrototype; private static GameObject _kimchiPrototype; private static GameObject _prototypeStorage; private static Value _mapleValuePreset; private static Value _kimchiValuePreset; private static Durability _durabilityPreset; private static PhysAttribute _maplePhysicsPreset; private static PhysAttribute _kimchiPhysicsPreset; private Harmony _harmony; private ConfigEntry _addToEveryLoadedMap; private ConfigEntry _mapleValueMin; private ConfigEntry _mapleValueMax; private ConfigEntry _kimchiValueMin; private ConfigEntry _kimchiValueMax; private ConfigEntry _mapleMass; private ConfigEntry _kimchiMass; private ConfigEntry _durability; private ConfigEntry _fragility; private void Awake() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown _instance = this; _log = ((BaseUnityPlugin)this).Logger; _addToEveryLoadedMap = ((BaseUnityPlugin)this).Config.Bind("Spawning", "Add to every loaded map", true, "Adds Maple and Kimchi to compatible valuable pools on every loaded vanilla or modded map."); _mapleValueMin = ((BaseUnityPlugin)this).Config.Bind("Maple", "Minimum value", 7000f, new ConfigDescription("Minimum sale value for Maple.", (AcceptableValueBase)(object)new AcceptableValueRange(100f, 100000f), new object[0])); _mapleValueMax = ((BaseUnityPlugin)this).Config.Bind("Maple", "Maximum value", 10000f, new ConfigDescription("Maximum sale value for Maple.", (AcceptableValueBase)(object)new AcceptableValueRange(100f, 100000f), new object[0])); _mapleMass = ((BaseUnityPlugin)this).Config.Bind("Maple", "Physics mass", 2.5f, new ConfigDescription("How heavy Maple feels while being carried.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 20f), new object[0])); _kimchiValueMin = ((BaseUnityPlugin)this).Config.Bind("Kimchi", "Minimum value", 15000f, new ConfigDescription("Minimum sale value for Kimchi.", (AcceptableValueBase)(object)new AcceptableValueRange(100f, 100000f), new object[0])); _kimchiValueMax = ((BaseUnityPlugin)this).Config.Bind("Kimchi", "Maximum value", 22000f, new ConfigDescription("Maximum sale value for Kimchi.", (AcceptableValueBase)(object)new AcceptableValueRange(100f, 100000f), new object[0])); _kimchiMass = ((BaseUnityPlugin)this).Config.Bind("Kimchi", "Physics mass", 4.5f, new ConfigDescription("How heavy Kimchi feels while being carried.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 30f), new object[0])); if (Mathf.Approximately(_kimchiMass.Value, 7.5f)) { _kimchiMass.Value = 4.5f; ((BaseUnityPlugin)this).Config.Save(); } _durability = ((BaseUnityPlugin)this).Config.Bind("Durability", "Value retention", 100f, new ConfigDescription("How little value the dogs lose when damaged. 100 is extremely forgiving.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); _fragility = ((BaseUnityPlugin)this).Config.Bind("Durability", "Impact sensitivity", 10f, new ConfigDescription("How readily impacts damage the dogs. Lower is tougher.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), new object[0])); _harmony = new Harmony("bobpope.repo.dogpope"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); CreatePrototypeStorage(); BundleLoader.OnAllBundlesLoaded += HandleAllBundlesLoaded; LoadAndRegisterDogModels(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Dogpope 1.0.5 loaded."); } private void OnDestroy() { BundleLoader.OnAllBundlesLoaded -= HandleAllBundlesLoaded; if (_harmony != null) { _harmony.UnpatchSelf(); } if ((Object)(object)_prototypeStorage != (Object)null) { Object.Destroy((Object)(object)_prototypeStorage); _prototypeStorage = null; } } private static void CreatePrototypeStorage() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_prototypeStorage != (Object)null)) { _prototypeStorage = new GameObject("Maple and Kimchi Prefab Storage"); ((Object)_prototypeStorage).hideFlags = (HideFlags)53; Object.DontDestroyOnLoad((Object)(object)_prototypeStorage); _prototypeStorage.SetActive(false); } } private void LoadAndRegisterDogModels() { string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string text = Path.Combine(directoryName, "mapleandkimchimodels.bundle"); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)("Dog model bundle was not found at " + text)); } else { BundleLoader.LoadBundle(text, (Action)RegisterDogsFromBundle, false); } } private static void RegisterDogsFromBundle(AssetBundle bundle) { //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bundle == (Object)null || (Object)(object)RunManager.instance == (Object)null || (Object)(object)_instance == (Object)null) { _log.LogError((object)"Dog model bundle loaded before the game's valuable lists were ready."); return; } GameObject val = LoadModel(bundle, "maple.prefab"); GameObject val2 = LoadModel(bundle, "kimchi.prefab"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { _log.LogError((object)"One or both dog models were missing from mapleandkimchimodels.bundle."); return; } _durabilityPreset = ScriptableObject.CreateInstance(); ((Object)_durabilityPreset).name = "Durability - Maple and Kimchi"; _mapleValuePreset = ScriptableObject.CreateInstance(); ((Object)_mapleValuePreset).name = "Value - Maple"; _kimchiValuePreset = ScriptableObject.CreateInstance(); ((Object)_kimchiValuePreset).name = "Value - Kimchi"; _maplePhysicsPreset = ScriptableObject.CreateInstance(); ((Object)_maplePhysicsPreset).name = "PhysAttribute - Maple"; _kimchiPhysicsPreset = ScriptableObject.CreateInstance(); ((Object)_kimchiPhysicsPreset).name = "PhysAttribute - Kimchi"; Object.DontDestroyOnLoad((Object)(object)_durabilityPreset); Object.DontDestroyOnLoad((Object)(object)_mapleValuePreset); Object.DontDestroyOnLoad((Object)(object)_kimchiValuePreset); Object.DontDestroyOnLoad((Object)(object)_maplePhysicsPreset); Object.DontDestroyOnLoad((Object)(object)_kimchiPhysicsPreset); ApplyConfiguredPresets(); ValuableObject val3 = FindVanillaTemplate((Type)2); ValuableObject val4 = FindVanillaTemplate((Type)3); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { _log.LogError((object)"Suitable vanilla valuable templates could not be found; the dogs were not registered."); return; } _maplePrototype = CreateDogPrototype(((Component)val3).gameObject, val, "Valuable Maple", (Type)2, _mapleValuePreset, _maplePhysicsPreset, new Vector3(0.01f, 0.23f, 0f), new Vector3(0.48f, 0.5f, 0.31f), new ColliderSpec[2] { new ColliderSpec("Maple Body Collider", new Vector3(-0.035f, 0.205f, 0f), new Vector3(0.35f, 0.39f, 0.25f)), new ColliderSpec("Maple Head Collider", new Vector3(0.145f, 0.355f, 0f), new Vector3(0.24f, 0.22f, 0.24f)) }); _kimchiPrototype = CreateDogPrototype(((Component)val4).gameObject, val2, "Valuable Kimchi", (Type)3, _kimchiValuePreset, _kimchiPhysicsPreset, new Vector3(-0.08f, 0.5f, 0f), new Vector3(1.25f, 0.98f, 0.52f), new ColliderSpec[4] { new ColliderSpec("Kimchi Legs Collider", new Vector3(-0.12f, 0.15f, 0f), new Vector3(0.72f, 0.22f, 0.32f)), new ColliderSpec("Kimchi Body Collider", new Vector3(-0.23f, 0.49f, 0f), new Vector3(0.84f, 0.52f, 0.4f)), new ColliderSpec("Kimchi Chest Collider", new Vector3(0.12f, 0.65f, 0f), new Vector3(0.34f, 0.48f, 0.42f)), new ColliderSpec("Kimchi Head Collider", new Vector3(0.4f, 0.79f, 0f), new Vector3(0.38f, 0.36f, 0.36f)) }); if ((Object)(object)_maplePrototype == (Object)null || (Object)(object)_kimchiPrototype == (Object)null) { _log.LogError((object)"A dog prototype could not be created."); return; } _maplePrefabRef = Valuables.RegisterValuable(_maplePrototype, new List { "Valuables - Generic" }); _kimchiPrefabRef = Valuables.RegisterValuable(_kimchiPrototype, new List { "Valuables - Generic" }); if (_maplePrefabRef == null || _kimchiPrefabRef == null) { _log.LogError((object)"REPOLib rejected one or both dog prefabs."); } else { _log.LogInfo((object)"Registered Maple (medium) and Kimchi (big) with custom forgiving collision shapes."); } } private static GameObject LoadModel(AssetBundle bundle, string fileName) { string[] allAssetNames = bundle.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)) { return bundle.LoadAsset(text); } } return null; } private static GameObject CreateDogPrototype(GameObject sourcePrefab, GameObject model, string prefabName, Type volumeType, Value valuePreset, PhysAttribute physicsPreset, Vector3 roomCheckPosition, Vector3 roomCheckSize, ColliderSpec[] colliders) { //IL_00d3: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Invalid comparison between Unknown and I4 //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) bool activeSelf = sourcePrefab.activeSelf; sourcePrefab.SetActive(false); GameObject val = Object.Instantiate(sourcePrefab); sourcePrefab.SetActive(activeSelf); ((Object)val).name = prefabName; ((Object)val).hideFlags = (HideFlags)53; Object.DontDestroyOnLoad((Object)(object)val); Renderer[] componentsInChildren = val.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { val2.enabled = false; } PhysGrabObjectCollider[] componentsInChildren2 = val.GetComponentsInChildren(true); foreach (PhysGrabObjectCollider val3 in componentsInChildren2) { Object.Destroy((Object)(object)val3); } Collider[] componentsInChildren3 = val.GetComponentsInChildren(true); foreach (Collider val4 in componentsInChildren3) { Object.Destroy((Object)(object)val4); } GameObject val5 = Object.Instantiate(model, val.transform); ((Object)val5).name = prefabName + " Model"; val5.transform.localPosition = Vector3.zero; val5.transform.localRotation = Quaternion.Euler(0f, -90f, 0f); val5.transform.localScale = Vector3.one; Renderer[] componentsInChildren4 = val5.GetComponentsInChildren(true); foreach (Renderer val6 in componentsInChildren4) { val6.enabled = true; } foreach (ColliderSpec spec in colliders) { AddBoxCollider(val.transform, spec); } ValuableObject component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return null; } component.volumeType = volumeType; component.valuePreset = valuePreset; component.durabilityPreset = _durabilityPreset; component.physAttributePreset = physicsPreset; component.audioPresetPitch = (((int)volumeType == 3) ? 0.72f : 0.92f); RoomVolumeCheck component2 = val.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.CheckPosition = roomCheckPosition; component2.currentSize = roomCheckSize; } CreatePrototypeStorage(); val.transform.SetParent(_prototypeStorage.transform, false); val.SetActive(true); return val; } private static void AddBoxCollider(Transform parent, ColliderSpec spec) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(spec.Name); val.transform.SetParent(parent, false); val.transform.localPosition = spec.Center; val.layer = LayerMask.NameToLayer("PhysGrabObject"); val.tag = "Phys Grab Object"; BoxCollider val2 = val.AddComponent(); val2.size = spec.Size; val2.center = Vector3.zero; val.AddComponent(); } private static ValuableObject FindVanillaTemplate(Type requestedType) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RunManager.instance == (Object)null) { return null; } HashSet allLevels = GetAllLevels(); foreach (Level item in allLevels) { if ((Object)(object)item == (Object)null || item.ValuablePresets == null) { continue; } foreach (LevelValuables valuablePreset in item.ValuablePresets) { ValuableObject val = FindVanillaInPool(GetPool(valuablePreset, requestedType)); if ((Object)(object)val != (Object)null) { return val; } } } foreach (PrefabRef allValuable in Valuables.AllValuables) { if (allValuable != null && !((Object)(object)((PrefabRef)(object)allValuable).Bundle != (Object)null)) { GameObject prefab = ((PrefabRef)(object)allValuable).Prefab; ValuableObject val2 = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent()); if ((Object)(object)val2 != (Object)null) { return val2; } } } return null; } private static ValuableObject FindVanillaInPool(List pool) { if (pool == null) { return null; } foreach (PrefabRef item in pool) { if (item != null && !((Object)(object)((PrefabRef)(object)item).Bundle != (Object)null)) { GameObject prefab = ((PrefabRef)(object)item).Prefab; ValuableObject val = (((Object)(object)prefab == (Object)null) ? null : prefab.GetComponent()); if ((Object)(object)val != (Object)null) { return val; } } } return null; } private static void ApplyConfiguredPresets() { if (!((Object)(object)_instance == (Object)null) && !((Object)(object)_durabilityPreset == (Object)null)) { _durabilityPreset.durability = _instance._durability.Value; _durabilityPreset.fragility = _instance._fragility.Value; SetOrderedRange(_mapleValuePreset, _instance._mapleValueMin.Value, _instance._mapleValueMax.Value); SetOrderedRange(_kimchiValuePreset, _instance._kimchiValueMin.Value, _instance._kimchiValueMax.Value); _maplePhysicsPreset.mass = _instance._mapleMass.Value; _kimchiPhysicsPreset.mass = _instance._kimchiMass.Value; } } private static void SetOrderedRange(Value preset, float first, float second) { preset.valueMin = Mathf.Min(first, second); preset.valueMax = Mathf.Max(first, second); } private static void HandleAllBundlesLoaded() { if (!((Object)(object)_instance == (Object)null)) { ApplyConfiguredPresets(); if (_instance._addToEveryLoadedMap.Value) { int num = InjectIntoEveryLevel(_maplePrefabRef, (Type)2); int num2 = InjectIntoEveryLevel(_kimchiPrefabRef, (Type)3); _log.LogInfo((object)("Maple is available on " + num + " loaded map(s); Kimchi is available on " + num2 + " loaded map(s).")); TryRefreshValuableRebalancePools(); } ((MonoBehaviour)_instance).StartCoroutine(ReapplyConfiguredPresetsAfterOtherMods()); } } private static IEnumerator ReapplyConfiguredPresetsAfterOtherMods() { yield return null; yield return null; ApplyConfiguredPresets(); } private static void TryRefreshValuableRebalancePools() { try { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { type = assembly.GetType("ValuableRebalance.Pools", throwOnError: false); if (type != null) { break; } } if (!(type == null)) { MethodInfo method = type.GetMethod("OnDrain", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(null, null); _log.LogInfo((object)"Refreshed Valuable Rebalance's cached pools after adding Maple and Kimchi."); } } } catch (Exception ex) { _log.LogWarning((object)("Valuable Rebalance pool refresh was skipped: " + ex.Message)); } } private static int InjectIntoEveryLevel(PrefabRef dog, Type preferredType) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Invalid comparison between Unknown and I4 //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 if (dog == null || (Object)(object)RunManager.instance == (Object)null) { return 0; } int num = 0; foreach (Level allLevel in GetAllLevels()) { if ((Object)(object)allLevel == (Object)null || allLevel.ValuablePresets == null || allLevel.ValuablePresets.Count == 0) { continue; } bool flag = false; foreach (LevelValuables valuablePreset in allLevel.ValuablePresets) { if ((Object)(object)valuablePreset == (Object)null) { continue; } List list = GetPool(valuablePreset, preferredType); if (list == null && (int)preferredType == 3) { list = valuablePreset.wide; } if (list == null && (int)preferredType == 2) { list = valuablePreset.small; } if (list != null) { if (!list.Contains(dog)) { list.Add(dog); } flag = true; } } if (flag) { num++; continue; } _log.LogWarning((object)("Map " + ((Object)allLevel).name + " has no suitable pool for " + ((PrefabRef)(object)dog).PrefabName + ".")); } return num; } private static HashSet GetAllLevels() { HashSet hashSet = new HashSet(); if ((Object)(object)RunManager.instance != (Object)null) { AddLevels(hashSet, RunManager.instance.levels); AddLevels(hashSet, RunManager.instance.levelArena); } return hashSet; } private static void AddLevels(HashSet destination, IList source) { if (source == null) { return; } foreach (Level item in source) { if ((Object)(object)item != (Object)null) { destination.Add(item); } } } private static List GetPool(LevelValuables preset, Type type) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown if ((Object)(object)preset == (Object)null) { return null; } return (int)type switch { 0 => preset.tiny, 1 => preset.small, 2 => preset.medium, 3 => preset.big, 4 => preset.wide, 5 => preset.tall, 6 => preset.veryTall, _ => null, }; } private static bool LevelContains(Level level, PrefabRef dog) { foreach (LevelValuables valuablePreset in level.ValuablePresets) { if ((Object)(object)valuablePreset != (Object)null && (Contains(valuablePreset.tiny, dog) || Contains(valuablePreset.small, dog) || Contains(valuablePreset.medium, dog) || Contains(valuablePreset.big, dog) || Contains(valuablePreset.wide, dog) || Contains(valuablePreset.tall, dog) || Contains(valuablePreset.veryTall, dog))) { return true; } } return false; } private static bool Contains(List pool, PrefabRef dog) { return pool?.Contains(dog) ?? false; } }