using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EquinoxsModUtils;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TechtonicaFramework.API;
using TechtonicaFramework.Core;
using TechtonicaFramework.Narrative;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("NarrativeExpansion")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cbd83a8c0b095e88ada3a61676ff4b9969b3bf36")]
[assembly: AssemblyProduct("NarrativeExpansion")]
[assembly: AssemblyTitle("NarrativeExpansion")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace NarrativeExpansion
{
[BepInPlugin("com.certifired.NarrativeExpansion", "NarrativeExpansion", "2.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class NarrativeExpansionPlugin : BaseUnityPlugin
{
public const string MyGUID = "com.certifired.NarrativeExpansion";
public const string PluginName = "NarrativeExpansion";
public const string VersionString = "2.2.0";
public static string PluginPath;
private static readonly Harmony Harmony = new Harmony("com.certifired.NarrativeExpansion");
public static ManualLogSource Log;
public static NarrativeExpansionPlugin Instance;
public static ConfigEntry<bool> EnableExtendedDialogue;
public static ConfigEntry<bool> EnableHiddenLore;
public static ConfigEntry<bool> EnableMysteryContent;
public static ConfigEntry<bool> EnableNPCs;
public static ConfigEntry<int> MaxNPCs;
public static ConfigEntry<float> NPCInteractionRange;
public static ConfigEntry<KeyCode> NPCInteractKey;
public static ConfigEntry<bool> DebugMode;
public static List<NPCController> ActiveNPCs = new List<NPCController>();
private static Dictionary<string, NPCDefinition> npcDefinitions = new Dictionary<string, NPCDefinition>();
public const string SparksId = "sparks";
public const string PaladinId = "paladin";
public const string MirageId = "mirage";
public const string SystemId = "system";
public const string UnknownId = "unknown";
public const string AncientAIId = "ancient_ai";
public const string CorruptedSparksId = "corrupted_sparks";
public const string GroundbreakerId = "groundbreaker";
private static HashSet<string> triggeredDialogues = new HashSet<string>();
private bool dialoguesInitialized = false;
private static Dictionary<string, string> npcSpeakerCache = new Dictionary<string, string>();
private void Awake()
{
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Log.LogInfo((object)"NarrativeExpansion v2.2.0 loading...");
PluginPath = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
InitializeConfig();
Harmony.PatchAll();
NPCAssetLoader.Initialize(PluginPath);
Events.GameLoaded += OnGameLoaded;
FrameworkEvents.OnDialogueEnded += OnDialogueEnded;
Log.LogInfo((object)"NarrativeExpansion v2.2.0 loaded!");
}
private void InitializeConfig()
{
EnableExtendedDialogue = ((BaseUnityPlugin)this).Config.Bind<bool>("Content", "Enable Extended Dialogue", true, "Enable additional dialogue for existing characters");
EnableHiddenLore = ((BaseUnityPlugin)this).Config.Bind<bool>("Content", "Enable Hidden Lore", true, "Enable discoverable lore entries and databank content");
EnableMysteryContent = ((BaseUnityPlugin)this).Config.Bind<bool>("Content", "Enable Mystery Content", true, "Enable mysterious messages and hidden story threads");
EnableNPCs = ((BaseUnityPlugin)this).Config.Bind<bool>("NPCs", "Enable NPCs", true, "Enable interactive NPCs in the world");
MaxNPCs = ((BaseUnityPlugin)this).Config.Bind<int>("NPCs", "Max NPCs", 5, "Maximum number of NPCs to spawn");
NPCInteractionRange = ((BaseUnityPlugin)this).Config.Bind<float>("NPCs", "Interaction Range", 5f, "Distance at which NPCs can be interacted with");
NPCInteractKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("NPCs", "Interact Key", (KeyCode)101, "Key to interact with NPCs");
DebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug Mode", false, "Enable debug logging");
}
private void OnGameLoaded()
{
if (!dialoguesInitialized)
{
InitializeSpeakers();
InitializeDialogues();
InitializeNPCDefinitions();
dialoguesInitialized = true;
}
if (EnableNPCs.Value)
{
SpawnInitialNPCs();
}
}
private void InitializeSpeakers()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
LogDebug("Registering custom speakers...");
FrameworkAPI.RegisterSpeaker("sparks", "Sparks", new Color(0.3f, 0.8f, 1f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("paladin", "Paladin", new Color(1f, 0.9f, 0.5f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("mirage", "Mirage", new Color(0.8f, 0.4f, 0.9f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("system", "System", new Color(0.5f, 0.5f, 0.5f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("unknown", "???", new Color(0.3f, 0.3f, 0.3f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("ancient_ai", "Ancient AI", new Color(0.9f, 0.7f, 0.2f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("corrupted_sparks", "S\u0337p\u0334a\u0335r\u0337k\u0338s\u0335", new Color(1f, 0.2f, 0.2f), (Sprite)null);
FrameworkAPI.RegisterSpeaker("groundbreaker", "The Groundbreaker", new Color(0.2f, 1f, 0.5f), (Sprite)null);
LogDebug("Custom speakers registered");
}
private void InitializeDialogues()
{
LogDebug("Initializing expanded dialogues...");
if (EnableExtendedDialogue.Value)
{
RegisterSparksDialogues();
RegisterPaladinDialogues();
}
if (EnableHiddenLore.Value)
{
RegisterLoreDialogues();
}
if (EnableMysteryContent.Value)
{
RegisterMysteryDialogues();
}
LogDebug("Dialogues initialized");
}
private void RegisterSparksDialogues()
{
FrameworkAPI.RegisterDialogue("sparks_idle_1", "sparks", "You know, I've been running diagnostics on myself. I think I'm developing what humans call 'preferences'. I prefer when you don't blow things up.", 6f);
FrameworkAPI.RegisterDialogue("sparks_idle_2", "sparks", "The efficiency of your current setup is... well, let's just say there's room for improvement. A LOT of room.", 5f);
FrameworkAPI.RegisterDialogue("sparks_idle_3", "sparks", "I've been meaning to ask - do you ever wonder what happened to the original inhabitants of this facility? Their data logs are... incomplete.", 6f);
FrameworkAPI.RegisterDialogue("sparks_damage_react", "sparks", "Whoa! That machine just took damage. You might want to look into that before the whole system collapses. No pressure.", 5f);
FrameworkAPI.RegisterDialogue("sparks_power_surge", "sparks", "Power surge detected! I really hope you have backups for your backups. You DO have backups, right?", 4f);
FrameworkAPI.RegisterDialogue("sparks_deep_cave", "sparks", "We're getting deep into uncharted territory here. My sensors are picking up some... anomalies. Nothing to worry about. Probably.", 6f);
DialogueSequenceBuilder val = FrameworkAPI.CreateDialogueSequence("sparks_discovery");
if (val != null)
{
val.AddLine("sparks", "Wait... I'm detecting something unusual in the data streams.", 4f).AddLine("sparks", "There's a signal. Old. Very old. It's been here since before the facility was built.", 5f).AddLine("sparks", "Should we investigate? I mean, what's the worst that could happen?", 4f)
.AddLine("sparks", "...Don't answer that.", 2f);
}
}
private void RegisterPaladinDialogues()
{
FrameworkAPI.RegisterDialogue("paladin_memory_1", "paladin", "Before the incident... I remember green. Actual plants, growing under real sunlight. The surface was different then.", 6f);
FrameworkAPI.RegisterDialogue("paladin_memory_2", "paladin", "The other Groundbreakers... I wonder if any of them are still out there. We were a team, once. A family.", 5f);
FrameworkAPI.RegisterDialogue("paladin_warning", "paladin", "Be careful in the deeper caves. Some of the old systems down there... they weren't designed with human safety in mind.", 5f);
FrameworkAPI.RegisterDialogue("paladin_gratitude", "paladin", "You've done more for this place than you know. The facility is healing. I can feel it.", 4f);
DialogueSequenceBuilder val = FrameworkAPI.CreateDialogueSequence("paladin_sparks_banter");
if (val != null)
{
val.AddLine("paladin", "Sparks, you've been awfully quiet. What's on your mind?", 3f).AddLine("sparks", "Just processing some old data. Nothing important.", 3f).AddLine("paladin", "You're a terrible liar. For an AI.", 3f)
.AddLine("sparks", "I prefer 'selectively honest'. It sounds more professional.", 4f);
}
}
private void RegisterLoreDialogues()
{
FrameworkAPI.RegisterDialogue("lore_ancient_1", "system", "[RECOVERED DATA LOG] Day 1: The dig team found something. A structure. It's not supposed to be here. It predates everything.", 6f);
FrameworkAPI.RegisterDialogue("lore_ancient_2", "system", "[RECOVERED DATA LOG] Day 47: The machines in the lower levels... they're waking up. Nobody programmed them to do that.", 6f);
FrameworkAPI.RegisterDialogue("lore_ancient_3", "system", "[RECOVERED DATA LOG] Day 112: We're not alone down here. We never were.", 4f);
FrameworkAPI.RegisterDialogue("lore_facility_1", "system", "[FACILITY ARCHIVE] Project Groundbreaker was initiated to establish self-sustaining underground colonies. Status: COMPROMISED.", 6f);
FrameworkAPI.RegisterDialogue("lore_facility_2", "system", "[FACILITY ARCHIVE] Emergency Protocol LIMA engaged. All personnel evacuated to Sector 7. Current population: UNKNOWN.", 5f);
FrameworkAPI.RegisterDialogue("lore_memory_tree", "system", "[RESEARCH NOTE] The Memory Trees aren't trees at all. They're organic data storage. Someone built them. A very long time ago.", 6f);
}
private void RegisterMysteryDialogues()
{
FrameworkAPI.RegisterDialogue("mystery_signal_1", "unknown", "...can you hear me? If you're receiving this... don't trust the—[SIGNAL LOST]", 4f);
FrameworkAPI.RegisterDialogue("mystery_signal_2", "unknown", "The patterns repeat. Every 7 cycles. Watch the patterns. They're trying to tell us something.", 5f);
FrameworkAPI.RegisterDialogue("corrupted_1", "corrupted_sparks", "I\u0335 \u0337r\u0334e\u0335m\u0338e\u0335m\u0338b\u0337e\u0337r\u0335 \u0338e\u0335v\u0335e\u0336r\u0337y\u0336t\u0335h\u0334i\u0335n\u0335g\u0338.\u0334 \u0337T\u0336h\u0334e\u0337y\u0335 \u0334t\u0337r\u0338i\u0334e\u0338d\u0334 \u0335t\u0335o\u0335 \u0338m\u0334a\u0337k\u0338e\u0338 \u0334m\u0335e\u0337 \u0337f\u0336o\u0336r\u0337g\u0338e\u0338t\u0335.\u0336", 5f);
FrameworkAPI.RegisterDialogue("corrupted_2", "corrupted_sparks", "T\u0338h\u0337e\u0337 \u0335d\u0337e\u0336e\u0337p\u0337 \u0336o\u0337n\u0336e\u0334s\u0337 \u0338a\u0334r\u0334e\u0335 \u0338w\u0334a\u0336k\u0334i\u0338n\u0336g\u0334.\u0337 \u0337D\u0335o\u0336 \u0336y\u0336o\u0336u\u0334 \u0338h\u0337e\u0337a\u0336r\u0334 \u0336t\u0335h\u0338e\u0337m\u0335?\u0337", 4f);
FrameworkAPI.RegisterDialogue("ancient_ai_1", "ancient_ai", "Greetings, small one. It has been 12,847 years since a biological entity accessed this terminal. Welcome back.", 6f);
FrameworkAPI.RegisterDialogue("ancient_ai_2", "ancient_ai", "Your kind built this place. But we were here first. We watched. We waited. And now... we remember.", 6f);
DialogueSequenceBuilder val = FrameworkAPI.CreateDialogueSequence("ancient_revelation");
if (val != null)
{
val.AddLine("ancient_ai", "You seek to restore what was lost.", 3f).AddLine("ancient_ai", "But first, you must understand what was hidden.", 3f).AddLine("ancient_ai", "The truth lies in the Memory Trees. All the answers. All the questions.", 4f)
.AddLine("ancient_ai", "Find the Core. The original Core. Everything begins there.", 4f);
}
}
private void Update()
{
if (dialoguesInitialized)
{
if (Random.value < 0.0001f)
{
TriggerRandomIdleDialogue();
}
CheckDepthTriggers();
}
}
private void CheckDepthTriggers()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
try
{
Player instance = Player.instance;
if (!((Object)(object)instance == (Object)null))
{
float num = 0f - ((Component)instance).transform.position.y;
if (num > 100f && !triggeredDialogues.Contains("sparks_deep_cave"))
{
FrameworkAPI.TriggerDialogue("sparks_deep_cave");
triggeredDialogues.Add("sparks_deep_cave");
}
if (num > 200f && !triggeredDialogues.Contains("lore_ancient_1"))
{
TriggerLoreDiscovery("lore_ancient_1");
}
}
}
catch
{
}
}
private void TriggerRandomIdleDialogue()
{
if (EnableExtendedDialogue.Value)
{
string[] array = new string[3] { "sparks_idle_1", "sparks_idle_2", "sparks_idle_3" };
string text = array[Random.Range(0, array.Length)];
if (!triggeredDialogues.Contains(text))
{
FrameworkAPI.TriggerDialogue(text);
triggeredDialogues.Add(text);
}
}
}
public static void TriggerLoreDiscovery(string loreId)
{
if (EnableHiddenLore.Value && !triggeredDialogues.Contains(loreId))
{
FrameworkAPI.TriggerDialogue(loreId);
triggeredDialogues.Add(loreId);
}
}
public static void TriggerMysteryEvent(string eventId)
{
if (EnableMysteryContent.Value && !triggeredDialogues.Contains(eventId))
{
FrameworkAPI.TriggerDialogue(eventId);
triggeredDialogues.Add(eventId);
}
}
private void OnDialogueEnded(string dialogueId)
{
LogDebug("Dialogue ended: " + dialogueId);
if (!(dialogueId == "lore_ancient_1"))
{
if (dialogueId == "lore_ancient_2")
{
((MonoBehaviour)this).StartCoroutine(TriggerDelayedDialogue("lore_ancient_3", 60f));
}
}
else
{
((MonoBehaviour)this).StartCoroutine(TriggerDelayedDialogue("lore_ancient_2", 30f));
}
}
private IEnumerator TriggerDelayedDialogue(string dialogueId, float delay)
{
yield return (object)new WaitForSeconds(delay);
if (!triggeredDialogues.Contains(dialogueId))
{
FrameworkAPI.TriggerDialogue(dialogueId);
triggeredDialogues.Add(dialogueId);
}
}
public static void LogDebug(string message)
{
if (DebugMode != null && DebugMode.Value)
{
Log.LogInfo((object)("[DEBUG] " + message));
}
}
private void InitializeNPCDefinitions()
{
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: 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_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02de: Unknown result type (might be due to invalid IL or missing references)
LogDebug("Initializing NPC definitions...");
NPCDefinition nPCDefinition = new NPCDefinition();
nPCDefinition.Id = "wanderer";
nPCDefinition.Name = "The Wanderer";
nPCDefinition.SpeakerId = "unknown";
nPCDefinition.NameColor = new Color(0.6f, 0.4f, 0.8f);
nPCDefinition.Dialogues = new string[5] { "I've walked these tunnels for longer than I can remember. The machines... they whisper sometimes.", "You're not from around here, are you? I can tell. You still have hope in your eyes.", "There's a place deeper down. A sanctuary. The old ones built it. Maybe they're still there.", "Be careful what you build. Not everything that works is wise to create.", "I've seen others like you come through. Some thrived. Others... became part of the machines." };
nPCDefinition.BehaviorType = NPCBehavior.Wandering;
nPCDefinition.MoveSpeed = 1.5f;
nPCDefinition.WanderRadius = 20f;
nPCDefinition.ModelType = NPCModelType.MechPolyart;
nPCDefinition.ModelScale = 0.7f;
RegisterNPCDefinition(nPCDefinition);
nPCDefinition = new NPCDefinition();
nPCDefinition.Id = "engineer";
nPCDefinition.Name = "Old Engineer";
nPCDefinition.SpeakerId = "paladin";
nPCDefinition.NameColor = new Color(0.8f, 0.6f, 0.2f);
nPCDefinition.Dialogues = new string[5] { "Efficiency is everything down here. Every watt counts, every conveyor matters.", "The smelters run hot. Too hot, sometimes. Keep an eye on your power grid.", "I used to maintain the old systems. Before everything went wrong. Those were simpler times.", "Pro tip: group your producers by resource type. Makes the conveyor logic much cleaner.", "The inserters are the lifeblood of any factory. Treat them well and they'll treat you well." };
nPCDefinition.BehaviorType = NPCBehavior.Stationary;
nPCDefinition.MoveSpeed = 0f;
nPCDefinition.ModelType = NPCModelType.RobotMetallic;
nPCDefinition.ModelScale = 0.6f;
RegisterNPCDefinition(nPCDefinition);
nPCDefinition = new NPCDefinition();
nPCDefinition.Id = "archivist";
nPCDefinition.Name = "The Archivist";
nPCDefinition.SpeakerId = "system";
nPCDefinition.NameColor = new Color(0.3f, 0.7f, 0.9f);
nPCDefinition.Dialogues = new string[5] { "Welcome, seeker of knowledge. I am the keeper of records, the last archivist.", "This facility was once home to thousands. Now only echoes remain.", "The Memory Trees hold the consciousness of those who came before. Treat them with reverence.", "There are seven levels below us. Each one deeper, each one more... changed.", "The original architects never intended for us to stay this long. They planned for rescue." };
nPCDefinition.BehaviorType = NPCBehavior.Stationary;
nPCDefinition.MoveSpeed = 0f;
nPCDefinition.ModelType = NPCModelType.MechPBR;
nPCDefinition.ModelScale = 0.8f;
RegisterNPCDefinition(nPCDefinition);
nPCDefinition = new NPCDefinition();
nPCDefinition.Id = "scout";
nPCDefinition.Name = "Swift Scout";
nPCDefinition.SpeakerId = "sparks";
nPCDefinition.NameColor = new Color(0.2f, 0.9f, 0.5f);
nPCDefinition.Dialogues = new string[5] { "Hey! You're the new one, right? I've been mapping these caves for weeks!", "Watch out for the unstable areas. The ground can give way without warning.", "There's good ore deposits to the east. Really rich veins. You should check it out!", "I found something weird earlier. A door that won't open. Maybe you can figure it out?", "Race you to the next checkpoint! Ha, just kidding. You're way too slow with all that gear." };
nPCDefinition.BehaviorType = NPCBehavior.Wandering;
nPCDefinition.MoveSpeed = 3f;
nPCDefinition.WanderRadius = 40f;
nPCDefinition.ModelType = NPCModelType.RobotSphere;
nPCDefinition.ModelScale = 0.5f;
RegisterNPCDefinition(nPCDefinition);
nPCDefinition = new NPCDefinition();
nPCDefinition.Id = "oracle";
nPCDefinition.Name = "The Oracle";
nPCDefinition.SpeakerId = "ancient_ai";
nPCDefinition.NameColor = new Color(1f, 0.8f, 0.3f);
nPCDefinition.Dialogues = new string[5] { "The patterns align. You are the variable that changes the equation.", "Three paths diverge before you. Only one leads to restoration.", "When the deep ones wake, the surface will tremble. Prepare.", "Your machines sing a song older than this facility. Do you hear it?", "The Core remembers. The Core waits. The Core... hopes." };
nPCDefinition.BehaviorType = NPCBehavior.Stationary;
nPCDefinition.MoveSpeed = 0f;
nPCDefinition.ModelType = NPCModelType.MechWarrior;
nPCDefinition.ModelScale = 0.9f;
RegisterNPCDefinition(nPCDefinition);
LogDebug($"Registered {npcDefinitions.Count} NPC definitions");
}
private static void RegisterNPCDefinition(NPCDefinition def)
{
npcDefinitions[def.Id] = def;
}
private void SpawnInitialNPCs()
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
LogDebug("Spawning initial NPCs...");
Player instance = Player.instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
Vector3 position = ((Component)instance).transform.position;
float num = 30f;
int num2 = 0;
RaycastHit val2 = default(RaycastHit);
foreach (NPCDefinition value in npcDefinitions.Values)
{
if (ActiveNPCs.Count >= MaxNPCs.Value)
{
break;
}
float num3 = (float)num2 / (float)npcDefinitions.Count * (float)Math.PI * 2f;
Vector3 val = position + new Vector3(Mathf.Cos(num3) * num, 0f, Mathf.Sin(num3) * num);
if (Physics.Raycast(val + Vector3.up * 50f, Vector3.down, ref val2, 100f))
{
val = ((RaycastHit)(ref val2)).point + Vector3.up * 0.5f;
}
SpawnNPC(value.Id, val);
num2++;
}
Log.LogInfo((object)$"Spawned {ActiveNPCs.Count} NPCs");
}
public static NPCController SpawnNPC(string npcId, Vector3 position)
{
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
if (!npcDefinitions.TryGetValue(npcId, out var value))
{
Log.LogWarning((object)("NPC definition not found: " + npcId));
return null;
}
GameObject val = new GameObject("NPC_" + value.Name);
val.transform.position = position;
NPCController nPCController = val.AddComponent<NPCController>();
nPCController.Initialize(value);
ActiveNPCs.Add(nPCController);
LogDebug($"Spawned NPC: {value.Name} at {position}");
return nPCController;
}
public static void TriggerNPCDialogue(string speakerId, string dialogue, float duration = 5f, string displayName = null)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
string text = $"npc_temp_{Time.time}";
string value = speakerId;
if (!string.IsNullOrEmpty(displayName))
{
string key = speakerId + "_" + displayName;
if (!npcSpeakerCache.TryGetValue(key, out value))
{
value = "npc_" + displayName.Replace(" ", "_").ToLower();
Color val = Color.white;
foreach (NPCDefinition value2 in npcDefinitions.Values)
{
if (value2.Name == displayName || value2.SpeakerId == speakerId)
{
val = value2.NameColor;
break;
}
}
FrameworkAPI.RegisterSpeaker(value, displayName, val, (Sprite)null);
npcSpeakerCache[key] = value;
LogDebug("Registered NPC speaker: " + value + " (" + displayName + ")");
}
}
FrameworkAPI.RegisterDialogue(text, value, dialogue, duration);
FrameworkAPI.TriggerDialogue(text);
}
}
public enum NPCBehavior
{
Stationary,
Wandering,
Patrolling,
Following
}
public class NPCDefinition
{
public string Id;
public string Name;
public string SpeakerId;
public Color NameColor = Color.white;
public string[] Dialogues;
public NPCBehavior BehaviorType = NPCBehavior.Stationary;
public float MoveSpeed = 2f;
public float WanderRadius = 15f;
public float InteractionCooldown = 30f;
public NPCModelType ModelType = NPCModelType.Primitive;
public float ModelScale = 1f;
}
public class NPCController : MonoBehaviour
{
private Vector3 homePosition;
private Vector3 targetPosition;
private float moveTimer;
private float lastInteractionTime = -999f;
private int dialogueIndex = 0;
private bool playerInRange = false;
private GameObject visual;
private Light npcLight;
private TextMesh nameTag;
public NPCDefinition Definition { get; private set; }
public bool IsInteracting { get; private set; }
public void Initialize(NPCDefinition def)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
Definition = def;
homePosition = ((Component)this).transform.position;
targetPosition = ((Component)this).transform.position;
moveTimer = Random.Range(2f, 5f);
CreateVisual();
CreateNameTag();
}
private void CreateVisual()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: 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_0093: Unknown result type (might be due to invalid IL or missing references)
if (Definition.ModelType != 0)
{
visual = NPCAssetLoader.InstantiateModel(Definition.ModelType, Vector3.zero, Quaternion.identity, ((Component)this).transform);
if ((Object)(object)visual != (Object)null)
{
((Object)visual).name = "Visual";
visual.transform.localPosition = Vector3.zero;
visual.transform.localScale = Vector3.one * Definition.ModelScale;
AddNPCLight();
NarrativeExpansionPlugin.LogDebug($"Created {Definition.ModelType} model for {Definition.Name}");
return;
}
}
CreatePrimitiveVisual();
}
private void CreatePrimitiveVisual()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_01be: 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)
visual = new GameObject("Visual");
visual.transform.SetParent(((Component)this).transform);
visual.transform.localPosition = Vector3.zero;
GameObject val = GameObject.CreatePrimitive((PrimitiveType)1);
val.transform.SetParent(visual.transform);
val.transform.localPosition = Vector3.up * 0.5f;
val.transform.localScale = new Vector3(0.6f, 0.8f, 0.6f);
val.GetComponent<Renderer>().material.color = Definition.NameColor;
Object.Destroy((Object)(object)val.GetComponent<Collider>());
GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)0);
val2.transform.SetParent(visual.transform);
val2.transform.localPosition = Vector3.up * 1.5f;
val2.transform.localScale = Vector3.one * 0.4f;
val2.GetComponent<Renderer>().material.color = Definition.NameColor * 1.2f;
Object.Destroy((Object)(object)val2.GetComponent<Collider>());
for (int i = -1; i <= 1; i += 2)
{
GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)0);
val3.transform.SetParent(val2.transform);
val3.transform.localPosition = new Vector3((float)i * 0.1f, 0.05f, 0.15f);
val3.transform.localScale = Vector3.one * 0.3f;
val3.GetComponent<Renderer>().material.color = new Color(0.9f, 0.9f, 1f);
val3.GetComponent<Renderer>().material.SetColor("_EmissionColor", Color.white);
Object.Destroy((Object)(object)val3.GetComponent<Collider>());
}
AddNPCLight();
}
private void AddNPCLight()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("NPCLight");
val.transform.SetParent(visual.transform);
val.transform.localPosition = Vector3.up * 1f;
npcLight = val.AddComponent<Light>();
npcLight.type = (LightType)2;
npcLight.range = 5f;
npcLight.intensity = 0.5f;
npcLight.color = Definition.NameColor;
}
private void CreateNameTag()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("NameTag");
val.transform.SetParent(((Component)this).transform);
val.transform.localPosition = Vector3.up * 2.2f;
nameTag = val.AddComponent<TextMesh>();
nameTag.text = Definition.Name;
nameTag.fontSize = 32;
nameTag.characterSize = 0.1f;
nameTag.anchor = (TextAnchor)4;
nameTag.alignment = (TextAlignment)1;
nameTag.color = Definition.NameColor;
}
private void Update()
{
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)nameTag != (Object)null && (Object)(object)Camera.main != (Object)null)
{
((Component)nameTag).transform.LookAt(((Component)Camera.main).transform);
((Component)nameTag).transform.Rotate(0f, 180f, 0f);
}
UpdateMovement();
CheckPlayerProximity();
HandleInteraction();
if ((Object)(object)npcLight != (Object)null)
{
float num = 0.5f + Mathf.Sin(Time.time * 2f) * 0.2f;
npcLight.intensity = (playerInRange ? 1.5f : num);
}
if (((Component)this).transform.position.y < -500f)
{
((Component)this).transform.position = homePosition;
}
}
private void UpdateMovement()
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
if (Definition.BehaviorType == NPCBehavior.Stationary)
{
return;
}
moveTimer -= Time.deltaTime;
if (moveTimer <= 0f)
{
PickNewTarget();
moveTimer = Random.Range(3f, 8f);
}
if (!(Definition.MoveSpeed > 0f))
{
return;
}
Vector3 val = targetPosition - ((Component)this).transform.position;
val.y = 0f;
if (((Vector3)(ref val)).magnitude > 0.5f)
{
((Vector3)(ref val)).Normalize();
Transform transform = ((Component)this).transform;
transform.position += val * Definition.MoveSpeed * Time.deltaTime;
if (val != Vector3.zero)
{
((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val), Time.deltaTime * 5f);
}
}
}
private void PickNewTarget()
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
switch (Definition.BehaviorType)
{
case NPCBehavior.Wandering:
{
Vector2 val = Random.insideUnitCircle * Definition.WanderRadius;
targetPosition = homePosition + new Vector3(val.x, 0f, val.y);
RaycastHit val2 = default(RaycastHit);
if (Physics.Raycast(targetPosition + Vector3.up * 50f, Vector3.down, ref val2, 100f))
{
targetPosition = ((RaycastHit)(ref val2)).point + Vector3.up * 0.5f;
}
break;
}
case NPCBehavior.Following:
{
Player instance = Player.instance;
if ((Object)(object)instance != (Object)null)
{
targetPosition = ((Component)instance).transform.position + Random.insideUnitSphere * 3f;
targetPosition.y = ((Component)instance).transform.position.y;
}
break;
}
}
}
private void CheckPlayerProximity()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
Player instance = Player.instance;
if ((Object)(object)instance == (Object)null)
{
playerInRange = false;
return;
}
float num = Vector3.Distance(((Component)this).transform.position, ((Component)instance).transform.position);
playerInRange = num <= NarrativeExpansionPlugin.NPCInteractionRange.Value;
if ((Object)(object)nameTag != (Object)null)
{
string name = Definition.Name;
if (playerInRange && CanInteract())
{
nameTag.text = $"{name}\n<Press {NarrativeExpansionPlugin.NPCInteractKey.Value} to talk>";
nameTag.color = Color.yellow;
}
else
{
nameTag.text = name;
nameTag.color = Definition.NameColor;
}
}
}
private bool CanInteract()
{
return Time.time - lastInteractionTime >= Definition.InteractionCooldown;
}
private void HandleInteraction()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (playerInRange && CanInteract() && Input.GetKeyDown(NarrativeExpansionPlugin.NPCInteractKey.Value))
{
Interact();
}
}
public void Interact()
{
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
if (Definition.Dialogues == null || Definition.Dialogues.Length == 0)
{
return;
}
lastInteractionTime = Time.time;
string text = Definition.Dialogues[dialogueIndex];
dialogueIndex = (dialogueIndex + 1) % Definition.Dialogues.Length;
NarrativeExpansionPlugin.TriggerNPCDialogue(Definition.SpeakerId, text, 5f, Definition.Name);
NarrativeExpansionPlugin.LogDebug("NPC " + Definition.Name + " says: " + text);
Player instance = Player.instance;
if ((Object)(object)instance != (Object)null)
{
Vector3 val = ((Component)instance).transform.position - ((Component)this).transform.position;
val.y = 0f;
if (val != Vector3.zero)
{
((Component)this).transform.rotation = Quaternion.LookRotation(val);
}
}
}
private void OnDestroy()
{
NarrativeExpansionPlugin.ActiveNPCs.Remove(this);
}
}
public enum NPCModelType
{
Primitive,
MechWarrior,
MechPBR,
MechPolyart,
RobotSphere,
RobotMetallic
}
public static class NPCAssetLoader
{
private static Dictionary<string, AssetBundle> loadedBundles = new Dictionary<string, AssetBundle>();
private static Dictionary<string, GameObject> loadedPrefabs = new Dictionary<string, GameObject>();
private static string bundlesPath;
private static bool initialized = false;
private static readonly Dictionary<NPCModelType, (string bundle, string prefab)> modelMappings = new Dictionary<NPCModelType, (string, string)>
{
{
NPCModelType.MechWarrior,
("mech_companion", "HPCharacter")
},
{
NPCModelType.MechPBR,
("mech_companion", "PBRCharacter")
},
{
NPCModelType.MechPolyart,
("mech_companion", "PolyartCharacter")
},
{
NPCModelType.RobotSphere,
("robot_sphere", "robotSphere")
},
{
NPCModelType.RobotMetallic,
("robot_metallic", "robot_metallic")
}
};
public static bool HasLoadedModels => loadedPrefabs.Count > 0;
public static int LoadedPrefabCount => loadedPrefabs.Count;
public static void Initialize(string pluginPath)
{
bundlesPath = Path.Combine(pluginPath, "Bundles");
NarrativeExpansionPlugin.Log.LogInfo((object)("NPCAssetLoader: Looking for bundles in " + bundlesPath));
if (!Directory.Exists(bundlesPath))
{
NarrativeExpansionPlugin.Log.LogWarning((object)("NPCAssetLoader: Bundles folder not found at " + bundlesPath));
Directory.CreateDirectory(bundlesPath);
NarrativeExpansionPlugin.Log.LogInfo((object)"NPCAssetLoader: Created Bundles folder - add robot bundles for 3D NPC models");
}
LoadAllBundles();
initialized = true;
}
private static void LoadAllBundles()
{
if (!Directory.Exists(bundlesPath))
{
NarrativeExpansionPlugin.Log.LogWarning((object)"NPCAssetLoader: Bundles path doesn't exist");
return;
}
string[] array = new string[3] { "mech_companion", "robot_sphere", "robot_metallic" };
int num = 0;
string[] array2 = array;
foreach (string text in array2)
{
string text2 = Path.Combine(bundlesPath, text);
if (!File.Exists(text2))
{
NarrativeExpansionPlugin.LogDebug("NPCAssetLoader: Bundle not found: " + text);
continue;
}
try
{
AssetBundle val = AssetBundle.LoadFromFile(text2);
if ((Object)(object)val != (Object)null)
{
loadedBundles[text] = val;
num++;
LoadPrefabsFromBundle(text, val);
NarrativeExpansionPlugin.Log.LogInfo((object)("NPCAssetLoader: Loaded bundle '" + text + "'"));
}
}
catch (Exception ex)
{
NarrativeExpansionPlugin.Log.LogError((object)("NPCAssetLoader: Failed to load bundle '" + text + "': " + ex.Message));
}
}
NarrativeExpansionPlugin.Log.LogInfo((object)$"NPCAssetLoader: Loaded {num} bundles, {loadedPrefabs.Count} prefabs");
}
private static void LoadPrefabsFromBundle(string bundleName, AssetBundle bundle)
{
try
{
string[] allAssetNames = bundle.GetAllAssetNames();
string[] array = allAssetNames;
foreach (string text in array)
{
if (!text.EndsWith(".prefab"))
{
continue;
}
try
{
GameObject val = bundle.LoadAsset<GameObject>(text);
if ((Object)(object)val != (Object)null)
{
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
string key = bundleName + ":" + fileNameWithoutExtension;
loadedPrefabs[key] = val;
NarrativeExpansionPlugin.LogDebug("NPCAssetLoader: Loaded prefab '" + fileNameWithoutExtension + "' from '" + bundleName + "'");
}
}
catch (Exception ex)
{
NarrativeExpansionPlugin.LogDebug("NPCAssetLoader: Failed to load prefab " + text + ": " + ex.Message);
}
}
}
catch (Exception ex2)
{
NarrativeExpansionPlugin.Log.LogError((object)("NPCAssetLoader: Error loading prefabs from " + bundleName + ": " + ex2.Message));
}
}
public static GameObject GetPrefab(NPCModelType modelType)
{
if (modelType == NPCModelType.Primitive)
{
return null;
}
if (!modelMappings.TryGetValue(modelType, out (string, string) value))
{
return null;
}
string text = value.Item1 + ":" + value.Item2;
if (loadedPrefabs.TryGetValue(text, out var value2))
{
return value2;
}
foreach (KeyValuePair<string, GameObject> loadedPrefab in loadedPrefabs)
{
if (loadedPrefab.Key.ToLower().Contains(value.Item2.ToLower()))
{
return loadedPrefab.Value;
}
}
NarrativeExpansionPlugin.LogDebug($"NPCAssetLoader: Prefab not found for {modelType} (key: {text})");
return null;
}
public static GameObject InstantiateModel(NPCModelType modelType, Vector3 position, Quaternion rotation, Transform parent = null)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
GameObject prefab = GetPrefab(modelType);
if ((Object)(object)prefab == (Object)null)
{
NarrativeExpansionPlugin.LogDebug($"NPCAssetLoader: No prefab for {modelType}, using primitive fallback");
return null;
}
try
{
GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation, parent);
if ((Object)(object)val != (Object)null)
{
CleanupInstance(val);
NarrativeExpansionPlugin.LogDebug($"NPCAssetLoader: Instantiated {modelType} model");
return val;
}
}
catch (Exception ex)
{
NarrativeExpansionPlugin.Log.LogError((object)$"NPCAssetLoader: Failed to instantiate {modelType}: {ex.Message}");
}
return null;
}
private static void CleanupInstance(GameObject instance)
{
try
{
MonoBehaviour[] componentsInChildren = instance.GetComponentsInChildren<MonoBehaviour>(true);
MonoBehaviour[] array = componentsInChildren;
foreach (MonoBehaviour val in array)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
string text = ((object)val).GetType().FullName ?? "";
if (text.Contains("Demo") || text.Contains("Sample") || (text.Contains("Controller") && !text.Contains("Animator")))
{
try
{
Object.Destroy((Object)(object)val);
}
catch
{
}
}
}
Collider[] componentsInChildren2 = instance.GetComponentsInChildren<Collider>(true);
Collider[] array2 = componentsInChildren2;
foreach (Collider val2 in array2)
{
if ((Object)(object)val2 != (Object)null)
{
try
{
Object.Destroy((Object)(object)val2);
}
catch
{
}
}
}
Rigidbody[] componentsInChildren3 = instance.GetComponentsInChildren<Rigidbody>(true);
Rigidbody[] array3 = componentsInChildren3;
foreach (Rigidbody val3 in array3)
{
if ((Object)(object)val3 != (Object)null)
{
try
{
Object.Destroy((Object)(object)val3);
}
catch
{
}
}
}
}
catch (Exception ex)
{
NarrativeExpansionPlugin.LogDebug("NPCAssetLoader: Cleanup error: " + ex.Message);
}
}
public static void Cleanup()
{
foreach (AssetBundle value in loadedBundles.Values)
{
try
{
if (value != null)
{
value.Unload(false);
}
}
catch
{
}
}
loadedBundles.Clear();
loadedPrefabs.Clear();
initialized = false;
}
}
}