Decompiled source of EconomicEvents v1.4.0

EconomicEvents/EconomicEvents.dll

Decompiled 6 days 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 System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using cakeslice;

[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("https://github.com/bryon82/SailwindEconomicEvents")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("raddude")]
[assembly: AssemblyProduct("EconomicEvents")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("47f2429a-1581-46a0-a562-29bc48bfe982")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
namespace EconomicEvents;

internal sealed class Event
{
	private string _itemsDisplay;

	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 HashSet<int> GoodIndexSet { get; private set; }

	internal float 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, Event> EventsById { 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, float priceMult, int eventDuration, int[] ports)
	{
		Id = id;
		Name = name;
		EventText = eventText;
		GoodIndexes = goodIndexes;
		GoodIndexSet = new HashSet<int>(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 }, 3f, 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 }, 3f, 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 }, 2f, 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 }, 3f, 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 }, 3f, 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 }, 2f, 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 }, 2f, 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 }, 3f, 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 }, 2f, 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 }, 2f, 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 }, 3f, 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 }, 2f, 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(), 2f, 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 }, 3f, 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 }, 4f, 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 }, 5f, 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 }, 2f, 14, new int[1] { 4 }));
		list.Add(new Event(17, "New Tavern", "A new tavern is opening up and they need supplies to get it up\nand running.", new int[3] { 12, 36, 58 }, 2f, 14, new int[1] { 9 }));
		list.Add(new Event(18, "New Restaurant", "A new restaurant is opening up and they need supplies to get it up\nand running.", new int[4] { 11, 23, 50, 55 }, 2f, 14, new int[1] { 4 }));
		list.Add(new Event(19, "Naval Blockade", "A naval blockade has cut off trade routes. Smugglers are paying\na premium for goods that can slip through.", new int[3] { 11, 13, 28 }, 3f, 14, new int[0]));
		list.Add(new Event(20, "Monastery Brewing", "The local monastery has taken up brewing and needs supplies\nto expand their operation.", new int[3] { 12, 36, 58 }, 2f, 14, new int[0]));
		list.Add(new Event(21, "Copper Shortage", "A collapse at the main copper mine has halted production.\nPorts are scrambling for any supply.", new int[1] { 23 }, 3f, 14, new int[1] { 999 }));
		list.Add(new Event(22, "Pirate Raid", "Pirates ransacked the town's stores. The port is restocking\nessentials and will pay well for delivered goods.", new int[3] { 10, 26, 29 }, 2f, 14, new int[0]));
		list.Add(new Event(23, "Royal Visit", "Royalty is visiting the port and the locals are scrambling\nto prepare a proper feast and celebration.", new int[4] { 11, 13, 36, 58 }, 3f, 7, new int[0]));
		list.Add(new Event(24, "Tanner's Guild Strike", "The tanners have walked off the job. Fur prices have spiked\nas finished leather goods dry up.", new int[1] { 50 }, 3f, 14, new int[0]));
		list.Add(new Event(25, "Alchemist Convention", "Alchemists from across the region have gathered. They are\npaying handsomely for rare materials.", new int[4] { 20, 22, 23, 55 }, 3f, 7, new int[1] { 4 }));
		list.Add(new Event(26, "Cathedral Construction", "A grand cathedral is being built and the port needs large\nquantities of stone and materials.", new int[3] { 47, 48, 55 }, 3f, 21, new int[0]));
		list.Add(new Event(27, "Flooded Mines", "Flooding has shut down the iron mines. Smiths everywhere\nare paying top coin for any iron available.", new int[1] { 21 }, 4f, 14, new int[1] { 999 }));
		list.Add(new Event(28, "Shipwright Boom", "A surge in merchant activity has every shipyard booked solid.\nThey are buying timber at record prices.", new int[2] { 35, 47 }, 3f, 21, new int[0]));
		list.Add(new Event(29, "Scurvy Outbreak", "Scurvy has broken out among the sailors and locals alike.\nFresh fruit is being bought up as fast as it arrives.", new int[4] { 17, 44, 54, 2 }, 3f, 14, new int[0]));
		list.Add(new Event(30, "Merchants' Summit", "Trade representatives from across the region have convened.\nLuxury goods are commanding extraordinary prices.", new int[4] { 5, 20, 22, 28 }, 3f, 7, new int[0]));
		list.Add(new Event(31, "Noble Wedding", "A noble family's wedding has the whole town buying up\nfine goods, drink, and delicacies for the festivities.", new int[4] { 13, 28, 53, 54 }, 3f, 7, new int[0]));
		list.Add(new Event(32, "Counterfeit Coin Scandal", "A counterfeiting ring has been uncovered and trust in local\ncurrency has collapsed. Merchants now demand goods over gold.", new int[2] { 22, 20 }, 2f, 14, new int[0]));
		list.Add(new Event(33, "Lighthouse Repair", "The harbor lighthouse was damaged in a storm and needs\nmaterials before the next bad weather rolls in.", new int[3] { 47, 48, 21 }, 2f, 7, new int[0]));
		list.Add(new Event(34, "Wool Shortage", "A blight has struck the sheep herds. Weavers are paying\nwell for any wool or finished cloth they can find.", new int[2] { 28, 50 }, 3f, 14, new int[0]));
		list.Add(new Event(35, "Smugglers' Market", "A black market has sprung up in the back alleys, offering\nfine prices for goods no questions asked.", new int[3] { 13, 28, 22 }, 3f, 7, new int[0]));
		list.Add(new Event(36, "Apothecary Expansion", "The local apothecary is expanding and stockpiling rare\ningredients and medicines for the coming season.", new int[3] { 26, 32, 46 }, 2f, 14, new int[0]));
		list.Add(new Event(37, "Coastal Erosion", "The coastline is crumbling near the docks and engineers\nneed stone and timber for emergency reinforcement.", new int[3] { 55, 35, 47 }, 3f, 7, new int[0]));
		list.Add(new Event(38, "Bumper Harvest", "Unusually good weather has produced a record harvest. Markets\nare flooded and prices have dropped across the board.", new int[13]
		{
			1, 2, 3, 4, 7, 8, 9, 14, 15, 16,
			17, 18, 19
		}, 0.25f, 14, new int[1] { 999 }));
		list.Add(new Event(39, "Trade Fleet Arrives", "A massive merchant fleet has arrived laden with goods.\nThe sudden surplus has driven prices down.", new int[4] { 5, 13, 29, 28 }, 0.5f, 7, new int[0]));
		list.Add(new Event(40, "Mine Reopened", "A previously flooded mine has been pumped dry and production\nhas resumed, flooding the market with ore.", new int[2] { 21, 23 }, 0.333f, 14, new int[0]));
		list.Add(new Event(41, "Fishing Bonanza", "Enormous shoals of fish have moved close to shore. Fishermen\nare pulling in record catches and prices have collapsed.", new int[12]
		{
			1, 2, 4, 6, 7, 9, 19, 25, 31, 32,
			42, 43
		}, 0.5f, 21, new int[0]));
		list.Add(new Event(42, "Logging Camp Expansion", "A new logging camp has opened up production and is\nflooding the market with cheap timber.", new int[2] { 35, 47 }, 0.666f, 14, new int[0]));
		Events = list;
		EventsById = Events.ToDictionary((Event e) => e.Id, (Event e) => e);
	}

	internal string GetItemsDisplay()
	{
		if (_itemsDisplay != null)
		{
			return _itemsDisplay;
		}
		List<string> list = new List<string>(GoodIndexes.Length);
		int[] goodIndexes = GoodIndexes;
		foreach (int num in goodIndexes)
		{
			int num2 = PrefabsDirectory.GoodToItemIndex(num);
			ShipItem val = PrefabsDirectory.instance.GetItem(num2) ?? PrefabsDirectory.instance.GetItem(num);
			if ((Object)(object)val != (Object)null)
			{
				list.Add("<b>" + val.name + "</b>");
			}
		}
		_itemsDisplay = string.Join(", ", list);
		return _itemsDisplay;
	}

	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 = null;
			int portIndex = __instance.GetPortIndex();
			foreach (EventPort portsWithEvent in EventScheduler.Instance.PortsWithEvents)
			{
				if (portsWithEvent.Index == portIndex && portsWithEvent.IsEventActive())
				{
					eventPort = portsWithEvent;
					break;
				}
			}
			if (eventPort != null)
			{
				Event.EventsById.TryGetValue(eventPort.AssignedEvent, out var value);
				if (value != null && value.GoodIndexSet.Contains(goodIndex))
				{
					__result = Mathf.RoundToInt((float)__result * value.PriceMult);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Shopkeeper))]
	private class ShopkeeperPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetPrice")]
		public static void EventPriceAdjust(ShipItem item, Shopkeeper __instance, ref int __result)
		{
			if (item.IsBulk())
			{
				return;
			}
			IslandSceneryScene componentInParent = ((Component)__instance).GetComponentInParent<IslandSceneryScene>();
			int portIndex = ((Component)Refs.islands[componentInParent.parentIslandIndex]).GetComponentInChildren<Port>().portIndex;
			EventPort eventPort = null;
			foreach (EventPort portsWithEvent in EventScheduler.Instance.PortsWithEvents)
			{
				if (portsWithEvent.Index == portIndex && portsWithEvent.IsEventActive())
				{
					eventPort = portsWithEvent;
					break;
				}
			}
			if (eventPort == null)
			{
				return;
			}
			Event.EventsById.TryGetValue(eventPort.AssignedEvent, out var value);
			if (value != null)
			{
				int prefabIndex = ((Component)item).gameObject.GetComponent<SaveablePrefab>().prefabIndex;
				int value2;
				bool flag = Event.ItemToCrateConversion.TryGetValue(prefabIndex, out value2);
				if (value.GoodIndexSet.Contains(prefabIndex) || (flag && value.GoodIndexSet.Contains(value2)))
				{
					__result = Mathf.RoundToInt((float)__result * value.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;
	}

	public string SaveString()
	{
		return $"{Index}|{Name}|{AssignedEvent}|{DayEventStarts}|{DayEventEnds}";
	}
}
internal sealed class EventRegion
{
	private readonly List<EventPort> _ports;

	public static readonly EventRegion AlAnkh;

	public static readonly EventRegion EmeraldArchipelago;

	public static readonly EventRegion Aestrin;

	public static readonly EventRegion FireFishLagoon;

	public static readonly IReadOnlyList<EventRegion> AllRegions;

	private static readonly IReadOnlyList<EventPort> AllPortsList;

	private static readonly Dictionary<int, EventPort> PortsByIndex;

	internal int Index { get; private set; }

	internal string Name { get; private set; }

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

	public static IReadOnlyList<EventPort> AllPorts => AllPortsList;

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

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

	static 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")
		});
		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")
		});
		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")
		});
		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")
		});
		AllRegions = new List<EventRegion> { AlAnkh, EmeraldArchipelago, Aestrin, FireFishLagoon }.AsReadOnly();
		List<EventPort> list = new List<EventPort>();
		foreach (EventRegion allRegion in AllRegions)
		{
			list.AddRange(allRegion.Ports);
		}
		AllPortsList = list.AsReadOnly();
		PortsByIndex = list.ToDictionary((EventPort p) => p.Index, (EventPort p) => p);
	}

	public static EventPort FindPort(int index)
	{
		PortsByIndex.TryGetValue(index, out var value);
		return value;
	}

	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
{
	private readonly List<Event> _eventBuffer = new List<Event>();

	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)
			{
				return false;
			}
			port.DayEventStarts = -1;
			port.DayEventEnds = -1;
			port.AssignedEvent = -1;
			List<EventPort> loggedEventPorts = EventsUI.Instance.LoggedEventPorts;
			for (int num = loggedEventPorts.Count - 1; num >= 0; num--)
			{
				if (loggedEventPorts[num].Index == port.Index)
				{
					loggedEventPorts.RemoveAt(num);
					break;
				}
			}
			return true;
		});
		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()
	{
		_eventBuffer.Clear();
		foreach (Event @event in Event.Events)
		{
			if (@event.SpecificPorts.Contains(999))
			{
				_eventBuffer.Add(@event);
			}
		}
		if (_eventBuffer.Count == 0)
		{
			return;
		}
		Event obj = _eventBuffer[Random.Range(0, _eventBuffer.Count)];
		int num = GameState.day + Random.Range(0, 10);
		EE_Plugin.LogDebug($"event scheduled in all ports on day {GameState.day}");
		foreach (EventPort allPort in EventRegion.AllPorts)
		{
			allPort.AssignedEvent = obj.Id;
			allPort.DayEventStarts = num;
			allPort.DayEventEnds = num + obj.EventDuration;
			PortsWithEvents.Add(allPort);
		}
	}

	public void ScheduleEventInRegion(EventRegion region)
	{
		EventPort eventPort = region.Ports[Random.Range(0, region.Ports.Count)];
		_eventBuffer.Clear();
		foreach (Event @event in Event.Events)
		{
			if (@event.SpecificPorts.Length == 0 || @event.SpecificPorts.Contains(eventPort.Index))
			{
				_eventBuffer.Add(@event);
			}
		}
		if (_eventBuffer.Count != 0)
		{
			Event obj = _eventBuffer[Random.Range(0, _eventBuffer.Count)];
			int num = GameState.day + Random.Range(0, 10);
			eventPort.AssignedEvent = obj.Id;
			eventPort.DayEventStarts = num;
			eventPort.DayEventEnds = num + obj.EventDuration;
			PortsWithEvents.Add(eventPort);
		}
	}

	internal void LoadEventsScheduler()
	{
		PortsWithEvents = ModData.GetEventPortListEntry("com.raddude.economicevents.PortsWithEvents");
		ModData.GetDictEntry("com.raddude.economicevents.RegionChance", RegionChance);
	}

	internal void SaveEventsScheduler()
	{
		ModData.AddEventPortListEntry("com.raddude.economicevents.PortsWithEvents", PortsWithEvents);
		ModData.AddDictEntry("com.raddude.economicevents.RegionChance", RegionChance);
	}
}
[BepInPlugin("com.raddude.economicevents", "EconomicEvents", "1.4.0")]
public class EE_Plugin : BaseUnityPlugin
{
	public const string PLUGIN_GUID = "com.raddude.economicevents";

	public const string PLUGIN_NAME = "EconomicEvents";

	public const string PLUGIN_VERSION = "1.4.0";

	public const string SAILADEX_GUID = "com.raddude.sailadex";

	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.raddude.economicevents");
		((Component)this).gameObject.AddComponent<EventScheduler>();
	}
}
internal class SaveLoadPatches
{
	[HarmonyPatch(typeof(SaveLoadManager))]
	private class SaveLoadManagerPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("SaveModData")]
		public static void SaveModData()
		{
			EventsUI.Instance.SaveEventsUI();
			EventScheduler.Instance.SaveEventsScheduler();
		}

		[HarmonyPrefix]
		[HarmonyPatch("LoadModData")]
		public static void LoadModData()
		{
			EventsUI.Instance.LoadEventsUI();
			EventScheduler.Instance.LoadEventsScheduler();
		}
	}
}
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"))
			{
				return;
			}
			List<EventPort> loggedEventPorts = EventsUI.Instance.LoggedEventPorts;
			foreach (EventPort portsWithEvent in EventScheduler.Instance.PortsWithEvents)
			{
				if (!portsWithEvent.IsEventActive())
				{
					continue;
				}
				bool flag = false;
				for (int i = 0; i < loggedEventPorts.Count; i++)
				{
					if (loggedEventPorts[i].Index == portsWithEvent.Index)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					continue;
				}
				UpdateEventsUI.Instance.ActivateUI(__instance);
				break;
			}
		}

		[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.EventsById.TryGetValue(LoggedEventPorts[0].AssignedEvent, out var value) && value.SpecificPorts.Length != 0 && value.SpecificPorts[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)
	{
		if (Event.EventsById.TryGetValue(LoggedEventPorts[i].AssignedEvent, out var value))
		{
			string itemsDisplay = value.GetItemsDisplay();
			int num = LoggedEventPorts[i].DayEventEnds - GameState.day;
			_eventTMs[$"event{i}"].text = (global ? (value.Name ?? "") : (value.Name + " in " + LoggedEventPorts[i].Name));
			_eventTMs[$"event{i}_description"].text = value.EventText;
			_eventTMs[$"event{i}_items"].text = (global ? ("Items affected: " + itemsDisplay) : ("Items needed: " + itemsDisplay));
			_eventTMs[$"event{i}_multiplier"].text = $"Price multiplier: <b>{value.PriceMult}X</b>";
			_eventTMs[$"event{i}_duration"].text = ((num == 0) ? "<b>Ends today</b>" : $"<b>Ends in {num} days</b>");
		}
	}

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

	internal void SaveEventsUI()
	{
		ModData.AddEventPortListEntry("com.raddude.economicevents.LoggedEventPorts", LoggedEventPorts);
	}

	internal void LoadEventsUI()
	{
		LoggedEventPorts = ModData.GetEventPortListEntry("com.raddude.economicevents.LoggedEventPorts");
	}
}
internal class LogUIPatches
{
	[HarmonyPatch(typeof(MissionListUI))]
	private class MissionListUIPatches
	{
		[HarmonyAfter(new string[] { "com.raddude.sailadex" })]
		[HarmonyPrefix]
		[HarmonyPatch("Start")]
		public static void StartPatch(GameObject ___modeButtons, ref GPButtonLogMode[] ___logModeButtons, GameObject ___reputationUI)
		{
			List<GPButtonLogMode> existingLogModeButtons = new List<GPButtonLogMode>(___logModeButtons);
			logModeButtons = UIBuilder.MakeBookmark(___modeButtons, existingLogModeButtons);
			eventsUI = UIBuilder.MakeEventsUI(___reputationUI);
			___logModeButtons = logModeButtons;
		}

		[HarmonyAfter(new string[] { "com.raddude.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 == 8)
			{
				eventsUI.SetActive(true);
				EventsUI.Instance.UpdatePage();
			}
		}

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

	private static GameObject eventsUI;

	private static GPButtonLogMode[] logModeButtons;
}
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 const MissionListMode EVENTS = (MissionListMode)8;

	internal static GPButtonLogMode[] MakeBookmark(GameObject modeButtons, List<GPButtonLogMode> existingLogModeButtons)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		GameObject gameObject = ((Component)modeButtons.transform.GetChild(9)).gameObject;
		GameObject val = Object.Instantiate<GameObject>(gameObject);
		val.transform.parent = modeButtons.transform;
		val.transform.localPosition = new Vector3(-0.515f, -0.0032f, 0.071f);
		val.transform.localRotation = Quaternion.Euler(270f, 180f, 0f);
		val.transform.localScale = gameObject.transform.localScale;
		((Object)val).name = "bookmark events";
		((Component)val.transform.GetChild(0)).gameObject.GetComponent<TextMesh>().text = "events";
		val.transform.GetChild(0).localRotation = Quaternion.Euler(0f, 180f, 180f);
		GPButtonLogMode component = val.GetComponent<GPButtonLogMode>();
		Traverse.Create((object)component).Field("mode").SetValue((object)(MissionListMode)8);
		Traverse.Create((object)component).Field("inactiveLocalPos").SetValue((object)new Vector3(-0.515f, -0.0032f, 0.071f));
		Traverse.Create((object)component).Field("activeLocalPos").SetValue((object)new Vector3(-0.51f, 0.0072f, 0.063f));
		Object.Destroy((Object)(object)val.GetComponent<Outline>());
		existingLogModeButtons.Add(component);
		return existingLogModeButtons.ToArray();
	}

	internal static GameObject MakeEventsUI(GameObject repUI)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0504: Unknown result type (might be due to invalid IL or missing references)
		//IL_066c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0671: Unknown result type (might be due to invalid IL or missing references)
		//IL_067b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0693: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bc: Unknown result type (might be due to invalid IL or missing references)
		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(7)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(6)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(5)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(4)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(3)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(2)).gameObject);
		Object.Destroy((Object)(object)((Component)val.transform.GetChild(0)).gameObject);
		val.AddComponent<EventsUI>();
		GameObject gameObject = ((Component)val.transform.GetChild(1)).gameObject;
		gameObject.SetActive(true);
		gameObject.transform.localPosition = new Vector3(0.835f, -0.085f, -0.007f);
		gameObject.GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
		gameObject.GetComponent<TextMesh>().fontSize = 42;
		gameObject.GetComponent<TextMesh>().characterSize = 1f;
		gameObject.GetComponent<TextMesh>().fontStyle = (FontStyle)1;
		gameObject.GetComponent<TextMesh>().anchor = (TextAnchor)0;
		gameObject.GetComponent<TextMesh>().text = string.Empty;
		((Renderer)gameObject.GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Object)((Component)gameObject.transform.GetChild(0)).gameObject).name = "description";
		gameObject.transform.GetChild(0).localPosition = new Vector3(0f, -5f, 0f);
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().characterSize = 1f;
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().lineSpacing = 1f;
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject.transform.GetChild(0)).GetComponent<TextMesh>().text = string.Empty;
		((Renderer)((Component)gameObject.transform.GetChild(0)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Object)((Component)gameObject.transform.GetChild(1)).gameObject).name = "items";
		gameObject.transform.GetChild(1).localPosition = new Vector3(0f, -17f, 0f);
		((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().text = string.Empty;
		((Object)((Component)gameObject.transform.GetChild(2)).gameObject).name = "multiplier";
		gameObject.transform.GetChild(2).localPosition = new Vector3(0f, -23f, 0f);
		((Component)gameObject.transform.GetChild(2)).GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject.transform.GetChild(2)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject.transform.GetChild(2)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject.transform.GetChild(2)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Renderer)((Component)gameObject.transform.GetChild(2)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Component)gameObject.transform.GetChild(2)).GetComponent<TextMesh>().text = string.Empty;
		((Component)gameObject.transform.GetChild(2)).gameObject.SetActive(true);
		((Object)((Component)gameObject.transform.GetChild(3)).gameObject).name = "duration";
		gameObject.transform.GetChild(3).localPosition = new Vector3(0f, -29f, 0f);
		((Component)gameObject.transform.GetChild(3)).GetComponent<TextMesh>().font = ((Component)gameObject.transform.GetChild(1)).GetComponent<TextMesh>().font;
		((Component)gameObject.transform.GetChild(3)).GetComponent<TextMesh>().fontSize = 42;
		((Component)gameObject.transform.GetChild(3)).GetComponent<TextMesh>().anchor = (TextAnchor)0;
		((Component)gameObject.transform.GetChild(3)).GetComponent<TextMesh>().fontStyle = (FontStyle)0;
		((Renderer)((Component)gameObject.transform.GetChild(3)).GetComponent<MeshRenderer>()).material = ((Renderer)((Component)gameObject.transform.GetChild(1)).GetComponent<MeshRenderer>()).material;
		((Component)gameObject.transform.GetChild(3)).GetComponent<TextMesh>().text = string.Empty;
		((Component)gameObject.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>(gameObject);
			Object.Destroy((Object)(object)((Component)val2.transform.GetChild(4)).gameObject);
			((Object)val2).name = text;
			val2.transform.parent = gameObject.transform.parent;
			Transform transform = val2.transform;
			float num2 = 0.215f - 0.125f * (float)i;
			Vector3 localPosition = gameObject.transform.localPosition;
			transform.localPosition = new Vector3(num, num2, ((Vector3)(ref localPosition))[2]);
			val2.transform.localRotation = gameObject.transform.localRotation;
			val2.transform.localScale = gameObject.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)gameObject).name = "events header";
		gameObject.GetComponent<TextMesh>().text = "Economic Events";
		gameObject.transform.localPosition = new Vector3(0.835f, 0.25f, -0.007f);
		gameObject.GetComponent<TextMesh>().fontSize = 55;
		gameObject.GetComponent<TextMesh>().fontStyle = (FontStyle)1;
		Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(4)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(3)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(2)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject.transform.GetChild(1)).gameObject);
		Object.Destroy((Object)(object)((Component)gameObject.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>()));
	}
}
internal class ModData
{
	public static void AddDictEntry<K, T>(string dataName, Dictionary<K, T> data)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (KeyValuePair<K, T> datum in data)
		{
			stringBuilder.AppendLine($"{datum.Key}|{datum.Value}");
		}
		string value = stringBuilder.ToString();
		if (GameState.modData.ContainsKey(dataName))
		{
			GameState.modData[dataName] = value;
		}
		else
		{
			GameState.modData.Add(dataName, value);
		}
	}

	public static void GetDictEntry<K, T>(string dataName, Dictionary<K, T> gameDict)
	{
		if (!GameState.modData.ContainsKey(dataName))
		{
			EE_Plugin.LogWarning("LoadDictFromModData: " + dataName + " not found in modData");
			return;
		}
		string text = GameState.modData[dataName];
		string[] array = text.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			string[] array3 = text2.Trim().Split(new char[1] { '|' });
			if (array3.Length >= 2)
			{
				K val = (K)Convert.ChangeType(array3[0], typeof(K));
				if (!gameDict.ContainsKey(val))
				{
					EE_Plugin.LogWarning($"LoadDictFromModData: {val} not found in game");
				}
				else
				{
					gameDict[val] = (T)Convert.ChangeType(array3[1], typeof(T));
				}
			}
		}
	}

	public static void AddEventPortListEntry(string dataName, List<EventPort> data)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (EventPort datum in data)
		{
			stringBuilder.AppendLine(datum.SaveString() ?? "");
		}
		string value = stringBuilder.ToString();
		if (GameState.modData.ContainsKey(dataName))
		{
			GameState.modData[dataName] = value;
		}
		else
		{
			GameState.modData.Add(dataName, value);
		}
	}

	public static List<EventPort> GetEventPortListEntry(string dataName)
	{
		List<EventPort> list = new List<EventPort>();
		if (!GameState.modData.ContainsKey(dataName))
		{
			EE_Plugin.LogWarning("GetModDataEntry: " + dataName + " not found in modData");
			return list;
		}
		string text = GameState.modData[dataName];
		string[] array = text.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			string[] array3 = text2.Trim().Split(new char[1] { '|' });
			if (array3.Length >= 5)
			{
				EventPort item = new EventPort(int.Parse(array3[0]), array3[1])
				{
					AssignedEvent = int.Parse(array3[2]),
					DayEventStarts = int.Parse(array3[3]),
					DayEventEnds = int.Parse(array3[4])
				};
				list.Add(item);
			}
		}
		return list;
	}
}