using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using CustomGameplayModifiers;
using CustomGameplayModifiers.Artifacts;
using CustomGameplayModifiers.CustomAddressables;
using CustomGameplayModifiers.Framework;
using CustomGameplayModifiers.Framework.EventType;
using CustomGameplayModifiers.Framework.Observers;
using CustomGameplayModifiers.ItemModules;
using HarmonyLib;
using Il2Cpp;
using Il2CppAI;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppKeepsake;
using Il2CppKeepsake.CharacterCustomization;
using Il2CppKeepsake.Common.Collision;
using Il2CppKeepsake.Common.DependencyManagement;
using Il2CppKeepsake.Common.Unity;
using Il2CppKeepsake.GeneratedItems.Cosmetics;
using Il2CppKeepsake.HyperSpace.GameplayFeatures.AI.OnFoot;
using Il2CppKeepsake.HyperSpace.Online.Steam;
using Il2CppKeepsake.HyperSpace.System.Modifiers.ItemModule;
using Il2CppKeepsake.InteriorObjects.Vendor;
using Il2CppKeepsake.MetaProgression;
using Il2CppKeepsake.Modifiers;
using Il2CppKeepsake.Modifiers.Traits;
using Il2CppKeepsake.Pickupables.GenericWeapon;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Collections.ObjectModel;
using Il2CppSystem.Threading;
using Il2CppTMPro;
using Il2CppUniRx;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.UI;
using UnityEngine.VFX;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "CustomGameplayModifiers", "1.0.0", "domipiggie", null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("CustomGameplayModifiers")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1a0d9b156f1d4c25b42db65fb214e60af360908f")]
[assembly: AssemblyProduct("CustomGameplayModifiers")]
[assembly: AssemblyTitle("CustomGameplayModifiers")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace CustomGameplayModifiers
{
public class Core : MelonMod
{
public override void OnInitializeMelon()
{
ItemAssetRegistry.Initialize();
ModLogger.Initialize();
MelonCoroutines.Start(LocalizationInjector.FindTableRoutine());
MelonCoroutines.Start(RegisterAddressablesRoutine());
ModLogger.Msg("Initialized.");
}
public override void OnLateInitializeMelon()
{
MelonCoroutines.Start(InitRoutine());
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
SceneEventsService.OnSceneLoaded(buildIndex, sceneName);
}
private IEnumerator InitRoutine()
{
yield return ArtifactMeshCache.LoadRoutine();
while (PersistentScriptableLibrary.m_ModuleSchoolAssets == null)
{
yield return (object)new WaitForSeconds(0.2f);
}
ModLogger.Msg("PersistentScriptableLibrary ready — initializing caches and building modifiers.");
yield return BuildPipeline.Run();
}
private IEnumerator RegisterAddressablesRoutine()
{
WaitForSeconds wait = new WaitForSeconds(0.1f);
while (Addressables.ResourceManager == null)
{
yield return wait;
}
CustomAddressablesRegisterer.TryRegister();
}
}
}
namespace CustomGameplayModifiers.PlayerTraits
{
public abstract class CustomPlayerTrait : CustomModifier<PlayerTraitScriptable, PlayerTraitInstance>
{
public override void ConfigureScriptable(PlayerTraitScriptable scriptable)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
base.ConfigureScriptable(scriptable);
scriptable.m_CurrentBranch = KeepsakeSteamManager.SteamBlackboardData.m_Branch.Value;
}
}
public abstract class PlayerTraitInstance : ModifierInstance
{
public PlayerTrait LiveTrait => (PlayerTrait)base.LiveModifier;
public PlayerTraitScriptable TraitScriptable => (PlayerTraitScriptable)base.Scriptable;
}
}
namespace CustomGameplayModifiers.Patches
{
[HarmonyPatch(typeof(OnFootDamageHandler), "OnReceivedDamage")]
internal static class Patch_OnFootDamageHandler_OnReceivedDamage
{
private static void Postfix(OnFootDamageHandler __instance, ReceivedDamage receivedDamage)
{
if (__instance.m_DamageComponent.m_HealthComponent.IsDead)
{
GameEventBus.Publish(new OnFootKilledEvent(__instance.m_Controller, receivedDamage));
}
}
}
[HarmonyPatch(typeof(FlyingDroneDamageHandler), "OnReceivedDamage")]
internal static class Patch_FlyingDroneDamageHandler_OnReceivedDamage
{
private static void Postfix(FlyingDroneDamageHandler __instance, ReceivedDamage receivedDamage)
{
if (__instance.m_DamageComponent.m_HealthComponent.IsDead)
{
GameEventBus.Publish(new OnFootKilledEvent((AI_Controller_OnFoot)(object)__instance.m_Controller, receivedDamage));
}
}
}
[HarmonyPatch(typeof(PickupableItemFirstPerson_GenericWeapon), "OnReload")]
internal static class Patch_PickupableItemFirstPerson_OnReload
{
private static void Prefix(PickupableItemFirstPerson_GenericWeapon __instance)
{
GameEventBus.Publish(new WeaponReloadedEvent(__instance));
}
}
[HarmonyPatch(typeof(PickupableItemFirstPerson_GenericWeapon), "Shoot")]
internal static class Patch_DoShootAsync
{
private static void Postfix(PickupableItemFirstPerson_GenericWeapon __instance)
{
GameEventBus.Publish(new WeaponFiredEvent(__instance));
}
}
[HarmonyPatch(typeof(PlayerPickupableItemHandler), "Handle_ItemHeldPersistentChanged")]
internal static class Patch_PlayerPickupableItemHandler
{
private static void Postfix(PlayerPickupableItemHandler __instance, PersistentPickupable persistentItem)
{
HeldItemTracker.OnItemHeldChanged(__instance.m_PlayerController, persistentItem);
}
}
[HarmonyPatch(typeof(PlayerShip_IndividualTurretController), "Fire")]
internal static class Patch_TurretController
{
private static void Postfix(SpaceShip_Cannon_Base cannon, VisualEffectAsset muzzleFlashFx, bool isFiredByBuddyBot)
{
GameEventBus.Publish(new ShipCannonFiredEvent(cannon, muzzleFlashFx, isFiredByBuddyBot));
}
}
[HarmonyPatch(typeof(ItemModule), "InitializeForPreview")]
internal static class Patch_ItemModule
{
private static void Postfix(ItemModule __instance)
{
ICustomModifier definition = ModifierRegistry.GetDefinition(((GameplayModifier)__instance).m_Template.AssetGUID);
if (definition != null && definition.CreateInstance() is ItemModuleInstance itemModuleInstance)
{
itemModuleInstance.Scriptable = ((GameplayModifier)__instance).m_Template;
itemModuleInstance.LiveModifier = (GameplayModifier)(object)__instance;
itemModuleInstance.IsPreview = true;
itemModuleInstance.OnPreviewActivated();
}
}
}
[HarmonyPatch(typeof(AI_Capability_Ship_Health), "DamageRecieved")]
internal static class Patch_AIShipDamageRecieved
{
private static void Postfix(AI_Capability_Ship_Health __instance, ReceivedDamage receivedDamage)
{
GameEventBus.Publish(new AIShipDamagedEvent(__instance, receivedDamage));
}
}
[HarmonyPatch(typeof(GameplayModifierManager))]
internal static class GameplayModifierManagerPatches
{
private static readonly List<IDisposable?> _subs = new List<IDisposable>();
private static readonly List<Action?> _observerCleanup = new List<Action>();
[HarmonyPostfix]
[HarmonyPatch("Awake")]
public static void Awake(GameplayModifierManager __instance)
{
foreach (IDisposable sub in _subs)
{
if (sub != null)
{
sub.Dispose();
}
}
_subs.Clear();
foreach (Action item7 in _observerCleanup)
{
item7?.Invoke();
}
_observerCleanup.Clear();
foreach (KeyValuePair<string, ICustomModifier> item8 in ModifierRegistry.All)
{
item8.Deconstruct(out var key, out var _);
string guid = key;
GameplayModifierScriptable val = ((Il2CppObjectBase)CustomAssetRegistry.GetModule(guid)).TryCast<GameplayModifierScriptable>();
if (!((Object)(object)val == (Object)null))
{
ModifierInjector.InjectIntoManager(val);
}
}
ItemModuleAddObserver itemModuleAddObserver = new ItemModuleAddObserver();
_observerCleanup.Add(delegate
{
itemModuleAddObserver.OnNextAction = null;
});
itemModuleAddObserver.OnNextAction = delegate(CollectionAddEvent<ItemModule> addEvent)
{
MelonCoroutines.Start(Link<ItemModule>(addEvent, "ItemModule"));
};
IDisposable item = __instance.m_BlackboardData.m_ActiveItemModules.ObserveAdd().Subscribe(new IObserver<CollectionAddEvent<ItemModule>>(((Il2CppObjectBase)itemModuleAddObserver).Pointer));
_subs.Add(item);
ItemModuleRemoveObserver itemModuleRemoveObserver = new ItemModuleRemoveObserver();
_observerCleanup.Add(delegate
{
itemModuleRemoveObserver.OnNextAction = null;
});
itemModuleRemoveObserver.OnNextAction = delegate(CollectionRemoveEvent<ItemModule> removeEvent)
{
MelonCoroutines.Start(Unlink<ItemModule>(removeEvent));
};
IDisposable item2 = __instance.m_BlackboardData.m_ActiveItemModules.ObserveRemove().Subscribe(new IObserver<CollectionRemoveEvent<ItemModule>>(((Il2CppObjectBase)itemModuleRemoveObserver).Pointer));
_subs.Add(item2);
ArtifactAddObserver artifactAddObserver = new ArtifactAddObserver();
_observerCleanup.Add(delegate
{
artifactAddObserver.OnNextAction = null;
});
artifactAddObserver.OnNextAction = delegate(CollectionAddEvent<Artifact> addEvent)
{
MelonCoroutines.Start(Link<Artifact>(addEvent, "Artifact"));
};
IDisposable item3 = __instance.m_BlackboardData.m_ActiveArtifacts.ObserveAdd().Subscribe(new IObserver<CollectionAddEvent<Artifact>>(((Il2CppObjectBase)artifactAddObserver).Pointer));
_subs.Add(item3);
ArtifactRemoveObserver artifactRemoveObserver = new ArtifactRemoveObserver();
_observerCleanup.Add(delegate
{
artifactRemoveObserver.OnNextAction = null;
});
artifactRemoveObserver.OnNextAction = delegate(CollectionRemoveEvent<Artifact> removeEvent)
{
MelonCoroutines.Start(Unlink<Artifact>(removeEvent));
};
IDisposable item4 = __instance.m_BlackboardData.m_ActiveArtifacts.ObserveRemove().Subscribe(new IObserver<CollectionRemoveEvent<Artifact>>(((Il2CppObjectBase)artifactRemoveObserver).Pointer));
_subs.Add(item4);
PlayerTraitAddObserver playerTraitAddObserver = new PlayerTraitAddObserver();
_observerCleanup.Add(delegate
{
playerTraitAddObserver.OnNextAction = null;
});
playerTraitAddObserver.OnNextAction = delegate(CollectionAddEvent<PlayerTrait> addEvent)
{
MelonCoroutines.Start(Link<PlayerTrait>(addEvent, "PlayerTrait"));
};
IDisposable item5 = __instance.m_BlackboardData.m_ActiveLocalPlayerTraits.ObserveAdd().Subscribe(new IObserver<CollectionAddEvent<PlayerTrait>>(((Il2CppObjectBase)playerTraitAddObserver).Pointer));
_subs.Add(item5);
PlayerTraitRemoveObserver playerTraitRemoveObserver = new PlayerTraitRemoveObserver();
_observerCleanup.Add(delegate
{
playerTraitRemoveObserver.OnNextAction = null;
});
playerTraitRemoveObserver.OnNextAction = delegate(CollectionRemoveEvent<PlayerTrait> removeEvent)
{
MelonCoroutines.Start(Unlink<PlayerTrait>(removeEvent));
};
IDisposable item6 = __instance.m_BlackboardData.m_ActiveLocalPlayerTraits.ObserveRemove().Subscribe(new IObserver<CollectionRemoveEvent<PlayerTrait>>(((Il2CppObjectBase)playerTraitRemoveObserver).Pointer));
_subs.Add(item6);
}
private static IEnumerator Link<T>(CollectionAddEvent<T>? addEvent, string typeName) where T : GameplayModifier
{
yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)delegate
{
CollectionAddEvent<T>? obj = addEvent;
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
object obj3 = obj.Value;
if (obj3 == null)
{
obj2 = null;
}
else
{
GameplayModifierScriptable template = ((GameplayModifier)obj3).m_Template;
obj2 = ((template != null) ? template.AssetGUID : null);
}
}
return obj2 != null;
}));
if (ModifierRegistry.IsCustom(((GameplayModifier)addEvent.Value).m_Template.AssetGUID))
{
GameplayModifier module = (GameplayModifier)(object)addEvent.Value;
ModifierRegistry.NotifyActivated(module.m_Template.AssetGUID, ((Il2CppObjectBase)module).Pointer, module.m_Template, module, () => ModifierRegistry.GetDefinition(module.m_Template.AssetGUID).CreateInstance());
Melon<Core>.Logger.Msg("[Patch] " + typeName + " activated: " + module.m_Template.AssetGUID);
}
}
private static IEnumerator Unlink<T>(CollectionRemoveEvent<T>? removeEvent) where T : GameplayModifier
{
yield return (object)new WaitUntil(Func<bool>.op_Implicit((Func<bool>)delegate
{
CollectionRemoveEvent<T>? obj = removeEvent;
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
object obj3 = obj.Value;
if (obj3 == null)
{
obj2 = null;
}
else
{
GameplayModifierScriptable template = ((GameplayModifier)obj3).m_Template;
obj2 = ((template != null) ? template.AssetGUID : null);
}
}
return obj2 != null;
}));
if (ModifierRegistry.IsCustom(((GameplayModifier)removeEvent.Value).m_Template.AssetGUID))
{
GameplayModifier module = (GameplayModifier)(object)removeEvent.Value;
ModifierRegistry.NotifyRemoved(module.m_Template.m_AssetGUID, ((Il2CppObjectBase)module).Pointer);
}
}
}
[HarmonyPatch(typeof(GUI_LoadoutTab))]
internal static class GUI_LoadoutTabPatches
{
[HarmonyPostfix]
[HarmonyPatch("SafeStart")]
public static void SafeStart(GUI_LoadoutTab __instance)
{
foreach (KeyValuePair<string, ICustomModifier> item in ModifierRegistry.All)
{
item.Deconstruct(out var key, out var _);
string guid = key;
PlayerTraitScriptable val = ((Il2CppObjectBase)CustomAssetRegistry.GetModule(guid)).TryCast<PlayerTraitScriptable>();
if (!((Object)(object)val == (Object)null))
{
LoadoutGUIInjector.InjectIntoLoadoutGUI(__instance, val);
}
}
}
}
}
namespace CustomGameplayModifiers.ItemModules
{
public abstract class CustomItemModule : CustomModifier<ItemModuleScriptable, ItemModuleInstance>
{
public abstract IReadOnlyList<string> SchoolGuids { get; }
public override void ConfigureScriptable(ItemModuleScriptable scriptable)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
base.ConfigureScriptable(scriptable);
scriptable.m_CurrentBranch = KeepsakeSteamManager.SteamBlackboardData.m_Branch.Value;
scriptable.m_AllowedItems = new List<AssetReference>();
scriptable.m_ForbiddenItems = new List<AssetReference>();
scriptable.m_LinkedStatusEffects = new List<StatusEffectScriptable>();
scriptable.m_TweakableValues_Common = new List<ItemModuleTweakableValue>();
scriptable.m_TweakableValues_Epic = new List<ItemModuleTweakableValue>();
scriptable.m_TweakableValues_Legendary = new List<ItemModuleTweakableValue>();
scriptable.m_TweakableValues_Rare = new List<ItemModuleTweakableValue>();
}
}
public abstract class ItemModuleInstance : ModifierInstance
{
public ItemModule LiveModule => (ItemModule)base.LiveModifier;
public ItemModuleScriptable ModuleScriptable => (ItemModuleScriptable)base.Scriptable;
public PersistentPickupable Item => LiveModule.Item;
public PlayerController LocalPlayer => PlayerHandler.GetPlayerHandler.localPlayerController;
public bool IsHeldByLocalPlayer => (Object)(object)LocalPlayer != (Object)null && LocalPlayer.Inventory.m_ItemHeldPersistentObject.HasValue && (Object)(object)LocalPlayer.Inventory.m_ItemHeldPersistentObject.Value == (Object)(object)Item;
public bool IsPreview { get; internal set; }
public float GetTweakable(int index)
{
return ((GameplayModifier)LiveModule).TweakableGetter(index);
}
public virtual void OnPreviewActivated()
{
((GameplayModifier)LiveModule).GetStatModificationAdd = Func<ModifierStat, GameObject, float>.op_Implicit(StatModificationAdd);
}
}
}
namespace CustomGameplayModifiers.Framework
{
public abstract class CustomItemModuleSchool
{
public abstract string Guid { get; }
public abstract void ConfigureSchool(ItemModuleSchool school);
internal ItemModuleSchool CreateSchool()
{
ItemModuleSchool val = ScriptableObject.CreateInstance<ItemModuleSchool>();
val.m_AssetGUID = Guid;
ConfigureSchool(val);
return val;
}
}
public abstract class CustomModifier<TScriptable, TInstance> : ICustomModifier where TScriptable : GameplayModifierScriptable where TInstance : ModifierInstance
{
public abstract string Guid { get; }
public abstract string Name { get; }
public abstract string Description { get; }
public virtual void ConfigureScriptable(TScriptable scriptable)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: 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_0086: Expected O, but got Unknown
//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_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Expected O, but got Unknown
((GameplayModifierScriptable)scriptable).m_Curves = new List<AnimationCurve>();
((GameplayModifierScriptable)scriptable).m_DependencyHandle = default(Handle);
((GameplayModifierScriptable)scriptable).m_Effects = new List<EffectData>();
((GameplayModifierScriptable)scriptable).m_TweakableValues = new List<TweakableValue>();
((GameplayModifierScriptable)scriptable).m_LocalizedName = new LocalizedString
{
TableReference = TableReference.op_Implicit("STC_Main"),
TableEntryReference = TableEntryReference.op_Implicit(Guid + "-NAME")
};
((GameplayModifierScriptable)scriptable).m_Description = new LocalizedString
{
TableReference = TableReference.op_Implicit("STC_Main"),
TableEntryReference = TableEntryReference.op_Implicit(Guid + "-DESC")
};
}
public abstract TInstance CreateInstance();
void ICustomModifier.ConfigureScriptable(GameplayModifierScriptable scriptable)
{
ConfigureScriptable((TScriptable)(object)scriptable);
}
GameplayModifierScriptable ICustomModifier.CreateScriptable()
{
return (GameplayModifierScriptable)(object)ScriptableObject.CreateInstance<TScriptable>();
}
ModifierInstance ICustomModifier.CreateInstance()
{
return CreateInstance();
}
}
public interface ICustomModifier
{
string Guid { get; }
string Name { get; }
string Description { get; }
void ConfigureScriptable(GameplayModifierScriptable scriptable);
GameplayModifierScriptable CreateScriptable();
ModifierInstance CreateInstance();
}
public abstract class ModifierInstance
{
public GameplayModifierScriptable Scriptable { get; internal set; } = null;
public GameplayModifier LiveModifier { get; internal set; } = null;
public virtual Func<ModifierStat, GameObject, float> StatModificationAdd => (ModifierStat _, GameObject _) => 0f;
public virtual void OnActivated()
{
}
public virtual void OnRemoved(bool destroyed = false)
{
}
}
internal static class BuildPipeline
{
private static ModifierBuilder _builder = new ModifierBuilder();
private static bool _isBuilt;
private static HashSet<string>? _knownSchoolGuids;
public static bool IsBuilt => _isBuilt;
public static IEnumerator Run()
{
yield return _builder.BuildAllSchools();
yield return _builder.BuildAllModifiers();
ModifierInjector.InjectAllIntoScriptableLib();
_knownSchoolGuids = new HashSet<string>();
Enumerator<string, ItemModuleSchool> enumerator = PersistentScriptableLibrary.m_ModuleSchoolAssets.GetEnumerator();
while (enumerator.MoveNext())
{
KeyValuePair<string, ItemModuleSchool> kvp = enumerator.Current;
_knownSchoolGuids.Add(kvp.Key);
}
_isBuilt = true;
}
internal static void ReconcileSchools()
{
if (_knownSchoolGuids == null)
{
return;
}
Dictionary<string, ItemModuleSchool> moduleSchoolAssets = PersistentScriptableLibrary.m_ModuleSchoolAssets;
if (moduleSchoolAssets == null)
{
return;
}
Enumerator<string, ItemModuleSchool> enumerator = moduleSchoolAssets.GetEnumerator();
while (enumerator.MoveNext())
{
KeyValuePair<string, ItemModuleSchool> current = enumerator.Current;
if (_knownSchoolGuids.Add(current.Key))
{
ModifierBuilder.LinkExistingModulesToSchool(current.Value, current.Key);
}
}
}
internal static IEnumerator BuildLateModifier(string guid)
{
yield return _builder.BuildOne(guid);
ModifierInjector.InjectScriptableLibFor(guid);
}
internal static IEnumerator BuildLateSchool(string guid)
{
yield return _builder.BuildOneSchool(guid);
}
}
internal static class LoadoutGUIInjector
{
public static void InjectIntoLoadoutGUI(GUI_LoadoutTab loadoutTab, PlayerTraitScriptable scriptable)
{
GameObject gameObject = ((Component)((IEnumerable<GUI_TraitSlot>)loadoutTab.m_TraitSlots).ElementAt(0)).gameObject;
GameObject val = Object.Instantiate<GameObject>(gameObject, loadoutTab.m_AvailableTraitsParent);
((Object)val).name = "Trait_" + ((GameplayModifierScriptable)scriptable).DisplayName;
VAssist_PlayerTrait component = val.GetComponent<VAssist_PlayerTrait>();
if ((Object)(object)component != (Object)null)
{
Object.DestroyImmediate((Object)(object)component);
}
GUI_TraitSlot component2 = val.GetComponent<GUI_TraitSlot>();
if ((Object)(object)component2 != (Object)null)
{
Object.DestroyImmediate((Object)(object)component2);
}
val.SetActive(false);
VAssist_PlayerTrait val2 = val.AddComponent<VAssist_PlayerTrait>();
val2.SetTrait(scriptable);
GUI_TraitSlot val3 = val.AddComponent<GUI_TraitSlot>();
val3.m_Trait = scriptable;
val3.m_IconImage = ((Component)val.transform.Find("IconImage")).GetComponent<Image>();
val3.m_CostBox = ((Component)val.transform.Find("PointCostBox")).gameObject;
val3.m_CostText = (TMP_Text)(object)((Component)val3.m_CostBox.transform.Find("PointCostText")).GetComponent<TextMeshProUGUI>();
val3.m_VAssist = val2;
val.SetActive(true);
}
}
public static class ModBundleLoader
{
private const string TexturesFolder = "textures/";
private const string ArtifactsFolder = "artifacts/";
public static bool LoadBundle(string bundlePath, string modId)
{
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Expected O, but got Unknown
if (!File.Exists(bundlePath))
{
ModLogger.Error("AssetBundle not found at " + bundlePath);
return false;
}
byte[] array = File.ReadAllBytes(bundlePath);
AssetBundle val = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(array));
if ((Object)(object)val == (Object)null)
{
ModLogger.Error("Failed to load AssetBundle from memory.");
return false;
}
string[] array2 = Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)val.GetAllAssetNames());
string[] array3 = array2;
foreach (string text in array3)
{
string text2 = text.ToLowerInvariant();
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
if (text2.Contains("textures/"))
{
Texture2D val2 = val.LoadAsset<Texture2D>(text);
if (!((Object)(object)val2 == (Object)null))
{
((Object)val2).hideFlags = (HideFlags)32;
Object.DontDestroyOnLoad((Object)(object)val2);
if (AssetRegistry<Texture2D>.Register(modId, fileNameWithoutExtension, val2))
{
ModLogger.Msg($"Loaded texture '{modId}:{fileNameWithoutExtension}'");
}
}
}
else if (text2.Contains("artifacts/"))
{
GameObject val3 = val.LoadAsset<GameObject>(text);
if (!((Object)(object)val3 == (Object)null))
{
MultilayerCollision val4 = val3.AddComponent<MultilayerCollision>();
val4.m_CreateForAllChildren = false;
val4.m_ExistingCollidersToIgnore = new Il2CppReferenceArray<Collider>((Collider[])(object)new Collider[0]);
val4.m_Layer = new SingleUnityLayer();
val4.m_Mode = (Mode)1;
((Object)val3).hideFlags = (HideFlags)32;
Object.DontDestroyOnLoad((Object)(object)val3);
if (AssetRegistry<GameObject>.Register(modId, fileNameWithoutExtension, val3))
{
ModLogger.Msg($"Loaded mesh '{modId}:{fileNameWithoutExtension}'");
}
}
}
else
{
ModLogger.Warning($"Asset '{text}' is not under '{"textures/"}' or '{"artifacts/"}' — skipped.");
}
}
val.Unload(false);
return true;
}
}
internal class ModifierBuilder
{
public IEnumerator BuildAllModifiers()
{
foreach (var (guid, _) in ModifierRegistry.All)
{
yield return BuildOne(guid);
}
}
public IEnumerator BuildAllSchools()
{
foreach (var (guid, _) in SchoolRegistry.All)
{
yield return BuildOneSchool(guid);
}
}
public IEnumerator BuildOneSchool(string guid)
{
if ((Object)(object)CustomAssetRegistry.GetModule(guid) != (Object)null)
{
yield break;
}
CustomItemModuleSchool schoolDef = SchoolRegistry.GetDefinition(guid);
if (schoolDef != null)
{
Melon<Core>.Logger.Msg("[ModifierBuilder] Building school " + guid);
ItemModuleSchool school = schoolDef.CreateSchool();
Object.DontDestroyOnLoad((Object)(object)school);
((Object)school).hideFlags = (HideFlags)32;
CustomAssetLocator.Register(guid);
CustomAssetRegistry.Register(guid, (Il2CppObjectBase)(object)school);
if (!PersistentScriptableLibrary.m_ModuleSchoolAssets.ContainsKey(guid))
{
PersistentScriptableLibrary.m_ModuleSchoolAssets.Add(guid, school);
PersistentScriptableLibrary.m_ModuleSchools.Add(school);
}
LinkExistingModulesToSchool(school, guid);
Melon<Core>.Logger.Msg("[ModifierBuilder] School " + guid + " ready.");
}
}
public IEnumerator BuildOne(string guid)
{
if ((Object)(object)CustomAssetRegistry.GetModule(guid) != (Object)null)
{
yield break;
}
ICustomModifier def = ModifierRegistry.GetDefinition(guid);
if (def != null)
{
Melon<Core>.Logger.Msg("[ModifierBuilder] Building " + guid);
GameplayModifierScriptable scriptable = def.CreateScriptable();
Object.DontDestroyOnLoad((Object)(object)scriptable);
scriptable.m_AssetGUID = guid;
((Object)scriptable).hideFlags = (HideFlags)32;
ModifierRegistry.NotifyScriptableCreated(guid, scriptable);
CustomAssetLocator.Register(guid);
CustomAssetRegistry.Register(guid, (Il2CppObjectBase)(object)scriptable);
ModifierInjector.InjectIntoManager(scriptable);
if ((Object)(object)((Il2CppObjectBase)scriptable).TryCast<ArtifactScriptable>() != (Object)null)
{
yield return VendorItemBuilder.RegisterVendorItem(guid);
}
Melon<Core>.Logger.Msg("[ModifierBuilder] " + guid + " ready.");
}
}
internal static void LinkExistingModulesToSchool(ItemModuleSchool school, string schoolGuid)
{
ItemModuleScriptable scriptable = default(ItemModuleScriptable);
foreach (var (text2, customModifier2) in ModifierRegistry.All)
{
if (customModifier2 is CustomItemModule customItemModule && customItemModule.SchoolGuids.Contains(schoolGuid) && PersistentScriptableLibrary.m_ItemModuleByGuid.TryGetValue(text2, ref scriptable))
{
ModifierInjector.AddModuleToSchool(scriptable, schoolGuid);
}
}
}
}
internal static class ModifierInjector
{
public static void InjectIntoManager(GameplayModifierScriptable scriptable)
{
GameplayModifierManager val = WeakStaticMonoBehaviourReference<GameplayModifierManager>.op_Implicit(GameplayModifierManager.m_Instance);
if (!((Object)(object)val == (Object)null))
{
string assetGUID = scriptable.m_AssetGUID;
if (!val.m_ModifierAssetMap.ContainsKey(assetGUID))
{
val.m_ModifierScriptables.Add(scriptable);
val.m_ModifierAssetMap.Add(assetGUID, scriptable);
}
PlayerTraitScriptable val2 = ((Il2CppObjectBase)scriptable).TryCast<PlayerTraitScriptable>();
if ((Object)(object)val2 != (Object)null)
{
IReadOnlyReactiveCollection<PlayerTraitScriptable> unlockedTraits = MetaProgressionManager.UnlockedTraits;
((Collection<PlayerTraitScriptable>)(object)((Il2CppObjectBase)unlockedTraits).TryCast<ReactiveCollection<PlayerTraitScriptable>>())?.Add(val2);
}
}
}
public static void InjectIntoScriptableLib(ItemModuleScriptable scriptable, IReadOnlyList<string> schoolGuids)
{
ModLogger.Msg("Injecting into persistent lib: " + ((GameplayModifierScriptable)scriptable).DisplayName);
if (!PersistentScriptableLibrary.m_ItemModuleByGuid.ContainsKey(((GameplayModifierScriptable)scriptable).m_AssetGUID))
{
PersistentScriptableLibrary.m_ItemModuleByGuid.Add(((GameplayModifierScriptable)scriptable).m_AssetGUID, scriptable);
}
if (!IsInIl2CppList<ItemModuleScriptable>(PersistentScriptableLibrary.m_ItemModules, ((GameplayModifierScriptable)scriptable).m_AssetGUID))
{
PersistentScriptableLibrary.m_ItemModules.Add(scriptable);
}
foreach (string schoolGuid in schoolGuids)
{
AddModuleToSchool(scriptable, schoolGuid);
}
}
public static void AddModuleToSchool(ItemModuleScriptable scriptable, string schoolGuid)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
ItemModuleSchool val = default(ItemModuleSchool);
if (!PersistentScriptableLibrary.m_ModuleSchoolAssets.TryGetValue(schoolGuid, ref val))
{
return;
}
for (int i = 0; i < val.m_SchoolEntries.Count; i++)
{
if (((GameplayModifierScriptable)val.m_SchoolEntries[i].m_ItemModule).m_AssetGUID == ((GameplayModifierScriptable)scriptable).m_AssetGUID)
{
return;
}
}
ModuleSchoolEntry val2 = new ModuleSchoolEntry();
val2.m_ItemModule = scriptable;
val2.m_Weight = scriptable.m_Weight;
val.m_SchoolEntries.Add(val2);
}
public static void InjectScriptableLibFor(string guid)
{
if (!(ModifierRegistry.GetDefinition(guid) is CustomItemModule customItemModule))
{
return;
}
ScriptableObject? module = CustomAssetRegistry.GetModule(guid);
ItemModuleScriptable val = ((module != null) ? ((Il2CppObjectBase)module).TryCast<ItemModuleScriptable>() : null);
if ((Object)(object)val == (Object)null)
{
return;
}
if (!PersistentScriptableLibrary.m_ItemModuleByGuid.ContainsKey(guid))
{
PersistentScriptableLibrary.m_ItemModuleByGuid.Add(guid, val);
}
if (!IsInIl2CppList<ItemModuleScriptable>(PersistentScriptableLibrary.m_ItemModules, guid))
{
PersistentScriptableLibrary.m_ItemModules.Add(val);
}
foreach (string schoolGuid in customItemModule.SchoolGuids)
{
AddModuleToSchool(val, schoolGuid);
}
}
public static void InjectAllIntoScriptableLib()
{
foreach (KeyValuePair<string, ICustomModifier> item in ModifierRegistry.All)
{
item.Deconstruct(out var key, out var _);
string guid = key;
ScriptableObject module = CustomAssetRegistry.GetModule(guid);
ItemModuleScriptable val = ((Il2CppObjectBase)module).TryCast<ItemModuleScriptable>();
if (!((Object)(object)val == (Object)null) && ModifierRegistry.GetDefinition(guid) is CustomItemModule customItemModule)
{
InjectIntoScriptableLib(val, customItemModule.SchoolGuids);
}
}
}
private static bool IsInIl2CppList<T>(List<T> list, string guid) where T : Object
{
for (int i = 0; i < list.Count; i++)
{
GameplayModifierScriptable val = ((Il2CppObjectBase)(object)list[i]).TryCast<GameplayModifierScriptable>();
if ((Object)(object)val != (Object)null && val.m_AssetGUID == guid)
{
return true;
}
}
return false;
}
}
internal static class VendorItemBuilder
{
private static readonly List<ArtifactSoldByVendor> _vendorArtifacts = new List<ArtifactSoldByVendor>();
private static Currency? cachedCurrency;
public static IEnumerator RegisterVendorItem(string guid)
{
if ((Object)(object)cachedCurrency == (Object)null)
{
AsyncOperationHandle<Currency> handle = Addressables.LoadAssetAsync<Currency>(Object.op_Implicit("00e70cd5fa09dc64aa3e64b4d8ee4011"));
yield return handle;
if ((int)handle.Status == 1)
{
cachedCurrency = handle.Result;
}
}
ArtifactSoldByVendor artifactDef = (ArtifactSoldByVendor)ModifierRegistry.GetDefinition(guid);
if (artifactDef != null)
{
VendorItem vendorItem = ScriptableObject.CreateInstance<VendorItem>();
vendorItem.m_Item = CustomAssetRegistry.GetModule(guid);
vendorItem.m_AssetGuid = artifactDef.VendorItemGuid;
vendorItem.m_BaseCost_Currency = artifactDef.CreditBaseCost;
vendorItem.m_BaseCost_Materia = artifactDef.MateriaBaseCost;
vendorItem.m_CanSpawnCondition = new VentureCondition();
vendorItem.m_CanSpawnCondition.m_RequiredStatus = (VentureStatus)0;
vendorItem.m_CanSpawnCondition.m_Venture = null;
vendorItem.m_Currency = cachedCurrency;
vendorItem.m_CurrencyReward = new ItemCurrencyValue();
vendorItem.m_CurrencyReward.m_Amount = 0f;
vendorItem.m_CurrencyReward.m_Currency = null;
CustomAssetLocator.Register(vendorItem.m_AssetGuid);
CustomAssetRegistry.Register(vendorItem.m_AssetGuid, (Il2CppObjectBase)(object)vendorItem);
_vendorArtifacts.Add(artifactDef);
}
}
public static void AddItemsToVendor(Vendor vendor)
{
VendorItemList randomItemList = vendor.m_RandomItemList;
List<PotentialItem> val = ((randomItemList != null) ? randomItemList.m_PotentialItems : null);
if (val == null)
{
return;
}
HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
Enumerator<PotentialItem> enumerator = val.GetEnumerator();
while (enumerator.MoveNext())
{
PotentialItem current = enumerator.Current;
if ((Object)(object)((current != null) ? current.m_Item : null) != (Object)null)
{
hashSet.Add(current.m_Item.m_AssetGuid);
}
}
foreach (ArtifactSoldByVendor vendorArtifact in _vendorArtifacts)
{
string vendorItemGuid = vendorArtifact.VendorItemGuid;
if (!hashSet.Contains(vendorItemGuid))
{
ScriptableObject? module = CustomAssetRegistry.GetModule(vendorItemGuid);
VendorItem val2 = ((module != null) ? ((Il2CppObjectBase)module).TryCast<VendorItem>() : null);
if (!((Object)(object)val2 == (Object)null))
{
PotentialItem val3 = Activator.CreateInstance<PotentialItem>();
val3.m_AllowMultiple = vendorArtifact.VendorAllowMultiple;
val3.m_PickChanceWeight = vendorArtifact.VendorPickChanceWeight;
val3.m_Item = val2;
val.Add(val3);
hashSet.Add(vendorItemGuid);
}
}
}
}
}
public static class ModLogger
{
private const string CategoryName = "CustomGameplayModifiers";
private static MelonPreferences_Category _category;
private static MelonPreferences_Entry<bool> _verboseLogging;
public static void Initialize()
{
_category = MelonPreferences.CreateCategory("CustomGameplayModifiers", "Custom Gameplay Modifiers");
_verboseLogging = _category.CreateEntry<bool>("VerboseLogging", false, "Verbose Logging", "When enabled, all log messages are shown. When disabled, only errors are printed.", false, false, (ValueValidator)null, (string)null);
}
public static void Msg(string text)
{
if (_verboseLogging.Value)
{
MelonLogger.Msg(text);
}
}
public static void Warning(string text)
{
if (_verboseLogging.Value)
{
MelonLogger.Warning(text);
}
}
public static void Error(string text)
{
MelonLogger.Error(text);
}
}
public static class AssetRegistry<T> where T : Object
{
private static readonly TypedAssetRegistry<T> s_Registry = new TypedAssetRegistry<T>();
public static T? Get(string ns, string key)
{
return s_Registry.Get(ns, key);
}
internal static bool Register(string ns, string key, T obj)
{
return s_Registry.Register(ns, key, obj);
}
internal static void RegisterVanilla(string key, T obj)
{
s_Registry.RegisterVanilla(key, obj);
}
}
public enum ComponentSubtype
{
Engine,
Aux,
Reactor,
Sensor,
ShieldGenerator,
PilotCannon,
MultiTurret,
SpecialWeapon,
SpecialWeaponNoProjectile
}
public static class ItemAssetRegistry
{
private sealed record WeaponData(string Guid, string Name, bool IsMelee);
private sealed record ComponentData(string Guid, string Name, ComponentSubtype Subtype);
private static readonly WeaponData[] WeaponEntries = new WeaponData[13]
{
new WeaponData("046383b13f53ad144805f5dca98b4b86", "MeleeWeapon_Chainblade", IsMelee: true),
new WeaponData("a52219e07db611248800766fe8d53744", "MeleeWeapon_Wrench", IsMelee: true),
new WeaponData("f077b42a85cfb7f4bb0d55729c4fc5c0", "MeleeWeapon_Crowbar", IsMelee: true),
new WeaponData("46f7dd81eea325d4295083369d7b9a9d", "MeleeWeapon_AtiranBlackbelt", IsMelee: true),
new WeaponData("b5b14acbf52842b4f90002bd4e9d1391", "Pickupable_SemiRifle_MK0", IsMelee: false),
new WeaponData("11d2d7e9f079ed4499c9591d8d68c7a7", "Pickupable_Shotgun_MK0", IsMelee: false),
new WeaponData("2cbd789d647fa9a4d96f462001a99c91", "Pickupable_MarksmanRifle_Mk0", IsMelee: false),
new WeaponData("ea1f1e6ac3c88fe469708ce10b5e451a", "Pickupable_SMG_MK0", IsMelee: false),
new WeaponData("b90b477e483f6cc4aa9a48f33e4400e3", "Pickupable_PDW_MK0", IsMelee: false),
new WeaponData("55b2b5f6d20d4eb4ab9ef216e5237928", "Pickupable_LMG_MK0", IsMelee: false),
new WeaponData("dd2afc39b34322c4381b6a3ed3e5988a", "Pickupable_AssaultRifle_MK0", IsMelee: false),
new WeaponData("5b78767341d912a489d26a3136ab62c7", "Pickupable_MiningLaser_MK0", IsMelee: false),
new WeaponData("d0261db8215008e48abfefbf7485acfd", "Pickupable_Revolver_MK0", IsMelee: false)
};
private static readonly ComponentData[] ComponentEntries = new ComponentData[31]
{
new ComponentData("f1302af5a63e825478b7fb9f953401aa", "Component_Engine_1_1", ComponentSubtype.Engine),
new ComponentData("4524f4ac1fa8cb34dbff50f8c5c14927", "Component_Engine_2_1", ComponentSubtype.Engine),
new ComponentData("fb2bbc3f13c228a44ba53f020e1df249", "Component_Engine_3_1", ComponentSubtype.Engine),
new ComponentData("dde01f5723d9b0047abb3d223f5541cd", "Component_Engine_4_1", ComponentSubtype.Engine),
new ComponentData("2c60b00a88d34b546865a36738fabc2a", "Component_Aux_1_1", ComponentSubtype.Aux),
new ComponentData("8cbe912f6e885134680a52935cca96a5", "Component_Aux_2_1", ComponentSubtype.Aux),
new ComponentData("4bfcb457279ce824e8fd7989760d9252", "Component_Aux_3_1", ComponentSubtype.Aux),
new ComponentData("65e495611fd9233419832053f8ce55bd", "Component_Reactor_1_1", ComponentSubtype.Reactor),
new ComponentData("85b241f7f2fa6654e9c522519358d1bc", "Component_Reactor_2_1", ComponentSubtype.Reactor),
new ComponentData("f400f9acd1731b64a87b69ce40517971", "Component_Reactor_3_1", ComponentSubtype.Reactor),
new ComponentData("95c51a0f21d28ba459a43bbf3dbc0790", "Component_Reactor_4_1", ComponentSubtype.Reactor),
new ComponentData("3ee2f96ed55e8de4898d4f922eba8f66", "Component_Sensor_1_1", ComponentSubtype.Sensor),
new ComponentData("d4b4eb9b7856fce4e9c1bb3a78c9807e", "Component_Sensor_2_1", ComponentSubtype.Sensor),
new ComponentData("eac8acd058989964ab7a07cf7de03fa5", "Component_Sensor_3_1", ComponentSubtype.Sensor),
new ComponentData("352d8b4d1f0f38249b5a88c19a11caf3", "Component_ShieldGenerator_1_1", ComponentSubtype.ShieldGenerator),
new ComponentData("7a2d7e2dbbb33f742a1c885667377425", "Component_ShieldGenerator_2_1", ComponentSubtype.ShieldGenerator),
new ComponentData("554d65de54698714c9f5d2f73bc33261", "Component_ShieldGenerator_3_1", ComponentSubtype.ShieldGenerator),
new ComponentData("c7e0f6d13e18db440b37a42470f42744", "Component_PilotCannon_1_1", ComponentSubtype.PilotCannon),
new ComponentData("c3346b9a547672948a2fe02ea2bb5de5", "Component_PilotCannon_2_1", ComponentSubtype.PilotCannon),
new ComponentData("8c32f9e4ff293894582ceb6b831c40af", "Component_PilotCannon_3_1", ComponentSubtype.PilotCannon),
new ComponentData("d151b8914ed56d74985d345a118f9a5e", "Component_PilotCannon_4_1", ComponentSubtype.PilotCannon),
new ComponentData("558ac570efdfbe64390ab32c39d45ff3", "Component_MultiTurret_1_1", ComponentSubtype.MultiTurret),
new ComponentData("5e4082467be3c344698f724e74c6660a", "Component_MultiTurret_2_1", ComponentSubtype.MultiTurret),
new ComponentData("b98c1f15ee8b58343acf4f62ddaa93ab", "Component_MultiTurret_3_1", ComponentSubtype.MultiTurret),
new ComponentData("e2b646f5b39d9994a929c62d32635793", "Component_MultiTurret_4_1", ComponentSubtype.MultiTurret),
new ComponentData("889c471a3fab57d44b28f2592be5d7f8", "Component_SpecialWeapon_HeavyCannon", ComponentSubtype.SpecialWeapon),
new ComponentData("15bebeb1e9273af4fb7f4213452a6c58", "Component_SpecialWeapon_MissileTurret_1", ComponentSubtype.SpecialWeapon),
new ComponentData("d593e671947518544ab6dcd2deef3e2e", "Component_SpecialWeapon_Railgun_1", ComponentSubtype.SpecialWeapon),
new ComponentData("3290a7dbea83de5488cca77e44cae0a8", "Component_SpecialWeapon_Minigun", ComponentSubtype.SpecialWeapon),
new ComponentData("e1d2c08495890004e9ebb0ca7fe7c5a1", "Component_SpecialWeapon_Shield_1", ComponentSubtype.SpecialWeaponNoProjectile),
new ComponentData("10b36cf783993154cbcf8679744cd900", "Component_SpecialWeapon_TargetingModule_1", ComponentSubtype.SpecialWeaponNoProjectile)
};
private static List<AssetReference>? _allWeaponRefs;
private static Dictionary<string, AssetReference>? _weaponByGuid;
private static Dictionary<string, AssetReference>? _weaponByName;
private static List<AssetReference>? _allComponentRefs;
private static Dictionary<string, AssetReference>? _componentByGuid;
private static Dictionary<string, AssetReference>? _componentByName;
private static bool _initialized;
internal static void Initialize()
{
if (!_initialized)
{
_initialized = true;
BuildWeaponCache();
BuildComponentCache();
}
}
private static void BuildCache<T>(T[] entries, Func<T, string> getGuid, Func<T, string> getName, out List<AssetReference> allRefs, out Dictionary<string, AssetReference> byGuid, out Dictionary<string, AssetReference> byName)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
allRefs = new List<AssetReference>(entries.Length);
byGuid = new Dictionary<string, AssetReference>(entries.Length);
byName = new Dictionary<string, AssetReference>(entries.Length);
foreach (T arg in entries)
{
AssetReference val = new AssetReference(getGuid(arg));
allRefs.Add(val);
byGuid[getGuid(arg)] = val;
byName[getName(arg)] = val;
}
}
private static void BuildWeaponCache()
{
BuildCache(WeaponEntries, (WeaponData w) => w.Guid, (WeaponData w) => w.Name, out _allWeaponRefs, out _weaponByGuid, out _weaponByName);
}
private static void BuildComponentCache()
{
BuildCache(ComponentEntries, (ComponentData c) => c.Guid, (ComponentData c) => c.Name, out _allComponentRefs, out _componentByGuid, out _componentByName);
}
public static IEnumerable<AssetReference> GetAllWeapons()
{
return _allWeaponRefs;
}
public static IEnumerable<AssetReference> GetAllMeleeWeapons()
{
return from w in WeaponEntries
where w.IsMelee
select _weaponByGuid.GetValueOrDefault(w.Guid) into r
where r != null
select r;
}
public static IEnumerable<AssetReference> GetAllPrimaryWeapons()
{
return from w in WeaponEntries
where !w.IsMelee
select _weaponByGuid.GetValueOrDefault(w.Guid) into r
where r != null
select r;
}
public static AssetReference? GetWeaponByGuid(string guid)
{
if (string.IsNullOrEmpty(guid) || _weaponByGuid == null)
{
return null;
}
_weaponByGuid.TryGetValue(guid, out AssetReference value);
return value;
}
public static AssetReference? GetWeaponByName(string name)
{
if (string.IsNullOrEmpty(name) || _weaponByName == null)
{
return null;
}
_weaponByName.TryGetValue(name, out AssetReference value);
return value;
}
public static IEnumerable<AssetReference> GetAllComponents()
{
return _allComponentRefs;
}
public static IEnumerable<AssetReference> GetAllComponentsBySubtype(ComponentSubtype subtype)
{
return from c in ComponentEntries
where c.Subtype == subtype
select _componentByGuid.GetValueOrDefault(c.Guid) into r
where r != null
select r;
}
public static AssetReference? GetComponentByGuid(string guid)
{
if (string.IsNullOrEmpty(guid) || _componentByGuid == null)
{
return null;
}
_componentByGuid.TryGetValue(guid, out AssetReference value);
return value;
}
public static AssetReference? GetComponentByName(string name)
{
if (string.IsNullOrEmpty(name) || _componentByName == null)
{
return null;
}
_componentByName.TryGetValue(name, out AssetReference value);
return value;
}
}
public static class ModifierRegistry
{
private static readonly Dictionary<string, ICustomModifier> _definitions = new Dictionary<string, ICustomModifier>();
private static readonly Dictionary<string, Dictionary<IntPtr, ModifierInstance>> _instances = new Dictionary<string, Dictionary<IntPtr, ModifierInstance>>();
internal static IReadOnlyDictionary<string, ICustomModifier> All => _definitions;
public static void Register(ICustomModifier modifier)
{
if (_definitions.ContainsKey(modifier.Guid))
{
throw new InvalidOperationException("A modifier with GUID '" + modifier.Guid + "' is already registered.");
}
_definitions[modifier.Guid] = modifier;
LocalizationInjector.AddOrUpdate(modifier.Guid + "-NAME", modifier.Name);
LocalizationInjector.AddOrUpdate(modifier.Guid + "-DESC", modifier.Description);
ModLogger.Msg("[ModifierRegistry] Registered: " + modifier.Guid);
if (BuildPipeline.IsBuilt)
{
ModLogger.Msg("[ModifierRegistry] Late registration — triggering incremental build.");
MelonCoroutines.Start(BuildPipeline.BuildLateModifier(modifier.Guid));
}
}
internal static ICustomModifier? GetDefinition(string guid)
{
ICustomModifier value;
return _definitions.TryGetValue(guid, out value) ? value : null;
}
internal static bool IsCustom(string guid)
{
return _definitions.ContainsKey(guid);
}
internal static IEnumerable<ModifierInstance> GetInstances(string guid)
{
if (!_instances.TryGetValue(guid, out Dictionary<IntPtr, ModifierInstance> map))
{
yield break;
}
foreach (ModifierInstance value in map.Values)
{
yield return value;
}
}
internal static IEnumerable<ModifierInstance> AllInstances()
{
foreach (Dictionary<IntPtr, ModifierInstance> map in _instances.Values)
{
foreach (ModifierInstance value in map.Values)
{
yield return value;
}
}
}
internal static ModifierInstance? GetInstance(string guid, IntPtr stablePtr)
{
if (_instances.TryGetValue(guid, out Dictionary<IntPtr, ModifierInstance> value) && value.TryGetValue(stablePtr, out var value2))
{
return value2;
}
return null;
}
internal static void ClearAllInstances()
{
foreach (Dictionary<IntPtr, ModifierInstance> value in _instances.Values)
{
foreach (ModifierInstance value2 in value.Values)
{
try
{
value2.OnRemoved(destroyed: true);
}
catch (NullReferenceException ex)
{
ModLogger.Error(ex.Message);
ModLogger.Error("Possibly caused by trying to access a LiveModifier while the parameter \"destroyed\" is true");
ModLogger.Error(ex.StackTrace ?? "null");
}
}
}
_instances.Clear();
}
internal static void NotifyScriptableCreated(string guid, GameplayModifierScriptable scriptable)
{
GetDefinition(guid)?.ConfigureScriptable(scriptable);
}
internal static ModifierInstance? NotifyActivated(string guid, IntPtr stablePtr, GameplayModifierScriptable scriptable, GameplayModifier liveModifier, Func<ModifierInstance> createInstance)
{
if (!_definitions.ContainsKey(guid))
{
return null;
}
if (!_instances.TryGetValue(guid, out Dictionary<IntPtr, ModifierInstance> value))
{
value = (_instances[guid] = new Dictionary<IntPtr, ModifierInstance>());
}
if (value.TryGetValue(stablePtr, out var value2))
{
value2.LiveModifier = liveModifier;
return value2;
}
ModifierInstance modifierInstance = createInstance();
modifierInstance.Scriptable = scriptable;
modifierInstance.LiveModifier = liveModifier;
value[stablePtr] = modifierInstance;
modifierInstance.OnActivated();
return modifierInstance;
}
internal static void NotifyRemoved(string guid, IntPtr stablePtr)
{
if (_instances.TryGetValue(guid, out Dictionary<IntPtr, ModifierInstance> value) && value.TryGetValue(stablePtr, out var value2))
{
value2.OnRemoved();
value.Remove(stablePtr);
}
}
}
public static class SchoolRegistry
{
private static readonly Dictionary<string, CustomItemModuleSchool> _definitions = new Dictionary<string, CustomItemModuleSchool>();
internal static IReadOnlyDictionary<string, CustomItemModuleSchool> All => _definitions;
public static void Register(CustomItemModuleSchool school)
{
if (_definitions.ContainsKey(school.Guid))
{
throw new InvalidOperationException("A school with GUID '" + school.Guid + "' is already registered.");
}
_definitions[school.Guid] = school;
ModLogger.Msg("[SchoolRegistry] Registered: " + school.Guid);
if (BuildPipeline.IsBuilt)
{
ModLogger.Msg("[SchoolRegistry] Late registration — triggering incremental build.");
MelonCoroutines.Start(BuildPipeline.BuildLateSchool(school.Guid));
}
}
internal static CustomItemModuleSchool? GetDefinition(string guid)
{
CustomItemModuleSchool value;
return _definitions.TryGetValue(guid, out value) ? value : null;
}
}
internal class TypedAssetRegistry<T> where T : Object
{
private const string VanillaNamespace = "vanilla";
private readonly Dictionary<string, Dictionary<string, T>> _namespaces = new Dictionary<string, Dictionary<string, T>>();
public T? Get(string ns, string key)
{
if (_namespaces.TryGetValue(ns, out Dictionary<string, T> value) && value.TryGetValue(key, out var value2))
{
return value2;
}
return default(T);
}
public bool Register(string ns, string key, T obj)
{
if (string.Equals(ns, "vanilla", StringComparison.OrdinalIgnoreCase))
{
ModLogger.Error($"Refusing to register '{key}' under reserved namespace '{"vanilla"}'.");
return false;
}
if ((Object)(object)obj == (Object)null)
{
ModLogger.Error($"Refusing to register null object for '{ns}:{key}'.");
return false;
}
if (!_namespaces.TryGetValue(ns, out Dictionary<string, T> value))
{
value = new Dictionary<string, T>();
_namespaces[ns] = value;
}
if (value.ContainsKey(key))
{
ModLogger.Warning($"Overwriting existing key '{key}' in namespace '{ns}'.");
}
value[key] = obj;
return true;
}
internal void RegisterVanilla(string key, T obj)
{
if (!_namespaces.TryGetValue("vanilla", out Dictionary<string, T> value))
{
value = new Dictionary<string, T>();
_namespaces["vanilla"] = value;
}
value[key] = obj;
}
}
public static class GameEventBus
{
private static readonly Dictionary<Type, Delegate?> _handlers = new Dictionary<Type, Delegate>();
public static void Subscribe<T>(Action<T> handler)
{
Type typeFromHandle = typeof(T);
_handlers[typeFromHandle] = (_handlers.TryGetValue(typeFromHandle, out Delegate value) ? Delegate.Combine(value, handler) : handler);
}
public static void Unsubscribe<T>(Action<T> handler)
{
Type typeFromHandle = typeof(T);
if (_handlers.TryGetValue(typeFromHandle, out Delegate value))
{
Delegate obj = Delegate.Remove(value, handler);
if ((object)obj == null)
{
_handlers.Remove(typeFromHandle);
}
else
{
_handlers[typeFromHandle] = obj;
}
}
}
public static void Publish<T>(T evt)
{
if (_handlers.TryGetValue(typeof(T), out Delegate value) && (object)value != null)
{
((Action<T>)value)(evt);
}
}
internal static void ClearSubscriptions()
{
_handlers.Clear();
}
}
internal static class HeldItemTracker
{
private static readonly Dictionary<ulong, PersistentPickupable?> _lastHeldByClientId = new Dictionary<ulong, PersistentPickupable>();
public static void OnItemHeldChanged(PlayerController player, PersistentPickupable? current)
{
if (!((Object)(object)player == (Object)null))
{
_lastHeldByClientId.TryGetValue(player.ClientId, out PersistentPickupable value);
if (!object.Equals(value, current))
{
_lastHeldByClientId[player.ClientId] = current;
GameEventBus.Publish(new ItemHeldChangedEvent(player, value, current));
}
}
}
}
internal static class LocalizationInjector
{
private static StringTable? s_StringTable;
private static readonly Dictionary<string, string> s_PendingEntries = new Dictionary<string, string>();
private static readonly object s_Lock = new object();
public static bool IsReady
{
get
{
lock (s_Lock)
{
return (Object)(object)s_StringTable != (Object)null;
}
}
}
public static IEnumerator FindTableRoutine()
{
int attempts = 0;
while (attempts < 300)
{
bool found;
lock (s_Lock)
{
found = (Object)(object)s_StringTable != (Object)null;
}
if (found)
{
yield break;
}
attempts++;
Il2CppArrayBase<StringTable> tables = Resources.FindObjectsOfTypeAll<StringTable>();
foreach (StringTable table in tables)
{
if (((LocalizationTable)table).TableCollectionName == "STC_Main")
{
lock (s_Lock)
{
s_StringTable = table;
}
ModLogger.Msg("STC_Main found, flushing pending entries.");
FlushPending();
yield break;
}
}
yield return (object)new WaitForSeconds(0.5f);
}
lock (s_Lock)
{
if ((Object)(object)s_StringTable == (Object)null)
{
ModLogger.Error("STC_Main was never found after max attempts.");
}
}
}
private static void FlushPending()
{
lock (s_Lock)
{
foreach (KeyValuePair<string, string> s_PendingEntry in s_PendingEntries)
{
WriteEntry(s_PendingEntry.Key, s_PendingEntry.Value);
}
s_PendingEntries.Clear();
}
}
public static void AddOrUpdate(string key, string value)
{
lock (s_Lock)
{
if ((Object)(object)s_StringTable == (Object)null)
{
s_PendingEntries[key] = value;
}
else
{
WriteEntry(key, value);
}
}
}
private static void WriteEntry(string key, string value)
{
StringTableEntry entry = ((DetailedLocalizationTable<StringTableEntry>)(object)s_StringTable).GetEntry(key);
if (entry != null)
{
entry.Value = value;
}
else
{
((DetailedLocalizationTable<StringTableEntry>)(object)s_StringTable).AddEntry(key, value);
}
}
}
internal static class SceneEventsService
{
private static GameplayModifierManager? _lastKnownManager;
public static void OnSceneLoaded(int buildIndex, string sceneName)
{
HandleManagerChange(sceneName);
InjectVendors();
BuildPipeline.ReconcileSchools();
RefreshArtifactCabinets();
}
private static void HandleManagerChange(string sceneName)
{
GameplayModifierManager instance = GameplayModifierManager.Instance;
if (instance != _lastKnownManager)
{
ModLogger.Msg("GameplayModifierManager instance changed on scene '" + sceneName + "' — clearing modifier registry.");
ModifierRegistry.ClearAllInstances();
GameEventBus.ClearSubscriptions();
_lastKnownManager = instance;
}
}
private static void InjectVendors()
{
Vendor[] array = Il2CppArrayBase<Vendor>.op_Implicit(Object.FindObjectsByType<Vendor>((FindObjectsInactive)1, (FindObjectsSortMode)0));
Vendor[] array2 = array;
foreach (Vendor val in array2)
{
VendorItemList randomItemList = val.m_RandomItemList;
if (((randomItemList != null) ? randomItemList.m_AssetGuid : null) == "f21d418892b193b458716f7c6576ac21")
{
ModLogger.Msg(((Object)val).name);
VendorItemBuilder.AddItemsToVendor(val);
}
}
}
private static void RefreshArtifactCabinets()
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
ArtifactCabinet[] array = Il2CppArrayBase<ArtifactCabinet>.op_Implicit(Object.FindObjectsOfType<ArtifactCabinet>());
ArtifactCabinet[] array2 = array;
foreach (ArtifactCabinet val in array2)
{
if (val.Artifact != null)
{
val.m_ArtifactVisualsInstalled.DestroyCurrentVisuals();
val.m_ArtifactVisualsInstalled.SpawnVisualsAsync(val.Artifact, new CancellationToken(), false);
}
}
}
}
}
namespace CustomGameplayModifiers.Framework.Observers
{
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionAddEvent<Artifact>>) })]
public class ArtifactAddObserver : Object
{
public Action<CollectionAddEvent<Artifact>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public ArtifactAddObserver(IntPtr ptr)
: base(ptr)
{
}
public ArtifactAddObserver()
: base(ClassInjector.DerivedConstructorPointer<ArtifactAddObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionAddEvent<Artifact> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionRemoveEvent<Artifact>>) })]
public class ArtifactRemoveObserver : Object
{
public Action<CollectionRemoveEvent<Artifact>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public ArtifactRemoveObserver(IntPtr ptr)
: base(ptr)
{
}
public ArtifactRemoveObserver()
: base(ClassInjector.DerivedConstructorPointer<ArtifactRemoveObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionRemoveEvent<Artifact> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<float>) })]
public class FloatObserver : Object
{
public Action<float>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public FloatObserver(IntPtr ptr)
: base(ptr)
{
}
public FloatObserver()
: base(ClassInjector.DerivedConstructorPointer<FloatObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(float value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<int>) })]
public class IntObserver : Object
{
public Action<int>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public IntObserver(IntPtr ptr)
: base(ptr)
{
}
public IntObserver()
: base(ClassInjector.DerivedConstructorPointer<IntObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(int value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionAddEvent<ItemModule>>) })]
public class ItemModuleAddObserver : Object
{
public Action<CollectionAddEvent<ItemModule>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public ItemModuleAddObserver(IntPtr ptr)
: base(ptr)
{
}
public ItemModuleAddObserver()
: base(ClassInjector.DerivedConstructorPointer<ItemModuleAddObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionAddEvent<ItemModule> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionRemoveEvent<ItemModule>>) })]
public class ItemModuleRemoveObserver : Object
{
public Action<CollectionRemoveEvent<ItemModule>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public ItemModuleRemoveObserver(IntPtr ptr)
: base(ptr)
{
}
public ItemModuleRemoveObserver()
: base(ClassInjector.DerivedConstructorPointer<ItemModuleRemoveObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionRemoveEvent<ItemModule> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionAddEvent<PlayerTrait>>) })]
public class PlayerTraitAddObserver : Object
{
public Action<CollectionAddEvent<PlayerTrait>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public PlayerTraitAddObserver(IntPtr ptr)
: base(ptr)
{
}
public PlayerTraitAddObserver()
: base(ClassInjector.DerivedConstructorPointer<PlayerTraitAddObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionAddEvent<PlayerTrait> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IObserver<CollectionRemoveEvent<PlayerTrait>>) })]
public class PlayerTraitRemoveObserver : Object
{
public Action<CollectionRemoveEvent<PlayerTrait>>? OnNextAction;
public Action<Exception>? OnErrorAction;
public Action? OnCompletedAction;
public PlayerTraitRemoveObserver(IntPtr ptr)
: base(ptr)
{
}
public PlayerTraitRemoveObserver()
: base(ClassInjector.DerivedConstructorPointer<PlayerTraitRemoveObserver>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public void OnNext(CollectionRemoveEvent<PlayerTrait> value)
{
OnNextAction?.Invoke(value);
}
public void OnError(Exception error)
{
OnErrorAction?.Invoke(error);
}
public void OnCompleted()
{
OnCompletedAction?.Invoke();
}
}
}
namespace CustomGameplayModifiers.Framework.EventType
{
public readonly struct AIShipDamagedEvent
{
public readonly AI_Capability_Ship_Health ShipHealth;
public readonly ReceivedDamage ReceivedDamage;
public AIShipDamagedEvent(AI_Capability_Ship_Health shipHealth, ReceivedDamage dmg)
{
ShipHealth = shipHealth;
ReceivedDamage = dmg;
}
}
public readonly struct ItemHeldChangedEvent
{
public readonly PlayerController Player;
public readonly PersistentPickupable? PreviousItem;
public readonly PersistentPickupable? NewItem;
public ItemHeldChangedEvent(PlayerController player, PersistentPickupable? previous, PersistentPickupable? current)
{
Player = player;
PreviousItem = previous;
NewItem = current;
}
}
public readonly struct OnFootKilledEvent
{
public readonly AI_Controller_OnFoot AiController;
public readonly ReceivedDamage ReceivedDamage;
public OnFootKilledEvent(AI_Controller_OnFoot ai, ReceivedDamage dmg)
{
AiController = ai;
ReceivedDamage = dmg;
}
}
public struct ShipCannonFiredEvent
{
public readonly SpaceShip_Cannon_Base Cannon;
public readonly VisualEffectAsset MuzzleFlashFx;
public readonly bool IsFiredByBuddyBot;
public ShipCannonFiredEvent(SpaceShip_Cannon_Base cannon, VisualEffectAsset muzzleFlashFx, bool isFiredByBuddyBot)
{
Cannon = cannon;
MuzzleFlashFx = muzzleFlashFx;
IsFiredByBuddyBot = isFiredByBuddyBot;
}
}
public readonly struct WeaponFiredEvent
{
public readonly PickupableItemFirstPerson_GenericWeapon Weapon;
public WeaponFiredEvent(PickupableItemFirstPerson_GenericWeapon weapon)
{
Weapon = weapon;
}
}
public readonly struct WeaponReloadedEvent
{
public readonly PickupableItemFirstPerson_GenericWeapon Weapon;
public WeaponReloadedEvent(PickupableItemFirstPerson_GenericWeapon weapon)
{
Weapon = weapon;
}
}
}
namespace CustomGameplayModifiers.CustomAddressables
{
internal static class CustomAddressablesRegisterer
{
private static bool _registered;
public static void TryRegister()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
if (!_registered && Addressables.ResourceManager != null)
{
CustomAssetLocator customAssetLocator = new CustomAssetLocator();
Addressables.AddResourceLocator(new IResourceLocator(((Il2CppObjectBase)customAssetLocator).Pointer), (string)null, (IResourceLocation)null);
CustomAssetProvider customAssetProvider = new CustomAssetProvider();
Addressables.ResourceManager.ResourceProviders.Insert(0, new IResourceProvider(((Il2CppObjectBase)customAssetProvider).Pointer));
_registered = true;
Melon<Core>.Logger.Msg("Addressables registration complete.");
}
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IResourceLocator) })]
public class CustomAssetLocator : Object
{
private static readonly Dictionary<string, ResourceLocationBase> _locations = new Dictionary<string, ResourceLocationBase>();
public string LocatorId => "CustomGameplayModifiers.CustomAssetLocator";
public List<Object> Keys => new List<Object>();
public CustomAssetLocator(IntPtr ptr)
: base(ptr)
{
}
public CustomAssetLocator()
: base(ClassInjector.DerivedConstructorPointer<CustomAssetLocator>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public bool Locate(Object? key, Type resourceType, out List<IResourceLocation>? locations)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
string text = ((key != null) ? key.ToString() : null);
if (text != null && _locations.TryGetValue(text, out ResourceLocationBase value))
{
locations = new List<IResourceLocation>();
locations.Add(new IResourceLocation(((Il2CppObjectBase)value).Pointer));
return true;
}
locations = null;
return false;
}
public static void Register(string guid)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
_locations[guid] = new ResourceLocationBase(guid, guid, "CustomGameplayModifiers.CustomAssetProvider", Il2CppType.From(typeof(ScriptableObject)), (Il2CppReferenceArray<IResourceLocation>)null);
}
}
[RegisterTypeInIl2CppWithInterfaces(new Type[] { typeof(IResourceProvider) })]
public class CustomAssetProvider : Object
{
public string ProviderId => "CustomGameplayModifiers.CustomAssetProvider";
public int OperationCacheCount => 0;
public CustomAssetProvider(IntPtr ptr)
: base(ptr)
{
}
public CustomAssetProvider()
: base(ClassInjector.DerivedConstructorPointer<CustomAssetProvider>())
{
ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
}
public bool CanProvide(IResourceLocation location, Type resourceType)
{
return true;
}
public void Provide(ProvideHandle provideHandle)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Expected O, but got Unknown
string primaryKey = provideHandle.Location.PrimaryKey;
ScriptableObject module = CustomAssetRegistry.GetModule(primaryKey);
if ((Object)(object)module != (Object)null)
{
ModLogger.Msg("Provider serving asset for key: " + primaryKey);
provideHandle.Complete<Object>(((Il2CppObjectBase)module).Cast<Object>(), true, (Exception)null);
}
else
{
provideHandle.Complete<Object>((Object)null, false, new Exception("[ModCustomAssetProvider] Key not found: " + primaryKey));
}
}
public bool Release(IResourceLocation location, Object asset)
{
return true;
}
public void Initialize(string id, string data)
{
}
}
internal static class CustomAssetRegistry
{
private static readonly Dictionary<string, IntPtr> _registry = new Dictionary<string, IntPtr>();
public static int Count => _registry.Count;
public static void Register(string guid, Il2CppObjectBase obj)
{
_registry[guid] = obj.Pointer;
}
public static ScriptableObject? GetModule(string guid)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
if (_registry.TryGetValue(guid, out var value) && value != IntPtr.Zero)
{
return new ScriptableObject(value);
}
return null;
}
}
}
namespace CustomGameplayModifiers.Artifacts
{
public class ArtifactInstance : ModifierInstance
{
public Artifact LiveArtifact => (Artifact)base.LiveModifier;
public ArtifactScriptable ArtifactScriptable => (ArtifactScriptable)base.Scriptable;
}
internal static class ArtifactMeshCache
{
public const string FrameCommonKey = "frame-common";
public const string FrameRareKey = "frame-rare";
public const string FrameLegendaryKey = "frame-legendary";
public const string UtilityDiscKey = "disc-utility";
public const string AttackDiscKey = "disc-attack";
public const string DefenseDiscKey = "disc-defense";
public static bool Ready { get; private set; }
public static IEnumerator LoadRoutine()
{
(string Guid, string Key)[] assets = new(string, string)[6]
{
("b6a641b7d560fd644aa1afd7240c03e7", "frame-common"),
("bfe2c7b6abac8ad45a1a6be2bbeb1f26", "frame-rare"),
("24ec8675fabb83d47be7a8209231f16d", "frame-legendary"),
("2dfcb45d376119241870ddd52ec02bf7", "disc-utility"),
("c2a52f9486b7e8e4da678f775711ef10", "disc-attack"),
("b6362c804adb0404fad7190da2b284d5", "disc-defense")
};
(string Guid, string Key)[] array = assets;
for (int i = 0; i < array.Length; i++)
{
var (guid, key) = array[i];
yield return LoadAsset(guid, key);
if ((Object)(object)AssetRegistry<GameObject>.Get("vanilla", key) == (Object)null)
{
yield break;
}
}
Ready = true;
ModLogger.Msg("[ArtifactMeshCache] Loaded vanilla meshes.");
}
private static IEnumerator LoadAsset(string address, string key)
{
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>(Object.op_Implicit(address));
yield return handle;
if ((int)handle.Status == 1)
{
AssetRegistry<GameObject>.RegisterVanilla(key, handle.Result);
Addressables.Release<GameObject>(handle);
}
}
}
public abstract class ArtifactSoldByVendor : CustomArtifact
{
public abstract string VendorItemGuid { get; }
public abstract int MateriaBaseCost { get; }
public abstract int CreditBaseCost { get; }
public abstract int VendorPickChanceWeight { get; }
public abstract bool VendorAllowMultiple { get; }
}
public abstract class CustomArtifact : CustomModifier<ArtifactScriptable, ArtifactInstance>
{
public override void ConfigureScriptable(ArtifactScriptable scriptable)
{
base.ConfigureScriptable(scriptable);
scriptable.m_TweakableValues_Common = new List<TweakableValue>();
scriptable.m_TweakableValues_Legendary = new List<TweakableValue>();
scriptable.m_TweakableValues_Rare = new List<TweakableValue>();
}
}
}