using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using NodeCanvas.DialogueTrees;
using NodeCanvas.Framework;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace BankOfAurai;
[BepInPlugin("com.spencer4792.bankofaurai", "BankOfAurai", "1.0.3")]
public class BankOfAuraiPlugin : BaseUnityPlugin
{
public const string GUID = "com.spencer4792.bankofaurai";
public const string NAME = "BankOfAurai";
public const string VERSION = "1.0.3";
internal static ManualLogSource Log;
internal static BankOfAuraiPlugin Instance;
internal static ConfigEntry<float> InterestPerDay;
internal static ConfigEntry<float> DepositFeePercent;
internal static ConfigEntry<KeyboardShortcut> PlacementKey;
internal static ConfigEntry<KeyboardShortcut> AudioScanKey;
internal static ConfigEntry<KeyboardShortcut> CopyLookKey;
internal static ConfigEntry<string> BarkDialogueKey;
internal static ConfigEntry<string> BarkLineText;
internal static ConfigEntry<string> BarkNpcKey;
internal static ConfigEntry<bool> WiretapEnabled;
internal static ConfigEntry<float> InteractionRadius;
internal void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
Instance = this;
try
{
Init();
}
catch (Exception ex)
{
Log.LogError((object)("Startup failed: " + ex));
}
}
private void Init()
{
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
InterestPerDay = ((BaseUnityPlugin)this).Config.Bind<float>("Bank", "InterestPercentPerDay", 0.5f, "Interest earned on the deposited balance per in-game day (24h). 0 disables interest.");
DepositFeePercent = ((BaseUnityPlugin)this).Config.Bind<float>("Bank", "DepositFeePercent", 0f, "Percentage fee charged on deposits. 0 = free banking.");
InteractionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Bank", "InteractionRadius", 1.6f, "Radius (meters) of the bank interaction spot.");
BarkDialogueKey = ((BaseUnityPlugin)this).Config.Bind<string>("Bank", "BarkLineKey", "auto", "Localization key of the banker's voiced bark line. 'auto' = find it by searching dialogue text for BarkLineText (result is logged). Empty = silent banker.");
BarkLineText = ((BaseUnityPlugin)this).Config.Bind<string>("Bank", "BarkLineText", "better have the money", "Phrase used to locate the bark line when BarkLineKey is 'auto'.");
BarkNpcKey = ((BaseUnityPlugin)this).Config.Bind<string>("Bank", "BarkSpeakerNameKey", "Banker", "Name shown on the bark's vicinity subtitle bubble (a localization key, or plain text).");
WiretapEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "AudioWiretap", false, "Log every sound played through the game's audio manager (very chatty).");
AudioScanKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Placement", "AudioScanKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Debug: scan all dialogue trees loaded in the current scene for statements mentioning money and log their audio clip names. Used to identify the vendor greeting bark for the banker.");
CopyLookKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Placement", "CopyBankerLookKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Stand next to any NPC and press this: their appearance becomes the banker's body at this city's bank spot, remembered across visits.");
PlacementKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Placement", "PlaceBankSpotKey", new KeyboardShortcut((KeyCode)287, Array.Empty<KeyCode>()), "Stand where the bank should be in a city and press this to save/move the bank spot for the current scene. It spawns immediately and on every future visit.");
AudioWiretap.Install();
BankLedger.Load();
BankSpots.Load();
BankBody.Load();
SceneManager.sceneLoaded += OnSceneLoaded;
Log.LogMessage((object)"BankOfAurai 1.0.3 ready.");
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
try
{
BankSpots.SpawnForScene(((Scene)(ref scene)).name);
}
catch (Exception ex)
{
Log.LogError((object)("SpawnForScene: " + ex));
}
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
try
{
KeyboardShortcut value = AudioScanKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
AudioWiretap.SnapshotPlaying();
}
KeyboardShortcut value2 = CopyLookKey.Value;
if (((KeyboardShortcut)(ref value2)).IsDown())
{
BankBody.CopyNearestLook();
}
KeyboardShortcut value3 = PlacementKey.Value;
if (((KeyboardShortcut)(ref value3)).IsDown())
{
Character val = ((!((Object)(object)CharacterManager.Instance != (Object)null)) ? null : CharacterManager.Instance.GetFirstLocalCharacter());
if (!((Object)(object)val == (Object)null))
{
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
BankSpots.SetSpot(name, ((Component)val).transform.position);
BankSpots.SpawnForScene(name);
Log.LogMessage((object)("Bank spot saved for scene '" + name + "' at " + ((Component)val).transform.position));
}
}
}
catch (Exception ex)
{
Log.LogError((object)("Update: " + ex));
}
}
}
internal static class BankLedger
{
internal class Account
{
public long Balance;
public float LastInterestTime;
}
private static readonly Dictionary<string, Account> s_accounts = new Dictionary<string, Account>();
private static string DirPath => Path.Combine(Paths.ConfigPath, "BankOfAurai");
private static string FilePath => Path.Combine(DirPath, "ledger.txt");
public static void Load()
{
s_accounts.Clear();
try
{
if (!File.Exists(FilePath))
{
return;
}
string[] array = File.ReadAllLines(FilePath);
foreach (string text in array)
{
string[] array2 = text.Split(new char[1] { '\t' });
if (array2.Length >= 3 && long.TryParse(array2[1], out var result))
{
if (!float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
{
result2 = 0f;
}
s_accounts[array2[0]] = new Account
{
Balance = result,
LastInterestTime = result2
};
}
}
BankOfAuraiPlugin.Log.LogInfo((object)("Ledger loaded: " + s_accounts.Count + " account(s)."));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Ledger load: " + ex));
}
}
public static void Save()
{
try
{
Directory.CreateDirectory(DirPath);
string text = FilePath + ".tmp";
List<string> list = new List<string>();
foreach (KeyValuePair<string, Account> s_account in s_accounts)
{
list.Add(s_account.Key + "\t" + s_account.Value.Balance + "\t" + s_account.Value.LastInterestTime.ToString(CultureInfo.InvariantCulture));
}
File.WriteAllLines(text, list.ToArray());
if (File.Exists(FilePath))
{
File.Delete(FilePath);
}
File.Move(text, FilePath);
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Ledger save: " + ex));
}
}
public static Account GetAccount(string uid)
{
if (!s_accounts.TryGetValue(uid, out var value))
{
Account account = new Account();
account.Balance = 0L;
account.LastInterestTime = NowGameHours();
value = account;
s_accounts[uid] = value;
}
AccrueInterest(value);
return value;
}
private static void AccrueInterest(Account acc)
{
float num = NowGameHours();
float value = BankOfAuraiPlugin.InterestPerDay.Value;
if (value <= 0f || acc.Balance <= 0)
{
acc.LastInterestTime = num;
return;
}
float num2 = num - acc.LastInterestTime;
if (num2 <= 0f)
{
acc.LastInterestTime = num;
return;
}
long num3 = (long)Math.Floor((float)acc.Balance * (value / 100f) * (num2 / 24f));
if (num3 > 0)
{
acc.Balance += num3;
acc.LastInterestTime = num;
BankOfAuraiPlugin.Log.LogInfo((object)("Interest accrued: +" + num3 + " silver."));
}
}
private static float NowGameHours()
{
try
{
return EnvironmentConditions.GameTimeF;
}
catch
{
}
return 0f;
}
}
internal static class BankSpots
{
private static readonly Dictionary<string, Vector3> s_spots = new Dictionary<string, Vector3>();
private static GameObject s_current;
public static GameObject CurrentSpot => s_current;
private static string FilePath => Path.Combine(Path.Combine(Paths.ConfigPath, "BankOfAurai"), "spots.txt");
private static void ApplyDefaults()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
if (!s_spots.ContainsKey("CierzoNewTerrain"))
{
s_spots["CierzoNewTerrain"] = new Vector3(1426.2f, 5.8f, 1658.8f);
}
if (!s_spots.ContainsKey("Monsoon"))
{
s_spots["Monsoon"] = new Vector3(62.5f, -4.6f, 159.5f);
}
if (!s_spots.ContainsKey("Levant"))
{
s_spots["Levant"] = new Vector3(-60.8f, 0.1f, 76.8f);
}
if (!s_spots.ContainsKey("Harmattan"))
{
s_spots["Harmattan"] = new Vector3(89f, 64.8f, 786.9f);
}
if (!s_spots.ContainsKey("Berg"))
{
s_spots["Berg"] = new Vector3(1206.1f, -13.7f, 1383.2f);
}
if (!s_spots.ContainsKey("NewSirocco"))
{
s_spots["NewSirocco"] = new Vector3(55.8f, 55.9f, -61.7f);
}
}
public static void Load()
{
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
s_spots.Clear();
try
{
if (!File.Exists(FilePath))
{
ApplyDefaults();
return;
}
string[] array = File.ReadAllLines(FilePath);
foreach (string text in array)
{
string[] array2 = text.Split(new char[1] { '\t' });
if (array2.Length >= 4 && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result2) && float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out var result3))
{
s_spots[array2[0]] = new Vector3(result, result2, result3);
}
}
ApplyDefaults();
BankOfAuraiPlugin.Log.LogInfo((object)("Bank spots loaded: " + s_spots.Count + " scene(s)."));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Spots load: " + ex));
}
}
private static void Save()
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_0074: 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_0099: Unknown result type (might be due to invalid IL or missing references)
try
{
Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
List<string> list = new List<string>();
foreach (KeyValuePair<string, Vector3> s_spot in s_spots)
{
list.Add(s_spot.Key + "\t" + s_spot.Value.x.ToString(CultureInfo.InvariantCulture) + "\t" + s_spot.Value.y.ToString(CultureInfo.InvariantCulture) + "\t" + s_spot.Value.z.ToString(CultureInfo.InvariantCulture));
}
File.WriteAllLines(FilePath, list.ToArray());
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Spots save: " + ex));
}
}
public static void SetSpot(string sceneName, Vector3 pos)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
s_spots[sceneName] = pos;
Save();
}
public static void SpawnForScene(string sceneName)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
//IL_0050: 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)
BankAudio.InvalidateCache();
if ((Object)(object)s_current != (Object)null)
{
Object.Destroy((Object)(object)s_current);
s_current = null;
}
if (s_spots.TryGetValue(sceneName, out var value))
{
GameObject val = new GameObject("BankOfAurai_Spot");
val.SetActive(false);
val.transform.position = value;
InteractionTriggerBase val2 = val.AddComponent<InteractionTriggerBase>();
val2.DetectionColliderRadius = BankOfAuraiPlugin.InteractionRadius.Value;
FieldInfo field = typeof(InteractionTriggerBase).GetField("m_generateColliderIfNone", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(val2, true);
}
val.AddComponent<InteractionActivator>();
BankDialogue.Attach(val);
val.SetActive(true);
s_current = val;
BankOfAuraiPlugin.Log.LogInfo((object)("Bank spot spawned in '" + sceneName + "' at " + value));
BankBody.SpawnForScene(sceneName, val);
}
}
}
internal static class BankDialogue
{
public const string ACTOR = "Banker";
public static void Attach(GameObject go)
{
DialogueActor val = go.AddComponent<DialogueActor>();
val.SetName("Banker");
DialogueTreeController val2 = go.AddComponent<DialogueTreeController>();
DialogueTreeExt val3 = ScriptableObject.CreateInstance<DialogueTreeExt>();
((Graph)val3).name = "BankOfAuraiDialogue";
val3.CanBeQueued = false;
BuildGraph(val3);
((GraphOwner)val2).graph = (Graph)(object)val3;
try
{
FieldInfo field = typeof(GraphOwner).GetField("instances", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
IDictionary dictionary = field.GetValue(val2) as IDictionary;
if (dictionary == null)
{
dictionary = (IDictionary)Activator.CreateInstance(field.FieldType);
field.SetValue(val2, dictionary);
}
dictionary[val3] = val3;
}
else
{
BankOfAuraiPlugin.Log.LogWarning((object)"GraphOwner.instances not found; dialogue may not start.");
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Instance seed: " + ex));
}
DialogueStarter val4 = go.AddComponent<DialogueStarter>();
BankTalkInteraction bankTalkInteraction = go.AddComponent<BankTalkInteraction>();
bankTalkInteraction.Starter = val4;
bankTalkInteraction.Controller = val2;
DialogueTreeController dialogueController = val4.DialogueController;
InteractionActivator component = go.GetComponent<InteractionActivator>();
if ((Object)(object)component != (Object)null)
{
component.BasicInteraction = (IInteraction)(object)bankTalkInteraction;
}
}
private static void BuildGraph(DialogueTreeExt tree)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
((DialogueTree)tree).actorParameters.Add(new ActorParameter("Banker"));
StatementNodeExt val = ((Graph)tree).AddNode<StatementNodeExt>();
val.statement = new Statement("I'm a representative of the Bank of Aurai. I can help you deposit your silver, or return what's yours.");
BankAudio.ApplyGreetingClip(val.statement);
val.SetActorName("Banker");
ActionNode val2 = ((Graph)tree).AddNode<ActionNode>();
val2.action = (ActionTask)(object)new RefreshVarsTask();
StatementNodeExt val3 = ((Graph)tree).AddNode<StatementNodeExt>();
val3.statement = new Statement("Your account holds [BANK_BALANCE] silver. You carry [POUCH] silver.");
val3.SetActorName("Banker");
MultipleChoiceNodeExt val4 = ((Graph)tree).AddNode<MultipleChoiceNodeExt>();
AddChoice(val4, "Deposit everything.");
AddChoice(val4, "Deposit half of my silver.");
AddChoice(val4, "Withdraw everything.");
AddChoice(val4, "Withdraw half of my balance.");
AddChoice(val4, "I'll be on my way.");
ActionNode val5 = MakeOp(tree, BankOpTask.Op.DepositAll);
ActionNode val6 = MakeOp(tree, BankOpTask.Op.DepositHalf);
ActionNode val7 = MakeOp(tree, BankOpTask.Op.WithdrawAll);
ActionNode val8 = MakeOp(tree, BankOpTask.Op.WithdrawHalf);
FinishNode val9 = ((Graph)tree).AddNode<FinishNode>();
((Graph)tree).ConnectNodes((Node)(object)val, (Node)(object)val2, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val2, (Node)(object)val3, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val3, (Node)(object)val4, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val4, (Node)(object)val5, 0, -1);
((Graph)tree).ConnectNodes((Node)(object)val4, (Node)(object)val6, 1, -1);
((Graph)tree).ConnectNodes((Node)(object)val4, (Node)(object)val7, 2, -1);
((Graph)tree).ConnectNodes((Node)(object)val4, (Node)(object)val8, 3, -1);
((Graph)tree).ConnectNodes((Node)(object)val4, (Node)(object)val9, 4, -1);
((Graph)tree).ConnectNodes((Node)(object)val5, (Node)(object)val2, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val6, (Node)(object)val2, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val7, (Node)(object)val2, -1, -1);
((Graph)tree).ConnectNodes((Node)(object)val8, (Node)(object)val2, -1, -1);
}
private static void AddChoice(MultipleChoiceNodeExt hub, string text)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
hub.availableChoices.Add(new Choice(new Statement(text)));
}
private static ActionNode MakeOp(DialogueTreeExt tree, BankOpTask.Op op)
{
ActionNode val = ((Graph)tree).AddNode<ActionNode>();
BankOpTask bankOpTask = new BankOpTask();
bankOpTask.Operation = op;
val.action = (ActionTask)(object)bankOpTask;
return val;
}
internal static Character LocalCharacter()
{
return (!((Object)(object)CharacterManager.Instance != (Object)null)) ? null : CharacterManager.Instance.GetFirstLocalCharacter();
}
}
public class BankTalkInteraction : InteractionBase
{
public DialogueStarter Starter;
public DialogueTreeController Controller;
private bool m_warmed;
private static readonly FieldInfo s_lastCharField = typeof(InteractionBase).GetField("m_lastCharacter", BindingFlags.Instance | BindingFlags.NonPublic);
protected override string DefaultPressText => "Talk";
protected override void OnActivate()
{
BankOfAuraiPlugin.Log.LogInfo((object)"Bank talk: OnActivate fired.");
((InteractionBase)this).OnActivate();
try
{
Character val = null;
if (s_lastCharField != null)
{
object? value = s_lastCharField.GetValue(this);
val = (Character)((value is Character) ? value : null);
}
if ((Object)(object)val == (Object)null)
{
val = BankDialogue.LocalCharacter();
}
if ((Object)(object)val == (Object)null)
{
BankOfAuraiPlugin.Log.LogWarning((object)"Bank talk: no character found.");
return;
}
if ((Object)(object)Starter == (Object)null)
{
BankOfAuraiPlugin.Log.LogWarning((object)"Bank talk: no DialogueStarter.");
return;
}
BankOfAuraiPlugin.Log.LogInfo((object)("Bank talk: starting dialogue for " + val.Name));
Starter.StartDialogue(val);
if (!m_warmed)
{
m_warmed = true;
BankOfAuraiPlugin.Log.LogInfo((object)"Bank talk: first-use warm restart.");
if ((Object)(object)Controller != (Object)null)
{
Controller.StopDialogue();
}
Starter.StartDialogue(val);
}
else if ((Object)(object)Controller != (Object)null && !((GraphOwner)Controller).isRunning)
{
BankOfAuraiPlugin.Log.LogInfo((object)"Bank talk: start no-op'd, retrying.");
Starter.StartDialogue(val);
}
BankAudio.PlayGreetingBark(((Component)this).gameObject, val);
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Bank talk failed: " + ex));
}
}
}
public class RefreshVarsTask : ActionTask
{
protected override void OnExecute()
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
BankOfAuraiPlugin.Log.LogInfo((object)"Bank dialogue running (RefreshVars).");
try
{
Character val = BankDialogue.LocalCharacter();
if ((Object)(object)val != (Object)null && ((Task)this).blackboard != null)
{
BankLedger.Account account = BankLedger.GetAccount(UID.op_Implicit(val.UID));
int num = (((Object)(object)val.Inventory != (Object)null) ? val.Inventory.AvailableMoney : 0);
SetVar("BANK_BALANCE", account.Balance.ToString());
SetVar("POUCH", num.ToString());
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("RefreshVarsTask: " + ex));
}
((ActionTask)this).EndAction(true);
}
private void SetVar(string name, string value)
{
if (((Task)this).blackboard.GetVariable(name, (Type)null) == null)
{
((Task)this).blackboard.AddVariable(name, (object)value);
}
else
{
((Task)this).blackboard.SetValue(name, (object)value);
}
}
}
public class BankOpTask : ActionTask
{
public enum Op
{
DepositAll,
DepositHalf,
WithdrawAll,
WithdrawHalf
}
public Op Operation;
protected override void OnExecute()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
try
{
Character val = BankDialogue.LocalCharacter();
if ((Object)(object)val != (Object)null && (Object)(object)val.Inventory != (Object)null)
{
BankLedger.Account account = BankLedger.GetAccount(UID.op_Implicit(val.UID));
int availableMoney = val.Inventory.AvailableMoney;
switch (Operation)
{
case Op.DepositAll:
Deposit(val, account, availableMoney);
break;
case Op.DepositHalf:
Deposit(val, account, availableMoney / 2);
break;
case Op.WithdrawAll:
Withdraw(val, account, account.Balance);
break;
case Op.WithdrawHalf:
Withdraw(val, account, account.Balance / 2);
break;
}
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("BankOpTask: " + ex));
}
((ActionTask)this).EndAction(true);
}
private static void Deposit(Character character, BankLedger.Account acc, int amount)
{
if (amount > 0 && character.Inventory.RemoveMoney(amount, false))
{
long num = (long)Math.Floor((float)amount * (BankOfAuraiPlugin.DepositFeePercent.Value / 100f));
acc.Balance += amount - num;
BankLedger.Save();
}
}
private static void Withdraw(Character character, BankLedger.Account acc, long amount)
{
if (amount > 0)
{
if (amount > acc.Balance)
{
amount = acc.Balance;
}
int num = (int)((amount <= int.MaxValue) ? amount : int.MaxValue);
character.Inventory.AddMoney(num);
acc.Balance -= num;
BankLedger.Save();
}
}
}
internal static class BankAudio
{
private static readonly Type s_clipType = Type.GetType("UnityEngine.AudioClip, UnityEngine.AudioModule");
private static readonly Type s_sourceType = Type.GetType("UnityEngine.AudioSource, UnityEngine.AudioModule");
private static readonly List<Object> s_repertoire = new List<Object>();
private static string s_cachedPrefix;
private static Object s_bundle;
private static bool s_warnedBundle;
private static readonly List<string> s_clipNames = new List<string>();
private static string s_resolvedKey;
public static void InvalidateCache()
{
s_repertoire.Clear();
s_cachedPrefix = null;
}
public static void ApplyGreetingClip(Statement statement)
{
}
public static void PlayGreetingBark(GameObject at, Character speaker)
{
try
{
string text = BankOfAuraiPlugin.BarkDialogueKey.Value;
if (string.IsNullOrEmpty(text))
{
return;
}
if (text == "auto")
{
text = "dlg_buy_hostileman_1-";
}
text = text.ToLowerInvariant();
Type type = Type.GetType("UnityEngine.AssetBundle, UnityEngine.AssetBundleModule");
if (type == null || s_clipType == null || s_sourceType == null)
{
return;
}
if (s_bundle == (Object)null)
{
SNPCManager instance = SNPCManager.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
instance.LoadDialogueSoundsBundle();
FieldInfo[] fields = typeof(SNPCManager).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
if (type.IsAssignableFrom(fieldInfo.FieldType))
{
object? value = fieldInfo.GetValue(instance);
Object val = (Object)((value is Object) ? value : null);
if (val != (Object)null)
{
s_bundle = val;
break;
}
}
}
if (s_bundle == (Object)null)
{
if (!s_warnedBundle)
{
s_warnedBundle = true;
BankOfAuraiPlugin.Log.LogInfo((object)"Banker voice unavailable (dialogue sound bundle not exposed); see README.");
}
return;
}
MethodInfo method = type.GetMethod("GetAllAssetNames");
string[] array = ((!(method != null)) ? null : (method.Invoke(s_bundle, null) as string[]));
if (array != null)
{
s_clipNames.Clear();
string[] array2 = array;
foreach (string text2 in array2)
{
if (text2.ToLowerInvariant().Contains(text))
{
s_clipNames.Add(text2);
}
}
BankOfAuraiPlugin.Log.LogInfo((object)("Bark bundle loaded: " + array.Length + " assets, " + s_clipNames.Count + " matching '" + text + "'."));
}
}
if (s_clipNames.Count == 0)
{
return;
}
string text3 = s_clipNames[Random.Range(0, s_clipNames.Count)];
MethodInfo method2 = type.GetMethod("LoadAsset", new Type[2]
{
typeof(string),
typeof(Type)
});
Object val2 = (Object)((!(method2 != null)) ? null : /*isinst with value type is only supported in some contexts*/);
if (val2 == (Object)null)
{
BankOfAuraiPlugin.Log.LogWarning((object)("Could not load bark clip: " + text3));
return;
}
Component val3 = at.GetComponent(s_sourceType);
if ((Object)(object)val3 == (Object)null)
{
val3 = at.AddComponent(s_sourceType);
}
if (!((Object)(object)val3 == (Object)null))
{
PropertyInfo property = s_sourceType.GetProperty("spatialBlend");
if (property != null)
{
property.SetValue(val3, 0f, null);
}
PropertyInfo property2 = s_sourceType.GetProperty("volume");
if (property2 != null)
{
property2.SetValue(val3, 1f, null);
}
MethodInfo method3 = s_sourceType.GetMethod("PlayOneShot", new Type[1] { s_clipType.MakeByRefType().GetElementType() ?? s_clipType });
if (method3 == null)
{
method3 = s_sourceType.GetMethod("PlayOneShot", new Type[1] { s_clipType });
}
if (method3 != null)
{
method3.Invoke(val3, new object[1] { val2 });
BankOfAuraiPlugin.Log.LogInfo((object)("Banker bark: " + text3));
}
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("PlayGreetingBark: " + ex));
}
}
private static string FindKeyByText(string phrase)
{
try
{
if (string.IsNullOrEmpty(phrase))
{
return null;
}
string p = phrase.ToLowerInvariant();
FieldInfo field = typeof(LocalizationManager).GetField("m_dialogueLocalization", BindingFlags.Instance | BindingFlags.NonPublic);
IDictionary dictionary = ((!(field != null)) ? null : (field.GetValue(LocalizationManager.Instance) as IDictionary));
if (dictionary == null)
{
return null;
}
foreach (DictionaryEntry item in dictionary)
{
if (ContainsPhrase(item.Value, p, 0))
{
BankOfAuraiPlugin.Log.LogMessage((object)string.Concat("Bark line found: key='", item.Key, "'"));
return item.Key.ToString();
}
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("FindKeyByText: " + ex));
}
return null;
}
private static bool ContainsPhrase(object obj, string p, int depth)
{
if (obj == null || depth > 2)
{
return false;
}
Type type = obj.GetType();
FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo fieldInfo in fields)
{
object value;
try
{
value = fieldInfo.GetValue(obj);
}
catch
{
continue;
}
if (value is string)
{
if (((string)value).ToLowerInvariant().Contains(p))
{
return true;
}
}
else
{
if (!(value is IEnumerable) || value is string)
{
continue;
}
foreach (object item in (IEnumerable)value)
{
if (item is string)
{
if (((string)item).ToLowerInvariant().Contains(p))
{
return true;
}
}
else if (ContainsPhrase(item, p, depth + 1))
{
return true;
}
}
}
}
return false;
}
private static void DumpCandidateKeys(string hint)
{
try
{
FieldInfo field = typeof(LocalizationManager).GetField("m_dialogueLocalization", BindingFlags.Instance | BindingFlags.NonPublic);
IDictionary dictionary = ((!(field != null)) ? null : (field.GetValue(LocalizationManager.Instance) as IDictionary));
if (dictionary == null)
{
BankOfAuraiPlugin.Log.LogWarning((object)" (dialogue localization not readable)");
return;
}
string text = (hint ?? "").ToLowerInvariant();
int num = 0;
foreach (object key in dictionary.Keys)
{
string text2 = key.ToString();
string text3 = text2.ToLowerInvariant();
if (text3.Contains("buy") || text3.Contains("hostile") || (text.Length > 2 && text3.Contains(text.Substring(0, 3))))
{
BankOfAuraiPlugin.Log.LogMessage((object)(" candidate: " + text2));
if (++num >= 40)
{
break;
}
}
}
BankOfAuraiPlugin.Log.LogMessage((object)(" (" + dictionary.Count + " dialogue keys total, " + num + " shown)"));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("DumpCandidateKeys: " + ex));
}
}
public static void ScanScene()
{
try
{
int num = 0;
int num2 = 0;
int num3 = 0;
DialogueTree[] array = Resources.FindObjectsOfTypeAll<DialogueTree>();
BankOfAuraiPlugin.Log.LogMessage((object)("Audio scan: " + array.Length + " dialogue trees loaded."));
DialogueTree[] array2 = array;
foreach (DialogueTree val in array2)
{
List<Node> allNodes = ((Graph)val).allNodes;
if (allNodes == null)
{
continue;
}
foreach (Node item in allNodes)
{
StatementNodeExt val2 = (StatementNodeExt)(object)((item is StatementNodeExt) ? item : null);
if (val2 == null || val2.statement == null)
{
continue;
}
num++;
string text = val2.statement.text ?? "";
string text2 = text;
try
{
string loc = LocalizationManager.Instance.GetLoc(text);
if (!string.IsNullOrEmpty(loc))
{
text2 = loc;
}
}
catch
{
}
Object val3 = null;
string text3 = (text + " " + text2).ToLowerInvariant();
if (text3.Contains("money") || text3.Contains("better") || text3.Contains("coin"))
{
num3++;
BankOfAuraiPlugin.Log.LogMessage((object)(" [" + ((Graph)val).name + "] text='" + text2 + "' key='" + text + "' clip=" + ((!(val3 != (Object)null)) ? "none" : val3.name)));
}
}
}
BankOfAuraiPlugin.Log.LogMessage((object)("Audio scan done: " + num + " statements, " + num2 + " voiced, " + num3 + " matched."));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Audio scan: " + ex));
}
}
}
internal static class AudioWiretap
{
public static void Install()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
try
{
Harmony val = new Harmony("com.spencer4792.bankofaurai.wiretap");
HarmonyMethod val2 = new HarmonyMethod(typeof(AudioWiretap).GetMethod("SoundPostfix", BindingFlags.Static | BindingFlags.NonPublic));
int num = 0;
MethodInfo[] methods = typeof(GlobalAudioManager).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (MethodInfo methodInfo in methods)
{
if (!methodInfo.Name.StartsWith("Play"))
{
continue;
}
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != 0 && !(parameters[0].Name != "_sound"))
{
try
{
val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null);
num++;
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogWarning((object)("Wiretap skip " + methodInfo.Name + ": " + ex.Message));
}
}
}
BankOfAuraiPlugin.Log.LogInfo((object)("Audio wiretap installed on " + num + " methods."));
}
catch (Exception ex2)
{
BankOfAuraiPlugin.Log.LogError((object)("Wiretap install: " + ex2));
}
}
private static void SoundPostfix(object _sound, MethodBase __originalMethod)
{
try
{
if (BankOfAuraiPlugin.WiretapEnabled.Value)
{
BankOfAuraiPlugin.Log.LogMessage((object)("[wiretap] " + __originalMethod.Name + ": " + _sound));
}
}
catch
{
}
}
public static void SnapshotPlaying()
{
try
{
Type type = Type.GetType("UnityEngine.AudioSource, UnityEngine.AudioModule");
if (type == null)
{
BankOfAuraiPlugin.Log.LogWarning((object)"Snapshot: AudioSource type not found.");
return;
}
PropertyInfo property = type.GetProperty("isPlaying");
PropertyInfo property2 = type.GetProperty("clip");
Object[] array = Resources.FindObjectsOfTypeAll(type);
int num = 0;
Object[] array2 = array;
foreach (Object val in array2)
{
bool flag = false;
try
{
flag = (bool)property.GetValue(val, null);
}
catch
{
continue;
}
if (flag)
{
num++;
object? value = property2.GetValue(val, null);
Object val2 = (Object)((value is Object) ? value : null);
Component val3 = (Component)(object)((val is Component) ? val : null);
string text = ((!((Object)(object)val3 != (Object)null)) ? "?" : ((Object)val3.gameObject).name);
BankOfAuraiPlugin.Log.LogMessage((object)("[snapshot] playing: clip=" + ((!(val2 != (Object)null)) ? "none" : val2.name) + " on '" + text + "'"));
}
}
BankOfAuraiPlugin.Log.LogMessage((object)("[snapshot] " + num + " sources playing of " + array.Length + "."));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Snapshot: " + ex));
}
}
}
internal static class BankBody
{
private static readonly Dictionary<string, string> s_sources = new Dictionary<string, string>();
private static readonly Dictionary<string, float> s_yaws = new Dictionary<string, float>();
private static GameObject s_currentBody;
private static string FilePath => Path.Combine(Path.Combine(Paths.ConfigPath, "BankOfAurai"), "bodies.txt");
public static void Load()
{
s_sources.Clear();
s_yaws.Clear();
s_sources["CierzoNewTerrain"] = "snpc:HumanSNPCMoving (6)";
s_yaws["CierzoNewTerrain"] = 73.34101f;
s_sources["Monsoon"] = "snpc:HumanSNPC_Priest";
s_yaws["Monsoon"] = 125.9873f;
s_sources["Levant"] = "snpc:HumanSNPC_FestiveNoble";
s_yaws["Levant"] = 26.10077f;
s_sources["Berg"] = "snpc:HumanSNPCMoving (1)";
s_yaws["Berg"] = 251.4524f;
s_sources["NewSirocco"] = "snpc:UNPC_DLC2_AlchemySkillGiver";
s_yaws["NewSirocco"] = 35.72704f;
s_sources["Harmattan"] = "snpc:UNPC_DLC_VictorBerthelot_MilitaryDean";
s_yaws["Harmattan"] = 125.2129f;
try
{
if (!File.Exists(FilePath))
{
return;
}
string[] array = File.ReadAllLines(FilePath);
foreach (string text in array)
{
string[] array2 = text.Split(new char[1] { '\t' });
if (array2.Length >= 2)
{
s_sources[array2[0]] = array2[1];
}
if (array2.Length >= 3 && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
s_yaws[array2[0]] = result;
}
}
BankOfAuraiPlugin.Log.LogInfo((object)("Banker bodies loaded: " + s_sources.Count + " scene(s)."));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Bodies load: " + ex));
}
}
private static void Save()
{
try
{
Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
List<string> list = new List<string>();
foreach (KeyValuePair<string, string> s_source in s_sources)
{
string text = s_source.Key + "\t" + s_source.Value;
if (s_yaws.TryGetValue(s_source.Key, out var value))
{
text = text + "\t" + value.ToString(CultureInfo.InvariantCulture);
}
list.Add(text);
}
File.WriteAllLines(FilePath, list.ToArray());
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("Bodies save: " + ex));
}
}
public static void CopyNearestLook()
{
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_022c: Unknown result type (might be due to invalid IL or missing references)
//IL_0231: Unknown result type (might be due to invalid IL or missing references)
//IL_025f: Unknown result type (might be due to invalid IL or missing references)
//IL_026e: Unknown result type (might be due to invalid IL or missing references)
//IL_0273: Unknown result type (might be due to invalid IL or missing references)
//IL_0278: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
try
{
Character val = ((!((Object)(object)CharacterManager.Instance != (Object)null)) ? null : CharacterManager.Instance.GetFirstLocalCharacter());
if ((Object)(object)val == (Object)null)
{
return;
}
GameObject val2 = null;
string text = null;
float num = 6f;
Character[] array = Object.FindObjectsOfType<Character>();
foreach (Character val3 in array)
{
if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)val)
{
continue;
}
CharacterVisuals visuals = val3.Visuals;
if (!((Object)(object)visuals == (Object)null))
{
float num2 = Vector3.Distance(((Component)val3).transform.position, ((Component)val).transform.position);
if (num2 < num)
{
num = num2;
val2 = ((Component)visuals).gameObject;
text = "char:" + val3.Name;
}
}
}
SNPC[] array2 = Object.FindObjectsOfType<SNPC>();
foreach (SNPC val4 in array2)
{
if (!((Object)(object)val4 == (Object)null))
{
float num3 = Vector3.Distance(((Component)val4).transform.position, ((Component)val).transform.position);
if (num3 < num)
{
num = num3;
val2 = ((Component)val4).gameObject;
text = "snpc:" + ((Object)((Component)val4).gameObject).name;
}
}
}
GameObject currentSpot = BankSpots.CurrentSpot;
if ((Object)(object)val2 == (Object)null)
{
if ((Object)(object)currentSpot != (Object)null && (Object)(object)s_currentBody != (Object)null && Vector3.Distance(((Component)val).transform.position, currentSpot.transform.position) < 10f)
{
Scene activeScene = SceneManager.GetActiveScene();
string name = ((Scene)(ref activeScene)).name;
float value = AimBodyAt(currentSpot, ((Component)val).transform.position);
s_yaws[name] = value;
Save();
BankOfAuraiPlugin.Log.LogMessage((object)("Banker re-aimed (yaw " + value.ToString("F0") + ") and saved."));
}
else
{
BankOfAuraiPlugin.Log.LogMessage((object)"No NPC within 6m to copy.");
}
return;
}
Scene activeScene2 = SceneManager.GetActiveScene();
string name2 = ((Scene)(ref activeScene2)).name;
s_sources[name2] = text;
if ((Object)(object)BankSpots.CurrentSpot != (Object)null)
{
Vector3 val5 = ((Component)val).transform.position - BankSpots.CurrentSpot.transform.position;
val5.y = 0f;
if (((Vector3)(ref val5)).sqrMagnitude > 0.01f)
{
Dictionary<string, float> dictionary = s_yaws;
Quaternion val6 = Quaternion.LookRotation(val5);
dictionary[name2] = ((Quaternion)(ref val6)).eulerAngles.y;
}
}
Save();
BankOfAuraiPlugin.Log.LogMessage((object)("Banker for '" + name2 + "' cast: " + text));
GameObject currentSpot2 = BankSpots.CurrentSpot;
if ((Object)(object)currentSpot2 != (Object)null)
{
AttachCloneGO(val2, currentSpot2);
}
else
{
BankOfAuraiPlugin.Log.LogMessage((object)"No bank spot in this scene yet (F6 to place one).");
}
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("CopyNearestLook: " + ex));
}
}
public static void SpawnForScene(string sceneName, GameObject spot)
{
if ((Object)(object)s_currentBody != (Object)null)
{
Object.Destroy((Object)(object)s_currentBody);
s_currentBody = null;
}
if (s_sources.TryGetValue(sceneName, out var value))
{
((MonoBehaviour)BankOfAuraiPlugin.Instance).StartCoroutine(WaitAndClone(value, spot));
}
}
private static IEnumerator WaitAndClone(string key, GameObject spot)
{
for (int attempt = 0; attempt < 15; attempt++)
{
yield return (object)new WaitForSeconds(2f);
if ((Object)(object)spot == (Object)null)
{
yield break;
}
GameObject found = null;
if (key.StartsWith("snpc:"))
{
string text = key.Substring(5);
SNPC[] array = Object.FindObjectsOfType<SNPC>();
foreach (SNPC val in array)
{
if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == text)
{
found = ((Component)val).gameObject;
break;
}
}
}
else
{
string text2 = ((!key.StartsWith("char:")) ? key : key.Substring(5));
Character[] array2 = Object.FindObjectsOfType<Character>();
foreach (Character val2 in array2)
{
if ((Object)(object)val2 != (Object)null && val2.Name == text2 && (Object)(object)val2.Visuals != (Object)null)
{
found = ((Component)val2.Visuals).gameObject;
break;
}
}
}
if ((Object)(object)found != (Object)null)
{
AttachCloneGO(found, spot);
yield break;
}
}
BankOfAuraiPlugin.Log.LogWarning((object)("Banker body source '" + key + "' never appeared in this scene."));
}
private static float AimBodyAt(GameObject spot, Vector3 target)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: 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_003d: 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)
Vector3 val = target - spot.transform.position;
val.y = 0f;
float num;
if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
{
Quaternion val2 = Quaternion.LookRotation(val);
num = ((Quaternion)(ref val2)).eulerAngles.y;
}
else
{
num = 0f;
}
float num2 = num;
if ((Object)(object)s_currentBody != (Object)null)
{
s_currentBody.transform.rotation = Quaternion.Euler(0f, num2, 0f);
}
return num2;
}
private static void AttachCloneGO(GameObject sourceGO, GameObject spot)
{
//IL_00f6: 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_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)s_currentBody != (Object)null)
{
Object.Destroy((Object)(object)s_currentBody);
s_currentBody = null;
}
GameObject val = Object.Instantiate<GameObject>(sourceGO);
((Object)val).name = "BankOfAurai_Body";
MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val2 in componentsInChildren)
{
if ((Object)(object)val2 != (Object)null)
{
Object.Destroy((Object)(object)val2);
}
}
Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
foreach (Collider val3 in componentsInChildren2)
{
if ((Object)(object)val3 != (Object)null)
{
Object.Destroy((Object)(object)val3);
}
}
Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true);
foreach (Rigidbody val4 in componentsInChildren3)
{
if ((Object)(object)val4 != (Object)null)
{
Object.Destroy((Object)(object)val4);
}
}
val.transform.SetParent(spot.transform, false);
val.transform.localPosition = Vector3.zero;
val.transform.localRotation = Quaternion.identity;
Dictionary<string, float> dictionary = s_yaws;
Scene activeScene = SceneManager.GetActiveScene();
if (dictionary.TryGetValue(((Scene)(ref activeScene)).name, out var value))
{
val.transform.rotation = Quaternion.Euler(0f, value, 0f);
}
else
{
Character val5 = ((!((Object)(object)CharacterManager.Instance != (Object)null)) ? null : CharacterManager.Instance.GetFirstLocalCharacter());
if ((Object)(object)val5 != (Object)null)
{
Vector3 val6 = ((Component)val5).transform.position - spot.transform.position;
val6.y = 0f;
if (((Vector3)(ref val6)).sqrMagnitude > 0.01f)
{
val.transform.rotation = Quaternion.LookRotation(val6);
}
}
}
try
{
Type type = Type.GetType("UnityEngine.Animation, UnityEngine.AnimationModule");
if (type != null)
{
Component componentInChildren = val.GetComponentInChildren(type);
if ((Object)(object)componentInChildren != (Object)null)
{
MethodInfo method = type.GetMethod("Play", new Type[0]);
if (method != null)
{
method.Invoke(componentInChildren, null);
}
}
}
}
catch
{
}
val.SetActive(true);
s_currentBody = val;
BankOfAuraiPlugin.Log.LogMessage((object)("Banker body attached from: " + ((Object)sourceGO).name));
}
catch (Exception ex)
{
BankOfAuraiPlugin.Log.LogError((object)("AttachClone: " + ex));
}
}
}