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.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Crest;
using HarmonyLib;
using UnityEngine;
using cakeslice;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RadRefinements")]
[assembly: AssemblyDescription("https://github.com/bryon82/SailwindRadRefinements")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("raddude")]
[assembly: AssemblyProduct("RadRefinements")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c0c6b307-93f0-4209-8594-7f911e48e709")]
[assembly: AssemblyFileVersion("1.6.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.6.0.0")]
[module: UnverifiableCode]
namespace RadRefinements
{
internal class AddReadingTextsPatches
{
[HarmonyPatch(typeof(ShipItem))]
private class ShipItemPatches
{
private static Transform textMeshTemplate;
[HarmonyPrefix]
[HarmonyPatch("Awake")]
public static void AddTextMesh(ShipItem __instance)
{
//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_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_030c: Unknown result type (might be due to invalid IL or missing references)
//IL_0311: Unknown result type (might be due to invalid IL or missing references)
//IL_0280: Unknown result type (might be due to invalid IL or missing references)
//IL_0294: Unknown result type (might be due to invalid IL or missing references)
//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
//IL_0431: Unknown result type (might be due to invalid IL or missing references)
//IL_0436: Unknown result type (might be due to invalid IL or missing references)
//IL_049a: Unknown result type (might be due to invalid IL or missing references)
//IL_049f: Unknown result type (might be due to invalid IL or missing references)
//IL_0506: Unknown result type (might be due to invalid IL or missing references)
//IL_050b: Unknown result type (might be due to invalid IL or missing references)
//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
//IL_05a9: Unknown result type (might be due to invalid IL or missing references)
//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
//IL_06da: Unknown result type (might be due to invalid IL or missing references)
//IL_0637: Unknown result type (might be due to invalid IL or missing references)
//IL_063c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)textMeshTemplate == (Object)null)
{
textMeshTemplate = ((Component)DayLogs.instance).transform.parent.GetChild(0).GetChild(1);
}
if (__instance.name == "chronometer")
{
TextMesh readingTextMesh = AddTextMesh(((Component)__instance).transform, new Vector3(0f, -0.3f, -0.2f), Vector3.zero);
ReadingText readingText = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText.readingTextMesh = readingTextMesh;
readingText.shipItem = __instance;
readingText.isClock = true;
}
else if (__instance.name == "compass" || __instance.name == "bearing compass")
{
TextMesh val = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.03f, 0f), Vector3.zero);
val.lineSpacing = 0.6f;
ReadingText readingText2 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText2.readingTextMesh = val;
readingText2.shipItem = __instance;
readingText2.isCompass = true;
if (__instance.name == "bearing compass")
{
readingText2.isCompassFlipped = true;
readingText2.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "CompassCard"));
}
else
{
readingText2.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "compass_base"));
}
}
else if (__instance.name == "sun compass")
{
TextMesh val2 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0f, 0.18f), new Vector3(45f, 0f, 0f));
val2.fontSize = 20;
ReadingText readingText3 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText3.readingTextMesh = val2;
readingText3.shipItem = __instance;
readingText3.isSunCompass = true;
}
else if (__instance.name == "quadrant")
{
TextMesh val3 = AddTextMesh(((IEnumerable<Transform>)((Component)((Component)__instance).transform).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "dial")), new Vector3(-0.025f, -0.19f, -0.03f), new Vector3(0f, 90f, 270f));
val3.fontSize = 40;
ReadingText readingText4 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText4.readingTextMesh = val3;
readingText4.shipItem = __instance;
readingText4.isQuadrant = true;
}
else if (__instance.name == "chip log")
{
TextMesh readingTextMesh2 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.21f, -0.02f), Vector3.zero);
string pointerName = "pointer_002";
if (((Object)((Component)__instance).transform).name == "93 chip log E(Clone)")
{
pointerName = "pointer_001";
}
ReadingText readingText5 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText5.readingTextMesh = readingTextMesh2;
readingText5.shipItem = __instance;
readingText5.isChipLog = true;
readingText5.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == pointerName));
}
else if (__instance.name == "barometer")
{
TextMesh readingTextMesh3 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.12f, -0.075f), Vector3.zero);
ReadingText readingText6 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText6.readingTextMesh = readingTextMesh3;
readingText6.shipItem = __instance;
readingText6.isBarometer = true;
}
else if (__instance.name == "thermometer")
{
TextMesh readingTextMesh4 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.12f, -0.075f), Vector3.zero);
ReadingText readingText7 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText7.readingTextMesh = readingTextMesh4;
readingText7.shipItem = __instance;
readingText7.isThermometer = true;
}
else if (__instance.name == "hygrometer")
{
TextMesh readingTextMesh5 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.12f, -0.075f), Vector3.zero);
ReadingText readingText8 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText8.readingTextMesh = readingTextMesh5;
readingText8.shipItem = __instance;
readingText8.isHygrometer = true;
}
else if (__instance.name == "inclinometer")
{
TextMesh readingTextMesh6 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.12f, -0.05f), Vector3.zero);
ReadingText readingText9 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText9.readingTextMesh = readingTextMesh6;
readingText9.shipItem = __instance;
readingText9.isInclinometer = true;
readingText9.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "Arm"));
}
else if (__instance.name == "binnacle")
{
TextMesh val4 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 1.26f, 0f), Vector3.zero);
val4.lineSpacing = 0.6f;
ReadingText readingText10 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText10.readingTextMesh = val4;
readingText10.shipItem = __instance;
readingText10.isCompass = true;
readingText10.isCompassFlipped = true;
readingText10.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "CompassFace"));
TextMesh readingTextMesh7 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.9f, -0.201f), Vector3.zero);
ReadingText readingText11 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText11.readingTextMesh = readingTextMesh7;
readingText11.shipItem = __instance;
readingText11.isInclinometer = true;
readingText11.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "InclinometerArm"));
}
else if (__instance.name == "wind compass")
{
TextMesh val5 = AddTextMesh(((Component)__instance).transform, new Vector3(0f, 0.12f, -0.075f), Vector3.zero);
val5.lineSpacing = 0.6f;
ReadingText readingText12 = ((Component)__instance).gameObject.AddComponent<ReadingText>();
readingText12.readingTextMesh = val5;
readingText12.shipItem = __instance;
readingText12.isWindCompass = true;
readingText12.pointer = ((IEnumerable<Transform>)((Component)__instance).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "indicator"));
}
}
private static TextMesh AddTextMesh(Transform parent, Vector3 position, Vector3 rotation)
{
//IL_002e: 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_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
Transform val = Object.Instantiate<Transform>(textMeshTemplate);
((Object)val).name = "reading_text";
val.SetParent(parent);
((Component)val).gameObject.layer = 0;
val.localPosition = position;
val.localEulerAngles = rotation;
val.localScale = new Vector3(0.0114f, 0.0127f, 0.0127f);
TextMesh component = ((Component)val).GetComponent<TextMesh>();
component.color = Color32.op_Implicit(new Color32((byte)219, (byte)214, (byte)201, (byte)136));
component.fontSize = 55;
component.fontStyle = (FontStyle)0;
component.anchor = (TextAnchor)7;
component.richText = true;
((Component)val).gameObject.SetActive(false);
return component;
}
}
}
internal class ItemPatches
{
[HarmonyPatch(typeof(ShipItem), "OnLoad")]
private class ShipItemPatches
{
public static void Postfix(ShipItem __instance)
{
if (__instance is ShipItemHammer && Configs.removeItemHints.Value && __instance.sold)
{
((GoPointerButton)__instance).description = "";
}
}
}
}
internal class PipePatches
{
[HarmonyPatch(typeof(ShipItem), "OnAltActivate")]
private class ShipItemPatches
{
public static void Postfix(ShipItem __instance)
{
if (Configs.enableSingleClickSmoking.Value)
{
ShipItemPipe val = (ShipItemPipe)(object)((__instance is ShipItemPipe) ? __instance : null);
if (val != null && ((ShipItem)val).sold)
{
_clickedCount++;
((MonoBehaviour)__instance).StartCoroutine(MovePipe(val));
}
}
}
private static IEnumerator MovePipe(ShipItemPipe pipe)
{
while (Object.op_Implicit((Object)(object)((PickupableItem)pipe).held) && (double)((PickupableItem)pipe).holdDistance > 0.25 && _clickedCount % 2 != 0 && ((ShipItem)pipe).amount > 0f)
{
((PickupableItem)pipe).holdDistance = Mathf.Lerp(((PickupableItem)pipe).holdDistance, 0.25f, Time.deltaTime * 4.44f);
((PickupableItem)pipe).holdHeight = Mathf.Lerp(((PickupableItem)pipe).holdHeight, pipe.height, Time.deltaTime * 4.44f);
((PickupableItem)pipe).heldRotationOffset = Mathf.Lerp(((PickupableItem)pipe).heldRotationOffset, 0f - pipe.maxRot, Time.deltaTime * pipe.rotRate);
pipe.SetPrivateField("inhaling", !PipeExhaleEffect.instance.exhaling);
pipe.SetPrivateField("drinking", true);
yield return null;
}
if (!Object.op_Implicit((Object)(object)((PickupableItem)pipe).held) || ((ShipItem)pipe).amount <= 0f)
{
_clickedCount = 0;
}
}
}
[HarmonyPatch(typeof(ShipItemPipe), "OnAltHeld")]
public class ShipItemPipePatches
{
public static bool Prefix()
{
if (Configs.enableSingleClickSmoking.Value)
{
return false;
}
return true;
}
}
private static int _clickedCount;
}
internal class ReadingText : MonoBehaviour
{
internal TextMesh readingTextMesh;
internal ShipItem shipItem;
internal Transform pointer;
private bool _isInSunlight;
private float _sunlightTimer;
internal bool isCompass;
internal bool isChipLog;
internal bool isClock;
internal bool isQuadrant;
internal bool isSunCompass;
internal bool isInclinometer;
internal bool isBarometer;
internal bool isThermometer;
internal bool isHygrometer;
internal bool isWindCompass;
internal bool isCompassFlipped = false;
private const float ANGLE_TO_KNOTS = 1f / 15f;
private static readonly Vector3 NOT_HELD_SIZE = new Vector3(0.0114f, 0.0127f, 0.0127f);
private static readonly Vector3 HELD_SIZE = new Vector3(0.0044f, 0.0057f, 0.0057f);
private void LateUpdate()
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: 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_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0426: Unknown result type (might be due to invalid IL or missing references)
//IL_0435: Expected O, but got Unknown
//IL_0439: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: 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_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_0552: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_07e9: Unknown result type (might be due to invalid IL or missing references)
//IL_021c: Unknown result type (might be due to invalid IL or missing references)
//IL_08e3: Unknown result type (might be due to invalid IL or missing references)
//IL_08e8: Unknown result type (might be due to invalid IL or missing references)
//IL_08ed: Unknown result type (might be due to invalid IL or missing references)
//IL_08ee: Unknown result type (might be due to invalid IL or missing references)
//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
//IL_08f4: Unknown result type (might be due to invalid IL or missing references)
//IL_091e: Unknown result type (might be due to invalid IL or missing references)
//IL_093e: Unknown result type (might be due to invalid IL or missing references)
//IL_0937: Unknown result type (might be due to invalid IL or missing references)
//IL_0954: Unknown result type (might be due to invalid IL or missing references)
//IL_096a: Unknown result type (might be due to invalid IL or missing references)
if (!GameState.playing || GameState.currentlyLoading || GameState.loadingBoatLocalItems || (Object)(object)readingTextMesh == (Object)null)
{
return;
}
if (BoatCamera.on)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
bool flag = (Object)(object)((PickupableItem)shipItem).held != (Object)null;
Vector3 position = ((Component)Refs.observerMirror).transform.position;
Vector3 position2 = ((Component)this).transform.position;
float num = Vector3.Distance(position, position2);
bool flag2 = !shipItem.sold || ((Component)this).gameObject.layer == 5 || (Object)(object)shipItem.currentActualBoat == (Object)null;
bool flag3 = flag || flag2 || Vector3.Angle(-((Component)this).transform.forward, position - position2) > 85f || SpyglassPatches.HeldAndUp;
if (isCompass)
{
if (!((Object)(object)pointer == (Object)null))
{
if ((!Configs.enableCompassDegreesText.Value && !Configs.enableCompassCardinalText.Value) || (flag && !Configs.enableCompassReadingHeld.Value) || flag2 || num > Configs.compassViewDist.Value || SpyglassPatches.HeldAndUp)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float num2 = (flag ? 0f : Vector3.SignedAngle(-((Component)this).transform.forward, position - position2, Vector3.up));
((Component)readingTextMesh).transform.localEulerAngles = new Vector3(0f, num2, 0f);
((Component)readingTextMesh).transform.localScale = (flag ? HELD_SIZE : NOT_HELD_SIZE);
float num3 = (isCompassFlipped ? 180f : 360f);
float reading = (180f - ((Component)pointer).transform.localEulerAngles.y + num3) % 360f;
readingTextMesh.text = GetCompassReading(reading, Configs.compassCardinalPrecision.Value);
((Component)readingTextMesh).gameObject.SetActive(true);
}
}
else if (isChipLog)
{
if (!((Object)(object)pointer == (Object)null))
{
if (!Configs.enableChipLogText.Value || flag3 || num > Configs.chipLogViewDist.Value || !shipItem.GetPrivateField<bool>("thrown"))
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
readingTextMesh.text = $"{(360f - pointer.localEulerAngles.z) * (1f / 15f):F1} kts";
((Component)readingTextMesh).gameObject.SetActive(true);
}
}
else if (isClock)
{
if ((!Configs.enableClockGlobalText.Value && !Configs.enableClockLocalText.Value) || flag3 || num > Configs.clockViewDist.Value)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
readingTextMesh.text = GetClockReading();
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isQuadrant)
{
if (!Configs.enableQuadrantText.Value || !shipItem.GetPrivateField<bool>("inspecting") || shipItem.GetPrivateField<bool>("rotating"))
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
Transform privateField = ((object)(ShipItemQuadrant)shipItem).GetPrivateField<Transform>("dial");
double num4 = Math.Round(privateField.localEulerAngles.x, 2);
readingTextMesh.text = $"{num4}°";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isSunCompass)
{
if (!Configs.enableSunCompassText.Value || (Object)(object)((PickupableItem)shipItem).held == (Object)null || ((Component)this).gameObject.layer == 5)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
_sunlightTimer += Time.deltaTime;
if (_sunlightTimer >= 5f)
{
_sunlightTimer = 0f;
_isInSunlight = IsInSunlight();
}
if (!_isInSunlight)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float z = FloatingOriginManager.instance.GetGlobeCoords(((Component)this).transform).z;
readingTextMesh.text = $"{z:F1}°";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isBarometer)
{
if (!Configs.enableBarometerText.Value || flag3 || num > Configs.barometerViewDist.Value)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float privateField2 = shipItem.GetPrivateField<float>("_pressure");
readingTextMesh.text = $"{Mathf.Lerp(26f, 31.9f, privateField2):F1}inHg";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isThermometer)
{
if (!Configs.enableThermometerText.Value || flag3 || num > Configs.thermometerViewDist.Value)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float privateField3 = shipItem.GetPrivateField<float>("_temperature");
readingTextMesh.text = $"{Mathf.Lerp(10f, 115f, privateField3):F1}°F";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isHygrometer)
{
if (!Configs.enableHygrometerText.Value || flag3 || num > Configs.hygrometerViewDist.Value)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float privateField4 = shipItem.GetPrivateField<float>("_humidity");
readingTextMesh.text = $"{privateField4 * 100f:F1}%";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isInclinometer)
{
if ((Object)(object)pointer == (Object)null)
{
return;
}
if (!Configs.enableInclinometerText.Value || flag3 || num > Configs.inclinometerViewDist.Value)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float num5 = pointer.localEulerAngles.z;
if (num5 > 180f)
{
num5 = (Configs.negativeInclinometerAngles.Value ? (num5 - 360f) : (360f - num5));
}
readingTextMesh.text = $"{num5:F1}°";
((Component)readingTextMesh).gameObject.SetActive(true);
}
else if (isWindCompass && !((Object)(object)pointer == (Object)null))
{
if ((!Configs.enableWindCompassDegreesText.Value && !Configs.enableWindCompassCardinalText.Value) || flag || flag2 || num > Configs.compassViewDist.Value || SpyglassPatches.HeldAndUp)
{
((Component)readingTextMesh).gameObject.SetActive(false);
return;
}
float num6 = (flag ? 0f : Vector3.SignedAngle(-((Component)this).transform.forward, position - position2, Vector3.up));
((Component)readingTextMesh).transform.localEulerAngles = new Vector3(0f, num6, 0f);
((Component)readingTextMesh).transform.localScale = (flag ? HELD_SIZE : NOT_HELD_SIZE);
float reading2 = (((Component)pointer).transform.localEulerAngles.y + 180f + ((Component)this).transform.eulerAngles.y) % 360f;
readingTextMesh.text = GetCompassReading(reading2, Configs.windCompassCardinalPrecision.Value);
((Component)readingTextMesh).gameObject.SetActive(true);
}
}
private static string GetCompassReading(float reading, int cardinalPrecision)
{
if (!Configs.enableCompassCardinalText.Value)
{
return $"{reading:F1}°";
}
if (!Configs.enableCompassDegreesText.Value)
{
return CompassRose.GetAbbreviatedDir(reading, cardinalPrecision);
}
return $"{CompassRose.GetAbbreviatedDir(reading, cardinalPrecision)}\n{reading:F1}°";
}
private static string GetClockReading()
{
float globalTime = Sun.sun.globalTime;
float localTime = Sun.sun.localTime;
if (!Configs.enableClockLocalText.Value)
{
return GetTime(globalTime);
}
if (!Configs.enableClockGlobalText.Value)
{
return GetTime(localTime);
}
return GetTime(globalTime) + "\n\n\n\n" + GetTime(localTime);
}
private static string GetTime(float time)
{
int num = (int)time;
double num2 = Math.Round(time % 1f * 60f) % 60.0;
return $"{num:00}:{num2:00}";
}
private bool IsInSunlight()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: 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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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)
float localTime = Sun.sun.localTime;
if ((Object)(object)((PickupableItem)shipItem).held == (Object)null || localTime < 11f || localTime > 13f)
{
return false;
}
Vector3 val = -((Component)Sun.sun).transform.forward;
int num = -5;
Vector3 val2 = ((Component)this).transform.position + val * 0.01f;
bool flag = Physics.Raycast(val2, val, float.PositiveInfinity, num, (QueryTriggerInteraction)2);
return !flag;
}
}
internal class Crate
{
public static string GetCrateInventory(ShipItemCrate crate)
{
CrateInventory privateField = crate.GetPrivateField<CrateInventory>("crateInventory");
if ((Object)(object)privateField == (Object)null)
{
return string.Empty;
}
List<ShipItem> containedItems = privateField.containedItems;
if (containedItems == null || containedItems.Count == 0)
{
return string.Empty;
}
Dictionary<string, int> dictionary = new Dictionary<string, int>();
foreach (ShipItem item in containedItems)
{
string key = NormalizeKey(item);
if (!dictionary.ContainsKey(key))
{
dictionary[key] = 1;
}
else
{
dictionary[key]++;
}
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("crate");
foreach (KeyValuePair<string, int> item2 in dictionary.OrderBy((KeyValuePair<string, int> p) => p.Key))
{
stringBuilder.AppendLine($"{item2.Key}: {item2.Value}");
}
return stringBuilder.ToString();
}
private static string NormalizeKey(ShipItem item)
{
string name = item.name;
string text = ((GoPointerButton)item).description;
int num = text.IndexOf('<');
if (num >= 0)
{
text = text.Substring(0, num);
}
if (text.IndexOf('%') >= 0)
{
return name;
}
if (name.Equals("fishing hook") || name.Equals("knife") || name.Equals("hammer"))
{
return name;
}
return Utility.IsNullOrWhiteSpace(text) ? name : text;
}
}
internal class KnifeWood : MonoBehaviour
{
private KnifeWoodCollider _knifeWoodCol;
public void RegisterKnifeWoodCol(KnifeWoodCollider col)
{
_knifeWoodCol = col;
}
internal void CutContainer(ShipItem container)
{
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: 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_010a: Unknown result type (might be due to invalid IL or missing references)
if ((container is ShipItemBottle && container.health > 0f) || (!(container is ShipItemBottle) && container.amount > 0f))
{
return;
}
ShipItemCrate val = (ShipItemCrate)(object)((container is ShipItemCrate) ? container : null);
if (val == null || val.GetPrivateField<CrateInventory>("crateInventory").containedItems.Count <= 0)
{
string key = ((Component)container).gameObject.GetComponent<Good>()?.sizeDescription ?? container.name;
int num = Knife.WoodPiecesPerContainer[key];
float num2 = -0.01f * (float)num;
for (int i = 0; i < num; i++)
{
GameObject val2 = Object.Instantiate<GameObject>(PrefabsDirectory.instance.directory[71]);
val2.transform.position = ((Component)container).transform.position + ((Component)container).transform.right * num2;
val2.transform.rotation = ((Component)container).transform.rotation * Quaternion.Euler(0f, 90f, 0f);
num2 += 0.02f;
ShipItemStoveFuel component = val2.GetComponent<ShipItemStoveFuel>();
((ShipItem)component).sold = true;
val2.GetComponent<SaveablePrefab>().RegisterToSave();
}
((Component)container).GetComponent<ShipItem>().DestroyItem();
((MonoBehaviour)this).StartCoroutine(MakeLocalPosTracker());
}
}
internal IEnumerator MakeLocalPosTracker()
{
yield return (object)new WaitForEndOfFrame();
if ((Object)(object)CrateInventoryUI.instance.GetPrivateField<Transform>("localPosTracker") == (Object)null)
{
CrateInventoryUI.instance.SetPrivateField("localPosTracker", Object.Instantiate<GameObject>(new GameObject()).transform);
}
}
}
internal class KnifeWoodCollider : MonoBehaviour
{
public ShipItem CurrentWood { get; private set; }
private void Awake()
{
((Component)((Component)this).transform.parent).GetComponent<KnifeWood>().RegisterKnifeWoodCol(this);
}
public void OnTriggerEnter(Collider other)
{
ShipItem component = ((Component)other).GetComponent<ShipItem>();
if ((Object)(object)component == (Object)null)
{
return;
}
RR_Plugin.LogDebug("KnifeCollider: entering wood col: " + component.name);
if (!(component is ShipItemBottle) || !(component.health <= 0f))
{
if (!(component is ShipItemCrate))
{
return;
}
ShipItemCrate component2 = ((Component)component).gameObject.GetComponent<ShipItemCrate>();
if (component2 == null || !(component2.GetPrivateField<CrateInventory>("crateInventory")?.containedItems.Count <= 0))
{
return;
}
}
CurrentWood = component;
}
public void OnTriggerExit(Collider other)
{
if ((Object)(object)((Component)other).GetComponent<ShipItem>() == (Object)(object)CurrentWood)
{
CurrentWood = null;
}
}
}
public class Knife
{
private static readonly Dictionary<string, int> _woodPiecesPerContainer = new Dictionary<string, int>
{
{ "small crate", 4 },
{ "standard crate", 6 },
{ "large crate", 8 },
{ "very large crate", 10 },
{ "standard barrel", 6 },
{ "firewood", 4 },
{ "fishing hooks", 4 },
{ "lantern candles", 2 },
{ "green tobacco", 2 },
{ "blue tobacco", 2 },
{ "black tobacco", 2 },
{ "brown tobacco", 2 },
{ "white tobacco", 2 },
{ "coffee", 2 },
{ "white tea", 2 },
{ "black tea", 2 },
{ "green tea", 2 },
{ "empty crate", 6 },
{ "sealing nails", 2 },
{ "spoon lures", 2 },
{ "swimbait lures", 2 },
{ "topwater lures", 2 }
};
public static Dictionary<string, int> WoodPiecesPerContainer => _woodPiecesPerContainer;
}
internal class SwapSlot : MonoBehaviour
{
public static SwapSlot Instance { get; private set; }
internal static GPButtonInventorySlot Slot { get; private set; }
internal static GoPointer GoPntr { get; set; }
private void Awake()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
Instance = this;
Slot = new GPButtonInventorySlot();
}
public void SwapItems(PickupableItem item, GPButtonInventorySlot invSlot)
{
ShipItem component = ((Component)item).GetComponent<ShipItem>();
if (!component.sold || !Object.op_Implicit((Object)(object)component) || ((PickupableItem)component).big)
{
return;
}
ShipItemBottle component2 = ((Component)item).GetComponent<ShipItemBottle>();
if (!Object.op_Implicit((Object)(object)component2) || !(component2.GetCapacity() > 10f))
{
RR_Plugin.LogDebug("Inserting " + component.name + " into swap slot.");
Slot.currentItem = component;
item.held = null;
((Component)component).GetComponent<Collider>().enabled = false;
((Component)Slot.currentItem).gameObject.layer = 5;
Transform[] componentsInChildren = ((Component)Slot.currentItem).GetComponentsInChildren<Transform>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
((Component)componentsInChildren[i]).gameObject.layer = 5;
}
ShipItem currentItem = invSlot.currentItem;
RR_Plugin.LogDebug("Withdrawing " + currentItem.name + " from inventory slot.");
GoPntr.PickUpItem((PickupableItem)(object)currentItem);
((MonoBehaviour)this).StartCoroutine(GrabItem(currentItem));
RR_Plugin.LogDebug("Moving " + Slot.currentItem.name + " from swap slot to inventory slot.");
Debug.Log((object)"Inserting item.");
Slot.currentItem.GetItemRigidbody().EnterInventorySlot(((Component)invSlot).transform);
invSlot.currentItem = Slot.currentItem;
UISoundPlayer.instance.PlayUISound((UISounds)4, 0.2f, 1.36f);
Slot.currentItem = null;
RR_Plugin.LogDebug("Items Swapped");
}
}
private IEnumerator GrabItem(ShipItem item)
{
yield return (object)new WaitForEndOfFrame();
GoPntr.SetPrivateField("heldItem", item);
((Component)item).gameObject.layer = 2;
GoPntr.GetPrivateField<PickupableItem>("heldItem").held = GoPntr;
GoPntr.SetPrivateField("heldItemRot", Vector3.zero);
GoPntr.SetPrivateField("timerAfterPickup", 0f);
((PickupableItem)item).OnPickup();
((Component)((Component)GoPntr).transform.parent).GetComponent<LookUI>().SetPrivateField("currentButton", ((Component)item).gameObject);
}
internal static bool IsItemHeld()
{
return (Object)(object)GoPntr.GetHeldItem() != (Object)null;
}
internal void WithdrawFromSwapSlot()
{
ShipItem currentItem = Slot.currentItem;
RR_Plugin.LogDebug("Withdrawing " + currentItem.name + " from inventory slot.");
GoPntr.PickUpItem((PickupableItem)(object)currentItem);
((MonoBehaviour)this).StartCoroutine(GrabItem(currentItem));
}
internal void SwapSlotToOpenInvSlot()
{
GPButtonInventorySlot val = ((IEnumerable<GPButtonInventorySlot>)GPButtonInventorySlot.inventorySlots).FirstOrDefault((Func<GPButtonInventorySlot, bool>)((GPButtonInventorySlot s) => (Object)(object)s.currentItem == (Object)null));
Slot.currentItem.GetItemRigidbody().EnterInventorySlot(((Component)val).transform);
val.currentItem = Slot.currentItem;
Slot.currentItem = null;
}
}
internal class ViewMap
{
public static string[] MapNames = new string[5] { "ocean map", "Al'Ankh map", "Emerald Archipelago map", "Aestrin map", "Fire Fish Lagoon map" };
private static int _mapSlotIndex = 4;
public static bool GetMapSlotIndex()
{
GPButtonInventorySlot val = ((IEnumerable<GPButtonInventorySlot>)GPButtonInventorySlot.inventorySlots).FirstOrDefault((Func<GPButtonInventorySlot, bool>)((GPButtonInventorySlot s) => Object.op_Implicit((Object)(object)s.currentItem) && MapNames.Contains(s.currentItem.name)));
if (!Object.op_Implicit((Object)(object)val))
{
return false;
}
_mapSlotIndex = val.slotIndex;
return true;
}
public static void ToggleMap()
{
GoPointer goPntr = SwapSlot.GoPntr;
PickupableItem val = ((goPntr != null) ? goPntr.GetHeldItem() : null);
if ((Object)(object)val == (Object)null)
{
return;
}
string text = ((val == null) ? null : ((Component)val).GetComponent<ShipItem>()?.name);
if (Object.op_Implicit((Object)(object)val) && MapNames.Contains(text))
{
RR_Plugin.LogDebug("Stowing map: " + text);
GPButtonInventorySlot val2 = GPButtonInventorySlot.inventorySlots[_mapSlotIndex];
((GoPointerButton)val2).OnActivate();
((GoPointerButton)val2).OnItemClick(val);
goPntr.GetHeldItem().OnDrop();
goPntr.DropItem();
}
else
{
if (!GetMapSlotIndex())
{
return;
}
RR_Plugin.LogDebug("Displaying map: " + GPButtonInventorySlot.inventorySlots[_mapSlotIndex].currentItem.name);
if (!Object.op_Implicit((Object)(object)val) || (!val.big && Configs.enableInventorySwap.Value))
{
GPButtonInventorySlot val3 = GPButtonInventorySlot.inventorySlots[_mapSlotIndex];
if (!Object.op_Implicit((Object)(object)val))
{
((GoPointerButton)val3).OnActivate(goPntr);
}
else
{
((GoPointerButton)val3).OnItemClick(val);
}
ShipItemFoldable component = ((Component)goPntr.GetHeldItem()).GetComponent<ShipItemFoldable>();
if (((ShipItem)component).amount > 0f)
{
component.InvokePrivateMethod("Unfold");
}
}
}
}
}
internal class FishingHookPatches
{
[HarmonyPatch(typeof(ShipItem))]
private class ShipItemFishingHookPatches
{
[HarmonyPostfix]
[HarmonyPatch("OnLoad")]
public static void OnLoadRemoveDescription(ShipItem __instance)
{
if (Configs.removeItemHints.Value && __instance.sold && __instance is ShipItemFishingHook)
{
((GoPointerButton)__instance).description = "";
}
}
[HarmonyPostfix]
[HarmonyPatch("EnterBoat")]
public static void EnterBoatRemoveDescription(ShipItem __instance)
{
if (Configs.removeItemHints.Value && __instance.sold && __instance is ShipItemFishingHook)
{
((GoPointerButton)__instance).description = "";
}
}
}
}
internal class InventoryPatches
{
[HarmonyPatch(typeof(LookUI))]
private class LookUIPatches
{
[HarmonyPrefix]
[HarmonyPatch("RegisterPointer")]
public static void GetPointer(GoPointer goPointer)
{
SwapSlot.GoPntr = goPointer;
}
[HarmonyPostfix]
[HarmonyPatch("LateUpdate")]
public static void ToggleQuickMap()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
if (Configs.enableQuickMap.Value && !GameState.wasInSettingsMenu && Input.GetKeyDown(Configs.quickMapKey.Value))
{
ViewMap.ToggleMap();
}
}
}
[HarmonyPatch(typeof(GPButtonInventorySlot))]
private class GPButtonInventorySlotPatches
{
private static bool swapSlotMade;
[HarmonyPrefix]
[HarmonyPatch("Awake")]
public static void Awake(GPButtonInventorySlot __instance)
{
if (!swapSlotMade)
{
swapSlotMade = true;
Transform parent = ((Component)__instance).transform.parent;
Transform val = Object.Instantiate<Transform>(parent.GetChild(0), parent);
((Object)val).name = "inventory_slot_swap";
Object.Destroy((Object)(object)((Component)val).GetComponent<MeshFilter>());
Object.Destroy((Object)(object)((Component)val).GetComponent<MeshRenderer>());
Object.Destroy((Object)(object)((Component)val).GetComponent<SphereCollider>());
Object.Destroy((Object)(object)((Component)val).GetComponent<GPButtonInventorySlot>());
Object.Destroy((Object)(object)((Component)val).GetComponent<Outline>());
((Component)val).gameObject.AddComponent<SwapSlot>();
}
}
[HarmonyPrefix]
[HarmonyPatch("OnItemClick")]
public static void OnItemClickSwapItems(PickupableItem heldItem, ShipItem ___currentItem, GPButtonInventorySlot __instance)
{
if (Configs.enableInventorySwap.Value && Object.op_Implicit((Object)(object)___currentItem))
{
SwapSlot.Instance.SwapItems(heldItem, __instance);
}
}
}
[HarmonyPatch(typeof(CrateInventoryUI))]
public class CrateInventoryUIPatches
{
[HarmonyPostfix]
[HarmonyPatch("LateUpdate")]
public static void AddItemDescription(CrateInventoryButton[] ___buttons)
{
if (Configs.enableCrateItemDescription.Value)
{
foreach (CrateInventoryButton val in ___buttons)
{
((GoPointerButton)val).description = ((GoPointerButton)(val.GetPrivateField<ShipItem>("currentItem")?)).description ?? "";
}
}
}
}
}
internal class KnifePatches
{
[HarmonyPatch(typeof(ShipItemKnife))]
private class ShipItemKnifePatches
{
[HarmonyPostfix]
[HarmonyPatch("OnAltActivate")]
public static void KnifeCutContainer(ShipItemKnife __instance, ref bool ___animating, ref float ___heldRotationOffset, ref float ___cutTimer)
{
if (Configs.enableWoodFromContainers.Value && ((ShipItem)__instance).sold)
{
ShipItem pointedAtItem = ((PickupableItem)__instance).held.GetPointedAtItem();
Good component = ((Component)pointedAtItem).gameObject.GetComponent<Good>();
if (Object.op_Implicit((Object)(object)pointedAtItem) && pointedAtItem.sold && (Knife.WoodPiecesPerContainer.ContainsKey(pointedAtItem.name) || ((Object)(object)component != (Object)null && Knife.WoodPiecesPerContainer.ContainsKey(component.sizeDescription))))
{
___animating = true;
___heldRotationOffset = 0f;
___cutTimer = 0.25f;
KnifeWood component2 = ((Component)__instance).GetComponent<KnifeWood>();
component2.CutContainer(((Component)pointedAtItem).GetComponent<ShipItem>());
}
}
}
[HarmonyPostfix]
[HarmonyPatch("OnLoad")]
public static void OnLoadPatch(ShipItemKnife __instance)
{
if (Configs.removeItemHints.Value && ((ShipItem)__instance).sold)
{
((GoPointerButton)__instance).description = "";
}
((Component)__instance).gameObject.AddComponent<KnifeWood>();
}
}
[HarmonyPatch(typeof(LookUI))]
private class LookUIPatches
{
[HarmonyPrefix]
[HarmonyPatch("ShowLookText")]
public static bool AddKnifeControlsText(LookUI __instance, GoPointerButton button, GoPointer ___pointer, TextMesh ___textLicon, TextMesh ___textRIcon, ref bool ___showingIcon, TextMesh ___controlsText, TextMesh ___extraText)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
if (!Configs.enableWoodFromContainers.Value)
{
return true;
}
___extraText.text = button.lookText;
((Component)__instance).transform.position = ((Component)button).gameObject.transform.position;
((Component)__instance).transform.LookAt(((Component)Camera.main).transform);
((Component)___textLicon).gameObject.SetActive(false);
((Component)___textRIcon).gameObject.SetActive(false);
___showingIcon = false;
Good component = ((Component)button).gameObject.GetComponent<Good>();
ShipItem component2 = ((Component)button).gameObject.GetComponent<ShipItem>();
if (Object.op_Implicit((Object)(object)___pointer.GetHeldItem()) && Object.op_Implicit((Object)(object)((Component)___pointer.GetHeldItem()).GetComponent<ShipItemKnife>()) && (((Object)(object)component2 != (Object)null && Knife.WoodPiecesPerContainer.ContainsKey(component2.name)) || ((Object)(object)component != (Object)null && Knife.WoodPiecesPerContainer.ContainsKey(component.sizeDescription))))
{
((Component)___textRIcon).gameObject.SetActive(true);
___showingIcon = true;
___controlsText.text = "\ncut";
return false;
}
return true;
}
}
}
internal class LogBookPatches
{
[HarmonyPatch(typeof(MissionListUI))]
private class MissionListUIPatches
{
[HarmonyPostfix]
[HarmonyPatch("ToggleMenu")]
public static void OpenLastOpenBookmark(MissionListUI __instance, bool ___UIActive)
{
if (Configs.enableLogbookLastSection.Value && ___UIActive)
{
__instance.SwitchMode((MissionListMode)_currentPage);
}
}
}
[HarmonyPatch(typeof(GPButtonLogMode))]
private class GPButtonLogModePatches
{
[HarmonyPostfix]
[HarmonyPatch("OnActivate")]
public static void GetLastActivatedBookmark(MissionListMode ___mode)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected I4, but got Unknown
if (Configs.enableLogbookLastSection.Value)
{
_currentPage = (int)___mode;
}
}
}
private static int _currentPage;
}
internal class QuadrantPatches
{
[HarmonyPatch(typeof(ShipItemQuadrant))]
private class ShipItemQuadrantPatches
{
private static bool _rotating;
[HarmonyPrefix]
[HarmonyPatch("OnAltActivate")]
public static bool ReverseLook(ShipItemQuadrant __instance, bool ___inspecting, Transform ___rotatingParent, ref Quaternion ___initialRot)
{
//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_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_0045: 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)
if (Input.GetKey((KeyCode)101) && !___inspecting && !_rotating)
{
((MonoBehaviour)__instance).StartCoroutine(Rotate180(___rotatingParent));
___initialRot *= Quaternion.Euler(Vector3.up * 180f);
return false;
}
return true;
}
private static IEnumerator Rotate180(Transform rotatingParent)
{
_rotating = true;
Quaternion startRotation = rotatingParent.rotation;
Quaternion rotation180 = Quaternion.AngleAxis(180f, Vector3.up);
Quaternion targetRotation = startRotation * rotation180;
float elapsedTime = 0f;
while (elapsedTime < 0.3f)
{
float t = elapsedTime / 0.3f;
t = Mathf.SmoothStep(0f, 1f, t);
rotatingParent.rotation = Quaternion.Slerp(startRotation, targetRotation, t);
elapsedTime += Time.deltaTime;
yield return null;
}
rotatingParent.rotation = targetRotation;
_rotating = false;
}
}
}
internal class SpyglassPatches
{
[HarmonyPatch(typeof(ShipItemSpyglass))]
private static class ShipItemSpyglassPatches
{
[HarmonyPostfix]
[HarmonyPatch("OnAltActivate")]
public static void DisableItemReadingsActivate(ShipItemSpyglass __instance, float ___heldRotationOffset)
{
if (((ShipItem)__instance).sold && ___heldRotationOffset == -22f)
{
HeldAndUp = true;
}
else
{
HeldAndUp = false;
}
}
[HarmonyPostfix]
[HarmonyPatch("OnPickup")]
public static void DisableItemReadingsOnPickup(ShipItemSpyglass __instance, float ___heldRotationOffset)
{
if (((ShipItem)__instance).sold && ___heldRotationOffset == 0f)
{
HeldAndUp = true;
}
else
{
HeldAndUp = false;
}
}
[HarmonyPostfix]
[HarmonyPatch("OnEnterInventory")]
public static void EnableItemReadingsInventory()
{
HeldAndUp = false;
}
[HarmonyPostfix]
[HarmonyPatch("OnDrop")]
public static void EnableItemReadingsDrop()
{
HeldAndUp = false;
}
}
internal static bool HeldAndUp { get; private set; }
}
[BepInPlugin("com.raddude.radrefinements", "RadRefinements", "1.6.0")]
public class RR_Plugin : BaseUnityPlugin
{
public const string PLUGIN_GUID = "com.raddude.radrefinements";
public const string PLUGIN_NAME = "RadRefinements";
public const string PLUGIN_VERSION = "1.6.0";
private static ManualLogSource _logger;
internal static RR_Plugin Instance { get; private set; }
internal static void LogDebug(string message)
{
_logger.LogDebug((object)message);
}
internal static void LogInfo(string message)
{
_logger.LogInfo((object)message);
}
internal static void LogWarning(string message)
{
_logger.LogWarning((object)message);
}
internal static void LogError(string message)
{
_logger.LogError((object)message);
}
private void Awake()
{
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
return;
}
Instance = this;
_logger = ((BaseUnityPlugin)this).Logger;
Configs.InitializeConfigs();
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.raddude.radrefinements");
}
}
public static class CompassRose
{
private static readonly string[] Directions4 = new string[5] { "North", "East", "South", "West", "North" };
private static readonly string[] Directions8 = new string[9] { "North", "Northeast", "East", "Southeast", "South", "Southwest", "West", "Northwest", "North" };
private static readonly string[] Directions16 = new string[17]
{
"North", "North-northeast", "Northeast", "East-northeast", "East", "East-southeast", "Southeast", "South-southeast", "South", "South-southwest",
"Southwest", "West-southwest", "West", "West-northwest", "Northwest", "North-northwest", "North"
};
private static readonly string[] Directions32 = new string[33]
{
"North", "North by east", "North-northeast", "Northeast by north", "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south",
"East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast", "South by east", "South", "South by west", "South-southwest", "Southwest by south",
"Southwest", "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest", "Northwest by west", "Northwest", "Northwest by north",
"North-northwest", "North by west", "North"
};
private static readonly Dictionary<string, string> Abbreviations = BuildAbbreviations();
private static Dictionary<string, string> BuildAbbreviations()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
AddAbbreviations(dictionary, Directions4);
AddAbbreviations(dictionary, Directions8);
AddAbbreviations(dictionary, Directions16);
AddAbbreviations(dictionary, Directions32);
return dictionary;
}
private static void AddAbbreviations(Dictionary<string, string> abbreviations, string[] directions)
{
foreach (string text in directions)
{
if (!abbreviations.ContainsKey(text))
{
abbreviations[text] = Abbreviate(text);
}
}
}
private static string Abbreviate(string direction)
{
return direction.ToLower().Replace("north", "N").Replace("east", "E")
.Replace("south", "S")
.Replace("west", "W")
.Replace("-", "")
.Replace(" by ", "b");
}
public static string GetCardinalDir(float degrees, int precision)
{
switch (precision)
{
case 4:
{
int num4 = (int)Math.Round((double)degrees / 90.0) % 4;
return Directions4[num4];
}
case 8:
{
int num3 = (int)Math.Round((double)degrees / 45.0) % 8;
return Directions8[num3];
}
case 16:
{
int num2 = (int)Math.Round((double)degrees / 22.5) % 16;
return Directions16[num2];
}
default:
{
int num = (int)Math.Round((double)degrees / 11.25) % 32;
return Directions32[num];
}
}
}
public static string GetAbbreviatedDir(float degrees, int precision)
{
string cardinalDir = GetCardinalDir(degrees, precision);
string value;
return Abbreviations.TryGetValue(cardinalDir, out value) ? value : Abbreviate(cardinalDir);
}
}
internal class Configs
{
internal static ConfigEntry<bool> enableInventorySwap;
internal static ConfigEntry<bool> enableQuickMap;
internal static ConfigEntry<KeyCode> quickMapKey;
internal static ConfigEntry<bool> enableCrateItemDescription;
internal static ConfigEntry<bool> enableQuadrantText;
internal static ConfigEntry<bool> enableCompassReadingHeld;
internal static ConfigEntry<bool> enableCompassDegreesText;
internal static ConfigEntry<bool> enableCompassCardinalText;
internal static ConfigEntry<int> compassCardinalPrecision;
internal static ConfigEntry<float> compassViewDist;
internal static ConfigEntry<bool> enableSunCompassText;
internal static ConfigEntry<bool> enableClockGlobalText;
internal static ConfigEntry<bool> enableClockLocalText;
internal static ConfigEntry<float> clockViewDist;
internal static ConfigEntry<bool> enableChipLogText;
internal static ConfigEntry<float> chipLogViewDist;
internal static ConfigEntry<bool> enableBarometerText;
internal static ConfigEntry<float> barometerViewDist;
internal static ConfigEntry<bool> enableThermometerText;
internal static ConfigEntry<float> thermometerViewDist;
internal static ConfigEntry<bool> enableHygrometerText;
internal static ConfigEntry<float> hygrometerViewDist;
internal static ConfigEntry<bool> enableInclinometerText;
internal static ConfigEntry<float> inclinometerViewDist;
internal static ConfigEntry<bool> negativeInclinometerAngles;
internal static ConfigEntry<bool> enableWindCompassDegreesText;
internal static ConfigEntry<bool> enableWindCompassCardinalText;
internal static ConfigEntry<int> windCompassCardinalPrecision;
internal static ConfigEntry<bool> enableWoodFromContainers;
internal static ConfigEntry<bool> enableCrateInvCountText;
internal static ConfigEntry<KeyCode> crateInvCountTextKey;
internal static ConfigEntry<bool> removeItemHints;
internal static ConfigEntry<bool> enableElixirColors;
internal static ConfigEntry<bool> enableLogbookLastSection;
internal static ConfigEntry<bool> enableSingleClickSmoking;
internal static void InitializeConfigs()
{
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
//IL_02fe: Expected O, but got Unknown
ConfigFile config = ((BaseUnityPlugin)RR_Plugin.Instance).Config;
enableInventorySwap = config.Bind<bool>("Inventory Settings", "Enable inventory swap", true, "Allows you to swap the item you are holding with the item in your selected inventory slot.");
enableQuickMap = config.Bind<bool>("Inventory Settings", "Enable quick map", true, "On quick map key press, causes your character to hold the leftmost map that is in your inventory slots or to put it back in the inventory slot it came from.");
quickMapKey = config.Bind<KeyCode>("Inventory Settings", "Quick map key", (KeyCode)109, "Key that retrieves or stows your map when pressed");
enableCrateItemDescription = config.Bind<bool>("Inventory Settings", "Enable item description in crates", true, (ConfigDescription)null);
enableQuadrantText = config.Bind<bool>("Enable Item Texts", "Quadrant reading text", true, (ConfigDescription)null);
enableCompassReadingHeld = config.Bind<bool>("Item Text Settings", "Compass reading text while held", false, (ConfigDescription)null);
enableCompassDegreesText = config.Bind<bool>("Enable Item Texts", "Compass reading degrees text", true, (ConfigDescription)null);
enableCompassCardinalText = config.Bind<bool>("Enable Item Texts", "Compass reading cardinal text", true, (ConfigDescription)null);
compassCardinalPrecision = config.Bind<int>("Item Text Settings", "Number of compass ordinal directions", 16, new ConfigDescription("Number of ordinal directions given in the compass reading.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[4] { 4, 8, 16, 32 }), Array.Empty<object>()));
compassViewDist = config.Bind<float>("Item Text Settings", "Compass viewable distance", 3f, (ConfigDescription)null);
enableSunCompassText = config.Bind<bool>("Enable Item Texts", "Sun compass reading text", true, (ConfigDescription)null);
enableClockGlobalText = config.Bind<bool>("Enable Item Texts", "Clock global time text", true, (ConfigDescription)null);
enableClockLocalText = config.Bind<bool>("Enable Item Texts", "Clock local time text", true, (ConfigDescription)null);
clockViewDist = config.Bind<float>("Item Text Settings", "Clock viewable distance", 5f, (ConfigDescription)null);
enableChipLogText = config.Bind<bool>("Enable Item Texts", "Chip log reading text", true, (ConfigDescription)null);
chipLogViewDist = config.Bind<float>("Item Text Settings", "Chip log viewable distance", 5f, (ConfigDescription)null);
enableBarometerText = config.Bind<bool>("Enable Item Texts", "Barometer reading text", true, (ConfigDescription)null);
barometerViewDist = config.Bind<float>("Item Text Settings", "Barometer viewable distance", 5f, (ConfigDescription)null);
enableThermometerText = config.Bind<bool>("Enable Item Texts", "Thermometer reading text", true, (ConfigDescription)null);
thermometerViewDist = config.Bind<float>("Item Text Settings", "Thermometer viewable distance", 5f, (ConfigDescription)null);
enableHygrometerText = config.Bind<bool>("Enable Item Texts", "Hygrometer reading text", true, (ConfigDescription)null);
hygrometerViewDist = config.Bind<float>("Item Text Settings", "Hygrometer viewable distance", 5f, (ConfigDescription)null);
enableInclinometerText = config.Bind<bool>("Enable Item Texts", "Inclinometer reading text", true, (ConfigDescription)null);
inclinometerViewDist = config.Bind<float>("Item Text Settings", "Inclinometer viewable distance", 5f, (ConfigDescription)null);
negativeInclinometerAngles = config.Bind<bool>("Item Text Settings", "Inclinometer shows negative angles", false, (ConfigDescription)null);
enableWindCompassDegreesText = config.Bind<bool>("Enable Item Texts", "Wind compass reading degrees text", true, (ConfigDescription)null);
enableWindCompassCardinalText = config.Bind<bool>("Enable Item Texts", "Wind compass reading cardinal text", true, (ConfigDescription)null);
windCompassCardinalPrecision = config.Bind<int>("Item Text Settings", "Number of wind compass ordinal directions", 16, new ConfigDescription("Number of ordinal directions given in the wind compass reading.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[4] { 4, 8, 16, 32 }), Array.Empty<object>()));
enableWoodFromContainers = config.Bind<bool>("Other Settings", "Enable firewood from breaking containers", true, "Allows you to get firewood by breaking containers with a knife.");
enableCrateInvCountText = config.Bind<bool>("Other Settings", "Enable crate total count text", true, "Enables the look text that shows the number of items in a crate.");
crateInvCountTextKey = config.Bind<KeyCode>("Other Settings", "Crate inventory count text key", (KeyCode)101, "Crate inventory count text will show when holding this key.");
removeItemHints = config.Bind<bool>("Other Settings", "Remove item hints", false, "Removes the hint text that appears when you look at a common items (e.g., knife, fishing hook).");
enableElixirColors = config.Bind<bool>("Other Settings", "Enable elixir colors", true, "Makes the bottles for Energy Elixir blue and Snake Oil brown.");
enableLogbookLastSection = config.Bind<bool>("Other Settings", "Logbook remembers last section", true, "Makes the logbook remember the last section you had open so when you reopen it, it opens to that section.");
enableSingleClickSmoking = config.Bind<bool>("Other Settings", "Enable single click smoking", false, "Allows you to smoke a pipe with a single click instead of having to hold the button down.");
}
}
internal static class Extensions
{
public static T GetPrivateField<T>(this object obj, string field)
{
return (T)Traverse.Create(obj).Field(field).GetValue();
}
public static void SetPrivateField(this object obj, string field, object value)
{
Traverse.Create(obj).Field(field).SetValue(value);
}
public static void SetPrivateField<T>(string field, object value)
{
Traverse.Create(typeof(T)).Field(field).SetValue(value);
}
public static object InvokePrivateMethod(this object obj, string method, params object[] parameters)
{
return AccessTools.Method(obj.GetType(), method, (Type[])null, (Type[])null).Invoke(obj, parameters);
}
public static T InvokePrivateMethod<T>(this object obj, string method, params object[] parameters)
{
return (T)obj.InvokePrivateMethod(method, parameters);
}
public static object InvokePrivateMethod<T>(string method, params object[] parameters)
{
return AccessTools.Method(typeof(T), method, (Type[])null, (Type[])null).Invoke(null, parameters);
}
public static T InvokePrivateMethod<T, E>(string method, params object[] parameters)
{
return (T)InvokePrivateMethod<E>(method, parameters);
}
}
}
namespace RadRefinements.Patches
{
internal class OarPatches
{
[HarmonyPatch(typeof(ShipItemOar))]
private class ShipItemOarPatches
{
[HarmonyPatch("ExtraLateUpdate")]
public static bool Prefix(ShipItemOar __instance, ref bool ___isOverWater, ref bool ___isHoldingButton, float ___rowProgress, ref bool ___isRowing)
{
//IL_0021: 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_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: 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_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
//IL_016e: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
//IL_020e: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_022b: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
if (__instance.height == null)
{
__instance.height = new SampleHeightHelper();
}
__instance.waterPos.localPosition = Vector3.zero;
__instance.waterPos.localRotation = Quaternion.identity;
if (Object.op_Implicit((Object)(object)((PickupableItem)__instance).held) && Object.op_Implicit((Object)(object)GameState.currentBoat))
{
__instance.waterPos.Translate(Vector3.forward * __instance.waterPosDistance, (Space)1);
__instance.height.Init(__instance.waterPos.position, 0f, false, (Object)null);
float num = default(float);
__instance.height.Sample(ref num);
__instance.waterPos.position = new Vector3(__instance.waterPos.position.x, num + __instance.waterPosHeight, __instance.waterPos.position.z);
Transform controllerCameraRotMirror = Refs.controllerCameraRotMirror;
if (Vector3.SignedAngle(controllerCameraRotMirror.forward, ((Component)Refs.ovrController).transform.forward, controllerCameraRotMirror.right) > 0f)
{
___isOverWater = false;
}
else if (Physics.Raycast(controllerCameraRotMirror.position, controllerCameraRotMirror.forward, 10f))
{
___isOverWater = false;
}
else
{
___isOverWater = true;
}
}
else
{
___isOverWater = false;
}
if (!___isOverWater)
{
__instance.waterPos.localPosition = Vector3.zero;
__instance.waterPos.localRotation = Quaternion.identity;
}
if (___isOverWater && (___isRowing | ___isHoldingButton))
{
__instance.waterPos.Translate(Vector3.down * __instance.rowDipHeight, (Space)0);
float num2 = sweepAngle * Mathf.Sin(___rowProgress);
float num3 = pitchVariation * Mathf.Sin(2f * ___rowProgress);
Vector3 right = ((Component)Refs.observerMirror).transform.right;
Vector3 val = __instance.waterPos.position + right;
__instance.waterPos.LookAt(val, Vector3.up);
__instance.waterPos.Rotate(Vector3.forward * (0f - outwardAngle), (Space)1);
__instance.waterPos.Rotate(Vector3.up * num2, (Space)1);
__instance.waterPos.Rotate(Vector3.right * num3, (Space)1);
}
if (___isRowing)
{
PlayerNeeds.water -= Time.deltaTime * 0.8f;
PlayerNeeds.food -= Time.deltaTime * 1.3f;
PlayerNeedsMinibar.instance.ShowMinibars(1f, false);
}
if (___isOverWater && !___isRowing)
{
((ShipItem)__instance).amount = 1f;
}
else
{
((ShipItem)__instance).amount = 0f;
}
__instance.InvokePrivateMethod("UpdateVisuals");
___isRowing = false;
___isHoldingButton = false;
return false;
}
[HarmonyPatch("OnAltHeld")]
public static bool Prefix(ShipItemOar __instance, ref bool ___isHoldingButton, bool ___isOverWater, ref bool ___isRowing, ref float ___rowProgress)
{
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: 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_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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_009e: 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_00ca: 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_00da: 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)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
___isHoldingButton = true;
if (Object.op_Implicit((Object)(object)((PickupableItem)__instance).held) && ___isOverWater && Object.op_Implicit((Object)(object)GameState.currentBoat))
{
___isRowing = true;
___rowProgress += scullingSpeed * Time.deltaTime;
if (___rowProgress > (float)Math.PI * 2f)
{
___rowProgress -= (float)Math.PI * 2f;
}
float num = Mathf.Abs(Mathf.Cos(___rowProgress));
Vector3 position = GameState.currentBoat.parent.position;
Vector3 val = __instance.waterPos.position - position;
Vector3 normalized = ((Vector3)(ref val)).normalized;
float num2 = 0f - Mathf.Sign(Vector3.Dot(GameState.currentBoat.parent.forward, normalized));
((Component)GameState.currentBoat.parent).GetComponent<Rigidbody>().AddForceAtPosition(GameState.currentBoat.parent.forward * rowForce * num * Time.deltaTime * num2, __instance.waterPos.position);
}
return false;
}
}
[Header("Figure-8 Motion")]
public static float sweepAngle = 50f;
public static float pitchVariation = 12f;
public static float scullingSpeed = 2.5f;
public static float rowForce = 18000f;
public static float outwardAngle = 35f;
}
internal class CratePatches
{
[HarmonyPatch(typeof(ShipItemCrate))]
private class ShipItemCratePatches
{
[HarmonyPostfix]
[HarmonyPatch("UpdateLookText")]
public static void AddNumItemsText(ShipItemCrate __instance, Good ___goodC, CrateInventory ___crateInventory)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
if (Configs.enableCrateInvCountText.Value && ((ShipItem)__instance).sold && !(((ShipItem)__instance).amount > 0f) && Object.op_Implicit((Object)(object)___crateInventory) && (!Object.op_Implicit((Object)(object)___goodC) || ___goodC.GetMissionIndex() <= -1))
{
string text = string.Empty;
if (Input.GetKey(Configs.crateInvCountTextKey.Value))
{
text = Crate.GetCrateInventory(__instance);
}
((GoPointerButton)__instance).lookText = (Utility.IsNullOrWhiteSpace(text) ? $"{((GoPointerButton)__instance).lookText}\n{___crateInventory.containedItems.Count} items" : text);
}
}
}
}
internal class ElixirPatches
{
[HarmonyPatch(typeof(ShipItem), "Awake")]
private static class ShipItemPatch
{
private static readonly Color32 snakeOilColor = new Color32(byte.MaxValue, byte.MaxValue, (byte)0, byte.MaxValue);
private static readonly Color32 energyElixirColor = new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue);
[HarmonyPostfix]
public static void Postfix(ShipItem __instance)
{
//IL_0045: 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_0075: 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)
if (Configs.enableElixirColors.Value && __instance is ShipItemElixir)
{
MeshRenderer component = ((Component)__instance).GetComponent<MeshRenderer>();
if (__instance.name == "snake oil")
{
((Renderer)component).materials[0].color = Color32.op_Implicit(snakeOilColor);
}
else if (__instance.name == "energy elixir")
{
((Renderer)component).materials[0].color = Color32.op_Implicit(energyElixirColor);
}
}
}
}
}
}