Decompiled source of EconomicEvents v1.0.1

EconomicEvents\EconomicEvents.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ModSaveBackups;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("EconomicEvents")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EconomicEvents")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("47f2429a-1581-46a0-a562-29bc48bfe982")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace EconomicEvents;

internal sealed class Event
{
	internal int Id { get; private set; }

	internal string Name { get; private set; }

	internal string EventText { get; private set; }

	internal int[] GoodIndexes { get; private set; }

	internal int PriceMult { get; private set; }

	internal int EventDuration { get; private set; }

	internal int[] SpecificPorts { get; private set; }

	internal static List<Event> Events { get; private set; }

	internal static Dictionary<int, int> ItemToCrateConversion { get; } = new Dictionary<int, int>
	{
		{ 33, 1 },
		{ 42, 2 },
		{ 54, 4 },
		{ 46, 6 },
		{ 52, 7 },
		{ 53, 8 },
		{ 32, 9 },
		{ 37, 14 },
		{ 41, 15 },
		{ 39, 16 },
		{ 44, 17 },
		{ 36, 18 },
		{ 34, 19 },
		{ 147, 43 },
		{ 144, 44 },
		{ 146, 46 },
		{ 149, 54 }
	};


	private Event(int id, string name, string eventText, int[] goodIndexes, int priceMult, int eventDuration, int[] ports)
	{
		Id = id;
		Name = name;
		EventText = eventText;
		GoodIndexes = goodIndexes;
		PriceMult = priceMult;
		EventDuration = eventDuration;
		SpecificPorts = ports;
	}

	internal static void InitializeEvents()
	{
		List<Event> list = new List<Event>();
		list.Add(new Event(0, "Storm Damage", "A terrible storm swept through and the port needs building supplies\nfor repairs.", new int[2] { 47, 48 }, 3, 7, new int[0]));
		list.Add(new Event(1, "Drought", "A drought has stricken the area. The people are thirsty and are\nin urgent need of water.", new int[1] { 10 }, 3, 7, new int[0]));
		list.Add(new Event(2, "Plague", "A plague is ravaging the port. They are in dire need of more\nmedicine.", new int[1] { 26 }, 2, 14, new int[0]));
		list.Add(new Event(3, "Library Fire", "A fire broke out in the library. They need more books to replace\nthe damged texts.", new int[1] { 30 }, 3, 7, new int[3] { 5, 23, 26 }));
		list.Add(new Event(4, "Volcano Erupted", "Mt. Malefic erupted and destroyed parts of the town. They need\nbuilding supplies for repairs and medicine for the injured.", new int[3] { 47, 48, 26 }, 3, 14, new int[1] { 17 }));
		list.Add(new Event(5, "New Mine", "They are making a new mine on the island and will pay a premium\nfor materials and tools.", new int[3] { 47, 48, 33 }, 2, 14, new int[3] { 19, 0, 28 }));
		list.Add(new Event(6, "Missed Wine Delivery", "A shipment of wine never arrived and the people of the port are\nclamoring for some.", new int[1] { 13 }, 2, 14, new int[0]));
		list.Add(new Event(7, "Increased Relic Production", "Interest in relics is rising. They need gold and gems in Aestra\nAbbey to make more.", new int[2] { 20, 22 }, 3, 7, new int[1] { 26 }));
		list.Add(new Event(8, "Shipwreck", "A ship wrecked was found and the port needs supplies to help the\nsurvivors.", new int[3] { 5, 26, 29 }, 2, 14, new int[0]));
		list.Add(new Event(9, "Festival", "A festival is being held and the port needs supplies for the\ncelebration.", new int[6] { 11, 12, 13, 15, 36, 58 }, 2, 7, new int[0]));
		list.Add(new Event(10, "Shipyard Maintenance", "The shipyard is in need of maintenance and needs supplies for\nthe job.", new int[5] { 47, 48, 33, 21, 35 }, 3, 14, new int[4] { 0, 9, 15, 22 }));
		list.Add(new Event(11, "New Fishing Grounds", "New fishing grounds have been discovered and the port wants\nsupplies to build more fishing boats.", new int[3] { 48, 33, 35 }, 2, 21, new int[0]));
		list.Add(new Event(12, "New Dish", "A new dish is sweeping the area and the residents can't get enough.\nThe port will buy the ingredients at a high price", Ingredients(), 2, 7, new int[0]));
		list.Add(new Event(13, "Silk Shirt Craze", "A new fashion trend has taken hold and the port's clothiers need\nsilk to keep up with demand.", new int[1] { 28 }, 3, 7, new int[0]));
		list.Add(new Event(14, "Global Drought", "A global drought has struck and all ports have a water shortage\ndriving up prices.", new int[1] { 10 }, 4, 21, new int[1] { 999 }));
		list.Add(new Event(15, "Fishing Hook Shortage", "An explosion at the hook maker has left all ports with a fishing\nhook shortage.", new int[1] { 104 }, 5, 14, new int[1] { 999 }));
		list.Add(new Event(16, "Explosive Event", "Moments away from figuring out the how to create gold from everyday\nitems, they suffered an explosion damaging all of their materials.", new int[4] { 11, 23, 50, 55 }, 2, 14, new int[1] { 4 }));
		Events = list;
	}

	private static int[] Ingredients()
	{
		List<int> list = new List<int>
		{
			1, 2, 3, 4, 6, 7, 8, 9, 14, 15,
			16, 17, 18, 19, 25, 31, 32, 42, 43, 44,
			46, 54
		};
		List<int> list2 = new List<int> { 24, 53 };
		for (int i = 0; i < 3; i++)
		{
			int index = Random.Range(0, list.Count);
			list2.Add(list.ElementAt(index));
			list.RemoveAt(index);
		}
		return list2.ToArray();
	}
}
internal class EventPatches
{
	[HarmonyPatch(typeof(IslandMarket))]
	private class IslandMarketPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetGoodPriceAtSupply")]
		public static void EventPriceAdjust(int goodIndex, IslandMarket __instance, ref int __result)
		{
			EventPort eventPort = EventScheduler.Instance.PortsWithEvents.Where((EventPort p) => p.Index == __instance.GetPortIndex() && p.IsEventActive()).FirstOrDefault();
			Event @event = ((eventPort == null) ? null : Event.Events.Where((Event e) => e.Id == eventPort.AssignedEvent).FirstOrDefault());
			if (eventPort != null && @event.GoodIndexes.Contains(goodIndex))
			{
				__result *= @event.PriceMult;
			}
		}
	}

	[HarmonyPatch(typeof(Shopkeeper))]
	private class ShopkeeperPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetPrice")]
		public static void EventPriceAdjust(ShipItem item, Shopkeeper __instance, ref int __result)
		{
			if (!item.IsBulk())
			{
				EventPort eventPort = EventScheduler.Instance.PortsWithEvents.Where((EventPort p) => p.Index == ((Component)Refs.islands[((Component)__instance).GetComponentInParent<IslandSceneryScene>().parentIslandIndex]).GetComponentInChildren<Port>().portIndex && p.IsEventActive()).FirstOrDefault();
				Event @event = ((eventPort == null) ? null : Event.Events.Where((Event e) => e.Id == eventPort.AssignedEvent).FirstOrDefault());
				if (eventPort != null && (@event.GoodIndexes.Contains(((Component)item).gameObject.GetComponent<SaveablePrefab>().prefabIndex) || @event.GoodIndexes.Contains(Event.ItemToCrateConversion.TryGetValue(((Component)item).gameObject.GetComponent<SaveablePrefab>().prefabIndex, out var value) ? value : (-1))))
				{
					__result *= @event.PriceMult;
				}
			}
		}
	}
}
[Serializable]
public class EventPort
{
	public int Index { get; private set; }

	public string Name { get; private set; }

	public int AssignedEvent { get; set; } = -1;


	public int DayEventStarts { get; set; } = -1;


	public int DayEventEnds { get; set; } = -1;


	public EventPort(int index, string name)
	{
		Index = index;
		Name = name;
	}

	public override string ToString()
	{
		return Name ?? "";
	}

	public bool IsEventActive()
	{
		return HasAssignedEvent() && DayEventStarts <= GameState.day;
	}

	public bool HasAssignedEvent()
	{
		return AssignedEvent >= 0;
	}
}
internal sealed class EventRegion
{
	private readonly List<EventPort> _ports;

	public static readonly EventRegion AlAnkh = new EventRegion(0, "Al'Ankh", new List<EventPort>
	{
		new EventPort(0, "Gold Rock City"),
		new EventPort(1, "Al'Nilem"),
		new EventPort(2, "Neverdin"),
		new EventPort(3, "Albacore Town"),
		new EventPort(4, "Alchemist's Island"),
		new EventPort(5, "Al'Ankh Academy"),
		new EventPort(6, "Oasis"),
		new EventPort(31, "Old Ankh Town"),
		new EventPort(32, "Mirage Mountain"),
		new EventPort(33, "Saffron Island")
	});

	public static readonly EventRegion EmeraldArchipelago = new EventRegion(1, "Emerald Archipelago", new List<EventPort>
	{
		new EventPort(9, "Dragon Cliffs"),
		new EventPort(10, "Sanctuary"),
		new EventPort(11, "Crab Beach"),
		new EventPort(12, "New Port"),
		new EventPort(13, "Sage Hills"),
		new EventPort(14, "Serpent Isle"),
		new EventPort(30, "Dead Cove"),
		new EventPort(29, "Turtle Island")
	});

	public static readonly EventRegion Aestrin = new EventRegion(2, "Aestrin", new List<EventPort>
	{
		new EventPort(15, "Fort Aestrin"),
		new EventPort(16, "Sunspire"),
		new EventPort(17, "Mount Malefic"),
		new EventPort(18, "Siren Song"),
		new EventPort(19, "Eastwind"),
		new EventPort(28, "Firefly Grotto"),
		new EventPort(26, "Aestra Abbey"),
		new EventPort(27, "Fey Valley"),
		new EventPort(20, "Happy Bay"),
		new EventPort(21, "Chronos")
	});

	public static readonly EventRegion FireFishLagoon = new EventRegion(3, "Fire Fish Lagoon", new List<EventPort>
	{
		new EventPort(22, "Kicia Bay"),
		new EventPort(23, "Fire Fish Town"),
		new EventPort(24, "On'na"),
		new EventPort(25, "Sen'na")
	});

	public static readonly IReadOnlyList<EventRegion> AllRegions = new List<EventRegion> { AlAnkh, EmeraldArchipelago, Aestrin, FireFishLagoon }.AsReadOnly();

	internal int Index { get; private set; }

	internal string Name { get; private set; }

	internal IReadOnlyList<EventPort> Ports => _ports.AsReadOnly();

	public static IReadOnlyList<EventPort> AllPorts
	{
		get
		{
			List<EventPort> list = new List<EventPort>();
			foreach (EventRegion allRegion in AllRegions)
			{
				list.AddRange(allRegion.Ports);
			}
			return list.AsReadOnly();
		}
	}

	private EventRegion(int index, string name, List<EventPort> ports)
	{
		Index = index;
		Name = name;
		_ports = ports;
	}

	public override string ToString()
	{
		return Name ?? "";
	}

	public static bool AnyAssignedEvents()
	{
		return AllRegions.Any((EventRegion r) => r.HasAssignedEvent());
	}

	public bool HasAssignedEvent()
	{
		return Ports.Any((EventPort p) => p.HasAssignedEvent());
	}
}
internal class EventScheduler : MonoBehaviour
{
	public static EventScheduler Instance { get; private set; }

	internal List<EventPort> PortsWithEvents { get; private set; }

	internal Dictionary<int, int> RegionChance { get; private set; }

	public void Awake()
	{
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Expected O, but got Unknown
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		RegionChance = new Dictionary<int, int>();
		foreach (EventRegion allRegion in EventRegion.AllRegions)
		{
			RegionChance[allRegion.Index] = Configs.eventInRegionBaseChance.Value;
		}
		Event.InitializeEvents();
		PortsWithEvents = new List<EventPort>();
		Sun.OnNewDay += new NewDay(UpdateEvents);
	}

	public void UpdateEvents()
	{
		PortsWithEvents.RemoveAll(delegate(EventPort port)
		{
			if (GameState.day > port.DayEventEnds)
			{
				port.DayEventStarts = -1;
				port.DayEventEnds = -1;
				port.AssignedEvent = -1;
				EventPort eventPort = EventsUI.Instance.LoggedEventPorts.Where((EventPort ep) => ep.Index == port.Index).FirstOrDefault();
				if (eventPort != null)
				{
					EventsUI.Instance.LoggedEventPorts.Remove(eventPort);
				}
				return true;
			}
			return false;
		});
		ScheduleEvents();
	}

	public void ScheduleEvents()
	{
		if (GameState.day % 14 != 0)
		{
			return;
		}
		if (Configs.enableGlobalEvents.Value && !EventRegion.AnyAssignedEvents() && Random.Range(0, 100) < Configs.globalEventChance.Value)
		{
			ScheduleGlobalEvent();
			return;
		}
		foreach (EventRegion allRegion in EventRegion.AllRegions)
		{
			if (!allRegion.HasAssignedEvent() && Random.Range(0, 100) < RegionChance[allRegion.Index])
			{
				ScheduleEventInRegion(allRegion);
				RegionChance[allRegion.Index] = Configs.eventInRegionBaseChance.Value;
				EE_Plugin.LogDebug($"event scheduled in {allRegion.Name} region on day {GameState.day}");
			}
			if (!allRegion.HasAssignedEvent())
			{
				RegionChance[allRegion.Index] += Random.Range(5, 15);
				EE_Plugin.LogDebug($"{allRegion.Name} chance increased to {RegionChance[allRegion.Index]} on day {GameState.day}");
			}
		}
	}

	public void ScheduleGlobalEvent()
	{
		List<Event> list = Event.Events.Where((Event e) => e.SpecificPorts.Contains(999)).ToList();
		Event @event = list.ElementAt(Random.Range(0, list.Count));
		int num = GameState.day + Random.Range(0, 10);
		foreach (EventPort allPort in EventRegion.AllPorts)
		{
			allPort.AssignedEvent = @event.Id;
			allPort.DayEventStarts = num;
			allPort.DayEventEnds = num + @event.EventDuration;
			PortsWithEvents.Add(allPort);
		}
	}

	public void ScheduleEventInRegion(EventRegion region)
	{
		EventPort selectedPort = region.Ports[Random.Range(0, region.Ports.Count)];
		List<Event> list = Event.Events.Where((Event e) => e.SpecificPorts.Contains(selectedPort.Index) || e.SpecificPorts.Length == 0).ToList();
		Event @event = list.ElementAt(Random.Range(0, list.Count));
		int num = GameState.day + Random.Range(0, 10);
		selectedPort.AssignedEvent = @event.Id;
		selectedPort.DayEventStarts = num;
		selectedPort.DayEventEnds = num + @event.EventDuration;
		PortsWithEvents.Add(selectedPort);
	}

	internal void LoadPortsWithEvents(List<EventPort> portsWithEvents)
	{
		PortsWithEvents = portsWithEvents;
	}

	internal void LoadRegionChance(Dictionary<int, int> regionChance)
	{
		SaveLoadPatches.LoadDictionary(regionChance, RegionChance);
	}
}
[BepInPlugin("com.raddude82.economicevents", "EconomicEvents", "1.0.1")]
[BepInDependency("com.raddude82.modsavebackups", "1.1.1")]
public class EE_Plugin : BaseUnityPlugin
{
	public const string PLUGIN_GUID = "com.raddude82.economicevents";

	public const string PLUGIN_NAME = "EconomicEvents";

	public const string PLUGIN_VERSION = "1.0.1";

	public const string MODSAVEBACKUPS_GUID = "com.raddude82.modsavebackups";

	public const string MODSAVEBACKUPS_VERSION = "1.1.1";

	private static ManualLogSource _logger;

	internal static EE_Plugin Instance { get; private set; }

	internal static void LogDebug(string message)
	{
		_logger.LogDebug((object)message);
	}

	internal static void LogInfo(string message)
	{
		_logger.LogInfo((object)message);
	}

	internal static void LogWarning(string message)
	{
		_logger.LogWarning((object)message);
	}

	internal static void LogError(string message)
	{
		_logger.LogError((object)message);
	}

	private void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		_logger = ((BaseUnityPlugin)this).Logger;
		Configs.InitializeConfigs();
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.raddude82.economicevents");
		((Component)this).gameObject.AddComponent<EventScheduler>();
	}
}
internal class SaveLoadPatches
{
	[HarmonyPatch(typeof(SaveLoadManager))]
	private class SaveLoadManagerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("SaveModData")]
		public static void DoSaveGamePatch()
		{
			EconomicEventsSaveContainer economicEventsSaveContainer = new EconomicEventsSaveContainer
			{
				loggedEventPorts = EventsUI.Instance.LoggedEventPorts.ToList(),
				portsWithEvents = EventScheduler.Instance.PortsWithEvents.ToList(),
				regionChance = EventScheduler.Instance.RegionChance.ToDictionary((KeyValuePair<int, int> entry) => entry.Key, (KeyValuePair<int, int> entry) => entry.Value)
			};
			ModSave.Save(((BaseUnityPlugin)EE_Plugin.Instance).Info, (object)economicEventsSaveContainer);
		}

		[HarmonyPostfix]
		[HarmonyPatch("LoadModData")]
		public static void LoadModDataPatch()
		{
			EconomicEventsSaveContainer economicEventsSaveContainer = default(EconomicEventsSaveContainer);
			if (!ModSave.Load<EconomicEventsSaveContainer>(((BaseUnityPlugin)EE_Plugin.Instance).Info, ref economicEventsSaveContainer))
			{
				EE_Plugin.LogWarning("Save file loading failed. If this is the first time loading this save with this mod, this is normal.");
				return;
			}
			if (economicEventsSaveContainer.loggedEventPorts != null)
			{
				EventsUI.Instance.LoadLoggedEventPorts(economicEventsSaveContainer.loggedEventPorts);
			}
			if (economicEventsSaveContainer.portsWithEvents != null)
			{
				EventScheduler.Instance.LoadPortsWithEvents(economicEventsSaveContainer.portsWithEvents);
			}
			if (economicEventsSaveContainer.regionChance != null)
			{
				EventScheduler.Instance.LoadRegionChance(economicEventsSaveContainer.regionChance);
			}
		}
	}

	public static void LoadDictionary<T>(Dictionary<int, T> saveDict, Dictionary<int, T> gameDict)
	{
		foreach (KeyValuePair<int, T> item in saveDict)
		{
			if (!gameDict.ContainsKey(item.Key))
			{
				EE_Plugin.LogWarning($"LoadData: {item.Key} not found in game");
			}
			else
			{
				gameDict[item.Key] = item.Value;
			}
		}
	}
}
[Serializable]
public class EconomicEventsSaveContainer
{
	public List<EventPort> loggedEventPorts;

	public List<EventPort> portsWithEvents;

	public Dictionary<int, int> regionChance;
}
internal class UpdateEventsPatches
{
	[HarmonyPatch(typeof(BuyItemUI))]
	private class BuyItemUIPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		public static void CopyMenu(BuyItemUI __instance)
		{
			if (!_initialized)
			{
				_initialized = true;
				GameObject val = Object.Instantiate<GameObject>(((Component)__instance.menu.transform.parent).gameObject);
				((Object)val).name = "update events ui";
				Object.Destroy((Object)(object)val.GetComponent<BuyItemUI>());
				val.AddComponent<UpdateEventsUI>();
				Transform child = val.transform.GetChild(0);
				Object.Destroy((Object)(object)((Component)child.GetChild(0).GetChild(0)).gameObject.GetComponent<GPButtonBuyItem>());
				((Component)child.GetChild(0).GetChild(0)).gameObject.AddComponent<GPButtonUpdateEvents>();
				((Component)child.GetChild(0).GetChild(1)).GetComponent<TextMesh>().text = "update events";
				((Component)child.GetChild(1).GetChild(1)).GetComponent<TextMesh>().text = "Have you heard the latest\nnews?";
				UpdateEventsUI.Instance.UpdateEventsMenu = ((Component)child).gameObject;
			}
		}
	}

	[HarmonyPatch(typeof(PortDude))]
	private class PortDudePatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("OnTriggerEnter")]
		public static void OnTriggerEnterPatch(PortDude __instance, Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				List<EventPort> source = EventScheduler.Instance.PortsWithEvents.Where((EventPort ep) => ep.IsEventActive()).ToList();
				if (!source.All((EventPort ae) => EventsUI.Instance.LoggedEventPorts.Any((EventPort le) => le.Index == ae.Index)))
				{
					UpdateEventsUI.Instance.ActivateUI(__instance);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnTriggerExit")]
		public static void OnTriggerExitPatch(Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				UpdateEventsUI.Instance.DeactivateUI();
			}
		}
	}

	private static bool _initialized;
}
internal class EventsUI : MonoBehaviour
{
	private Dictionary<string, TextMesh> _eventTMs;

	public static EventsUI Instance { get; private set; }

	internal List<EventPort> LoggedEventPorts { get; set; }

	private void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		_eventTMs = new Dictionary<string, TextMesh>();
		LoggedEventPorts = new List<EventPort>();
	}

	public void UpdatePage()
	{
		for (int i = 0; i < 4; i++)
		{
			_eventTMs[$"event{i}"].text = string.Empty;
			_eventTMs[$"event{i}_description"].text = string.Empty;
			_eventTMs[$"event{i}_items"].text = string.Empty;
			_eventTMs[$"event{i}_multiplier"].text = string.Empty;
			_eventTMs[$"event{i}_duration"].text = string.Empty;
		}
		if (LoggedEventPorts.Count == 0)
		{
			_eventTMs["event0"].text = "No active events";
			return;
		}
		if (Event.Events.FirstOrDefault((Event e) => e.Id == LoggedEventPorts.ElementAt(0).AssignedEvent).SpecificPorts.ElementAtOrDefault(0) == 999)
		{
			UpdateTexts(0, global: true);
			return;
		}
		for (int j = 0; j < LoggedEventPorts.Count; j++)
		{
			UpdateTexts(j, global: false);
		}
	}

	private void UpdateTexts(int i, bool global)
	{
		Event @event = Event.Events.FirstOrDefault((Event e) => e.Id == LoggedEventPorts.ElementAt(i).AssignedEvent);
		string text = string.Empty;
		int[] goodIndexes = @event.GoodIndexes;
		foreach (int num in goodIndexes)
		{
			int num2 = PrefabsDirectory.GoodToItemIndex(num);
			ShipItem item = PrefabsDirectory.instance.GetItem(num2);
			item = item ?? PrefabsDirectory.instance.GetItem(num);
			text = text + "<b>" + item.name + "</b>, ";
		}
		text = text.Substring(0, text.Length - 2);
		int num3 = LoggedEventPorts.ElementAt(i).DayEventEnds - GameState.day;
		_eventTMs[$"event{i}"].text = (global ? (@event.Name ?? "") : (@event.Name + " in " + LoggedEventPorts.ElementAt(i).Name));
		_eventTMs[$"event{i}_description"].text = @event.EventText;
		_eventTMs[$"event{i}_items"].text = (global ? ("Items affected: " + text) : ("Items needed: " + text));
		_eventTMs[$"event{i}_multiplier"].text = $"Price multiplier: <b>{@event.PriceMult}X</b>";
		_eventTMs[$"event{i}_duration"].text = ((num3 == 0) ? "<b>Ends today</b>" : $"<b>Ends in {num3} days</b>");
	}

	internal void SetUIElems(Dictionary<string, TextMesh> eventTMs)
	{
		_eventTMs = eventTMs;
	}

	internal void LoadLoggedEventPorts(List<EventPort> loggedEventPorts)
	{
		LoggedEventPorts = loggedEventPorts;
	}
}
internal class LogUIPatches
{
	[HarmonyPatch(typeof(MissionListUI))]
	private class MissionListUIPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		public static void StartPatch(GameObject ___modeButtons, GameObject ___reputationUI)
		{
			eventsUI = UIBuilder.MakeEventsUI(___reputationUI, ___modeButtons);
		}

		[HarmonyBefore(new string[] { "com.raddude82.sailadex" })]
		[HarmonyPostfix]
		[HarmonyPatch("SwitchMode")]
		public static void SwitchModePatches(MissionListMode mode)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			eventsUI.SetActive(false);
			if ((int)mode == 2)
			{
				eventsUI.SetActive(true);
				EventsUI.Instance.UpdatePage();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("HideUI")]
		public static void HideUIPatches()
		{
			eventsUI.SetActive(false);
		}
	}

	private static GameObject eventsUI;
}
public class GPButtonUpdateEvents : GoPointerButton
{
	public override void OnActivate()
	{
		UpdateEventsUI.Instance.UpdateEvents();
		UpdateEventsUI.Instance.DeactivateUI();
	}
}
internal class UIBuilder
{
	private const int HEADER_FONT_SIZE = 55;

	private const int FONT_SIZE = 42;

	internal static GameObject MakeEventsUI(GameObject repUI, GameObject modeButtons)
	{
		//IL_006a: 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_0098: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_035a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0473: Unknown result type (might be due to invalid IL or missing references)
		//IL_05de: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0605: Unknown result type (might be due to invalid IL or missing references)
		//IL_061d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0731: Unknown result type (might be due to invalid IL or missing references)
		GameObject gameObject = ((Component)modeButtons.transform.GetChild(5)).gameObject;
		((Component)gameObject.transform.GetChild(0)).gameObject.GetComponent<TextMesh>().text = "events & rep";
		GameObject val = Object.Instantiate<GameObject>(repUI);
		Object.Destroy((Object)(object)val.GetComponent<ReputationUI>());
		val.transform.parent = repUI.transform.parent;
		val.transform.localPosition = repUI.transform.localPosition;
		val.transform.localRotation = repUI.transform.localRotation;
		val.transform.localScale = repUI.transform.localScale;
		((Object)val).name = "events ui";
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(1)).gameObject);
		val.AddComponent<EventsUI>();
		GameObject gameObject2 = ((Component)val.transform.GetChild(0)).gameObject;
		gameObject2.transform.localPosition = new Vector3(0.835f, -0.085f, -0.007f);
		gameObject2.GetComponent<TextMesh>().font = ((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().font;
		gameObject2.GetComponent<TextMesh>().fontSize = 42;
		gameObject2.GetComponent<TextMesh>().fontStyle = (FontStyle)1;
		gameObject2.GetComponent<TextMesh>().anchor = (TextAnchor)0;
		gameObject2.GetComponent<TextMesh>().text = string.Empty;
		((Renderer)gameObject2.GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject2.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Object)((Component)gameObject2.transform.GetChild(0)).gameObject).name = "description";
		gameObject2.transform.GetChild(0).localPosition = new Vector3(0f, -5f, 0f);
		((Component)gameObject2.transform.GetChild(0)).GetComponent<TextMesh>().font = ((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject2.transform.GetChild(0)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject2.transform.GetChild(0)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject2.transform.GetChild(0)).GetComponent<TextMesh>().text = string.Empty;
		((Renderer)((Component)gameObject2.transform.GetChild(0)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject2.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Object)((Component)gameObject2.transform.GetChild(1)).gameObject).name = "items";
		gameObject2.transform.GetChild(1).localPosition = new Vector3(0f, -17f, 0f);
		((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().text = string.Empty;
		((Object)((Component)gameObject2.transform.GetChild(2)).gameObject).name = "multiplier";
		gameObject2.transform.GetChild(2).localPosition = new Vector3(0f, -23f, 0f);
		((Component)gameObject2.transform.GetChild(2)).GetComponent<TextMesh>().font = ((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject2.transform.GetChild(2)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject2.transform.GetChild(2)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject2.transform.GetChild(2)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Renderer)((Component)gameObject2.transform.GetChild(2)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject2.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Component)gameObject2.transform.GetChild(2)).GetComponent<TextMesh>().text = string.Empty;
		((Component)gameObject2.transform.GetChild(2)).gameObject.SetActive(true);
		((Object)((Component)gameObject2.transform.GetChild(3)).gameObject).name = "duration";
		gameObject2.transform.GetChild(3).localPosition = new Vector3(0f, -29f, 0f);
		((Component)gameObject2.transform.GetChild(3)).GetComponent<TextMesh>().font = ((Component)gameObject2.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject2.transform.GetChild(3)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject2.transform.GetChild(3)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject2.transform.GetChild(3)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Renderer)((Component)gameObject2.transform.GetChild(3)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject2.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Component)gameObject2.transform.GetChild(3)).GetComponent<TextMesh>().text = string.Empty;
		((Component)gameObject2.transform.GetChild(3)).gameObject.SetActive(true);
		Dictionary<string, TextMesh> dictionary = new Dictionary<string, TextMesh>();
		for (int i = 0; i < EventRegion.AllRegions.Count; i++)
		{
			string text = $"event{i}";
			float num = 0.835f;
			GameObject val2 = Object.Instantiate<GameObject>(gameObject2);
			Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject);
			((Object)val2).name = text;
			val2.transform.parent = gameObject2.transform.parent;
			Transform transform = val2.transform;
			float num2 = 0.215f - 0.125f * (float)i;
			Vector3 localPosition = gameObject2.transform.localPosition;
			transform.localPosition = new Vector3(num, num2, ((Vector3)(ref localPosition))[2]);
			val2.transform.localRotation = gameObject2.transform.localRotation;
			val2.transform.localScale = gameObject2.transform.localScale;
			dictionary[text ?? ""] = val2.GetComponent<TextMesh>();
			dictionary[text + "_description"] = ((Component)val2.transform.GetChild(0)).GetComponent<TextMesh>();
			dictionary[text + "_items"] = ((Component)val2.transform.GetChild(1)).GetComponent<TextMesh>();
			dictionary[text + "_multiplier"] = ((Component)val2.transform.GetChild(2)).GetComponent<TextMesh>();
			dictionary[text + "_duration"] = ((Component)val2.transform.GetChild(3)).GetComponent<TextMesh>();
		}
		EventsUI.Instance.SetUIElems(dictionary);
		((Object)gameObject2).name = "events header";
		gameObject2.GetComponent<TextMesh>().text = "Economic Events";
		gameObject2.transform.localPosition = new Vector3(0.835f, 0.25f, -0.007f);
		gameObject2.GetComponent<TextMesh>().fontSize = 55;
		gameObject2.GetComponent<TextMesh>().fontStyle = (FontStyle)1;
		Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(4)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(3)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(2)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(1)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject2.transform.GetChild(0)).gameObject);
		EE_Plugin.LogInfo("Loaded events UI");
		return val;
	}
}
internal class UpdateEventsUI : MonoBehaviour
{
	internal static UpdateEventsUI Instance { get; private set; }

	internal GameObject UpdateEventsMenu { get; set; }

	private void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
		else
		{
			Instance = this;
		}
	}

	private void Update()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		if (UpdateEventsMenu.activeInHierarchy)
		{
			((Component)this).transform.rotation = ((Component)Refs.observerMirror).transform.rotation;
		}
	}

	internal void ActivateUI(PortDude portDude)
	{
		//IL_000d: 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)
		((Component)this).transform.position = ((Component)portDude).transform.position;
		((Component)this).transform.rotation = ((Component)Refs.observerMirror).transform.rotation;
		UpdateEventsMenu.SetActive(true);
	}

	internal void DeactivateUI()
	{
		UpdateEventsMenu.SetActive(false);
	}

	internal void UpdateEvents()
	{
		UISoundPlayer.instance.PlayWritingSound();
		NotificationUi.instance.ShowNotification("Logbook updated");
		EventsUI.Instance.LoggedEventPorts = (from ep in EventScheduler.Instance.PortsWithEvents
			where ep.IsEventActive()
			orderby ep.DayEventEnds
			select ep).ToList();
	}
}
internal class Configs
{
	internal static ConfigEntry<int> eventInRegionBaseChance;

	internal static ConfigEntry<bool> enableGlobalEvents;

	internal static ConfigEntry<int> globalEventChance;

	internal static void InitializeConfigs()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		ConfigFile config = ((BaseUnityPlugin)EE_Plugin.Instance).Config;
		eventInRegionBaseChance = config.Bind<int>("Settings", "BaseEventInRegionChance", 20, new ConfigDescription("Base chance for an event to occur in a region.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		enableGlobalEvents = config.Bind<bool>("Settings", "EnableGlobalEvents", true, "Enable global events that affect all ports at once. If disabled, only regional events will occur.");
		globalEventChance = config.Bind<int>("Settings", "GlobalEventChance", 5, new ConfigDescription("Chance for a global event to occur.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
	}
}