using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AzNean.SotfCommon;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using EnemyAiToggle.Logic;
using EnemyAiToggle.Patches;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Sons.Ai.Vail;
using Sons.Gameplay;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("EnemyAiToggle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.25.0")]
[assembly: AssemblyInformationalVersion("0.1.25+04f969363884d50e104bc4139452770beb67c5b6")]
[assembly: AssemblyProduct("EnemyAiToggle")]
[assembly: AssemblyTitle("EnemyAiToggle")]
[assembly: AssemblyVersion("0.1.25.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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;
}
}
}
internal static class SettingMove
{
internal static void Move(ConfigFile config, string oldSection, string oldKey, ConfigEntryBase to)
{
bool saveOnConfigSet = config.SaveOnConfigSet;
config.SaveOnConfigSet = false;
try
{
ConfigEntry<string> val = config.Bind<string>(oldSection, oldKey, "\u0001", "Old place of a moved setting.");
bool num = val.Value != "\u0001";
if (num)
{
to.SetSerializedValue(((ConfigEntryBase)val).GetSerializedValue());
}
config.Remove(((ConfigEntryBase)val).Definition);
if (num)
{
config.Save();
}
}
finally
{
config.SaveOnConfigSet = saveOnConfigSet;
}
}
}
namespace AzNean.SotfCommon
{
internal static class ModLog
{
private static ManualLogSource _log;
private static ConfigEntry<bool> _full;
private static readonly HashSet<string> _once = new HashSet<string>();
private static readonly Dictionary<(int, string), int> _state = new Dictionary<(int, string), int>();
internal static bool Full => _full.Value;
internal static void Init(ManualLogSource log, ConfigEntry<bool> full)
{
_log = log;
_full = full;
}
internal static void Trace(string message)
{
if (_full.Value)
{
_log.LogInfo((object)message);
}
}
internal static bool Changed(int id, string what, int state)
{
if (!_full.Value || (_state.TryGetValue((id, what), out var value) && value == state))
{
return false;
}
_state[(id, what)] = state;
return true;
}
internal static void Once(string key, string message, LogLevel level = (LogLevel)16)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
if (_once.Add(key))
{
_log.Log(level, (object)message);
}
}
}
}
namespace EnemyAiToggle
{
[BepInPlugin("aznan.sotf.enemyaitoggle", "EnemyAiToggle", "0.1.25")]
public class Plugin : BasePlugin
{
internal const string Version = "0.1.25";
internal static ManualLogSource Logger;
internal static ConfigEntry<bool> FullLogging;
internal static ConfigEntry<bool> EnemiesFrozen;
private static readonly Dictionary<string, ConfigEntry<bool>> ChosenTypes = new Dictionary<string, ConfigEntry<bool>>();
internal static ConfigEntry<KeyCode> ToggleKey;
internal static ConfigEntry<float> MessageSeconds;
internal static ConfigEntry<string> MessageEnabled;
internal static ConfigEntry<string> MessageDisabled;
internal static ConfigEntry<string> MessageGuest;
internal static ConfigEntry<float> MessageTop;
internal static ConfigEntry<float> MessageMaxWidth;
internal static ConfigEntry<bool> StopAnimations;
internal static ConfigEntry<bool> FrozenAllowSleep;
internal static bool IsTypeChosen(string typeId)
{
if (ChosenTypes.TryGetValue(typeId, out var value))
{
return value.Value;
}
return false;
}
public override void Load()
{
//IL_0363: Unknown result type (might be due to invalid IL or missing references)
//IL_0377: Unknown result type (might be due to invalid IL or missing references)
//IL_037c: Unknown result type (might be due to invalid IL or missing references)
//IL_0382: Expected O, but got Unknown
//IL_0382: Unknown result type (might be due to invalid IL or missing references)
//IL_039a: Unknown result type (might be due to invalid IL or missing references)
//IL_03a1: Expected O, but got Unknown
Logger = ((BasePlugin)this).Log;
EnemyFilter.SelfCheck();
Texts.SelfCheck();
EnemiesFrozen = ((BasePlugin)this).Config.Bind<bool>("General", "EnemiesFrozen", false, "True = the types ticked in [Frozen types] stand still.");
ToggleKey = ((BasePlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)289, "Key that toggles enemy AI.");
StopAnimations = ((BasePlugin)this).Config.Bind<bool>("General", "StopAnimations", true, "True = frozen creatures also stop animating (statue). False = only their AI stops.");
FrozenAllowSleep = ((BasePlugin)this).Config.Bind<bool>("General", "FrozenAllowSleep", true, "True = frozen creatures near you no longer make the game say it is not safe to sleep. False = the game counts them like any nearby enemy. Default: true.");
foreach (string item in Enum.GetNames(typeof(VailActorTypeId)).Where(EnemyFilter.IsListed))
{
string text = EnemyFilter.ShownName(item);
string text2 = ((text == item) ? item : (text + " (" + item + " in the game files)"));
ConfigEntry<bool> val = ((BasePlugin)this).Config.Bind<bool>("Frozen types", item, EnemyFilter.FrozenByDefault(item), "Freeze " + text2 + " when enemy AI is OFF.");
val.SettingChanged += delegate
{
EnemyFreezer.ApplyToAll();
};
ChosenTypes[item] = val;
}
MessageEnabled = ((BasePlugin)this).Config.Bind<string>("Texts", "MessageEnabled", "", "Message shown when enemies move again. Empty = automatic, in the game's language.");
MessageDisabled = ((BasePlugin)this).Config.Bind<string>("Texts", "MessageDisabled", "", "Message shown when the ticked types are frozen; {0} = their list. Empty = automatic, in the game's language.");
MessageGuest = ((BasePlugin)this).Config.Bind<string>("Texts", "MessageGuest", "", "Message shown when a multiplayer guest presses the key (the host runs enemy AI, so only the host can freeze enemies). Empty = automatic, in the game's language.");
MessageSeconds = ((BasePlugin)this).Config.Bind<float>("Texts", "MessageSeconds", 4f, "How long the on-screen message stays visible, in seconds. 0 = no message. Advised: 0 to 30.");
MessageTop = ((BasePlugin)this).Config.Bind<float>("Texts", "MessageTop", 40f, "Distance of the message from the top of the screen, in pixels. Advised: 0 to 2000.");
MessageMaxWidth = ((BasePlugin)this).Config.Bind<float>("Texts", "MessageMaxWidth", 900f, "Widest the message box gets, in pixels; longer text wraps onto more lines. Advised: 100 to 4000.");
FullLogging = ((BasePlugin)this).Config.Bind<bool>("Debug", "FullLogging", false, "True = the BepInEx log gets every step useful to diagnose a problem (decisions, values read, object aimed at, failures with their cause). False = only loading, version and errors.");
ModLog.Init(Logger, FullLogging);
ConfigEntryBase[] array = (ConfigEntryBase[])(object)new ConfigEntryBase[5]
{
(ConfigEntryBase)MessageEnabled,
(ConfigEntryBase)MessageDisabled,
(ConfigEntryBase)MessageSeconds,
(ConfigEntryBase)MessageTop,
(ConfigEntryBase)MessageMaxWidth
};
foreach (ConfigEntryBase val2 in array)
{
SettingMove.Move(((BasePlugin)this).Config, "Message", val2.Definition.Key, val2);
}
string path = Path.Combine(Paths.ConfigPath, "aznan.sotf.enemyaitoggle.seconds-0.1.21.done");
if (!File.Exists(path))
{
if (MessageSeconds.Value == 2f)
{
MessageSeconds.Value = 4f;
Logger.LogInfo((object)"Texts/MessageSeconds was the old default 2 s: set to the new default 4 s (once only).");
}
File.WriteAllText(path, "MessageSeconds default 2 -> 4 migrated once (see NOTES).");
}
EnemiesFrozen.SettingChanged += delegate
{
EnemyFreezer.ApplyToAll();
};
new Harmony("aznan.sotf.enemyaitoggle").PatchAll();
ClassInjector.RegisterTypeInIl2Cpp<KeyWatcher>();
GameObject val3 = new GameObject("EnemyAiToggle");
Object.DontDestroyOnLoad((Object)val3);
((Object)val3).hideFlags = (HideFlags)61;
val3.AddComponent<KeyWatcher>();
ManualLogSource logger = Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("EnemyAiToggle ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("0.1.25");
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" loaded");
}
logger.LogInfo(val4);
}
internal static string StateMessage()
{
Locale selectedLocale = LocalizationSettings.SelectedLocale;
string locale = ((selectedLocale != null) ? selectedLocale.Identifier.Code : null);
if (BoltNetwork.isClient)
{
return Pick(MessageGuest, "Guest");
}
if (!EnemiesFrozen.Value)
{
return Pick(MessageEnabled, "Enabled");
}
List<string> frozenTypes = (from t in ChosenTypes
where t.Value.Value
select EnemyFilter.ShownName(t.Key)).ToList();
return Texts.WithTypes(Pick(MessageDisabled, "Disabled"), frozenTypes, Texts.Get(locale, "NoType"));
string Pick(ConfigEntry<string> setting, string key)
{
if (!string.IsNullOrEmpty(setting.Value))
{
return setting.Value;
}
return Texts.Get(locale, key);
}
}
}
public class KeyWatcher : MonoBehaviour
{
private float _messageUntil;
private string _message;
public KeyWatcher(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
//IL_0005: 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
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(Plugin.ToggleKey.Value))
{
if (!BoltNetwork.isClient)
{
Plugin.EnemiesFrozen.Value = !Plugin.EnemiesFrozen.Value;
}
ManualLogSource logger = Plugin.Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 3, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<KeyCode>(Plugin.ToggleKey.Value);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pressed: enemy AI ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Plugin.EnemiesFrozen.Value ? "OFF" : "ON");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(BoltNetwork.isClient ? " (multiplayer guest: the host's game runs the AI, nothing changed here)" : "");
}
logger.LogInfo(val);
_message = Plugin.StateMessage();
_messageUntil = Time.unscaledTime + Plugin.MessageSeconds.Value;
}
}
private void OnGUI()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if (!(Time.unscaledTime > _messageUntil) && !string.IsNullOrEmpty(_message))
{
GUIContent val = new GUIContent(_message);
GUIStyle val2 = new GUIStyle(GUI.skin.box)
{
wordWrap = true
};
float num = Mathf.Min(val2.CalcSize(val).x, Plugin.MessageMaxWidth.Value);
float num2 = val2.CalcHeight(val, num);
GUI.Box(new Rect(((float)Screen.width - num) / 2f, Plugin.MessageTop.Value, num, num2), val, val2);
}
}
}
}
namespace EnemyAiToggle.Patches
{
[HarmonyPatch(typeof(VailActor), "Start")]
public static class EnemyFreezer
{
private static readonly Dictionary<IntPtr, (VailActor actor, bool animatorStopped)> FrozenByUs = new Dictionary<IntPtr, (VailActor, bool)>();
internal static int FrozenCount => FrozenByUs.Count;
internal static bool IsFrozen(WorldSimActor worldActor)
{
foreach (var value in FrozenByUs.Values)
{
if ((Object)(object)value.actor != (Object)null && !((Behaviour)value.actor).enabled && value.actor._worldSimUniqueId == worldActor._uniqueId)
{
return true;
}
}
return false;
}
public static void Postfix(VailActor __instance)
{
FrozenByUs.Remove(((Il2CppObjectBase)__instance).Pointer);
Apply(__instance);
}
public static void ApplyToAll()
{
int num = 0;
foreach (VailActor item in Object.FindObjectsOfType<VailActor>(true))
{
Apply(item);
num++;
}
foreach (IntPtr item2 in (from e in FrozenByUs
where (Object)(object)e.Value.actor == (Object)null
select e.Key).ToList())
{
FrozenByUs.Remove(item2);
}
ModLog.Trace($"Enemy AI {(Plugin.EnemiesFrozen.Value ? "OFF" : "ON")}: {num} creature(s) checked, {FrozenByUs.Count} frozen by this mod, animations {(Plugin.StopAnimations.Value ? "stopped" : "kept")}");
}
private static void Apply(VailActor actor)
{
//IL_0062: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
if (BoltNetwork.isClient)
{
if (ModLog.Changed(0, "guest", Plugin.EnemiesFrozen.Value ? 1 : 0))
{
ModLog.Trace($"Multiplayer guest: creatures left to the host's AI (EnemiesFrozen {Plugin.EnemiesFrozen.Value} here changes nothing).");
}
return;
}
string text = ((object)actor.TypeId/*cast due to .constrained prefix*/).ToString();
bool flag = Plugin.EnemiesFrozen.Value && Plugin.IsTypeChosen(text);
(VailActor, bool) value;
bool flag2 = FrozenByUs.TryGetValue(((Il2CppObjectBase)actor).Pointer, out value);
bool flag3 = value.Item2;
if (flag == flag2)
{
return;
}
if (flag && !((Behaviour)actor).enabled)
{
if (ModLog.Changed(((Object)actor).GetInstanceID(), "gameoff", 1))
{
ModLog.Trace($"{((Object)actor).name} ({actor.ClassId}/{text}) not frozen: the game switched its AI off itself.");
}
return;
}
((Behaviour)actor).enabled = !flag;
Animator componentInChildren = ((Component)actor).GetComponentInChildren<Animator>(true);
if (flag)
{
flag3 = Plugin.StopAnimations.Value && (Object)(object)componentInChildren != (Object)null && ((Behaviour)componentInChildren).enabled;
if (flag3)
{
((Behaviour)componentInChildren).enabled = false;
}
FrozenByUs[((Il2CppObjectBase)actor).Pointer] = (actor, flag3);
}
else
{
if (flag3 && (Object)(object)componentInChildren != (Object)null)
{
((Behaviour)componentInChildren).enabled = true;
}
FrozenByUs.Remove(((Il2CppObjectBase)actor).Pointer);
}
ModLog.Trace($"{((Object)actor).name} ({actor.ClassId}/{text}) frozen={flag}, animator {(((Object)(object)componentInChildren == (Object)null) ? "not found" : ((!flag3) ? "untouched" : (flag ? "stopped" : "restarted")))}");
}
}
[HarmonyPatch(typeof(VailWorldSimulation), "SleepCheckEnemies")]
internal static class SleepCheck
{
internal static bool Ran;
private static void Postfix(ref List<WorldSimActor> nearActors, ref int __result)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Expected O, but got Unknown
if (nearActors == null)
{
ModLog.Trace("Sleep check: the game gave no enemy list, nothing left out.");
return;
}
int count = nearActors.Count;
int num = 0;
if (Plugin.FrozenAllowSleep.Value)
{
for (int num2 = nearActors.Count - 1; num2 >= 0; num2--)
{
if (nearActors[num2] != null && EnemyFreezer.IsFrozen(nearActors[num2]))
{
nearActors.RemoveAt(num2);
num++;
}
}
}
__result = nearActors.Count;
Ran = true;
ManualLogSource logger = Plugin.Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(88, 4, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sleep check: the game counted ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" enemy(ies) near you, ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" frozen by this mod left out");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Plugin.FrozenAllowSleep.Value ? "" : " (FrozenAllowSleep off)");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__result);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" kept.");
}
logger.LogInfo(val);
}
}
[HarmonyPatch(typeof(SleepingManager), "InterruptSleep")]
internal static class SleepInterrupted
{
private static void Prefix(int __0, string __1)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
ManualLogSource logger = Plugin.Logger;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Sleep interrupted by the game after ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__0);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" h: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(__1);
}
logger.LogInfo(val);
if (!SleepCheck.Ran && Plugin.FrozenAllowSleep.Value && EnemyFreezer.FrozenCount > 0)
{
ManualLogSource logger2 = Plugin.Logger;
BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(115, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Sleep refused without this mod's sleep check while ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(EnemyFreezer.FrozenCount);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" creature(s) are frozen: they may have been counted as a threat.");
}
logger2.LogWarning(val2);
}
SleepCheck.Ran = false;
}
}
}
namespace EnemyAiToggle.Logic
{
public static class EnemyFilter
{
private static readonly string[] NotFrozenByDefault = new string[25]
{
"None", "Robby", "Virginia", "Timmy", "PlayerRobby", "Helicopter", "Slug_Deprecated", "SpongeTest", "Rabbit", "Squirrel",
"Turtle", "Shark", "Seagull", "Eagle", "Duck", "Moose", "Salmon", "Bat", "Deer", "Bluebird",
"Hummingbird", "KillerWhale", "LandTurtle", "Raccoon", "Skunk"
};
private static readonly Dictionary<string, string> KnownAs = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { ["Robby"] = "Kelvin" };
public static bool IsListed(string typeId)
{
return !string.Equals(typeId, "None", StringComparison.OrdinalIgnoreCase);
}
public static string ShownName(string typeId)
{
if (!KnownAs.TryGetValue(typeId, out var value))
{
return typeId;
}
return value;
}
public static bool FrozenByDefault(string typeId)
{
return !NotFrozenByDefault.Contains<string>(typeId, StringComparer.OrdinalIgnoreCase);
}
public static void SelfCheck()
{
if (FrozenByDefault("Robby") || FrozenByDefault("Virginia") || !FrozenByDefault("Billy") || !FrozenByDefault("Fingers"))
{
throw new InvalidOperationException("EnemyFilter defaults are wrong.");
}
if (IsListed("None") || !IsListed("Billy") || ShownName("Robby") != "Kelvin" || ShownName("Billy") != "Billy")
{
throw new InvalidOperationException("EnemyFilter names are wrong.");
}
}
}
public static class Texts
{
public const string Disabled = "Disabled";
public const string Enabled = "Enabled";
public const string NoType = "NoType";
public const string Guest = "Guest";
private static readonly Dictionary<string, Dictionary<string, string>> ByLanguage = new Dictionary<string, Dictionary<string, string>>
{
["en"] = new Dictionary<string, string>
{
["Disabled"] = "Enemy AI disabled for: {0}",
["Enabled"] = "Enemy AI enabled: every creature moves",
["NoType"] = "no type ticked",
["Guest"] = "Enemy AI runs on the host: only the host can freeze enemies"
},
["fr"] = new Dictionary<string, string>
{
["Disabled"] = "IA ennemie désactivée pour : {0}",
["Enabled"] = "IA ennemie activée : toutes les créatures bougent",
["NoType"] = "aucun type coché",
["Guest"] = "L'IA ennemie tourne chez l'hôte : seul l'hôte peut figer les ennemis"
},
["zh"] = new Dictionary<string, string>
{
["Disabled"] = "已禁用以下敌人的 AI:{0}",
["Enabled"] = "敌人 AI 已启用:所有生物恢复行动",
["NoType"] = "未勾选任何类型",
["Guest"] = "敌人 AI 由房主运行:仅房主可定住敌人"
},
["zh-hant"] = new Dictionary<string, string>
{
["Disabled"] = "已停用以下敵人的 AI:{0}",
["Enabled"] = "敵人 AI 已啟用:所有生物恢復行動",
["NoType"] = "未勾選任何類型",
["Guest"] = "敵人 AI 由房主運行:僅房主可定住敵人"
},
["cs"] = new Dictionary<string, string>
{
["Disabled"] = "UI nepřátel vypnuta pro: {0}",
["Enabled"] = "UI nepřátel zapnuta: všechny bytosti se pohybují",
["NoType"] = "není zaškrtnut žádný typ",
["Guest"] = "UI nepřátel běží na hostiteli: zmrazit nepřátele může pouze hostitel"
},
["fi"] = new Dictionary<string, string>
{
["Disabled"] = "Vihollisten tekoäly poistettu käytöstä kohteelta: {0}",
["Enabled"] = "Vihollisten tekoäly käytössä: kaikki olennot liikkuvat",
["NoType"] = "tyyppiä ei valittu",
["Guest"] = "Vihollisten tekoäly toimii isännällä: vain isäntä voi pysäyttää viholliset"
},
["de"] = new Dictionary<string, string>
{
["Disabled"] = "Gegner-KI deaktiviert für: {0}",
["Enabled"] = "Gegner-KI aktiviert: Alle Kreaturen bewegen sich",
["NoType"] = "Kein Typ ausgewählt",
["Guest"] = "Gegner-KI läuft auf dem Host: Nur der Host kann Gegner einfrieren"
},
["it"] = new Dictionary<string, string>
{
["Disabled"] = "IA nemica disattivata per: {0}",
["Enabled"] = "IA nemica attivata: tutte le creature si muovono",
["NoType"] = "nessun tipo selezionato",
["Guest"] = "L'IA nemica gira sull'host: solo l'host può congelare i nemici"
},
["ja"] = new Dictionary<string, string>
{
["Disabled"] = "敵のAIを無効化: {0}",
["Enabled"] = "敵のAIを有効化: すべての生物が行動",
["NoType"] = "タイプ未選択",
["Guest"] = "敵AIはホスト側で実行中: 敵を停止できるのはホストのみです"
},
["ko"] = new Dictionary<string, string>
{
["Disabled"] = "적 AI 비활성화됨: {0}",
["Enabled"] = "적 AI 활성화됨: 모든 생명체가 움직입니다",
["NoType"] = "선택된 유형 없음",
["Guest"] = "적 AI는 호스트에서 실행됩니다: 호스트만 적을 멈출 수 있습니다"
},
["pl"] = new Dictionary<string, string>
{
["Disabled"] = "Wyłączono SI wrogów dla: {0}",
["Enabled"] = "Włączono SI wrogów: wszystkie stworzenia się poruszają",
["NoType"] = "nie zaznaczono typu",
["Guest"] = "SI wrogów działa u hosta: tylko host może zamrozić wrogów"
},
["pt"] = new Dictionary<string, string>
{
["Disabled"] = "IA dos inimigos desativada para: {0}",
["Enabled"] = "IA dos inimigos ativada: todas as criaturas se movem",
["NoType"] = "nenhum tipo marcado",
["Guest"] = "A IA dos inimigos roda no anfitrião: apenas o anfitrião pode congelar inimigos"
},
["ru"] = new Dictionary<string, string>
{
["Disabled"] = "ИИ врагов отключен для: {0}",
["Enabled"] = "ИИ врагов включен: все существа двигаются",
["NoType"] = "тип не выбран",
["Guest"] = "ИИ врагов работает на хосте: заморозить врагов может только хост"
},
["es"] = new Dictionary<string, string>
{
["Disabled"] = "IA enemiga desactivada para: {0}",
["Enabled"] = "IA enemiga activada: todas las criaturas se mueven",
["NoType"] = "ningún tipo marcado",
["Guest"] = "La IA enemiga se ejecuta en el anfitrión: solo el anfitrión puede congelar enemigos"
},
["sv"] = new Dictionary<string, string>
{
["Disabled"] = "Fiendens AI avstängd för: {0}",
["Enabled"] = "Fiendens AI aktiverad: alla varelser rör sig",
["NoType"] = "ingen typ markerad",
["Guest"] = "Fiendens AI körs på värden: endast värden kan frysa fiender"
},
["tr"] = new Dictionary<string, string>
{
["Disabled"] = "Düşman yapay zekâsı devre dışı: {0}",
["Enabled"] = "Düşman yapay zekâsı etkin: tüm yaratıklar hareket ediyor",
["NoType"] = "hiçbir tür seçilmedi",
["Guest"] = "Düşman yapay zekâsı kurucuda çalışır: düşmanları yalnızca kurucu dondurabilir"
}
};
public static string Get(string localeCode, string key)
{
string text = (localeCode ?? "en").ToLowerInvariant();
string key2 = (ByLanguage.ContainsKey(text) ? text : text.Split('-')[0]);
if (!ByLanguage.TryGetValue(key2, out var value) || !value.TryGetValue(key, out var value2))
{
return ByLanguage["en"][key];
}
return value2;
}
public static string WithTypes(string template, IReadOnlyCollection<string> frozenTypes, string noType)
{
return template.Replace("{0}", (frozenTypes.Count > 0) ? string.Join(", ", frozenTypes) : noType);
}
public static void SelfCheck()
{
foreach (string key in ByLanguage["fr"].Keys)
{
if (!ByLanguage["en"].ContainsKey(key))
{
throw new InvalidOperationException("Texts: '" + key + "' missing in English.");
}
}
if (Get("fr-FR", "Enabled") != ByLanguage["fr"]["Enabled"] || Get("xx", "Enabled") != ByLanguage["en"]["Enabled"] || WithTypes("x {0} {y}", (IReadOnlyCollection<string>)(object)new string[2] { "Billy", "Fingers" }, "-") != "x Billy, Fingers {y}" || WithTypes("{0}", (IReadOnlyCollection<string>)(object)new string[0], "-") != "-")
{
throw new InvalidOperationException("Texts lookup is wrong.");
}
}
}
}