using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using NodeCanvas.DialogueTrees; using NodeCanvas.Framework; using SideLoader; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OutwardModTemplate")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OutwardModTemplate")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("c5450fe0-edcf-483f-b9ea-4b1ef9d36da7")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace TravelNetwork; public static class Helpers { public static int GetCurrentDayNumber() { float num = (float)EnvironmentConditions.GameTime; return Mathf.FloorToInt(num / 24f) + 1; } public static int GetCurrentMapID() { return AreaManager.Instance.CurrentArea.ID; } public static int GenerateSeedFromString(string randomString) { return randomString.GetHashCode(); } public static void Shuffle(this IList list, int seed) { Random random = new Random(seed); int num = list.Count; while (num > 1) { num--; int index = random.Next(num + 1); T value = list[index]; list[index] = list[num]; list[num] = value; } } public static T GetPseudoRandomItem(IReadOnlyList list, int step) { int num = 0; if (list == null || list.Count == 0) { throw new ArgumentException("List cannot be empty.", "list"); } if (list.Count == 1) { return list[0]; } int count = list.Count; int num2 = 1013; if (num2 % count == 0) { num2++; } int index = Math.Abs((num + step * num2) % count); return list[index]; } public static int PickTravelConnection(List connections, int seed) { if (connections.Count == 0) { return -1; } int index = seed % connections.Count; return connections[index]; } public static List TravelConnections(int fromID) { List list = new List(); switch (fromID) { case 100: list.Add(400); break; case 101: list.Add(200); list.Add(300); list.Add(500); list.Add(400); list.Add(601); break; case 200: list.Add(400); break; case 201: list.Add(100); list.Add(500); list.Add(300); list.Add(400); list.Add(601); break; case 500: list.Add(400); break; case 501: list.Add(100); list.Add(200); list.Add(300); list.Add(400); list.Add(601); break; case 300: list.Add(400); break; case 301: list.Add(100); list.Add(200); list.Add(500); list.Add(400); list.Add(601); break; case 400: list.Add(100); list.Add(200); list.Add(300); list.Add(500); list.Add(601); break; case 401: list.Add(100); list.Add(200); list.Add(300); list.Add(500); list.Add(601); break; case 601: list.Add(400); break; case 602: list.Add(100); list.Add(200); list.Add(300); list.Add(500); list.Add(400); break; default: list.Add(400); break; } return list; } public static void SwapDialogue(string sceneLocation, int subtreeNodeID, int statementNodeID, string newStatement) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown GameObject val = GameObject.Find(sceneLocation); if (!((Object)(object)val != (Object)null)) { return; } DialogueTreeController component = val.GetComponent(); DialogueTreeExt graph = GetGraph(component, subtreeNodeID); if ((Object)(object)graph == (Object)null) { TravelNetworkPlugin.Log.LogError((object)"Graph is null."); return; } if (((Graph)graph)._nodes.Count < statementNodeID) { TravelNetworkPlugin.Log.LogError((object)"Statement node ID is out of range."); return; } StatementNodeExt val2 = (StatementNodeExt)((Graph)graph)._nodes[statementNodeID]; if (val2 == null) { TravelNetworkPlugin.Log.LogError((object)"Target node is not a StatementNode."); return; } val2.statement = new Statement(newStatement); TravelNetworkPlugin.Log.LogMessage((object)"Statement changed."); } public static DialogueTreeExt GetGraph(DialogueTreeController controller, int subtreeNodeID) { if ((Object)(object)controller == (Object)null) { return null; } DialogueTreeExt graph = ((GraphOwner)(object)controller)._graph; return GetSubFromPrimaryGraph(graph, subtreeNodeID); } public static AreaEnum GetAreaEnumFromMapID(int mapID) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return (AreaEnum)mapID; } public static DialogueTreeExt GetSubFromPrimaryGraph(DialogueTreeExt graph, int subtreeNodeID) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if ((Object)(object)graph != (Object)null) { Node val = ((Graph)graph)._nodes[subtreeNodeID]; if (val == null) { TravelNetworkPlugin.Log.LogError((object)"Subtree node not found or is not a SubDialogueTree."); return null; } SubDialogueTree val2 = (SubDialogueTree)val; if (val2 == null) { TravelNetworkPlugin.Log.LogError((object)"SubDialogueTree is null."); return null; } return (DialogueTreeExt)val2.subTree; } return null; } public static DTNode ConnectTo(this DTNode sourceNode, DialogueTree DT, DTNode TargetNode, int sourceIndex = -1, int targetIndex = -1) { if (!((Graph)DT).allNodes.Contains((Node)(object)TargetNode)) { ((Graph)DT).allNodes.Add((Node)(object)TargetNode); } ((Graph)DT).ConnectNodes((Node)(object)sourceNode, (Node)(object)TargetNode, sourceIndex, targetIndex); return TargetNode; } } public class Patches { [HarmonyPatch(typeof(MerchantFastTravel), "RefreshTravelDestinations")] [HarmonyPatch(new Type[] { typeof(bool) })] public class InsertNewTravelDestinationPatch { private static bool Prefix(MerchantFastTravel __instance, ref List ___tmpCurrentTravelData, ref AreaEnum ___m_currentAreaAssociatedCity, ref bool ___m_refreshRequired, bool _forceRefresh) { //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Expected O, but got Unknown //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Expected O, but got Unknown TravelNetworkPlugin.Instance.manager.UpdateWorldStateData(); int num = -1; ___tmpCurrentTravelData.Clear(); if (!PhotonNetwork.isNonMasterClientInRoom || _forceRefresh) { __instance.m_travelToRegion.Clear(); Area currentArea = AreaManager.Instance.CurrentArea; __instance.InCity = AreaManager.Instance.GetIsAreaTownOrCity(currentArea); if (__instance.InCierzoArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)100; } else if (__instance.InBergArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)500; } else if (__instance.InLevantArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)300; } else if (__instance.InMonsoonArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)200; } else if (__instance.InHarmattanArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)400; } else if (__instance.InNewSiroccoArea(currentArea)) { ___m_currentAreaAssociatedCity = (AreaEnum)601; } else { ___m_currentAreaAssociatedCity = (AreaEnum)552; } MerchantFastTravel.CanTravelToHarmattan = StoreManager.Instance.IsDlcInstalled((DLCs)2) && !__instance.InHarmattanArea(currentArea); List list = Helpers.TravelConnections(currentArea.ID); if (QuestEventManager.Instance.HasQuestEvent("lDHL_XMS7kKEs0uOqrLQjw") && list.Contains(100)) { list.Remove(100); } if (QuestEventManager.Instance.HasQuestEvent("vW4sarzBGkalTwy_KhGI6A") && list.Contains(500)) { list.Remove(500); } if (!__instance.CheckIfLevantBlocked() && list.Contains(300)) { list.Remove(300); } if (!QuestEventManager.Instance.HasQuestEvent("eYmZGb_BJ0qAtpcwrndhTg")) { list.Remove(601); } if (list.Count == 0) { list.Add(400); } TravelNetworkPlugin.Instance.manager.UpdateTravelLocations(list); int travelLocation = TravelNetworkPlugin.Instance.manager.travelLocation; __instance.m_travelToRegion.Add(travelLocation); MerchantFastTravel.Destinations.TryGetValue(currentArea.SceneName, out var value); if (value == null || EnvironmentConditions.GameTimeF - value.LastRefreshTime >= 72f || _forceRefresh) { int num2 = -1; if (__instance.m_travelToRegion.Count > 1) { num2 = Random.Range(0, __instance.m_travelToRegion.Count); } else if (__instance.m_travelToRegion.Count == 1) { num2 = 0; } if (value == null) { value = new DestinationData(); MerchantFastTravel.Destinations.Add(currentArea.SceneName, value); } value.LastRefreshTime = EnvironmentConditions.GameTimeF; num = (value.DestinationID = ((num2 != -1) ? __instance.m_travelToRegion[num2] : num2)); } else if (__instance.m_travelToRegion.Contains(value.DestinationID)) { num = value.DestinationID; } if (num != -1) { TravelData val = AreaManager.Instance.GetMerchantTravelData(MerchantFastTravel.m_currentAreaAssociatedCity, (AreaEnum)num); if (val == null) { val = new TravelData(); val.From = TravelNetworkPlugin.Instance.manager.GetAreaEnum(currentArea.ID); val.Destination = TravelNetworkPlugin.Instance.manager.GetAreaEnum(travelLocation); if (__instance.InCity) { val.SilverCost = 200; val.RationCost = 2; } else { val.SilverCost = 40; val.RationCost = 1; } } ___tmpCurrentTravelData.Add(val); } MerchantFastTravel.SyncTravelDestinations(); } else { Global.RPCManager.RequestMerchantFastTravelDestinations(); } ___m_refreshRequired = false; __instance.UnregisterRefresh(); return false; } } [HarmonyPatch(typeof(CharacterManager), "AddCharacter")] public class RegisterPlayerPatch { private static void Postfix(CharacterManager __instance, Character _char) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((int)_char.InstantiationType != 1) { return; } for (int i = 0; i < __instance.PlayerCharacters.Count; i++) { if (i == 0) { Character character = __instance.GetCharacter(__instance.PlayerCharacters.Values[i]); string hostCharacterUID = ((object)character.UID/*cast due to .constrained prefix*/).ToString(); TravelNetworkPlugin.Instance.manager.hostCharacterUID = hostCharacterUID; } } } } [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class TextSetterPatch { private static void Postfix(Text __instance, ref string ___m_Text) { if (!(__instance.text != "Sure, I can give you a lift, for a small fee. And you’ll need to handle your own rations.")) { ___m_Text = TravelNetworkPlugin.Instance.manager.currentStatementCheck; } } } } [BepInPlugin("johbenji.travelnetwork", "Travel Network", "0.5.0")] public class TravelNetworkPlugin : BaseUnityPlugin { public const string GUID = "johbenji.travelnetwork"; public const string NAME = "Travel Network"; public const string VERSION = "0.5.0"; internal static ManualLogSource Log; public TravelNetworkManager manager; public static TravelNetworkPlugin Instance { get; private set; } internal void Awake() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Instance = this; manager = new TravelNetworkManager(); new Harmony("johbenji.travelnetwork").PatchAll(); SL.OnGameplayResumedAfterLoading += OnGameplayResumedAfterLoading; } internal void OnGameplayResumedAfterLoading() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) manager.hostCharacterUID = ((object)CharacterManager.Instance.GetFirstLocalCharacter().UID/*cast due to .constrained prefix*/).ToString(); manager.UpdateWorldStateData(); UpdateDialogueToIncludeForecast(); } private void UpdateDialogueToIncludeForecast() { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) int mapID = manager.worldStateData.MapID; string text = "Sure, I can give you a lift, for a small fee. And you'll need to handle your own rations."; string sceneLocation = ""; int subtreeNodeID = -1; int statementNodeID = -1; bool flag = true; switch (mapID) { case 100: sceneLocation = "_SNPC/_Merchants/HumanSNPC_CaravanTrader/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; case 500: sceneLocation = "_SNPC/_Merchants/HumanSNPC_CaravanTrader/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; case 200: sceneLocation = "_SNPC/CharactersToDesactivate/_Merchants/UNPC_CaravanTraderA/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; case 300: sceneLocation = "_SNPC/DisablingForHMQ4/_MerchantsHighPrices/UNPC_CaravanTraderA/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; case 400: sceneLocation = "Interactions/NPCs/NPC_Minor/UNPC_CaravanTraderA/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; case 601: sceneLocation = "Interactions/NPCGestion/CaravanTrader/UNPC_CaravanTraderA/MerchantTemplate/NPC/ShopDialogue"; subtreeNodeID = 4; statementNodeID = 2; break; default: flag = false; break; } string text2 = text; text2 = ((!flag) ? (text2 + " I'm going to " + ((object)manager.GetAreaEnum(manager.travelLocation)/*cast due to .constrained prefix*/).ToString() + ".") : ((mapID != 400) ? (text2 + " I'm heading back to Harmattan.") : (text2 + " I'm going to " + ((object)manager.GetAreaEnum(manager.travelLocation)/*cast due to .constrained prefix*/).ToString() + ". Later, I will be travelling to " + ((object)manager.GetAreaEnum(manager.nextTravelLocation)/*cast due to .constrained prefix*/).ToString() + " in case that piques your interest."))); Helpers.SwapDialogue(sceneLocation, subtreeNodeID, statementNodeID, text2); manager.currentStatementCheck = text2; } } public class TravelNetworkManager { public string hostCharacterUID = ""; public WorldStateData worldStateData; public int rotationNumber = 0; public List travelLocations; public int travelLocation = 400; public int nextTravelLocation = 400; public string currentStatementCheck = "Yj942iDHldwX3f3hjmO2J4WBh"; public AreaEnum GetAreaEnum(int id) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) return (AreaEnum)id; } public void SetTravelLocation() { rotationNumber = (int)((float)Helpers.GetCurrentDayNumber() / 3f); travelLocation = Helpers.GetPseudoRandomItem(travelLocations, rotationNumber); nextTravelLocation = Helpers.GetPseudoRandomItem(travelLocations, rotationNumber + 1); } public void UpdateTravelLocations(List locations) { locations.Shuffle(Helpers.GenerateSeedFromString(hostCharacterUID)); travelLocations = locations; SetTravelLocation(); } public void UpdateWorldStateData() { int currentDayNumber = Helpers.GetCurrentDayNumber(); int currentMapID = Helpers.GetCurrentMapID(); SetWorldStateData(currentMapID, currentDayNumber); } public void SetWorldStateData(int mapID, int dayInt) { worldStateData = new WorldStateData(mapID, dayInt); } } public struct WorldStateData { public int MapID { get; } public int DayInt { get; } public WorldStateData(int mapID, int dayInt) { MapID = mapID; DayInt = dayInt; } }