LokiSixVikings.dll

Decompiled 8 hours ago
using System;
using System.Collections;
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 Jotunn;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SixVikings;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("LokiSixVikings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+974e564dc5bcc9eb9c83c07a39b499608edec719")]
[assembly: AssemblyProduct("LokiSixVikings")]
[assembly: AssemblyTitle("LokiSixVikings")]
[assembly: AssemblyVersion("1.1.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 SixVikings
{
	internal static class Langue
	{
		internal static bool Francais
		{
			get
			{
				try
				{
					return Localization.instance.GetSelectedLanguage() == "French";
				}
				catch (Exception)
				{
					return false;
				}
			}
		}

		internal static string T(string francais, string anglais)
		{
			if (!Francais)
			{
				return anglais;
			}
			return francais;
		}

		internal static string Reglage(string anglais, string francais)
		{
			return anglais + "\nFR : " + francais;
		}
	}
}
namespace LokiSixVikings
{
	public abstract class Caprice
	{
		public ConfigEntry<bool> Actif;

		public ConfigEntry<float> Poids;

		public ConfigEntry<string> Annonces;

		public ConfigEntry<string> AnnoncesAnglaises;

		public static readonly List<Caprice> Tous = (from type in typeof(Caprice).Assembly.GetTypes()
			where type.IsSubclassOf(typeof(Caprice)) && !type.IsAbstract
			select (Caprice)Activator.CreateInstance(type)).OrderBy<Caprice, string>((Caprice caprice) => caprice.Id, StringComparer.Ordinal).ToList();

		public abstract string Id { get; }

		public abstract string Nom { get; }

		public abstract string NomAnglais { get; }

		public abstract Color Couleur { get; }

		protected abstract string[] AnnoncesParDefaut { get; }

		protected abstract string[] AnnoncesAnglaisesParDefaut { get; }

		protected abstract string[] AnnoncesDeLa104 { get; }

		public bool EnCours => Etat.Actif == this;

		protected string Section => char.ToUpperInvariant(Id[0]) + Id.Substring(1);

		public abstract string Resume(bool francais);

		public string NomPour(bool francais)
		{
			if (!francais)
			{
				return NomAnglais;
			}
			return Nom;
		}

		public void Configurer(ConfigFile config)
		{
			Actif = ConfigFileExtensions.BindConfig<bool>(config, Section, "Actif", true, Langue.Reglage("false: \"" + NomAnglais + "\" is no longer drawn.", "false : « " + Nom + " » ne sort plus au tirage."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			string section = Section;
			string text = Langue.Reglage("Weight in the draw: 2 comes up twice as often as 1.", "Poids dans le tirage : 2 sort deux fois plus souvent que 1.");
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f);
			Poids = ConfigFileExtensions.BindConfig<float>(config, section, "Poids", 1f, text, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			Annonces = ConfigFileExtensions.BindConfig<string>(config, Section, "Annonces", string.Join(" | ", AnnoncesParDefaut), Langue.Reglage("French announcement texts, separated by a vertical bar, for players whose game is in French. One is shown each day.", "Textes d'annonce en français, séparés par une barre verticale, pour les joueurs dont le jeu est en français. Un seul est affiché chaque jour."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			if (Annonces.Value == string.Join(" | ", AnnoncesDeLa104))
			{
				Annonces.Value = string.Join(" | ", AnnoncesParDefaut);
			}
			AnnoncesAnglaises = ConfigFileExtensions.BindConfig<string>(config, Section, "Announcements", string.Join(" | ", AnnoncesAnglaisesParDefaut), Langue.Reglage("Announcement texts, separated by a vertical bar, for players whose game is in any language but French. One is shown each day.", "Textes d'annonce, séparés par une barre verticale, pour les joueurs dont le jeu n'est pas en français. Un seul est affiché chaque jour."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			Reglages(config);
		}

		protected virtual void Reglages(ConfigFile config)
		{
		}

		public virtual void Demarrer()
		{
		}

		public virtual void Arreter()
		{
		}

		public virtual void Tic()
		{
		}

		public List<string> ListeAnnonces(bool francais)
		{
			List<string> list = (from t in (francais ? Annonces : AnnoncesAnglaises).Value.Split(new char[1] { '|' })
				select t.Trim() into t
				where t.Length > 0
				select t).ToList();
			if (list.Count <= 0)
			{
				return (francais ? AnnoncesParDefaut : AnnoncesAnglaisesParDefaut).ToList();
			}
			return list;
		}

		public static Caprice Par(string id)
		{
			return Tous.FirstOrDefault((Caprice caprice) => caprice.Id == id);
		}

		protected static string Nombre(float valeur)
		{
			return Vocabulaire.Nombre(valeur, francais: true);
		}
	}
	public class BrumeDeHel : Caprice
	{
		[HarmonyPatch(typeof(EnvMan), "SetEnv")]
		private static class VueDegagee
		{
			private static void Postfix()
			{
				if (moi.EnCours && !(visibilite.Value <= 1f) && !((Object)(object)Utils.GetMainCamera() == (Object)null))
				{
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).InInterior())
					{
						RenderSettings.fogDensity /= visibilite.Value;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Character), "Awake")]
		private static class NoterLesNaissances
		{
			private static void Postfix(Character __instance)
			{
				if (apparitions > 0)
				{
					nes.Add(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(SpawnSystem), "Spawn", new Type[]
		{
			typeof(SpawnData),
			typeof(Vector3),
			typeof(bool)
		})]
		private static class ApparitionDansLaNature
		{
			private static void Prefix(bool eventSpawner, out bool __state)
			{
				__state = Ouvrir(!eventSpawner || raids.Value);
			}

			private static void Finalizer(bool __state)
			{
				Fermer(__state);
			}
		}

		[HarmonyPatch(typeof(CreatureSpawner), "Spawn")]
		private static class ApparitionDansUnCamp
		{
			private static void Prefix(out bool __state)
			{
				__state = Ouvrir(concerne: true);
			}

			private static void Finalizer(bool __state)
			{
				Fermer(__state);
			}
		}

		[HarmonyPatch(typeof(SpawnArea), "SpawnOne")]
		private static class ApparitionDansUnNid
		{
			private static void Prefix(out bool __state)
			{
				__state = Ouvrir(concerne: true);
			}

			private static void Finalizer(bool __state)
			{
				Fermer(__state);
			}
		}

		[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
		private static class ButinMultiplie
		{
			private static void Postfix(Character ___m_character, List<KeyValuePair<GameObject, int>> __result)
			{
				if (moi.EnCours && !(butin.Value <= 1f) && __result != null && !((Object)(object)___m_character == (Object)null) && !___m_character.IsBoss() && !___m_character.IsTamed())
				{
					int num = 0;
					int num2 = 0;
					for (int i = 0; i < __result.Count; i++)
					{
						int value = __result[i].Value;
						int num3 = Regles.ButinApresBrume(value, butin.Value);
						__result[i] = new KeyValuePair<GameObject, int>(__result[i].Key, num3);
						num += value;
						num2 += num3;
					}
					if (num2 != num)
					{
						Plugin.Journal("Brume : butin de " + ((Object)___m_character).name + " porté de " + num + " à " + num2 + " objets.");
					}
				}
			}
		}

		private static BrumeDeHel moi;

		private static ConfigEntry<float> visibilite;

		private static ConfigEntry<int> etoilesEnPlus;

		private static ConfigEntry<int> etoilesMax;

		private static ConfigEntry<float> butin;

		private static ConfigEntry<bool> raids;

		private static readonly List<Character> nes = new List<Character>();

		private static int apparitions;

		public override string Id => "brume";

		public override string Nom => "Brume de Hel";

		public override string NomAnglais => "Hel's Mist";

		public override Color Couleur => new Color(0.7f, 0.5f, 0.95f);

		protected override string[] AnnoncesParDefaut => new string[5] { "Hel retient son souffle : la brume se lève et l'on voit jusqu'au bout du monde. Ce qui y rôde est plus fort… et plus riche.", "Brume de Hel dissipée ! Les morts sortent au grand jour, une étoile de plus au front et les poches pleines.", "Hel a ouvert ses portes. Rien ne se cache aujourd'hui : ni les monstres, plus coriaces, ni leur butin, plus gras.", "Brume de Hel ! Le brouillard se retire, les monstres se montrent, plus forts et plus généreux.", "Hel a soufflé la brume. Vous verrez venir le danger de loin, et il aura de quoi payer." };

		protected override string[] AnnoncesAnglaisesParDefaut => new string[5] { "Hel holds her breath: the mist lifts and you can see to the end of the world. What prowls there is stronger… and richer.", "Hel's Mist has cleared! The dead walk in broad daylight, an extra star on their brow and their pockets full.", "Hel has opened her gates. Nothing hides today: not the monsters, tougher, nor their loot, fatter.", "Hel's Mist! The fog retreats, the monsters show themselves, stronger and more generous.", "Hel blew the mist away. You will see danger coming from afar, and it will be worth the trouble." };

		protected override string[] AnnoncesDeLa104 => new string[3] { "Hel retient son souffle : la brume se lève et l'on voit jusqu'au bout du monde. Ce qui y rôde est plus fort… et plus riche.", "Brume de Hel dissipée ! Les morts sortent au grand jour, une étoile de plus au front et les poches pleines.", "Hel a ouvert ses portes. Rien ne se cache aujourd'hui : ni les monstres, plus coriaces, ni leur butin, plus gras." };

		public BrumeDeHel()
		{
			moi = this;
		}

		public override string Resume(bool francais)
		{
			if (!francais)
			{
				return "clear view ×" + Vocabulaire.Nombre(visibilite.Value, francais: false) + ", monsters +" + etoilesEnPlus.Value + ((etoilesEnPlus.Value == 1) ? " star" : " stars") + " (up to " + etoilesMax.Value + "), loot ×" + Vocabulaire.Nombre(butin.Value, francais: false);
			}
			return "vue dégagée ×" + Vocabulaire.Nombre(visibilite.Value, francais: true) + ", monstres +" + etoilesEnPlus.Value + ((etoilesEnPlus.Value > 1) ? " étoiles" : " étoile") + " (jusqu'à " + etoilesMax.Value + "), butin ×" + Vocabulaire.Nombre(butin.Value, francais: true);
		}

		protected override void Reglages(ConfigFile config)
		{
			string section = base.Section;
			string text = Langue.Reglage("The game's fog is divided by this number, outdoors only: 3 = three times thinner, 1 = no change.", "Le brouillard du jeu est divisé par ce nombre, dehors seulement : 3 = trois fois moins dense, 1 = aucun changement.");
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f);
			visibilite = ConfigFileExtensions.BindConfig<float>(config, section, "Visibilite", 3f, text, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			string section2 = base.Section;
			string text2 = Langue.Reglage("Stars added to monsters that spawn (wild, camps, dungeons, nests). 0 = none.", "Étoiles ajoutées aux monstres qui apparaissent (nature, camps, donjons, nids). 0 = aucune.");
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2);
			etoilesEnPlus = ConfigFileExtensions.BindConfig<int>(config, section2, "EtoilesEnPlus", 1, text2, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			string section3 = base.Section;
			string text3 = Langue.Reglage("Star ceiling: the game shows nothing beyond 2.", "Plafond d'étoiles : le jeu n'affiche rien au-delà de 2.");
			val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2);
			etoilesMax = ConfigFileExtensions.BindConfig<int>(config, section3, "EtoilesMax", 2, text3, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			string section4 = base.Section;
			string text4 = Langue.Reglage("Loot multiplier for monsters killed (bosses and tamed animals excluded). It adds to the bonus the game already gives per star.", "Multiplicateur du butin des monstres tués (boss et animaux apprivoisés exclus). Il s'ajoute au bonus que le jeu donne déjà par étoile.");
			val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f);
			butin = ConfigFileExtensions.BindConfig<float>(config, section4, "Butin", 2f, text4, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			raids = ConfigFileExtensions.BindConfig<bool>(config, base.Section, "EtoilesPendantLesRaids", false, Langue.Reglage("true: raid monsters also get their star.", "true : les monstres des raids gagnent aussi leur étoile."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		private static bool Ouvrir(bool concerne)
		{
			if (!concerne || !moi.EnCours || etoilesEnPlus.Value <= 0)
			{
				return false;
			}
			apparitions++;
			return true;
		}

		private static void Fermer(bool ouverte)
		{
			if (!ouverte || --apparitions > 0)
			{
				return;
			}
			apparitions = 0;
			try
			{
				foreach (Character ne in nes)
				{
					Promouvoir(ne);
				}
			}
			finally
			{
				nes.Clear();
			}
		}

		private static void Promouvoir(Character monstre)
		{
			if ((Object)(object)monstre == (Object)null || monstre.IsPlayer() || monstre.IsBoss() || monstre.IsTamed())
			{
				return;
			}
			ZNetView component = ((Component)monstre).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
			{
				int level = monstre.GetLevel();
				int num = Regles.NiveauApresBrume(level, etoilesEnPlus.Value, etoilesMax.Value);
				if (num > level)
				{
					monstre.SetLevel(num);
					Plugin.Journal("Brume : " + ((Object)monstre).name + " apparaît au niveau " + num + " au lieu de " + level + ".");
				}
			}
		}
	}
	public class FestinDOdin : Caprice
	{
		[HarmonyPatch(typeof(Game), "UpdateWorldRates")]
		private static class ApresLeCalculDuJeu
		{
			private static void Postfix()
			{
				vitesseDuJeu = Game.m_foodRate;
				vitesseConnue = true;
				Regler();
			}
		}

		private static FestinDOdin moi;

		private static ConfigEntry<float> duree;

		private static float vitesseDuJeu = 1f;

		private static bool vitesseConnue;

		private static float vitesseAnnoncee = -1f;

		public override string Id => "festin";

		public override string Nom => "Festin d'Odin";

		public override string NomAnglais => "Odin's Feast";

		public override Color Couleur => new Color(1f, 0.65f, 0.2f);

		protected override string[] AnnoncesParDefaut => new string[5] { "Odin dresse sa table ! Aujourd'hui, chaque bouchée tient au ventre bien plus longtemps.", "Festin d'Odin : le Père de tout bénit vos marmites. Mangez, la faim attendra demain.", "Les Ases festoient et vous laissent les restes. Votre repas durera, profitez-en.", "Festin d'Odin ! Les Valkyries servent double ration, et la faim attend son tour.", "Odin régale Midgard. Ce que vous mangez aujourd'hui vous tiendra bien plus longtemps." };

		protected override string[] AnnoncesAnglaisesParDefaut => new string[5] { "Odin lays his table! Today, every bite stays with you much longer.", "Odin's Feast: the Allfather blesses your cauldrons. Eat up, hunger can wait until tomorrow.", "The Aesir are feasting and leave you the leftovers. Your meal will last, enjoy it.", "Odin's Feast! The Valkyries serve double portions, and hunger waits its turn.", "Odin treats Midgard. What you eat today will keep you going much longer." };

		protected override string[] AnnoncesDeLa104 => new string[3] { "Odin dresse sa table ! Aujourd'hui, chaque bouchée tient au ventre bien plus longtemps.", "Festin d'Odin : le Père de tout bénit vos marmites. Mangez, la faim attendra demain.", "Les Ases festoient et vous laissent les restes. Votre repas durera, profitez-en." };

		public FestinDOdin()
		{
			moi = this;
		}

		public override string Resume(bool francais)
		{
			if (!francais)
			{
				return "food lasts ×" + Vocabulaire.Nombre(duree.Value, francais: false);
			}
			return "les nourritures durent ×" + Vocabulaire.Nombre(duree.Value, francais: true);
		}

		protected override void Reglages(ConfigFile config)
		{
			string section = base.Section;
			string text = Langue.Reglage("Food duration multiplier: 2 = twice as long, 1 = no change.", "Multiplicateur de durée des nourritures : 2 = deux fois plus longtemps, 1 = aucun changement.");
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f);
			duree = ConfigFileExtensions.BindConfig<float>(config, section, "Duree", 2f, text, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		public override void Demarrer()
		{
			Regler();
		}

		public override void Arreter()
		{
			Regler();
		}

		public override void Tic()
		{
			Regler();
		}

		private static void Regler()
		{
			if (!vitesseConnue)
			{
				vitesseDuJeu = Game.m_foodRate;
				vitesseConnue = true;
			}
			float num = (moi.EnCours ? (vitesseDuJeu / Mathf.Max(1f, duree.Value)) : vitesseDuJeu);
			if (!Mathf.Approximately(Game.m_foodRate, num))
			{
				Game.m_foodRate = num;
				if (!Mathf.Approximately(vitesseAnnoncee, num))
				{
					vitesseAnnoncee = num;
					Plugin.Journal("Festin : vitesse de consommation de la nourriture réglée à " + Caprice.Nombre(num) + ".");
				}
			}
		}
	}
	public class JourDeLaPlume : Caprice
	{
		[HarmonyPatch(typeof(Character), "UpdateWalking")]
		private static class GraviteReduite
		{
			private static void Postfix(Character __instance, Rigidbody ___m_body)
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				if (moi.EnCours && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ChuteProtegee && !__instance.IsOnGround() && !__instance.IsAttached())
				{
					___m_body.AddForce(-Physics.gravity * (1f - gravite.Value), (ForceMode)5);
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "ModifyFallDamage")]
		private static class AucuneChuteNeBlesse
		{
			private static void Postfix(Character ___m_character, ref float damage)
			{
				if (!((Object)(object)___m_character != (Object)(object)Player.m_localPlayer) && (moi.EnCours || !(Time.time >= immuniteJusqua)))
				{
					if (damage > 0f)
					{
						Plugin.Journal("Plume : chute sans dégâts (" + Caprice.Nombre(damage) + " annulés).");
					}
					damage = 0f;
				}
			}
		}

		private static JourDeLaPlume moi;

		private static ConfigEntry<float> gravite;

		private static float immuniteJusqua;

		public override string Id => "plume";

		public override string Nom => "Jour de la Plume";

		public override string NomAnglais => "Feather Day";

		public override Color Couleur => new Color(0.55f, 0.85f, 1f);

		protected override string[] AnnoncesParDefaut => new string[5] { "Loki a volé leur poids aux mortels. Aujourd'hui, même un troll danserait sur un brin d'herbe.", "Jour de la Plume ! Les corbeaux d'Odin ricanent : sautez, guerriers, le sol ne veut plus de vous.", "Loki souffle sur Midgard. Vos bottes ne pèsent plus rien, et aucune chute ne vous brisera aujourd'hui.", "Jour de la Plume : la gravité prend sa journée. Sautez haut, retombez sans mal.", "Loki a glissé une plume dans chaque botte. Les falaises n'ont plus rien d'effrayant aujourd'hui." };

		protected override string[] AnnoncesAnglaisesParDefaut => new string[5] { "Loki stole the mortals' weight. Today, even a troll could dance on a blade of grass.", "Feather Day! Odin's ravens snicker: jump, warriors, the ground wants nothing to do with you.", "Loki breathes over Midgard. Your boots weigh nothing, and no fall will break you today.", "Feather Day: gravity takes the day off. Jump high, land softly.", "Loki slipped a feather into every boot. Cliffs hold no fear today." };

		protected override string[] AnnoncesDeLa104 => new string[3] { "Loki a volé leur poids aux mortels. Aujourd'hui, même un troll danserait sur un brin d'herbe.", "Jour de la Plume ! Les corbeaux d'Odin ricanent : sautez, guerriers, le sol ne veut plus de vous.", "Loki souffle sur Midgard. Vos bottes ne pèsent plus rien, et aucune chute ne vous brisera aujourd'hui." };

		private static bool ChuteProtegee => Plugin.GreffePosee("AucuneChuteNeBlesse");

		public JourDeLaPlume()
		{
			moi = this;
		}

		public override string Resume(bool francais)
		{
			if (!francais)
			{
				return "gravity ×" + Vocabulaire.Nombre(gravite.Value, francais: false) + " for players, no fall hurts";
			}
			return "gravité ×" + Vocabulaire.Nombre(gravite.Value, francais: true) + " pour les joueurs, aucune chute ne blesse";
		}

		protected override void Reglages(ConfigFile config)
		{
			string section = base.Section;
			string text = Langue.Reglage("Share of normal gravity felt by players: 0.25 = a quarter, 1 = no change.", "Part de la gravité normale subie par les joueurs : 0.25 = un quart, 1 = aucun changement.");
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f);
			gravite = ConfigFileExtensions.BindConfig<float>(config, section, "Gravite", 0.25f, text, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}

		public override void Demarrer()
		{
			if (!ChuteProtegee && !GUIManager.IsHeadless())
			{
				Plugin.Journal("Plume : la protection contre les chutes manque sur cette machine, la gravité reste donc normale.");
			}
		}

		public override void Arreter()
		{
			immuniteJusqua = Time.time + 10f;
		}
	}
	internal class CommandeLoki : ConsoleCommand
	{
		public override string Name => "loki";

		public override string Help
		{
			get
			{
				if (!Langue.Francais)
				{
					return "today's whim. \"loki set " + Mots(francais: false, "|") + "\" changes it (admin).";
				}
				return "le caprice du jour. « loki set " + Mots(francais: true, "|") + " » le change (admin).";
			}
		}

		private static string Mots(bool francais, string separateur)
		{
			return string.Join(separateur, Horloge.Choix.Select((string c) => Vocabulaire.MotAffiche(c, francais)));
		}

		public override List<string> CommandOptionList()
		{
			return new List<string> { "set" };
		}

		public override void Run(string[] args, Terminal context)
		{
			bool francais = Langue.Francais;
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				Repondre(context, francais ? "Loki ne parle qu'en jeu." : "Loki only speaks in game.");
				return;
			}
			if (args.Length == 0)
			{
				Repondre(context, Etat.Phrase());
				return;
			}
			if (args.Length != 2 || args[0].ToLowerInvariant() != "set")
			{
				Repondre(context, (francais ? "Usage : /loki, ou /loki set " : "Usage: /loki, or /loki set ") + Mots(francais, "|"));
				return;
			}
			string text = Vocabulaire.Normaliser(args[1]);
			if (!Horloge.Choix.Contains(text))
			{
				Repondre(context, Vocabulaire.TexteDuRefus(Vocabulaire.Refus("refus-inconnu", args[1]), francais, Horloge.Choix));
			}
			else if (ZNet.instance.IsServer())
			{
				string text2 = Horloge.Forcer(text);
				Repondre(context, (text2 != null) ? Vocabulaire.TexteDuRefus(text2, francais, Horloge.Choix) : ((francais ? "Caprice imposé. " : "Whim forced. ") + Etat.Phrase()));
			}
			else if (!SynchronizationManager.Instance.PlayerIsAdmin)
			{
				Repondre(context, Vocabulaire.TexteDuRefus(Vocabulaire.Refus("refus-pas-admin"), francais, Horloge.Choix));
			}
			else
			{
				Reseau.Demander(text);
				Repondre(context, francais ? "Demande envoyée au serveur." : "Request sent to the server.");
			}
		}

		private static void Repondre(Terminal contexte, string texte)
		{
			if ((Object)(object)contexte != (Object)null)
			{
				contexte.AddString(texte);
			}
		}
	}
	internal static class Etat
	{
		public static Caprice Actif { get; private set; }

		public static int Jour { get; private set; } = -1;

		public static bool Force { get; private set; }

		public static void Appliquer(string id, int jour, bool force)
		{
			Caprice actif = Actif;
			Caprice caprice = Caprice.Par(id);
			bool flag = jour != Jour;
			Actif = caprice;
			Jour = jour;
			Force = force;
			if (caprice != actif)
			{
				actif?.Arreter();
				caprice?.Demarrer();
			}
			if (caprice != actif || flag)
			{
				Annonce.Demander();
				Plugin.Journal("Jour " + jour + " : " + ((caprice != null) ? caprice.Nom : "aucun caprice") + (force ? " (imposé)" : ""));
			}
		}

		public static void Reinitialiser()
		{
			Caprice actif = Actif;
			Actif = null;
			Jour = -1;
			Force = false;
			actif?.Arreter();
			Annonce.Annuler();
		}

		public static void Tic()
		{
			if (Actif != null)
			{
				Actif.Tic();
			}
			Icone.Tic();
		}

		public static string Phrase()
		{
			bool francais = Langue.Francais;
			if (Jour < 0)
			{
				if (!francais)
				{
					return "Loki has not announced anything yet.";
				}
				return "Loki n'a encore rien annoncé.";
			}
			if (Actif == null)
			{
				if (!francais)
				{
					return "Day " + Jour + ": no whim, Loki is silent.";
				}
				return "Jour " + Jour + " : aucun caprice, Loki se tait.";
			}
			return (francais ? ("Jour " + Jour + " : ") : ("Day " + Jour + ": ")) + Actif.NomPour(francais) + " (" + Actif.Resume(francais) + ")" + ((!Force) ? "" : (francais ? " [imposé par un admin]" : " [forced by an admin]"));
		}
	}
	internal static class Annonce
	{
		[HarmonyPatch(typeof(EnvMan), "OnMorning")]
		private static class ApresJourN
		{
			private static void Postfix()
			{
				MatinAffiche();
			}
		}

		private const string Loki = "<color=#F0A030>Loki</color>";

		private const string Silence = "Loki se tait. Aujourd'hui, Midgard suit ses propres lois.";

		private const string SilenceAnglais = "Loki is silent. Today, Midgard follows its own laws.";

		private static bool enAttente;

		private static bool dormait;

		private static float reveil = -1f;

		private static float dernierMatin = -1000f;

		public static void Demander()
		{
			if (!GUIManager.IsHeadless())
			{
				enAttente = true;
			}
		}

		public static void Annuler()
		{
			enAttente = false;
			dormait = false;
			reveil = -1f;
		}

		public static void MatinAffiche()
		{
			dernierMatin = Time.time;
		}

		public static void Tic()
		{
			if (!enAttente)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)Chat.instance == (Object)null || (Object)(object)MessageHud.instance == (Object)null)
			{
				return;
			}
			if (localPlayer.IsSleeping())
			{
				dormait = true;
				return;
			}
			if (dormait)
			{
				dormait = false;
				reveil = Time.time;
			}
			if (reveil >= 0f)
			{
				float num = ((dernierMatin >= reveil - 20f) ? (Mathf.Max(dernierMatin, reveil) + 5f) : (reveil + 30f));
				if (Time.time < num)
				{
					return;
				}
				reveil = -1f;
			}
			enAttente = false;
			Caprice actif = Etat.Actif;
			bool francais = Langue.Francais;
			Plugin.Journal("Annonce affichée : " + ((actif != null) ? actif.Nom : "aucun caprice") + ".");
			Dire((actif != null) ? Tirage.Variante(actif.ListeAnnonces(francais), Etat.Jour) : (francais ? "Loki se tait. Aujourd'hui, Midgard suit ses propres lois." : "Loki is silent. Today, Midgard follows its own laws."));
			MessageHud.instance.ShowMessage((MessageType)2, (actif != null) ? actif.NomPour(francais) : (francais ? "Loki se tait" : "Loki is silent"), 0, (Sprite)null, false, true);
		}

		public static void Dire(string texte)
		{
			if ((Object)(object)Chat.instance == (Object)null)
			{
				return;
			}
			((Terminal)Chat.instance).AddString("<color=#F0A030>Loki</color>" + (Langue.Francais ? " : " : ": ") + texte);
			try
			{
				AccessTools.FieldRefAccess<Chat, float>("m_hideTimer").Invoke(Chat.instance) = 0f;
			}
			catch (Exception)
			{
			}
		}
	}
	internal static class Horloge
	{
		private static readonly Random des = new Random();

		private static int dernierJour = int.MinValue;

		public static IEnumerable<string> Choix => Caprice.Tous.Select((Caprice c) => c.Id).Concat(new string[2] { "aucun", "hasard" });

		public static void Reinitialiser()
		{
			dernierJour = int.MinValue;
		}

		public static void Tic()
		{
			if (!ZNet.instance.IsServer() || (Object)(object)EnvMan.instance == (Object)null)
			{
				return;
			}
			int day = EnvMan.instance.GetDay();
			if (day != dernierJour)
			{
				dernierJour = day;
				List<Tirage.Option> options = Options();
				string text = Tirage.DuJour(Monde(), day, options, Plugin.SansRepetition.Value);
				if (Plugin.SansRepetition.Value && Etat.Force && Etat.Actif != null)
				{
					text = Tirage.SansRedite(Monde(), day, options, text, Etat.Actif.Id);
				}
				Etat.Appliquer(text, day, force: false);
				Reseau.Diffuser();
			}
		}

		public static string Forcer(string choix)
		{
			if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
			{
				return Vocabulaire.Refus("refus-pas-serveur");
			}
			choix = Vocabulaire.Normaliser(choix);
			string text;
			if (choix == "aucun")
			{
				text = "";
			}
			else if (choix == "hasard")
			{
				text = Tirage.Parmi(des.NextDouble(), Options(Etat.Actif, avecCalme: false));
				if (text == "")
				{
					return Vocabulaire.Refus("refus-aucun-autre");
				}
			}
			else
			{
				if (Caprice.Par(choix) == null)
				{
					return Vocabulaire.Refus("refus-inconnu", choix);
				}
				text = choix;
			}
			Etat.Appliquer(text, dernierJour = (((Object)(object)EnvMan.instance != (Object)null) ? EnvMan.instance.GetDay() : Math.Max(0, Etat.Jour)), force: true);
			Reseau.Diffuser();
			return null;
		}

		private static List<Tirage.Option> Options(Caprice sauf = null, bool avecCalme = true)
		{
			List<Tirage.Option> list = (from c in Caprice.Tous
				where c.Actif.Value && c != sauf
				select new Tirage.Option(c.Id, c.Poids.Value)).ToList();
			if (avecCalme)
			{
				list.Add(new Tirage.Option("", Plugin.PoidsJourCalme.Value));
			}
			return list;
		}

		private static long Monde()
		{
			try
			{
				return ZNet.instance.GetWorldUID();
			}
			catch (Exception)
			{
				return 0L;
			}
		}
	}
	internal static class Icone
	{
		private static readonly Dictionary<Caprice, StatusEffect> effets = new Dictionary<Caprice, StatusEffect>();

		public static void Tic()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			SEMan sEMan = ((Character)localPlayer).GetSEMan();
			foreach (Caprice tou in Caprice.Tous)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(NomDe(tou));
				bool flag = sEMan.HaveStatusEffect(stableHashCode);
				if (tou == Etat.Actif && !flag)
				{
					if ((Object)(object)sEMan.AddStatusEffect(Pour(tou), false, 0, 0f, (short)(-1)) != (Object)null)
					{
						Plugin.Journal("Pastille posée : " + tou.Nom + ".");
					}
				}
				else if (tou != Etat.Actif && flag)
				{
					sEMan.RemoveStatusEffect(stableHashCode, true);
				}
			}
		}

		private static string NomDe(Caprice caprice)
		{
			return "SE_Loki_" + caprice.Id;
		}

		private static StatusEffect Pour(Caprice caprice)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!effets.TryGetValue(caprice, out var value) || (Object)(object)value == (Object)null)
			{
				value = ScriptableObject.CreateInstance<StatusEffect>();
				((Object)value).name = NomDe(caprice);
				value.m_icon = Pastille(caprice.Couleur);
				effets[caprice] = value;
			}
			bool francais = Langue.Francais;
			value.m_name = caprice.NomPour(francais);
			value.m_tooltip = caprice.Resume(francais);
			return value;
		}

		private static Sprite Pastille(Color couleur)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_003c: Expected O, but got Unknown
			//IL_00ca: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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)
			Color val = default(Color);
			((Color)(ref val))..ctor(couleur.r * 0.4f, couleur.g * 0.4f, couleur.b * 0.4f, 1f);
			Texture2D val2 = new Texture2D(64, 64, (TextureFormat)4, false);
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(32f, 32f);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), val3);
					val2.SetPixel(j, i, (num > 30f) ? Color.clear : ((num > 24f) ? val : couleur));
				}
			}
			val2.Apply();
			return Sprite.Create(val2, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}
	}
	[BepInPlugin("sixvikings.loki", "SixVikings Loki", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "sixvikings.loki";

		public const string ModNom = "SixVikings Loki";

		public const string ModVersion = "1.1.0";

		internal static ConfigEntry<bool> SansRepetition;

		internal static ConfigEntry<float> PoidsJourCalme;

		private static Plugin instance;

		private static readonly HashSet<string> greffesPosees = new HashSet<string>();

		private ZNet partie;

		private float prochainTic;

		private void Awake()
		{
			instance = this;
			SansRepetition = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "General", "SansRepetition", true, Langue.Reglage("true: the same whim never comes up two days in a row.", "true : un même caprice ne sort jamais deux jours de suite."), true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			ConfigFile config = ((BaseUnityPlugin)this).Config;
			string text = Langue.Reglage("Weight of the \"day without a whim\" in the draw. 0: there is a whim every day.", "Poids du « jour sans caprice » dans le tirage. 0 : il y a un caprice chaque jour.");
			AcceptableValueBase val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f);
			PoidsJourCalme = ConfigFileExtensions.BindConfig<float>(config, "General", "PoidsJourCalme", 0f, text, true, (int?)null, val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			foreach (Caprice tou in Caprice.Tous)
			{
				tou.Configurer(((BaseUnityPlugin)this).Config);
			}
			Reseau.Brancher();
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new CommandeLoki());
			PoserLesGreffes();
		}

		private void PoserLesGreffes()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Harmony val = new Harmony("sixvikings.loki");
			int num = 0;
			int num2 = 0;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				string text = "?";
				try
				{
					HarmonyPatch val2 = type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).OfType<HarmonyPatch>().FirstOrDefault();
					if (val2 != null)
					{
						text = ((((HarmonyAttribute)val2).info.declaringType != null) ? ((HarmonyAttribute)val2).info.declaringType.Name : "?") + "." + ((HarmonyAttribute)val2).info.methodName;
						List<MethodInfo> list = val.CreateClassProcessor(type).Patch();
						if (list == null || list.Count == 0)
						{
							throw new InvalidOperationException("la méthode n'a pas été trouvée");
						}
						num++;
						greffesPosees.Add(type.Name);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Greffe posée : " + type.Name + " sur " + text + "."));
					}
				}
				catch (Exception ex)
				{
					num2++;
					Exception ex2 = ex.InnerException ?? ex;
					((BaseUnityPlugin)this).Logger.LogError((object)("Greffe MANQUANTE : " + type.Name + " sur " + text + " (" + ex2.GetType().Name + " : " + ex2.Message + "). L'effet correspondant ne fonctionnera pas sur cette machine."));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Greffes : " + num + " posée(s), " + num2 + " manquante(s)."));
		}

		private void Update()
		{
			ZNet val = (Object.op_Implicit((Object)(object)ZNet.instance) ? ZNet.instance : null);
			if (val != partie)
			{
				partie = val;
				Etat.Reinitialiser();
				Horloge.Reinitialiser();
			}
			if (!((Object)(object)partie == (Object)null))
			{
				Annonce.Tic();
				if (!(Time.unscaledTime < prochainTic))
				{
					prochainTic = Time.unscaledTime + 1f;
					Horloge.Tic();
					Etat.Tic();
				}
			}
		}

		internal static bool GreffePosee(string classe)
		{
			return greffesPosees.Contains(classe);
		}

		internal static void Journal(string message)
		{
			if ((Object)(object)instance != (Object)null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)message);
			}
		}
	}
	public static class Regles
	{
		public static int NiveauApresBrume(int niveau, int etoilesEnPlus, int etoilesMax)
		{
			int val = Math.Min(niveau + Math.Max(0, etoilesEnPlus), 1 + etoilesMax);
			return Math.Max(niveau, val);
		}

		public static int ButinApresBrume(int avant, float facteur)
		{
			int val = (int)Math.Round((float)avant * facteur);
			return Math.Max(avant, Math.Min(100, val));
		}
	}
	internal static class Reseau
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static CoroutineHandler <0>__RecuParLeServeur;

			public static CoroutineHandler <1>__RecuParUnJoueur;

			public static Func<ZPackage> <2>__EtatPourUnArrivant;
		}

		private const byte PaquetEtat = 1;

		private const byte PaquetDemande = 2;

		private const byte PaquetRefus = 3;

		private static CustomRPC rpc;

		public static void Brancher()
		{
			//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_0025: Expected O, but got Unknown
			//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_0040: Expected O, but got Unknown
			NetworkManager instance = NetworkManager.Instance;
			object obj = <>O.<0>__RecuParLeServeur;
			if (obj == null)
			{
				CoroutineHandler val = RecuParLeServeur;
				<>O.<0>__RecuParLeServeur = val;
				obj = (object)val;
			}
			object obj2 = <>O.<1>__RecuParUnJoueur;
			if (obj2 == null)
			{
				CoroutineHandler val2 = RecuParUnJoueur;
				<>O.<1>__RecuParUnJoueur = val2;
				obj2 = (object)val2;
			}
			rpc = instance.AddRPC("Caprice", (CoroutineHandler)obj, (CoroutineHandler)obj2);
			SynchronizationManager.Instance.AddInitialSynchronization(rpc, (Func<ZPackage>)EtatPourUnArrivant);
		}

		public static void Diffuser()
		{
			if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				rpc.SendPackage(ZNet.instance.GetPeers(), EtatDuJour());
			}
		}

		public static void Demander(string choix)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write((byte)2);
			val.Write(choix);
			rpc.SendPackage(ZNet.instance.GetPeers(), val);
		}

		private static ZPackage EtatDuJour()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0041: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write((byte)1);
			val.Write(Etat.Jour);
			val.Write((Etat.Actif != null) ? Etat.Actif.Id : "");
			val.Write(Etat.Force);
			return val;
		}

		private static ZPackage EtatPourUnArrivant()
		{
			try
			{
				return EtatDuJour();
			}
			catch (Exception ex)
			{
				Plugin.Journal("État non envoyé au joueur qui arrive : " + ex.Message);
				return null;
			}
		}

		private static IEnumerator RecuParLeServeur(long expediteur, ZPackage paquet)
		{
			if (paquet.ReadByte() == 2)
			{
				string choix = paquet.ReadString();
				string text = (ZNetExtension.IsAdmin(ZNet.instance, expediteur) ? Horloge.Forcer(choix) : Vocabulaire.Refus("refus-pas-admin"));
				if (text != null)
				{
					ZPackage val = new ZPackage();
					val.Write((byte)3);
					val.Write(text);
					rpc.SendPackage(expediteur, val);
				}
			}
			yield break;
		}

		private static IEnumerator RecuParUnJoueur(long expediteur, ZPackage paquet)
		{
			switch (paquet.ReadByte())
			{
			case 1:
			{
				int jour = paquet.ReadInt();
				string id = paquet.ReadString();
				bool force = paquet.ReadBool();
				Etat.Appliquer(id, jour, force);
				break;
			}
			case 3:
			{
				bool francais = Langue.Francais;
				Annonce.Dire(Vocabulaire.TexteDuRefus(paquet.ReadString(), francais, Horloge.Choix));
				break;
			}
			}
			yield break;
		}
	}
	public static class Tirage
	{
		public struct Option
		{
			public string Id;

			public float Poids;

			public Option(string id, float poids)
			{
				Id = id;
				Poids = poids;
			}
		}

		public const string Calme = "";

		public static string DuJour(long monde, int jour, IEnumerable<Option> options, bool sansRepetition)
		{
			List<Option> list = Valides(options, null);
			if (list.Count == 0)
			{
				return "";
			}
			jour = Math.Max(0, jour);
			if (!sansRepetition)
			{
				return Choisir(Hasard(monde, jour, 0), list);
			}
			string text = null;
			for (int i = 0; i <= jour; i++)
			{
				string text2 = Choisir(Hasard(monde, i, 0), list);
				if (text2 == text && text2 != "")
				{
					List<Option> list2 = Valides(list, text);
					if (list2.Count > 0)
					{
						text2 = Choisir(Hasard(monde, i, 1), list2);
					}
				}
				text = text2;
			}
			return text;
		}

		public static string SansRedite(long monde, int jour, IEnumerable<Option> options, string prevu, string impose)
		{
			if (prevu == "" || prevu != impose)
			{
				return prevu;
			}
			jour = Math.Max(0, jour);
			List<Option> list = Valides(options, impose);
			if (list.Count == 0)
			{
				return prevu;
			}
			string demain = DuJour(monde, jour + 1, options, sansRepetition: true);
			List<Option> list2 = list.Where((Option o) => o.Id == "" || o.Id != demain).ToList();
			return Choisir(Hasard(monde, jour, 2), (list2.Count > 0) ? list2 : list);
		}

		public static string Parmi(double hasard, IEnumerable<Option> options, string exclu = null)
		{
			List<Option> list = Valides(options, exclu);
			if (list.Count != 0)
			{
				return Choisir(hasard, list);
			}
			return "";
		}

		public static double Hasard(long monde, int jour, int essai)
		{
			long num = monde * -7046029254386353131L + jour * -4658895280553007687L + essai * -7723592293110705685L + -7046029254386353131L;
			long num2 = (num ^ (num >>> 30)) * -4658895280553007687L;
			long num3 = (num2 ^ (num2 >>> 27)) * -7723592293110705685L;
			return (double)((ulong)(num3 ^ (num3 >>> 31)) >> 11) * 1.1102230246251565E-16;
		}

		public static T Variante<T>(IList<T> liste, int jour)
		{
			if (liste == null || liste.Count == 0)
			{
				return default(T);
			}
			return liste[(int)(Hasard(4289L, jour, 7) * (double)liste.Count)];
		}

		private static List<Option> Valides(IEnumerable<Option> options, string exclu)
		{
			return (options ?? Enumerable.Empty<Option>()).Where((Option o) => o.Poids > 0f && o.Id != exclu).OrderBy<Option, string>((Option o) => o.Id, StringComparer.Ordinal).ToList();
		}

		private static string Choisir(double hasard, List<Option> valides)
		{
			double num = hasard * ((IEnumerable<Option>)valides).Sum((Func<Option, double>)((Option o) => o.Poids));
			foreach (Option valide in valides)
			{
				num -= (double)valide.Poids;
				if (num < 0.0)
				{
					return valide.Id;
				}
			}
			return valides[valides.Count - 1].Id;
		}
	}
	public static class Vocabulaire
	{
		public const string Aucun = "aucun";

		public const string Hasard = "hasard";

		public const string RefusPasServeur = "refus-pas-serveur";

		public const string RefusAucunAutre = "refus-aucun-autre";

		public const string RefusInconnu = "refus-inconnu";

		public const string RefusPasAdmin = "refus-pas-admin";

		private static readonly Dictionary<string, string> Anglais = new Dictionary<string, string>
		{
			{ "feather", "plume" },
			{ "feast", "festin" },
			{ "mist", "brume" },
			{ "none", "aucun" },
			{ "random", "hasard" }
		};

		public static string Normaliser(string mot)
		{
			string text = (mot ?? "").Trim().ToLowerInvariant();
			if (!Anglais.TryGetValue(text, out var value))
			{
				return text;
			}
			return value;
		}

		public static string MotAffiche(string choix, bool francais)
		{
			if (francais)
			{
				return choix;
			}
			foreach (KeyValuePair<string, string> anglai in Anglais)
			{
				if (anglai.Value == choix)
				{
					return anglai.Key;
				}
			}
			return choix;
		}

		public static string Refus(string sorte, string detail = null)
		{
			if (detail != null)
			{
				return sorte + ":" + detail;
			}
			return sorte;
		}

		public static string TexteDuRefus(string refus, bool francais, IEnumerable<string> choix)
		{
			if (refus == null)
			{
				return "";
			}
			int num = refus.IndexOf(':');
			string text = ((num >= 0) ? refus.Substring(0, num) : refus);
			string text2 = ((num >= 0) ? refus.Substring(num + 1) : "");
			switch (text)
			{
			case "refus-pas-serveur":
				if (!francais)
				{
					return "Only the server can change the whim.";
				}
				return "Seul le serveur peut changer le caprice.";
			case "refus-aucun-autre":
				if (!francais)
				{
					return "No other enabled whim to draw.";
				}
				return "Aucun autre caprice activé à tirer.";
			case "refus-pas-admin":
				if (!francais)
				{
					return "Only server admins can change the whim.";
				}
				return "Seuls les admins du serveur peuvent changer le caprice.";
			case "refus-inconnu":
			{
				string text3 = string.Join(", ", (choix ?? Enumerable.Empty<string>()).Select((string c) => MotAffiche(c, francais)));
				if (!francais)
				{
					return "Unknown whim: " + text2 + ". Possible choices: " + text3 + ".";
				}
				return "Caprice inconnu : " + text2 + ". Choix possibles : " + text3 + ".";
			}
			default:
				return refus;
			}
		}

		public static string Nombre(float valeur, bool francais)
		{
			string text = valeur.ToString("0.##", CultureInfo.InvariantCulture);
			if (!francais)
			{
				return text;
			}
			return text.Replace('.', ',');
		}
	}
}