using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
using cakeslice;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("WindTotem")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5")]
[assembly: AssemblyProduct("WindTotem")]
[assembly: AssemblyTitle("WindTotem")]
[assembly: AssemblyVersion("1.0.5.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace WindTotem
{
internal static class HappyBayClues
{
internal static bool Eligible
{
get
{
if (QuestSave.Valid && QuestSave.Progress.Stage == 1 && !GameState.currentlyLoading && !GameState.justStarted && !GameState.sleeping)
{
return !GameState.recovering;
}
return false;
}
}
internal static bool IsLee(CargoTransportDude dude)
{
if (Object.op_Implicit((Object)(object)dude) && dude.carrierIndex == 18)
{
return ((Object)dude).name == "transport dude";
}
return false;
}
internal static void Attach(GameObject npc, CargoTransportDude transport = null)
{
HappyBayClue happyBayClue = npc.GetComponent<HappyBayClue>();
if (!Object.op_Implicit((Object)(object)happyBayClue))
{
happyBayClue = npc.AddComponent<HappyBayClue>();
}
happyBayClue.Transport = transport;
}
}
[HarmonyPatch(typeof(PortDude), "Awake")]
internal static class HappyBayPortInstall
{
private static void Postfix(PortDude __instance)
{
if (Object.op_Implicit((Object)(object)__instance.GetPort()) && __instance.GetPort().portIndex == 20)
{
HappyBayClues.Attach(((Component)__instance).gameObject);
}
}
}
[HarmonyPatch(typeof(IslandSceneryScene), "Update")]
internal static class HappyBayLeeInstall
{
private static void Postfix(IslandSceneryScene __instance)
{
if (__instance.parentIslandIndex != 18)
{
return;
}
HappyBayInstalled happyBayInstalled = ((Component)__instance).GetComponent<HappyBayInstalled>();
if (!Object.op_Implicit((Object)(object)happyBayInstalled))
{
happyBayInstalled = ((Component)__instance).gameObject.AddComponent<HappyBayInstalled>();
}
if (happyBayInstalled.Complete || Time.unscaledTime < happyBayInstalled.NextAttempt)
{
return;
}
happyBayInstalled.NextAttempt = Time.unscaledTime + 1f;
CargoTransportDude[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<CargoTransportDude>(true);
foreach (CargoTransportDude val in componentsInChildren)
{
if (HappyBayClues.IsLee(val))
{
HappyBayClues.Attach(((Component)val).gameObject, val);
happyBayInstalled.Complete = true;
break;
}
}
}
}
public sealed class HappyBayInstalled : MonoBehaviour
{
public bool Complete;
public float NextAttempt;
}
[HarmonyPatch(typeof(CargoTransportDude), "OnTriggerEnter")]
internal static class HappyBayTransportEnter
{
private static bool Prefix(CargoTransportDude __instance)
{
if (HappyBayClues.IsLee(__instance))
{
return !HappyBayClues.Eligible;
}
return true;
}
}
[HarmonyPatch(typeof(CargoTransportDude), "OnTriggerExit")]
internal static class HappyBayTransportExit
{
private static bool Prefix(CargoTransportDude __instance)
{
if (HappyBayClues.IsLee(__instance))
{
return !HappyBayClues.Eligible;
}
return true;
}
}
public sealed class HappyBayClue : MonoBehaviour
{
public CargoTransportDude Transport;
private QuestDialogue dialogue;
private bool open;
private float retry;
private void Update()
{
//IL_0019: 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)
float num = (Object.op_Implicit((Object)(object)Refs.observerMirror) ? Vector3.Distance(((Component)this).transform.position, ((Component)Refs.observerMirror).transform.position) : float.PositiveInfinity);
if (!HappyBayClues.Eligible || !(num <= (open ? 5f : (Object.op_Implicit((Object)(object)Transport) ? 4f : 3f))))
{
if (open && Object.op_Implicit((Object)(object)Transport) && Object.op_Implicit((Object)(object)CargoCarrierUI.instance))
{
CargoCarrierUI.instance.HideUI();
}
open = false;
dialogue?.Hide();
return;
}
if (Object.op_Implicit((Object)(object)Transport))
{
if (!open && Object.op_Implicit((Object)(object)CargoCarrierUI.instance))
{
CargoCarrierUI.instance.ShowUI(((Component)this).transform, Transport.carrierIndex);
}
open = Object.op_Implicit((Object)(object)CargoCarrierUI.instance);
return;
}
open = true;
if (dialogue == null && Time.unscaledTime >= retry)
{
retry = Time.unscaledTime + 0.5f;
dialogue = QuestDialogue.Create(((Component)this).transform, "No, I don’t recall a boat like that. Try asking Lee, the cart loader sitting outside. He might have seen it.", null);
}
dialogue?.Show(((Component)this).transform, giver: true);
}
private void OnDisable()
{
if (open && Object.op_Implicit((Object)(object)Transport) && Object.op_Implicit((Object)(object)CargoCarrierUI.instance))
{
CargoCarrierUI.instance.HideUI();
}
open = false;
dialogue?.Hide();
}
}
[HarmonyPatch(typeof(CargoCarrierUI), "ShowUI")]
internal static class HappyBayServiceShow
{
private static void Prefix(CargoCarrierUI __instance)
{
((Component)__instance).GetComponent<HappyBayServiceClue>()?.Restore();
}
private static void Postfix(CargoCarrierUI __instance, Transform transportDude, int carrierIndex)
{
if (carrierIndex == 18 && HappyBayClues.Eligible && Object.op_Implicit((Object)(object)transportDude) && !(((Object)transportDude).name != "transport dude"))
{
HappyBayServiceClue happyBayServiceClue = ((Component)__instance).GetComponent<HappyBayServiceClue>();
if (!Object.op_Implicit((Object)(object)happyBayServiceClue))
{
happyBayServiceClue = ((Component)__instance).gameObject.AddComponent<HappyBayServiceClue>();
}
happyBayServiceClue.Source = transportDude;
}
}
}
[HarmonyPatch(typeof(CargoCarrierUI), "HideUI")]
internal static class HappyBayServiceHide
{
private static void Prefix(CargoCarrierUI __instance)
{
((Component)__instance).GetComponent<HappyBayServiceClue>()?.Restore();
}
}
public sealed class HappyBayServiceClue : MonoBehaviour
{
public Transform Source;
private QuestDialogue dialogue;
private Transform button;
private Vector3 buttonPosition;
private Quaternion buttonRotation;
private Quaternion buttonFaceRotation;
private Renderer[] buttonRenderers;
private readonly Dictionary<Renderer, bool> originalRenderers = new Dictionary<Renderer, bool>();
private void LateUpdate()
{
//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)Source))
{
return;
}
if (!HappyBayClues.Eligible)
{
Restore();
return;
}
if (dialogue == null)
{
CargoCarrierUI component = ((Component)this).GetComponent<CargoCarrierUI>();
CargoCarrierButton componentInChildren = ((Component)this).GetComponentInChildren<CargoCarrierButton>(true);
if (!Object.op_Implicit((Object)(object)componentInChildren) || !Object.op_Implicit((Object)(object)component.buttonText))
{
return;
}
button = ((Component)componentInChildren).transform;
while ((Object)(object)button != (Object)(object)((Component)this).transform && !((Component)component.buttonText).transform.IsChildOf(button))
{
button = button.parent;
}
if ((Object)(object)button == (Object)(object)((Component)this).transform)
{
button = null;
return;
}
Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
dialogue = QuestDialogue.Create(((Component)this).transform, "Oh, yes, I remember that boat! You don’t often see a dhow in these waters. I think he headed east. Now, do you need anything hauled? My services are well worth the coin!", null);
if (dialogue == null)
{
button = null;
return;
}
buttonPosition = button.localPosition;
buttonRotation = button.localRotation;
buttonFaceRotation = Quaternion.Inverse(button.rotation) * ((Component)component.buttonText).transform.rotation;
buttonRenderers = ((Component)button).GetComponentsInChildren<Renderer>();
Renderer[] array = componentsInChildren;
foreach (Renderer val in array)
{
if (!((Component)val).transform.IsChildOf(button))
{
originalRenderers[val] = val.enabled;
val.enabled = false;
}
}
}
dialogue.Show(Source, giver: true);
dialogue.PlaceServiceButton(button, buttonFaceRotation, buttonRenderers);
}
public void Restore()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
Source = null;
if (Object.op_Implicit((Object)(object)button))
{
button.localPosition = buttonPosition;
button.localRotation = buttonRotation;
}
foreach (KeyValuePair<Renderer, bool> originalRenderer in originalRenderers)
{
if (Object.op_Implicit((Object)(object)originalRenderer.Key))
{
originalRenderer.Key.enabled = originalRenderer.Value;
}
}
originalRenderers.Clear();
button = null;
buttonRenderers = null;
dialogue?.Hide();
dialogue?.Dispose();
dialogue = null;
}
private void OnDisable()
{
Restore();
}
}
public sealed class ItemOutlineSanitizer : MonoBehaviour
{
private void Awake()
{
Outline[] components = ((Component)this).GetComponents<Outline>();
for (int i = 0; i < components.Length; i++)
{
Object.DestroyImmediate((Object)(object)components[i]);
}
}
}
[HarmonyPatch(typeof(ShipItem), "UpdateLookText")]
internal static class TotemHoverText
{
private static void Postfix(ShipItem __instance)
{
if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<PortableTotem>()))
{
((GoPointerButton)__instance).lookText = "";
}
}
}
[HarmonyPatch(typeof(GoPointer), "DoRaycast")]
internal static class OrbPointerPriority
{
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
MethodInfo raycast = AccessTools.Method(typeof(Physics), "Raycast", new Type[4]
{
typeof(Ray),
typeof(RaycastHit).MakeByRefType(),
typeof(float),
typeof(int)
}, (Type[])null);
MethodInfo replacement = AccessTools.Method(typeof(OrbPointerPriority), "Raycast", (Type[])null, (Type[])null);
int replaced = 0;
foreach (CodeInstruction instruction in instructions)
{
if (instruction.opcode == OpCodes.Call && object.Equals(instruction.operand, raycast))
{
instruction.operand = replacement;
replaced++;
}
yield return instruction;
}
if (replaced != 1)
{
throw new InvalidOperationException("Expected one world-pointer raycast; found " + replaced);
}
}
internal static bool Raycast(Ray ray, out RaycastHit hit, float distance, int mask)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: 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_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
if (!Physics.Raycast(ray, ref hit, distance, mask))
{
return false;
}
PortableTotem portableTotem = FindTotem(((RaycastHit)(ref hit)).collider);
if (!Object.op_Implicit((Object)(object)portableTotem))
{
return true;
}
PortableWindOrb componentInChildren = ((Component)portableTotem).GetComponentInChildren<PortableWindOrb>();
if (!Object.op_Implicit((Object)(object)componentInChildren) || !componentInChildren.CanPoint || (mask & (1 << ((Component)componentInChildren).gameObject.layer)) == 0)
{
return true;
}
RaycastHit val = default(RaycastHit);
if (!componentInChildren.PointerCollider.Raycast(ray, ref val, distance))
{
return true;
}
RaycastHit[] array = Physics.RaycastAll(ray, ((RaycastHit)(ref val)).distance, mask);
for (int i = 0; i < array.Length; i++)
{
RaycastHit val2 = array[i];
if ((Object)(object)((RaycastHit)(ref val2)).collider != (Object)(object)componentInChildren.PointerCollider && (Object)(object)FindTotem(((RaycastHit)(ref val2)).collider) != (Object)(object)portableTotem)
{
return true;
}
}
hit = val;
return true;
}
private static PortableTotem FindTotem(Collider collider)
{
PortableTotem componentInParent = ((Component)collider).GetComponentInParent<PortableTotem>();
if (Object.op_Implicit((Object)(object)componentInParent))
{
return componentInParent;
}
ItemRigidbody componentInParent2 = ((Component)collider).GetComponentInParent<ItemRigidbody>();
ShipItem val = (Object.op_Implicit((Object)(object)componentInParent2) ? componentInParent2.GetShipItem() : null);
if (!Object.op_Implicit((Object)(object)val))
{
return null;
}
return ((Component)val).GetComponent<PortableTotem>();
}
}
[BepInPlugin("DogEggz.WindTotem", "Wind Totem", "1.0.5")]
public sealed class WindTotemPlugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(PrefabsDirectory), "Start")]
private static class RegisterPrefab
{
[HarmonyPrefix]
private static void Prefix(PrefabsDirectory __instance)
{
if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.prefab) || __instance.directory == null)
{
return;
}
GameObject[] array = __instance.directory;
if (array.Length <= 609)
{
Array.Resize(ref array, 610);
}
if ((Object.op_Implicit((Object)(object)array[609]) && (Object)(object)array[609] != (Object)(object)instance.prefab) || (Object.op_Implicit((Object)(object)array[608]) && (Object)(object)array[608] != (Object)(object)instance.questPrefab))
{
((BaseUnityPlugin)instance).Logger.LogError((object)"Prefab 608 or 609 is occupied; Wind Totem registration refused.");
return;
}
try
{
instance.CreateQuestPrefab(__instance);
}
catch (Exception ex)
{
((BaseUnityPlugin)instance).Logger.LogError((object)ex);
if (Object.op_Implicit((Object)(object)instance.questPrefab))
{
Object.Destroy((Object)(object)instance.questPrefab);
}
instance.questPrefab = null;
return;
}
array[609] = instance.prefab;
array[608] = instance.questPrefab;
__instance.directory = array;
((BaseUnityPlugin)instance).Logger.LogInfo((object)"Registered WindTotemQuest 608 and Wind Totem 609.");
}
}
internal const int PrefabIndex = 609;
internal const int QuestPrefabIndex = 608;
private static WindTotemPlugin instance;
private AssetBundle bundle;
private Harmony patches;
private GameObject prefab;
private GameObject templateHolder;
private GameObject questPrefab;
internal static bool Ready
{
get
{
if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.prefab) && Object.op_Implicit((Object)(object)instance.questPrefab) && Object.op_Implicit((Object)(object)PrefabsDirectory.instance) && PrefabsDirectory.instance.directory.Length > 609 && (Object)(object)PrefabsDirectory.instance.directory[609] == (Object)(object)instance.prefab)
{
return (Object)(object)PrefabsDirectory.instance.directory[608] == (Object)(object)instance.questPrefab;
}
return false;
}
}
internal static void Log(string text)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)text);
}
internal static void Error(string text)
{
((BaseUnityPlugin)instance).Logger.LogError((object)text);
}
private void Awake()
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_0248: Expected O, but got Unknown
instance = this;
try
{
string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "windtotem_assets");
bundle = AssetBundle.LoadFromFile(text);
if (!Object.op_Implicit((Object)(object)bundle))
{
throw new InvalidOperationException("Cannot load " + text);
}
GameObject val = bundle.LoadAsset<GameObject>("Assets/Generated/WindTotem.prefab");
if (!Object.op_Implicit((Object)(object)val))
{
throw new InvalidOperationException("Wind Totem visual prefab is missing.");
}
templateHolder = new GameObject("Wind Totem prefab storage");
templateHolder.SetActive(false);
Object.DontDestroyOnLoad((Object)(object)templateHolder);
prefab = Object.Instantiate<GameObject>(val, templateHolder.transform);
((Object)prefab).name = "609 Wind Totem";
ShipItem obj = prefab.AddComponent<ShipItem>();
obj.name = "Wind Totem";
((GoPointerButton)obj).description = "";
((PickupableItem)obj).big = true;
obj.mass = 3f;
obj.value = 300000;
obj.sold = true;
obj.health = 100f;
((PickupableItem)obj).holdDistance = 1.3f;
obj.floaterHeight = 0.2f;
obj.inventoryScale = 1f;
SaveablePrefab obj2 = prefab.AddComponent<SaveablePrefab>();
obj2.prefabIndex = 609;
obj2.SetParentObject(-1);
prefab.AddComponent<PortableTotem>();
prefab.AddComponent<ItemOutlineSanitizer>();
Transform obj3 = prefab.transform.Find("Visuals/wind_totem_wind/wind_totem_target");
if (!Object.op_Implicit((Object)(object)obj3))
{
throw new InvalidOperationException("Wind Totem orb is missing.");
}
((Component)obj3).gameObject.AddComponent<PortableWindOrb>();
((Component)obj3).gameObject.AddComponent<ItemOutlineSanitizer>();
Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Material[] sharedMaterials = componentsInChildren[i].sharedMaterials;
foreach (Material val2 in sharedMaterials)
{
if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.shader))
{
Shader val3 = Shader.Find((((Object)val2).name == "Particle Storm Lightning") ? "Particles/Priority Alpha Blended" : ((Object)val2.shader).name);
if (Object.op_Implicit((Object)(object)val3))
{
val2.shader = val3;
}
}
}
}
patches = new Harmony("DogEggz.WindTotem");
patches.PatchAll(typeof(WindTotemPlugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Wind Totem 1.0.5 loaded; quest 608, totem 609; return quest and 60-second base wind hold active.");
}
catch (Exception ex)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Wind Totem initialization failed: " + ex));
try
{
Harmony obj4 = patches;
if (obj4 != null)
{
obj4.UnpatchSelf();
}
}
catch (Exception ex2)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Patch rollback failed: " + ex2));
}
if (Object.op_Implicit((Object)(object)templateHolder))
{
Object.Destroy((Object)(object)templateHolder);
}
prefab = null;
}
}
private void CreateQuestPrefab(PrefabsDirectory directory)
{
if (!Object.op_Implicit((Object)(object)questPrefab))
{
if (directory.directory.Length <= 5 || !Object.op_Implicit((Object)(object)directory.directory[5]))
{
throw new InvalidOperationException("Vanilla tea crate prefab 5 is unavailable.");
}
questPrefab = Object.Instantiate<GameObject>(directory.directory[5], templateHolder.transform);
((Object)questPrefab).name = "608 WindTotemQuest";
Good component = questPrefab.GetComponent<Good>();
if (Object.op_Implicit((Object)(object)component))
{
Object.DestroyImmediate((Object)(object)component);
}
questPrefab.tag = "Untagged";
ShipItem component2 = questPrefab.GetComponent<ShipItem>();
component2.name = "WindTotemQuest";
((GoPointerButton)component2).description = "";
((GoPointerButton)component2).lookText = "";
component2.sold = true;
component2.nailed = false;
component2.value = 0;
SaveablePrefab component3 = questPrefab.GetComponent<SaveablePrefab>();
component3.prefabIndex = 608;
component3.instanceId = 0;
component3.currentCrateId = 0;
component3.SetParentObject(-1);
questPrefab.AddComponent<ItemOutlineSanitizer>();
}
}
}
public sealed class PortableTotem : MonoBehaviour
{
private IEnumerator Start()
{
ShipItem item = ((Component)this).GetComponent<ShipItem>();
SaveablePrefab saveable = ((Component)this).GetComponent<SaveablePrefab>();
while (!Object.op_Implicit((Object)(object)SaveLoadManager.instance) || GameState.currentlyLoading || GameState.justStarted)
{
yield return null;
}
yield return (object)new WaitForEndOfFrame();
if (item.sold)
{
saveable.RegisterToSave();
}
LODGroup component = ((Component)this).GetComponent<LODGroup>();
if (Object.op_Implicit((Object)(object)component))
{
LOD[] lODs = component.GetLODs();
if (lODs.Length != 0)
{
lODs[0].renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
component.SetLODs(lODs);
component.RecalculateBounds();
}
}
}
}
public sealed class PortableWindOrb : PickupableItem
{
private const float MaxCarryDistance = 8f;
private ShipItem owner;
private Transform pivot;
private Vector3 homePosition;
private Quaternion homeRotation;
private ParticleSystem particles;
private AudioSource orbAudio;
private Collider orbCollider;
private bool effectsPlaying;
internal Collider PointerCollider => orbCollider;
internal bool CanPoint
{
get
{
if (Object.op_Implicit((Object)(object)owner) && !Object.op_Implicit((Object)(object)((PickupableItem)owner).held) && !Object.op_Implicit((Object)(object)base.held) && Object.op_Implicit((Object)(object)orbCollider) && orbCollider.enabled && ((Component)this).gameObject.activeInHierarchy && !((GoPointerButton)this).unclickable && ((Component)owner).gameObject.layer != 5 && ((Component)owner).gameObject.layer != 26 && !GameState.currentlyLoading && !GameState.sleeping)
{
return !GameState.recovering;
}
return false;
}
}
private void Awake()
{
//IL_0024: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
owner = ((Component)this).GetComponentInParent<ShipItem>();
pivot = ((Component)this).transform.parent;
homePosition = ((Component)this).transform.localPosition;
homeRotation = ((Component)this).transform.localRotation;
particles = ((Component)this).GetComponentInChildren<ParticleSystem>(true);
orbAudio = ((Component)this).GetComponent<AudioSource>();
orbCollider = ((Component)this).GetComponent<Collider>();
((GoPointerButton)this).lookText = "";
((GoPointerButton)this).description = "";
base.holdDistance = 1.15f;
((Component)this).transform.SetParent(((Component)owner).transform, true);
StopEffects();
}
public override void OnDrop()
{
StopEffects();
WindHold.Release(this);
}
public override void ExtraLateUpdate()
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0171: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)pivot))
{
return;
}
bool flag = ((Component)owner).gameObject.layer == 5 || ((Component)owner).gameObject.layer == 26;
bool flag2 = !Object.op_Implicit((Object)(object)((PickupableItem)owner).held) && !flag && !GameState.currentlyLoading && !GameState.sleeping && !GameState.recovering;
orbCollider.enabled = flag2;
if (Object.op_Implicit((Object)(object)base.held) && (!flag2 || Vector3.Distance(((Component)this).transform.position, pivot.position) > 8f))
{
((PickupableItem)this).OnDrop();
base.held.DropItem();
}
if (Object.op_Implicit((Object)(object)base.held) && Object.op_Implicit((Object)(object)Wind.instance))
{
float num = Vector3.Distance(((Component)this).transform.position, pivot.position);
Vector3 val = ((Component)this).transform.position - pivot.position;
val.y = 0f;
if (((Vector3)(ref val)).sqrMagnitude > 1E-06f)
{
pivot.rotation = Quaternion.Slerp(pivot.rotation, Quaternion.LookRotation(val, Vector3.up), Time.deltaTime * 2f);
}
Vector3 val2 = Vector3.ProjectOnPlane(pivot.forward, Vector3.up);
Vector3 normalized = ((Vector3)(ref val2)).normalized;
if (((Vector3)(ref normalized)).sqrMagnitude > 1E-06f)
{
float num2 = Mathf.Lerp(Wind.instance.minimumMagnitude, Wind.instance.maximumMagnitude, num / 8f);
WindHold.Command(this, normalized * num2);
}
EmissionModule emission = particles.emission;
((EmissionModule)(ref emission)).enabled = true;
((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(num * 20f);
MainModule main = particles.main;
((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(Mathf.Lerp(0.08f, 0.25f, num / 8f) * 0.4f);
orbAudio.volume = num / 8f;
orbAudio.pitch = Mathf.Lerp(1.21f, 1.53f, num / 8f);
if (!orbAudio.isPlaying)
{
((Behaviour)orbAudio).enabled = true;
orbAudio.Play();
}
effectsPlaying = true;
}
else
{
if (effectsPlaying)
{
StopEffects();
}
((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, pivot.TransformPoint(homePosition), Time.deltaTime * 5f);
((Component)this).transform.rotation = pivot.rotation * homeRotation;
((Component)this).gameObject.layer = ((!flag2) ? ((Component)owner).gameObject.layer : 0);
}
}
private void StopEffects()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)particles))
{
EmissionModule emission = particles.emission;
((EmissionModule)(ref emission)).enabled = false;
}
if (Object.op_Implicit((Object)(object)orbAudio))
{
orbAudio.volume = 0f;
orbAudio.Stop();
((Behaviour)orbAudio).enabled = false;
}
effectsPlaying = false;
}
private void OnDisable()
{
if (Object.op_Implicit((Object)(object)base.held))
{
base.held.DropItem();
}
StopEffects();
}
}
internal sealed class QuestDialogue
{
private static GameObject template;
private static string textPath;
private static string buttonPath;
private readonly GameObject panel;
private readonly Transform bubble;
private QuestDialogue(GameObject panel, Transform bubble)
{
this.panel = panel;
this.bubble = bubble;
}
internal static void Capture(TavernRumorsDude source)
{
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)template) && Object.op_Implicit((Object)(object)source) && Object.op_Implicit((Object)(object)source.speechUI) && Object.op_Implicit((Object)(object)source.text) && Object.op_Implicit((Object)(object)source.drinkButton))
{
textPath = Path(source.speechUI.transform, ((Component)source.text).transform);
buttonPath = Path(source.speechUI.transform, source.drinkButton.transform);
template = Object.Instantiate<GameObject>(source.speechUI);
((Object)template).name = "Wind Totem dialogue template";
template.SetActive(false);
template.transform.SetParent((Transform)null, false);
template.transform.localScale = Vector3.one;
MonoBehaviour[] componentsInChildren = template.GetComponentsInChildren<MonoBehaviour>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
}
if (Application.isPlaying)
{
Object.DontDestroyOnLoad((Object)(object)template);
}
}
}
internal static QuestDialogue Create(Transform parent, string content, Action accept)
{
//IL_0083: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0186: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: Unknown result type (might be due to invalid IL or missing references)
//IL_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0274: Unknown result type (might be due to invalid IL or missing references)
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
//IL_028e: Unknown result type (might be due to invalid IL or missing references)
//IL_0293: Unknown result type (might be due to invalid IL or missing references)
//IL_0297: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)template))
{
TavernRumorsDude[] array = Resources.FindObjectsOfTypeAll<TavernRumorsDude>();
foreach (TavernRumorsDude val in array)
{
Scene scene = ((Component)val).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
Capture(val);
if (Object.op_Implicit((Object)(object)template))
{
break;
}
}
}
}
if (!Object.op_Implicit((Object)(object)template))
{
return null;
}
GameObject val2 = Object.Instantiate<GameObject>(template, parent, false);
((Object)val2).name = "Wind Totem quest dialogue";
val2.transform.localPosition = Vector3.zero;
val2.transform.localRotation = Quaternion.identity;
val2.transform.localScale = Vector3.one;
TextMesh component = ((Component)val2.transform.Find(textPath)).GetComponent<TextMesh>();
Transform parent2 = ((Component)component).transform.parent;
Transform val3 = parent2.Find("gfx");
Transform val4 = val2.transform.Find(buttonPath);
val2.SetActive(true);
((Component)val4).gameObject.SetActive(false);
Renderer component2 = ((Component)component).GetComponent<Renderer>();
Bounds bounds = component2.bounds;
Vector3 size = ((Bounds)(ref bounds)).size;
bounds = ((Component)val3).GetComponent<Renderer>().bounds;
Vector3 size2 = ((Bounds)(ref bounds)).size;
string text = Wrap(content, 40);
component.font.RequestCharactersInTexture(text, component.fontSize, component.fontStyle);
component.text = text;
bounds = component2.bounds;
Vector3 size3 = ((Bounds)(ref bounds)).size;
Vector3 localScale = val3.localScale;
localScale.x *= Mathf.Max(0.35f, (size2.x + size3.x - size.x) / Mathf.Max(0.001f, size2.x));
localScale.y *= Mathf.Max(1f, (size2.y + size3.y - size.y) / Mathf.Max(0.001f, size2.y));
val3.localScale = localScale;
Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].enabled = false;
}
if (accept != null)
{
((Component)val4).gameObject.SetActive(true);
((Component)val4).GetComponentInChildren<TextMesh>(true).text = "Accept";
Collider componentInChildren = ((Component)val4).GetComponentInChildren<Collider>(true);
componentInChildren.enabled = true;
((Component)componentInChildren).gameObject.layer = 0;
((Component)componentInChildren).gameObject.AddComponent<QuestAcceptButton>().Accepted = accept;
Vector3 localPosition = val4.localPosition;
float y = parent2.localPosition.y;
bounds = ((Component)val3).GetComponent<Renderer>().bounds;
float num = y - ((Bounds)(ref bounds)).size.y * 0.5f;
bounds = ((Component)componentInChildren).GetComponent<Renderer>().bounds;
localPosition.y = num - ((Bounds)(ref bounds)).size.y * 0.5f - 0.08f;
val4.localPosition = localPosition;
}
val2.SetActive(false);
return new QuestDialogue(val2, parent2);
}
internal void Show(Transform anchor, bool giver)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: 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)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: 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)
if (Object.op_Implicit((Object)(object)panel) && Object.op_Implicit((Object)(object)Refs.observerMirror))
{
Transform transform = ((Component)Refs.observerMirror).transform;
Vector3 val = Vector3.ProjectOnPlane(transform.position - anchor.position, Vector3.up);
Vector3 normalized = ((Vector3)(ref val)).normalized;
Vector3 val2 = anchor.position + normalized * 0.75f;
val2.y = (giver ? (transform.position.y + 1.2f) : (Mathf.Max(anchor.position.y + 0.8f, transform.position.y + 0.5f) + 0.3f)) - bubble.localPosition.y;
panel.transform.SetPositionAndRotation(val2, transform.rotation);
panel.SetActive(true);
}
}
internal void Hide()
{
if (Object.op_Implicit((Object)(object)panel))
{
panel.SetActive(false);
}
}
internal void PlaceServiceButton(Transform button, Quaternion faceRotation, Renderer[] renderers)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: 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)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = ((Component)bubble.Find("gfx")).GetComponent<Renderer>().bounds;
button.rotation = panel.transform.rotation * Quaternion.Inverse(faceRotation);
if (renderers.Length != 0)
{
Bounds bounds2 = renderers[0].bounds;
foreach (Renderer val in renderers)
{
((Bounds)(ref bounds2)).Encapsulate(val.bounds);
}
button.position += new Vector3(((Bounds)(ref bounds)).center.x - ((Bounds)(ref bounds2)).center.x, ((Bounds)(ref bounds)).min.y - 0.08f - ((Bounds)(ref bounds2)).max.y, ((Bounds)(ref bounds)).center.z - ((Bounds)(ref bounds2)).center.z);
}
}
internal void Dispose()
{
if (Object.op_Implicit((Object)(object)panel))
{
Object.Destroy((Object)(object)panel);
}
}
private static string Path(Transform root, Transform child)
{
List<string> list = new List<string>();
while (Object.op_Implicit((Object)(object)child) && (Object)(object)child != (Object)(object)root)
{
list.Add(((Object)child).name);
child = child.parent;
}
if ((Object)(object)child != (Object)(object)root)
{
throw new InvalidOperationException("Dialogue element is outside speech UI.");
}
list.Reverse();
return string.Join("/", list);
}
private static string Wrap(string value, int width)
{
value = value.TrimStart(Array.Empty<char>());
if (value.Length <= width)
{
return value;
}
int num = value.LastIndexOf(' ', width);
if (num < 1)
{
num = width;
}
return value.Substring(0, num) + "\n" + Wrap(value.Substring(num), width);
}
}
public sealed class QuestAcceptButton : GoPointerButton
{
public Action Accepted;
public override void OnActivate()
{
Accepted?.Invoke();
}
}
[HarmonyPatch(typeof(TavernRumorsDude), "Awake")]
internal static class QuestDialogueCapture
{
private static void Postfix(TavernRumorsDude __instance)
{
QuestDialogue.Capture(__instance);
}
}
[HarmonyPatch(typeof(IslandSceneryScene), "Update")]
internal static class QuestIslandInstaller
{
[HarmonyPostfix]
internal static void Postfix(IslandSceneryScene __instance)
{
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Expected O, but got Unknown
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_020d: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_0217: Unknown result type (might be due to invalid IL or missing references)
int parentIslandIndex = __instance.parentIslandIndex;
if (parentIslandIndex != 37 && parentIslandIndex != 30)
{
return;
}
QuestIslandStatus questIslandStatus = ((Component)__instance).GetComponent<QuestIslandStatus>();
if (!Object.op_Implicit((Object)(object)questIslandStatus))
{
questIslandStatus = ((Component)__instance).gameObject.AddComponent<QuestIslandStatus>();
}
if (questIslandStatus.Complete || Time.unscaledTime < questIslandStatus.NextAttempt)
{
return;
}
questIslandStatus.NextAttempt = Time.unscaledTime + 1f;
GameObject val = null;
try
{
Transform val2 = FindTarget(((Component)__instance).transform, parentIslandIndex);
if (!Object.op_Implicit((Object)(object)val2))
{
if (!questIslandStatus.ReportedMissing)
{
questIslandStatus.ReportedMissing = true;
WindTotemPlugin.Error("Quest anchor not found on island " + parentIslandIndex + " under " + ((Object)__instance).name + "; retrying.");
}
return;
}
QuestAnchorMarker questAnchorMarker = ((Component)val2).GetComponent<QuestAnchorMarker>();
if (Object.op_Implicit((Object)(object)questAnchorMarker) && Object.op_Implicit((Object)(object)questAnchorMarker.Area))
{
questIslandStatus.Complete = true;
return;
}
val = new GameObject((parentIslandIndex == 37) ? "Wind Totem quest giver" : "Wind Totem quest delivery");
val.SetActive(false);
SceneManager.MoveGameObjectToScene(val, ((Component)val2).gameObject.scene);
val.transform.position = val2.position;
Rigidbody obj = val.AddComponent<Rigidbody>();
obj.isKinematic = true;
obj.useGravity = false;
val.layer = 2;
Collider val3;
if (parentIslandIndex == 37)
{
SphereCollider obj2 = val.AddComponent<SphereCollider>();
obj2.radius = 4f;
val3 = (Collider)(object)obj2;
}
else
{
BoxCollider obj3 = val.AddComponent<BoxCollider>();
obj3.size = Vector3.one * 3f;
val3 = (Collider)(object)obj3;
}
val3.isTrigger = true;
WindTotemQuestArea windTotemQuestArea = val.AddComponent<WindTotemQuestArea>();
windTotemQuestArea.Source = val2;
windTotemQuestArea.IsGiver = parentIslandIndex == 37;
val.SetActive(true);
if (!Object.op_Implicit((Object)(object)questAnchorMarker))
{
questAnchorMarker = ((Component)val2).gameObject.AddComponent<QuestAnchorMarker>();
}
questAnchorMarker.Area = val;
questIslandStatus.Complete = true;
WindTotemPlugin.Log("Installed " + ((Object)val).name + " on island " + parentIslandIndex + " at " + ((Object)val2).name + "; local=" + ((object)((Component)__instance).transform.InverseTransformPoint(val2.position)/*cast due to .constrained prefix*/).ToString() + ((parentIslandIndex == 37) ? "; radius=4m." : "; size=3x3x3m."));
}
catch (Exception ex)
{
if (Object.op_Implicit((Object)(object)val))
{
val.SetActive(false);
Object.Destroy((Object)(object)val);
}
questIslandStatus.Complete = false;
questIslandStatus.NextAttempt = Time.unscaledTime + 10f;
WindTotemPlugin.Error("Quest trigger installation failed on island " + parentIslandIndex + ": " + ex);
}
}
internal static Transform FindTarget(Transform island, int index)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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)
if (index != 37 && index != 30)
{
return null;
}
Transform[] componentsInChildren = ((Component)island).GetComponentsInChildren<Transform>(true);
foreach (Transform val in componentsInChildren)
{
if (index == 37 && ((Object)val).name == "Modular NPC (1)" && Vector3.Distance(island.InverseTransformPoint(val.position), new Vector3(-12.699f, 45.577f, 23.885f)) < 0.5f)
{
return val;
}
if (index == 30 && ((Object)val).name == "building_arab_obelisk_small")
{
return val;
}
}
return null;
}
}
public sealed class QuestIslandStatus : MonoBehaviour
{
public bool Complete;
public bool ReportedMissing;
public float NextAttempt;
}
public sealed class QuestAnchorMarker : MonoBehaviour
{
public GameObject Area;
}
internal static class QuestItems
{
internal static ShipItem SpawnAndCommit(int index, Vector3 position, Func<int, bool> commit)
{
//IL_0010: 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)
GameObject val = null;
SaveablePrefab val2 = null;
try
{
val = Object.Instantiate<GameObject>(PrefabsDirectory.instance.directory[index], position, Quaternion.identity, ((Component)FloatingOriginManager.instance).transform);
ShipItem component = val.GetComponent<ShipItem>();
val2 = val.GetComponent<SaveablePrefab>();
if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)val2))
{
throw new InvalidOperationException("Quest prefab is missing item/save components.");
}
component.sold = true;
component.nailed = false;
val2.RegisterToSave();
if (!commit(val2.instanceId))
{
throw new InvalidOperationException("Quest transition rejected; removing uncommitted item.");
}
return component;
}
catch
{
try
{
if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)SaveLoadManager.instance))
{
val2.Unregister();
}
}
finally
{
if (Object.op_Implicit((Object)(object)val))
{
val.SetActive(false);
Object.Destroy((Object)(object)val);
}
}
throw;
}
}
internal static IEnumerator ReleasePhysics(ShipItem item)
{
for (int i = 0; i < 8; i++)
{
yield return (object)new WaitForFixedUpdate();
}
if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.itemRigidbodyC) && !Object.op_Implicit((Object)(object)((PickupableItem)item).held) && !item.nailed && !GameState.currentlyLoading)
{
ItemRigidbody itemRigidbodyC = item.itemRigidbodyC;
itemRigidbodyC.attached = false;
itemRigidbodyC.disableCol = false;
itemRigidbodyC.inStove = false;
Rigidbody body = itemRigidbodyC.GetBody();
if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)((Component)itemRigidbodyC).GetComponent<Collider>()))
{
body.useGravity = true;
body.isKinematic = false;
body.WakeUp();
}
}
}
}
public static class QuestStages
{
public const int NotAccepted = 0;
public const int Outbound = 1;
public const int Returning = 2;
public const int Completed = 3;
}
public sealed class QuestProgress
{
public int Stage { get; private set; }
public int CrateId { get; private set; }
public int RewardId { get; private set; }
public static QuestProgress Reconcile(string data, int vanillaState)
{
if (data == null && vanillaState != 0)
{
throw new FormatException("Quest identity data is missing but a vanilla quest flag exists; quest disabled to prevent repeating it.");
}
QuestProgress questProgress = ((data == null) ? new QuestProgress() : Decode(data));
if (vanillaState == -5 && questProgress.Stage != 3)
{
throw new FormatException("Quest completion records disagree; quest disabled to prevent another reward.");
}
return questProgress;
}
public bool Accept(int crateId)
{
if (Stage != 0 || crateId <= 0)
{
return false;
}
CrateId = crateId;
Stage = 1;
return true;
}
public bool Matches(int prefab, int id)
{
if ((Stage == 1 || Stage == 2) && prefab == 608)
{
return id == CrateId;
}
return false;
}
public bool Visit(int crateId)
{
if (Stage != 1 || !Matches(608, crateId))
{
return false;
}
Stage = 2;
return true;
}
public bool Complete(int crateId, int rewardId)
{
if (Stage != 2 || !Matches(608, crateId) || rewardId <= 0)
{
return false;
}
RewardId = rewardId;
Stage = 3;
return true;
}
public string Encode()
{
return string.Join("|", "2", Stage.ToString(CultureInfo.InvariantCulture), CrateId.ToString(CultureInfo.InvariantCulture), RewardId.ToString(CultureInfo.InvariantCulture));
}
public static QuestProgress Decode(string data)
{
string[] array = data.Split(new char[1] { '|' });
if (array.Length != 4 || (array[0] != "1" && array[0] != "2") || !int.TryParse(array[1], out var result) || !int.TryParse(array[2], out var result2) || !int.TryParse(array[3], out var result3) || result < 0 || result > ((array[0] == "1") ? 2 : 3) || result2 < 0 || result3 < 0 || (result == 0 && (result2 != 0 || result3 != 0)) || (result >= 1 && result2 == 0) || (result < ((array[0] == "1") ? 2 : 3) && result3 != 0) || (result == ((array[0] == "1") ? 2 : 3) && result3 == 0))
{
throw new FormatException("Invalid Wind Totem quest state; quest disabled to protect saved progress.");
}
return new QuestProgress
{
Stage = ((array[0] == "1" && result == 2) ? 3 : result),
CrateId = result2,
RewardId = result3
};
}
}
public sealed class WindTotemQuestArea : MonoBehaviour
{
public Transform Source;
public bool IsGiver;
public bool IsReturn;
public WindTotemQuestArea Giver;
internal static readonly Vector3 CrateLocalPosition = new Vector3(-1.4f, 1.3f, -0.42f);
private readonly HashSet<Collider> players = new HashSet<Collider>();
private QuestDialogue dialogue;
private Rigidbody body;
private Collider trigger;
private bool accepting;
private bool delivering;
private int dialogueStage = -1;
private float retry;
private bool missingDialogueLogged;
private bool offerOpen;
private GameObject returnAreaObject;
private float returnRetry;
private bool WithinOfferDistance
{
get
{
//IL_0023: 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_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
if (Object.op_Implicit((Object)(object)Refs.observerMirror) && Object.op_Implicit((Object)(object)Source))
{
Vector3 val = ((Component)Refs.observerMirror).transform.position - Source.position;
return ((Vector3)(ref val)).sqrMagnitude <= 25f;
}
return false;
}
}
private bool Available
{
get
{
if (Object.op_Implicit((Object)(object)Source) && ((Component)Source).gameObject.activeInHierarchy && WindTotemPlugin.Ready && QuestSave.Valid && !GameState.currentlyLoading && !GameState.justStarted && !GameState.recovering)
{
return !GameState.sleeping;
}
return false;
}
}
private void Awake()
{
body = ((Component)this).GetComponent<Rigidbody>();
trigger = ((Component)this).GetComponent<Collider>();
}
private void Start()
{
EnsureReturnArea();
}
private void EnsureReturnArea()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
if (!IsGiver || Object.op_Implicit((Object)(object)returnAreaObject) || Time.unscaledTime < returnRetry)
{
return;
}
returnRetry = Time.unscaledTime + 5f;
GameObject val = new GameObject("Wind Totem return delivery");
try
{
val.SetActive(false);
SceneManager.MoveGameObjectToScene(val, ((Component)this).gameObject.scene);
val.layer = 2;
val.transform.position = Source.TransformPoint(CrateLocalPosition);
Rigidbody obj = val.AddComponent<Rigidbody>();
obj.isKinematic = true;
obj.useGravity = false;
SphereCollider obj2 = val.AddComponent<SphereCollider>();
obj2.radius = 2f;
((Collider)obj2).isTrigger = true;
WindTotemQuestArea windTotemQuestArea = val.AddComponent<WindTotemQuestArea>();
windTotemQuestArea.Source = Source;
windTotemQuestArea.IsReturn = true;
windTotemQuestArea.Giver = this;
val.SetActive(true);
returnAreaObject = val;
}
catch (Exception ex)
{
val.SetActive(false);
Object.Destroy((Object)(object)val);
WindTotemPlugin.Error("Return area setup failed; retrying: " + ex);
}
}
private void FixedUpdate()
{
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)Source))
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
if (IsGiver && !Object.op_Implicit((Object)(object)returnAreaObject))
{
EnsureReturnArea();
}
trigger.enabled = ((Component)Source).gameObject.activeInHierarchy;
if (!trigger.enabled || GameState.currentlyLoading)
{
players.Clear();
}
body.position = (IsReturn ? Source.TransformPoint(CrateLocalPosition) : Source.position);
body.rotation = Quaternion.identity;
}
private void Update()
{
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
if (IsReturn)
{
return;
}
players.RemoveWhere((Collider c) => !Object.op_Implicit((Object)(object)c) || !((Component)c).gameObject.activeInHierarchy);
int stage = QuestSave.Progress.Stage;
if (dialogueStage != stage)
{
dialogue?.Dispose();
dialogue = null;
dialogueStage = stage;
retry = 0f;
}
if (IsGiver)
{
if (!Available || (stage != 0 && stage != 3) || !WithinOfferDistance)
{
offerOpen = false;
}
else if (players.Count > 0)
{
offerOpen = true;
}
}
if (Available)
{
bool num;
if (!IsGiver)
{
if (stage != 2 || !Object.op_Implicit((Object)(object)Refs.observerMirror))
{
goto IL_0105;
}
num = Vector3.Distance(((Component)Refs.observerMirror).transform.position, Source.position) < 6f;
}
else
{
num = offerOpen;
}
if (num)
{
if (dialogue == null && Time.unscaledTime >= retry)
{
retry = Time.unscaledTime + 0.5f;
dialogue = QuestDialogue.Create(((Component)this).transform, (!IsGiver) ? "Your fellow sailor will no longer need this. You should bring this back to Dead Cove." : ((stage == 3) ? "Oh… then I suppose the priest from Neverdin has already seen to him. You sailed to the end of the Emerald sea just to help a stranger. That was kind of you. Keep the totem. I hope it serves you well." : "The monks at the Sanctuary sent word of a recent vision: a dhow stranded far to the north, at the edge of the Emerald Sea. They asked me to send help to its unfortunate sailor. Please, take this crate to him. Its contents may yet be of use. Ask around Happy Bay harbour, someone there may know where he went."), (IsGiver && stage == 0) ? new Action(Accept) : null);
if (dialogue == null && !missingDialogueLogged)
{
missingDialogueLogged = true;
WindTotemPlugin.Error("Quest trigger reached, but the vanilla dialogue template is not yet available; retrying.");
}
}
dialogue?.Show(Source, IsGiver);
return;
}
}
goto IL_0105;
IL_0105:
dialogue?.Hide();
}
private void OnTriggerEnter(Collider other)
{
Observe(other);
}
private void OnTriggerStay(Collider other)
{
Observe(other);
}
private void OnTriggerExit(Collider other)
{
players.Remove(other);
}
private void Observe(Collider other)
{
if (((Component)other).CompareTag("Player") && players.Add(other) && IsGiver)
{
WindTotemPlugin.Log("Player entered Modular NPC (1) quest radius; ready=" + WindTotemPlugin.Ready + ", stage=" + QuestSave.Progress.Stage + ", loading=" + GameState.currentlyLoading);
}
if (IsGiver || !Available || delivering || QuestSave.Progress.Stage != ((!IsReturn) ? 1 : 2))
{
return;
}
ShipItem val = ((Component)other).GetComponentInParent<ShipItem>();
if (!Object.op_Implicit((Object)(object)val))
{
ItemRigidbody componentInParent = ((Component)other).GetComponentInParent<ItemRigidbody>();
if (Object.op_Implicit((Object)(object)componentInParent))
{
val = componentInParent.GetShipItem();
}
}
SaveablePrefab val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<SaveablePrefab>() : null);
if (!Object.op_Implicit((Object)(object)val2) || !QuestSave.Progress.Matches(val2.prefabIndex, val2.instanceId))
{
return;
}
if (!IsReturn)
{
if (QuestSave.Progress.Visit(val2.instanceId))
{
QuestSave.Store();
WindTotemPlugin.Log("Rock of Despair visited; return crate " + val2.instanceId + " to Dead Cove.");
}
return;
}
if (Object.op_Implicit((Object)(object)((PickupableItem)val).held))
{
((PickupableItem)val).OnDrop();
((PickupableItem)val).held.DropItem();
}
((MonoBehaviour)this).StartCoroutine(Deliver(val, val2.instanceId));
}
private void Accept()
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
if (!Available || accepting || !offerOpen || !WithinOfferDistance || QuestSave.Progress.Stage != 0)
{
return;
}
accepting = true;
try
{
ShipItem val = QuestItems.SpawnAndCommit(608, Source.TransformPoint(CrateLocalPosition), QuestSave.Progress.Accept);
SaveablePrefab component = ((Component)val).GetComponent<SaveablePrefab>();
QuestSave.Store();
dialogue?.Hide();
((MonoBehaviour)this).StartCoroutine(QuestItems.ReleasePhysics(val));
WindTotemPlugin.Log("Quest accepted; crate instance " + component.instanceId);
}
catch (Exception ex)
{
WindTotemPlugin.Error("Quest acceptance failed: " + ex);
}
finally
{
accepting = false;
}
}
private IEnumerator Deliver(ShipItem crate, int crateId)
{
delivering = true;
ShipItem val = null;
try
{
val = QuestItems.SpawnAndCommit(609, Source.TransformPoint(CrateLocalPosition), (int id) => QuestSave.Progress.Complete(crateId, id));
int instanceId = ((Component)val).GetComponent<SaveablePrefab>().instanceId;
QuestSave.Store();
crate.DestroyItem();
if (Object.op_Implicit((Object)(object)Giver))
{
Giver.offerOpen = true;
}
WindTotemPlugin.Log("Quest completed; reward instance " + instanceId);
}
catch (Exception ex)
{
WindTotemPlugin.Error("Quest delivery failed: " + ex);
}
if (Object.op_Implicit((Object)(object)val))
{
yield return QuestItems.ReleasePhysics(val);
}
delivering = false;
}
}
internal static class QuestSave
{
private const string Key = "DogEggz.WindTotem.Quest.v1";
internal static QuestProgress Progress = new QuestProgress();
internal static bool Valid = true;
internal static void Reset()
{
Progress = new QuestProgress();
Valid = true;
}
internal static void Load()
{
Reset();
try
{
string value = null;
GameState.modData?.TryGetValue("DogEggz.WindTotem.Quest.v1", out value);
int[] array = (Object.op_Implicit((Object)(object)Quests.instance) ? Quests.instance.currentQuests : null);
Progress = QuestProgress.Reconcile(value, (array != null && array.Length > 1) ? array[1] : 0);
SyncVanilla();
}
catch (Exception ex)
{
Valid = false;
WindTotemPlugin.Error(ex.Message);
}
}
internal static void Store()
{
if (Valid)
{
if (GameState.modData == null)
{
GameState.modData = new Dictionary<string, string>();
}
GameState.modData["DogEggz.WindTotem.Quest.v1"] = Progress.Encode();
SyncVanilla();
}
}
private static void SyncVanilla()
{
if (Valid && Object.op_Implicit((Object)(object)Quests.instance))
{
int[] array = Quests.instance.currentQuests ?? new int[0];
if (array.Length < 2)
{
Array.Resize(ref array, 2);
}
array[1] = ((Progress.Stage == 3) ? (-5) : ((Progress.Stage == 2) ? (-2) : ((Progress.Stage == 1) ? (-1) : 0)));
Quests.instance.currentQuests = array;
}
}
}
[HarmonyPatch(typeof(SaveLoadManager), "Awake")]
internal static class QuestNewSession
{
private static void Prefix()
{
QuestSave.Reset();
}
}
[HarmonyPatch(typeof(SaveLoadManager), "LoadGame")]
internal static class QuestLoading
{
private static void Prefix()
{
QuestSave.Reset();
GameState.modData?.Remove("DogEggz.WindTotem.Quest.v1");
}
}
[HarmonyPatch(typeof(SaveLoadManager), "LoadModData")]
internal static class QuestLoad
{
private static void Postfix()
{
QuestSave.Load();
}
}
[HarmonyPatch(typeof(SaveLoadManager), "SaveModData")]
internal static class QuestStore
{
private static void Prefix()
{
QuestSave.Store();
}
}
public static class QuestText
{
public const string Offer = "The monks at the Sanctuary sent word of a recent vision: a dhow stranded far to the north, at the edge of the Emerald Sea. They asked me to send help to its unfortunate sailor. Please, take this crate to him. Its contents may yet be of use. Ask around Happy Bay harbour, someone there may know where he went.";
public const string Finish = "Oh… then I suppose the priest from Neverdin has already seen to him. You sailed to the end of the Emerald sea just to help a stranger. That was kind of you. Keep the totem. I hope it serves you well.";
public const string Rock = "Your fellow sailor will no longer need this. You should bring this back to Dead Cove.";
public const string PortLine = "No, I don’t recall a boat like that. Try asking Lee, the cart loader sitting outside. He might have seen it.";
public const string LeeLine = "Oh, yes, I remember that boat! You don’t often see a dhow in these waters. I think he headed east. Now, do you need anything hauled? My services are well worth the coin!";
}
internal static class WindHold
{
[HarmonyPatch(typeof(Wind), "Update")]
private static class Tick
{
private static void Prefix(Wind __instance)
{
if (Active)
{
if (GameState.currentlyLoading)
{
Reset();
}
else
{
Advance(Time.unscaledDeltaTime, Time.timeScale <= 0f);
}
}
}
}
[HarmonyPatch(typeof(Wind), "SetNewWindTarget")]
private static class LockBase
{
[HarmonyPriority(800)]
private static bool Prefix(Wind __instance, ref Vector3 ___currentWindTarget)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (!Active)
{
return true;
}
Wind.currentBaseWind = commanded;
__instance.outCurrentBaseWind = commanded;
___currentWindTarget = commanded;
return false;
}
[HarmonyPriority(0)]
private static void Postfix(Wind __instance, ref Vector3 ___currentWindTarget)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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)
if (Active)
{
Wind.currentBaseWind = commanded;
__instance.outCurrentBaseWind = commanded;
___currentWindTarget = commanded;
}
}
}
[HarmonyPatch(typeof(Wind), "Awake")]
private static class NewSession
{
private static void Prefix()
{
Reset();
}
}
[HarmonyPatch(typeof(Wind), "LoadWind")]
private static class Load
{
private static void Prefix()
{
Reset();
}
}
private static PortableWindOrb owner;
private static Vector3 commanded;
private static float remaining;
internal static bool Active => remaining > 0f;
internal static void Command(PortableWindOrb orb, Vector3 wind)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
owner = orb;
commanded = wind;
remaining = 0f;
Wind.instance.ForceNewWind(wind);
}
internal static void Release(PortableWindOrb orb)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)owner != (Object)(object)orb) && Object.op_Implicit((Object)(object)Wind.instance))
{
owner = null;
if (!GameState.currentlyLoading && !GameState.sleeping && !GameState.recovering)
{
remaining = 60f;
Wind.instance.ForceNewWind(commanded);
}
}
}
internal static void Reset()
{
owner = null;
remaining = 0f;
}
internal static void Advance(float realSeconds, bool paused)
{
//IL_0037: 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_004b: Unknown result type (might be due to invalid IL or missing references)
if (!(!Active || paused))
{
remaining = Mathf.Max(0f, remaining - realSeconds);
if (!Active && Object.op_Implicit((Object)(object)Wind.instance))
{
Vector3 currentWind = Wind.currentWind;
Wind.instance.ForceNewWind(commanded);
Wind.currentWind = currentWind;
}
}
}
}
}