Decompiled source of Tamed And Logs Harpoon v1.2.1

HarpoonForLogs.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HarpoonForLogs")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HarpoonForLogs")]
[assembly: AssemblyTitle("HarpoonForLogs")]
[assembly: AssemblyVersion("1.0.0.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 TamedHarpoon
{
	[BepInPlugin("com.Azura.tamedharpoon", "Tamed+Logs Harpoon", "1.2.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.Azura.tamedharpoon";

		public const string PluginName = "Tamed+Logs Harpoon";

		public const string PluginVersion = "1.2.1";

		public static ConfigEntry<bool> Actif;

		public static ConfigEntry<bool> SansDegats;

		public static ConfigEntry<bool> Rondins;

		public static ConfigEntry<float> Rembobinage;

		public static ConfigEntry<float> EndurancePulling;

		public static ConfigEntry<float> Facilite;

		private static int hashHarpon;

		private void Awake()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			Actif = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "true = the harpoon also catches tamed animals.\ntrue = le harpon accroche aussi les animaux apprivoisés.");
			SansDegats = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NoDamage", true, "true = the harpoon does no damage to tamed animals (it only pulls them).\ntrue = le harpon ne blesse pas les animaux apprivoisés (il ne fait que les tirer).");
			Rondins = ((BaseUnityPlugin)this).Config.Bind<bool>("Logs", "HookLogs", true, "true = the harpoon also hooks felled tree logs, to pull them out of the water.\ntrue = le harpon accroche aussi les rondins d'arbres abattus, pour les sortir de l'eau.");
			Rembobinage = ((BaseUnityPlugin)this).Config.Bind<float>("Logs", "ReelSpeed", 1.5f, new ConfigDescription("Meters per second the line is reeled in, until the log is a step away from you (0 = the log only follows you).\nMètres rembobinés par seconde, jusqu'à ce que le rondin soit à un pas de vous (0 = le rondin ne fait que vous suivre).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 6f), Array.Empty<object>()));
			EndurancePulling = ((BaseUnityPlugin)this).Config.Bind<float>("Logs", "StaminaPerSecond", 12f, new ConfigDescription("Stamina used per second while the line is taut.\nEndurance utilisée par seconde quand la corde est tendue.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			Facilite = ((BaseUnityPlugin)this).Config.Bind<float>("Logs", "TowingEase", 17.5f, new ConfigDescription("Percent: at the end of the line, a log behaves as if it were this much lighter (less stamina used, stronger pull). Logs themselves are unchanged. 0 = as in 1.1.1.\nPourcentage : au bout de la corde, un rondin se comporte comme s'il était d'autant plus léger (moins d'endurance, traction plus forte). Les rondins eux-mêmes ne changent pas. 0 = comme en 1.1.1.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
			new Harmony("com.Azura.tamedharpoon").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)Traductions.Format("journal_charge", null, new object[2] { "Tamed+Logs Harpoon", "1.2.1" }));
		}

		public static bool EstHarpon(int hashEffet)
		{
			if (hashEffet == 0 || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return false;
			}
			if (hashHarpon != 0)
			{
				return hashEffet == hashHarpon;
			}
			if (ObjectDB.instance.GetStatusEffect(hashEffet) is SE_Harpooned)
			{
				hashHarpon = hashEffet;
				return true;
			}
			return false;
		}

		public static bool ApprivoiseHarponne(Projectile p, Character proprio, int hashEffet, Character cible)
		{
			if (Actif.Value && (Object)(object)cible != (Object)null && !cible.IsPlayer() && cible.IsTamed() && (Object)(object)proprio != (Object)null && proprio.IsPlayer())
			{
				return EstHarpon(hashEffet);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Projectile), "IsValidTarget")]
	public static class Projectile_IsValidTarget_Patch
	{
		public static void Postfix(Projectile __instance, IDestructible destr, ref bool __result, Character ___m_owner, int ___m_statusEffectHash)
		{
			if (!__result && Plugin.ApprivoiseHarponne(__instance, ___m_owner, ___m_statusEffectHash, (Character)(object)((destr is Character) ? destr : null)))
			{
				__result = true;
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	public static class Projectile_OnHit_Patch
	{
		public struct Sauvegarde
		{
			public bool Change;

			public DamageTypes Degats;

			public float Force;
		}

		public static void Prefix(Projectile __instance, Collider collider, Character ___m_owner, int ___m_statusEffectHash, ref Sauvegarde __state)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			__state = default(Sauvegarde);
			if (Plugin.SansDegats.Value && !((Object)(object)collider == (Object)null))
			{
				GameObject val = Projectile.FindHitObject(collider);
				Character cible = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null);
				if (Plugin.ApprivoiseHarponne(__instance, ___m_owner, ___m_statusEffectHash, cible))
				{
					__state = new Sauvegarde
					{
						Change = true,
						Degats = __instance.m_damage,
						Force = __instance.m_attackForce
					};
					__instance.m_damage = default(DamageTypes);
					__instance.m_attackForce = 0f;
				}
			}
		}

		public static void Finalizer(Projectile __instance, Sauvegarde __state)
		{
			//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)
			if (__state.Change && !((Object)(object)__instance == (Object)null))
			{
				__instance.m_damage = __state.Degats;
				__instance.m_attackForce = __state.Force;
			}
		}
	}
	[HarmonyPatch(typeof(Projectile), "OnHit")]
	public static class Projectile_OnHit_Rondin_Patch
	{
		public static void Postfix(Collider collider, Vector3 hitPoint, Character ___m_owner, int ___m_statusEffectHash)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Rondins.Value && !((Object)(object)collider == (Object)null) && !((Object)(object)___m_owner == (Object)null) && !((Object)(object)___m_owner != (Object)(object)Player.m_localPlayer) && Plugin.EstHarpon(___m_statusEffectHash))
			{
				GameObject val = Projectile.FindHitObject(collider);
				TreeLog val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInParent<TreeLog>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					Player localPlayer = Player.m_localPlayer;
					StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(___m_statusEffectHash);
					Corde.Accrocher(localPlayer, val2, hitPoint, (SE_Harpooned)(object)((statusEffect is SE_Harpooned) ? statusEffect : null));
				}
			}
		}
	}
	public class Corde : MonoBehaviour
	{
		private const float LongueurMin = 2.5f;

		private const float Ecart = 1.8f;

		private const float Arrivee = 1f;

		private const float Raideur = 1.5f;

		private const float VitesseMax = 5f;

		private const float Reactivite = 5f;

		private const float TractionMax = 12f;

		private const float FreinMax = 6f;

		private const float VerticalMax = 3f;

		private const float MonteeMax = 2f;

		private const float AmortiRotation = 2f;

		private const float RotationMax = 1.5f;

		private static Corde actuelle;

		private Player joueur;

		private Rigidbody corps;

		private ZNetView vue;

		private Collider[] formes;

		private Vector3 ancrage;

		private float longueur;

		private float debut;

		private float rupture = 6f;

		private float porteeMax = 60f;

		private LineRenderer ligne;

		public float EcartMesure { get; private set; } = float.MaxValue;

		public float Tendue { get; private set; }

		public float Traction { get; private set; }

		public static string DerniereRaison { get; private set; } = "";

		public static void Accrocher(Player p, TreeLog rondin, Vector3 point, SE_Harpooned reglages)
		{
			//IL_0019: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)actuelle != (Object)null)
			{
				actuelle.Lacher(null);
			}
			float num = Vector3.Distance(Main(p), point);
			if ((Object)(object)reglages != (Object)null && num > reglages.m_maxDistance)
			{
				((Character)p).Message((MessageType)2, "$msg_harpoon_targettoofar", 0, (Sprite)null, false);
				return;
			}
			Corde corde = ((Component)rondin).gameObject.AddComponent<Corde>();
			corde.joueur = p;
			corde.corps = ((Component)rondin).GetComponent<Rigidbody>();
			corde.vue = ((Component)rondin).GetComponent<ZNetView>();
			corde.formes = (from f in ((Component)rondin).GetComponentsInChildren<Collider>()
				where f.enabled && !f.isTrigger
				select f).ToArray();
			corde.ancrage = ((Component)rondin).transform.InverseTransformPoint(point);
			corde.debut = Time.time;
			if ((Object)(object)reglages != (Object)null)
			{
				corde.rupture = Mathf.Max(2f, reglages.m_breakDistance) + 2f;
				corde.porteeMax = reglages.m_maxDistance + 10f;
			}
			if ((Object)(object)corde.corps == (Object)null || (Object)(object)corde.vue == (Object)null || !corde.vue.IsValid())
			{
				Object.Destroy((Object)(object)corde);
				return;
			}
			corde.longueur = Mathf.Max(2.5f, Vector3.Distance(Main(p), corde.corps.worldCenterOfMass));
			corde.vue.ClaimOwnership();
			corde.ligne = CreerLigne(((Component)rondin).transform);
			actuelle = corde;
			((Character)p).Message((MessageType)2, Traductions.Texte("rondin_accroche"), 0, (Sprite)null, false);
		}

		private static Vector3 Main(Player p)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_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)
			Transform val = ((Component)p).GetComponent<VisEquipment>()?.m_rightHand;
			if (!((Object)(object)val != (Object)null))
			{
				return ((Component)p).transform.position + Vector3.up * 1.2f;
			}
			return val.position;
		}

		private float EcartAuJoueur()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)joueur).transform.position + Vector3.up * 0.9f;
			float num = float.MaxValue;
			Collider[] array = formes;
			foreach (Collider val2 in array)
			{
				if ((Object)(object)val2 != (Object)null && val2.enabled)
				{
					num = Mathf.Min(num, Vector3.Distance(val, val2.ClosestPoint(val)));
				}
			}
			if (num != float.MaxValue)
			{
				return num;
			}
			return Vector3.Distance(val, corps.worldCenterOfMass);
		}

		private static LineRenderer CreerLigne(Transform parent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0053: Expected O, but got Unknown
			//IL_006b: 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)
			GameObject val = new GameObject("TamedHarpoon_Line");
			val.transform.SetParent(parent, false);
			LineRenderer obj = val.AddComponent<LineRenderer>();
			obj.positionCount = 3;
			float startWidth = (obj.endWidth = 0.03f);
			obj.startWidth = startWidth;
			obj.useWorldSpace = true;
			((Renderer)obj).material = new Material(Shader.Find("Sprites/Default"));
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.32f, 0.24f, 0.15f);
			obj.endColor = val2;
			obj.startColor = val2;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			return obj;
		}

		private void FixedUpdate()
		{
			//IL_007e: 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_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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: 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_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: 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_02a5: 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_026b: 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_02c1: 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_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)joueur == (Object)null || ((Character)joueur).IsDead() || (Object)(object)corps == (Object)null || (Object)(object)vue == (Object)null || !vue.IsValid())
			{
				Lacher(null);
				return;
			}
			if (!vue.IsOwner())
			{
				vue.ClaimOwnership();
			}
			if (corps.isKinematic)
			{
				return;
			}
			float fixedDeltaTime = Time.fixedDeltaTime;
			Vector3 val = Main(joueur) - corps.worldCenterOfMass;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < 0.01f))
			{
				Vector3 val2 = val / magnitude;
				float num = EcartAuJoueur();
				EcartMesure = Mathf.Min(EcartMesure, num);
				bool num2 = num < 1.8f;
				longueur = Mathf.Min(longueur, magnitude + 0.5f);
				if (num2)
				{
					longueur = Mathf.Max(longueur, magnitude);
				}
				else if (magnitude - longueur < 1.5f)
				{
					longueur = Mathf.Max(2.5f, longueur - Plugin.Rembobinage.Value * fixedDeltaTime);
				}
				float num3 = (Tendue = magnitude - longueur);
				float num5 = Mathf.Clamp(Mathf.Min(num3 * 1.5f, (num - 1.8f) * 1f), 0f, 5f);
				float num6 = Vector3.Dot(corps.linearVelocity, val2);
				float num7 = (num5 - num6) * 5f;
				if (num2 || num3 <= 0f)
				{
					num7 = Mathf.Min(num7, 0f);
				}
				float num8 = 1f - Plugin.Facilite.Value / 100f;
				num7 = (Traction = Mathf.Clamp(num7, -6f, 12f / num8));
				Vector3 val3 = val2 * num7;
				val3.y = Mathf.Clamp(val3.y, -3f, 3f);
				corps.AddForce(val3, (ForceMode)5);
				corps.AddTorque(-corps.angularVelocity * 2f, (ForceMode)5);
				Vector3 linearVelocity = corps.linearVelocity;
				Vector3 val4 = default(Vector3);
				((Vector3)(ref val4))..ctor(linearVelocity.x, 0f, linearVelocity.z);
				if (((Vector3)(ref val4)).sqrMagnitude > 36f || linearVelocity.y > 2f)
				{
					val4 = Vector3.ClampMagnitude(val4, 6f);
					corps.linearVelocity = new Vector3(val4.x, Mathf.Min(linearVelocity.y, 2f), val4.z);
				}
				Vector3 angularVelocity = corps.angularVelocity;
				if (((Vector3)(ref angularVelocity)).sqrMagnitude > 2.25f)
				{
					Rigidbody obj = corps;
					angularVelocity = corps.angularVelocity;
					obj.angularVelocity = ((Vector3)(ref angularVelocity)).normalized * 1.5f;
				}
				if (num7 > 0.1f)
				{
					((Character)joueur).UseStamina(Plugin.EndurancePulling.Value * (num7 * num8 / 12f) * fixedDeltaTime);
				}
				if (num3 > rupture || magnitude > porteeMax)
				{
					Lacher("$msg_harpoon_linebroke");
				}
				else if (!((Character)joueur).HaveStamina(0f))
				{
					Lacher(Traductions.Texte("rondin_libere"));
				}
				else if (Time.time - debut > 2f && (((Character)joueur).IsBlocking() || ((Character)joueur).InAttack()))
				{
					Lacher(Traductions.Texte("rondin_lache"));
				}
			}
		}

		private void LateUpdate()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_0075: 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_008a: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)ligne == (Object)null) && !((Object)(object)joueur == (Object)null))
			{
				Vector3 val = Main(joueur);
				Vector3 val2 = ((Component)this).transform.TransformPoint(ancrage);
				float num = Mathf.Clamp01(1f - (Tendue + 1f) / 2f) * 0.6f;
				ligne.SetPosition(0, val);
				ligne.SetPosition(1, (val + val2) * 0.5f + Vector3.down * num);
				ligne.SetPosition(2, val2);
			}
		}

		public void Lacher(string message)
		{
			DerniereRaison = message ?? "(rondin ou joueur disparu, ou nouvelle corde)";
			if (message != null && (Object)(object)joueur != (Object)null)
			{
				((Character)joueur).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
			if ((Object)(object)ligne != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)ligne).gameObject);
			}
			if ((Object)(object)actuelle == (Object)(object)this)
			{
				actuelle = null;
			}
			Object.Destroy((Object)(object)this);
		}
	}
	internal static class Traductions
	{
		internal static readonly string[] Langues = new string[36]
		{
			"English", "Swedish", "French", "Italian", "German", "Spanish", "Russian", "Romanian", "Bulgarian", "Macedonian",
			"Finnish", "Danish", "Norwegian", "Icelandic", "Turkish", "Lithuanian", "Czech", "Hungarian", "Slovak", "Polish",
			"Dutch", "Portuguese_European", "Portuguese_Brazilian", "Chinese", "Chinese_Trad", "Japanese", "Korean", "Hindi", "Thai", "Abenaki",
			"Croatian", "Georgian", "Greek", "Serbian", "Ukrainian", "Latvian"
		};

		private static readonly string[] Cultures = new string[36]
		{
			"en-US", "sv-SE", "fr-FR", "it-IT", "de-DE", "es-ES", "ru-RU", "ro-RO", "bg-BG", "mk-MK",
			"fi-FI", "da-DK", "nb-NO", "is-IS", "tr-TR", "lt-LT", "cs-CZ", "hu-HU", "sk-SK", "pl-PL",
			"nl-NL", "pt-PT", "pt-BR", "zh-CN", "zh-TW", "ja-JP", "ko-KR", "hi-IN", "th-TH", "en-US",
			"hr-HR", "ka-GE", "el-GR", "sr-Latn-RS", "uk-UA", "lv-LV"
		};

		internal static readonly Dictionary<string, string[]> Textes;

		private static readonly FieldInfo TraductionDuJeu;

		private static bool jeuPret;

		internal static string LangueDuJeu
		{
			get
			{
				try
				{
					if (!jeuPret)
					{
						if (TraductionDuJeu != null && TraductionDuJeu.GetValue(null) == null)
						{
							return PlayerPrefs.GetString("language", "English");
						}
						jeuPret = true;
					}
					return Localization.instance.GetSelectedLanguage();
				}
				catch (Exception)
				{
					return "English";
				}
			}
		}

		internal static string Texte(string cle, string langue = null)
		{
			if (!Textes.TryGetValue(cle, out var value))
			{
				return cle;
			}
			int num = Array.IndexOf(Langues, langue ?? LangueDuJeu);
			if (num <= 0 || num >= value.Length || string.IsNullOrEmpty(value[num]))
			{
				return value[0];
			}
			return value[num];
		}

		internal static string Format(string cle, string langue, object[] valeurs)
		{
			string text = Texte(cle, langue);
			if (valeurs != null && valeurs.Length != 0)
			{
				return string.Format(Culture(langue), text, valeurs);
			}
			return text;
		}

		internal static CultureInfo Culture(string langue = null)
		{
			int num = Array.IndexOf(Langues, langue ?? LangueDuJeu);
			try
			{
				return CultureInfo.GetCultureInfo((num >= 0) ? Cultures[num] : "en-US");
			}
			catch
			{
				return CultureInfo.InvariantCulture;
			}
		}

		static Traductions()
		{
			Dictionary<string, string[]> dictionary = new Dictionary<string, string[]>
			{
				["rondin_accroche"] = new string[36]
				{
					"Log harpooned", "Stock harpunerad", "Rondin harponné", "Tronco arpionato", "Baumstamm harpuniert", "Tronco arponeado", "Бревно загарпунено", "Buștean harponat", "Дънерът е харпуниран", "Трупецот е харпуниран",
					"Puunrunko harppuunoitu", "Træstamme harpuneret", "Tømmerstokk harpunert", "Skutull festur í drumbi", "Kütük zıpkınlandı", "Rąstas užkabintas žeberklu", "Kláda zachycena harpunou", "Farönk megszigonyozva", "Klada zachytená harpúnou", "Kłoda trafiona harpunem",
					"Stam geharpoeneerd", "Tronco arpoado", "Tronco arpoado", "原木已被叉中", "木材已被魚叉叉中", "丸太に銛を打ち込んだ", "통나무에 작살을 꽂았습니다", "लट\u094dठ\u0947 म\u0947\u0902 भ\u093eल\u093e फ\u0901स गय\u093e", "ป\u0e31กฉมวกท\u0e35\u0e48ซ\u0e38งแล\u0e49ว", null,
					"Balvan pogođen harpunom", "ხის მორი ჰარპუნით დაიჭირე", "Ο κορμός καμακώθηκε", "Balvan pogođen harpunom", "Колоду загарпунено", "Baļķis noharpūnēts"
				},
				["rondin_libere"] = new string[36]
				{
					"The log got away", "Stocken slet sig loss", "Le rondin s'est libéré", "Il tronco si è liberato", "Der Baumstamm hat sich losgerissen", "El tronco se ha soltado", "Бревно сорвалось", "Bușteanul a scăpat", "Дънерът се изплъзна", "Трупецот се ослободи",
					"Puunrunko pääsi irti", "Træstammen slap fri", "Tømmerstokken slet seg løs", "Drumburinn losnaði", "Kütük kurtuldu", "Rąstas ištrūko", "Kláda se utrhla", "A farönk elszabadult", "Klada sa vytrhla", "Kłoda się wyrwała",
					"De stam is losgeschoten", "O tronco soltou-se", "O tronco se soltou", "原木挣脱了", "木材掙脫了", "丸太が外れた", "통나무가 풀려났습니다", "लट\u094dठ\u093e छ\u0942ट गय\u093e", "ซ\u0e38งหล\u0e38ดไปแล\u0e49ว", null,
					"Balvan se otrgnuo", "ხის მორი გაგექცა", "Ο κορμός ξέφυγε", "Balvan se otrgao", "Колода зірвалася", "Baļķis izrāvās"
				},
				["rondin_lache"] = new string[36]
				{
					"Log released", "Stock släppt", "Rondin lâché", "Tronco rilasciato", "Baumstamm losgelassen", "Tronco soltado", "Бревно отпущено", "Buștean eliberat", "Дънерът е пуснат", "Трупецот е пуштен",
					"Puunrunko päästetty", "Træstamme sluppet", "Tømmerstokk sluppet", "Drumbi sleppt", "Kütük bırakıldı", "Rąstas paleistas", "Kláda puštěna", "Farönk elengedve", "Klada pustená", "Kłoda puszczona",
					"Stam losgelaten", "Tronco largado", "Tronco solto", "已松开原木", "已放開木材", "丸太を放した", "통나무를 놓았습니다", "लट\u094dठ\u093e छ\u094bड\u093c द\u093fय\u093e", "ปล\u0e48อยซ\u0e38งแล\u0e49ว", null,
					"Balvan pušten", "ხის მორი გაუშვი", "Ο κορμός αφέθηκε", "Balvan pušten", "Колоду відпущено", "Baļķis atlaists"
				}
			};
			string[] array = new string[36];
			array[0] = "{0} v{1} loaded.";
			array[2] = "{0} v{1} chargé.";
			dictionary["journal_charge"] = array;
			Textes = dictionary;
			TraductionDuJeu = typeof(Localization).GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		}
	}
}