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<T>(this IList<T> 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<T>(IReadOnlyList<T> 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<int> connections, int seed)
{
if (connections.Count == 0)
{
return -1;
}
int index = seed % connections.Count;
return connections[index];
}
public static List<int> TravelConnections(int fromID)
{
List<int> list = new List<int>();
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<DialogueTreeController>();
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<DialogueTreeExt>)(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<TravelData> ___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<int> 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 <color=#00CCFF><b>" + ((object)manager.GetAreaEnum(manager.travelLocation)/*cast due to .constrained prefix*/).ToString() + "</b></color>.") : ((mapID != 400) ? (text2 + " I'm heading back to <color=#00CCFF><b>Harmattan</b></color>.") : (text2 + " I'm going to <color=#00CCFF><b>" + ((object)manager.GetAreaEnum(manager.travelLocation)/*cast due to .constrained prefix*/).ToString() + "</b></color>. Later, I will be travelling to <color=#00CCFF><b>" + ((object)manager.GetAreaEnum(manager.nextTravelLocation)/*cast due to .constrained prefix*/).ToString() + "</b></color> 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<int> 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<int> 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;
}
}