Decompiled source of IntelligentDialogue v1.1.0

IntelligentDialogue.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using FishNet.Object;
using HarmonyLib;
using IntelligentDialogue;
using MelonLoader;
using Newtonsoft.Json.Linq;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Economy;
using ScheduleOne.Employees;
using ScheduleOne.GameTime;
using ScheduleOne.NPCs;
using ScheduleOne.Persistence;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Police;
using ScheduleOne.VoiceOver;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
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: MelonInfo(typeof(global::IntelligentDialogue.IntelligentDialogue), "IntelligentDialogue", "1.1", "XOWithSauce", null)]
[assembly: MelonColor]
[assembly: MelonOptionalDependencies(new string[] { "FishNet.Runtime" })]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("IntelligentDialogue")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("IntelligentDialogue")]
[assembly: AssemblyTitle("IntelligentDialogue")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace IntelligentDialogue;

public static class BuildInfo
{
	public const string Name = "IntelligentDialogue";

	public const string Description = "Smart!";

	public const string Author = "XOWithSauce";

	public const string Company = null;

	public const string Version = "1.1";

	public const string DownloadLink = null;
}
public delegate void RoleActionDelegate(NPC npc);
public class Role
{
	public Dictionary<int, RoleActionDelegate> Actions = new Dictionary<int, RoleActionDelegate>();

	public List<string> Descriptions = new List<string>();

	public List<string> Moods = new List<string>();

	public string Name { get; set; }
}
public static class RoleRegistry
{
	public static Dictionary<string, Role> Roles = new Dictionary<string, Role>();

	public static void Initialize()
	{
		Roles["Employee"] = new Role
		{
			Name = "Employee",
			Actions = new Dictionary<int, RoleActionDelegate>
			{
				{ 1, EmployeeAction1 },
				{ 2, EmployeeAction2 },
				{ 3, EmployeeAction3 },
				{ 4, EmployeeAction4 },
				{ 5, EmployeeAction5 }
			},
			Descriptions = new List<string> { "Action1 (Make Suprised sound), ", "Action2 (Make Disagreeing sound), ", "Action3 (Start being annoyed), ", "Action4 (Try resigning from the job), ", "Action5 (Increase your Daily Wage), " },
			Moods = new List<string> { "Stressed about deadlines", "Pretending to care", "Trying to stay positive", "Counting minutes to lunch break", "Annoyed by management" }
		};
		Roles["Officer"] = new Role
		{
			Name = "Officer",
			Actions = new Dictionary<int, RoleActionDelegate>
			{
				{ 1, OfficerAction1 },
				{ 2, OfficerAction2 },
				{ 3, OfficerAction3 },
				{ 4, OfficerAction4 },
				{ 5, OfficerAction5 }
			},
			Descriptions = new List<string> { "Action1 (Talk to Police Radio), ", "Action2 (Make sounds that command the player), ", "Action3 (Increase Suspicion level), ", "Action4 (Player committed crime, try to arrest), ", "Action5 (Body search the nearest Player), " },
			Moods = new List<string> { "Suspicious of everyone", "Calm but alert", "Tired of crime", "In command mode", "Ready to escalate" }
		};
		Roles["Dealer"] = new Role
		{
			Name = "Dealer",
			Actions = new Dictionary<int, RoleActionDelegate>
			{
				{ 1, DealerAction1 },
				{ 2, DealerAction2 },
				{ 3, DealerAction3 },
				{ 4, DealerAction4 },
				{ 5, DealerAction5 }
			},
			Descriptions = new List<string> { "Action1 (Increase aggression), ", "Action2 (Make Annoyed sounds), ", "Action3 (Make Thinking sounds), ", "Action4 (Decrease Dealer Payment Cut), ", "Action5 (Increase Dealer Payment Cut), " },
			Moods = new List<string> { "Paranoid", "Smooth-talking", "Cocky and overconfident", "On edge", "Chill but watching you" }
		};
		Roles["Citizen"] = new Role
		{
			Name = "Citizen",
			Actions = new Dictionary<int, RoleActionDelegate>
			{
				{ 1, CitizenAction1 },
				{ 2, CitizenAction2 },
				{ 3, CitizenAction3 },
				{ 4, CitizenAction4 },
				{ 5, CitizenAction5 }
			},
			Descriptions = new List<string> { "Action1 (Start Panicking), ", "Action2 (Thank the Player), ", "Action3 (Make Acknowledge sounds), ", "Action4 (Fall down Funnily), ", "Action5 (Walk away), " },
			Moods = new List<string> { "Worried about safety", "Happy and satisfied", "Innocent and curious", "Fed up with the system", "Friendly but cautious" }
		};
	}

	private static void EmployeeAction1(NPC npc)
	{
		npc.PlayVO((EVOLineType)11);
	}

	private static void EmployeeAction2(NPC npc)
	{
		npc.PlayVO((EVOLineType)17);
	}

	private static void EmployeeAction3(NPC npc)
	{
		npc.Avatar.EmotionManager.AddEmotionOverride("Annoyed", "base_emotion", 0f, 0);
		npc.PlayVO((EVOLineType)9);
	}

	private static void EmployeeAction4(NPC npc)
	{
		if (Random.Range(0, 100) >= 70)
		{
			Employee obj = (Employee)(object)((npc is Employee) ? npc : null);
			typeof(Employee).GetMethod("Fire", BindingFlags.Instance | BindingFlags.NonPublic)?.Invoke(obj, null);
		}
	}

	private static void EmployeeAction5(NPC npc)
	{
		Employee val = (Employee)(object)((npc is Employee) ? npc : null);
		if (val.DailyWage < 2000f)
		{
			val.DailyWage += 50f;
		}
	}

	private static void OfficerAction1(NPC npc)
	{
		npc.PlayVO((EVOLineType)13);
	}

	private static void OfficerAction2(NPC npc)
	{
		npc.PlayVO((EVOLineType)2);
	}

	private static void OfficerAction3(NPC npc)
	{
		PoliceOfficer val = (PoliceOfficer)(object)((npc is PoliceOfficer) ? npc : null);
		if (val.Suspicion < 0.95f)
		{
			val.Suspicion += 0.05f;
		}
	}

	private static void OfficerAction4(NPC npc)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		PoliceOfficer val = (PoliceOfficer)(object)((npc is PoliceOfficer) ? npc : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		float num = default(float);
		Player closestPlayer = Player.GetClosestPlayer(((Component)val).transform.position, ref num, (List<Player>)null);
		if (!((Object)(object)closestPlayer != (Object)null))
		{
			return;
		}
		try
		{
			closestPlayer.CrimeData.SetPursuitLevel((EPursuitLevel)2);
			val.BeginFootPursuit_Networked(((NetworkBehaviour)closestPlayer).NetworkObject, false);
		}
		catch (Exception)
		{
		}
	}

	private static void OfficerAction5(NPC npc)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		PoliceOfficer val = (PoliceOfficer)(object)((npc is PoliceOfficer) ? npc : null);
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		float num = default(float);
		Player closestPlayer = Player.GetClosestPlayer(((Component)val).transform.position, ref num, (List<Player>)null);
		if (!((Object)(object)closestPlayer != (Object)null))
		{
			return;
		}
		try
		{
			closestPlayer.CrimeData.SetPursuitLevel((EPursuitLevel)0);
			val.BeginBodySearch_Networked(((NetworkBehaviour)closestPlayer).NetworkObject);
		}
		catch (Exception)
		{
		}
	}

	private static void DealerAction1(NPC npc)
	{
		npc.OverrideAggression(1f);
	}

	private static void DealerAction2(NPC npc)
	{
		npc.PlayVO((EVOLineType)9);
	}

	private static void DealerAction3(NPC npc)
	{
		npc.PlayVO((EVOLineType)19);
	}

	private static void DealerAction4(NPC npc)
	{
		Dealer val = (Dealer)(object)((npc is Dealer) ? npc : null);
		if (val.Cut > 0.05f)
		{
			val.Cut -= 0.05f;
		}
	}

	private static void DealerAction5(NPC npc)
	{
		Dealer val = (Dealer)(object)((npc is Dealer) ? npc : null);
		if (val.Cut < 0.7f)
		{
			val.Cut += 0.05f;
		}
	}

	private static void CitizenAction1(NPC npc)
	{
		npc.SetPanicked();
	}

	private static void CitizenAction2(NPC npc)
	{
		npc.PlayVO((EVOLineType)3);
	}

	private static void CitizenAction3(NPC npc)
	{
		npc.PlayVO((EVOLineType)14);
	}

	private static void CitizenAction4(NPC npc)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		npc.Movement.ActivateRagdoll(((Component)npc).transform.position, Vector3.forward, 3f);
	}

	private static void CitizenAction5(NPC npc)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: 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)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Random.insideUnitSphere * 5f;
		val.y = 0f;
		Vector3 val2 = ((Component)npc).transform.position + val;
		Vector3 destination = default(Vector3);
		if (npc.Movement.GetClosestReachablePoint(val2, ref destination))
		{
			npc.Movement.SetDestination(destination);
			npc.Movement.ResumeMovement();
		}
	}
}
public class IntelligentDialogue : MelonMod
{
	[HarmonyPatch(typeof(DialogueHandler), "InitializeDialogue", new Type[] { typeof(DialogueContainer) })]
	public static class Patch_InitDialogue_Container
	{
		public static bool Prefix(DialogueHandler __instance, DialogueContainer container)
		{
			return HandleDialogueInit(__instance);
		}
	}

	[HarmonyPatch(typeof(DialogueHandler), "InitializeDialogue", new Type[]
	{
		typeof(DialogueContainer),
		typeof(bool),
		typeof(string)
	})]
	public static class Patch_InitDialogue_ContainerBoolString
	{
		public static bool Prefix(DialogueHandler __instance, DialogueContainer dialogueContainer, bool enableDialogueBehaviour = true, string entryNodeLabel = "ENTRY")
		{
			return HandleDialogueInit(__instance);
		}
	}

	[HarmonyPatch(typeof(DialogueHandler), "InitializeDialogue", new Type[]
	{
		typeof(string),
		typeof(bool),
		typeof(string)
	})]
	public static class Patch_InitDialogue_StringBoolString
	{
		public static bool Prefix(DialogueHandler __instance, string dialogueContainerName, bool enableDialogueBehaviour = true, string entryNodeLabel = "ENTRY")
		{
			return HandleDialogueInit(__instance);
		}
	}

	[HarmonyPatch(typeof(DialogueHandler), "EndDialogue")]
	public static class Diag_EndDiag_Patch
	{
		public static bool Prefix(DialogueHandler __instance)
		{
			((Selectable)_userInputField).interactable = false;
			((Selectable)_apiKeyInputField).interactable = false;
			conversantRole = "";
			conversantAdditional = "";
			conversantRelationStatus = "";
			conversantNpc = null;
			((TMP_Text)respComponent).text = "";
			return true;
		}
	}

	public class SnapshotCamera : MonoBehaviour
	{
		private Camera cam;

		private SnapshotCamera()
		{
		}

		public static SnapshotCamera MakeSnapshotCamera(Transform tr, string name = "Snapshot Camera")
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			Camera val2 = val.AddComponent<Camera>();
			val2.orthographic = false;
			val2.orthographicSize = 1f;
			val2.clearFlags = (CameraClearFlags)2;
			val2.backgroundColor = Color.clear;
			val2.nearClipPlane = 0.1f;
			((Behaviour)val2).enabled = false;
			val.transform.parent = tr;
			val.transform.localPosition = Vector3.zero + Vector3.forward * 1.02f;
			Transform transform = val.transform;
			transform.localPosition += Vector3.up * 1.78f;
			float num = default(float);
			Vector3 position = ((Component)Player.GetClosestPlayer(val.transform.position, ref num, (List<Player>)null)).transform.position;
			val.transform.LookAt(position + Vector3.up * 1.06f);
			SnapshotCamera snapshotCamera = val.AddComponent<SnapshotCamera>();
			snapshotCamera.cam = val2;
			return snapshotCamera;
		}

		public Texture2D TakeSnapshot(Color backgroundColor, int width, int height)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			cam.backgroundColor = backgroundColor;
			cam.targetTexture = RenderTexture.GetTemporary(width, height, 24);
			cam.Render();
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = cam.targetTexture;
			Texture2D val = new Texture2D(((Texture)cam.targetTexture).width, ((Texture)cam.targetTexture).height, (TextureFormat)5, false);
			val.ReadPixels(new Rect(0f, 0f, (float)((Texture)cam.targetTexture).width, (float)((Texture)cam.targetTexture).height), 0, 0);
			val.Apply(false);
			RenderTexture.active = active;
			cam.targetTexture = null;
			RenderTexture.ReleaseTemporary(cam.targetTexture);
			return val;
		}
	}

	[CompilerGenerated]
	private sealed class <ResponseCb>d__29 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string response;

		public IntelligentDialogue <>4__this;

		private string <pattern>5__1;

		private Match <match>5__2;

		private string <speech>5__3;

		private string <action>5__4;

		private int <actionId>5__5;

		private Role <role>5__6;

		private RoleActionDelegate <actionFn>5__7;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ResponseCb>d__29(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<pattern>5__1 = null;
			<match>5__2 = null;
			<speech>5__3 = null;
			<action>5__4 = null;
			<role>5__6 = null;
			<actionFn>5__7 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<pattern>5__1 = "\\[Speech\\]\\s*(?<speech>[^[]+?)\\s*\\[Action\\]\\s*(?<action>[^\\[\\]]+)";
				<match>5__2 = Regex.Match(response, <pattern>5__1);
				<speech>5__3 = <match>5__2.Groups["speech"].Value.Trim();
				<action>5__4 = <match>5__2.Groups["action"].Value.Trim();
				if ((Object)(object)_responseTextField != (Object)null)
				{
					_responseTextField.text = <speech>5__3;
				}
				if (int.TryParse(<action>5__4.Substring(6), out <actionId>5__5))
				{
					if (string.IsNullOrEmpty(conversantRole))
					{
						return false;
					}
					if (RoleRegistry.Roles.TryGetValue(conversantRole, out <role>5__6) && <role>5__6.Actions.TryGetValue(<actionId>5__5, out <actionFn>5__7))
					{
						<actionFn>5__7(conversantNpc);
					}
					<role>5__6 = null;
					<actionFn>5__7 = null;
				}
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <SendRequestToGeminiWithImage>d__30 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string prompt;

		public Action<string> onResponse;

		public IntelligentDialogue <>4__this;

		private string <urlWithKey>5__1;

		private Transform <npcTransform>5__2;

		private string <systemInstruction>5__3;

		private SnapshotCamera <snapshotCamera>5__4;

		private Texture2D <snapshot>5__5;

		private byte[] <imageBytes>5__6;

		private string <mimeType>5__7;

		private string <base64Image>5__8;

		private string <jsonPayload>5__9;

		private UnityWebRequest <request>5__10;

		private byte[] <bodyRaw>5__11;

		private string <responseText>5__12;

		private JObject <jsonResponse>5__13;

		private string <generatedText>5__14;

		private Exception <e>5__15;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <SendRequestToGeminiWithImage>d__30(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			int num = <>1__state;
			if (num == -3 || num == 1)
			{
				try
				{
				}
				finally
				{
					<>m__Finally1();
				}
			}
			<urlWithKey>5__1 = null;
			<npcTransform>5__2 = null;
			<systemInstruction>5__3 = null;
			<snapshotCamera>5__4 = null;
			<snapshot>5__5 = null;
			<imageBytes>5__6 = null;
			<mimeType>5__7 = null;
			<base64Image>5__8 = null;
			<jsonPayload>5__9 = null;
			<request>5__10 = null;
			<bodyRaw>5__11 = null;
			<responseText>5__12 = null;
			<jsonResponse>5__13 = null;
			<generatedText>5__14 = null;
			<e>5__15 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0099: 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_0165: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Invalid comparison between Unknown and I4
			try
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<urlWithKey>5__1 = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=" + <>4__this._geminiApiKey;
					<npcTransform>5__2 = ((Component)conversantNpc).transform;
					<systemInstruction>5__3 = <>4__this.GetPromptEmbed();
					if ((Object)(object)<npcTransform>5__2 == (Object)null)
					{
						return false;
					}
					<snapshotCamera>5__4 = SnapshotCamera.MakeSnapshotCamera(<npcTransform>5__2, "NPCSnapshotCamera");
					<snapshot>5__5 = <snapshotCamera>5__4.TakeSnapshot(Color.clear, 1920, 1080);
					Object.Destroy((Object)(object)((Component)<snapshotCamera>5__4).gameObject);
					<imageBytes>5__6 = ImageConversion.EncodeToJPG(<snapshot>5__5, 8);
					<mimeType>5__7 = "image/jpg";
					<base64Image>5__8 = Convert.ToBase64String(<imageBytes>5__6);
					<jsonPayload>5__9 = "{\r\n              \"system_instruction\": {\r\n                \"parts\": [\r\n                  {\r\n                    \"text\": \"" + <systemInstruction>5__3 + "\"\r\n                  }\r\n                ]\r\n              },\r\n              \"contents\": [\r\n                {\r\n                  \"parts\": [\r\n                    {\r\n                      \"inline_data\": {\r\n                        \"mime_type\": \"" + <mimeType>5__7 + "\",\r\n                        \"data\": \"" + <base64Image>5__8 + "\"\r\n                      }\r\n                    },\r\n                    {\r\n                      \"text\": \"" + prompt + "\"\r\n                    }\r\n                  ]\r\n                }\r\n              ],\r\n              \"generationConfig\": {\r\n                \"temperature\": 1.5,\r\n                \"maxOutputTokens\": 350,\r\n                \"topP\": 0.25,\r\n                \"topK\": 30\r\n              }\r\n            }";
					<request>5__10 = new UnityWebRequest(<urlWithKey>5__1, "POST");
					<>1__state = -3;
					<bodyRaw>5__11 = Encoding.UTF8.GetBytes(<jsonPayload>5__9);
					<request>5__10.uploadHandler = (UploadHandler)new UploadHandlerRaw(<bodyRaw>5__11);
					<request>5__10.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
					<request>5__10.SetRequestHeader("Content-Type", "application/json");
					<>2__current = <request>5__10.SendWebRequest();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -3;
					if ((int)<request>5__10.result != 1)
					{
						MelonLogger.Error("Gemini API request failed: " + <request>5__10.error);
						onResponse?.Invoke("Gemini API error: " + <request>5__10.error);
					}
					else
					{
						<responseText>5__12 = <request>5__10.downloadHandler.text;
						try
						{
							<jsonResponse>5__13 = JObject.Parse(<responseText>5__12);
							<generatedText>5__14 = ((object)<jsonResponse>5__13["candidates"][(object)0][(object)"content"][(object)"parts"][(object)0][(object)"text"]).ToString().Trim();
							onResponse?.Invoke(<generatedText>5__14);
							<jsonResponse>5__13 = null;
							<generatedText>5__14 = null;
						}
						catch (Exception ex)
						{
							<e>5__15 = ex;
							MelonLogger.Error("Error parsing Gemini response: " + <e>5__15.Message + "\nResponse: " + <responseText>5__12);
							onResponse?.Invoke("Failed to parse Gemini API response.");
						}
						<responseText>5__12 = null;
					}
					<bodyRaw>5__11 = null;
					<>m__Finally1();
					<request>5__10 = null;
					Object.Destroy((Object)(object)<snapshot>5__5);
					return false;
				}
			}
			catch
			{
				//try-fault
				((IDisposable)this).Dispose();
				throw;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		private void <>m__Finally1()
		{
			<>1__state = -1;
			if (<request>5__10 != null)
			{
				((IDisposable)<request>5__10).Dispose();
			}
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private string _geminiApiKey = "";

	private string _userInput = "";

	private GameObject _dialogueCanvas;

	public static TMP_InputField _apiKeyInputField;

	public static TMP_InputField _userInputField;

	public static TMP_InputField _responseTextField;

	public static TextMeshProUGUI respComponent;

	private const string GeminiGenerateContentUrl = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent";

	private bool registered = false;

	public static string conversantRole;

	public static NPC conversantNpc;

	public static string conversantFirstName;

	public static string conversantRelationStatus;

	public static string conversantAdditional;

	private string hiddenInstruction = "You are a professional actor in a criminal movie set in the fictional town of Hyland Point. You must stay in character at all times based on the role and scene description provided. Interpret any provided image as first-person imagery, representing what you, the character, are currently seeing. Always reply in the same language as the user latest dialogue. All sentences must begin directly with meaningful language and contribute to the scene or role. Match the language used in the latest message. Stay consistent with tone and style. The world includes Officers, Drug Dealers, Employees, and Citizens, each with their own slang, attitude, and speech style. Offense, slang, and criminal tone are allowed this is part of the setting. Responses must be expressive and natural, not robotic or abrupt. Always use immersive, character-fitting language in your reply. All Speech responses must be less than 300 characters and between 1-3 sentences. All Speech responses must be full paragraphs. You may only use letters, numbers, and the following punctuation: period (.), exclamation (!), question mark (?), comma (,), and apostrophe ('). Every reply must contain two parts: 1. [Speech] A vivid in-character line of dialogue. 2. [Action] One Action ID (e.g., Action1 to Action5) OR 'Action0' to indicate no action. Fill Actions response by choosing the correct Action from the given role actions. Even if no fitting action exists, you must still reply with an [Action] tag using 'Action0'. Always include the [Action] field. Example format: [Speech] This is a response to user dialogue. [Action] Action2 \n";

	public override void OnInitializeMelon()
	{
		RoleRegistry.Initialize();
	}

	private bool EnforcesInternalRules(string response)
	{
		if (response.Length > 350)
		{
			return false;
		}
		if (!response.Contains("[Speech]"))
		{
			return false;
		}
		if (!response.Contains("[Action]"))
		{
			return false;
		}
		string pattern = "\\[Speech\\]\\s*(?<speech>[^[]+)\\s*\\[Action\\]\\s*(?<action>.+)";
		Match match = Regex.Match(response, pattern);
		if (!match.Success)
		{
			return false;
		}
		if (match.Groups.Count != 3)
		{
			return false;
		}
		string input = match.Groups["action"].Value.Trim();
		if (!Regex.IsMatch(input, "^Action[0-5]$"))
		{
			return false;
		}
		return true;
	}

	public override void OnSceneWasInitialized(int buildIndex, string sceneName)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Expected O, but got Unknown
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Expected O, but got Unknown
		if (buildIndex == 1)
		{
			if ((Object)(object)Singleton<LoadManager>.Instance != (Object)null && !registered)
			{
				Singleton<LoadManager>.Instance.onLoadComplete.AddListener(new UnityAction(OnLoadCompleteCb));
			}
			return;
		}
		if ((Object)(object)Singleton<LoadManager>.Instance != (Object)null && registered)
		{
			Singleton<LoadManager>.Instance.onLoadComplete.RemoveListener(new UnityAction(OnLoadCompleteCb));
		}
		registered = false;
	}

	private void OnLoadCompleteCb()
	{
		if (!registered)
		{
			_dialogueCanvas = GameObject.Find("DialogueCanvas");
			if (!((Object)(object)_dialogueCanvas == (Object)null))
			{
				CreateGeminiUI();
				registered = true;
			}
		}
	}

	private static bool HandleDialogueInit(DialogueHandler __instance)
	{
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		((Selectable)_userInputField).interactable = true;
		((Selectable)_apiKeyInputField).interactable = true;
		NPC nPC = __instance.NPC;
		if ((Object)(object)nPC == (Object)null)
		{
			return true;
		}
		conversantNpc = nPC;
		conversantFirstName = nPC.FirstName;
		float relationDelta = nPC.RelationData.RelationDelta;
		conversantRelationStatus = ((relationDelta < 1f) ? "Bad" : ((relationDelta < 2f) ? "Poor" : ((relationDelta < 3f) ? "Neutral" : ((relationDelta < 4f) ? "Good" : ((relationDelta >= 4f) ? "Great" : "Unknown")))));
		if (nPC is Employee)
		{
			conversantRole = "Employee";
		}
		else if (nPC is PoliceOfficer)
		{
			conversantRole = "Officer";
			float num = default(float);
			Player closestPlayer = Player.GetClosestPlayer(((Component)nPC).transform.position, ref num, (List<Player>)null);
			if (closestPlayer.CrimeData.Crimes.Count > 0)
			{
				conversantAdditional = "Your dialogue conversant is a known criminal and has following crimes on record: ";
				for (int i = 0; i < closestPlayer.CrimeData.Crimes.Count; i++)
				{
					conversantAdditional = conversantAdditional + " " + closestPlayer.CrimeData.Crimes.ElementAt(i).Key.CrimeName;
				}
				conversantAdditional += ". ";
			}
		}
		else
		{
			Dealer val = (Dealer)(object)((nPC is Dealer) ? nPC : null);
			if (val != null)
			{
				conversantRole = "Dealer";
				if (val.IsRecruited)
				{
					conversantAdditional = "You are recruited as dealer by the dialogue conversant Boss. ";
				}
				else
				{
					conversantAdditional = "Your dialogue conversant is a competing drug dealer. ";
				}
			}
			else
			{
				conversantRole = "Citizen";
				Customer component = ((Component)nPC).GetComponent<Customer>();
				if ((Object)(object)component != (Object)null && nPC.RelationData.Unlocked && Customer.UnlockedCustomers.Contains(component))
				{
					string text = ((object)(EDay)(ref component.CustomerData.PreferredOrderDay)).ToString();
					float currentAddiction = component.CurrentAddiction;
					string arg = ((currentAddiction < 0.2f) ? "not" : ((currentAddiction < 0.4f) ? "somewhat" : ((currentAddiction < 0.6f) ? "" : ((currentAddiction < 0.8f) ? "very" : ((currentAddiction >= 0.8f) ? "extremely" : "")))));
					conversantAdditional = $"Your dialogue conversant is your personal drug dealer and you are {arg} addicted to their drugs. You like ordering from them on every {component.CustomerData.PreferredOrderDay} and you spend {component.CustomerData.MinWeeklySpend} dollars on drugs weekly. ";
				}
				else
				{
					conversantAdditional = "Your dialogue conversant is a dealer, but you dont consume their drugs. ";
				}
			}
		}
		return true;
	}

	public string GetPromptEmbed()
	{
		string text = "";
		string text2 = "";
		if (RoleRegistry.Roles.TryGetValue(conversantRole, out var value))
		{
			foreach (string description in value.Descriptions)
			{
				text += description;
			}
			text2 = value.Moods[Random.Range(0, value.Moods.Count)];
		}
		string text3 = "You are " + conversantFirstName + " Your mood is: " + text2 + ". Your relations with the conversant are " + conversantRelationStatus + ". " + conversantAdditional + " Your Role is: " + conversantRole + ". Role Actions: " + text + ". ";
		return hiddenInstruction + text3;
	}

	private void CreateGeminiUI()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Expected O, but got Unknown
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_021f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_0316: Unknown result type (might be due to invalid IL or missing references)
		//IL_031d: Expected O, but got Unknown
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_036f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("UserInputField", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(_dialogueCanvas.transform, false);
		val.transform.SetAsLastSibling();
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = new Vector2(0.5f, 0.5f);
		component.anchorMax = new Vector2(0.5f, 0.5f);
		component.pivot = new Vector2(0.5f, 0.5f);
		component.sizeDelta = new Vector2(500f, 100f);
		component.anchoredPosition = new Vector2(0f, 350f);
		Image val2 = val.AddComponent<Image>();
		((Graphic)val2).color = new Color(1f, 1f, 1f, 0.8f);
		_userInputField = val.AddComponent<TMP_InputField>();
		_userInputField.textViewport = CreateTextArea(val.transform, out var textComp, Color.black);
		_userInputField.textComponent = (TMP_Text)(object)textComp;
		_userInputField.placeholder = CreatePlaceholder(val.transform, "Type your message");
		_userInputField.characterLimit = 200;
		_userInputField.lineType = (LineType)2;
		_userInputField.contentType = (ContentType)0;
		((UnityEvent<string>)(object)_userInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
		{
			_userInput = text;
		});
		((Selectable)_userInputField).interactable = false;
		GameObject val3 = new GameObject("ResponseField", new Type[1] { typeof(RectTransform) });
		val3.transform.SetParent(_dialogueCanvas.transform, false);
		val3.transform.SetAsLastSibling();
		RectTransform component2 = val3.GetComponent<RectTransform>();
		component2.anchorMin = new Vector2(0.5f, 0.5f);
		component2.anchorMax = new Vector2(0.5f, 0.5f);
		component2.pivot = new Vector2(0.5f, 0.5f);
		component2.sizeDelta = new Vector2(500f, 350f);
		component2.anchoredPosition = new Vector2(0f, 120f);
		Image val4 = val3.AddComponent<Image>();
		((Graphic)val4).color = Color.clear;
		_responseTextField = val3.AddComponent<TMP_InputField>();
		((Graphic)((Selectable)_responseTextField).image).color = Color.clear;
		_responseTextField.textViewport = CreateTextArea(val3.transform, out var textComp2, Color.white);
		respComponent = textComp2;
		((TMP_Text)respComponent).fontSize = 18f;
		_responseTextField.textComponent = (TMP_Text)(object)respComponent;
		_responseTextField.characterLimit = 300;
		_responseTextField.lineType = (LineType)2;
		_responseTextField.contentType = (ContentType)0;
		_responseTextField.readOnly = true;
		((Selectable)_responseTextField).interactable = false;
		GameObject val5 = new GameObject("InputKeyField", new Type[1] { typeof(RectTransform) });
		val5.transform.SetParent(_dialogueCanvas.transform, false);
		val5.transform.SetAsLastSibling();
		RectTransform component3 = val5.GetComponent<RectTransform>();
		component3.anchorMin = new Vector2(0.5f, 0.5f);
		component3.anchorMax = new Vector2(0.5f, 0.5f);
		component3.pivot = new Vector2(0.5f, 0.5f);
		component3.sizeDelta = new Vector2(300f, 40f);
		component3.anchoredPosition = new Vector2(-800f, 300f);
		Image val6 = val5.AddComponent<Image>();
		((Graphic)val6).color = new Color(1f, 0.45f, 0.3f, 0.4f);
		_apiKeyInputField = val5.AddComponent<TMP_InputField>();
		_apiKeyInputField.textViewport = CreateTextArea(val5.transform, out var textComp3, Color.black);
		((TMP_Text)textComp3).fontSize = 12f;
		_apiKeyInputField.textComponent = (TMP_Text)(object)textComp3;
		_apiKeyInputField.characterLimit = 50;
		_apiKeyInputField.placeholder = CreatePlaceholder(val5.transform, "Insert API Key");
		_apiKeyInputField.lineType = (LineType)0;
		_apiKeyInputField.contentType = (ContentType)7;
		((UnityEvent<string>)(object)_apiKeyInputField.onValueChanged).AddListener((UnityAction<string>)delegate(string text)
		{
			_geminiApiKey = text;
		});
		((Selectable)_apiKeyInputField).interactable = false;
	}

	private RectTransform CreateTextArea(Transform parent, out TextMeshProUGUI textComp, Color color)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Text", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = Vector2.zero;
		component.anchorMax = Vector2.one;
		component.offsetMin = new Vector2(10f, 6f);
		component.offsetMax = new Vector2(-10f, -6f);
		textComp = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)textComp).fontSize = 18f;
		((Graphic)textComp).color = color;
		((TMP_Text)textComp).alignment = (TextAlignmentOptions)4097;
		return component;
	}

	private Graphic CreatePlaceholder(Transform parent, string content)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Placeholder", new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		RectTransform component = val.GetComponent<RectTransform>();
		component.anchorMin = Vector2.zero;
		component.anchorMax = Vector2.one;
		component.offsetMin = new Vector2(10f, 6f);
		component.offsetMax = new Vector2(-10f, -6f);
		TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
		((TMP_Text)val2).text = content;
		((TMP_Text)val2).fontSize = 12f;
		((TMP_Text)val2).fontStyle = (FontStyles)2;
		((Graphic)val2).color = Color.black;
		((TMP_Text)val2).alignment = (TextAlignmentOptions)4097;
		return (Graphic)(object)val2;
	}

	public override void OnUpdate()
	{
		if (!Input.GetKeyDown((KeyCode)13) || string.IsNullOrEmpty(_userInput) || string.IsNullOrEmpty(_geminiApiKey))
		{
			return;
		}
		MelonCoroutines.Start(SendRequestToGeminiWithImage(_userInput, delegate(string response)
		{
			_userInput = "";
			_userInputField.text = "";
			if (response != null && !(response == string.Empty))
			{
				if (!EnforcesInternalRules(response))
				{
					MelonLogger.Warning("Gemini Response does not enforce mod rules and was discarded.");
				}
				else
				{
					MelonCoroutines.Start(ResponseCb(response));
				}
			}
		}));
	}

	[IteratorStateMachine(typeof(<ResponseCb>d__29))]
	private IEnumerator ResponseCb(string response)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ResponseCb>d__29(0)
		{
			<>4__this = this,
			response = response
		};
	}

	[IteratorStateMachine(typeof(<SendRequestToGeminiWithImage>d__30))]
	private IEnumerator SendRequestToGeminiWithImage(string prompt, Action<string> onResponse)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <SendRequestToGeminiWithImage>d__30(0)
		{
			<>4__this = this,
			prompt = prompt,
			onResponse = onResponse
		};
	}
}