Decompiled source of Trait Control v0.1.6

plugins/TraitControl.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Lamb.UI.FollowerInteractionWheel;
using Microsoft.CodeAnalysis;
using MonoMod.Utils;
using Newtonsoft.Json;
using TraitControl.Patches;
using UnityEngine;
using UnityEngine.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("p1xel8ted")]
[assembly: AssemblyConfiguration("Release-Thunderstore")]
[assembly: AssemblyDescription("TraitControl")]
[assembly: AssemblyFileVersion("0.1.6.0")]
[assembly: AssemblyInformationalVersion("0.1.6+b8244049254ee21064962d0fae61b1f02300417a")]
[assembly: AssemblyProduct("TraitControl")]
[assembly: AssemblyTitle("TraitControl")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
internal sealed class ConfigurationManagerAttributes
{
	public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);

	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public CustomHotkeyDrawerFunc CustomHotkeyDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
namespace TraitControl
{
	[BepInPlugin("p1xel8ted.cotl.traitcontrol", "Trait Control", "0.1.6")]
	[BepInDependency("com.bepis.bepinex.configurationmanager", "18.4.1")]
	[BepInIncompatibility("NothingNegative")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <RefreshConfigurationManager>d__162 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					BaseUnityPlugin configurationManager = GetConfigurationManager();
					if ((Object)(object)configurationManager == (Object)null)
					{
						Log.LogWarning((object)"ConfigurationManager plugin not found");
						return false;
					}
					Type type = ((object)configurationManager).GetType();
					PropertyInfo property = type.GetProperty("DisplayingWindow");
					if (property == null)
					{
						Log.LogWarning((object)"ConfigurationManager.DisplayingWindow property not found");
						return false;
					}
					if (!(bool)property.GetValue(configurationManager))
					{
						return false;
					}
					MethodInfo method = type.GetMethod("BuildSettingList");
					if (method == null)
					{
						Log.LogWarning((object)"ConfigurationManager.BuildSettingList method not found");
						return false;
					}
					method.Invoke(configurationManager, null);
					return false;
				}
				}
			}

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

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

		private const string PluginGuid = "p1xel8ted.cotl.traitcontrol";

		internal const string PluginName = "Trait Control";

		private const string PluginVer = "0.1.6";

		private const string TraitReplacementSection = "── Trait Replacement ──";

		private const string UniqueTraitsSection = "── Unique Traits ──";

		private const string NotificationsSection = "── Notifications ──";

		private const string TraitWeightsSection = "── Trait Weights ──";

		private const string GoodTraitsSection = "── Good Traits ──";

		private const string BadTraitsSection = "── Bad Traits ──";

		private const string ResetSettingsSection = "── Reset Settings ──";

		private static bool? _isNothingNegativePresentCache;

		private static bool _showResetConfirmation;

		internal static readonly HashSet<TraitType> StoryEventTraits = new HashSet<TraitType>
		{
			(TraitType)70,
			(TraitType)71,
			(TraitType)75,
			(TraitType)77,
			(TraitType)73,
			(TraitType)74,
			(TraitType)101,
			(TraitType)102,
			(TraitType)103,
			(TraitType)64,
			(TraitType)63,
			(TraitType)62,
			(TraitType)61,
			(TraitType)66,
			(TraitType)65,
			(TraitType)67,
			(TraitType)34,
			(TraitType)78,
			(TraitType)122,
			(TraitType)124,
			(TraitType)125,
			(TraitType)92,
			(TraitType)56,
			(TraitType)53,
			(TraitType)54,
			(TraitType)55,
			(TraitType)57,
			(TraitType)121
		};

		private static Plugin _instance;

		private static bool _showApplyToExistingWarning;

		internal static ConfigEntry<bool> NoNegativeTraits { get; private set; }

		internal static ConfigEntry<bool> ApplyToExistingFollowers { get; private set; }

		internal static ConfigEntry<bool> UseUnlockedTraitsOnly { get; private set; }

		internal static ConfigEntry<bool> PreferExclusiveCounterparts { get; private set; }

		internal static ConfigEntry<bool> PreserveMutatedTrait { get; private set; }

		internal static ConfigEntry<bool> AllowMultipleUniqueTraits { get; private set; }

		internal static ConfigEntry<int> MinimumTraits { get; private set; }

		internal static ConfigEntry<int> MaximumTraits { get; private set; }

		internal static ConfigEntry<bool> RandomizeTraitsOnReindoctrination { get; private set; }

		internal static ConfigEntry<bool> TraitRerollOnReeducation { get; private set; }

		internal static ConfigEntry<bool> ProtectTraitCountOnReroll { get; private set; }

		internal static ConfigEntry<bool> RerollableAltarTraits { get; private set; }

		internal static ConfigEntry<bool> IncludeImmortal { get; private set; }

		internal static ConfigEntry<bool> GuaranteeImmortal { get; private set; }

		internal static ConfigEntry<bool> IncludeDisciple { get; private set; }

		internal static ConfigEntry<bool> GuaranteeDisciple { get; private set; }

		internal static ConfigEntry<bool> IncludeDontStarve { get; private set; }

		internal static ConfigEntry<bool> GuaranteeDontStarve { get; private set; }

		internal static ConfigEntry<bool> IncludeBlind { get; private set; }

		internal static ConfigEntry<bool> GuaranteeBlind { get; private set; }

		internal static ConfigEntry<bool> IncludeBornToTheRot { get; private set; }

		internal static ConfigEntry<bool> GuaranteeBornToTheRot { get; private set; }

		internal static ConfigEntry<bool> IncludeBishopOfCult { get; private set; }

		internal static ConfigEntry<bool> GuaranteeBishopOfCult { get; private set; }

		internal static ConfigEntry<bool> ShowNotificationsWhenRemovingTraits { get; private set; }

		internal static ConfigEntry<bool> ShowNotificationsWhenAddingTraits { get; private set; }

		internal static ConfigEntry<bool> ShowNotificationOnTraitReroll { get; private set; }

		internal static ConfigEntry<bool> EnableTraitWeights { get; private set; }

		internal static ConfigEntry<bool> IncludeStoryEventTraits { get; private set; }

		internal static ConfigEntry<bool> UseAllTraits { get; private set; }

		internal static Dictionary<TraitType, ConfigEntry<float>> TraitWeights { get; } = new Dictionary<TraitType, ConfigEntry<float>>();


		internal static List<TraitType> AllTraitsList { get; } = new List<TraitType>();


		internal static ManualLogSource Log { get; private set; }

		private static ConfigFile ConfigInstance { get; set; }

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Expected O, but got Unknown
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Expected O, but got Unknown
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Expected O, but got Unknown
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Expected O, but got Unknown
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Expected O, but got Unknown
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Expected O, but got Unknown
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Expected O, but got Unknown
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Expected O, but got Unknown
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Expected O, but got Unknown
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_062b: Expected O, but got Unknown
			//IL_069f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a9: Expected O, but got Unknown
			//IL_071f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Expected O, but got Unknown
			//IL_079d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a7: Expected O, but got Unknown
			//IL_081d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0827: Expected O, but got Unknown
			//IL_089b: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a5: Expected O, but got Unknown
			//IL_091b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0925: Expected O, but got Unknown
			//IL_0999: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a3: Expected O, but got Unknown
			//IL_0a19: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a23: Expected O, but got Unknown
			//IL_0a97: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa1: Expected O, but got Unknown
			//IL_0b0a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b14: Expected O, but got Unknown
			//IL_0b54: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5e: Expected O, but got Unknown
			//IL_0b9e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ba8: Expected O, but got Unknown
			//IL_0be9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf3: Expected O, but got Unknown
			//IL_0c5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c67: Expected O, but got Unknown
			//IL_0d07: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d11: Expected O, but got Unknown
			_instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigInstance = ((BaseUnityPlugin)this).Config;
			NoNegativeTraits = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Enable Trait Replacement", false, new ConfigDescription(Localization.DescNoNegativeTraits, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10,
					DispName = Localization.NameEnableTraitReplacement
				}
			}));
			NoNegativeTraits.SettingChanged += delegate
			{
				UpdateNoNegativeTraits();
			};
			ApplyToExistingFollowers = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Apply To Existing Followers", false, new ConfigDescription(Localization.DescApplyToExisting, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 9,
					DispName = Localization.NameApplyToExisting,
					CustomDrawer = DrawApplyToExistingToggle
				}
			}));
			ApplyToExistingFollowers.SettingChanged += delegate
			{
				OnApplyToExistingChanged();
			};
			UseUnlockedTraitsOnly = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Use Unlocked Traits Only", true, new ConfigDescription(Localization.DescUseUnlockedTraits, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 8,
					DispName = Localization.NameUseUnlockedTraits
				}
			}));
			UseUnlockedTraitsOnly.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				TraitControl.Patches.TraitWeights.RefreshAllTraitsList();
				UpdateTraitWeightVisibility();
			};
			UseAllTraits = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Use All Traits Pool", false, new ConfigDescription(Localization.DescUseAllTraits, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 7,
					DispName = Localization.NameUseAllTraits
				}
			}));
			PreferExclusiveCounterparts = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Prefer Exclusive Counterparts", true, new ConfigDescription(Localization.DescPreferExclusive, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 6,
					DispName = Localization.NamePreferExclusive
				}
			}));
			PreserveMutatedTrait = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Preserve Rot Followers", true, new ConfigDescription(Localization.DescPreserveMutated, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 5,
					DispName = Localization.NamePreserveMutated
				}
			}));
			MinimumTraits = ConfigInstance.Bind<int>("── Trait Replacement ──", "Minimum Traits", 2, new ConfigDescription(Localization.DescMinTraits, (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 4,
					DispName = Localization.NameMinTraits
				}
			}));
			MaximumTraits = ConfigInstance.Bind<int>("── Trait Replacement ──", "Maximum Traits", 3, new ConfigDescription(Localization.DescMaxTraits, (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 3,
					DispName = Localization.NameMaxTraits
				}
			}));
			MaximumTraits.SettingChanged += delegate
			{
				if (MaximumTraits.Value < MinimumTraits.Value)
				{
					MaximumTraits.Value = MinimumTraits.Value;
				}
			};
			MinimumTraits.SettingChanged += delegate
			{
				if (MinimumTraits.Value > MaximumTraits.Value)
				{
					MaximumTraits.Value = MinimumTraits.Value;
				}
			};
			RandomizeTraitsOnReindoctrination = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Randomize Traits on Re-indoctrination", false, new ConfigDescription(Localization.DescRandomizeReindoc, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2,
					DispName = Localization.NameRandomizeReindoc
				}
			}));
			TraitRerollOnReeducation = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Trait Reroll via Reeducation", false, new ConfigDescription(Localization.DescTraitReroll, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1,
					DispName = Localization.NameTraitReroll
				}
			}));
			ProtectTraitCountOnReroll = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Protect Trait Count on Reroll", true, new ConfigDescription(Localization.DescProtectTraitCount, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 0,
					DispName = Localization.NameProtectTraitCount
				}
			}));
			RerollableAltarTraits = ConfigInstance.Bind<bool>("── Trait Replacement ──", "Re-rollable Altar Traits", false, new ConfigDescription(Localization.DescRerollableAltar, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = -1,
					DispName = Localization.NameRerollableAltar
				}
			}));
			AllowMultipleUniqueTraits = ConfigInstance.Bind<bool>("── Unique Traits ──", "Allow Multiple Unique Traits", false, new ConfigDescription(Localization.DescAllowMultipleUnique, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 100,
					DispName = Localization.NameAllowMultipleUnique
				}
			}));
			IncludeImmortal = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Immortal", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)32, Localization.SourceSpecialReward), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 20,
					DispName = Localization.NameIncludeTrait("Immortal")
				}
			}));
			IncludeImmortal.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeImmortal = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Immortal", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Immortal"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 19,
					DispName = Localization.NameGuaranteeTrait("Immortal")
				}
			}));
			GuaranteeImmortal.SettingChanged += delegate
			{
				if (GuaranteeImmortal.Value && !IncludeImmortal.Value)
				{
					IncludeImmortal.Value = true;
				}
			};
			IncludeDisciple = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Disciple", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)35, Localization.SourceSpecialReward), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 18,
					DispName = Localization.NameIncludeTrait("Disciple")
				}
			}));
			IncludeDisciple.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeDisciple = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Disciple", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Disciple"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 17,
					DispName = Localization.NameGuaranteeTrait("Disciple")
				}
			}));
			GuaranteeDisciple.SettingChanged += delegate
			{
				if (GuaranteeDisciple.Value && !IncludeDisciple.Value)
				{
					IncludeDisciple.Value = true;
				}
			};
			IncludeDontStarve = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Dont Starve", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)33, Localization.SourceCrossover), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 16,
					DispName = Localization.NameIncludeTrait("Dont Starve")
				}
			}));
			IncludeDontStarve.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeDontStarve = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Dont Starve", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Dont Starve"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 15,
					DispName = Localization.NameGuaranteeTrait("Dont Starve")
				}
			}));
			GuaranteeDontStarve.SettingChanged += delegate
			{
				if (GuaranteeDontStarve.Value && !IncludeDontStarve.Value)
				{
					IncludeDontStarve.Value = true;
				}
			};
			IncludeBlind = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Blind", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)120, Localization.SourceCrossover), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 14,
					DispName = Localization.NameIncludeTrait("Blind")
				}
			}));
			IncludeBlind.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeBlind = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Blind", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Blind"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 13,
					DispName = Localization.NameGuaranteeTrait("Blind")
				}
			}));
			GuaranteeBlind.SettingChanged += delegate
			{
				if (GuaranteeBlind.Value && !IncludeBlind.Value)
				{
					IncludeBlind.Value = true;
				}
			};
			IncludeBornToTheRot = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Born To The Rot", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)123, Localization.SourceCrossover), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 12,
					DispName = Localization.NameIncludeTrait("Born To The Rot")
				}
			}));
			IncludeBornToTheRot.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeBornToTheRot = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Born To The Rot", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Born To The Rot"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 11,
					DispName = Localization.NameGuaranteeTrait("Born To The Rot")
				}
			}));
			GuaranteeBornToTheRot.SettingChanged += delegate
			{
				if (GuaranteeBornToTheRot.Value && !IncludeBornToTheRot.Value)
				{
					IncludeBornToTheRot.Value = true;
				}
			};
			IncludeBishopOfCult = ConfigInstance.Bind<bool>("── Unique Traits ──", "Include Ex-Bishop", false, new ConfigDescription(BuildUniqueTraitDescription((TraitType)81, Localization.SourceBishopConvert), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10,
					DispName = Localization.NameIncludeTrait("Ex-Bishop")
				}
			}));
			IncludeBishopOfCult.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				UpdateTraitWeightVisibility();
			};
			GuaranteeBishopOfCult = ConfigInstance.Bind<bool>("── Unique Traits ──", "Guarantee Ex-Bishop", false, new ConfigDescription(Localization.GuaranteeTraitDesc("Ex-Bishop"), (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 9,
					DispName = Localization.NameGuaranteeTrait("Ex-Bishop")
				}
			}));
			GuaranteeBishopOfCult.SettingChanged += delegate
			{
				if (GuaranteeBishopOfCult.Value && !IncludeBishopOfCult.Value)
				{
					IncludeBishopOfCult.Value = true;
				}
			};
			ShowNotificationsWhenRemovingTraits = ConfigInstance.Bind<bool>("── Notifications ──", "Show When Removing Traits", false, new ConfigDescription(Localization.DescShowRemoving, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 2,
					DispName = Localization.NameShowRemoving
				}
			}));
			ShowNotificationsWhenAddingTraits = ConfigInstance.Bind<bool>("── Notifications ──", "Show When Adding Traits", false, new ConfigDescription(Localization.DescShowAdding, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1,
					DispName = Localization.NameShowAdding
				}
			}));
			ShowNotificationOnTraitReroll = ConfigInstance.Bind<bool>("── Notifications ──", "Show On Trait Reroll", true, new ConfigDescription(Localization.DescShowReroll, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 0,
					DispName = Localization.NameShowReroll
				}
			}));
			EnableTraitWeights = ConfigInstance.Bind<bool>("── Trait Weights ──", "Enable Trait Weights", false, new ConfigDescription(Localization.DescEnableWeights, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 100,
					DispName = Localization.NameEnableWeights
				}
			}));
			EnableTraitWeights.SettingChanged += delegate
			{
				UpdateTraitWeightVisibility();
			};
			IncludeStoryEventTraits = ConfigInstance.Bind<bool>("── Trait Weights ──", "Include Event Traits", false, new ConfigDescription(Localization.DescIncludeEventTraits, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 99,
					DispName = Localization.NameIncludeEventTraits
				}
			}));
			IncludeStoryEventTraits.SettingChanged += delegate
			{
				TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
				TraitControl.Patches.TraitWeights.RefreshAllTraitsList();
				UpdateTraitWeightVisibility();
			};
			GenerateTraitWeightConfigs();
			UpdateTraitWeightVisibility();
			ConfigInstance.Bind<bool>("── Reset Settings ──", "Reset All Settings", false, new ConfigDescription(Localization.DescResetSettings, (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 0,
					DispName = Localization.NameResetSettings,
					HideDefaultButton = true,
					CustomDrawer = ResetAllSettings
				}
			}));
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "p1xel8ted.cotl.traitcontrol");
			Log.LogInfo((object)"Trait Control loaded.");
		}

		internal static void LogAllTraitNames()
		{
			//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_0032: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo((object)"=== Trait Enum Names and Display Names ===");
			foreach (TraitType item in Enum.GetValues(typeof(TraitType)).Cast<TraitType>())
			{
				if ((int)item != 0)
				{
					string localizedTitle = FollowerTrait.GetLocalizedTitle(item);
					bool flag = !string.IsNullOrEmpty(localizedTitle) && !localizedTitle.StartsWith("Traits/");
					Log.LogInfo((object)string.Format("  {0} => \"{1}\"{2}", item, localizedTitle, flag ? "" : " [NOT LOCALIZED]"));
				}
			}
			Log.LogInfo((object)"=== End Trait List ===");
		}

		private static void GenerateTraitWeightConfigs()
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			HashSet<TraitType> hashSet = Enum.GetValues(typeof(TraitType)).Cast<TraitType>().ToHashSet();
			hashSet.Remove((TraitType)0);
			hashSet.Remove((TraitType)80);
			AllTraitsList.Clear();
			IEnumerable<TraitType> enumerable = hashSet;
			if (!IncludeStoryEventTraits.Value)
			{
				enumerable = enumerable.Except(StoryEventTraits);
			}
			AllTraitsList.AddRange(enumerable);
			List<TraitType> list = (from t in hashSet
				where FollowerTrait.GoodTraits.Contains(t)
				orderby ((object)(TraitType)(ref t)).ToString()
				select t).ToList();
			List<TraitType> list2 = (from t in hashSet
				where !FollowerTrait.GoodTraits.Contains(t)
				orderby ((object)(TraitType)(ref t)).ToString()
				select t).ToList();
			bool isHidden = !EnableTraitWeights.Value;
			int count = list.Count;
			foreach (TraitType item in list)
			{
				CreateTraitWeightConfig(item, "── Good Traits ──", count--, isHidden);
			}
			int count2 = list2.Count;
			foreach (TraitType item2 in list2)
			{
				CreateTraitWeightConfig(item2, "── Bad Traits ──", count2--, isHidden);
			}
			Log.LogInfo((object)$"Generated {TraitWeights.Count} trait weight configs ({list.Count} good, {list2.Count} bad).");
		}

		private static void CreateTraitWeightConfig(TraitType trait, string section, int order, bool isHidden)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			string traitCategories = GetTraitCategories(trait);
			string traitDescription = GetTraitDescription(trait);
			string text = ((object)(TraitType)(ref trait)).ToString();
			string traitTitle = GetTraitTitle(trait);
			string dispName = ((!string.IsNullOrEmpty(traitTitle)) ? (traitTitle + " (" + text + ")") : null);
			string text2 = (string.IsNullOrEmpty(traitDescription) ? (Localization.TraitWeightDesc + traitCategories) : (traitDescription + "\n\n" + Localization.TraitWeightDesc + traitCategories));
			ConfigEntry<float> weight = ConfigInstance.Bind<float>(section, text, 1f, new ConfigDescription(text2, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = order,
					Browsable = !isHidden,
					DispName = dispName
				}
			}));
			weight.SettingChanged += delegate
			{
				float num = ((weight.Value < 0.1f) ? 0f : (Mathf.Round(weight.Value / 0.05f) * 0.05f));
				if (!Mathf.Approximately(weight.Value, num))
				{
					weight.Value = num;
				}
			};
			TraitWeights[trait] = weight;
		}

		private static string GetTraitCategories(TraitType trait)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			if (StoryEventTraits.Contains(trait))
			{
				list.Add("Event");
			}
			if (FollowerTrait.UniqueTraits.Contains(trait))
			{
				list.Add("Unique");
			}
			if (FollowerTrait.SingleTraits.Contains(trait))
			{
				list.Add("Single");
			}
			if (FollowerTrait.RareStartingTraits.Contains(trait))
			{
				list.Add("Rare");
			}
			if (FollowerTrait.StartingTraits.Contains(trait))
			{
				list.Add("Starting");
			}
			if (FollowerTrait.FaithfulTraits.Contains(trait))
			{
				list.Add("Faithful");
			}
			if (FollowerTrait.MajorDLCTraits.Contains(trait))
			{
				list.Add("DLC");
			}
			if (FollowerTrait.WinterSpecificTraits.Contains(trait))
			{
				list.Add("Winter");
			}
			if (FollowerTrait.SinTraits.Contains(trait))
			{
				list.Add("Sin");
			}
			if (FollowerTrait.RequiresOnboardingCompleted.Contains(trait))
			{
				list.Add("Unlock");
			}
			if (list.Count <= 0)
			{
				return "\n\n" + Localization.CategoryGrantedOther;
			}
			return "\n\n" + string.Format(Localization.CategoryFoundIn, string.Join(", ", list));
		}

		private static string BuildUniqueTraitDescription(TraitType trait, string source)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string traitDescription = GetTraitDescription(trait);
			string text = Localization.UniqueTraitDesc(((object)(TraitType)(ref trait)).ToString(), source);
			if (!string.IsNullOrEmpty(traitDescription))
			{
				return traitDescription + "\n\n" + text;
			}
			return text;
		}

		private static string GetTraitTitle(TraitType trait)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string localizedTitle = FollowerTrait.GetLocalizedTitle(trait);
				if (string.IsNullOrWhiteSpace(localizedTitle) || localizedTitle.StartsWith("Traits/"))
				{
					return null;
				}
				return StripRichText(localizedTitle);
			}
			catch
			{
				return null;
			}
		}

		private static string GetTraitDescription(TraitType trait)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string localizedDescription = FollowerTrait.GetLocalizedDescription(trait, (FollowerBrain)null);
				if (string.IsNullOrWhiteSpace(localizedDescription) || localizedDescription.StartsWith("Traits/"))
				{
					return null;
				}
				return StripRichText(localizedDescription);
			}
			catch
			{
				return null;
			}
		}

		private static string StripRichText(string input)
		{
			if (string.IsNullOrEmpty(input))
			{
				return input;
			}
			return Regex.Replace(input, "<[^>]+>", string.Empty).Trim();
		}

		private static string SanitizeConfigKey(string input)
		{
			if (string.IsNullOrEmpty(input))
			{
				return null;
			}
			string text = input.Replace("=", "-").Replace("\n", " ").Replace("\t", " ")
				.Replace("\\", "-")
				.Replace("\"", "")
				.Replace("'", "")
				.Replace("[", "(")
				.Replace("]", ")");
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text.Trim();
			}
			return null;
		}

		internal static void RefreshTraitWeightVisibility()
		{
			UpdateTraitWeightVisibility();
		}

		private static void UpdateTraitWeightVisibility()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Invalid comparison between Unknown and I4
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected I4, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			bool value = EnableTraitWeights.Value;
			foreach (KeyValuePair<TraitType, ConfigEntry<float>> traitWeight in TraitWeights)
			{
				ConfigDescription description = ((ConfigEntryBase)traitWeight.Value).Description;
				if (description == null || !(description.Tags?.Length > 0) || !(((ConfigEntryBase)traitWeight.Value).Description.Tags[0] is ConfigurationManagerAttributes configurationManagerAttributes))
				{
					continue;
				}
				bool flag = value;
				bool flag2;
				if (flag)
				{
					TraitType key = traitWeight.Key;
					if ((int)key <= 81)
					{
						switch (key - 32)
						{
						case 0:
							goto IL_00d7;
						case 3:
							goto IL_00e5;
						case 1:
							goto IL_00f3;
						case 2:
							goto IL_012b;
						}
						if ((int)key != 81)
						{
							goto IL_012b;
						}
						flag2 = IncludeBishopOfCult.Value;
					}
					else if ((int)key != 120)
					{
						if ((int)key != 123)
						{
							goto IL_012b;
						}
						flag2 = IncludeBornToTheRot.Value;
					}
					else
					{
						flag2 = IncludeBlind.Value;
					}
					goto IL_012e;
				}
				goto IL_0132;
				IL_012b:
				flag2 = true;
				goto IL_012e;
				IL_0132:
				if (flag && StoryEventTraits.Contains(traitWeight.Key))
				{
					flag = IncludeStoryEventTraits.Value;
				}
				if (flag && UseUnlockedTraitsOnly.Value)
				{
					flag = !FollowerTrait.IsTraitUnavailable(traitWeight.Key);
				}
				configurationManagerAttributes.Browsable = flag;
				continue;
				IL_00f3:
				flag2 = IncludeDontStarve.Value;
				goto IL_012e;
				IL_00e5:
				flag2 = IncludeDisciple.Value;
				goto IL_012e;
				IL_012e:
				flag = flag2;
				goto IL_0132;
				IL_00d7:
				flag2 = IncludeImmortal.Value;
				goto IL_012e;
			}
			Plugin instance = _instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(RefreshConfigurationManager());
			}
		}

		internal static void UpdateTraitDisplayNames()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<TraitType, ConfigEntry<float>> traitWeight in TraitWeights)
			{
				ConfigDescription description = ((ConfigEntryBase)traitWeight.Value).Description;
				if (description != null && description.Tags?.Length > 0 && ((ConfigEntryBase)traitWeight.Value).Description.Tags[0] is ConfigurationManagerAttributes configurationManagerAttributes)
				{
					TraitType key = traitWeight.Key;
					string text = ((object)(TraitType)(ref key)).ToString();
					string traitTitle = GetTraitTitle(traitWeight.Key);
					if (!string.IsNullOrEmpty(traitTitle))
					{
						configurationManagerAttributes.DispName = traitTitle + " (" + text + ")";
					}
					else
					{
						configurationManagerAttributes.DispName = "* " + text;
					}
				}
			}
			Plugin instance = _instance;
			if (instance != null)
			{
				((MonoBehaviour)instance).StartCoroutine(RefreshConfigurationManager());
			}
		}

		private static BaseUnityPlugin GetConfigurationManager()
		{
			return (from p in Chainloader.PluginInfos.Values
				where p.Metadata.GUID == "com.bepis.bepinex.configurationmanager"
				select p.Instance).FirstOrDefault();
		}

		[IteratorStateMachine(typeof(<RefreshConfigurationManager>d__162))]
		private static IEnumerator RefreshConfigurationManager()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <RefreshConfigurationManager>d__162(0);
		}

		private static void UpdateNoNegativeTraits()
		{
			if (IsNothingNegativePresent())
			{
				NoNegativeTraits.Value = false;
			}
			else if (ApplyToExistingFollowers.Value)
			{
				if (NoNegativeTraits.Value)
				{
					TraitControl.Patches.NoNegativeTraits.UpdateAllFollowerTraits();
				}
				else
				{
					TraitControl.Patches.NoNegativeTraits.RestoreOriginalTraits();
				}
			}
		}

		private static void OnApplyToExistingChanged()
		{
			if (!IsNothingNegativePresent())
			{
				if (ApplyToExistingFollowers.Value && NoNegativeTraits.Value)
				{
					TraitControl.Patches.NoNegativeTraits.UpdateAllFollowerTraits();
				}
				else if (!ApplyToExistingFollowers.Value && NoNegativeTraits.Value)
				{
					TraitControl.Patches.NoNegativeTraits.RestoreOriginalTraits();
				}
			}
		}

		private static void DrawApplyToExistingToggle(ConfigEntryBase entry)
		{
			ConfigEntry<bool> val = (ConfigEntry<bool>)(object)entry;
			if (_showApplyToExistingWarning)
			{
				GUILayout.Label(Localization.WarningModifyAll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.Label(Localization.WarningNecklaceLoss, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button(Localization.ButtonConfirm, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
				{
					val.Value = true;
					_showApplyToExistingWarning = false;
				}
				if (GUILayout.Button(Localization.ButtonCancel, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
				{
					_showApplyToExistingWarning = false;
				}
				GUILayout.EndHorizontal();
				return;
			}
			bool flag = GUILayout.Toggle(val.Value, val.Value ? Localization.ToggleEnabled : Localization.ToggleDisabled, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			if (flag != val.Value)
			{
				if (flag)
				{
					_showApplyToExistingWarning = true;
				}
				else
				{
					val.Value = false;
				}
			}
		}

		internal static bool IsNothingNegativePresent()
		{
			bool valueOrDefault = _isNothingNegativePresentCache.GetValueOrDefault();
			if (!_isNothingNegativePresentCache.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.Any((KeyValuePair<string, PluginInfo> plugin) => plugin.Value.Instance.Info.Metadata.GUID.Equals("NothingNegative", StringComparison.OrdinalIgnoreCase));
				_isNothingNegativePresentCache = valueOrDefault;
			}
			return _isNothingNegativePresentCache.Value;
		}

		internal static void L(string message)
		{
			Log.LogInfo((object)message);
		}

		private static void ResetAllSettings(ConfigEntryBase entry)
		{
			if (_showResetConfirmation)
			{
				DisplayResetConfirmation();
			}
			else if (GUILayout.Button(Localization.ButtonResetAll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				_showResetConfirmation = true;
			}
		}

		private static void DisplayResetConfirmation()
		{
			GUILayout.Label(Localization.ConfirmResetAll, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button(Localization.ButtonYes, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				ResetAllToDefaults();
				_showResetConfirmation = false;
			}
			if (GUILayout.Button(Localization.ButtonNo, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }))
			{
				_showResetConfirmation = false;
			}
			GUILayout.EndHorizontal();
		}

		private static void ResetAllToDefaults()
		{
			foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in from e in ConfigInstance.Entries
				where e.Value.BoxedValue != e.Value.DefaultValue
				where e.Key.Section != "── Reset Settings ──"
				select e)
			{
				item.Value.BoxedValue = item.Value.DefaultValue;
				Log.LogInfo((object)$"Reset {item.Key} to default: {item.Value.DefaultValue}");
			}
			TraitControl.Patches.NoNegativeTraits.GenerateAvailableTraits();
			TraitControl.Patches.TraitWeights.RefreshAllTraitsList();
			UpdateTraitWeightVisibility();
		}
	}
	internal static class Localization
	{
		private static readonly Dictionary<string, Dictionary<string, string>> Strings = new Dictionary<string, Dictionary<string, string>>
		{
			{
				"English",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Replace negative traits with positive ones. By default only affects NEW followers. Enable 'Apply To Existing Followers' to also modify current followers." },
					{ "DescApplyToExisting", "When enabled, trait replacement also applies to existing followers (not just new ones). Disabling will restore original traits." },
					{ "DescUseUnlockedTraits", "Only use traits you have unlocked. Applies to both trait replacement and new follower trait selection." },
					{ "DescUseAllTraits", "Merge all trait pools into one, bypassing vanilla's normal/rare split. Without this, vanilla assigns traits from separate pools (normal pool by default, ~10% chance of rare pool per trait). Enable this for trait weights to have full control over distribution. Unique traits require their individual toggles." },
					{ "DescPreferExclusive", "When replacing negative traits, exclusive traits (like Lazy) are replaced with their positive counterpart (Industrious) instead of a random trait." },
					{ "DescPreserveMutated", "When enabled, Rot (Mutated) followers will not have their trait removed. Rot followers are mechanically distinct and useful for certain rituals." },
					{ "DescMinTraits", "Minimum number of traits new followers will have. Vanilla is 2." },
					{ "DescMaxTraits", "Maximum number of traits new followers will have. Vanilla is 3. Limited to 8 due to UI constraints." },
					{ "DescRandomizeReindoc", "When re-indoctrinating an existing follower (at the altar), randomize their traits using the configured min/max. Vanilla re-indoctrination only changes appearance/name." },
					{ "DescTraitReroll", "Adds the Re-educate command to normal followers. Using it will re-roll their traits using the configured min/max and weights." },
					{ "DescProtectTraitCount", "When rerolling traits (via reeducation or reindoctrination), ensure the follower doesn't end up with fewer traits than they started with." },
					{ "DescRerollableAltar", "When using the Exorcism Altar, re-selecting a follower shows different trait results each time instead of the same result per day." },
					{ "DescAllowMultipleUnique", "Allow multiple followers to have the same unique trait (Immortal, Disciple, etc.). Normally only one follower can have each unique trait." },
					{ "UniqueTraitDesc", "Allow the {0} trait ({1}) to appear in trait pools." },
					{ "GuaranteeTraitDesc", "New followers will always receive the {0} trait (ignores weights). Only one follower can have this trait." },
					{ "SourceSpecialReward", "normally a special reward" },
					{ "SourceCrossover", "crossover reward" },
					{ "SourceBishopConvert", "normally granted when converting a bishop" },
					{ "DescShowRemoving", "Show notifications when trait replacement removes negative traits." },
					{ "DescShowAdding", "Show notifications when trait replacement adds positive traits." },
					{ "DescShowReroll", "Show a notification when a follower's traits are rerolled via reeducation or reindoctrination." },
					{ "DescEnableWeights", "Enable weighted random selection for new followers. Weights affect trait selection within each pool. For full control over all traits, enable 'Use All Traits Pool' - otherwise vanilla's normal/rare pool split still applies (rare pool has ~10% chance per trait). Set a weight to 0 to disable a trait." },
					{ "DescIncludeEventTraits", "Include traits normally granted through gameplay events (marriage, parenting, criminal, missionary, etc.) in the weights list. Only applies when 'Use All Traits Pool' is enabled. Warning: This can result in nonsensical assignments (e.g., ProudParent on followers who have never had children)." },
					{ "DescResetSettings", "Click to reset all settings to defaults (vanilla behavior)." },
					{ "TraitWeightDesc", "Weight: Higher = more likely relative to other traits. Set to 0 to disable. Default is 1.0. With ~85 traits at weight 1: weight 10 ~ 10%, weight 50 ~ 37%, weight 100 ~ 54%." },
					{ "CategoryFoundIn", "Found in: {0}" },
					{ "CategoryGrantedOther", "Granted via other means (doctrines, rituals, events, etc.)" },
					{ "WarningModifyAll", "WARNING: This will modify ALL existing followers!" },
					{ "WarningNecklaceLoss", "Traits from necklaces may be lost on restore." },
					{ "ButtonConfirm", "Confirm" },
					{ "ButtonCancel", "Cancel" },
					{ "ToggleEnabled", "Enabled" },
					{ "ToggleDisabled", "Disabled" },
					{ "ButtonResetAll", "Reset All Settings" },
					{ "ConfirmResetAll", "Are you sure? This will reset all settings to defaults." },
					{ "ButtonYes", "Yes" },
					{ "ButtonNo", "No" },
					{ "NotifyTraitsRerolled", "<color=#FFD201>{0}</color>'s traits rerolled! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Enable Trait Replacement" },
					{ "NameApplyToExisting", "Apply To Existing Followers" },
					{ "NameUseUnlockedTraits", "Use Unlocked Traits Only" },
					{ "NameUseAllTraits", "Use All Traits Pool" },
					{ "NamePreferExclusive", "Prefer Exclusive Counterparts" },
					{ "NamePreserveMutated", "Preserve Rot Followers" },
					{ "NameMinTraits", "Minimum Traits" },
					{ "NameMaxTraits", "Maximum Traits" },
					{ "NameRandomizeReindoc", "Randomize on Re-indoctrination" },
					{ "NameTraitReroll", "Trait Reroll via Reeducation" },
					{ "NameProtectTraitCount", "Protect Trait Count" },
					{ "NameRerollableAltar", "Re-rollable Altar Traits" },
					{ "NameAllowMultipleUnique", "Allow Multiple Unique Traits" },
					{ "NameIncludeTrait", "Include {0}" },
					{ "NameGuaranteeTrait", "    └ Guarantee {0}" },
					{ "NameShowRemoving", "Show When Removing" },
					{ "NameShowAdding", "Show When Adding" },
					{ "NameShowReroll", "Show On Reroll" },
					{ "NameEnableWeights", "Enable Trait Weights" },
					{ "NameIncludeEventTraits", "Include Event Traits" },
					{ "NameResetSettings", "Reset All Settings" }
				}
			},
			{
				"Japanese",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "ネガティブな特性をポジティブなものに置き換えます。デフォルトでは新しいフォロワーのみに適用されます。「既存のフォロワーに適用」を有効にすると、現在のフォロワーも変更されます。" },
					{ "DescApplyToExisting", "有効にすると、特性の置き換えが既存のフォロワーにも適用されます。無効にすると元の特性が復元されます。" },
					{ "DescUseUnlockedTraits", "解放済みの特性のみを使用します。特性の置き換えと新しいフォロワーの特性選択の両方に適用されます。" },
					{ "DescUseAllTraits", "すべての特性プールを1つに統合し、バニラの通常/レアの分割をバイパスします。これがないと、バニラは別々のプールから特性を割り当てます(デフォルトは通常プール、特性ごとに約10%の確率でレアプール)。特性ウェイトで完全に制御するにはこれを有効にしてください。ユニーク特性は個別のトグルが必要です。" },
					{ "DescPreferExclusive", "ネガティブ特性を置き換える際、排他的特性(怠惰など)はランダムな特性ではなく、ポジティブな対になる特性(勤勉)に置き換えられます。" },
					{ "DescPreserveMutated", "有効にすると、ロット(変異)フォロワーの特性は削除されません。ロットフォロワーは特定の儀式に役立ちます。" },
					{ "DescMinTraits", "新しいフォロワーが持つ特性の最小数。バニラは2です。" },
					{ "DescMaxTraits", "新しいフォロワーが持つ特性の最大数。バニラは3です。UIの制約により8が上限です。" },
					{ "DescRandomizeReindoc", "既存のフォロワーを再教化する際(祭壇で)、設定されたmin/maxを使用して特性をランダム化します。バニラの再教化は外見/名前のみ変更します。" },
					{ "DescTraitReroll", "通常のフォロワーに再教育コマンドを追加します。使用すると、設定されたmin/maxとウェイトを使用して特性がリロールされます。" },
					{ "DescProtectTraitCount", "特性をリロールする際(再教育または再教化)、フォロワーの特性数が開始時より少なくならないようにします。" },
					{ "DescRerollableAltar", "エクソシズム祭壇使用時、フォロワーを再選択するたびに異なる特性結果が表示されます(1日1回の固定結果ではなく)。" },
					{ "DescAllowMultipleUnique", "複数のフォロワーが同じユニーク特性(不死、弟子など)を持つことを許可します。通常、各ユニーク特性は1人のフォロワーのみが持てます。" },
					{ "UniqueTraitDesc", "{0}特性({1})が特性プールに出現することを許可します。" },
					{ "GuaranteeTraitDesc", "新しいフォロワーは必ず{0}特性を受け取ります(ウェイトを無視)。この特性を持てるのは1人のフォロワーのみです。" },
					{ "SourceSpecialReward", "通常は特別な報酬" },
					{ "SourceCrossover", "クロスオーバー報酬" },
					{ "SourceBishopConvert", "通常はビショップを改宗させた際に付与" },
					{ "DescShowRemoving", "特性の置き換えがネガティブ特性を削除した際に通知を表示します。" },
					{ "DescShowAdding", "特性の置き換えがポジティブ特性を追加した際に通知を表示します。" },
					{ "DescShowReroll", "再教育または再教化でフォロワーの特性がリロールされた際に通知を表示します。" },
					{ "DescEnableWeights", "新しいフォロワーに重み付きランダム選択を有効にします。ウェイトは各プール内の特性選択に影響します。すべての特性を完全に制御するには「すべての特性プールを使用」を有効にしてください。そうでない場合、バニラの通常/レアプール分割が適用されます(レアプールは特性ごとに約10%の確率)。ウェイトを0に設定すると特性が無効になります。" },
					{ "DescIncludeEventTraits", "ゲームプレイイベント(結婚、育児、犯罪、宣教師など)で付与される特性をウェイトリストに含めます。「すべての特性プールを使用」が有効な場合のみ適用されます。警告:不自然な割り当て(子供がいないフォロワーにProudParentなど)が発生する可能性があります。" },
					{ "DescResetSettings", "クリックしてすべての設定をデフォルト(バニラの動作)にリセットします。" },
					{ "TraitWeightDesc", "ウェイト:高いほど他の特性に比べて出現しやすくなります。0に設定すると無効になります。デフォルトは1.0です。約85の特性がウェイト1の場合:ウェイト10 ~ 10%、ウェイト50 ~ 37%、ウェイト100 ~ 54%。" },
					{ "CategoryFoundIn", "所属: {0}" },
					{ "CategoryGrantedOther", "その他の方法で付与(教義、儀式、イベントなど)" },
					{ "WarningModifyAll", "警告:既存のすべてのフォロワーが変更されます!" },
					{ "WarningNecklaceLoss", "ネックレスから付与された特性は復元時に失われる可能性があります。" },
					{ "ButtonConfirm", "確認" },
					{ "ButtonCancel", "キャンセル" },
					{ "ToggleEnabled", "有効" },
					{ "ToggleDisabled", "無効" },
					{ "ButtonResetAll", "すべての設定をリセット" },
					{ "ConfirmResetAll", "よろしいですか?すべての設定がデフォルトにリセットされます。" },
					{ "ButtonYes", "はい" },
					{ "ButtonNo", "いいえ" },
					{ "NotifyTraitsRerolled", "<color=#FFD201>{0}</color>の特性がリロールされました!({1} → {2})" },
					{ "NameEnableTraitReplacement", "特性置換を有効化" },
					{ "NameApplyToExisting", "既存の信者に適用" },
					{ "NameUseUnlockedTraits", "解除済み特性のみ使用" },
					{ "NameUseAllTraits", "全特性プール使用" },
					{ "NamePreferExclusive", "専用対応特性を優先" },
					{ "NamePreserveMutated", "腐敗信者を保持" },
					{ "NameMinTraits", "最小特性数" },
					{ "NameMaxTraits", "最大特性数" },
					{ "NameRandomizeReindoc", "再教化時にランダム化" },
					{ "NameTraitReroll", "再教育で特性リロール" },
					{ "NameProtectTraitCount", "特性数を保護" },
					{ "NameRerollableAltar", "祭壇特性を再ロール可能に" },
					{ "NameAllowMultipleUnique", "固有特性の複数所持を許可" },
					{ "NameIncludeTrait", "{0}を含む" },
					{ "NameGuaranteeTrait", "    └ {0}を保証" },
					{ "NameShowRemoving", "削除時に表示" },
					{ "NameShowAdding", "追加時に表示" },
					{ "NameShowReroll", "リロール時に表示" },
					{ "NameEnableWeights", "特性重み付けを有効化" },
					{ "NameIncludeEventTraits", "イベント特性を含む" },
					{ "NameResetSettings", "全設定をリセット" }
				}
			},
			{
				"Russian",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Заменяет негативные черты на позитивные. По умолчанию влияет только на НОВЫХ последователей. Включите 'Применить к существующим' для изменения текущих последователей." },
					{ "DescApplyToExisting", "Замена черт также применяется к существующим последователям (не только новым). Отключение восстановит исходные черты." },
					{ "DescUseUnlockedTraits", "Использовать только разблокированные черты. Применяется к замене черт и выбору черт для новых последователей." },
					{ "DescUseAllTraits", "Объединить все пулы черт в один, обходя ванильное разделение на обычные/редкие. Без этого ванильная игра назначает черты из отдельных пулов (обычный пул по умолчанию, ~10% шанс редкого пула на черту). Включите для полного контроля весов. Уникальные черты требуют индивидуальных переключателей." },
					{ "DescPreferExclusive", "При замене негативных черт эксклюзивные черты (Ленивый) заменяются позитивной парой (Трудолюбивый) вместо случайной черты." },
					{ "DescPreserveMutated", "Рот (Мутированные) последователи не лишатся своей черты. Рот-последователи механически уникальны и полезны для ритуалов." },
					{ "DescMinTraits", "Минимальное количество черт для новых последователей. Ванильное значение: 2." },
					{ "DescMaxTraits", "Максимальное количество черт для новых последователей. Ванильное значение: 3. Ограничено 8 из-за интерфейса." },
					{ "DescRandomizeReindoc", "При реиндоктринации последователя (на алтаре) рандомизировать черты используя настроенные min/max. Ванильная реиндоктринация меняет только внешность/имя." },
					{ "DescTraitReroll", "Добавляет команду 'Перевоспитать' обычным последователям. Перебрасывает черты используя настроенные min/max и веса." },
					{ "DescProtectTraitCount", "При перебросе черт (перевоспитание или реиндоктринация) последователь не получит меньше черт, чем было изначально." },
					{ "DescRerollableAltar", "При использовании Алтаря Экзорцизма повторный выбор последователя показывает разные результаты каждый раз (а не одинаковые за день)." },
					{ "DescAllowMultipleUnique", "Разрешить нескольким последователям иметь одну и ту же уникальную черту (Бессмертный, Ученик и т.д.)." },
					{ "UniqueTraitDesc", "Разрешить черте {0} ({1}) появляться в пулах черт." },
					{ "GuaranteeTraitDesc", "Новые последователи всегда получают черту {0} (игнорирует веса). Только один последователь может иметь эту черту." },
					{ "SourceSpecialReward", "обычно особая награда" },
					{ "SourceCrossover", "кроссовер-награда" },
					{ "SourceBishopConvert", "обычно даётся при обращении епископа" },
					{ "DescShowRemoving", "Показывать уведомления при удалении негативных черт." },
					{ "DescShowAdding", "Показывать уведомления при добавлении позитивных черт." },
					{ "DescShowReroll", "Показывать уведомление при перебросе черт через перевоспитание или реиндоктринацию." },
					{ "DescEnableWeights", "Включить взвешенный случайный выбор для новых последователей. Веса влияют на выбор черт в каждом пуле. Для полного контроля включите 'Использовать все пулы черт' -иначе ванильное разделение на обычный/редкий пул сохраняется (редкий пул ~10% шанс на черту). Установите вес 0, чтобы отключить черту." },
					{ "DescIncludeEventTraits", "Включить черты, обычно получаемые через игровые события (брак, родительство, преступления, миссионерство и т.д.) в список весов. Применяется только при включённом 'Использовать все пулы черт'. Предупреждение: может привести к нелогичным назначениям." },
					{ "DescResetSettings", "Нажмите для сброса всех настроек к значениям по умолчанию (ванильное поведение)." },
					{ "TraitWeightDesc", "Вес: Выше = вероятнее относительно других черт. 0 = отключено. По умолчанию 1.0. При ~85 чертах с весом 1: вес 10 ~ 10%, вес 50 ~ 37%, вес 100 ~ 54%." },
					{ "CategoryFoundIn", "Найдено в: {0}" },
					{ "CategoryGrantedOther", "Даётся другими способами (доктрины, ритуалы, события и т.д.)" },
					{ "WarningModifyAll", "ВНИМАНИЕ: Все существующие последователи будут изменены!" },
					{ "WarningNecklaceLoss", "Черты от ожерелий могут быть потеряны при восстановлении." },
					{ "ButtonConfirm", "Подтвердить" },
					{ "ButtonCancel", "Отмена" },
					{ "ToggleEnabled", "Включено" },
					{ "ToggleDisabled", "Выключено" },
					{ "ButtonResetAll", "Сбросить все настройки" },
					{ "ConfirmResetAll", "Вы уверены? Все настройки будут сброшены к значениям по умолчанию." },
					{ "ButtonYes", "Да" },
					{ "ButtonNo", "Нет" },
					{ "NotifyTraitsRerolled", "Черты <color=#FFD201>{0}</color> переброшены! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Включить замену черт" },
					{ "NameApplyToExisting", "Применить к существующим" },
					{ "NameUseUnlockedTraits", "Только разблокированные черты" },
					{ "NameUseAllTraits", "Все черты" },
					{ "NamePreferExclusive", "Предпочитать эксклюзивные" },
					{ "NamePreserveMutated", "Сохранять гнилых последователей" },
					{ "NameMinTraits", "Минимум черт" },
					{ "NameMaxTraits", "Максимум черт" },
					{ "NameRandomizeReindoc", "Рандомизировать при переобращении" },
					{ "NameTraitReroll", "Переброс черт через перевоспитание" },
					{ "NameProtectTraitCount", "Защитить количество черт" },
					{ "NameRerollableAltar", "Переброс черт алтаря" },
					{ "NameAllowMultipleUnique", "Несколько уникальных черт" },
					{ "NameIncludeTrait", "Включить {0}" },
					{ "NameGuaranteeTrait", "    └ Гарантировать {0}" },
					{ "NameShowRemoving", "Показывать при удалении" },
					{ "NameShowAdding", "Показывать при добавлении" },
					{ "NameShowReroll", "Показывать при перебросе" },
					{ "NameEnableWeights", "Включить веса черт" },
					{ "NameIncludeEventTraits", "Включить черты событий" },
					{ "NameResetSettings", "Сбросить все настройки" }
				}
			},
			{
				"French",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Remplace les traits négatifs par des positifs. Par défaut, n'affecte que les NOUVEAUX suiveurs. Activez 'Appliquer aux suiveurs existants' pour modifier les suiveurs actuels." },
					{ "DescApplyToExisting", "Le remplacement des traits s'applique aussi aux suiveurs existants (pas seulement les nouveaux). Désactiver restaurera les traits originaux." },
					{ "DescUseUnlockedTraits", "Utiliser uniquement les traits débloqués. S'applique au remplacement et à la sélection des traits des nouveaux suiveurs." },
					{ "DescUseAllTraits", "Fusionner tous les pools de traits en un seul, contournant la séparation normal/rare du jeu. Sans cela, le jeu assigne les traits depuis des pools séparés (pool normal par défaut, ~10% de chance du pool rare par trait). Activez ceci pour un contrôle total des poids. Les traits uniques nécessitent leurs propres boutons." },
					{ "DescPreferExclusive", "Lors du remplacement des traits négatifs, les traits exclusifs (comme Paresseux) sont remplacés par leur contrepartie positive (Industrieux) au lieu d'un trait aléatoire." },
					{ "DescPreserveMutated", "Les suiveurs Rot (Mutés) ne perdront pas leur trait. Les suiveurs Rot sont mécaniquement distincts et utiles pour certains rituels." },
					{ "DescMinTraits", "Nombre minimum de traits des nouveaux suiveurs. Vanilla : 2." },
					{ "DescMaxTraits", "Nombre maximum de traits des nouveaux suiveurs. Vanilla : 3. Limité à 8 pour des raisons d'interface." },
					{ "DescRandomizeReindoc", "Lors de la réendoctrinement d'un suiveur (à l'autel), randomiser ses traits avec les min/max configurés. Le réendoctrinement vanilla ne change que l'apparence/le nom." },
					{ "DescTraitReroll", "Ajoute la commande Rééduquer aux suiveurs normaux. L'utiliser relance leurs traits avec les min/max et poids configurés." },
					{ "DescProtectTraitCount", "Lors du reroll des traits (rééducation ou réendoctrinement), le suiveur ne se retrouvera pas avec moins de traits qu'au départ." },
					{ "DescRerollableAltar", "Avec l'Autel d'Exorcisme, resélectionner un suiveur affiche des résultats différents à chaque fois au lieu du même résultat par jour." },
					{ "DescAllowMultipleUnique", "Permettre à plusieurs suiveurs d'avoir le même trait unique (Immortel, Disciple, etc.)." },
					{ "UniqueTraitDesc", "Permettre au trait {0} ({1}) d'apparaître dans les pools de traits." },
					{ "GuaranteeTraitDesc", "Les nouveaux suiveurs recevront toujours le trait {0} (ignore les poids). Un seul suiveur peut avoir ce trait." },
					{ "SourceSpecialReward", "normalement une récompense spéciale" },
					{ "SourceCrossover", "récompense crossover" },
					{ "SourceBishopConvert", "normalement accordé en convertissant un évêque" },
					{ "DescShowRemoving", "Afficher les notifications lors de la suppression de traits négatifs." },
					{ "DescShowAdding", "Afficher les notifications lors de l'ajout de traits positifs." },
					{ "DescShowReroll", "Afficher une notification quand les traits d'un suiveur sont relancés via rééducation ou réendoctrinement." },
					{ "DescEnableWeights", "Activer la sélection aléatoire pondérée pour les nouveaux suiveurs. Les poids affectent la sélection dans chaque pool. Pour un contrôle total, activez 'Utiliser tous les pools de traits' -sinon la séparation normal/rare du jeu s'applique (pool rare ~10% par trait). Mettez un poids à 0 pour désactiver un trait." },
					{ "DescIncludeEventTraits", "Inclure les traits normalement accordés par des événements de jeu (mariage, parentalité, criminel, missionnaire, etc.) dans la liste des poids. S'applique uniquement avec 'Utiliser tous les pools de traits'. Attention : peut causer des assignations absurdes." },
					{ "DescResetSettings", "Cliquez pour réinitialiser tous les paramètres par défaut (comportement vanilla)." },
					{ "TraitWeightDesc", "Poids : Plus élevé = plus probable par rapport aux autres traits. 0 = désactivé. Défaut : 1.0. Avec ~85 traits à poids 1 : poids 10 ~ 10%, poids 50 ~ 37%, poids 100 ~ 54%." },
					{ "CategoryFoundIn", "Trouvé dans : {0}" },
					{ "CategoryGrantedOther", "Accordé par d'autres moyens (doctrines, rituels, événements, etc.)" },
					{ "WarningModifyAll", "ATTENTION : Tous les suiveurs existants seront modifiés !" },
					{ "WarningNecklaceLoss", "Les traits des colliers pourraient être perdus lors de la restauration." },
					{ "ButtonConfirm", "Confirmer" },
					{ "ButtonCancel", "Annuler" },
					{ "ToggleEnabled", "Activé" },
					{ "ToggleDisabled", "Désactivé" },
					{ "ButtonResetAll", "Réinitialiser tous les paramètres" },
					{ "ConfirmResetAll", "Êtes-vous sûr ? Tous les paramètres seront réinitialisés par défaut." },
					{ "ButtonYes", "Oui" },
					{ "ButtonNo", "Non" },
					{ "NotifyTraitsRerolled", "Traits de <color=#FFD201>{0}</color> relancés ! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Activer remplacement des traits" },
					{ "NameApplyToExisting", "Appliquer aux suivants existants" },
					{ "NameUseUnlockedTraits", "Traits débloqués uniquement" },
					{ "NameUseAllTraits", "Tous les traits" },
					{ "NamePreferExclusive", "Préférer les exclusifs" },
					{ "NamePreserveMutated", "Préserver suivants pourris" },
					{ "NameMinTraits", "Traits minimum" },
					{ "NameMaxTraits", "Traits maximum" },
					{ "NameRandomizeReindoc", "Aléatoire lors de réendoctrinement" },
					{ "NameTraitReroll", "Relance de traits par rééducation" },
					{ "NameProtectTraitCount", "Protéger le nombre de traits" },
					{ "NameRerollableAltar", "Traits d'autel relançables" },
					{ "NameAllowMultipleUnique", "Plusieurs traits uniques" },
					{ "NameIncludeTrait", "Inclure {0}" },
					{ "NameGuaranteeTrait", "    └ Garantir {0}" },
					{ "NameShowRemoving", "Afficher lors de suppression" },
					{ "NameShowAdding", "Afficher lors d'ajout" },
					{ "NameShowReroll", "Afficher lors de relance" },
					{ "NameEnableWeights", "Activer poids des traits" },
					{ "NameIncludeEventTraits", "Inclure traits d'événements" },
					{ "NameResetSettings", "Réinitialiser tous les paramètres" }
				}
			},
			{
				"German",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Ersetzt negative Eigenschaften durch positive. Standardmäßig nur für NEUE Anhänger. Aktivieren Sie 'Auf bestehende Anhänger anwenden', um auch aktuelle Anhänger zu aendern." },
					{ "DescApplyToExisting", "Eigenschaftsersetzung gilt auch für bestehende Anhänger (nicht nur neue). Deaktivieren stellt die ursprünglichen Eigenschaften wieder her." },
					{ "DescUseUnlockedTraits", "Nur freigeschaltete Eigenschaften verwenden. Gilt für Eigenschaftsersetzung und neue Anhänger-Auswahl." },
					{ "DescUseAllTraits", "Alle Eigenschaftspools zu einem zusammenführen und die Vanilla-Normal/Selten-Aufteilung umgehen. Ohne dies weist Vanilla Eigenschaften aus getrennten Pools zu (Normalpool standardmäßig, ~10% Chance auf Seltenpool pro Eigenschaft). Aktivieren Sie dies für volle Gewichtskontrolle. Einzigartige Eigenschaften benötigen individuelle Schalter." },
					{ "DescPreferExclusive", "Beim Ersetzen negativer Eigenschaften werden exklusive Eigenschaften (wie Faul) durch ihr positives Gegenstück (Fleißig) statt einer zufälligen Eigenschaft ersetzt." },
					{ "DescPreserveMutated", "Rot (Mutierte) Anhänger verlieren ihre Eigenschaft nicht. Rot-Anhänger sind mechanisch einzigartig und nützlich für bestimmte Rituale." },
					{ "DescMinTraits", "Minimale Anzahl an Eigenschaften für neue Anhänger. Vanilla: 2." },
					{ "DescMaxTraits", "Maximale Anzahl an Eigenschaften für neue Anhänger. Vanilla: 3. Auf 8 begrenzt (UI-Einschränkungen)." },
					{ "DescRandomizeReindoc", "Bei der Re-Indoktrinierung eines Anhängers (am Altar) werden Eigenschaften mit den konfigurierten Min/Max randomisiert. Vanilla-Re-Indoktrinierung ändert nur Aussehen/Name." },
					{ "DescTraitReroll", "Fügt normalen Anhängern den Umerziehen-Befehl hinzu. Würfelt Eigenschaften mit konfigurierten Min/Max und Gewichten neu." },
					{ "DescProtectTraitCount", "Beim Neuwürfeln (Umerziehung oder Re-Indoktrinierung) erhält der Anhänger nicht weniger Eigenschaften als zuvor." },
					{ "DescRerollableAltar", "Am Exorzismus-Altar zeigt die erneute Auswahl eines Anhängers jedes Mal andere Ergebnisse statt desselben Ergebnisses pro Tag." },
					{ "DescAllowMultipleUnique", "Mehreren Anhängern erlauben, dieselbe einzigartige Eigenschaft zu haben (Unsterblich, Schüler usw.)." },
					{ "UniqueTraitDesc", "Erlaubt der Eigenschaft {0} ({1}), in Eigenschaftspools zu erscheinen." },
					{ "GuaranteeTraitDesc", "Neue Anhänger erhalten immer die Eigenschaft {0} (ignoriert Gewichte). Nur ein Anhänger kann diese Eigenschaft haben." },
					{ "SourceSpecialReward", "normalerweise eine besondere Belohnung" },
					{ "SourceCrossover", "Crossover-Belohnung" },
					{ "SourceBishopConvert", "normalerweise beim Bekehren eines Bischofs gewährt" },
					{ "DescShowRemoving", "Benachrichtigungen anzeigen, wenn negative Eigenschaften entfernt werden." },
					{ "DescShowAdding", "Benachrichtigungen anzeigen, wenn positive Eigenschaften hinzugefügt werden." },
					{ "DescShowReroll", "Benachrichtigung anzeigen, wenn Eigenschaften eines Anhängers durch Umerziehung oder Re-Indoktrinierung neu gewürfelt werden." },
					{ "DescEnableWeights", "Gewichtete Zufallsauswahl für neue Anhänger aktivieren. Gewichte beeinflussen die Eigenschaftsauswahl innerhalb jedes Pools. Fuer volle Kontrolle 'Alle Eigenschaftspools verwenden' aktivieren - sonst gilt Vanillas Normal/Selten-Aufteilung (Seltenpool ~10% pro Eigenschaft). Gewicht 0 = deaktiviert." },
					{ "DescIncludeEventTraits", "Normalerweise durch Spielereignisse vergebene Eigenschaften (Heirat, Elternschaft, Kriminelle, Missionare usw.) in die Gewichtsliste aufnehmen. Nur bei aktiviertem 'Alle Eigenschaftspools verwenden'. Warnung: Kann unsinnige Zuweisungen verursachen." },
					{ "DescResetSettings", "Klicken, um alle Einstellungen auf Standard zurückzusetzen (Vanilla-Verhalten)." },
					{ "TraitWeightDesc", "Gewicht: Höher = wahrscheinlicher relativ zu anderen Eigenschaften. 0 = deaktiviert. Standard: 1.0. Bei ~85 Eigenschaften mit Gewicht 1: Gewicht 10 ~ 10%, Gewicht 50 ~ 37%, Gewicht 100 ~ 54%." },
					{ "CategoryFoundIn", "Gefunden in: {0}" },
					{ "CategoryGrantedOther", "Vergeben durch andere Mittel (Doktrinen, Rituale, Ereignisse usw.)" },
					{ "WarningModifyAll", "WARNUNG: Alle bestehenden Anhänger werden geändert!" },
					{ "WarningNecklaceLoss", "Eigenschaften von Halsketten könnten bei der Wiederherstellung verloren gehen." },
					{ "ButtonConfirm", "Bestätigen" },
					{ "ButtonCancel", "Abbrechen" },
					{ "ToggleEnabled", "Aktiviert" },
					{ "ToggleDisabled", "Deaktiviert" },
					{ "ButtonResetAll", "Alle Einstellungen zurücksetzen" },
					{ "ConfirmResetAll", "Sind Sie sicher? Alle Einstellungen werden auf Standard zurückgesetzt." },
					{ "ButtonYes", "Ja" },
					{ "ButtonNo", "Nein" },
					{ "NotifyTraitsRerolled", "Eigenschaften von <color=#FFD201>{0}</color> neu gewürfelt! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Eigenschaftsersetzung aktivieren" },
					{ "NameApplyToExisting", "Auf vorhandene Anhänger anwenden" },
					{ "NameUseUnlockedTraits", "Nur freigeschaltete Eigenschaften" },
					{ "NameUseAllTraits", "Alle Eigenschaften" },
					{ "NamePreferExclusive", "Exklusive bevorzugen" },
					{ "NamePreserveMutated", "Verrottete Anhänger bewahren" },
					{ "NameMinTraits", "Minimale Eigenschaften" },
					{ "NameMaxTraits", "Maximale Eigenschaften" },
					{ "NameRandomizeReindoc", "Zufällig bei Neuindoktrinierung" },
					{ "NameTraitReroll", "Eigenschaftsneuverteilung per Umerziehung" },
					{ "NameProtectTraitCount", "Eigenschaftsanzahl schützen" },
					{ "NameRerollableAltar", "Altar-Eigenschaften neu würfeln" },
					{ "NameAllowMultipleUnique", "Mehrere einzigartige Eigenschaften" },
					{ "NameIncludeTrait", "{0} einschließen" },
					{ "NameGuaranteeTrait", "    └ {0} garantieren" },
					{ "NameShowRemoving", "Beim Entfernen anzeigen" },
					{ "NameShowAdding", "Beim Hinzufügen anzeigen" },
					{ "NameShowReroll", "Beim Neuverteilen anzeigen" },
					{ "NameEnableWeights", "Eigenschaftsgewichtung aktivieren" },
					{ "NameIncludeEventTraits", "Event-Eigenschaften einschließen" },
					{ "NameResetSettings", "Alle Einstellungen zurücksetzen" }
				}
			},
			{
				"Spanish",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Reemplaza rasgos negativos por positivos. Por defecto solo afecta a NUEVOS seguidores. Activa 'Aplicar a seguidores existentes' para modificar los actuales." },
					{ "DescApplyToExisting", "El reemplazo de rasgos también se aplica a seguidores existentes (no solo nuevos). Desactivar restaurará los rasgos originales." },
					{ "DescUseUnlockedTraits", "Usar solo rasgos desbloqueados. Se aplica al reemplazo y selección de rasgos de nuevos seguidores." },
					{ "DescUseAllTraits", "Fusionar todos los pools de rasgos en uno, omitiendo la separación normal/raro del juego. Sin esto, el juego asigna rasgos de pools separados (pool normal por defecto, ~10% de probabilidad del pool raro por rasgo). Actívalo para control total de pesos. Los rasgos únicos requieren sus interruptores individuales." },
					{ "DescPreferExclusive", "Al reemplazar rasgos negativos, los rasgos exclusivos (como Perezoso) se reemplazan por su contraparte positiva (Industrioso) en lugar de un rasgo aleatorio." },
					{ "DescPreserveMutated", "Los seguidores Rot (Mutados) no perderán su rasgo. Los seguidores Rot son mecánicamente distintos y útiles para ciertos rituales." },
					{ "DescMinTraits", "Número mínimo de rasgos de nuevos seguidores. Vanilla: 2." },
					{ "DescMaxTraits", "Número máximo de rasgos de nuevos seguidores. Vanilla: 3. Limitado a 8 por restricciones de interfaz." },
					{ "DescRandomizeReindoc", "Al reindoctrinar a un seguidor (en el altar), aleatorizar sus rasgos usando los min/max configurados. La reindoctrinación vanilla solo cambia apariencia/nombre." },
					{ "DescTraitReroll", "Añade el comando Reeducar a seguidores normales. Relanza sus rasgos usando los min/max y pesos configurados." },
					{ "DescProtectTraitCount", "Al relanzar rasgos (reeducación o reindoctrinación), el seguidor no terminará con menos rasgos de los que tenía." },
					{ "DescRerollableAltar", "En el Altar de Exorcismo, reseleccionar un seguidor muestra resultados diferentes cada vez en lugar del mismo resultado por día." },
					{ "DescAllowMultipleUnique", "Permitir que múltiples seguidores tengan el mismo rasgo único (Inmortal, Discípulo, etc.)." },
					{ "UniqueTraitDesc", "Permitir que el rasgo {0} ({1}) aparezca en los pools de rasgos." },
					{ "GuaranteeTraitDesc", "Los nuevos seguidores siempre recibirán el rasgo {0} (ignora pesos). Solo un seguidor puede tener este rasgo." },
					{ "SourceSpecialReward", "normalmente una recompensa especial" },
					{ "SourceCrossover", "recompensa crossover" },
					{ "SourceBishopConvert", "normalmente otorgado al convertir un obispo" },
					{ "DescShowRemoving", "Mostrar notificaciones al eliminar rasgos negativos." },
					{ "DescShowAdding", "Mostrar notificaciones al añadir rasgos positivos." },
					{ "DescShowReroll", "Mostrar notificación cuando los rasgos de un seguidor se relanzan por reeducación o reindoctrinación." },
					{ "DescEnableWeights", "Activar selección aleatoria ponderada para nuevos seguidores. Los pesos afectan la selección dentro de cada pool. Para control total, activa 'Usar todos los pools' -si no, se aplica la separación normal/raro del juego (pool raro ~10% por rasgo). Peso 0 = desactivado." },
					{ "DescIncludeEventTraits", "Incluir rasgos normalmente otorgados por eventos de juego (matrimonio, paternidad, criminal, misionero, etc.) en la lista de pesos. Solo aplica con 'Usar todos los pools de rasgos'. Advertencia: puede causar asignaciones absurdas." },
					{ "DescResetSettings", "Clic para restablecer todos los ajustes a los valores predeterminados (comportamiento vanilla)." },
					{ "TraitWeightDesc", "Peso: Mayor = más probable respecto a otros rasgos. 0 = desactivado. Predeterminado: 1.0. Con ~85 rasgos a peso 1: peso 10 ~ 10%, peso 50 ~ 37%, peso 100 ~ 54%." },
					{ "CategoryFoundIn", "Encontrado en: {0}" },
					{ "CategoryGrantedOther", "Otorgado por otros medios (doctrinas, rituales, eventos, etc.)" },
					{ "WarningModifyAll", "¡ADVERTENCIA: Todos los seguidores existentes serán modificados!" },
					{ "WarningNecklaceLoss", "Los rasgos de collares podrían perderse al restaurar." },
					{ "ButtonConfirm", "Confirmar" },
					{ "ButtonCancel", "Cancelar" },
					{ "ToggleEnabled", "Activado" },
					{ "ToggleDisabled", "Desactivado" },
					{ "ButtonResetAll", "Restablecer todos los ajustes" },
					{ "ConfirmResetAll", "¿Estás seguro? Todos los ajustes se restablecerán a los valores predeterminados." },
					{ "ButtonYes", "Sí" },
					{ "ButtonNo", "No" },
					{ "NotifyTraitsRerolled", "¡Rasgos de <color=#FFD201>{0}</color> relanzados! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Activar reemplazo de rasgos" },
					{ "NameApplyToExisting", "Aplicar a seguidores existentes" },
					{ "NameUseUnlockedTraits", "Solo rasgos desbloqueados" },
					{ "NameUseAllTraits", "Todos los rasgos" },
					{ "NamePreferExclusive", "Preferir exclusivos" },
					{ "NamePreserveMutated", "Preservar seguidores podridos" },
					{ "NameMinTraits", "Rasgos mínimos" },
					{ "NameMaxTraits", "Rasgos máximos" },
					{ "NameRandomizeReindoc", "Aleatorizar al reindoctrinar" },
					{ "NameTraitReroll", "Relanzar rasgos por reeducación" },
					{ "NameProtectTraitCount", "Proteger cantidad de rasgos" },
					{ "NameRerollableAltar", "Rasgos de altar relanzables" },
					{ "NameAllowMultipleUnique", "Varios rasgos únicos" },
					{ "NameIncludeTrait", "Incluir {0}" },
					{ "NameGuaranteeTrait", "    └ Garantizar {0}" },
					{ "NameShowRemoving", "Mostrar al eliminar" },
					{ "NameShowAdding", "Mostrar al agregar" },
					{ "NameShowReroll", "Mostrar al relanzar" },
					{ "NameEnableWeights", "Activar pesos de rasgos" },
					{ "NameIncludeEventTraits", "Incluir rasgos de eventos" },
					{ "NameResetSettings", "Restablecer toda la configuración" }
				}
			},
			{
				"Portuguese (Brazil)",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "Substitui traços negativos por positivos. Por padrão, afeta apenas NOVOS seguidores. Ative 'Aplicar a seguidores existentes' para modificar os atuais." },
					{ "DescApplyToExisting", "A substituição de traços também se aplica a seguidores existentes (não apenas novos). Desativar restaurará os traços originais." },
					{ "DescUseUnlockedTraits", "Usar apenas traços desbloqueados. Aplica-se à substituição e seleção de traços de novos seguidores." },
					{ "DescUseAllTraits", "Mesclar todos os pools de traços em um, ignorando a divisão normal/raro do jogo. Sem isso, o jogo atribui traços de pools separados (pool normal por padrão, ~10% de chance do pool raro por traço). Ative para controle total de pesos. Traços únicos requerem seus interruptores individuais." },
					{ "DescPreferExclusive", "Ao substituir traços negativos, traços exclusivos (como Preguiçoso) são substituídos por sua contraparte positiva (Industrioso) em vez de um traço aleatório." },
					{ "DescPreserveMutated", "Seguidores Rot (Mutados) não perderão seu traço. Seguidores Rot são mecanicamente distintos e úteis para certos rituais." },
					{ "DescMinTraits", "Número mínimo de traços de novos seguidores. Vanilla: 2." },
					{ "DescMaxTraits", "Número máximo de traços de novos seguidores. Vanilla: 3. Limitado a 8 por restrições de interface." },
					{ "DescRandomizeReindoc", "Ao reindoutrinar um seguidor (no altar), aleatorizar seus traços usando os min/max configurados. A reindoutrinação vanilla só muda aparência/nome." },
					{ "DescTraitReroll", "Adiciona o comando Reeducar a seguidores normais. Rerrola seus traços usando os min/max e pesos configurados." },
					{ "DescProtectTraitCount", "Ao rerrolar traços (reeducação ou reindoutrinação), o seguidor não ficará com menos traços do que tinha." },
					{ "DescRerollableAltar", "No Altar de Exorcismo, resselecionar um seguidor mostra resultados diferentes a cada vez em vez do mesmo resultado por dia." },
					{ "DescAllowMultipleUnique", "Permitir que múltiplos seguidores tenham o mesmo traço único (Imortal, Discípulo, etc.)." },
					{ "UniqueTraitDesc", "Permitir que o traço {0} ({1}) apareça nos pools de traços." },
					{ "GuaranteeTraitDesc", "Novos seguidores sempre receberão o traço {0} (ignora pesos). Apenas um seguidor pode ter este traço." },
					{ "SourceSpecialReward", "normalmente uma recompensa especial" },
					{ "SourceCrossover", "recompensa crossover" },
					{ "SourceBishopConvert", "normalmente concedido ao converter um bispo" },
					{ "DescShowRemoving", "Mostrar notificações ao remover traços negativos." },
					{ "DescShowAdding", "Mostrar notificações ao adicionar traços positivos." },
					{ "DescShowReroll", "Mostrar notificação quando os traços de um seguidor são rerrolados por reeducação ou reindoutrinação." },
					{ "DescEnableWeights", "Ativar seleção aleatória ponderada para novos seguidores. Os pesos afetam a seleção dentro de cada pool. Para controle total, ative 'Usar todos os pools' -senão a divisão normal/raro do jogo se aplica (pool raro ~10% por traço). Peso 0 = desativado." },
					{ "DescIncludeEventTraits", "Incluir traços normalmente concedidos por eventos de jogo (casamento, paternidade, criminal, missionário, etc.) na lista de pesos. Só se aplica com 'Usar todos os pools de traços'. Aviso: pode causar atribuições absurdas." },
					{ "DescResetSettings", "Clique para redefinir todas as configurações para o padrão (comportamento vanilla)." },
					{ "TraitWeightDesc", "Peso: Maior = mais provável em relação a outros traços. 0 = desativado. Padrão: 1.0. Com ~85 traços a peso 1: peso 10 ~ 10%, peso 50 ~ 37%, peso 100 ~ 54%." },
					{ "CategoryFoundIn", "Encontrado em: {0}" },
					{ "CategoryGrantedOther", "Concedido por outros meios (doutrinas, rituais, eventos, etc.)" },
					{ "WarningModifyAll", "AVISO: Todos os seguidores existentes serão modificados!" },
					{ "WarningNecklaceLoss", "Traços de colares podem ser perdidos ao restaurar." },
					{ "ButtonConfirm", "Confirmar" },
					{ "ButtonCancel", "Cancelar" },
					{ "ToggleEnabled", "Ativado" },
					{ "ToggleDisabled", "Desativado" },
					{ "ButtonResetAll", "Redefinir todas as configurações" },
					{ "ConfirmResetAll", "Tem certeza? Todas as configurações serão redefinidas para o padrão." },
					{ "ButtonYes", "Sim" },
					{ "ButtonNo", "Não" },
					{ "NotifyTraitsRerolled", "Traços de <color=#FFD201>{0}</color> rerrolados! ({1} → {2})" },
					{ "NameEnableTraitReplacement", "Ativar substituição de traços" },
					{ "NameApplyToExisting", "Aplicar a seguidores existentes" },
					{ "NameUseUnlockedTraits", "Apenas traços desbloqueados" },
					{ "NameUseAllTraits", "Todos os traços" },
					{ "NamePreferExclusive", "Preferir exclusivos" },
					{ "NamePreserveMutated", "Preservar seguidores podres" },
					{ "NameMinTraits", "Traços mínimos" },
					{ "NameMaxTraits", "Traços máximos" },
					{ "NameRandomizeReindoc", "Aleatorizar ao redoutrinar" },
					{ "NameTraitReroll", "Rerolar traços via reeducação" },
					{ "NameProtectTraitCount", "Proteger quantidade de traços" },
					{ "NameRerollableAltar", "Traços de altar rerroláveis" },
					{ "NameAllowMultipleUnique", "Vários traços únicos" },
					{ "NameIncludeTrait", "Incluir {0}" },
					{ "NameGuaranteeTrait", "    └ Garantir {0}" },
					{ "NameShowRemoving", "Mostrar ao remover" },
					{ "NameShowAdding", "Mostrar ao adicionar" },
					{ "NameShowReroll", "Mostrar ao rerolar" },
					{ "NameEnableWeights", "Ativar pesos de traços" },
					{ "NameIncludeEventTraits", "Incluir traços de eventos" },
					{ "NameResetSettings", "Redefinir todas as configurações" }
				}
			},
			{
				"Chinese (Simplified)",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "将负面特质替换为正面特质。默认仅影响新追随者。启用'应用到现有追随者'以修改当前追随者。" },
					{ "DescApplyToExisting", "启用后,特质替换也适用于现有追随者(不仅是新追随者)。禁用将恢复原始特质。" },
					{ "DescUseUnlockedTraits", "仅使用已解锁的特质。适用于特质替换和新追随者特质选择。" },
					{ "DescUseAllTraits", "将所有特质池合并为一个,绕过原版的普通/稀有分割。没有此项时,游戏从不同池分配特质(默认普通池,每个特质约10%概率来自稀有池)。启用此项可完全控制权重。唯一特质需要单独开关。" },
					{ "DescPreferExclusive", "替换负面特质时,排他特质(如懒惰)会被替换为其正面对应特质(勤劳)而非随机特质。" },
					{ "DescPreserveMutated", "启用后,腐烂(变异)追随者不会失去其特质。腐烂追随者在机制上独特,对某些仪式有用。" },
					{ "DescMinTraits", "新追随者的最少特质数。原版为2。" },
					{ "DescMaxTraits", "新追随者的最多特质数。原版为3。受UI限制最多为8。" },
					{ "DescRandomizeReindoc", "在祭坛重新教化追随者时,使用配置的最小/最大值随机化其特质。原版重新教化只改变外观/名字。" },
					{ "DescTraitReroll", "为普通追随者添加再教育命令。使用后将根据配置的最小/最大值和权重重新掷骰特质。" },
					{ "DescProtectTraitCount", "重新掷骰特质时(通过再教育或重新教化),确保追随者的特质数不会少于初始数量。" },
					{ "DescRerollableAltar", "使用驱魔祭坛时,重新选择追随者会每次显示不同结果,而非每天固定结果。" },
					{ "DescAllowMultipleUnique", "允许多个追随者拥有相同的唯一特质(不朽、门徒等)。通常每个唯一特质只能有一个追随者拥有。" },
					{ "UniqueTraitDesc", "允许{0}特质({1})出现在特质池中。" },
					{ "GuaranteeTraitDesc", "新追随者将始终获得{0}特质(忽略权重)。只有一个追随者可以拥有此特质。" },
					{ "SourceSpecialReward", "通常为特殊奖励" },
					{ "SourceCrossover", "联动奖励" },
					{ "SourceBishopConvert", "通常在转化主教时获得" },
					{ "DescShowRemoving", "移除负面特质时显示通知。" },
					{ "DescShowAdding", "添加正面特质时显示通知。" },
					{ "DescShowReroll", "通过再教育或重新教化重新掷骰追随者特质时显示通知。" },
					{ "DescEnableWeights", "为新追随者启用加权随机选择。权重影响每个池内的特质选择。要完全控制所有特质,请启用'使用所有特质池' - 否则原版的普通/稀有池分割仍然适用(稀有池每个特质约10%概率)。将权重设为0可禁用特质。" },
					{ "DescIncludeEventTraits", "将通常通过游戏事件(婚姻、育儿、犯罪、传教士等)授予的特质纳入权重列表。仅在启用'使用所有特质池'时适用。警告:可能导致不合理的分配。" },
					{ "DescResetSettings", "点击将所有设置重置为默认值(原版行为)。" },
					{ "TraitWeightDesc", "权重:越高 = 相对其他特质越可能出现。0 = 禁用。默认1.0。约85个特质权重为1时:权重10 ~ 10%,权重50 ~ 37%,权重100 ~ 54%。" },
					{ "CategoryFoundIn", "所属: {0}" },
					{ "CategoryGrantedOther", "通过其他方式获得(教义、仪式、事件等)" },
					{ "WarningModifyAll", "警告:所有现有追随者都将被修改!" },
					{ "WarningNecklaceLoss", "恢复时可能丢失项链赋予的特质。" },
					{ "ButtonConfirm", "确认" },
					{ "ButtonCancel", "取消" },
					{ "ToggleEnabled", "已启用" },
					{ "ToggleDisabled", "已禁用" },
					{ "ButtonResetAll", "重置所有设置" },
					{ "ConfirmResetAll", "确定吗?所有设置将重置为默认值。" },
					{ "ButtonYes", "是" },
					{ "ButtonNo", "否" },
					{ "NotifyTraitsRerolled", "<color=#FFD201>{0}</color>的特质已重新掷骰!({1} → {2})" },
					{ "NameEnableTraitReplacement", "启用特质替换" },
					{ "NameApplyToExisting", "应用于现有信徒" },
					{ "NameUseUnlockedTraits", "仅使用已解锁特质" },
					{ "NameUseAllTraits", "使用所有特质" },
					{ "NamePreferExclusive", "优先专属特质" },
					{ "NamePreserveMutated", "保留腐化信徒" },
					{ "NameMinTraits", "最少特质数" },
					{ "NameMaxTraits", "最多特质数" },
					{ "NameRandomizeReindoc", "重新教化时随机" },
					{ "NameTraitReroll", "通过再教育重掷特质" },
					{ "NameProtectTraitCount", "保护特质数量" },
					{ "NameRerollableAltar", "可重掷祭坛特质" },
					{ "NameAllowMultipleUnique", "允许多个独特特质" },
					{ "NameIncludeTrait", "包含 {0}" },
					{ "NameGuaranteeTrait", "    └ 保证 {0}" },
					{ "NameShowRemoving", "移除时显示" },
					{ "NameShowAdding", "添加时显示" },
					{ "NameShowReroll", "重掷时显示" },
					{ "NameEnableWeights", "启用特质权重" },
					{ "NameIncludeEventTraits", "包含事件特质" },
					{ "NameResetSettings", "重置所有设置" }
				}
			},
			{
				"Chinese (Traditional)",
				new Dictionary<string, string>
				{
					{ "DescNoNegativeTraits", "將負面特質替換為正面特質。預設僅影響新追隨者。啟用「套用到現有追隨者」以修改當前追隨者。" },
					{ "DescApplyToExisting", "啟用後,特質替換也適用於現有追隨者(不僅是新追隨者)。停用將恢復原始特質。" },
					{ "DescUseUnlockedTraits", "僅使用已解鎖的特質。適用於特質替換和新追隨者特質選擇。" },
					{ "DescUseAllTraits", "將所有特質池合併為一個,繞過原版的普通/稀有分割。沒有此項時,遊戲從不同池分配特質(預設普通池,每個特質約10%機率來自稀有池)。啟用此項可完全控制權重。唯一特質需要單獨開關。" },
					{ "DescPreferExclusive", "替換負面特質時,排他特質(如懶惰)會被替換為其正面對應特質(勤勞)而非隨機特質。" },
					{ "DescPreserveMutated", "啟用後,腐爛(變異)追隨者不會失去其特質。腐爛追隨者在機制上獨特,對某些儀式有用。" },
					{ "DescMinTraits", "新追隨者的最少特質數。原版為2。" },
					{ "DescMaxTraits", "新追隨者的最多特質數。原版為3。受UI限制最多為8。" },
					{ "DescRandomizeReindoc", "在祭壇重新教化追隨者時,使用設定的最小/最大值隨機化其特質。原版重新教化只改變外觀/名字。" },
					{ "DescTraitReroll", "為普通追隨者新增再教育命令。使用後將根據設定的最小/最大值和權重重新擲骰特質。" },
					{ "DescProtectTraitCount", "重新擲骰特質時(透過再教育或重新教化),確保追隨者的特質數不會少於初始數量。" },
					{ "DescRerollableAltar", "使用驅魔祭壇時,重新選擇追隨者會每次顯示不同結果,而非每天固定結果。" },
					{ "DescAllowMultipleUnique", "允許多個追隨者擁有相同的唯一特質(不朽、門徒等)。通常每個唯一特質只能有一個追隨者擁有。" },
					{ "UniqueTraitDesc", "允許{0}特質({1})出現在特質池中。" },
					{ "GuaranteeTraitDesc", "新追隨者將始終獲得{0}特質(忽略權重)。只有一個追隨者可以擁有此特質。" },
					{ "SourceSpecialReward", "通常為特殊獎勵" },
					{ "SourceCrossover", "聯動獎勵" },
					{ "SourceBishopConvert", "通常在轉化主教時獲得" },
					{ "DescShowRemoving", "移除負面特質時顯示通知。" },
					{ "DescShowAdding", "新增正面特質時顯示通知。" },
					{ "DescShowReroll", "透過再教育或重新教化重新擲骰追隨者特質時顯示通知。" },
					{ "DescEnableWeights", "為新追隨者啟用加權隨機選擇。權重影響每個池內的特質選擇。要完全控制所有特質,請啟用「使用所有特質池」 -否則原版的普通/稀有池分割仍然適用(稀有池每個特質約10%機率)。將權重設為0可停用特質。" },
					{ "DescIncludeEventTraits", "將通常透過遊戲事件(婚姻、育兒、犯罪、傳教士等)授予的特質納入權重列表。僅在啟用「使用所有特質池」時適用。警告:可能導致不合理的分配。" },
					{ "DescResetSettings", "點擊將所有設定重置為預設值(原版行為)。" },
					{ "TraitWeightDesc", "權重:越高 = 相對其他特質越可能出現。0 = 停用。預設1.0。約85個特質權重為1時:權重10 ~ 10%,權重50 ~ 37%,權重100 ~ 54%。" },
					{ "CategoryFoundIn", "所屬: {0}" },
					{ "CategoryGrantedOther", "透過其他方式獲得(教義、儀式、事件等)" },
					{ "WarningModifyAll", "警告:所有現有追隨者都將被修改!" },
					{ "WarningNecklaceLoss", "恢復時可能遺失項鏈賦予的特質。" },
					{ "ButtonConfirm", "確認" },
					{ "ButtonCancel", "取消" },
					{ "ToggleEnabled", "已啟用" },
					{ "ToggleDisabled", "已停用" },
					{ "ButtonResetAll", "重置所有設定" },
					{ "ConfirmResetAll", "確定嗎?所有設定將重置為預設值。" },
					{ "ButtonYes", "是" },
					{ "ButtonNo", "否" },
					{ "NotifyTraitsRerolled", "<color=#FFD201>{0}</color>的特質已重新擲骰!({1} → {2})" },
					{ "NameEnableTraitReplacement", "啟用特質替換" },
					{ "NameApplyToExisting", "套用至現有信徒" },
					{ "NameUseUnlockedTraits", "僅使用已解鎖特質" },
					{ "NameUseAllTraits", "使用所有特質" },
					{ "NamePreferExclusive", "優先專屬特質" },
					{ "NamePreserveMutated", "保留腐化信徒" },
					{ "NameMinTraits", "最少特質數" },
					{ "NameMaxTraits", "最多特質數" },
					{ "NameRandomizeReindoc", "重新教化時隨機" },
					{ "NameTraitReroll", "透過再教育重擲特質" },
					{ "NameProtectTraitCount", "保護特質數量" },
					{ "NameRerollableAltar", "可重擲祭壇特質" },
					{ "NameAllowMu